diff --git a/src/aabb.rs b/src/aabb/aabb_impl.rs similarity index 92% rename from src/aabb.rs rename to src/aabb/aabb_impl.rs index 97f15e5..125821a 100644 --- a/src/aabb.rs +++ b/src/aabb/aabb_impl.rs @@ -1,5 +1,3 @@ -//! Axis Aligned Bounding Boxes. - use nalgebra::{Point, SVector}; use std::fmt; use std::ops::Index; @@ -23,76 +21,6 @@ impl fmt::Display for Aabb } } -/// 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 { - /// Returns whether this object intersects an [`Aabb`]. - /// - /// # Examples - /// ``` - /// use bvh::aabb::{Aabb, AabbIntersection}; - /// use nalgebra::Point3; - /// - /// struct XyPlane; - /// - /// impl AabbIntersection for XyPlane { - /// fn intersects_aabb(&self, aabb: &Aabb) -> 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) -> bool; -} - -impl AabbIntersection for Aabb { - fn intersects_aabb(&self, aabb: &Aabb) -> bool { - for i in 0..D { - if self.max[i] < aabb.min[i] || aabb.max[i] < self.min[i] { - return false; - } - } - true - } -} - -impl AabbIntersection for Point { - fn intersects_aabb(&self, aabb: &Aabb) -> bool { - aabb.contains(self) - } -} - -/// In 2D, a circle. In 3D, a sphere. This can be used for traversing BVH's. -pub struct Ball { - /// The center of the ball. - pub center: Point, - /// The radius of the ball. - pub radius: T, -} - -impl AabbIntersection for Ball { - fn intersects_aabb(&self, aabb: &Aabb) -> 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 - } -} - /// A trait implemented by things which can be bounded by an [`Aabb`]. /// /// [`Aabb`]: struct.Aabb.html diff --git a/src/aabb/intersection.rs b/src/aabb/intersection.rs new file mode 100644 index 0000000..982cd73 --- /dev/null +++ b/src/aabb/intersection.rs @@ -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 { + /// Returns whether this object intersects an [`Aabb`]. + /// + /// # Examples + /// ``` + /// use bvh::aabb::{Aabb, AabbIntersection}; + /// use nalgebra::Point3; + /// + /// struct XyPlane; + /// + /// impl AabbIntersection for XyPlane { + /// fn intersects_aabb(&self, aabb: &Aabb) -> 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) -> bool; +} + +impl AabbIntersection for Aabb { + fn intersects_aabb(&self, aabb: &Aabb) -> bool { + for i in 0..D { + if self.max[i] < aabb.min[i] || aabb.max[i] < self.min[i] { + return false; + } + } + true + } +} + +impl AabbIntersection for Point { + fn intersects_aabb(&self, aabb: &Aabb) -> bool { + aabb.contains(self) + } +} diff --git a/src/aabb/mod.rs b/src/aabb/mod.rs new file mode 100644 index 0000000..818fc4b --- /dev/null +++ b/src/aabb/mod.rs @@ -0,0 +1,7 @@ +//! Axis Aligned Bounding Boxes. + +mod aabb_impl; +mod intersection; + +pub use aabb_impl::*; +pub use intersection::*; diff --git a/src/ball.rs b/src/ball.rs new file mode 100644 index 0000000..7101413 --- /dev/null +++ b/src/ball.rs @@ -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 { + /// The center of the ball. + pub center: Point, + /// The radius of the ball. + pub radius: T, +} + +impl AabbIntersection for Ball { + fn intersects_aabb(&self, aabb: &Aabb) -> 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 + } +} diff --git a/src/lib.rs b/src/lib.rs index c397e1b..fb5e8da 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -84,6 +84,7 @@ extern crate test; pub mod aabb; +pub mod ball; pub mod bounding_hierarchy; pub mod bvh; pub mod flat_bvh;