use num::Float;
use crate::vector4::Vector4;
use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, Index, IndexMut, Add, Neg, Sub, Mul, Div};
use crate::matrix3x3::Matrix3x3;
use crate::vector3::Vector3;
pub struct Matrix4x4<T: Float> {
_elements: [T; 16],
}
pub type Matrix4x4F = Matrix4x4<f32>;
pub type Matrix4x4D = Matrix4x4<f64>;
impl<T: Float> Matrix4x4<T> {
pub fn new_default() -> Matrix4x4<T> {
return Matrix4x4 {
_elements: [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()]
};
}
pub fn new_scalar(s: T) -> Matrix4x4<T> {
return Matrix4x4 {
_elements: [s, s, s, s,
s, s, s, s,
s, s, s, s,
s, s, s, s]
};
}
pub fn new(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) -> Matrix4x4<T> {
return Matrix4x4 {
_elements: [m00, m01, m02, m03,
m10, m11, m12, m13,
m20, m21, m22, m23,
m30, m31, m32, m33]
};
}
pub fn new_lst(lst: [[T; 4]; 4]) -> Matrix4x4<T> {
return Matrix4x4 {
_elements: [lst[0][0], lst[0][1], lst[0][2], lst[0][3],
lst[1][0], lst[1][1], lst[1][2], lst[1][3],
lst[2][0], lst[2][1], lst[2][2], lst[2][3],
lst[3][0], lst[3][1], lst[3][2], lst[3][3]]
};
}
pub fn new_mat(m33: Matrix3x3<T>) -> Matrix4x4<T> {
return Matrix4x4 {
_elements: [m33[0], m33[1], m33[2], T::zero(),
m33[3], m33[4], m33[5], T::zero(),
m33[6], m33[7], m33[8], T::zero(),
T::zero(), T::zero(), T::zero(), T::one()]
};
}
pub fn new_array(arr: [T; 16]) -> Matrix4x4<T> {
return Matrix4x4 {
_elements: arr
};
}
}
impl<T: Float> Matrix4x4<T> {
pub fn set_scalar(&mut self, s: T) {
self._elements[0] = s;
self._elements[1] = s;
self._elements[2] = s;
self._elements[3] = s;
self._elements[4] = s;
self._elements[5] = s;
self._elements[6] = s;
self._elements[7] = s;
self._elements[8] = s;
self._elements[9] = s;
self._elements[10] = s;
self._elements[11] = s;
self._elements[12] = s;
self._elements[13] = s;
self._elements[14] = s;
self._elements[15] = s;
}
pub fn set(&mut self, 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) {
self._elements[0] = m00;
self._elements[1] = m01;
self._elements[2] = m02;
self._elements[3] = m03;
self._elements[4] = m10;
self._elements[5] = m11;
self._elements[6] = m12;
self._elements[7] = m13;
self._elements[8] = m20;
self._elements[9] = m21;
self._elements[10] = m22;
self._elements[11] = m23;
self._elements[12] = m30;
self._elements[13] = m31;
self._elements[14] = m32;
self._elements[15] = m33;
}
pub fn set_lst(&mut self, lst: [[T; 4]; 4]) {
self._elements[0] = lst[0][0];
self._elements[1] = lst[0][1];
self._elements[2] = lst[0][2];
self._elements[3] = lst[0][3];
self._elements[4] = lst[1][0];
self._elements[5] = lst[1][1];
self._elements[6] = lst[1][2];
self._elements[7] = lst[1][3];
self._elements[8] = lst[2][0];
self._elements[9] = lst[2][1];
self._elements[10] = lst[2][2];
self._elements[11] = lst[2][3];
self._elements[12] = lst[3][0];
self._elements[13] = lst[3][1];
self._elements[14] = lst[3][2];
self._elements[15] = lst[3][3];
}
pub fn set_mat(&mut self, m33: Matrix3x3<T>) {
self.set(m33[0], m33[1], m33[2], T::zero(),
m33[3], m33[4], m33[5], T::zero(),
m33[6], m33[7], m33[8], T::zero(),
T::zero(), T::zero(), T::zero(), T::one());
}
pub fn set_self(&mut self, m: Matrix4x4<T>) {
self._elements = m._elements;
}
pub fn set_array(&mut self, arr: [T; 16]) {
self._elements = arr;
}
pub fn set_diagonal(&mut self, s: T) {
self._elements[0] = s;
self._elements[5] = s;
self._elements[10] = s;
self._elements[15] = s;
}
pub fn set_off_diagonal(&mut self, s: T) {
self._elements[1] = s;
self._elements[2] = s;
self._elements[3] = s;
self._elements[4] = s;
self._elements[6] = s;
self._elements[7] = s;
self._elements[8] = s;
self._elements[9] = s;
self._elements[11] = s;
self._elements[12] = s;
self._elements[13] = s;
self._elements[14] = s;
}
pub fn set_row(&mut self, i: usize, row: Vector4<T>) {
self._elements[4 * i] = row.x;
self._elements[4 * i + 1] = row.y;
self._elements[4 * i + 2] = row.z;
self._elements[4 * i + 3] = row.w;
}
pub fn set_column(&mut self, j: usize, col: Vector4<T>) {
self._elements[j] = col.x;
self._elements[j + 4] = col.y;
self._elements[j + 8] = col.z;
self._elements[j + 12] = col.w;
}
}
impl<T: Float> Matrix4x4<T> {
pub fn is_similar(&self, m: Matrix4x4<T>, tol: Option<T>) -> bool {
return
T::abs(self._elements[0] - m._elements[0]) < tol.unwrap_or(T::epsilon())
&& T::abs(self._elements[1] - m._elements[1]) < tol.unwrap_or(T::epsilon())
&& T::abs(self._elements[2] - m._elements[2]) < tol.unwrap_or(T::epsilon())
&& T::abs(self._elements[3] - m._elements[3]) < tol.unwrap_or(T::epsilon())
&& T::abs(self._elements[4] - m._elements[4]) < tol.unwrap_or(T::epsilon())
&& T::abs(self._elements[5] - m._elements[5]) < tol.unwrap_or(T::epsilon())
&& T::abs(self._elements[6] - m._elements[6]) < tol.unwrap_or(T::epsilon())
&& T::abs(self._elements[7] - m._elements[7]) < tol.unwrap_or(T::epsilon())
&& T::abs(self._elements[8] - m._elements[8]) < tol.unwrap_or(T::epsilon())
&& T::abs(self._elements[9] - m._elements[9]) < tol.unwrap_or(T::epsilon())
&& T::abs(self._elements[10] - m._elements[10]) < tol.unwrap_or(T::epsilon())
&& T::abs(self._elements[11] - m._elements[11]) < tol.unwrap_or(T::epsilon())
&& T::abs(self._elements[12] - m._elements[12]) < tol.unwrap_or(T::epsilon())
&& T::abs(self._elements[13] - m._elements[13]) < tol.unwrap_or(T::epsilon())
&& T::abs(self._elements[14] - m._elements[14]) < tol.unwrap_or(T::epsilon())
&& T::abs(self._elements[15] - m._elements[15]) < tol.unwrap_or(T::epsilon());
}
pub fn is_square(&self) -> bool {
return true;
}
pub fn rows(&self) -> usize {
return 4;
}
pub fn cols(&self) -> usize {
return 4;
}
pub fn data_mut(&mut self) -> &mut [T; 16] {
return &mut self._elements;
}
pub fn data(&self) -> &[T; 16] {
return &self._elements;
}
pub fn matrix3(&self) -> Matrix3x3<T> {
return Matrix3x3::new(
self._elements[0], self._elements[1], self._elements[2],
self._elements[4], self._elements[5], self._elements[6],
self._elements[8], self._elements[9], self._elements[10]);
}
}
impl<T: Float> Matrix4x4<T> {
pub fn add_scalar(&self, s: T) -> Matrix4x4<T> {
return Matrix4x4::new(self._elements[0] + s,
self._elements[1] + s,
self._elements[2] + s,
self._elements[3] + s,
self._elements[4] + s,
self._elements[5] + s,
self._elements[6] + s,
self._elements[7] + s,
self._elements[8] + s,
self._elements[9] + s,
self._elements[10] + s,
self._elements[11] + s,
self._elements[12] + s,
self._elements[13] + s,
self._elements[14] + s,
self._elements[15] + s);
}
pub fn add_mat(&self, m: Matrix4x4<T>) -> Matrix4x4<T> {
return Matrix4x4::new(self._elements[0] + m._elements[0],
self._elements[1] + m._elements[1],
self._elements[2] + m._elements[2],
self._elements[3] + m._elements[3],
self._elements[4] + m._elements[4],
self._elements[5] + m._elements[5],
self._elements[6] + m._elements[6],
self._elements[7] + m._elements[7],
self._elements[8] + m._elements[8],
self._elements[9] + m._elements[9],
self._elements[10] + m._elements[10],
self._elements[11] + m._elements[11],
self._elements[12] + m._elements[12],
self._elements[13] + m._elements[13],
self._elements[14] + m._elements[14],
self._elements[15] + m._elements[15]);
}
pub fn sub_scalar(&self, s: T) -> Matrix4x4<T> {
return Matrix4x4::new(self._elements[0] - s, self._elements[1] - s, self._elements[2] - s, self._elements[3] - s,
self._elements[4] - s, self._elements[5] - s, self._elements[6] - s, self._elements[7] - s,
self._elements[8] - s, self._elements[9] - s, self._elements[10] - s, self._elements[11] - s,
self._elements[12] - s, self._elements[13] - s, self._elements[14] - s, self._elements[15] - s);
}
pub fn sub_mat(&self, m: Matrix4x4<T>) -> Matrix4x4<T> {
return Matrix4x4::new(self._elements[0] - m._elements[0],
self._elements[1] - m._elements[1],
self._elements[2] - m._elements[2],
self._elements[3] - m._elements[3],
self._elements[4] - m._elements[4],
self._elements[5] - m._elements[5],
self._elements[6] - m._elements[6],
self._elements[7] - m._elements[7],
self._elements[8] - m._elements[8],
self._elements[9] - m._elements[9],
self._elements[10] - m._elements[10],
self._elements[11] - m._elements[11],
self._elements[12] - m._elements[12],
self._elements[13] - m._elements[13],
self._elements[14] - m._elements[14],
self._elements[15] - m._elements[15]);
}
pub fn mul_scalar(&self, s: T) -> Matrix4x4<T> {
return Matrix4x4::new(self._elements[0] * s, self._elements[1] * s, self._elements[2] * s, self._elements[3] * s,
self._elements[4] * s, self._elements[5] * s, self._elements[6] * s, self._elements[7] * s,
self._elements[8] * s, self._elements[9] * s, self._elements[10] * s, self._elements[11] * s,
self._elements[12] * s, self._elements[13] * s, self._elements[14] * s, self._elements[15] * s);
}
pub fn mul_vec(&self, v: Vector4<T>) -> Vector4<T> {
return Vector4::new(self._elements[0] * v.x + self._elements[1] * v.y + self._elements[2] * v.z + self._elements[3] * v.w,
self._elements[4] * v.x + self._elements[5] * v.y + self._elements[6] * v.z + self._elements[7] * v.w,
self._elements[8] * v.x + self._elements[9] * v.y + self._elements[10] * v.z + self._elements[11] * v.w,
self._elements[12] * v.x + self._elements[13] * v.y + self._elements[14] * v.z + self._elements[15] * v.w);
}
pub fn mul_mat(&self, m: Matrix4x4<T>) -> Matrix4x4<T> {
return Matrix4x4::new(
self._elements[0] * m._elements[0] + self._elements[1] * m._elements[4] + self._elements[2] * m._elements[8] + self._elements[3] * m._elements[12],
self._elements[0] * m._elements[1] + self._elements[1] * m._elements[5] + self._elements[2] * m._elements[9] + self._elements[3] * m._elements[13],
self._elements[0] * m._elements[2] + self._elements[1] * m._elements[6] + self._elements[2] * m._elements[10] + self._elements[3] * m._elements[14],
self._elements[0] * m._elements[3] + self._elements[1] * m._elements[7] + self._elements[2] * m._elements[11] + self._elements[3] * m._elements[15],
self._elements[4] * m._elements[0] + self._elements[5] * m._elements[4] + self._elements[6] * m._elements[8] + self._elements[7] * m._elements[12],
self._elements[4] * m._elements[1] + self._elements[5] * m._elements[5] + self._elements[6] * m._elements[9] + self._elements[7] * m._elements[13],
self._elements[4] * m._elements[2] + self._elements[5] * m._elements[6] + self._elements[6] * m._elements[10] + self._elements[7] * m._elements[14],
self._elements[4] * m._elements[3] + self._elements[5] * m._elements[7] + self._elements[6] * m._elements[11] + self._elements[7] * m._elements[15],
self._elements[8] * m._elements[0] + self._elements[9] * m._elements[4] + self._elements[10] * m._elements[8] + self._elements[11] * m._elements[12],
self._elements[8] * m._elements[1] + self._elements[9] * m._elements[5] + self._elements[10] * m._elements[9] + self._elements[11] * m._elements[13],
self._elements[8] * m._elements[2] + self._elements[9] * m._elements[6] + self._elements[10] * m._elements[10] + self._elements[11] * m._elements[14],
self._elements[8] * m._elements[3] + self._elements[9] * m._elements[7] + self._elements[10] * m._elements[11] + self._elements[11] * m._elements[15],
self._elements[12] * m._elements[0] + self._elements[13] * m._elements[4] + self._elements[14] * m._elements[8] + self._elements[15] * m._elements[12],
self._elements[12] * m._elements[1] + self._elements[13] * m._elements[5] + self._elements[14] * m._elements[9] + self._elements[15] * m._elements[13],
self._elements[12] * m._elements[2] + self._elements[13] * m._elements[6] + self._elements[14] * m._elements[10] + self._elements[15] * m._elements[14],
self._elements[12] * m._elements[3] + self._elements[13] * m._elements[7] + self._elements[14] * m._elements[11] + self._elements[15] * m._elements[15]);
}
pub fn div_scalar(&self, s: T) -> Matrix4x4<T> {
return Matrix4x4::new(self._elements[0] / s, self._elements[1] / s, self._elements[2] / s, self._elements[3] / s,
self._elements[4] / s, self._elements[5] / s, self._elements[6] / s, self._elements[7] / s,
self._elements[8] / s, self._elements[9] / s, self._elements[10] / s, self._elements[11] / s,
self._elements[12] / s, self._elements[13] / s, self._elements[14] / s, self._elements[15] / s);
}
}
impl<T: Float> Matrix4x4<T> {
pub fn radd_scalar(&self, s: T) -> Matrix4x4<T> {
return Matrix4x4::new(s + self._elements[0], s + self._elements[1], s + self._elements[2], s + self._elements[3],
s + self._elements[4], s + self._elements[5], s + self._elements[6], s + self._elements[7],
s + self._elements[8], s + self._elements[9], s + self._elements[10], s + self._elements[11],
s + self._elements[12], s + self._elements[13], s + self._elements[14], s + self._elements[15]);
}
pub fn radd_mat(&self, m: Matrix4x4<T>) -> Matrix4x4<T> {
return Matrix4x4::new(m._elements[0] + self._elements[0], m._elements[1] + self._elements[1], m._elements[2] + self._elements[2], m._elements[3] + self._elements[3],
m._elements[4] + self._elements[4], m._elements[5] + self._elements[5], m._elements[6] + self._elements[6], m._elements[7] + self._elements[7],
m._elements[8] + self._elements[8], m._elements[9] + self._elements[9], m._elements[10] + self._elements[10], m._elements[11] + self._elements[11],
m._elements[12] + self._elements[12], m._elements[13] + self._elements[13], m._elements[14] + self._elements[14], m._elements[15] + self._elements[15]);
}
pub fn rsub_scalar(&self, s: T) -> Matrix4x4<T> {
return Matrix4x4::new(s - self._elements[0], s - self._elements[1], s - self._elements[2], s - self._elements[3],
s - self._elements[4], s - self._elements[5], s - self._elements[6], s - self._elements[7],
s - self._elements[8], s - self._elements[9], s - self._elements[10], s - self._elements[11],
s - self._elements[12], s - self._elements[13], s - self._elements[14], s - self._elements[15]);
}
pub fn rsub_mat(&self, m: Matrix4x4<T>) -> Matrix4x4<T> {
return Matrix4x4::new(m._elements[0] - self._elements[0], m._elements[1] - self._elements[1], m._elements[2] - self._elements[2], m._elements[3] - self._elements[3],
m._elements[4] - self._elements[4], m._elements[5] - self._elements[5], m._elements[6] - self._elements[6], m._elements[7] - self._elements[7],
m._elements[8] - self._elements[8], m._elements[9] - self._elements[9], m._elements[10] - self._elements[10], m._elements[11] - self._elements[11],
m._elements[12] - self._elements[12], m._elements[13] - self._elements[13], m._elements[14] - self._elements[14], m._elements[15] - self._elements[15]);
}
pub fn rmul_scalar(&self, s: T) -> Matrix4x4<T> {
return Matrix4x4::new(s * self._elements[0], s * self._elements[1], s * self._elements[2], s * self._elements[3],
s * self._elements[4], s * self._elements[5], s * self._elements[6], s * self._elements[7],
s * self._elements[8], s * self._elements[9], s * self._elements[10], s * self._elements[11],
s * self._elements[12], s * self._elements[13], s * self._elements[14], s * self._elements[15]);
}
pub fn rmul_mat(&self, m: Matrix4x4<T>) -> Matrix4x4<T> {
return m.mul_mat(*self);
}
pub fn rdiv_scalar(&self, s: T) -> Matrix4x4<T> {
return Matrix4x4::new(s / self._elements[0], s / self._elements[1], s / self._elements[2], s / self._elements[3],
s / self._elements[4], s / self._elements[5], s / self._elements[6], s / self._elements[7],
s / self._elements[8], s / self._elements[9], s / self._elements[10], s / self._elements[11],
s / self._elements[12], s / self._elements[13], s / self._elements[14], s / self._elements[15]);
}
}
impl<T: Float> Matrix4x4<T> {
pub fn iadd_scalar(&mut self, s: T) {
self._elements[0] = self._elements[0] + s;
self._elements[1] = self._elements[1] + s;
self._elements[2] = self._elements[2] + s;
self._elements[3] = self._elements[3] + s;
self._elements[4] = self._elements[4] + s;
self._elements[5] = self._elements[5] + s;
self._elements[6] = self._elements[6] + s;
self._elements[7] = self._elements[7] + s;
self._elements[8] = self._elements[8] + s;
self._elements[9] = self._elements[9] + s;
self._elements[10] = self._elements[10] + s;
self._elements[11] = self._elements[11] + s;
self._elements[12] = self._elements[12] + s;
self._elements[13] = self._elements[13] + s;
self._elements[14] = self._elements[14] + s;
self._elements[15] = self._elements[15] + s;
}
pub fn iadd_mat(&mut self, m: Matrix4x4<T>) {
self._elements[0] = self._elements[0] + m._elements[0];
self._elements[1] = self._elements[1] + m._elements[1];
self._elements[2] = self._elements[2] + m._elements[2];
self._elements[3] = self._elements[3] + m._elements[3];
self._elements[4] = self._elements[4] + m._elements[4];
self._elements[5] = self._elements[5] + m._elements[5];
self._elements[6] = self._elements[6] + m._elements[6];
self._elements[7] = self._elements[7] + m._elements[7];
self._elements[8] = self._elements[8] + m._elements[8];
self._elements[9] = self._elements[9] + m._elements[9];
self._elements[10] = self._elements[10] + m._elements[10];
self._elements[11] = self._elements[11] + m._elements[11];
self._elements[12] = self._elements[12] + m._elements[12];
self._elements[13] = self._elements[13] + m._elements[13];
self._elements[14] = self._elements[14] + m._elements[14];
self._elements[15] = self._elements[15] + m._elements[15];
}
pub fn isub_scalar(&mut self, s: T) {
self._elements[0] = self._elements[0] - s;
self._elements[1] = self._elements[1] - s;
self._elements[2] = self._elements[2] - s;
self._elements[3] = self._elements[3] - s;
self._elements[4] = self._elements[4] - s;
self._elements[5] = self._elements[5] - s;
self._elements[6] = self._elements[6] - s;
self._elements[7] = self._elements[7] - s;
self._elements[8] = self._elements[8] - s;
self._elements[9] = self._elements[9] - s;
self._elements[10] = self._elements[10] - s;
self._elements[11] = self._elements[11] - s;
self._elements[12] = self._elements[12] - s;
self._elements[13] = self._elements[13] - s;
self._elements[14] = self._elements[14] - s;
self._elements[15] = self._elements[15] - s;
}
pub fn isub_mat(&mut self, m: Matrix4x4<T>) {
self._elements[0] = self._elements[0] - m._elements[0];
self._elements[1] = self._elements[1] - m._elements[1];
self._elements[2] = self._elements[2] - m._elements[2];
self._elements[3] = self._elements[3] - m._elements[3];
self._elements[4] = self._elements[4] - m._elements[4];
self._elements[5] = self._elements[5] - m._elements[5];
self._elements[6] = self._elements[6] - m._elements[6];
self._elements[7] = self._elements[7] - m._elements[7];
self._elements[8] = self._elements[8] - m._elements[8];
self._elements[9] = self._elements[9] - m._elements[9];
self._elements[10] = self._elements[10] - m._elements[10];
self._elements[11] = self._elements[11] - m._elements[11];
self._elements[12] = self._elements[12] - m._elements[12];
self._elements[13] = self._elements[13] - m._elements[13];
self._elements[14] = self._elements[14] - m._elements[14];
self._elements[15] = self._elements[15] - m._elements[15];
}
pub fn imul_scalar(&mut self, s: T) {
self._elements[0] = self._elements[0] * s;
self._elements[1] = self._elements[1] * s;
self._elements[2] = self._elements[2] * s;
self._elements[3] = self._elements[3] * s;
self._elements[4] = self._elements[4] * s;
self._elements[5] = self._elements[5] * s;
self._elements[6] = self._elements[6] * s;
self._elements[7] = self._elements[7] * s;
self._elements[8] = self._elements[8] * s;
self._elements[9] = self._elements[9] * s;
self._elements[10] = self._elements[10] * s;
self._elements[11] = self._elements[11] * s;
self._elements[12] = self._elements[12] * s;
self._elements[13] = self._elements[13] * s;
self._elements[14] = self._elements[14] * s;
self._elements[15] = self._elements[15] * s;
}
pub fn imul_mat(&mut self, m: Matrix4x4<T>) {
self.set_self(self.mul_mat(m));
}
pub fn idiv_scalar(&mut self, s: T) {
self._elements[0] = self._elements[0] / s;
self._elements[1] = self._elements[1] / s;
self._elements[2] = self._elements[2] / s;
self._elements[3] = self._elements[3] / s;
self._elements[4] = self._elements[4] / s;
self._elements[5] = self._elements[5] / s;
self._elements[6] = self._elements[6] / s;
self._elements[7] = self._elements[7] / s;
self._elements[8] = self._elements[8] / s;
self._elements[9] = self._elements[9] / s;
self._elements[10] = self._elements[10] / s;
self._elements[11] = self._elements[11] / s;
self._elements[12] = self._elements[12] / s;
self._elements[13] = self._elements[13] / s;
self._elements[14] = self._elements[14] / s;
self._elements[15] = self._elements[15] / s;
}
}
impl<T: Float> Matrix4x4<T> {
pub fn transpose(&mut self) {
let temp = self._elements[1];
self._elements[1] = self._elements[4];
self._elements[4] = temp;
let temp = self._elements[2];
self._elements[2] = self._elements[8];
self._elements[8] = temp;
let temp = self._elements[3];
self._elements[3] = self._elements[12];
self._elements[12] = temp;
let temp = self._elements[6];
self._elements[6] = self._elements[9];
self._elements[9] = temp;
let temp = self._elements[7];
self._elements[7] = self._elements[13];
self._elements[13] = temp;
let temp = self._elements[11];
self._elements[11] = self._elements[14];
self._elements[14] = temp;
}
pub fn invert(&mut self) {
let d = self.determinant();
let mut m = Matrix4x4::new_default();
m._elements[0] = self._elements[5] * self._elements[10] * self._elements[15] + self._elements[6] * self._elements[11] * self._elements[13] + self._elements[7] * self._elements[9] * self._elements[14] - self._elements[5] * self._elements[11] * self._elements[14] - self._elements[6] * self._elements[9] * self._elements[15] - self._elements[7] * self._elements[10] * self._elements[13];
m._elements[1] = self._elements[1] * self._elements[11] * self._elements[14] + self._elements[2] * self._elements[9] * self._elements[15] + self._elements[3] * self._elements[10] * self._elements[13] - self._elements[1] * self._elements[10] * self._elements[15] - self._elements[2] * self._elements[11] * self._elements[13] - self._elements[3] * self._elements[9] * self._elements[14];
m._elements[2] = self._elements[1] * self._elements[6] * self._elements[15] + self._elements[2] * self._elements[7] * self._elements[13] + self._elements[3] * self._elements[5] * self._elements[14] - self._elements[1] * self._elements[7] * self._elements[14] - self._elements[2] * self._elements[5] * self._elements[15] - self._elements[3] * self._elements[6] * self._elements[13];
m._elements[3] = self._elements[1] * self._elements[7] * self._elements[10] + self._elements[2] * self._elements[5] * self._elements[11] + self._elements[3] * self._elements[6] * self._elements[9] - self._elements[1] * self._elements[6] * self._elements[11] - self._elements[2] * self._elements[7] * self._elements[9] - self._elements[3] * self._elements[5] * self._elements[10];
m._elements[4] = self._elements[4] * self._elements[11] * self._elements[14] + self._elements[6] * self._elements[8] * self._elements[15] + self._elements[7] * self._elements[10] * self._elements[12] - self._elements[4] * self._elements[10] * self._elements[15] - self._elements[6] * self._elements[11] * self._elements[12] - self._elements[7] * self._elements[8] * self._elements[14];
m._elements[5] = self._elements[0] * self._elements[10] * self._elements[15] + self._elements[2] * self._elements[11] * self._elements[12] + self._elements[3] * self._elements[8] * self._elements[14] - self._elements[0] * self._elements[11] * self._elements[14] - self._elements[2] * self._elements[8] * self._elements[15] - self._elements[3] * self._elements[10] * self._elements[12];
m._elements[6] = self._elements[0] * self._elements[7] * self._elements[14] + self._elements[2] * self._elements[4] * self._elements[15] + self._elements[3] * self._elements[6] * self._elements[12] - self._elements[0] * self._elements[6] * self._elements[15] - self._elements[2] * self._elements[7] * self._elements[12] - self._elements[3] * self._elements[4] * self._elements[14];
m._elements[7] = self._elements[0] * self._elements[6] * self._elements[11] + self._elements[2] * self._elements[7] * self._elements[8] + self._elements[3] * self._elements[4] * self._elements[10] - self._elements[0] * self._elements[7] * self._elements[10] - self._elements[2] * self._elements[4] * self._elements[11] - self._elements[3] * self._elements[6] * self._elements[8];
m._elements[8] = self._elements[4] * self._elements[9] * self._elements[15] + self._elements[5] * self._elements[11] * self._elements[12] + self._elements[7] * self._elements[8] * self._elements[13] - self._elements[4] * self._elements[11] * self._elements[13] - self._elements[5] * self._elements[8] * self._elements[15] - self._elements[7] * self._elements[9] * self._elements[12];
m._elements[9] = self._elements[0] * self._elements[11] * self._elements[13] + self._elements[1] * self._elements[8] * self._elements[15] + self._elements[3] * self._elements[9] * self._elements[12] - self._elements[0] * self._elements[9] * self._elements[15] - self._elements[1] * self._elements[11] * self._elements[12] - self._elements[3] * self._elements[8] * self._elements[13];
m._elements[10] = self._elements[0] * self._elements[5] * self._elements[15] + self._elements[1] * self._elements[7] * self._elements[12] + self._elements[3] * self._elements[4] * self._elements[13] - self._elements[0] * self._elements[7] * self._elements[13] - self._elements[1] * self._elements[4] * self._elements[15] - self._elements[3] * self._elements[5] * self._elements[12];
m._elements[11] = self._elements[0] * self._elements[7] * self._elements[9] + self._elements[1] * self._elements[4] * self._elements[11] + self._elements[3] * self._elements[5] * self._elements[8] - self._elements[0] * self._elements[5] * self._elements[11] - self._elements[1] * self._elements[7] * self._elements[8] - self._elements[3] * self._elements[4] * self._elements[9];
m._elements[12] = self._elements[4] * self._elements[10] * self._elements[13] + self._elements[5] * self._elements[8] * self._elements[14] + self._elements[6] * self._elements[9] * self._elements[12] - self._elements[4] * self._elements[9] * self._elements[14] - self._elements[5] * self._elements[10] * self._elements[12] - self._elements[6] * self._elements[8] * self._elements[13];
m._elements[13] = self._elements[0] * self._elements[9] * self._elements[14] + self._elements[1] * self._elements[10] * self._elements[12] + self._elements[2] * self._elements[8] * self._elements[13] - self._elements[0] * self._elements[10] * self._elements[13] - self._elements[1] * self._elements[8] * self._elements[14] - self._elements[2] * self._elements[9] * self._elements[12];
m._elements[14] = self._elements[0] * self._elements[6] * self._elements[13] + self._elements[1] * self._elements[4] * self._elements[14] + self._elements[2] * self._elements[5] * self._elements[12] - self._elements[0] * self._elements[5] * self._elements[14] - self._elements[1] * self._elements[6] * self._elements[12] - self._elements[2] * self._elements[4] * self._elements[13];
m._elements[15] = self._elements[0] * self._elements[5] * self._elements[10] + self._elements[1] * self._elements[6] * self._elements[8] + self._elements[2] * self._elements[4] * self._elements[9] - self._elements[0] * self._elements[6] * self._elements[9] - self._elements[1] * self._elements[4] * self._elements[10] - self._elements[2] * self._elements[5] * self._elements[8];
m.idiv_scalar(d);
self.set_self(m);
}
}
impl<T: Float> Matrix4x4<T> {
pub fn sum(&self) -> T {
let mut s = T::zero();
for i in 0..16 {
s = s + self._elements[i];
}
return s;
}
pub fn avg(&self) -> T {
return self.sum() / T::from(16.0).unwrap();
}
pub fn min(&self) -> T {
let mut m = self._elements[0];
for i in 1..self._elements.len() {
m = T::min(m, self._elements[i]);
}
return m;
}
pub fn max(&self) -> T {
let mut m = self._elements[0];
for i in 1..self._elements.len() {
m = T::max(m, self._elements[i]);
}
return m;
}
pub fn absmin(&self) -> T {
let mut m = self._elements[0];
for i in 1..self._elements.len() {
m = crate::math_utils::absmin(m, self._elements[i]);
}
return m;
}
pub fn absmax(&self) -> T {
let mut m = self._elements[0];
for i in 1..self._elements.len() {
m = crate::math_utils::absmax(m, self._elements[i]);
}
return m;
}
pub fn trace(&self) -> T {
return self._elements[0] + self._elements[5] + self._elements[10] + self._elements[15];
}
pub fn determinant(&self) -> T {
return self._elements[0] * self._elements[5] * self._elements[10] * self._elements[15] + self._elements[0] * self._elements[6] * self._elements[11] * self._elements[13] + self._elements[0] * self._elements[7] * self._elements[9] * self._elements[14]
+ self._elements[1] * self._elements[4] * self._elements[11] * self._elements[14] + self._elements[1] * self._elements[6] * self._elements[8] * self._elements[15] + self._elements[1] * self._elements[7] * self._elements[10] * self._elements[12]
+ self._elements[2] * self._elements[4] * self._elements[9] * self._elements[15] + self._elements[2] * self._elements[5] * self._elements[11] * self._elements[12] + self._elements[2] * self._elements[7] * self._elements[8] * self._elements[13]
+ self._elements[3] * self._elements[4] * self._elements[10] * self._elements[13] + self._elements[3] * self._elements[5] * self._elements[8] * self._elements[14] + self._elements[3] * self._elements[6] * self._elements[9] * self._elements[12]
- self._elements[0] * self._elements[5] * self._elements[11] * self._elements[14] - self._elements[0] * self._elements[6] * self._elements[9] * self._elements[15] - self._elements[0] * self._elements[7] * self._elements[10] * self._elements[13]
- self._elements[1] * self._elements[4] * self._elements[10] * self._elements[15] - self._elements[1] * self._elements[6] * self._elements[11] * self._elements[12] - self._elements[1] * self._elements[7] * self._elements[8] * self._elements[14]
- self._elements[2] * self._elements[4] * self._elements[11] * self._elements[13] - self._elements[2] * self._elements[5] * self._elements[8] * self._elements[15] - self._elements[2] * self._elements[7] * self._elements[9] * self._elements[12]
- self._elements[3] * self._elements[4] * self._elements[9] * self._elements[14] - self._elements[3] * self._elements[5] * self._elements[10] * self._elements[12] - self._elements[3] * self._elements[6] * self._elements[8] * self._elements[13];
}
pub fn diagonal(&self) -> Matrix4x4<T> {
return Matrix4x4::new(self._elements[0], T::zero(), T::zero(), T::zero(),
T::zero(), self._elements[5], T::zero(), T::zero(),
T::zero(), T::zero(), self._elements[10], T::zero(),
T::zero(), T::zero(), T::zero(), self._elements[15]);
}
pub fn off_diagonal(&self) -> Matrix4x4<T> {
return Matrix4x4::new(T::zero(), self._elements[1], self._elements[2], self._elements[3],
self._elements[4], T::zero(), self._elements[6], self._elements[7],
self._elements[8], self._elements[9], T::zero(), self._elements[11],
self._elements[12], self._elements[13], self._elements[14], T::zero());
}
pub fn strict_lower_tri(&self) -> Matrix4x4<T> {
return Matrix4x4::new(T::zero(), T::zero(), T::zero(), T::zero(),
self._elements[4], T::zero(), T::zero(), T::zero(),
self._elements[8], self._elements[9], T::zero(), T::zero(),
self._elements[12], self._elements[13], self._elements[14], T::zero());
}
pub fn strict_upper_tri(&self) -> Matrix4x4<T> {
return Matrix4x4::new(T::zero(), self._elements[1], self._elements[2], self._elements[3],
T::zero(), T::zero(), self._elements[6], self._elements[7],
T::zero(), T::zero(), T::zero(), self._elements[11],
T::zero(), T::zero(), T::zero(), T::zero());
}
pub fn lower_tri(&self) -> Matrix4x4<T> {
return Matrix4x4::new(self._elements[0], T::zero(), T::zero(), T::zero(),
self._elements[4], self._elements[5], T::zero(), T::zero(),
self._elements[8], self._elements[9], self._elements[10], T::zero(),
self._elements[12], self._elements[13], self._elements[14], self._elements[15]);
}
pub fn upper_tri(&self) -> Matrix4x4<T> {
return Matrix4x4::new(self._elements[0], self._elements[1], self._elements[2], self._elements[3],
T::zero(), self._elements[5], self._elements[6], self._elements[7],
T::zero(), T::zero(), self._elements[10], self._elements[11],
T::zero(), T::zero(), T::zero(), self._elements[15]);
}
pub fn transposed(&self) -> Matrix4x4<T> {
return Matrix4x4::new(self._elements[0], self._elements[4], self._elements[8], self._elements[12],
self._elements[1], self._elements[5], self._elements[9], self._elements[13],
self._elements[2], self._elements[6], self._elements[10], self._elements[14],
self._elements[3], self._elements[7], self._elements[11], self._elements[15]);
}
pub fn inverse(&self) -> Matrix4x4<T> {
let mut m = *self;
m.invert();
return m;
}
}
impl<T: Float> Clone for Matrix4x4<T> {
fn clone(&self) -> Self {
return Matrix4x4 {
_elements: self._elements,
};
}
}
impl<T: Float> Copy for Matrix4x4<T> {}
impl<T: Float> AddAssign<T> for Matrix4x4<T> {
fn add_assign(&mut self, rhs: T) {
self.iadd_scalar(rhs);
}
}
impl<T: Float> AddAssign for Matrix4x4<T> {
fn add_assign(&mut self, rhs: Self) {
self.iadd_mat(rhs);
}
}
impl<T: Float> SubAssign<T> for Matrix4x4<T> {
fn sub_assign(&mut self, rhs: T) {
self.isub_scalar(rhs);
}
}
impl<T: Float> SubAssign for Matrix4x4<T> {
fn sub_assign(&mut self, rhs: Self) {
self.isub_mat(rhs);
}
}
impl<T: Float> MulAssign<T> for Matrix4x4<T> {
fn mul_assign(&mut self, rhs: T) {
self.imul_scalar(rhs);
}
}
impl<T: Float> MulAssign for Matrix4x4<T> {
fn mul_assign(&mut self, rhs: Self) {
self.imul_mat(rhs);
}
}
impl<T: Float> DivAssign<T> for Matrix4x4<T> {
fn div_assign(&mut self, rhs: T) {
self.idiv_scalar(rhs);
}
}
impl<T: Float> Index<usize> for Matrix4x4<T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
return &self._elements[index];
}
}
impl<T: Float> IndexMut<usize> for Matrix4x4<T> {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
return &mut self._elements[index];
}
}
impl<T: Float> Index<(usize, usize)> for Matrix4x4<T> {
type Output = T;
fn index(&self, index: (usize, usize)) -> &Self::Output {
return &self._elements[4 * index.0 + index.1];
}
}
impl<T: Float> IndexMut<(usize, usize)> for Matrix4x4<T> {
fn index_mut(&mut self, index: (usize, usize)) -> &mut Self::Output {
return &mut self._elements[4 * index.0 + index.1];
}
}
impl<T: Float> PartialEq for Matrix4x4<T> {
fn eq(&self, m: &Self) -> bool {
return self._elements[0] == m._elements[0] && self._elements[1] == m._elements[1] && self._elements[2] == m._elements[2] &&
self._elements[3] == m._elements[3] && self._elements[4] == m._elements[4] && self._elements[5] == m._elements[5] &&
self._elements[6] == m._elements[6] && self._elements[7] == m._elements[7] && self._elements[8] == m._elements[8] &&
self._elements[9] == m._elements[9] && self._elements[10] == m._elements[10] && self._elements[11] == m._elements[11] &&
self._elements[12] == m._elements[12] && self._elements[13] == m._elements[13] && self._elements[14] == m._elements[14] &&
self._elements[15] == m._elements[15];
}
}
impl<T: Float> Eq for Matrix4x4<T> {}
impl<T: Float> Matrix4x4<T> {
pub fn make_zero() -> Matrix4x4<T> {
return Matrix4x4::new(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());
}
pub fn make_identity() -> Matrix4x4<T> {
return Matrix4x4::new(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());
}
pub fn make_scale_matrix_scalar(sx: T, sy: T, sz: T) -> Matrix4x4<T> {
return Matrix4x4::new(sx, T::zero(), T::zero(), T::zero(),
T::zero(), sy, T::zero(), T::zero(),
T::zero(), T::zero(), sz, T::zero(),
T::zero(), T::zero(), T::zero(), T::one());
}
pub fn make_scale_matrix_vec(s: Vector3<T>) -> Matrix4x4<T> {
return Matrix4x4::new(s.x, T::zero(), T::zero(), T::zero(),
T::zero(), s.y, T::zero(), T::zero(),
T::zero(), T::zero(), s.z, T::zero(),
T::zero(), T::zero(), T::zero(), T::one());
}
pub fn make_rotation_matrix(axis: Vector3<T>, rad: T) -> Matrix4x4<T> {
return Matrix4x4::new_mat(Matrix3x3::make_rotation_matrix(axis, rad));
}
pub fn make_translation_matrix(t: Vector3<T>) -> Matrix4x4<T> {
return Matrix4x4::new(
T::one(), T::zero(), T::zero(), t.x,
T::zero(), T::one(), T::zero(), t.y,
T::zero(), T::zero(), T::one(), t.z,
T::zero(), T::zero(), T::zero(), T::one());
}
}
impl<T: Float> Neg for Matrix4x4<T> {
type Output = Matrix4x4<T>;
fn neg(self) -> Self::Output {
return Matrix4x4::new(-self._elements[0], -self._elements[1], -self._elements[2], -self._elements[3],
-self._elements[4], -self._elements[5], -self._elements[6], -self._elements[7],
-self._elements[8], -self._elements[9], -self._elements[10], -self._elements[11],
-self._elements[12], -self._elements[13], -self._elements[14], -self._elements[15]);
}
}
impl<T: Float> Add<T> for Matrix4x4<T> {
type Output = Matrix4x4<T>;
fn add(self, rhs: T) -> Self::Output {
return self.add_scalar(rhs);
}
}
impl<T: Float> Add for Matrix4x4<T> {
type Output = Matrix4x4<T>;
fn add(self, rhs: Self) -> Self::Output {
return self.add_mat(rhs);
}
}
impl<T: Float> Sub<T> for Matrix4x4<T> {
type Output = Matrix4x4<T>;
fn sub(self, rhs: T) -> Self::Output {
return self.sub_scalar(rhs);
}
}
impl<T: Float> Sub for Matrix4x4<T> {
type Output = Matrix4x4<T>;
fn sub(self, rhs: Self) -> Self::Output {
return self.sub_mat(rhs);
}
}
impl<T: Float> Mul<T> for Matrix4x4<T> {
type Output = Matrix4x4<T>;
fn mul(self, rhs: T) -> Self::Output {
return self.mul_scalar(rhs);
}
}
impl<T: Float> Mul<Vector4<T>> for Matrix4x4<T> {
type Output = Vector4<T>;
fn mul(self, rhs: Vector4<T>) -> Self::Output {
return self.mul_vec(rhs);
}
}
impl<T: Float> Mul for Matrix4x4<T> {
type Output = Matrix4x4<T>;
fn mul(self, rhs: Self) -> Self::Output {
return self.mul_mat(rhs);
}
}
impl<T: Float> Div<T> for Matrix4x4<T> {
type Output = Matrix4x4<T>;
fn div(self, rhs: T) -> Self::Output {
return self.div_scalar(rhs);
}
}