1use glam::{Vec3, Affine3A, Mat4};
2
3#[derive(Debug, Clone, Copy)]
4pub struct Aabb {
5 pub min: Vec3,
6 pub max: Vec3,
7}
8
9impl Aabb {
10 pub fn empty() -> Self {
11 Self {
12 min: Vec3::splat(f32::MAX),
13 max: Vec3::splat(f32::MIN),
14 }
15 }
16
17 pub fn expand(&mut self, point: Vec3) {
18 self.min = self.min.min(point);
19 self.max = self.max.max(point);
20 }
21
22 pub fn union(&self, other: &Aabb) -> Aabb {
24 if !other.is_valid() {
25 return *self;
26 }
27 if !self.is_valid() {
28 return *other;
29 }
30 Aabb {
31 min: self.min.min(other.min),
32 max: self.max.max(other.max),
33 }
34 }
35
36 pub fn from_transformed_aabb(local: &Aabb, transform: &Affine3A) -> Aabb {
38 let mat = Mat4::from(*transform);
39 let corners = [
40 Vec3::new(local.min.x, local.min.y, local.min.z),
41 Vec3::new(local.max.x, local.min.y, local.min.z),
42 Vec3::new(local.min.x, local.max.y, local.min.z),
43 Vec3::new(local.min.x, local.min.y, local.max.z),
44 Vec3::new(local.max.x, local.max.y, local.min.z),
45 Vec3::new(local.min.x, local.max.y, local.max.z),
46 Vec3::new(local.max.x, local.min.y, local.max.z),
47 Vec3::new(local.max.x, local.max.y, local.max.z),
48 ];
49 let mut out = Aabb::empty();
50 for c in &corners {
51 let t = mat.transform_point3(*c);
52 out.expand(t);
53 }
54 out
55 }
56
57 pub fn center(&self) -> Vec3 {
58 (self.min + self.max) * 0.5
59 }
60
61 pub fn extents(&self) -> Vec3 {
62 self.max - self.min
63 }
64
65 pub fn diagonal(&self) -> f32 {
66 self.extents().length()
67 }
68
69 pub fn is_valid(&self) -> bool {
70 self.min.x <= self.max.x && self.min.y <= self.max.y && self.min.z <= self.max.z
71 }
72}
73
74impl Default for Aabb {
75 fn default() -> Self {
76 Self::empty()
77 }
78}