collide-sphere 0.3.1

Sphere collider implementation for the collide crate
Documentation
use collide::{Collider, CollisionInfo};
use collide_ray::Ray;
use inner_space::InnerSpace;

use crate::Sphere;

impl<V: Copy + InnerSpace> Collider<Ray<V>> for Sphere<V> {
    type Vector = V;

    fn collision_info(&self, ray: &Ray<V>) -> Option<CollisionInfo<V>> {
        let (_, info) = ray.intersect_sphere(self.center, self.radius)?;
        Some(-info)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use simple_vectors::Vector;

    type Vec3 = Vector<f32, 3>;

    #[test]
    fn ray_hits_sphere() {
        let sphere = Sphere::new(Vec3::from([0.0, 0.0, 0.0]), 1.0);
        let ray = Ray::new(Vec3::from([-5.0, 0.0, 0.0]), Vec3::from([1.0, 0.0, 0.0]));

        let info = sphere.collision_info(&ray).unwrap();
        let distance = info.vector.magnitude();
        assert!((distance - 4.0).abs() < 0.001);
    }

    #[test]
    fn ray_misses_sphere() {
        let sphere = Sphere::new(Vec3::from([0.0, 0.0, 0.0]), 1.0);
        let ray = Ray::new(Vec3::from([-5.0, 0.0, 0.0]), Vec3::from([0.0, 1.0, 0.0]));

        assert!(sphere.collision_info(&ray).is_none());
    }

    #[test]
    fn ray_behind_origin_misses() {
        let sphere = Sphere::new(Vec3::from([0.0, 0.0, 0.0]), 1.0);
        let ray = Ray::new(Vec3::from([5.0, 0.0, 0.0]), Vec3::from([1.0, 0.0, 0.0]));

        assert!(sphere.collision_info(&ray).is_none());
    }
}