1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//! Axis-aligned bounding boxes.
use glam::{Mat4, Vec3};
/// Axis-aligned bounding box (AABB).
#[derive(Debug, Clone)]
pub struct Aabb {
pub min: Vec3,
pub max: Vec3,
}
impl Aabb {
/// Creates an AABB from min and max points.
pub fn new(min: Vec3, max: Vec3) -> Self {
Self { min, max }
}
/// Creates a cube AABB centered at the origin.
pub const fn new_cube(width: f32, height: f32) -> Self {
Self {
min: Vec3::new(-width / 2.0, -height / 2.0, -width / 2.0),
max: Vec3::new(width / 2.0, height / 2.0, width / 2.0),
}
}
/// Creates a 2x2x2 cube AABB centered at the origin.
pub const fn new_unit_cube() -> Self {
Self::new_cube(2.0, 2.0)
}
/// Expands this AABB to include another.
pub fn extend(&mut self, other: &Self) {
self.min = self.min.min(other.min);
self.max = self.max.max(other.max);
}
/// Transforms this AABB in place by a matrix.
pub fn transform(&mut self, mat: &Mat4) {
// Transform all 8 corners of the AABB and recompute bounds
// This is necessary because rotation can change which corners are min/max
let corners = [
Vec3::new(self.min.x, self.min.y, self.min.z),
Vec3::new(self.max.x, self.min.y, self.min.z),
Vec3::new(self.min.x, self.max.y, self.min.z),
Vec3::new(self.max.x, self.max.y, self.min.z),
Vec3::new(self.min.x, self.min.y, self.max.z),
Vec3::new(self.max.x, self.min.y, self.max.z),
Vec3::new(self.min.x, self.max.y, self.max.z),
Vec3::new(self.max.x, self.max.y, self.max.z),
];
let first = mat.transform_point3(corners[0]);
self.min = first;
self.max = first;
for corner in &corners[1..] {
let transformed = mat.transform_point3(*corner);
self.min = self.min.min(transformed);
self.max = self.max.max(transformed);
}
}
/// Returns a transformed copy of this AABB.
pub fn transformed(&self, mat: &Mat4) -> Self {
let mut out = self.clone();
out.transform(mat);
out
}
/// Returns the center point of the AABB.
pub fn center(&self) -> Vec3 {
(self.min + self.max) * 0.5
}
/// Returns the size of the AABB along each axis.
pub fn size(&self) -> Vec3 {
self.max - self.min
}
}
// glTF-specific AABB helpers (`Aabb::from_gltf_*`) moved to
// `awsm-renderer-gltf::aabb` so this crate no longer depends on the `gltf`
// crate. Callers should use `awsm_renderer_gltf::aabb_from_gltf_{doc,node,
// primitive}` instead.