box3d_rust/math_functions/
ray_triangle.rs1use super::*;
7
8fn any_less3(a: Vec3, b: Vec3) -> bool {
10 a.x < b.x || a.y < b.y || a.z < b.z
11}
12
13fn any_greater3(a: Vec3, b: Vec3) -> bool {
15 a.x > b.x || a.y > b.y || a.z > b.z
16}
17
18fn transpose3(c1: &mut Vec3, c2: &mut Vec3, c3: &mut Vec3) {
20 let temp1 = c1.y;
21 let temp2 = c1.z;
22 let temp3 = c2.z;
23
24 c1.y = c2.x;
25 c1.z = c3.x;
26 c2.z = c3.y;
27
28 c2.x = temp1;
29 c3.x = temp2;
30 c3.y = temp3;
31}
32
33pub fn test_bounds_triangle_overlap(
36 node_center: Vec3,
37 node_extent: Vec3,
38 mut vertex1: Vec3,
39 mut vertex2: Vec3,
40 mut vertex3: Vec3,
41) -> bool {
42 let two = Vec3 {
43 x: 2.0,
44 y: 2.0,
45 z: 2.0,
46 };
47
48 vertex1 = sub(vertex1, node_center);
50 vertex2 = sub(vertex2, node_center);
51 vertex3 = sub(vertex3, node_center);
52
53 let triangle_min = min(vertex1, min(vertex2, vertex3));
55 let triangle_max = max(vertex1, max(vertex2, vertex3));
56
57 let separation1 = sub(triangle_min, node_extent);
58 let separation2 = add(triangle_max, node_extent);
59
60 let face_separation = max(separation1, neg(separation2));
61 if any_greater3(face_separation, VEC3_ZERO) {
62 return false;
63 }
64
65 let edge1 = sub(vertex2, vertex1);
67 let edge2 = sub(vertex3, vertex2);
68 let edge3 = sub(vertex1, vertex3);
69
70 let normal = cross(edge1, edge2);
71
72 let d = dot(normal, vertex1);
73 let e = dot(abs(normal), node_extent);
74 let triangle_separation = Vec3 {
75 x: abs_float(d) - e,
76 y: abs_float(d) - e,
77 z: abs_float(d) - e,
78 };
79 if any_greater3(triangle_separation, VEC3_ZERO) {
80 return false;
81 }
82
83 let edge_separation1 = sub(
85 sub(
86 abs(cross(edge1, add(vertex1, vertex3))),
87 abs(cross(edge1, edge3)),
88 ),
89 mul(two, modified_cross(abs(edge1), node_extent)),
90 );
91 if any_greater3(edge_separation1, VEC3_ZERO) {
92 return false;
93 }
94
95 let edge_separation2 = sub(
96 sub(
97 abs(cross(edge2, add(vertex1, vertex2))),
98 abs(cross(edge2, edge1)),
99 ),
100 mul(two, modified_cross(abs(edge2), node_extent)),
101 );
102 if any_greater3(edge_separation2, VEC3_ZERO) {
103 return false;
104 }
105
106 let edge_separation3 = sub(
107 sub(
108 abs(cross(edge3, add(vertex2, vertex3))),
109 abs(cross(edge3, edge2)),
110 ),
111 mul(two, modified_cross(abs(edge3), node_extent)),
112 );
113 if any_greater3(edge_separation3, VEC3_ZERO) {
114 return false;
115 }
116
117 true
118}
119
120fn all_less_eq3(a: Vec3, b: Vec3) -> bool {
122 a.x <= b.x && a.y <= b.y && a.z <= b.z
123}
124
125pub fn test_bounds_overlap(
128 node_min1: Vec3,
129 node_max1: Vec3,
130 node_min2: Vec3,
131 node_max2: Vec3,
132) -> bool {
133 let separation = max(sub(node_min2, node_max1), sub(node_min1, node_max2));
134 all_less_eq3(separation, VEC3_ZERO)
135}
136
137pub fn test_bounds_ray_overlap(
140 node_min: Vec3,
141 node_max: Vec3,
142 mut ray_start: Vec3,
143 ray_delta: Vec3,
144) -> bool {
145 let node_center = mul_sv(0.5, add(node_min, node_max));
146 let node_extent = sub(node_max, node_center);
147
148 ray_start = sub(ray_start, node_center);
149
150 let edge_separation = sub(
151 abs(cross(ray_delta, ray_start)),
152 modified_cross(abs(ray_delta), node_extent),
153 );
154 all_less_eq3(edge_separation, VEC3_ZERO)
155}
156
157pub fn intersect_ray_triangle(
160 ray_start: Vec3,
161 ray_delta: Vec3,
162 vertex1: Vec3,
163 vertex2: Vec3,
164 vertex3: Vec3,
165) -> f32 {
166 {
168 let edge1 = sub(vertex3, vertex2);
169 let edge2 = sub(vertex1, vertex3);
170 let edge3 = sub(vertex2, vertex1);
171
172 let mid_point1 = mul_sv(0.5, add(vertex2, vertex3));
173 let mid_point2 = mul_sv(0.5, add(vertex3, vertex1));
174 let mid_point3 = mul_sv(0.5, add(vertex1, vertex2));
175
176 let mut normal1 = cross(edge1, sub(mid_point1, ray_start));
177 let mut normal2 = cross(edge2, sub(mid_point2, ray_start));
178 let mut normal3 = cross(edge3, sub(mid_point3, ray_start));
179 transpose3(&mut normal1, &mut normal2, &mut normal3);
180
181 let ray_delta_x = Vec3 {
182 x: ray_delta.x,
183 y: ray_delta.x,
184 z: ray_delta.x,
185 };
186 let ray_delta_y = Vec3 {
187 x: ray_delta.y,
188 y: ray_delta.y,
189 z: ray_delta.y,
190 };
191 let ray_delta_z = Vec3 {
192 x: ray_delta.z,
193 y: ray_delta.z,
194 z: ray_delta.z,
195 };
196
197 let volumes = add(
198 add(mul(normal1, ray_delta_x), mul(normal2, ray_delta_y)),
199 mul(normal3, ray_delta_z),
200 );
201 if any_less3(volumes, VEC3_ZERO) {
202 return 1.0;
203 }
204 }
205
206 let edge1 = sub(vertex2, vertex1);
208 let edge2 = sub(vertex3, vertex1);
209 let normal = cross(edge1, edge2);
210
211 let denominator = dot(normal, ray_delta);
212 if denominator >= 0.0 {
213 return 1.0;
214 }
215
216 let mut lambda = dot(normal, sub(vertex1, ray_start)) / denominator;
217 if lambda <= 0.0 {
218 return 1.0;
219 }
220
221 lambda = min_float(lambda, 1.0);
222 lambda
223}