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,
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
}
}