1use crate::{Ray, RayPacket4};
2use glam::*;
3use std::{default::Default, fmt::Debug};
4use std::{
5 fmt::{Display, Formatter},
6 ops::Index,
7};
8
9#[cfg(feature = "serde")]
10use serde::{Deserialize, Serialize};
11
12#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
13#[repr(C, align(16))]
14#[derive(Debug, Copy, Clone)]
15pub struct Aabb<Extra: Debug + Copy = i32> {
16 pub min: Vec3,
17 pub extra1: Extra,
18 pub max: Vec3,
19 pub extra2: Extra,
20}
21
22pub trait Bounds<E: Debug + Copy = i32> {
23 fn bounds(&self) -> Aabb<E>;
24}
25
26impl<E: Debug + Copy> Default for Aabb<E>
27where
28 E: Default,
29{
30 fn default() -> Self {
31 Self::new()
32 }
33}
34
35impl<E: Debug + Copy> Display for Aabb<E>
36where
37 E: Display,
38{
39 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
40 write!(
41 f,
42 "(min: {}, extra1: {}, max: {}, extra2: {}",
43 self.min, self.extra1, self.max, self.extra2
44 )
45 }
46}
47
48impl<E: Debug + Copy + Default> Aabb<E> {
49 #[inline]
50 pub fn new() -> Self {
51 Aabb {
52 min: Vec3::splat(1e34),
53 extra1: Default::default(),
54 max: Vec3::splat(-1e34),
55 extra2: Default::default(),
56 }
57 }
58
59 #[inline]
60 pub fn full() -> Self {
61 Aabb {
62 min: Vec3::splat(-1e34),
63 max: Vec3::splat(1e34),
64 ..Default::default()
65 }
66 }
67
68 #[inline]
69 pub fn empty() -> Self {
70 Self::new()
71 }
72
73 #[inline]
74 pub fn union_of(&self, bb: &Self) -> Self {
75 let (min, max) = self.points();
76 let (b_min, b_max) = bb.points();
77
78 let new_min = min.min(b_min);
79 let new_max = max.max(b_max);
80
81 Self {
82 min: new_min,
83 max: new_max,
84 ..Default::default()
85 }
86 }
87
88 #[inline]
89 pub fn intersection(&self, bb: &Self) -> Self {
90 let (min, max) = self.points();
91 let (b_min, b_max) = bb.points();
92
93 let new_min = min.max(b_min);
94 let new_max = max.min(b_max);
95
96 Self {
97 min: new_min,
98 max: new_max,
99 ..Default::default()
100 }
101 }
102
103 #[inline]
104 pub fn from_points(points: &[Vec3]) -> Self {
105 let mut aabb = Self::empty();
106 for point in points {
107 aabb.grow(*point);
108 }
109 aabb.offset_by(1e-5);
110 aabb
111 }
112
113 #[inline]
114 pub fn transformed(&self, transform: Mat4) -> Self {
115 let mut corners = self.all_corners();
116 for c in corners.iter_mut() {
117 let corner: Vec4 = transform * c.extend(1.0);
118 *c = Vec3::new(corner.x, corner.y, corner.z);
119 }
120
121 Self::from_points(&corners)
122 }
123
124 #[inline]
125 pub fn union_of_list(aabbs: &[Self]) -> Self {
126 let mut aabb = Self::new();
127 for bb in aabbs {
128 aabb.grow_bb(bb);
129 }
130 aabb.with_offset(0.0001)
131 }
132
133 #[inline]
134 pub fn transform(&mut self, transform: Mat4) {
135 *self = self.transformed(transform);
136 }
137}
138
139#[allow(dead_code)]
140impl<E: Debug + Copy> Aabb<E> {
141 pub fn is_valid(&self) -> bool {
142 Vec3A::from(self.min).cmple(self.max.into()).all()
143 }
144
145 #[inline(always)]
146 pub fn intersect(&self, ray: &Ray) -> Option<f32> {
147 let mut ray_min = (self[ray.sign_x()].x - ray.origin.x) * ray.inv_direction.x;
148 let mut ray_max = (self[1 - ray.sign_x()].x - ray.origin.x) * ray.inv_direction.x;
149
150 let y_min = (self[ray.sign_y()].y - ray.origin.y) * ray.inv_direction.y;
151 let y_max = (self[1 - ray.sign_y()].y - ray.origin.y) * ray.inv_direction.y;
152
153 if (ray_min > y_max) || (y_min > ray_max) {
154 return None;
155 }
156
157 if y_min > ray_min {
158 ray_min = y_min;
159 }
160
161 if y_max < ray_max {
162 ray_max = y_max;
163 }
164
165 let z_min = (self[ray.sign_z()].z - ray.origin.z) * ray.inv_direction.z;
166 let z_max = (self[1 - ray.sign_z()].z - ray.origin.z) * ray.inv_direction.z;
167
168 if (ray_min > z_max) || (z_min > ray_max) {
169 return None;
170 }
171
172 if z_max < ray_max {
173 ray_max = z_max;
174 }
175
176 if ray_max > ray.t_min {
177 Some(ray_max)
178 } else {
179 None
180 }
181 }
182
183 #[inline(always)]
184 pub fn intersects(&self, ray: &Ray) -> bool {
185 let mut ray_min = (self[ray.sign_x()].x - ray.origin.x) * ray.inv_direction.x;
186 let mut ray_max = (self[1 - ray.sign_x()].x - ray.origin.x) * ray.inv_direction.x;
187
188 let y_min = (self[ray.sign_y()].y - ray.origin.y) * ray.inv_direction.y;
189 let y_max = (self[1 - ray.sign_y()].y - ray.origin.y) * ray.inv_direction.y;
190
191 if (ray_min > y_max) || (y_min > ray_max) {
192 return false;
193 }
194
195 if y_min > ray_min {
196 ray_min = y_min;
197 }
198
199 if y_max < ray_max {
200 ray_max = y_max;
201 }
202
203 let z_min = (self[ray.sign_z()].z - ray.origin.z) * ray.inv_direction.z;
204 let z_max = (self[1 - ray.sign_z()].z - ray.origin.z) * ray.inv_direction.z;
205
206 if (ray_min > z_max) || (z_min > ray_max) {
207 return false;
208 }
209
210 if z_max < ray_max {
211 ray_max = z_max;
212 }
213
214 ray_max > 0.0
215 }
216
217 #[inline]
218 pub fn intersect4(&self, packet: &RayPacket4) -> Option<[f32; 4]> {
219 let t1_x = (self.min.xxxx() - packet.origin_x) * packet.inv_direction_x;
220 let t1_y = (self.min.yyyy() - packet.origin_y) * packet.inv_direction_y;
221 let t1_z = (self.min.zzzz() - packet.origin_z) * packet.inv_direction_z;
222
223 let t2_x = (self.max.xxxx() - packet.origin_x) * packet.inv_direction_x;
224 let t2_y = (self.max.yyyy() - packet.origin_y) * packet.inv_direction_y;
225 let t2_z = (self.max.zzzz() - packet.origin_z) * packet.inv_direction_z;
226
227 let t_min_x = t1_x.min(t2_x);
228 let t_min_y = t1_y.min(t2_y);
229 let t_min_z = t1_z.min(t2_z);
230
231 let t_max_x = t1_x.max(t2_x);
232 let t_max_y = t1_y.max(t2_y);
233 let t_max_z = t1_z.max(t2_z);
234
235 let t_min = t_min_x.max(t_min_y.max(t_min_z));
236 let t_max = t_max_x.min(t_max_y.min(t_max_z));
237
238 let mask = t_max.cmpgt(Vec4::ZERO) & t_max.cmpgt(t_min) & t_min.cmplt(packet.t);
239 if mask.any() {
240 Some(t_min.into())
241 } else {
242 None
243 }
244 }
245
246 pub fn contains(&self, pos: Vec3) -> bool {
247 let (min, max) = self.points();
248 (pos.cmpgt(min) & pos.cmplt(max)).all()
249 }
250
251 #[inline]
252 pub fn grow(&mut self, pos: Vec3) {
253 let (min, max) = self.points();
254 let min = min.min(pos);
255 let max = max.max(pos);
256
257 for i in 0..3 {
258 self.min[i] = min[i];
259 self.max[i] = max[i];
260 }
261 }
262
263 #[inline]
264 pub fn grow_bb(&mut self, aabb: &Self) {
265 let (min, max) = self.points();
266 let (a_min, a_max) = aabb.points();
267
268 let min = min.min(a_min);
269 let max = max.max(a_max);
270
271 self.min = min;
272 self.max = max;
273 }
274
275 #[inline]
276 pub fn grow_bbs(&mut self, aabbs: &[Self]) {
277 let (mut min, mut max) = self.points();
278 for bb in aabbs {
279 let (a_min, a_max) = bb.points();
280 min = min.min(a_min);
281 max = max.max(a_max);
282 }
283
284 self.min = min;
285 self.max = max;
286 }
287
288 #[inline]
289 pub fn shrink(&mut self, aabb: &Self) {
290 let (min, max) = self.points();
291 let (a_min, a_max) = aabb.points();
292
293 let min = min.max(a_min);
294 let max = max.min(a_max);
295
296 self.min = min;
297 self.max = max;
298 }
299
300 #[inline]
301 pub fn with_offset(mut self, delta: f32) -> Self {
302 let delta = Vec3::splat(delta);
303
304 let min = self.min - delta;
305 let max = self.max + delta;
306
307 self.min = min;
308 self.max = max;
309 self
310 }
311
312 #[inline]
313 pub fn offset_by(&mut self, delta: f32) {
314 let delta = Vec3::splat(delta);
315
316 let min = self.min - delta;
317 let max = self.max + delta;
318
319 self.min = min;
320 self.max = max;
321 }
322
323 #[inline]
324 pub fn volume(&self) -> f32 {
325 let length = Vec3A::from(self.max) - Vec3A::from(self.min);
326 length.x * length.y * length.z
327 }
328
329 #[inline]
330 pub fn center(&self) -> Vec3 {
331 (self.min + self.max) * 0.5
332 }
333
334 #[inline]
335 pub fn area(&self) -> f32 {
336 let e = Vec3A::from(self.max) - Vec3A::from(self.min);
337 let value: f32 = e.x * e.y + e.x * e.z + e.y * e.z;
338
339 0.0_f32.max(value)
340 }
341
342 #[inline]
343 pub fn half_area(&self) -> f32 {
344 let d = self.diagonal();
345 (d[0] + d[1]) * d[2] + d[0] * d[1]
346 }
347
348 #[inline]
349 pub fn lengths(&self) -> Vec3 {
350 self.max - self.min
351 }
352
353 #[inline]
354 pub fn longest_axis(&self) -> usize {
355 let mut a: usize = 0;
356 if self.extend(1) > self.extend(0) {
357 a = 1;
358 }
359 if self.extend(2) > self.extend(a) {
360 a = 2
361 }
362 a
363 }
364
365 #[inline]
366 pub fn all_corners(&self) -> [Vec3; 8] {
367 let lengths = self.lengths();
368
369 let x_l = Vec3::new(lengths.x, 0.0, 0.0);
370 let y_l = Vec3::new(0.0, lengths.y, 0.0);
371 let z_l = Vec3::new(0.0, 0.0, lengths.z);
372
373 let (min, max) = self.points();
374
375 [
376 min,
377 max,
378 min + x_l,
379 min + y_l,
380 min + z_l,
381 min + x_l + y_l,
382 min + x_l + z_l,
383 min + y_l + z_l,
384 ]
385 }
386
387 #[inline]
388 pub fn extend(&self, axis: usize) -> f32 {
389 self.max[axis] - self.min[axis]
390 }
391
392 #[inline]
393 pub fn points(&self) -> (Vec3, Vec3) {
394 (self.min, self.max)
395 }
396
397 #[inline]
398 pub fn diagonal(&self) -> Vec3 {
399 self.max - self.min
400 }
401
402 #[inline]
403 pub fn longest_extent(&self) -> f32 {
404 self.diagonal()[self.longest_axis()]
405 }
406}
407
408impl<E: Debug + Copy + Send + Sync + Default, const COUNT: usize> From<[Vec3; COUNT]> for Aabb<E> {
409 fn from(points: [Vec3; COUNT]) -> Self {
410 Self::from_points(&points)
411 }
412}
413
414impl<E: Debug + Copy + Send + Sync + Default> From<(Vec3, Vec3)> for Aabb<E> {
415 fn from((min, max): (Vec3, Vec3)) -> Self {
416 Self {
417 min,
418 max,
419 ..Default::default()
420 }
421 }
422}
423
424impl<E: Debug + Copy + Send + Sync + Default> From<Aabb<E>> for (Vec3, Vec3) {
425 fn from(bb: Aabb<E>) -> Self {
426 (bb.min, bb.max)
427 }
428}
429
430impl<E: Debug + Copy> Bounds<E> for Aabb<E> {
431 fn bounds(&self) -> Aabb<E> {
432 *self
433 }
434}
435
436impl<E: Debug + Copy + Send + Sync> crate::Primitive<E> for Aabb<E> {
437 fn center(&self) -> Vec3 {
438 self.center()
439 }
440
441 fn aabb(&self) -> Self {
442 *self
443 }
444}
445
446impl<E: Debug + Copy> Index<usize> for &Aabb<E> {
447 type Output = Vec3;
448
449 fn index(&self, index: usize) -> &Vec3 {
450 if index == 0 {
451 &self.min
452 } else {
453 &self.max
454 }
455 }
456}
457
458impl<E: Debug + Copy> Index<usize> for Aabb<E> {
459 type Output = Vec3;
460
461 fn index(&self, index: usize) -> &Vec3 {
462 if index == 0 {
463 &self.min
464 } else {
465 &self.max
466 }
467 }
468}
469
470#[macro_export]
471macro_rules! aabb {
473 ($($x:expr),*) => {{
474 let mut bb = Aabb::empty();
475 $(
476 bb.grow($x);
477 )*
478
479 bb.offset_by(1e-4);
480 bb
481 }};
482}