pub use glam::{EulerRot, Mat3, Mat4, Quat, Vec2, Vec3, Vec4, vec2, vec3, vec4};
#[inline]
pub fn deg(degrees: f32) -> f32 {
degrees.to_radians()
}
#[inline]
pub fn euler(x: f32, y: f32, z: f32) -> Quat {
Quat::from_euler(EulerRot::XYZ, x, y, z)
}
#[inline]
pub fn euler_deg(x: f32, y: f32, z: f32) -> Quat {
euler(deg(x), deg(y), deg(z))
}
#[inline]
pub fn smoothstep(edge0: f32, edge1: f32, x: f32) -> f32 {
let t = ((x - edge0) / (edge1 - edge0)).clamp(0.0, 1.0);
t * t * (3.0 - 2.0 * t)
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Aabb {
pub min: Vec3,
pub max: Vec3,
}
impl Default for Aabb {
fn default() -> Self {
Self::EMPTY
}
}
impl Aabb {
pub const EMPTY: Aabb = Aabb {
min: Vec3::splat(f32::INFINITY),
max: Vec3::splat(f32::NEG_INFINITY),
};
pub fn from_points(points: impl IntoIterator<Item = Vec3>) -> Self {
let mut aabb = Self::EMPTY;
for p in points {
aabb.extend(p);
}
aabb
}
pub fn extend(&mut self, p: Vec3) {
self.min = self.min.min(p);
self.max = self.max.max(p);
}
pub fn union(self, other: Aabb) -> Aabb {
Aabb {
min: self.min.min(other.min),
max: self.max.max(other.max),
}
}
pub fn is_empty(&self) -> bool {
self.min.x > self.max.x
}
pub fn center(&self) -> Vec3 {
(self.min + self.max) * 0.5
}
pub fn size(&self) -> Vec3 {
self.max - self.min
}
pub fn corners(&self) -> [Vec3; 8] {
let (a, b) = (self.min, self.max);
[
Vec3::new(a.x, a.y, a.z),
Vec3::new(b.x, a.y, a.z),
Vec3::new(a.x, b.y, a.z),
Vec3::new(b.x, b.y, a.z),
Vec3::new(a.x, a.y, b.z),
Vec3::new(b.x, a.y, b.z),
Vec3::new(a.x, b.y, b.z),
Vec3::new(b.x, b.y, b.z),
]
}
pub fn transformed(&self, m: &Mat4) -> Aabb {
if self.is_empty() {
return *self;
}
Aabb::from_points(self.corners().map(|c| m.transform_point3(c)))
}
}