parry3d/query/ray/
ray_aabb.rs1use core::mem;
2
3use na;
4
5use crate::bounding_volume::Aabb;
6use crate::math::{Real, Vector, DIM};
7use crate::query::{Ray, RayCast, RayIntersection};
8use crate::shape::FeatureId;
9use num::Zero;
10
11impl RayCast for Aabb {
12 fn cast_local_ray(&self, ray: &Ray, max_time_of_impact: Real, solid: bool) -> Option<Real> {
13 let mut tmin: Real = 0.0;
14 let mut tmax: Real = max_time_of_impact;
15
16 for i in 0usize..DIM {
17 if ray.dir[i].is_zero() {
18 if ray.origin[i] < self.mins[i] || ray.origin[i] > self.maxs[i] {
19 return None;
20 }
21 } else {
22 let denom = 1.0 / ray.dir[i];
23 let mut inter_with_near_halfspace = (self.mins[i] - ray.origin[i]) * denom;
24 let mut inter_with_far_halfspace = (self.maxs[i] - ray.origin[i]) * denom;
25
26 if inter_with_near_halfspace > inter_with_far_halfspace {
27 mem::swap(
28 &mut inter_with_near_halfspace,
29 &mut inter_with_far_halfspace,
30 )
31 }
32
33 tmin = tmin.max(inter_with_near_halfspace);
34 tmax = tmax.min(inter_with_far_halfspace);
35
36 if tmin > tmax {
37 return None;
40 }
41 }
42 }
43
44 if tmin.is_zero() && !solid {
45 Some(tmax)
46 } else {
47 Some(tmin)
48 }
49 }
50
51 #[inline]
52 fn cast_local_ray_and_get_normal(
53 &self,
54 ray: &Ray,
55 max_time_of_impact: Real,
56 solid: bool,
57 ) -> Option<RayIntersection> {
58 ray_aabb(self, ray, max_time_of_impact, solid).map(|(t, n, i)| {
59 let feature = if i < 0 {
60 FeatureId::Face((-i) as u32 - 1 + 3)
61 } else {
62 FeatureId::Face(i as u32 - 1)
63 };
64
65 RayIntersection::new(t, n, feature)
66 })
67 }
68}
69
70fn ray_aabb(
71 aabb: &Aabb,
72 ray: &Ray,
73 max_time_of_impact: Real,
74 solid: bool,
75) -> Option<(Real, Vector<Real>, isize)> {
76 use crate::query::clip;
77 clip::clip_aabb_line(aabb, &ray.origin, &ray.dir).and_then(|(near, far)| {
78 if near.0 < 0.0 {
79 if solid {
80 Some((0.0, na::zero(), far.2))
81 } else if far.0 <= max_time_of_impact {
82 Some(far)
83 } else {
84 None
85 }
86 } else if near.0 <= max_time_of_impact {
87 Some(near)
88 } else {
89 None
90 }
91 })
92}