1#[repr(C)]
3#[derive(Clone, Copy)]
4pub struct Mat4(pub [f32; 16]);
5
6impl std::fmt::Debug for Mat4 {
7 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
8 write!(f, "[\n\t{}, {}, {}, {}, \n\t{}, {}, {}, {}, \n\t{}, {}, {}, {}, \n\t{}, {}, {}, {}, \n]", self.0[0], self.0[1], self.0[2], self.0[3], self.0[4], self.0[5], self.0[6], self.0[7], self.0[8], self.0[9], self.0[10], self.0[11], self.0[12], self.0[13], self.0[14], self.0[15])
9 }
10}
11
12impl Mat4 {
13 pub fn new() -> Self {
15 Mat4([
16 1.0, 0.0, 0.0, 0.0,
17 0.0, 1.0, 0.0, 0.0,
18 0.0, 0.0, 1.0, 0.0,
19 0.0, 0.0, 0.0, 1.0,
20 ])
21 }
22
23 pub fn ptr(&self) -> *const f32 {
25 self.0.as_ptr()
26 }
27
28 pub fn add(&mut self, mat: Mat4) {
30 self.0.iter_mut().zip(mat.0.iter()).for_each(|(s, m)| *s+=m);
31 }
32
33 pub fn mult(&mut self, mat: Mat4) {
35 *self = Mat4([
36 mat.0[0] * self.0[0] + mat.0[1] * self.0[4] + mat.0[2] * self.0[8] + mat.0[3] * self.0[12] , mat.0[0] * self.0[1] + mat.0[1] * self.0[5] + mat.0[2] * self.0[9] + mat.0[3] * self.0[13] , mat.0[0] * self.0[2] + mat.0[1] * self.0[6] + mat.0[2] * self.0[10] + mat.0[3] * self.0[14] , mat.0[0] * self.0[3] + mat.0[1] * self.0[7] + mat.0[2] * self.0[11] + mat.0[3] * self.0[15],
37 mat.0[4] * self.0[0] + mat.0[5] * self.0[4] + mat.0[6] * self.0[8] + mat.0[7] * self.0[12] , mat.0[4] * self.0[1] + mat.0[5] * self.0[5] + mat.0[6] * self.0[9] + mat.0[7] * self.0[13] , mat.0[4] * self.0[2] + mat.0[5] * self.0[6] + mat.0[6] * self.0[10] + mat.0[7] * self.0[14] , mat.0[4] * self.0[3] + mat.0[5] * self.0[7] + mat.0[6] * self.0[11] + mat.0[7] * self.0[15],
38 mat.0[8] * self.0[0] + mat.0[9] * self.0[4] + mat.0[10] * self.0[8] + mat.0[11] * self.0[12] , mat.0[8] * self.0[1] + mat.0[9] * self.0[5] + mat.0[10] * self.0[9] + mat.0[11] * self.0[13] , mat.0[8] * self.0[2] + mat.0[9] * self.0[6] + mat.0[10] * self.0[10] + mat.0[11] * self.0[14] , mat.0[8] * self.0[3] + mat.0[9] * self.0[7] + mat.0[10] * self.0[11] + mat.0[11] * self.0[15],
39 mat.0[12] * self.0[0] + mat.0[13] * self.0[4] + mat.0[14] * self.0[8] + mat.0[15] * self.0[12] , mat.0[12] * self.0[1] + mat.0[13] * self.0[5] + mat.0[14] * self.0[9] + mat.0[15] * self.0[13] , mat.0[12] * self.0[2] + mat.0[13] * self.0[6] + mat.0[14] * self.0[10] + mat.0[15] * self.0[14] , mat.0[12] * self.0[3] + mat.0[13] * self.0[7] + mat.0[14] * self.0[11] + mat.0[15] * self.0[15],
40 ]);
41 }
42
43 pub fn div(&mut self, scalar: f32) {
45 self.0.iter_mut().for_each(|s| *s/=scalar);
46 }
47
48 pub fn interpolate(&mut self, mat: Mat4, advancement: f32) {
50 self.0.iter_mut().zip(mat.0.iter()).for_each(|(s, m)| *s = (1.0-advancement) * *s + advancement * m);
51 }
52
53 pub fn scale(x_scale: f32, y_scale: f32, z_scale: f32) -> Self {
56 Mat4([
57 x_scale , 0.0 , 0.0 , 0.0 ,
58 0.0 , y_scale , 0.0 , 0.0 ,
59 0.0 , 0.0 , z_scale , 0.0 ,
60 0.0 , 0.0 , 0.0 , 1.0 ,
61 ])
62 }
63
64 pub fn rotate_x(angle: f32) -> Self {
67 Mat4([
68 1.0 , 0.0 , 0.0 , 0.0 ,
69 0.0 , angle.cos() , angle.sin() , 0.0 ,
70 0.0 , -angle.sin(), angle.cos() , 0.0 ,
71 0.0 , 0.0 , 0.0 , 1.0 ,
72 ])
73 }
74
75 pub fn rotate_y(angle: f32) -> Self {
78 Mat4([
79 angle.cos() , 0.0 , angle.sin() , 0.0 ,
80 0.0 , 1.0 , 0.0 , 0.0 ,
81 -angle.sin(), 0.0 , angle.cos() , 0.0 ,
82 0.0 , 0.0 , 0.0 , 1.0 ,
83 ])
84 }
85
86 pub fn rotate_z(angle: f32) -> Self {
89 Mat4([
90 angle.cos() , angle.sin() , 0.0 , 0.0 ,
91 -angle.sin(), angle.cos() , 0.0 , 0.0 ,
92 0.0 , 0.0 , 1.0 , 0.0 ,
93 0.0 , 0.0 , 0.0 , 1.0 ,
94 ])
95 }
96
97 pub fn translate(x_move: f32, y_move: f32, z_move: f32) -> Self {
99 Mat4([
100 1.0 , 0.0 , 0.0 , x_move ,
101 0.0 , 1.0 , 0.0 , y_move ,
102 0.0 , 0.0 , 1.0 , z_move ,
103 0.0 , 0.0 , 0.0 , 1.0 ,
104 ])
105 }
106
107 pub fn lookat(eye_x: f32, eye_y: f32, eye_z: f32, target_x: f32, target_y: f32, target_z: f32, mut up_x: f32, mut up_y: f32, mut up_z: f32,) -> Self {
109 let (mut f_x, mut f_y, mut f_z) = (eye_x-target_x, eye_y-target_y, eye_z-target_z);
111 let invlen = 1.0 / (f_x*f_x+f_y*f_y+f_z*f_z).sqrt();
112 (f_x, f_y, f_z) = (f_x*invlen, f_y*invlen, f_z*invlen);
113
114 let (mut l_x, mut l_y, mut l_z) = (up_y*f_z - up_z*f_y, up_z*f_x - up_x*f_z, up_x*f_y - up_y*f_x);
116 let invlen = 1.0 / (l_x*l_x+l_y*l_y+l_z*l_z).sqrt();
117 (l_x, l_y, l_z) = (l_x*invlen, l_y*invlen, l_z*invlen);
118
119 (up_x, up_y, up_z) = (f_y*l_z - f_z*l_y, f_z*l_x - f_x*l_z, f_x*l_y - f_y*l_x);
121
122
123
124 let mut mat = Self::translate(-eye_x, -eye_y, -eye_z);
125 mat.mult(Mat4([
126 l_x , l_y , l_z , 0.0 ,
127 up_x, up_y, up_z, 0.0 ,
128 f_x , f_y , f_z , 0.0 ,
129 0.0 , 0.0 , 0.0 , 1.0 ,
130 ]));
131 mat
132 }
133
134 pub fn project_orthographic(l: f32, r: f32, b: f32, t: f32, n: f32, f: f32) -> Self {
137 Mat4([
138 2.0 / (r - l) , 0.0 , 0.0 , -(r + l) / (r - l) ,
139 0.0 , 2.0 / (t - b) , 0.0 , -(t + b) / (t - b) ,
140 0.0 , 0.0 , -2.0 / (f - n) , -(f + n) / (f - n) ,
141 0.0 , 0.0 , 0.0 , 1.0 ,
142 ])
143 }
144
145 pub fn project_perspective(l: f32, r: f32, b: f32, t: f32, n: f32, f: f32) -> Self {
148 Mat4([
149 2.0 * n/(r - l) , 0.0 , (r + l)/(r - l) , 0.0 ,
150 0.0 , 2.0 * n / (t - b) , (t + b) / (t - b) , 0.0 ,
151 0.0 , 0.0 , -(f + n) / (f - n) , -(2.0 * f * n)/(f - n) ,
152 0.0 , 0.0 , -1.0 , 0.0 ,
153 ])
154 }
155}