1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
use std::ops;
use serde::{Serialize, Deserialize};
use crate::traits::*;
use crate::Vec4;

#[repr(C)]
#[derive(Copy, Clone, PartialEq, Debug, Default)]
#[derive(Serialize, Deserialize)]
pub struct Mat4<T> {
    pub x: Vec4<T>,
    pub y: Vec4<T>,
    pub z: Vec4<T>,
    pub w: Vec4<T>,
}

impl<T: Number> Mat4<T> {
    pub const ZERO: Self = Self {
        x: Vec4::ZERO,
        y: Vec4::ZERO,
        z: Vec4::ZERO,
        w: Vec4::ZERO,
    };

    pub const ONE: Self = Self {
        x: Vec4::X,
        y: Vec4::Y,
        z: Vec4::Z,
        w: Vec4::W,
    };

    pub fn transpose(&self) -> Self {
        Self {
            x: Vec4::new(self.x.x, self.y.x, self.z.x, self.w.x),
            y: Vec4::new(self.x.y, self.y.y, self.z.y, self.w.y),
            z: Vec4::new(self.x.z, self.y.z, self.z.z, self.w.z),
            w: Vec4::new(self.x.w, self.y.w, self.z.w, self.w.w),
        }
    }
}

impl<T: Number> ops::Add for Mat4<T> {
    type Output = Self;

    #[inline(always)]
    fn add(self, other: Self) -> Self::Output { 
        Self {
            x: self.x + other.x,
            y: self.y + other.y,
            z: self.z + other.z,
            w: self.w + other.w,
        }
    }
}

impl<T: Number> ops::Mul for Mat4<T> {
    type Output = Self;

    #[inline(always)]
    fn mul(self, other: Self) -> Self::Output {
        Self {
            x: self.x * other.x.x + self.y * other.x.y + self.z * other.x.z + self.w * self.x.w,
            y: self.x * other.y.x + self.y * other.y.y + self.z * other.y.z + self.w * self.y.w,
            z: self.x * other.z.x + self.y * other.z.y + self.z * other.z.z + self.w * self.z.w,
            w: self.x * other.w.x + self.y * other.w.y + self.z * other.w.z + self.w * self.w.w,
        }
    }
}

impl<T: Number> ops::Mul<Vec4<T>> for Mat4<T> {
    type Output = Vec4<T>;

    #[inline(always)]
    fn mul(self, other: Vec4<T>) -> Self::Output {
        Vec4 {
            x: self.x.x * other.x + self.y.x * other.y + self.z.x * other.z + self.w.x * other.w,
            y: self.x.y * other.x + self.y.y * other.y + self.z.y * other.z + self.w.y * other.w,
            z: self.x.z * other.x + self.y.z * other.y + self.z.z * other.z + self.w.z * other.w,
            w: self.x.w * other.x + self.y.w * other.y + self.z.w * other.z + self.w.w * other.w,
        }
    }
}

impl<T: Number> ops::Mul<T> for Mat4<T> {
    type Output = Self;

    #[inline(always)]
    fn mul(self, other: T) -> Self {
        Self {
            x: self.x * other,
            y: self.y * other,
            z: self.z * other,
            w: self.w * other,
        }
    }
}

pub type Mat4B = Mat4<bool>;
pub type Mat4I = Mat4<i32>;
pub type Mat4U = Mat4<u32>;
pub type Mat4F = Mat4<f32>;
pub type Mat4D = Mat4<f64>;