1use crate::{Point3, Scalar, Vec3};
4
5#[derive(Debug, Clone, Copy, PartialEq)]
7pub struct Aabb {
8 pub min: Point3,
10 pub max: Point3,
12}
13
14impl Aabb {
15 pub const fn empty() -> Self {
17 Self {
18 min: Vec3::splat(Scalar::INFINITY),
19 max: Vec3::splat(Scalar::NEG_INFINITY),
20 }
21 }
22
23 #[inline]
25 pub const fn from_point(point: Point3) -> Self {
26 Self {
27 min: point,
28 max: point,
29 }
30 }
31
32 #[inline]
34 pub fn extend(&mut self, point: Point3) {
35 self.min = self.min.min(point);
36 self.max = self.max.max(point);
37 }
38
39 #[inline]
41 pub fn union(&mut self, other: &Self) {
42 self.min = self.min.min(other.min);
43 self.max = self.max.max(other.max);
44 }
45
46 #[inline]
48 pub fn is_finite(&self) -> bool {
49 self.min.is_finite() && self.max.is_finite()
50 }
51
52 #[inline]
54 pub fn intersects(&self, other: &Self) -> bool {
55 self.min.x <= other.max.x
56 && self.max.x >= other.min.x
57 && self.min.y <= other.max.y
58 && self.max.y >= other.min.y
59 && self.min.z <= other.max.z
60 && self.max.z >= other.min.z
61 }
62
63 #[inline]
65 pub fn is_empty(&self) -> bool {
66 self.min.x > self.max.x
67 }
68
69 pub fn diagonal(&self) -> Vec3 {
71 if self.is_empty() {
72 Vec3::ZERO
73 } else {
74 self.max - self.min
75 }
76 }
77
78 #[inline]
80 pub fn center(&self) -> Point3 {
81 if self.is_empty() {
82 Vec3::ZERO
83 } else {
84 (self.min + self.max) * 0.5
85 }
86 }
87
88 #[inline]
91 pub fn gap(&self, other: &Self) -> Scalar {
92 let separation = (other.min - self.max)
93 .max(self.min - other.max)
94 .max(Vec3::ZERO);
95 separation.length()
96 }
97}
98
99impl Default for Aabb {
100 fn default() -> Self {
101 Self::empty()
102 }
103}
104
105#[cfg(test)]
106mod tests {
107 use super::*;
108
109 #[test]
110 fn empty_box_absorbs_first_point() {
111 let mut bounds = Aabb::default();
112 assert!(bounds.is_empty());
113 bounds.extend(Vec3::new(1.0, 2.0, 3.0));
114 assert_eq!(bounds.min, bounds.max);
115 }
116
117 #[test]
118 fn disjoint_boxes_do_not_intersect() {
119 let mut left = Aabb::default();
120 left.extend(Vec3::ZERO);
121 left.extend(Vec3::ONE);
122 let mut right = Aabb::default();
123 right.extend(Vec3::splat(2.0));
124 right.extend(Vec3::splat(3.0));
125 assert!(!left.intersects(&right));
126 }
127}