-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcone.h
113 lines (86 loc) · 2.43 KB
/
cone.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#ifndef _CONE_H_
#define _CONE_H_
#include "common.h"
#include "vec3.h"
#include "onb.h"
#include <cmath>
using namespace std;
namespace Renzoku {
class Cone {
public:
Cone(const Cone &c);
Cone(const Vec3 &p, const Vec3 &n, Float half_angle);
Cone(const Vec3 &n, Float half_angle);
/**
* A cone spans from src to dest in anti-clockwise direction.
*/
Cone(const Vec3 &src, const Vec3 &dest);
inline Vec3 org() const;
inline Vec3 normal() const;
inline Float half_angle() const;
public:
/**
* Find the normal and half angle of the bounding cone that swipes from b to a in anti-clockwise order.
*
* The position of the new cone is set to the first cone.
*/
static Cone merge_direction(const Cone &src, const Cone &dest);
/**
* The cone rotates from a source place to the current cone position.
*/
void merge_direction(const Cone &src);
void merge_direction_algebraic(const Vec3 &v);
void merge_direction(const Vec3 &v);
bool contains(const Vec3 &dir) const;
inline void set_half_angle(Float half_angle);
private:
/**
* Angle to rotate src to dest in range [0, 360).
*
* Assume: src, dest are in XY plane.
*/
static Float angle(const Vec3 &src, const Vec3 &dest);
/**
* Return the angle in range [0, 360) from x-axis to a vector in XY plane.
*/
static Float angle_from_x_axis(const Vec3 &a);
private:
Vec3 p;
Vec3 n;
Float half;
};
inline Cone::Cone(const Cone &c) : p(c.p), n(c.n), half(c.half) {
}
inline Cone::Cone(const Vec3 &p, const Vec3 &n, Float half_angle) : p(p), n(n), half(half_angle) {
}
inline Cone::Cone(const Vec3 &n, Float half_angle) : p(Vec3(0.f)), n(n), half(half_angle) {
}
inline Cone::Cone(const Vec3 &src, const Vec3 &dest) : p(Vec3(0.f)) {
Vec3 l = unit_vector(src);
Vec3 r = unit_vector(dest);
Onb uvn;
uvn.init_from_uv(l, r); // anti-clockwise
l = uvn.world_to_local(l);
r = uvn.world_to_local(r);
half = angle(l, r) * 0.5f;
n = uvn.local_to_world(unit_vector((l + r) / 2));
if (half > A_PI)
n = -n;
}
inline Vec3 Cone::org() const {
return p;
}
inline Vec3 Cone::normal() const {
return n;
}
inline Float Cone::half_angle() const {
return half;
}
inline void Cone::set_half_angle(Float half_angle) {
half = half_angle;
}
inline bool Cone::contains(const Vec3 &v) const {
return dot(v, n) >= cos(half) ? true : false;
}
} // end namespace
#endif