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,
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.add_self(&rd.scale(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.add_self(&rd.scale(d)),
gradient: other.gradient(self.origin.add_self(&rd.scale(d)), params),
});
}
None
}
}