rtbvh/
aabb.rs

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]
471/// Creates an AABB from a list of vertices
472macro_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}