use super::*;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct DecomposedTransform {
pub translation: Vec3,
pub rotation: Quat,
pub scale: Vec3,
}
#[must_use]
pub fn decompose_mat4(m: Mat4) -> Option<DecomposedTransform> {
let cols = m.to_cols_array_2d();
let translation = Vec3::new(cols[3][0], cols[3][1], cols[3][2]);
let mut row0 = Vec3::new(cols[0][0], cols[0][1], cols[0][2]);
let mut row1 = Vec3::new(cols[1][0], cols[1][1], cols[1][2]);
let mut row2 = Vec3::new(cols[2][0], cols[2][1], cols[2][2]);
let sx = row0.length();
let sy = row1.length();
let sz = row2.length();
if sx < crate::EPSILON_F32 || sy < crate::EPSILON_F32 || sz < crate::EPSILON_F32 {
return None;
}
row0 /= sx;
row1 /= sy;
row2 /= sz;
let det = row0.cross(row1).dot(row2);
let (scale, row0, row1, row2) = if det < 0.0 {
(Vec3::new(-sx, sy, sz), -row0, row1, row2)
} else {
(Vec3::new(sx, sy, sz), row0, row1, row2)
};
let rot_mat = Mat3::from_cols(row0, row1, row2);
let rotation = Quat::from_mat3(&rot_mat);
Some(DecomposedTransform {
translation,
rotation,
scale,
})
}
#[must_use]
#[inline]
pub fn recompose_mat4(d: &DecomposedTransform) -> Mat4 {
Mat4::from_scale_rotation_translation(d.scale, d.rotation, d.translation)
}