Skip to main content

aabb.ixx File

Axis-Aligned Bounding Box (AABB) type and transformations. More...

Included Headers

#include <memory> #include <cassert> #include <algorithm> #include <helios.math.traits.FloatingPointType> #include <helios.math.concepts> #include <helios.math.types:mat4>

Namespaces Index

namespacehelios
namespacemath

Classes Index

structaabb<T>

Axis-Aligned Bounding Box for spatial culling and collision detection. More...

Description

Axis-Aligned Bounding Box (AABB) type and transformations.

File Listing

The file content with the documentation metadata removed is:

1
5module;
6
7#include <memory>
8#include <cassert>
9#include <algorithm>
10export module helios.math.types:aabb;
11
12import :vec3;
13import :mat4;
14import helios.math.concepts;
15import helios.math.traits.FloatingPointType;
16
17export namespace helios::math {
18
33 template<helios::math::concepts::IsNumeric T>
34 struct aabb {
35
36 private:
43
50
51 public:
52
60 constexpr aabb() noexcept
61 : min_{std::numeric_limits<T>::max(), std::numeric_limits<T>::max(), std::numeric_limits<T>::max()},
62 max_{std::numeric_limits<T>::lowest(), std::numeric_limits<T>::lowest(), std::numeric_limits<T>::lowest()}
63 {}
64
75 constexpr aabb(const T minX, const T minY, const T minZ, const T maxX, const T maxY, const T maxZ) noexcept
76 : min_{minX, minY, minZ},
77 max_{maxX, maxY, maxZ}
78 {}
79
86 constexpr aabb(const helios::math::vec3<T> min, const helios::math::vec3<T> max) noexcept
87 : min_(min),
88 max_(max)
89 {}
90
96 [[nodiscard]] constexpr const helios::math::vec3<T>& min() const noexcept {
97 return min_;
98 }
99
105 [[nodiscard]] constexpr const helios::math::vec3<T>& max() const noexcept {
106 return max_;
107 }
108
114 [[nodiscard]] constexpr helios::math::vec3<T> center() const noexcept {
115 return (min_ + max_) * static_cast<T>(0.5);
116 }
117
124 [[nodiscard]] constexpr helios::math::vec3<T> extent() const noexcept {
125 return (max_ - min_) * static_cast<T>(0.5);
126 }
127
128
134 [[nodiscard]] constexpr helios::math::vec3<T> size() const noexcept {
135 return max_ - min_;
136 }
137
148 [[nodiscard]] constexpr bool contains(const helios::math::aabb<T>& box) const noexcept {
149
150 auto v_min = box.min();
151 auto v_max = box.max();
152
153 return v_min[0] >= min_[0] && v_min[1] >= min_[1] && v_min[2] >= min_[2] &&
154 v_max[0] <= max_[0] && v_max[1] <= max_[1] && v_max[2] <= max_[2];
155
156 }
157
165 [[nodiscard]] constexpr bool contains(const helios::math::vec3<T>& point) const noexcept {
166 return point[0] >= min_[0] && point[1] >= min_[1] && point[2] >= min_[2] &&
167 point[0] <= max_[0] && point[1] <= max_[1] && point[2] <= max_[2];
168 }
169
177 [[nodiscard]] constexpr bool intersects(const helios::math::aabb<T>& box) const noexcept {
178
179 if (max_[0] < box.min()[0] || min_[0] > box.max()[0]) {
180 return false;
181 }
182 if (max_[1] < box.min()[1] || min_[1] > box.max()[1]) {
183 return false;
184 }
185 if (max_[2] < box.min()[2] || min_[2] > box.max()[2]) {
186 return false;
187 }
188 return true;
189 }
190
191
202 [[nodiscard]] constexpr helios::math::aabb<T> translate(const helios::math::vec3<T>& v) const noexcept {
204 min_ + v, max_ + v
205 };
206 }
207
208
209
220 void add(const helios::math::vec3<T>& point) noexcept {
221 min_[0] = std::min(min_[0], point[0]);
222 min_[1] = std::min(min_[1], point[1]);
223 min_[2] = std::min(min_[2], point[2]);
224
225 max_[0] = std::max(max_[0], point[0]);
226 max_[1] = std::max(max_[1], point[1]);
227 max_[2] = std::max(max_[2], point[2]);
228 }
229
246 [[nodiscard]] aabb<T> applyTransform(const mat4<T>& mat) const noexcept {
247
248 const T translationX = static_cast<T>(mat(0, 3));
249 const T translationY = static_cast<T>(mat(1, 3));
250 const T translationZ = static_cast<T>(mat(2, 3));
251
252 vec3<T> newMin = {translationX, translationY, translationZ};
253 vec3<T> newMax = newMin;
254
255 for (int i = 0; i < 3; ++i) {
256 for (int j = 0; j < 3; ++j) {
257
258 T val = static_cast<T>(mat(j, i));
259
260 T e = val * min_[i];
261 T f = val * max_[i];
262
263 if (e < f) {
264 newMin[j] += e;
265 newMax[j] += f;
266 } else {
267 newMin[j] += f;
268 newMax[j] += e;
269 }
270 }
271 }
272
273 return aabb<T>(newMin, newMax);
274 }
275 };
276
292 template<typename T>
293 [[nodiscard]] constexpr helios::math::vec3<T> overlap(
294 const helios::math::aabb<T> a, const helios::math::aabb<T> b) noexcept {
295
296 const auto overlapMin = helios::math::vec3<T>{
297 std::max(a.min()[0], b.min()[0]),
298 std::max(a.min()[1], b.min()[1]),
299 std::max(a.min()[2], b.min()[2])
300 };
301
302 const auto overlapMax = helios::math::vec3<T>{
303 std::min(a.max()[0], b.max()[0]),
304 std::min(a.max()[1], b.max()[1]),
305 std::min(a.max()[2], b.max()[2])
306 };
307
308 return overlapMax - overlapMin;
309 }
310
324 template<typename T>
325 [[nodiscard]] constexpr helios::math::vec3<T> overlapCenter(
326 const helios::math::aabb<T> a, const helios::math::aabb<T> b) noexcept {
327
328 const auto overlapMin = helios::math::vec3<T>{
329 std::max(a.min()[0], b.min()[0]),
330 std::max(a.min()[1], b.min()[1]),
331 std::max(a.min()[2], b.min()[2])
332 };
333
334 const auto overlapMax = helios::math::vec3<T>{
335 std::min(a.max()[0], b.max()[0]),
336 std::min(a.max()[1], b.max()[1]),
337 std::min(a.max()[2], b.max()[2])
338 };
339
340 return (overlapMax + overlapMin) * static_cast<T>(0.5);
341 }
342
355 template<typename T>
356 [[nodiscard]] constexpr helios::math::aabb<T> operator+(
357 const helios::math::aabb<T> aabb, const helios::math::vec3<T> v) noexcept {
358 return aabb.translate(v);
359 }
360
373 template<typename T>
374 [[nodiscard]] constexpr helios::math::aabb<T> operator*(
375 const helios::math::aabb<T>& aabb, const helios::math::vec3<T> v) noexcept {
376 assert(v[0] >= 0 && v[1] >= 0 && v[2] >= 0 && "unexpected negative value for scaling vector");
377 return helios::math::aabb<T>{aabb.min() * v, aabb.max() * v};
378 }
379
384
389
394
399
400} // namespace helios::math

Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.9.8.