File bounding_volume.h
File List > ext > geo > spatial_hash > bounding_volume.h
Go to the documentation of this file
#pragma once
#include <muda/ext/eigen/eigen_core_cxx20.h>
#include <Eigen/Geometry>
#include <muda/muda_def.h>
namespace muda::spatial_hash
{
class BoundingSphere
{
using Vector3 = Eigen::Vector3f;
public:
MUDA_GENERIC BoundingSphere(const Vector3& o, float r)
: o(o)
, r(r)
{
}
MUDA_GENERIC BoundingSphere() = default;
Vector3 o = Vector3::Zero();
float r = 0.0f;
int level = 0;
};
class AABB
{
using Vector3 = Eigen::Vector3f;
public:
Vector3 max;
Vector3 min;
MUDA_GENERIC AABB(const Vector3& min, const Vector3& max)
: min(min)
, max(max)
{
}
MUDA_GENERIC AABB(const AABB& l, const AABB& r)
{
max = l.max.cwiseMax(r.max);
min = l.min.cwiseMin(r.min);
}
MUDA_GENERIC Vector3 center() const { return (max + min) / 2; }
MUDA_GENERIC float radius() const { return (max - min).norm() / 2; }
};
MUDA_INLINE MUDA_GENERIC float squared_distance(const Eigen::Vector3f& p, AABB b)
{
float sq_dist = 0.0f;
#pragma unroll
for(int i = 0; i < 3; i++)
{
// for each axis count any excess distance outside box extents
float v = p[i];
if(v < b.min[i])
sq_dist += (b.min[i] - v) * (b.min[i] - v);
if(v > b.max[i])
sq_dist += (v - b.max[i]) * (v - b.max[i]);
}
return sq_dist;
}
MUDA_INLINE MUDA_GENERIC float distance(const Eigen::Vector3f& p, AABB b)
{
return ::sqrt(squared_distance(p, b));
}
MUDA_INLINE MUDA_GENERIC bool intersect(const BoundingSphere& s, const AABB& b)
{
// Compute squared distance between sphere center and AABB
// the sqrt(dist) is fine to use as well, but this is faster.
float sqDist = squared_distance(s.o, b);
// Sphere and AABB intersect if the (squared) distance between them is
// less than the (squared) sphere radius.
return sqDist <= s.r * s.r;
}
MUDA_INLINE MUDA_GENERIC bool intersect(const BoundingSphere& lhs, const BoundingSphere& rhs)
{
float r = lhs.r + rhs.r;
return (lhs.o - rhs.o).squaredNorm() <= r * r;
}
MUDA_INLINE MUDA_GENERIC bool intersect(const AABB& l, const AABB& r)
{
Eigen::Vector3i c;
#pragma unroll
for(int i = 0; i < 3; ++i)
c[i] = l.min[i] <= r.max[i] && l.max[i] >= r.min[i];
return c.all();
}
} // namespace muda::spatial_hash