Oxygen Engine
Modern C++ 3D Engine using OpenGL
Loading...
Searching...
No Matches
aabb.h
1#ifndef OE_SCENE_AABB_H
2#define OE_SCENE_AABB_H
3
4#include <glm/vec3.hpp>
5#include <glm/matrix.hpp>
6
7namespace oe::scene
8{
12 class AABB
13 {
14 public:
18 AABB() = default;
19
25 explicit AABB(const glm::vec3& extents):
26 min(-0.5f*glm::abs(extents)),
27 max(0.5f*glm::abs(extents))
28 {}
29
36 AABB(const glm::vec3& mini, const glm::vec3& maxi):
37 min(glm::min(mini, maxi)),
38 max(glm::max(mini, maxi))
39 {}
40
46 glm::vec3 getCenter() const noexcept
47 {
48 return 0.5f * (min + max);
49 }
50
57 void setBounds(const glm::vec3& mini, const glm::vec3& maxi) noexcept
58 {
59 min = mini;
60 max = maxi;
61 }
62
68 void extendToPoint(const glm::vec3& point) noexcept
69 {
70 if (point.x < min.x) min.x = point.x;
71 if (point.y < min.y) min.y = point.y;
72 if (point.z < min.z) min.z = point.z;
73
74 if (point.x > max.x) max.x = point.x;
75 if (point.y > max.y) max.y = point.y;
76 if (point.z > max.z) max.z = point.z;
77 }
78
87 AABB transform(const glm::mat4& model) const noexcept
88 {
89 glm::vec3 center = getCenter();
90 glm::vec3 demi_extents = max - center;
91
92 glm::vec3 transformed_center = glm::vec3(model * glm::vec4(center,1.0));
93
94 glm::mat3 abs_mat = glm::mat3(glm::abs(glm::vec3(model[0])), glm::abs(glm::vec3(model[1])), glm::abs(glm::vec3(model[2])));
95 glm::vec3 transformed_extents = abs_mat * demi_extents;
96
97 glm::vec3 min = transformed_center - transformed_extents;
98 glm::vec3 max = transformed_center + transformed_extents;
99
100 return AABB(min, max);
101 }
102
108 void extendToAABB(const oe::scene::AABB& aabb) noexcept
109 {
110 extendToPoint(aabb.min);
111 extendToPoint(aabb.max);
112 }
113
119 AABB& operator+=(const AABB& aabb) noexcept
120 {
121 extendToAABB(aabb);
122
123 return *this;
124 }
125
131 void scale(const glm::vec3& scale) noexcept
132 {
133 glm::vec3 center = getCenter();
134 glm::vec3 demi_extents = max - center;
135
136 min = center - demi_extents * scale;
137 max = center + demi_extents * scale;
138 }
139
145 glm::vec3 getExtents() const noexcept
146 {
147 return max - min;
148 }
149
155 float getVolume() const noexcept
156 {
157 const glm::vec3 size = getExtents();
158 return std::abs(size.x) * std::abs(size.y) * std::abs(size.z);
159 }
160
166 bool isEmpty() const noexcept
167 {
168 return max == min;
169 };
170
178 bool hasCollision(const AABB& box) const noexcept
179 {
180 return (min.x <= box.max.x && min.x >= box.min.x) &&
181 (min.y <= box.max.y && min.y >= box.min.y) &&
182 (min.z <= box.max.z && min.z >= box.min.z)
183 ;
184 }
185
194 bool hasCollision(const glm::vec3& center, const float& radius) const noexcept
195 {
196 // Get box closest point to sphere center by clamping
197 float x = glm::max(min.x, glm::min(center.x, max.x));
198 float y = glm::max(min.y, glm::min(center.y, max.y));
199 float z = glm::max(min.z, glm::min(center.z, max.z));
200
201 float distance = (x - center.x) * (x - center.x)
202 + (y - center.y) * (y - center.y)
203 + (z - center.z) * (z - center.z);
204
205 return distance < radius * radius;
206 }
207
215 bool contains(const glm::vec3& point) const noexcept
216 {
217 return (point.x <= max.x && point.x >= min.x) &&
218 (point.y <= max.y && point.y >= min.y) &&
219 (point.z <= max.z && point.z >= min.z)
220 ;
221 }
222
230 bool contains(const AABB& box) const noexcept
231 {
232 return contains(box.min) && contains(box.max);
233 }
234
238 glm::vec3 min = glm::vec3(0.0);
239
243 glm::vec3 max = glm::vec3(0.0);
244 };
245
252 inline AABB operator+(const AABB& op1, const AABB& op2) noexcept
253 {
254 AABB result(op1);
255 result.extendToAABB(op2);
256
257 return result;
258 }
259}
260
261#endif
Axis-aligned bounding box.
Definition aabb.h:13
AABB()=default
Create an empty box centered at origin.
bool contains(const glm::vec3 &point) const noexcept
Check if a point is in this box.
Definition aabb.h:215
bool hasCollision(const glm::vec3 &center, const float &radius) const noexcept
Check a sphere collision with this box.
Definition aabb.h:194
glm::vec3 getExtents() const noexcept
Get the box distance between min and max.
Definition aabb.h:145
AABB(const glm::vec3 &extents)
Create a box centered at origin.
Definition aabb.h:25
void scale(const glm::vec3 &scale) noexcept
Scale the bounding box.
Definition aabb.h:131
bool isEmpty() const noexcept
Check if the box is empty.
Definition aabb.h:166
glm::vec3 max
Maximum point of bounds.
Definition aabb.h:243
AABB(const glm::vec3 &mini, const glm::vec3 &maxi)
Create a box by providing bounds.
Definition aabb.h:36
void extendToAABB(const oe::scene::AABB &aabb) noexcept
Increase box size to contain another AABB.
Definition aabb.h:108
void extendToPoint(const glm::vec3 &point) noexcept
Update box size to contain the point.
Definition aabb.h:68
bool contains(const AABB &box) const noexcept
Check if another AABB is completely inside this box.
Definition aabb.h:230
glm::vec3 getCenter() const noexcept
Get coordinates of the box center.
Definition aabb.h:46
glm::vec3 min
Minimum point of bounds.
Definition aabb.h:238
bool hasCollision(const AABB &box) const noexcept
Check an box collision with this box.
Definition aabb.h:178
float getVolume() const noexcept
Get the box volume.
Definition aabb.h:155
AABB transform(const glm::mat4 &model) const noexcept
Returns a new AABB transformed according to a model matrix.
Definition aabb.h:87
void setBounds(const glm::vec3 &mini, const glm::vec3 &maxi) noexcept
Update box bounds.
Definition aabb.h:57
AABB & operator+=(const AABB &aabb) noexcept
Increase box size to contain another AABB.
Definition aabb.h:119
Scene related management (Render-agnostic Geometry, Manger, etc...)
Definition debug.h:19
AABB operator+(const AABB &op1, const AABB &op2) noexcept
return an AABB containing both AABB
Definition aabb.h:252