use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Vec2(pub f32, pub f32);
#[derive(Debug, Default, Clone, Copy, PartialEq)]
pub enum Rotation3 {
#[default]
Identity,
Quaternion([f32; 4]),
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Vec3(pub f32, pub f32, pub f32);
impl Vec3 {
#[must_use]
pub fn cross(self, other: Self) -> Self {
Self(
self.1.mul_add(other.2, -(self.2 * other.1)),
self.2.mul_add(other.0, -(self.0 * other.2)),
self.0.mul_add(other.1, -(self.1 * other.0)),
)
}
}
impl fmt::Display for Vec2 {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "({:.2}, {:.2})", self.0, self.1)
}
}
impl fmt::Display for Vec3 {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "({:.2}, {:.2}, {:.2})", self.0, self.1, self.2)
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Aabb {
pub min: Vec3,
pub max: Vec3,
}
impl Aabb {
#[must_use]
pub fn contains(self, point: Vec3) -> bool {
point.0 >= self.min.0
&& point.0 <= self.max.0
&& point.1 >= self.min.1
&& point.1 <= self.max.1
&& point.2 >= self.min.2
&& point.2 <= self.max.2
}
}
impl fmt::Display for Aabb {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "min={}, max={}", self.min, self.max)
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Obb {
pub center: Vec3,
pub axis0: Vec3,
pub axis1: Vec3,
pub axis2: Vec3,
pub half_extents: Vec3,
}
impl Obb {
#[must_use]
pub fn to_aabb(self) -> Aabb {
let ex = extent(self.axis0.0, self.axis1.0, self.axis2.0, self.half_extents);
let ey = extent(self.axis0.1, self.axis1.1, self.axis2.1, self.half_extents);
let ez = extent(self.axis0.2, self.axis1.2, self.axis2.2, self.half_extents);
Aabb {
min: Vec3(self.center.0 - ex, self.center.1 - ey, self.center.2 - ez),
max: Vec3(self.center.0 + ex, self.center.1 + ey, self.center.2 + ez),
}
}
}
impl fmt::Display for Obb {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
formatter,
"center={}, half_extents={}",
self.center, self.half_extents
)
}
}
fn extent(axis0: f32, axis1: f32, axis2: f32, half_extents: Vec3) -> f32 {
axis2.abs().mul_add(
half_extents.2,
axis0
.abs()
.mul_add(half_extents.0, axis1.abs() * half_extents.1),
)
}