use collide::Bounded;
use collide_sphere::Sphere;
use inner_space::InnerSpace;
use scalars::One;
use crate::Capsule;
impl<V: Copy + InnerSpace> Bounded<Sphere<V>> for Capsule<V> {
fn bounding_volume(&self) -> Sphere<V> {
let center = self.start + (self.end - self.start) / (V::Scalar::one() + V::Scalar::one());
let half_length =
(self.end - self.start).magnitude() / (V::Scalar::one() + V::Scalar::one());
Sphere::new(center, half_length + self.rad)
}
}
#[cfg(test)]
mod tests {
use super::*;
use simple_vectors::Vector;
type Vec3 = Vector<f32, 3>;
#[test]
fn capsule_bounding_sphere_contains_endpoints() {
let capsule = Capsule::new(
0.5,
Vec3::from([-2.0, 0.0, 0.0]),
Vec3::from([2.0, 0.0, 0.0]),
);
let sphere: Sphere<Vec3> = capsule.bounding_volume();
assert!((sphere.center - Vec3::from([0.0, 0.0, 0.0])).magnitude() < 0.001);
assert!((sphere.radius - 2.5).abs() < 0.001);
}
#[test]
fn sphere_capsule_bounding_sphere() {
let capsule = Capsule::sphere(Vec3::from([1.0, 0.0, 0.0]), 2.0);
let sphere: Sphere<Vec3> = capsule.bounding_volume();
assert!((sphere.center - Vec3::from([1.0, 0.0, 0.0])).magnitude() < 0.001);
assert!((sphere.radius - 2.0).abs() < 0.001);
}
}