parry3d/query/ray/
ray_halfspace.rs

1use na;
2
3use crate::math::{Point, Real, Vector};
4use crate::query::{Ray, RayCast, RayIntersection};
5use crate::shape::{FeatureId, HalfSpace};
6
7/// Computes the time_of_impact of an unbounded line with a halfspace described by its center and normal.
8#[inline]
9pub fn line_toi_with_halfspace(
10    halfspace_center: &Point<Real>,
11    halfspace_normal: &Vector<Real>,
12    line_origin: &Point<Real>,
13    line_dir: &Vector<Real>,
14) -> Option<Real> {
15    let dpos = *halfspace_center - *line_origin;
16    let denom = halfspace_normal.dot(line_dir);
17
18    if relative_eq!(denom, 0.0) {
19        None
20    } else {
21        Some(halfspace_normal.dot(&dpos) / denom)
22    }
23}
24
25/// Computes the time_of_impact of a ray with a halfspace described by its center and normal.
26#[inline]
27pub fn ray_toi_with_halfspace(
28    center: &Point<Real>,
29    normal: &Vector<Real>,
30    ray: &Ray,
31) -> Option<Real> {
32    if let Some(t) = line_toi_with_halfspace(center, normal, &ray.origin, &ray.dir) {
33        if t >= 0.0 {
34            return Some(t);
35        }
36    }
37
38    None
39}
40
41impl RayCast for HalfSpace {
42    #[inline]
43    fn cast_local_ray_and_get_normal(
44        &self,
45        ray: &Ray,
46        max_time_of_impact: Real,
47        solid: bool,
48    ) -> Option<RayIntersection> {
49        let dpos = -ray.origin;
50
51        let dot_normal_dpos = self.normal.dot(&dpos.coords);
52
53        if solid && dot_normal_dpos > 0.0 {
54            // The ray is inside of the solid half-space.
55            return Some(RayIntersection::new(0.0, na::zero(), FeatureId::Face(0)));
56        }
57
58        let t = dot_normal_dpos / self.normal.dot(&ray.dir);
59
60        if t >= 0.0 && t <= max_time_of_impact {
61            let n = if dot_normal_dpos > 0.0 {
62                -self.normal
63            } else {
64                self.normal
65            };
66
67            Some(RayIntersection::new(t, *n, FeatureId::Face(0)))
68        } else {
69            None
70        }
71    }
72}