Direct-BT v3.3.0-1-gc2d430c
Direct-BT - Direct Bluetooth Programming.
aabbox3f.hpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2022-2024 Gothel Software e.K.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24#ifndef JAU_AABBOX3F_HPP_
25#define JAU_AABBOX3F_HPP_
26
27#include <jau/functional.hpp>
28#include <jau/math/vec3f.hpp>
29
30namespace jau::math::geom {
31
32
33 /** \addtogroup Math
34 *
35 * @{
36 */
37
38 /**
39 * Axis Aligned Bounding Box. Defined by two 3D coordinates (low and high)
40 * The low being the the lower left corner of the box, and the high being the upper
41 * right corner of the box.
42 *
43 * A few references for collision detection, intersections:
44 * - http://www.realtimerendering.com/intersections.html
45 * - http://www.codercorner.com/RayAABB.cpp
46 * - http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter0.htm
47 * - http://realtimecollisiondetection.net/files/levine_swept_sat.txt
48 */
49 class AABBox3f {
50 private:
51 /** bottom left (low) */
52 Point3f m_lo;
53 /** top right (high) */
54 Point3f m_hi;
55 /** center */
56 Point3f m_center;
57
58 public:
59 /**
60 * Create an Axis Aligned bounding box (aabbox3f)
61 * where the low and and high MAX float Values.
62 */
63 AABBox3f() noexcept {
64 reset();
65 }
66
67 /**
68 * Create an aabbox3f with given bl (low) and tr (high)
69 */
70 AABBox3f(const Point3f& bl_, const Point3f& tr_) noexcept
71 : m_lo( bl_ ), m_hi( tr_ ) {
72 }
73
74 constexpr AABBox3f(const AABBox3f& o) noexcept = default;
75 constexpr AABBox3f(AABBox3f&& o) noexcept = default;
76 AABBox3f& operator=(const AABBox3f&) noexcept = default;
77 AABBox3f& operator=(AABBox3f&&) noexcept = default;
78
79 private:
80 void setHigh(const float hx, const float hy, const float hz) noexcept {
81 m_hi.set(hx, hy, hz);
82 }
83
84 void setLow(const float lx, const float ly, const float lz) noexcept {
85 m_lo.set(lx, ly, lz);
86 }
87
88 void computeCenter() noexcept {
89 ( ( m_center = m_hi ) += m_lo ) *= 0.5f;
90 }
91
92 public:
93 /**
94 * Reset this box to the inverse low/high, allowing the next {@link #resize(float, float, float)} command to hit.
95 * @return this aabbox3f for chaining
96 */
97 AABBox3f& reset() noexcept {
100 m_center.set(0, 0, 0);
101 return *this;
102 }
103
104 /** Returns the maximum right-top-near (xyz) coordinate */
105 const Point3f& high() const noexcept { return m_hi; }
106
107 /** Returns the minimum left-bottom-far (xyz) coordinate */
108 const Point3f& low() const noexcept { return m_lo; }
109
110 /** Returns computed center of this aabbox3f of low() and high(). */
111 const Point3f& center() const noexcept { return m_center; }
112
113 /**
114 * Get the size of this aabbox3f where the size is represented by the
115 * length of the vector between low and high.
116 * @return a float representing the size of the aabbox3f
117 */
118 float size() const noexcept { return m_lo.dist(m_hi); }
119
120 float width() const noexcept { return m_hi.x - m_lo.x; }
121
122 float height() const noexcept { return m_hi.y - m_lo.y; }
123
124 float depth() const noexcept { return m_hi.z - m_lo.z; }
125
126 /** Returns the volume, i.e. width * height * depth */
127 float volume() const noexcept { return width() * height() * depth(); }
128
129 /** Return true if {@link #getVolume()} is {@link FloatUtil#isZero(float)}, considering epsilon. */
130 bool hasZeroVolume() const noexcept { return jau::is_zero( volume() ); }
131
132 /** Returns the assumed 2D area, i.e. width * height while assuming low and high lies on same plane. */
133 float area2D() const noexcept { return width() * height(); }
134
135 /** Return true if {@link #get2DArea()} is {@link FloatUtil#isZero(float)}, considering epsilon. */
136 bool hasZeroArea2D() const noexcept { return jau::is_zero( area2D() ); }
137
138 /**
139 * Set size of the aabbox3f specifying the coordinates
140 * of the low and high.
141 *
142 * @param low min xyz-coordinates
143 * @param high max xyz-coordinates
144 * @return this aabbox3f for chaining
145 */
146 AABBox3f& setSize(const float low[], const float high[]) noexcept {
147 return setSize(low[0],low[1],low[2], high[0],high[1],high[2]);
148 }
149
150 /**
151 * Set size of the aabbox3f specifying the coordinates
152 * of the low and high.
153 *
154 * @param lx min x-coordinate
155 * @param ly min y-coordnate
156 * @param lz min z-coordinate
157 * @param hx max x-coordinate
158 * @param hy max y-coordinate
159 * @param hz max z-coordinate
160 * @return this aabbox3f for chaining
161 */
162 AABBox3f& setSize(const float lx, const float ly, const float lz,
163 const float hx, const float hy, const float hz) noexcept {
164 m_lo.set(lx, ly, lz);
165 m_hi.set(hx, hy, hz);
166 computeCenter();
167 return *this;
168 }
169
170 /**
171 * Set size of the aabbox3f specifying the coordinates
172 * of the low and high.
173 *
174 * @param low min xyz-coordinates
175 * @param high max xyz-coordinates
176 * @return this aabbox3f for chaining
177 */
178 AABBox3f& setSize(const Vec3f& low, const Vec3f& high) noexcept {
179 m_lo = low;
180 m_hi = high;
181 computeCenter();
182 return *this;
183 }
184
185 /**
186 * Resize width of this aabbox3f with explicit left- and right delta values
187 * @param deltaLeft positive value will expand width, otherwise shrink width
188 * @param deltaRight positive value will expand width, otherwise shrink width
189 * @return this aabbox3f for chaining
190 */
191 AABBox3f& resizeWidth(const float deltaLeft, const float deltaRight) noexcept {
192 bool mod = false;
193 if( !jau::is_zero(deltaLeft) ) {
194 m_lo.x -= deltaLeft;
195 mod = true;
196 }
197 if( !jau::is_zero(deltaRight) ) {
198 m_hi.x += deltaRight;
199 mod = true;
200 }
201 if( mod ) {
202 computeCenter();
203 }
204 return *this;
205 }
206
207 /**
208 * Resize height of this aabbox3f with explicit bottom- and top delta values
209 * @param deltaBottom positive value will expand height, otherwise shrink height
210 * @param deltaTop positive value will expand height, otherwise shrink height
211 * @return this aabbox3f for chaining
212 */
213 AABBox3f& resizeHeight(const float deltaBottom, const float deltaTop) noexcept {
214 bool mod = false;
215 if( !jau::is_zero(deltaBottom) ) {
216 m_lo.y -= deltaBottom;
217 mod = true;
218 }
219 if( !jau::is_zero(deltaTop) ) {
220 m_lo.y += deltaTop;
221 mod = true;
222 }
223 if( mod ) {
224 computeCenter();
225 }
226 return *this;
227 }
228
229 /**
230 * Resize the aabbox3f to encapsulate another AABox
231 * @param newBox aabbox3f to be encapsulated in
232 * @return this aabbox3f for chaining
233 */
234 AABBox3f& resize(const AABBox3f& o) noexcept {
235 /** test bl (low) */
236 if (o.m_lo.x < m_lo.x) {
237 m_lo.x = o.m_lo.x;
238 }
239 if (o.m_lo.y < m_lo.y) {
240 m_lo.y = o.m_lo.y;
241 }
242 if (o.m_lo.z < m_lo.z) {
243 m_lo.z = o.m_lo.z;
244 }
245
246 /** test tr (high) */
247 if (o.m_hi.x > m_hi.x) {
248 m_hi.x = o.m_hi.x;
249 }
250 if (o.m_hi.y > m_hi.y) {
251 m_hi.y = o.m_hi.y;
252 }
253 if (o.m_hi.z > m_hi.z) {
254 m_hi.z = o.m_hi.z;
255 }
256 computeCenter();
257 return *this;
258 }
259
260 /**
261 * General purpose Vec3f transform function
262 */
264
265 /**
266 * Resize the aabbox3f to encapsulate another AABox, which will be <i>transformed</i> on the fly first.
267 * @param newBox aabbox3f to be encapsulated in
268 * @param transform the transform function, applied on <i>newBox</i> on the fly
269 * @param tmpV3 temporary storage
270 * @return this aabbox3f for chaining
271 */
272 AABBox3f& resize(const AABBox3f& newBox, transform_vec3f_func& transform) noexcept {
273 /** test low */
274 {
275 const jau::math::Vec3f newBL = transform(newBox.low());
276 if (newBL.x < m_lo.x) {
277 m_lo.x = newBL.x;
278 }
279 if (newBL.y < m_lo.y) {
280 m_lo.y = newBL.y;
281 }
282 if (newBL.z < m_lo.z) {
283 m_lo.z = newBL.z;
284 }
285 }
286
287 /** test high */
288 {
289 const jau::math::Vec3f newTR = transform(newBox.high());
290 if (newTR.x > m_hi.x) {
291 m_hi.x = newTR.x;
292 }
293 if (newTR.y > m_hi.y) {
294 m_hi.y = newTR.y;
295 }
296 if (newTR.z > m_hi.z) {
297 m_hi.z = newTR.z;
298 }
299 }
300 computeCenter();
301 return *this;
302 }
303
304 /**
305 * Resize the aabbox3f to encapsulate the passed
306 * xyz-coordinates.
307 * @param x x-axis coordinate value
308 * @param y y-axis coordinate value
309 * @param z z-axis coordinate value
310 * @return this aabbox3f for chaining
311 */
312 AABBox3f& resize(const float x, const float y, const float z) noexcept {
313 /** test low */
314 if (x < m_lo.x) {
315 m_lo.x = x;
316 }
317 if (y < m_lo.y) {
318 m_lo.y = y;
319 }
320 if (z < m_lo.z) {
321 m_lo.z = z;
322 }
323
324 /** test high */
325 if (x > m_hi.x) {
326 m_hi.x = x;
327 }
328 if (y > m_hi.y) {
329 m_hi.y = y;
330 }
331 if (z > m_hi.z) {
332 m_hi.z = z;
333 }
334 computeCenter();
335 return *this;
336 }
337
338 /**
339 * Resize the aabbox3f to encapsulate the passed
340 * xyz-coordinates.
341 * @param xyz xyz-axis coordinate values
342 * @return this aabbox3f for chaining
343 */
344 AABBox3f& resize(const float xyz[]) noexcept {
345 return resize(xyz[0], xyz[1], xyz[2]);
346 }
347
348 /**
349 * Resize the aabbox3f to encapsulate the passed
350 * xyz-coordinates.
351 * @param xyz xyz-axis coordinate values
352 * @return this aabbox3f for chaining
353 */
354 AABBox3f& resize(const Point3f& p) noexcept {
355 return resize(p.x, p.y, p.z);
356 }
357
358 /**
359 * Check if the 2D point is bounded/contained by this aabbox3f
360 * @return true if {x, y} belongs to {low, high}
361 */
362 bool contains(const float x, const float y) const noexcept {
363 return !( x<m_lo.x || x>m_hi.x ||
364 y<m_lo.y || y>m_hi.y );
365 }
366
367 /**
368 * Check if the 2D point is bounded/contained by this aabbox3f
369 * @return true if p belongs to {low, high}
370 */
371 bool contains(const Point2f& p) const noexcept { return contains(p.x, p.y); }
372
373 /**
374 * Check if the 3D point is bounded/contained by this aabbox3f
375 * @return true if {x, y, z} belongs to {low, high}
376 */
377 bool contains(const float x, const float y, const float z) const noexcept {
378 return !( x<m_lo.x || x>m_hi.x ||
379 y<m_lo.y || y>m_hi.y ||
380 z<m_lo.z || z>m_hi.z );
381 }
382
383 /**
384 * Check if the 3D point is bounded/contained by this aabbox3f
385 * @return true if p belongs to (low.x, high.x) and y belong to (low.y, high.y)
386 */
387 bool contains(const Point3f& p) const noexcept { return contains(p.x, p.y, p.z); }
388
389 /** Returns whether this aabbox3f intersects (partially contains) given aabbox3f. */
390 bool intersects(const AABBox3f& o) const noexcept {
391 return !( m_hi.x < o.m_lo.x ||
392 m_hi.y < o.m_lo.y ||
393 m_hi.z < o.m_lo.z ||
394 m_lo.x > o.m_hi.x ||
395 m_lo.y > o.m_hi.y ||
396 m_lo.z > o.m_hi.z );
397 }
398
399 /** Returns whether this aabbox3f fully contains given aabbox3f. */
400 bool contains(const AABBox3f& o) const noexcept {
401 return m_hi.x >= o.m_hi.x &&
402 m_hi.y >= o.m_hi.y &&
403 m_hi.z >= o.m_hi.z &&
404 m_lo.x <= o.m_lo.x &&
405 m_lo.y <= o.m_lo.y &&
406 m_lo.z <= o.m_lo.z;
407 }
408
409 /**
410 * Check if there is a common region between this AABBox and the passed
411 * 2D region irrespective of z range
412 * @param x lower left x-coord
413 * @param y lower left y-coord
414 * @param w width
415 * @param h hight
416 * @return true if this AABBox might have a common region with this 2D region
417 */
418 bool intersects2DRegion(const float x, const float y, const float w, const float h) const noexcept {
419 if (w <= 0 || h <= 0) {
420 return false;
421 }
422 const float _w = width();
423 const float _h = height();
424 if (_w <= 0 || _h <= 0) {
425 return false;
426 }
427 const float x0 = m_lo.x;
428 const float y0 = m_lo.y;
429 return (x >= x0 &&
430 y >= y0 &&
431 x + w <= x0 + _w &&
432 y + h <= y0 + _h);
433 }
434
435 /**
436 * Check if {@link Ray} intersects this bounding box.
437 * <p>
438 * Versions uses the SAT[1], testing 6 axes.
439 * Original code for OBBs from MAGIC.
440 * Rewritten for AABBs and reorganized for early exits[2].
441 * </p>
442 * <pre>
443 * [1] SAT = Separating Axis Theorem
444 * [2] http://www.codercorner.com/RayAABB.cpp
445 * </pre>
446 * @param ray
447 * @return
448 */
449 bool intersectsRay(const Ray3f ray) const noexcept {
450 // diff[XYZ] -> ray.orig - center
451 // ext[XYZ] -> extend high - center
452
453 const float dirX = ray.dir.x;
454 const float diffX = ray.orig.x - m_center.x;
455 const float extX = m_hi.x - m_center.x;
456 if( std::abs(diffX) > extX && diffX*dirX >= 0.0f ) return false;
457
458 const float dirY = ray.dir.y;
459 const float diffY = ray.orig.y - m_center.y;
460 const float extY = m_hi.y - m_center.y;
461 if( std::abs(diffY) > extY && diffY*dirY >= 0.0f ) return false;
462
463 const float dirZ = ray.dir.z;
464 const float diffZ = ray.orig.z - m_center.z;
465 const float extZ = m_hi.z - m_center.z;
466 if( std::abs(diffZ) > extZ && diffZ*dirZ >= 0.0f ) return false;
467
468 const float absDirY = std::abs(dirY);
469 const float absDirZ = std::abs(dirZ);
470
471 float f = dirY * diffZ - dirZ * diffY;
472 if( std::abs(f) > extY*absDirZ + extZ*absDirY ) return false;
473
474 const float absDirX = std::abs(dirX);
475
476 f = dirZ * diffX - dirX * diffZ;
477 if( std::abs(f) > extX*absDirZ + extZ*absDirX ) return false;
478
479 f = dirX * diffY - dirY * diffX;
480 if( std::abs(f) > extX*absDirY + extY*absDirX ) return false;
481
482 return true;
483 }
484
485 /**
486 * Return intersection of a {@link Ray} with this bounding box,
487 * or false if none exist.
488 * <p>
489 * <ul>
490 * <li>Original code by Andrew Woo, from "Graphics Gems", Academic Press, 1990 [2]</li>
491 * <li>Optimized code by Pierre Terdiman, 2000 (~20-30% faster on my Celeron 500)</li>
492 * <li>Epsilon value added by Klaus Hartmann.</li>
493 * </ul>
494 * </p>
495 * <p>
496 * Method is based on the requirements:
497 * <ul>
498 * <li>the integer representation of 0.0f is 0x00000000</li>
499 * <li>the sign bit of the float is the most significant one</li>
500 * </ul>
501 * </p>
502 * <p>
503 * Report bugs: p.terdiman@codercorner.com (original author)
504 * </p>
505 * <pre>
506 * [1] http://www.codercorner.com/RayAABB.cpp
507 * [2] http://tog.acm.org/resources/GraphicsGems/gems/RayBox.c
508 * </pre>
509 * @param result vec3
510 * @param ray
511 * @param epsilon
512 * @param assumeIntersection if true, method assumes an intersection, i.e. by pre-checking via {@link #intersectsRay(Ray)}.
513 * In this case method will not validate a possible non-intersection and just computes
514 * coordinates.
515 * @return true with having intersection coordinates stored in result, or false if none exists
516 */
517 bool getRayIntersection(Vec3f& result, const Ray3f& ray, const float epsilon,
518 const bool assumeIntersection) {
519 float maxT[] = { -1.0f, -1.0f, -1.0f };
520
521 const Vec3f& origin = ray.orig;
522 const Vec3f& dir = ray.dir;
523
524 bool inside = true;
525
526 /**
527 * Use unrolled version below...
528 *
529 * Find candidate planes.
530 for(int i=0; i<3; i++) {
531 const float origin_i = origin.get(i);
532 const float dir_i = dir.get(i);
533 const float bl_i = bl.get(i);
534 const float tr_i = tr.get(i);
535 if(origin_i < bl_i) {
536 result.set(i, bl_i);
537 inside = false;
538
539 // Calculate T distances to candidate planes
540 if( 0 != jau::bit_value(dir_i) ) {
541 maxT[i] = (bl_i - origin_i) / dir_i;
542 }
543 } else if(origin_i > tr_i) {
544 result.set(i, tr_i);
545 inside = false;
546
547 // Calculate T distances to candidate planes
548 if( 0 != jau::bit_value(dir_i) ) {
549 maxT[i] = (tr_i - origin_i) / dir_i;
550 }
551 }
552 }
553 */
554 // Find candidate planes, unrolled
555 {
556 if(origin.x < m_lo.x) {
557 result.x = m_lo.x;
558 inside = false;
559
560 // Calculate T distances to candidate planes
561 if( 0 != jau::bit_value(dir.x) ) {
562 maxT[0] = (m_lo.x - origin.x) / dir.x;
563 }
564 } else if(origin.x > m_hi.x) {
565 result.x = m_hi.x;
566 inside = false;
567
568 // Calculate T distances to candidate planes
569 if( 0 != jau::bit_value(dir.x) ) {
570 maxT[0] = (m_hi.x - origin.x) / dir.x;
571 }
572 }
573 }
574 {
575 if(origin.y < m_lo.y) {
576 result.y = m_lo.y;
577 inside = false;
578
579 // Calculate T distances to candidate planes
580 if( 0 != jau::bit_value(dir.y) ) {
581 maxT[1] = (m_lo.y - origin.y) / dir.y;
582 }
583 } else if(origin.y > m_hi.y) {
584 result.y = m_hi.y;
585 inside = false;
586
587 // Calculate T distances to candidate planes
588 if( 0 != jau::bit_value(dir.y) ) {
589 maxT[1] = (m_hi.y - origin.y) / dir.y;
590 }
591 }
592 }
593 {
594 if(origin.z < m_lo.z) {
595 result.z = m_lo.z;
596 inside = false;
597
598 // Calculate T distances to candidate planes
599 if( 0 != jau::bit_value(dir.z) ) {
600 maxT[2] = (m_lo.z - origin.z) / dir.z;
601 }
602 } else if(origin.z > m_hi.z) {
603 result.z = m_hi.z;
604 inside = false;
605
606 // Calculate T distances to candidate planes
607 if( 0 != jau::bit_value(dir.z) ) {
608 maxT[2] = (m_hi.z - origin.z) / dir.z;
609 }
610 }
611 }
612
613 // Ray origin inside bounding box
614 if(inside) {
615 result = origin;
616 return true;
617 }
618
619 // Get largest of the maxT's for final choice of intersection
620 int whichPlane = 0;
621 if(maxT[1] > maxT[whichPlane]) { whichPlane = 1; }
622 if(maxT[2] > maxT[whichPlane]) { whichPlane = 2; }
623
624 if( !assumeIntersection ) {
625 // Check final candidate actually inside box
626 if( 0 != ( jau::bit_value(maxT[whichPlane]) & jau::float_iec559_sign_bit ) ) {
627 return false;
628 }
629
630 /** Use unrolled version below ..
631 for(int i=0; i<3; i++) {
632 if( i!=whichPlane ) {
633 result[i] = origin[i] + maxT[whichPlane] * dir[i];
634 if(result[i] < minB[i] - epsilon || result[i] > maxB[i] + epsilon) { return false; }
635 // if(result[i] < minB[i] || result[i] > maxB[i] ) { return false; }
636 }
637 } */
638 switch( whichPlane ) {
639 case 0:
640 result.y = origin.y + maxT[whichPlane] * dir.y;
641 if(result.y < m_lo.y - epsilon || result.y > m_hi.y + epsilon) { return false; }
642 result.z = origin.z + maxT[whichPlane] * dir.z;
643 if(result.z < m_lo.z - epsilon || result.z > m_hi.z + epsilon) { return false; }
644 break;
645 case 1:
646 result.x = origin.x + maxT[whichPlane] * dir.x;
647 if(result.x < m_lo.x - epsilon || result.x > m_hi.x + epsilon) { return false; }
648 result.z = origin.z + maxT[whichPlane] * dir.z;
649 if(result.z < m_lo.z - epsilon || result.z > m_hi.z + epsilon) { return false; }
650 break;
651 case 2:
652 result.x = origin.x + maxT[whichPlane] * dir.x;
653 if(result.x < m_lo.x - epsilon || result.x > m_hi.x + epsilon) { return false; }
654 result.y = origin.y + maxT[whichPlane] * dir.y;
655 if(result.y < m_lo.y - epsilon || result.y > m_hi.y + epsilon) { return false; }
656 break;
657 default:
658 throw InternalError("XXX", E_FILE_LINE);
659 }
660 } else {
661 switch( whichPlane ) {
662 case 0:
663 result.y = origin.y + maxT[whichPlane] * dir.y;
664 result.z = origin.z + maxT[whichPlane] * dir.z;
665 break;
666 case 1:
667 result.x = origin.x + maxT[whichPlane] * dir.x;
668 result.z = origin.z + maxT[whichPlane] * dir.z;
669 break;
670 case 2:
671 result.x = origin.x + maxT[whichPlane] * dir.x;
672 result.y = origin.y + maxT[whichPlane] * dir.y;
673 break;
674 default:
675 throw InternalError("XXX", E_FILE_LINE);
676 }
677 }
678 return true; // ray hits box
679 }
680
681 std::string toString() const noexcept {
682 return "aabb[bl " + m_lo.toString() +
683 ", tr " + m_hi.toString() +
684 "]"; }
685 };
686
687 /**@}*/
688
689} // namespace jau::math::geom
690
691#endif /* JAU_AABBOX3F_HPP_ */
#define E_FILE_LINE
Class template jau::function is a general-purpose static-polymorphic function wrapper.
constexpr Vector3F & set(const Vec2f &o, const value_type z_) noexcept
TODO constexpr bool operator<=>(const vec3f_t& rhs ) const noexcept { return ... }.
Definition: vec3f.hpp:143
value_type x
Definition: vec3f.hpp:72
constexpr value_type dist(const Vector3F &o) const noexcept
Return the distance between this vector and the given one.
Definition: vec3f.hpp:269
value_type y
Definition: vec3f.hpp:73
std::string toString() const noexcept
Definition: vec3f.hpp:214
value_type z
Definition: vec3f.hpp:74
Axis Aligned Bounding Box.
Definition: aabbox3f.hpp:49
bool contains(const float x, const float y) const noexcept
Check if the 2D point is bounded/contained by this aabbox3f.
Definition: aabbox3f.hpp:362
AABBox3f & resizeWidth(const float deltaLeft, const float deltaRight) noexcept
Resize width of this aabbox3f with explicit left- and right delta values.
Definition: aabbox3f.hpp:191
AABBox3f & setSize(const Vec3f &low, const Vec3f &high) noexcept
Set size of the aabbox3f specifying the coordinates of the low and high.
Definition: aabbox3f.hpp:178
AABBox3f & resizeHeight(const float deltaBottom, const float deltaTop) noexcept
Resize height of this aabbox3f with explicit bottom- and top delta values.
Definition: aabbox3f.hpp:213
AABBox3f & operator=(const AABBox3f &) noexcept=default
float depth() const noexcept
Definition: aabbox3f.hpp:124
float width() const noexcept
Definition: aabbox3f.hpp:120
float size() const noexcept
Get the size of this aabbox3f where the size is represented by the length of the vector between low a...
Definition: aabbox3f.hpp:118
AABBox3f & setSize(const float low[], const float high[]) noexcept
Set size of the aabbox3f specifying the coordinates of the low and high.
Definition: aabbox3f.hpp:146
float height() const noexcept
Definition: aabbox3f.hpp:122
AABBox3f & resize(const AABBox3f &newBox, transform_vec3f_func &transform) noexcept
Resize the aabbox3f to encapsulate another AABox, which will be transformed on the fly first.
Definition: aabbox3f.hpp:272
bool getRayIntersection(Vec3f &result, const Ray3f &ray, const float epsilon, const bool assumeIntersection)
Return intersection of a Ray with this bounding box, or false if none exist.
Definition: aabbox3f.hpp:517
bool contains(const Point2f &p) const noexcept
Check if the 2D point is bounded/contained by this aabbox3f.
Definition: aabbox3f.hpp:371
std::string toString() const noexcept
Definition: aabbox3f.hpp:681
bool contains(const Point3f &p) const noexcept
Check if the 3D point is bounded/contained by this aabbox3f.
Definition: aabbox3f.hpp:387
AABBox3f(const Point3f &bl_, const Point3f &tr_) noexcept
Create an aabbox3f with given bl (low) and tr (high)
Definition: aabbox3f.hpp:70
bool hasZeroArea2D() const noexcept
Return true if get2DArea() is FloatUtil#isZero(float), considering epsilon.
Definition: aabbox3f.hpp:136
float volume() const noexcept
Returns the volume, i.e.
Definition: aabbox3f.hpp:127
AABBox3f & reset() noexcept
Reset this box to the inverse low/high, allowing the next resize(float, float, float) command to hit.
Definition: aabbox3f.hpp:97
bool intersects2DRegion(const float x, const float y, const float w, const float h) const noexcept
Check if there is a common region between this AABBox and the passed 2D region irrespective of z rang...
Definition: aabbox3f.hpp:418
float area2D() const noexcept
Returns the assumed 2D area, i.e.
Definition: aabbox3f.hpp:133
constexpr AABBox3f(AABBox3f &&o) noexcept=default
bool intersectsRay(const Ray3f ray) const noexcept
Check if Ray intersects this bounding box.
Definition: aabbox3f.hpp:449
AABBox3f & resize(const float xyz[]) noexcept
Resize the aabbox3f to encapsulate the passed xyz-coordinates.
Definition: aabbox3f.hpp:344
AABBox3f() noexcept
Create an Axis Aligned bounding box (aabbox3f) where the low and and high MAX float Values.
Definition: aabbox3f.hpp:63
const Point3f & high() const noexcept
Returns the maximum right-top-near (xyz) coordinate.
Definition: aabbox3f.hpp:105
AABBox3f & setSize(const float lx, const float ly, const float lz, const float hx, const float hy, const float hz) noexcept
Set size of the aabbox3f specifying the coordinates of the low and high.
Definition: aabbox3f.hpp:162
bool hasZeroVolume() const noexcept
Return true if getVolume() is FloatUtil#isZero(float), considering epsilon.
Definition: aabbox3f.hpp:130
jau::function< jau::math::Vec3f(const jau::math::Vec3f &)> transform_vec3f_func
General purpose Vec3f transform function.
Definition: aabbox3f.hpp:263
bool intersects(const AABBox3f &o) const noexcept
Returns whether this aabbox3f intersects (partially contains) given aabbox3f.
Definition: aabbox3f.hpp:390
const Point3f & low() const noexcept
Returns the minimum left-bottom-far (xyz) coordinate.
Definition: aabbox3f.hpp:108
constexpr AABBox3f(const AABBox3f &o) noexcept=default
const Point3f & center() const noexcept
Returns computed center of this aabbox3f of low() and high().
Definition: aabbox3f.hpp:111
AABBox3f & resize(const float x, const float y, const float z) noexcept
Resize the aabbox3f to encapsulate the passed xyz-coordinates.
Definition: aabbox3f.hpp:312
bool contains(const float x, const float y, const float z) const noexcept
Check if the 3D point is bounded/contained by this aabbox3f.
Definition: aabbox3f.hpp:377
AABBox3f & resize(const AABBox3f &o) noexcept
Resize the aabbox3f to encapsulate another AABox.
Definition: aabbox3f.hpp:234
AABBox3f & resize(const Point3f &p) noexcept
Resize the aabbox3f to encapsulate the passed xyz-coordinates.
Definition: aabbox3f.hpp:354
bool contains(const AABBox3f &o) const noexcept
Returns whether this aabbox3f fully contains given aabbox3f.
Definition: aabbox3f.hpp:400
AABBox3f & operator=(AABBox3f &&) noexcept=default
constexpr uint32_t bit_value(const float a) noexcept
Returns the unsigned integer representation according to IEEE 754 (IEC 559) single floating-point bit...
Definition: float_math.hpp:174
std::enable_if< std::is_floating_point_v< T >, bool >::type constexpr is_zero(const T &a, const T &epsilon=std::numeric_limits< T >::epsilon()) noexcept
Returns true if the given value is less than epsilon, w/ epsilon > 0.
Definition: float_math.hpp:255
constexpr uint32_t const float_iec559_sign_bit
Signed bit 31 of IEEE 754 (IEC 559) single float-point bit layout, i.e.
Definition: float_math.hpp:57
constexpr T max(const T x, const T y) noexcept
Returns the maximum of two integrals (w/ branching) in O(1)
Definition: base_math.hpp:191
constexpr T abs(const T x) noexcept
Returns the absolute value of an arithmetic number (w/ branching) in O(1)
Definition: base_math.hpp:155
Vector3F< float > Vec3f
Definition: vec3f.hpp:371
Simple compound denoting a ray.
Definition: vec3f.hpp:399
Point3F< T > orig
Origin of Ray.
Definition: vec3f.hpp:401
Vector3F< T > dir
Normalized direction vector of ray.
Definition: vec3f.hpp:404