ncollide3d/query/ray/
ray_triangle.rs1use na::{self, RealField, Vector3};
2
3use crate::math::{Isometry, Point};
4use crate::query::{Ray, RayCast, RayIntersection};
5use crate::shape::{FeatureId, Triangle};
6
7impl<N: RealField + Copy> RayCast<N> for Triangle<N> {
8 #[inline]
9 fn toi_and_normal_with_ray(
10 &self,
11 m: &Isometry<N>,
12 ray: &Ray<N>,
13 max_toi: N,
14 _: bool,
15 ) -> Option<RayIntersection<N>> {
16 let ls_ray = ray.inverse_transform_by(m);
17 let mut inter = ray_intersection_with_triangle(&self.a, &self.b, &self.c, &ls_ray)?.0;
18
19 if inter.toi <= max_toi {
20 inter.normal = m * inter.normal;
21 Some(inter)
22 } else {
23 None
24 }
25 }
26}
27
28pub fn ray_intersection_with_triangle<N: RealField + Copy>(
33 a: &Point<N>,
34 b: &Point<N>,
35 c: &Point<N>,
36 ray: &Ray<N>,
37) -> Option<(RayIntersection<N>, Vector3<N>)> {
38 let ab = *b - *a;
39 let ac = *c - *a;
40
41 let n = ab.cross(&ac);
43 let d = n.dot(&ray.dir);
44
45 if d.is_zero() {
47 return None;
48 }
49
50 let ap = ray.origin - *a;
51 let t = ap.dot(&n);
52
53 if (t < na::zero() && d < na::zero()) || (t > na::zero() && d > na::zero()) {
55 return None;
56 }
57
58 let fid = if d < N::zero() { 0 } else { 1 };
59
60 let d = d.abs();
61
62 let e = -ray.dir.cross(&ap);
66
67 let mut v;
68 let mut w;
69 let toi;
70 let normal;
71
72 if t < na::zero() {
73 v = -ac.dot(&e);
74
75 if v < na::zero() || v > d {
76 return None;
77 }
78
79 w = ab.dot(&e);
80
81 if w < na::zero() || v + w > d {
82 return None;
83 }
84
85 let invd = na::one::<N>() / d;
86 toi = -t * invd;
87 normal = -n.normalize();
88 v = v * invd;
89 w = w * invd;
90 } else {
91 v = ac.dot(&e);
92
93 if v < na::zero() || v > d {
94 return None;
95 }
96
97 w = -ab.dot(&e);
98
99 if w < na::zero() || v + w > d {
100 return None;
101 }
102
103 let invd = na::one::<N>() / d;
104 toi = t * invd;
105 normal = n.normalize();
106 v = v * invd;
107 w = w * invd;
108 }
109
110 Some((
111 RayIntersection::new(toi, normal, FeatureId::Face(fid)),
112 Vector3::new(-v - w + na::one(), v, w),
113 ))
114}