Add Decomp3

Yes this is code duplication. But glam is not dimension-generic.
This commit is contained in:
numzero 2024-09-15 10:34:39 +03:00
parent e5221fbcf8
commit b0aa666af3

View File

@ -1,4 +1,4 @@
use glam::{FloatExt, Mat2, Mat3, Vec2};
use glam::{FloatExt, Mat2, Mat3, Vec2, Vec3};
mod bounds {
pub trait Pair<T> {}
@ -93,6 +93,55 @@ where
}
}
/// Represents a 3×3 matrix decomposed as O^T D O, where O is orthogonal and D is diagonal.
///
/// Not every matrix can be decomposed like this, only that of a symmetric bilinear function.
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Decomp3 {
/// The orthogonal part.
///
/// Using a non-orthogonal matrix will yield to incorrect results (but no UB).
pub ortho: Mat3,
/// The diagonal part.
pub diag: Vec3,
}
impl Decomp3 {
/// Computes the square of this, more efficiently than doing that with a matrix.
pub fn square(&self) -> Self {
Self {
ortho: self.ortho,
diag: self.diag * self.diag,
}
}
/// Computes the inverse of this, more efficiently than doing that with a matrix.
pub fn inverse(&self) -> Self {
Self {
ortho: self.ortho,
diag: Vec3::splat(1.0) / self.diag,
}
}
}
impl From<Decomp3> for Mat3 {
fn from(value: Decomp3) -> Self {
value.ortho.transpose() * Mat3::from_diagonal(value.diag) * value.ortho
}
}
impl<T> std::ops::Mul<T> for Decomp3
where
Mat3: std::ops::Mul<T>,
{
type Output = <Mat3 as std::ops::Mul<T>>::Output;
fn mul(self, rhs: T) -> Self::Output {
Mat3::from(self) * rhs
}
}
#[cfg(test)]
mod tests {
use super::*;