]> git.localhorst.tv Git - blank.git/blob - src/geometry/primitive.hpp
da4c37f1e03296d254d55f051d5e199f94132a9c
[blank.git] / src / geometry / primitive.hpp
1 #ifndef BLANK_GEOMETRY_PRIMITIVE_HPP_
2 #define BLANK_GEOMETRY_PRIMITIVE_HPP_
3
4 #include <algorithm>
5 #include <iosfwd>
6 #include <glm/glm.hpp>
7
8
9 namespace blank {
10
11 struct AABB {
12         glm::vec3 min;
13         glm::vec3 max;
14
15         void Adjust() noexcept {
16                 if (max.x < min.x) std::swap(max.x, min.x);
17                 if (max.y < min.y) std::swap(max.y, min.y);
18                 if (max.z < min.z) std::swap(max.z, min.z);
19         }
20
21         glm::vec3 Center() const noexcept {
22                 return min + (max - min) * 0.5f;
23         }
24
25         /// return distance between origin and farthest vertex
26         float OriginRadius() const noexcept {
27                 glm::vec3 high(glm::max(abs(min), abs(max)));
28                 return length(high);
29         }
30 };
31
32 std::ostream &operator <<(std::ostream &, const AABB &);
33
34 struct Ray {
35         glm::vec3 orig;
36         glm::vec3 dir;
37 };
38
39 std::ostream &operator <<(std::ostream &, const Ray &);
40
41 bool Intersection(
42         const Ray &,
43         const AABB &,
44         const glm::mat4 &M,
45         float *dist = nullptr,
46         glm::vec3 *normal = nullptr) noexcept;
47
48 /// matrices may translate and rotate, but must not scale/shear/etc
49 /// (basically the first three columns must have unit length)
50 bool Intersection(
51         const AABB &a_box,
52         const glm::mat4 &a_m,
53         const AABB &b_box,
54         const glm::mat4 &b_m,
55         float &depth,
56         glm::vec3 &normal) noexcept;
57
58
59 struct Plane {
60         glm::vec3 normal;
61         float dist;
62
63         float &A() noexcept { return normal.x; }
64         float &B() noexcept { return normal.y; }
65         float &C() noexcept { return normal.z; }
66         float &D() noexcept { return dist; }
67         float A() const noexcept { return normal.x; }
68         float B() const noexcept { return normal.y; }
69         float C() const noexcept { return normal.z; }
70         float D() const noexcept { return dist; }
71
72         Plane(const glm::vec3 &n, float d)
73         : normal(n), dist(d) { }
74         Plane(const glm::vec4 &abcd)
75         : normal(abcd), dist(abcd.w) { }
76
77         void Normalize() noexcept {
78                 const float l = length(normal);
79                 normal /= l;
80                 dist /= l;
81         }
82 };
83
84 std::ostream &operator <<(std::ostream &, const Plane &);
85
86 struct Frustum {
87         Plane plane[6];
88         Plane &Left() noexcept { return plane[0]; }
89         Plane &Right() noexcept { return plane[1]; }
90         Plane &Bottom() noexcept { return plane[2]; }
91         Plane &Top() noexcept { return plane[3]; }
92         Plane &Near() noexcept { return plane[4]; }
93         Plane &Far() noexcept { return plane[5]; }
94         const Plane &Left() const noexcept { return plane[0]; }
95         const Plane &Right() const noexcept { return plane[1]; }
96         const Plane &Bottom() const noexcept { return plane[2]; }
97         const Plane &Top() const noexcept { return plane[3]; }
98         const Plane &Near() const noexcept { return plane[4]; }
99         const Plane &Far() const noexcept { return plane[5]; }
100
101         /// create frustum from transposed MVP
102         Frustum(const glm::mat4 &mat)
103         : plane{
104                 { mat[3] + mat[0] },
105                 { mat[3] - mat[0] },
106                 { mat[3] + mat[1] },
107                 { mat[3] - mat[1] },
108                 { mat[3] + mat[2] },
109                 { mat[3] - mat[2] },
110         } { }
111
112         void Normalize() noexcept {
113                 for (Plane &p : plane) {
114                         p.Normalize();
115                 }
116         }
117 };
118
119 std::ostream &operator <<(std::ostream &, const Plane &);
120 std::ostream &operator <<(std::ostream &, const Frustum &);
121
122 bool CullTest(const AABB &box, const glm::mat4 &) noexcept;
123 bool CullTest(const AABB &box, const Frustum &) noexcept;
124
125 }
126
127 #endif