thimni 0.2.2

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

#[derive(Copy, Clone)]
pub struct RayCast {
    pub origin: Vec3,
    pub direction: Vec3,
    pub max_dist: f32,
    /// only updated when query is called.
    pub is_colliding: bool,
}

impl RayCast {
    pub fn new(origin: Vec3, direction: Vec3, max_dist: f32) -> Self {
        Self {
            origin,
            direction,
            max_dist,
            is_colliding: false,
        }
    }

    pub fn query(
        &mut self,
        other: &impl SDF<3, Vec3>,
        params: &CollisionParameters,
    ) -> Option<CollisionResult<3, Vec3>> {
        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
    }
}