-
-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create aabb directory and ball module.
- Loading branch information
Showing
5 changed files
with
88 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
use nalgebra::Point; | ||
|
||
use crate::{aabb::Aabb, bounding_hierarchy::BHValue}; | ||
|
||
/// A trait implemented by things that may or may not intersect an AABB and, by extension, | ||
/// things that can be used to traverse a BVH. | ||
pub trait AabbIntersection<T: BHValue, const D: usize> { | ||
/// Returns whether this object intersects an [`Aabb`]. | ||
/// | ||
/// # Examples | ||
/// ``` | ||
/// use bvh::aabb::{Aabb, AabbIntersection}; | ||
/// use nalgebra::Point3; | ||
/// | ||
/// struct XyPlane; | ||
/// | ||
/// impl AabbIntersection<f32,3> for XyPlane { | ||
/// fn intersects_aabb(&self, aabb: &Aabb<f32,3>) -> bool { | ||
/// aabb.min[2] <= 0.0 && aabb.max[2] >= 0.0 | ||
/// } | ||
/// } | ||
/// | ||
/// let xy_plane = XyPlane; | ||
/// let aabb = Aabb::with_bounds(Point3::new(-1.0,-1.0,-1.0), Point3::new(1.0,1.0,1.0)); | ||
/// assert!(xy_plane.intersects_aabb(&aabb)); | ||
/// ``` | ||
/// | ||
/// [`Aabb`]: struct.Aabb.html | ||
/// | ||
fn intersects_aabb(&self, aabb: &Aabb<T, D>) -> bool; | ||
} | ||
|
||
impl<T: BHValue, const D: usize> AabbIntersection<T, D> for Aabb<T, D> { | ||
fn intersects_aabb(&self, aabb: &Aabb<T, D>) -> bool { | ||
for i in 0..D { | ||
if self.max[i] < aabb.min[i] || aabb.max[i] < self.min[i] { | ||
return false; | ||
} | ||
} | ||
true | ||
} | ||
} | ||
|
||
impl<T: BHValue, const D: usize> AabbIntersection<T, D> for Point<T, D> { | ||
fn intersects_aabb(&self, aabb: &Aabb<T, D>) -> bool { | ||
aabb.contains(self) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
//! Axis Aligned Bounding Boxes. | ||
mod aabb_impl; | ||
mod intersection; | ||
|
||
pub use aabb_impl::*; | ||
pub use intersection::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
//! Balls, including circles and spheres. | ||
use crate::{ | ||
aabb::{Aabb, AabbIntersection}, | ||
bounding_hierarchy::BHValue, | ||
}; | ||
use nalgebra::Point; | ||
|
||
/// In 2D, a circle. In 3D, a sphere. This can be used for traversing BVH's. | ||
pub struct Ball<T: BHValue, const D: usize> { | ||
/// The center of the ball. | ||
pub center: Point<T, D>, | ||
/// The radius of the ball. | ||
pub radius: T, | ||
} | ||
|
||
impl<T: BHValue, const D: usize> AabbIntersection<T, D> for Ball<T, D> { | ||
fn intersects_aabb(&self, aabb: &Aabb<T, D>) -> bool { | ||
// https://gamemath.com/book/geomtests.html A.14 | ||
// Finding the point in/on the AABB that is closest to the ball's center or, | ||
// more specifically, find the squared distance betwen that point and the | ||
// ball's center. | ||
let mut distance_squared = T::zero(); | ||
for i in 0..D { | ||
let closest_on_aabb = self.center[i].clamp(aabb.min[i], aabb.max[i]); | ||
distance_squared += closest_on_aabb.powi(2); | ||
} | ||
|
||
// Then test if that point is in/on the ball. | ||
distance_squared <= self.radius | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters