thimni 0.2.3

efficient SDF collision without discretizatio, neural nets, or interval arithmetic
Documentation
use crate::{
    sdf::{CollisionResult, SDF},
    utils::CollisionParameters,
    vector::Vector,
};

#[derive(Copy, Clone)]
pub struct RayCast<const N: usize, V: Vector<N>> {
    pub origin: V,
    pub direction: V,
    pub max_dist: f32,
    /// only updated when query is called.
    pub is_colliding: bool,
}

impl<const N: usize, V: Vector<N>> RayCast<N, V> {
    pub fn new(origin: V, direction: V, max_dist: f32) -> Self {
        Self {
            origin,
            direction,
            max_dist,
            is_colliding: false,
        }
    }

    pub fn query(
        &mut self,
        other: &impl SDF<N, V>,
        params: &CollisionParameters,
    ) -> Option<CollisionResult<N, V>> {
        let rd = self.direction;
        let mut d = 0.0;
        let mut coll = false;

        for _ in 0..100 {
            let p = self.origin + rd * d;

            let ds = other.dist(p);

            if d > self.max_dist {
                break;
            }

            if ds.abs() < 0.002 {
                coll = true;
                break;
            }

            d += ds;
        }

        if coll {
            self.is_colliding = true;

            return Some(CollisionResult {
                point: self.origin + rd * d,
                gradient: other.gradient(self.origin + rd * d, params),
            });
        }

        None
    }
}