use crate::Mask;
use parry::{
bounding_volume as p,
math::{Point, Real},
query::Ray,
};
#[derive(Debug, Clone, Copy)]
pub struct Aabb {
aabb: p::Aabb,
layer: Mask,
mask: Mask,
}
impl Aabb {
#[inline]
pub fn new(aabb: p::Aabb, layer: Mask, mask: Mask) -> Self {
Self { aabb, layer, mask }
}
pub fn from_ray(ray: &Ray, max_time_of_impact: Real, mask: Mask) -> Self {
let (mins, maxs) = ray.origin.coords.inf_sup(&(ray.dir * max_time_of_impact));
let aabb = p::Aabb::new(Point::from(mins), Point::from(maxs));
Self::new(aabb, Mask::MAX, mask)
}
#[inline]
pub fn aabb(&self) -> &p::Aabb {
&self.aabb
}
#[inline]
pub fn layer(&self) -> Mask {
self.layer
}
#[inline]
pub fn mask(&self) -> Mask {
self.mask
}
}
impl Default for Aabb {
fn default() -> Self {
Self {
aabb: p::Aabb::new_invalid(),
layer: 0,
mask: 0,
}
}
}
impl bvh_arena::BoundingVolume for Aabb {
fn merge(self, other: Self) -> Self {
Self {
aabb: p::BoundingVolume::merged(&self.aabb, &other.aabb),
layer: self.layer | other.layer,
mask: self.mask | other.mask,
}
}
#[inline]
fn area(&self) -> f32 {
self.aabb.volume()
}
fn overlaps(&self, other: &Self) -> bool {
if self.layer & other.mask != 0 && self.mask & other.layer != 0 {
p::BoundingVolume::intersects(&self.aabb, &other.aabb)
} else {
false
}
}
}