use core::ops::{Add, Mul, Sub};
use num_traits::{One, Zero};
#[inline]
pub fn set<T>(
out: &mut [T; 9],
m00: T,
m01: T,
m02: T,
m10: T,
m11: T,
m12: T,
m20: T,
m21: T,
m22: T,
) -> &mut [T; 9] {
out[0] = m00;
out[3] = m01;
out[6] = m02;
out[1] = m10;
out[4] = m11;
out[7] = m12;
out[2] = m20;
out[5] = m21;
out[8] = m22;
out
}
#[inline(always)]
pub fn set_identity<T>(out: &mut [T; 9]) -> &mut [T; 9]
where
T: One + Zero,
{
set(
out,
T::one(),
T::zero(),
T::zero(),
T::zero(),
T::one(),
T::zero(),
T::zero(),
T::zero(),
T::one(),
)
}
#[inline(always)]
pub fn set_zero<T>(out: &mut [T; 9]) -> &mut [T; 9]
where
T: Zero,
{
set(
out,
T::zero(),
T::zero(),
T::zero(),
T::zero(),
T::zero(),
T::zero(),
T::zero(),
T::zero(),
T::zero(),
)
}
#[inline(always)]
pub fn set_one<T>(out: &mut [T; 9]) -> &mut [T; 9]
where
T: One,
{
set(
out,
T::one(),
T::one(),
T::one(),
T::one(),
T::one(),
T::one(),
T::one(),
T::one(),
T::one(),
)
}
#[inline]
pub fn set_mat2<'out, T>(out: &'out mut [T; 9], m: &[T; 4]) -> &'out mut [T; 9]
where
T: One + Zero + Clone,
{
set(
out,
m[0].clone(),
m[2].clone(),
T::zero(),
m[1].clone(),
m[3].clone(),
T::zero(),
T::zero(),
T::zero(),
T::one(),
)
}
#[inline]
pub fn set_mat32<'out, T>(out: &'out mut [T; 9], m: &[T; 6]) -> &'out mut [T; 9]
where
T: One + Zero + Clone,
{
set(
out,
m[0].clone(),
m[2].clone(),
T::zero(),
m[1].clone(),
m[3].clone(),
T::zero(),
T::zero(),
T::zero(),
T::one(),
)
}
#[inline]
pub fn set_mat4<'out, T>(out: &'out mut [T; 9], m: &[T; 16]) -> &'out mut [T; 9]
where
T: One + Zero + Clone,
{
set(
out,
m[0].clone(),
m[4].clone(),
m[8].clone(),
m[1].clone(),
m[5].clone(),
m[9].clone(),
m[2].clone(),
m[6].clone(),
m[10].clone(),
)
}
#[inline]
pub fn set_quat<'out, T>(out: &'out mut [T; 9], q: &[T; 4]) -> &'out mut [T; 9]
where
T: One,
for<'a, 'b> &'a T: Mul<&'b T, Output = T> + Add<&'b T, Output = T> + Sub<&'b T, Output = T>,
{
let x = &q[0];
let y = &q[1];
let z = &q[2];
let w = &q[3];
let x2 = x + x;
let y2 = y + y;
let z2 = z + z;
let xx = x * &x2;
let xy = x * &y2;
let xz = x * &z2;
let yy = y * &y2;
let yz = y * &z2;
let zz = z * &z2;
let wx = w * &x2;
let wy = w * &y2;
let wz = w * &z2;
out[0] = &T::one() - &(&yy + &zz);
out[1] = &xy + &wz;
out[2] = &xz - &wy;
out[3] = &xy - &wz;
out[4] = &T::one() - &(&xx + &zz);
out[5] = &yz + &wx;
out[6] = &xz + &wy;
out[7] = &yz - &wx;
out[8] = &T::one() - &(&xx + &yy);
out
}