11#ifndef JAU_MATH_GEOM_AABBOX3F_HPP_
12#define JAU_MATH_GEOM_AABBOX3F_HPP_
65 : m_lo( bl_ ), m_hi( tr_ ) {
74 void setHigh(const
float hx, const
float hy, const
float hz) noexcept {
78 void setLow(
const float lx,
const float ly,
const float lz)
noexcept {
82 void computeCenter() noexcept {
83 ( ( m_center = m_hi ) += m_lo ) *= 0.5f;
92 setLow(std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max());
93 setHigh(-std::numeric_limits<float>::max(), -std::numeric_limits<float>::max(), -std::numeric_limits<float>::max());
94 m_center.set(0, 0, 0);
112 float size() const noexcept {
return m_lo.dist(m_hi); }
114 float width() const noexcept {
return m_hi.x - m_lo.x; }
116 float height() const noexcept {
return m_hi.y - m_lo.y; }
118 float depth() const noexcept {
return m_hi.z - m_lo.z; }
157 const float hx,
const float hy,
const float hz)
noexcept {
158 m_lo.set(lx, ly, lz);
159 m_hi.set(hx, hy, hz);
192 m_hi.x += deltaRight;
210 m_lo.y -= deltaBottom;
230 if (o.m_lo.x < m_lo.x) {
233 if (o.m_lo.y < m_lo.y) {
236 if (o.m_lo.z < m_lo.z) {
241 if (o.m_hi.x > m_hi.x) {
244 if (o.m_hi.y > m_hi.y) {
247 if (o.m_hi.z > m_hi.z) {
270 if (newBL.
x < m_lo.x) {
273 if (newBL.
y < m_lo.y) {
276 if (newBL.
z < m_lo.z) {
284 if (newTR.
x > m_hi.x) {
287 if (newTR.
y > m_hi.y) {
290 if (newTR.
z > m_hi.z) {
339 return resize(xyz[0], xyz[1], xyz[2]);
349 return resize(p.x, p.y, p.z);
356 bool contains(
const float x,
const float y)
const noexcept {
357 return !( x<m_lo.x || x>m_hi.x ||
358 y<m_lo.y || y>m_hi.y );
371 bool contains(
const float x,
const float y,
const float z)
const noexcept {
372 return m_lo.x<=x && x<=m_hi.x &&
373 m_lo.y<=y && y<=m_hi.y &&
374 m_lo.z<=z && z<=m_hi.z;
398 return lo.
x <= hi.
x && lo.
y <= hi.
y && lo.
z <= hi.
z;
403 return m_hi.x >= o.m_hi.x &&
404 m_hi.y >= o.m_hi.y &&
405 m_hi.z >= o.m_hi.z &&
406 m_lo.x <= o.m_lo.x &&
407 m_lo.y <= o.m_lo.y &&
421 if (w <= 0 || h <= 0) {
424 const float _w =
width();
425 const float _h =
height();
426 if (_w <= 0 || _h <= 0) {
429 const float x0 = m_lo.x;
430 const float y0 = m_lo.y;
455 const Vec3f diff = ray.orig - m_center;
456 const Vec3f ext = m_hi - m_center;
457 if( std::abs(diff.
x) > ext.
x && diff.
x * ray.dir.x >= 0.0f )
return false;
458 if( std::abs(diff.
y) > ext.
y && diff.
y * ray.dir.y >= 0.0f )
return false;
459 if( std::abs(diff.
z) > ext.
z && diff.
z * ray.dir.z >= 0.0f )
return false;
462 float f = ray.dir.y * diff.
z - ray.dir.z * diff.
y;
463 if( std::abs(f) > ext.
y * absDir.
z + ext.
z * absDir.
y )
return false;
465 f = ray.dir.z * diff.
x - ray.dir.x * diff.
z;
466 if( std::abs(f) > ext.
x * absDir.
z + ext.
z * absDir.
x )
return false;
468 f = ray.dir.x * diff.
y - ray.dir.y * diff.
x;
469 if( std::abs(f) > ext.
x * absDir.
y + ext.
y * absDir.
x )
return false;
493 const Vec3f dir_inv = 1.0f / r.dir;
494 float t1 = (m_lo.x - r.orig.x)*dir_inv.
x;
495 float t2 = (m_hi.x - r.orig.x)*dir_inv.
x;
497 float tmin = std::min(t1, t2);
498 float tmax = std::max(t1, t2);
500 t1 = (m_lo.y - r.orig.y)*dir_inv.
y;
501 t2 = (m_hi.y - r.orig.y)*dir_inv.
y;
502 tmin = std::max(tmin, std::min(std::min(t1, t2), tmax));
503 tmax = std::min(tmax, std::max(std::max(t1, t2), tmin));
505 t1 = (m_lo.z - r.orig.z)*dir_inv.
z;
506 t2 = (m_hi.z - r.orig.z)*dir_inv.
z;
507 tmin = std::max(tmin, std::min(std::min(t1, t2), tmax));
508 tmax = std::min(tmax, std::max(std::max(t1, t2), tmin));
510 return tmax > std::max(tmin, 0.0f);
534 const Vec3f dir_inv = 1.0f / r.dir;
535 float t1 = (m_lo.x - r.orig.x)*dir_inv.
x;
536 float t2 = (m_hi.x - r.orig.x)*dir_inv.
x;
538 float tmin = std::min(t1, t2);
539 float tmax = std::max(t1, t2);
541 t1 = (m_lo.y - r.orig.y)*dir_inv.
y;
542 t2 = (m_hi.y - r.orig.y)*dir_inv.
y;
543 tmin = std::max(tmin, std::min(t1, t2));
544 tmax = std::min(tmax, std::max(t1, t2));
546 t1 = (m_lo.z - r.orig.z)*dir_inv.
z;
547 t2 = (m_hi.z - r.orig.z)*dir_inv.
z;
548 tmin = std::max(tmin, std::min(t1, t2));
549 tmax = std::min(tmax, std::max(t1, t2));
551 return tmax > std::max(tmin, 0.0f);
579 const bool assumeIntersection)
const noexcept {
580 float maxT[] = { -1.0f, -1.0f, -1.0f };
582 const Vec3f& origin = ray.orig;
583 const Vec3f& dir = ray.dir;
589 if(origin.
x < m_lo.x) {
595 maxT[0] = (m_lo.x - origin.
x) / dir.x;
597 }
else if(origin.
x > m_hi.x) {
603 maxT[0] = (m_hi.x - origin.
x) / dir.x;
608 if(origin.
y < m_lo.y) {
614 maxT[1] = (m_lo.y - origin.
y) / dir.y;
616 }
else if(origin.
y > m_hi.y) {
622 maxT[1] = (m_hi.y - origin.
y) / dir.y;
627 if(origin.
z < m_lo.z) {
633 maxT[2] = (m_lo.z - origin.
z) / dir.z;
635 }
else if(origin.
z > m_hi.z) {
641 maxT[2] = (m_hi.z - origin.
z) / dir.z;
719 if( !assumeIntersection ) {
720 switch( whichPlane ) {
722 result.y = origin.
y + maxT[whichPlane] * dir.y;
723 if(result.y < m_lo.y - epsilon || result.y > m_hi.y + epsilon) {
return false; }
724 result.z = origin.
z + maxT[whichPlane] * dir.z;
725 if(result.z < m_lo.z - epsilon || result.z > m_hi.z + epsilon) {
return false; }
728 result.x = origin.
x + maxT[whichPlane] * dir.x;
729 if(result.x < m_lo.x - epsilon || result.x > m_hi.x + epsilon) {
return false; }
730 result.z = origin.
z + maxT[whichPlane] * dir.z;
731 if(result.z < m_lo.z - epsilon || result.z > m_hi.z + epsilon) {
return false; }
734 result.x = origin.
x + maxT[whichPlane] * dir.x;
735 if(result.x < m_lo.x - epsilon || result.x > m_hi.x + epsilon) {
return false; }
736 result.y = origin.
y + maxT[whichPlane] * dir.y;
737 if(result.y < m_lo.y - epsilon || result.y > m_hi.y + epsilon) {
return false; }
744 switch( whichPlane ) {
746 result.y = origin.
y + maxT[whichPlane] * dir.y;
747 result.z = origin.
z + maxT[whichPlane] * dir.z;
750 result.x = origin.
x + maxT[whichPlane] * dir.x;
751 result.z = origin.
z + maxT[whichPlane] * dir.z;
754 result.x = origin.
x + maxT[whichPlane] * dir.x;
755 result.y = origin.
y + maxT[whichPlane] * dir.y;
774 out.resize( mat.mulVec3(m_lo, tmp) );
775 out.resize( mat.mulVec3(m_hi, tmp) );
806 float objZ = useCenterZ ? m_center.z : m_lo.z;
810 result.resize(winPos);
813 result.resize(winPos);
816 result.resize(winPos);
819 result.resize(winPos);
823 const float objZ = m_hi.z;
826 result.resize(winPos);
829 result.resize(winPos);
832 result.resize(winPos);
835 result.resize(winPos);
841 return "aabb[bl " + m_lo.toString() +
842 ", tr " + m_hi.toString() +
Class template jau::function is a general-purpose static-polymorphic function wrapper.
static bool mapObjToWin(const Vec3 &obj, const Matrix4 &mPMv, const Recti &viewport, Vec3 &winPos) noexcept
constexpr Vector3F & set(const Vec2f &o, const value_type z_) noexcept
TODO constexpr bool operator<=>(const vec3f_t& rhs ) const noexcept { return ... }...
bool contains(const float x, const float y) const noexcept
Check if the 2D point is bounded/contained by this aabbox3f.
AABBox3f & resizeWidth(const float deltaLeft, const float deltaRight) noexcept
Resize width of this aabbox3f with explicit left- and right delta values.
AABBox3f & setSize(const Vec3f &low, const Vec3f &high) noexcept
Set size of the aabbox3f specifying the coordinates of the low and high.
AABBox3f & resizeHeight(const float deltaBottom, const float deltaTop) noexcept
Resize height of this aabbox3f with explicit bottom- and top delta values.
AABBox3f & operator=(const AABBox3f &) noexcept=default
float depth() const noexcept
float width() const noexcept
bool intersectsRay0(const Ray3f ray) const noexcept
Check if Ray intersects this bounding box.
float size() const noexcept
Get the size of this aabbox3f where the size is represented by the length of the vector between low a...
AABBox3f & setSize(const float low[], const float high[]) noexcept
Set size of the aabbox3f specifying the coordinates of the low and high.
float height() const noexcept
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.
bool contains(const Point2f &p) const noexcept
Check if the 2D point is bounded/contained by this aabbox3f.
std::string toString() const noexcept
bool contains(const Point3f &p) const noexcept
Check if the 3D point is bounded/contained by this aabbox3f.
AABBox3f(const Point3f &bl_, const Point3f &tr_) noexcept
Create an aabbox3f with given bl (low) and tr (high)
bool hasZeroArea2D() const noexcept
Return true if get2DArea() is FloatUtil#isZero(float), considering epsilon.
float volume() const noexcept
Returns the volume, i.e.
AABBox3f & reset() noexcept
Reset this box to the inverse low/high, allowing the next resize(float, float, float) command to hit.
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...
float area2D() const noexcept
Returns the assumed 2D area, i.e.
constexpr AABBox3f(AABBox3f &&o) noexcept=default
bool getRayIntersection(Vec3f &result, const Ray3f &ray, const float epsilon, const bool assumeIntersection) const noexcept
Return intersection of a Ray with this bounding box, or false if none exist.
AABBox3f & resize(const float xyz[]) noexcept
Resize the aabbox3f to encapsulate the passed xyz-coordinates.
AABBox3f & transform(const Mat4f &mat, AABBox3f &out) const noexcept
Transform this box using the given Mat4f into out @endiliteral.
AABBox3f() noexcept
Create an Axis Aligned bounding box (aabbox3f) where the low and and high MAX float Values.
bool intersectsRay1(const Ray3f &r) const noexcept
Check if Ray intersects this bounding box.
const Point3f & high() const noexcept
Returns the maximum right-top-near (xyz) coordinate.
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.
bool hasZeroVolume() const noexcept
Return true if getVolume() is FloatUtil#isZero(float), considering epsilon.
jau::function< jau::math::Vec3f(const jau::math::Vec3f &)> transform_vec3f_func
General purpose Vec3f transform function.
bool intersects(const AABBox3f &o) const noexcept
Returns whether this aabbox3f intersects (partially contains) given aabbox3f.
const Point3f & low() const noexcept
Returns the minimum left-bottom-far (xyz) coordinate.
constexpr AABBox3f(const AABBox3f &o) noexcept=default
AABBox3f & mapToWindow(AABBox3f &result, const Mat4f &mat4PMv, const Recti &viewport, bool useCenterZ) const noexcept
Assume this bounding box as being in object space and compute the window bounding box.
const Point3f & center() const noexcept
Returns computed center of this aabbox3f of low() and high().
AABBox3f & resize(const float x, const float y, const float z) noexcept
Resize the aabbox3f to encapsulate the passed xyz-coordinates.
bool contains(const float x, const float y, const float z) const noexcept
Check if the 3D point is bounded/contained by this aabbox3f.
AABBox3f & resize(const AABBox3f &o) noexcept
Resize the aabbox3f to encapsulate another AABox.
AABBox3f & resize(const Point3f &p) noexcept
Resize the aabbox3f to encapsulate the passed xyz-coordinates.
bool intersectsRay(const Ray3f &r) const noexcept
Check if Ray intersects this bounding box.
bool contains(const AABBox3f &o) const noexcept
Returns whether this aabbox3f fully contains given aabbox3f.
AABBox3f & operator=(AABBox3f &&) noexcept=default
#define ERR_PRINT(...)
Use for unconditional error messages, prefix '[elapsed_time] Error @ FILE:LINE FUNC: '.
std::enable_if_t< std::is_floating_point_v< T >, bool > 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.
jau::uint_bytes_t< sizeof(T)> bit_value_raw(const T a) noexcept
Returns the unsigned integer representation according to IEEE 754 (IEC 559) floating-point bit layout...
constexpr uint32_t const float_iec559_sign_bit
Signed bit 31 of IEEE 754 (IEC 559) single float-point bit layout, i.e.
constexpr Vector2F< T > max(const Vector2F< T > &lhs, const Vector2F< T > &rhs) noexcept
constexpr Vector2F< T > min(const Vector2F< T > &lhs, const Vector2F< T > &rhs) noexcept
constexpr Vector2F< T > abs(const Vector2F< T > &lhs) noexcept