use core::ops::{Add, Mul, Sub};
use num_traits::{One, Zero};
#[inline]
pub fn set<T>(
out: &mut [T; 16],
m00: T,
m01: T,
m02: T,
m03: T,
m10: T,
m11: T,
m12: T,
m13: T,
m20: T,
m21: T,
m22: T,
m23: T,
m30: T,
m31: T,
m32: T,
m33: T,
) -> &mut [T; 16] {
out[0] = m00;
out[4] = m01;
out[8] = m02;
out[12] = m03;
out[1] = m10;
out[5] = m11;
out[9] = m12;
out[13] = m13;
out[2] = m20;
out[6] = m21;
out[10] = m22;
out[14] = m23;
out[3] = m30;
out[7] = m31;
out[11] = m32;
out[15] = m33;
out
}
#[inline(always)]
pub fn set_identity<T>(out: &mut [T; 16]) -> &mut [T; 16]
where
T: One + Zero,
{
set(
out,
T::one(),
T::zero(),
T::zero(),
T::zero(),
T::zero(),
T::one(),
T::zero(),
T::zero(),
T::zero(),
T::zero(),
T::one(),
T::zero(),
T::zero(),
T::zero(),
T::zero(),
T::one(),
)
}
#[inline(always)]
pub fn set_zero<T>(out: &mut [T; 16]) -> &mut [T; 16]
where
T: Zero,
{
set(
out,
T::zero(),
T::zero(),
T::zero(),
T::zero(),
T::zero(),
T::zero(),
T::zero(),
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; 16]) -> &mut [T; 16]
where
T: One,
{
set(
out,
T::one(),
T::one(),
T::one(),
T::one(),
T::one(),
T::one(),
T::one(),
T::one(),
T::one(),
T::one(),
T::one(),
T::one(),
T::one(),
T::one(),
T::one(),
T::one(),
)
}
#[inline]
pub fn set_position<'out, T>(out: &'out mut [T; 16], v: &[T; 3]) -> &'out mut [T; 16]
where
T: Clone,
{
out[12] = v[0].clone();
out[13] = v[1].clone();
out[14] = v[2].clone();
out
}
#[inline]
pub fn set_mat2<'out, T>(out: &'out mut [T; 16], m: &[T; 4]) -> &'out mut [T; 16]
where
T: Zero + One + Clone,
{
set(
out,
m[0].clone(),
m[2].clone(),
T::zero(),
T::zero(),
m[1].clone(),
m[3].clone(),
T::zero(),
T::zero(),
T::zero(),
T::zero(),
T::one(),
T::zero(),
T::zero(),
T::zero(),
T::zero(),
T::one(),
)
}
#[inline]
pub fn set_mat32<'out, T>(out: &'out mut [T; 16], m: &[T; 6]) -> &'out mut [T; 16]
where
T: Zero + One + Clone,
{
set(
out,
m[0].clone(),
m[2].clone(),
T::zero(),
m[4].clone(),
m[1].clone(),
m[3].clone(),
T::zero(),
m[5].clone(),
T::zero(),
T::zero(),
T::one(),
T::zero(),
T::zero(),
T::zero(),
T::zero(),
T::one(),
)
}
#[inline]
pub fn set_mat3<'out, T>(out: &'out mut [T; 16], m: &[T; 9]) -> &'out mut [T; 16]
where
T: Zero + One + Clone,
{
set(
out,
m[0].clone(),
m[3].clone(),
m[6].clone(),
T::zero(),
m[1].clone(),
m[4].clone(),
m[7].clone(),
T::zero(),
m[2].clone(),
m[5].clone(),
m[8].clone(),
T::zero(),
T::zero(),
T::zero(),
T::zero(),
T::one(),
)
}
#[inline]
pub fn set_quat<'out, T>(out: &'out mut [T; 16], q: &[T; 4]) -> &'out mut [T; 16]
where
T: One + Zero,
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[4] = &xy - &wz;
out[8] = &xz + &wy;
out[1] = &xy + &wz;
out[5] = &T::one() - &(&xx + &zz);
out[9] = &yz - &wx;
out[2] = &xz - &wy;
out[6] = &yz + &wx;
out[10] = &T::one() - &(&xx + &yy);
out[3] = T::zero();
out[7] = T::zero();
out[11] = T::zero();
out[12] = T::zero();
out[13] = T::zero();
out[14] = T::zero();
out[15] = T::one();
out
}