Skip to content

Commit

Permalink
Added a basic BVH utility class.
Browse files Browse the repository at this point in the history
Added ray/aabb intersection test function to bbox class.
  • Loading branch information
fLindahl committed Mar 12, 2024
1 parent dce58a3 commit 0e85820
Show file tree
Hide file tree
Showing 3 changed files with 393 additions and 0 deletions.
1 change: 1 addition & 0 deletions code/foundation/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ nebula_begin_module(foundation)
bitfield.h
blob.cc
blob.h
bvh.h
commandlineargs.cc
commandlineargs.h
crc.cc
Expand Down
59 changes: 59 additions & 0 deletions code/foundation/math/bbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "math/clipstatus.h"
#include "math/sse.h"
#include "util/array.h"
#include "math/line.h"

//------------------------------------------------------------------------------
namespace Math
Expand Down Expand Up @@ -65,6 +66,8 @@ class bbox
void affine_transform(const mat4& m);
/// check for intersection with axis aligned bounding box
bool intersects(const bbox& box) const;
/// check for intersection with ray. parameter t will be filled with the "time" of intersection along `line.m`.
bool intersects(const line& ray, float& t) const;
/// check if this box completely contains the parameter box
bool contains(const bbox& box) const;
/// return true if this box contains the position
Expand All @@ -83,6 +86,8 @@ class bbox
void get_clipplanes(const mat4& viewProjection, Util::Array<vec4>& outPlanes) const;
/// convert to any type
template<typename T> T as() const;
/// calculate half-area of the surface of the box. If you need the full area, just multiply by 2.
float area() const;

point pmin;
point pmax;
Expand Down Expand Up @@ -288,6 +293,50 @@ bbox::intersects(const bbox& box) const
return !(lt || gt);
}

//------------------------------------------------------------------------------
/**
Ray/AABB Slab test from Real-Time Collision Detection by Christer Ericsson
Assumes ray is normalized.
*/
inline bool
bbox::intersects(const line& ray, float& tmin) const
{
tmin = 0.0f;
float tmax = 1e30f;

for (int i = 0; i < 3; i++)
{
if (fabs(ray.m[i]) < 0.00001f)
{
// ray is parallel to slab, no hit if start is not in slab
if (ray.b[i] < this->pmin[i] || ray.b[i] > this->pmax[i])
{
tmin = 1e30f;
return false;
}
}
else
{
float ood = 1.0f / ray.m[i];
float t1 = (this->pmin[i] - ray.b[i]) * ood;
float t2 = (this->pmax[i] - ray.b[i]) * ood;
if (t1 > t2)
std::swap(t1, t2);
if (t1 > tmin)
tmin = t1;
if (t2 < tmax)
tmax = t2;
if (tmin > tmax)
{
tmin = 1e30f;
return false;
}
}
}

return true;
}

//------------------------------------------------------------------------------
/**
Check if the parameter bounding box is completely contained in this
Expand Down Expand Up @@ -507,5 +556,15 @@ bbox::clipstatus(const vec4* x_columns, const vec4* y_columns, const vec4* z_col
else return ClipStatus::Clipped;
}

//------------------------------------------------------------------------------
/**
*/
inline float
bbox::area() const
{
Math::vec3 extent = this->pmax - this->pmin;
return extent.x * extent.y + extent.y * extent.z + extent.z * extent.x;
}

} // namespace Math
//------------------------------------------------------------------------------
Loading

0 comments on commit 0e85820

Please sign in to comment.