1use crate::matrix::Matrix;
2use crate::utils::EPSILON;
3use crate::vec4::Vec4;
4use std::f32;
5
6pub type Mat4 = [f32; 16];
7
8impl Matrix for Mat4 {
9 type MatrixType = Mat4;
10 type VectorType = Vec4;
11
12 fn zeros() -> Self {
13 [0.; 16]
14 }
15 fn ones() -> Self {
16 [1.; 16]
17 }
18 fn identity() -> Self {
19 [
20 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1., 0., 0., 0., 0., 1.,
21 ]
22 }
23
24 fn copy_to(&self, dst: &mut Self) {
25 for i in 0..16 {
26 dst[i] = self[i];
27 }
28 }
29
30 fn transpose(&mut self) -> &mut Self {
31 let v01 = self[1];
32 let v02 = self[2];
33 let v03 = self[3];
34 let v12 = self[6];
35 let v13 = self[7];
36 let v23 = self[11];
37
38 self[1] = self[4];
39 self[2] = self[8];
40 self[3] = self[12];
41 self[4] = v01;
42 self[6] = self[9];
43 self[7] = self[13];
44 self[8] = v02;
45 self[9] = v12;
46 self[11] = self[14];
47 self[12] = v03;
48 self[13] = v13;
49 self[14] = v23;
50
51 self
52 }
53
54 fn mul(&mut self, rhs: &Self) -> &mut Self {
55 let r00 = rhs[0];
56 let r01 = rhs[1];
57 let r02 = rhs[2];
58 let r03 = rhs[3];
59 let r10 = rhs[4];
60 let r11 = rhs[5];
61 let r12 = rhs[6];
62 let r13 = rhs[7];
63 let r20 = rhs[8];
64 let r21 = rhs[9];
65 let r22 = rhs[10];
66 let r23 = rhs[11];
67 let r30 = rhs[12];
68 let r31 = rhs[13];
69 let r32 = rhs[14];
70 let r33 = rhs[15];
71
72 let mut v0 = self[0];
73 let mut v1 = self[1];
74 let mut v2 = self[2];
75 let mut v3 = self[3];
76 self[0] = v0 * r00 + v1 * r10 + v2 * r20 + v3 * r30;
77 self[1] = v0 * r01 + v1 * r11 + v2 * r21 + v3 * r31;
78 self[2] = v0 * r02 + v1 * r12 + v2 * r22 + v3 * r32;
79 self[3] = v0 * r03 + v1 * r13 + v2 * r23 + v3 * r33;
80
81 v0 = self[4];
82 v1 = self[5];
83 v2 = self[6];
84 v3 = self[7];
85 self[4] = v0 * r00 + v1 * r10 + v2 * r20 + v3 * r30;
86 self[5] = v0 * r01 + v1 * r11 + v2 * r21 + v3 * r31;
87 self[6] = v0 * r02 + v1 * r12 + v2 * r22 + v3 * r32;
88 self[7] = v0 * r03 + v1 * r13 + v2 * r23 + v3 * r33;
89
90 v0 = self[8];
91 v1 = self[9];
92 v2 = self[10];
93 v3 = self[11];
94 self[8] = v0 * r00 + v1 * r10 + v2 * r20 + v3 * r30;
95 self[9] = v0 * r01 + v1 * r11 + v2 * r21 + v3 * r31;
96 self[10] = v0 * r02 + v1 * r12 + v2 * r22 + v3 * r32;
97 self[11] = v0 * r03 + v1 * r13 + v2 * r23 + v3 * r33;
98
99 v0 = self[12];
100 v1 = self[13];
101 v2 = self[14];
102 v3 = self[15];
103 self[12] = v0 * r00 + v1 * r10 + v2 * r20 + v3 * r30;
104 self[13] = v0 * r01 + v1 * r11 + v2 * r21 + v3 * r31;
105 self[14] = v0 * r02 + v1 * r12 + v2 * r22 + v3 * r32;
106 self[15] = v0 * r03 + v1 * r13 + v2 * r23 + v3 * r33;
107
108 self
109 }
110 fn mul_vector(&self, rhs: &[f32]) -> Vec4 {
111 debug_assert!(rhs.len() >= 3);
112 let x = rhs[0];
113 let y = rhs[1];
114 let z = rhs[2];
115 let w = if rhs.len() > 3 { rhs[3] } else { 1. };
116
117 [
118 self[0] * x + self[1] * y + self[2] * z + self[3] * w,
119 self[4] * x + self[5] * y + self[6] * z + self[7] * w,
120 self[8] * x + self[9] * y + self[10] * z + self[11] * w,
121 self[12] * x + self[13] * y + self[14] * z + self[15] * w,
122 ]
123 }
124 fn mul_vector_left(&self, lhs: &[f32]) -> Vec4 {
125 debug_assert!(lhs.len() >= 3);
126 let x = lhs[0];
127 let y = lhs[1];
128 let z = lhs[2];
129 let w = if lhs.len() > 3 { lhs[3] } else { 1. };
130 [
131 self[0] * x + self[4] * y + self[8] * z + self[12] * w,
132 self[1] * x + self[5] * y + self[9] * z + self[13] * w,
133 self[2] * x + self[6] * y + self[10] * z + self[14] * w,
134 self[3] * x + self[7] * y + self[11] * z + self[15] * w,
135 ]
136 }
137 fn add(&mut self, rhs: &Self) -> &mut Self {
138 for i in 0..16 {
139 self[i] += rhs[i];
140 }
141
142 self
143 }
144 fn sub(&mut self, rhs: &Self) -> &mut Self {
145 for i in 0..16 {
146 self[i] -= rhs[i];
147 }
148
149 self
150 }
151
152 fn scale(&mut self, factor: f32) -> &mut Self {
153 for i in 0..16 {
154 self[i] *= factor;
155 }
156
157 self
158 }
159
160 fn inverse(&mut self) -> Option<&mut Self> {
161 let v00 = self[0];
162 let v01 = self[1];
163 let v02 = self[2];
164 let v03 = self[3];
165 let v10 = self[4];
166 let v11 = self[5];
167 let v12 = self[6];
168 let v13 = self[7];
169 let v20 = self[8];
170 let v21 = self[9];
171 let v22 = self[10];
172 let v23 = self[11];
173 let v30 = self[12];
174 let v31 = self[13];
175 let v32 = self[14];
176 let v33 = self[15];
177
178 let tmp00 = v00 * v11 - v01 * v10;
179 let tmp01 = v00 * v12 - v02 * v10;
180 let tmp02 = v00 * v13 - v03 * v10;
181 let tmp03 = v01 * v12 - v02 * v11;
182 let tmp04 = v01 * v13 - v03 * v11;
183 let tmp05 = v02 * v13 - v03 * v12;
184 let tmp06 = v20 * v31 - v21 * v30;
185 let tmp07 = v20 * v32 - v22 * v30;
186 let tmp08 = v20 * v33 - v23 * v30;
187 let tmp09 = v21 * v32 - v22 * v31;
188 let tmp10 = v21 * v33 - v23 * v31;
189 let tmp11 = v22 * v33 - v23 * v32;
190
191 let det = tmp00 * tmp11 - tmp01 * tmp10 + tmp02 * tmp09 + tmp03 * tmp08 - tmp04 * tmp07
192 + tmp05 * tmp06;
193
194 if det.abs() <= EPSILON {
195 return None;
196 }
197 let det_inv = 1.0 / det;
198
199 self[0] = (v11 * tmp11 - v12 * tmp10 + v13 * tmp09) * det_inv;
200 self[1] = (v02 * tmp10 - v01 * tmp11 - v03 * tmp09) * det_inv;
201 self[2] = (v31 * tmp05 - v32 * tmp04 + v33 * tmp03) * det_inv;
202 self[3] = (v22 * tmp04 - v21 * tmp05 - v23 * tmp03) * det_inv;
203 self[4] = (v12 * tmp08 - v10 * tmp11 - v13 * tmp07) * det_inv;
204 self[5] = (v00 * tmp11 - v02 * tmp08 + v03 * tmp07) * det_inv;
205 self[6] = (v32 * tmp02 - v30 * tmp05 - v33 * tmp01) * det_inv;
206 self[7] = (v20 * tmp05 - v22 * tmp02 + v23 * tmp01) * det_inv;
207 self[8] = (v10 * tmp10 - v11 * tmp08 + v13 * tmp06) * det_inv;
208 self[9] = (v01 * tmp08 - v00 * tmp10 - v03 * tmp06) * det_inv;
209 self[10] = (v30 * tmp04 - v31 * tmp02 + v33 * tmp00) * det_inv;
210 self[11] = (v21 * tmp02 - v20 * tmp04 - v23 * tmp00) * det_inv;
211 self[12] = (v11 * tmp07 - v10 * tmp09 - v12 * tmp06) * det_inv;
212 self[13] = (v00 * tmp09 - v01 * tmp07 + v02 * tmp06) * det_inv;
213 self[14] = (v31 * tmp01 - v30 * tmp03 - v32 * tmp00) * det_inv;
214 self[15] = (v20 * tmp03 - v21 * tmp01 + v22 * tmp00) * det_inv;
215
216 Some(self)
217 }
218
219 fn det(&self) -> f32 {
220 let v00 = self[0];
221 let v01 = self[1];
222 let v02 = self[2];
223 let v03 = self[3];
224 let v10 = self[4];
225 let v11 = self[5];
226 let v12 = self[6];
227 let v13 = self[7];
228 let v20 = self[8];
229 let v21 = self[9];
230 let v22 = self[10];
231 let v23 = self[11];
232 let v30 = self[12];
233 let v31 = self[13];
234 let v32 = self[14];
235 let v33 = self[15];
236
237 let tmp00 = v00 * v11 - v01 * v10;
238 let tmp01 = v00 * v12 - v02 * v10;
239 let tmp02 = v00 * v13 - v03 * v10;
240 let tmp03 = v01 * v12 - v02 * v11;
241 let tmp04 = v01 * v13 - v03 * v11;
242 let tmp05 = v02 * v13 - v03 * v12;
243 let tmp06 = v20 * v31 - v21 * v30;
244 let tmp07 = v20 * v32 - v22 * v30;
245 let tmp08 = v20 * v33 - v23 * v30;
246 let tmp09 = v21 * v32 - v22 * v31;
247 let tmp10 = v21 * v33 - v23 * v31;
248 let tmp11 = v22 * v33 - v23 * v32;
249
250 tmp00 * tmp11 - tmp01 * tmp10 + tmp02 * tmp09 + tmp03 * tmp08 - tmp04 * tmp07
251 + tmp05 * tmp06
252 }
253
254 fn adjugate(&mut self) -> &mut Self {
255 let v00 = self[0];
256 let v01 = self[1];
257 let v02 = self[2];
258 let v03 = self[3];
259 let v10 = self[4];
260 let v11 = self[5];
261 let v12 = self[6];
262 let v13 = self[7];
263 let v20 = self[8];
264 let v21 = self[9];
265 let v22 = self[10];
266 let v23 = self[11];
267 let v30 = self[12];
268 let v31 = self[13];
269 let v32 = self[14];
270 let v33 = self[15];
271
272 self[0] = v11 * (v22 * v33 - v23 * v32) - v21 * (v12 * v33 - v13 * v32)
273 + v31 * (v12 * v23 - v13 * v22);
274 self[1] = -(v01 * (v22 * v33 - v23 * v32) - v21 * (v02 * v33 - v03 * v32)
275 + v31 * (v02 * v23 - v03 * v22));
276 self[2] = v01 * (v12 * v33 - v13 * v32) - v11 * (v02 * v33 - v03 * v32)
277 + v31 * (v02 * v13 - v03 * v12);
278 self[3] = -(v01 * (v12 * v23 - v13 * v22) - v11 * (v02 * v23 - v03 * v22)
279 + v21 * (v02 * v13 - v03 * v12));
280 self[4] = -(v10 * (v22 * v33 - v23 * v32) - v20 * (v12 * v33 - v13 * v32)
281 + v30 * (v12 * v23 - v13 * v22));
282 self[5] = v00 * (v22 * v33 - v23 * v32) - v20 * (v02 * v33 - v03 * v32)
283 + v30 * (v02 * v23 - v03 * v22);
284 self[6] = -(v00 * (v12 * v33 - v13 * v32) - v10 * (v02 * v33 - v03 * v32)
285 + v30 * (v02 * v13 - v03 * v12));
286 self[7] = v00 * (v12 * v23 - v13 * v22) - v10 * (v02 * v23 - v03 * v22)
287 + v20 * (v02 * v13 - v03 * v12);
288 self[8] = v10 * (v21 * v33 - v23 * v31) - v20 * (v11 * v33 - v13 * v31)
289 + v30 * (v11 * v23 - v13 * v21);
290 self[9] = -(v00 * (v21 * v33 - v23 * v31) - v20 * (v01 * v33 - v03 * v31)
291 + v30 * (v01 * v23 - v03 * v21));
292 self[10] = v00 * (v11 * v33 - v13 * v31) - v10 * (v01 * v33 - v03 * v31)
293 + v30 * (v01 * v13 - v03 * v11);
294 self[11] = -(v00 * (v11 * v23 - v13 * v21) - v10 * (v01 * v23 - v03 * v21)
295 + v20 * (v01 * v13 - v03 * v11));
296 self[12] = -(v10 * (v21 * v32 - v22 * v31) - v20 * (v11 * v32 - v12 * v31)
297 + v30 * (v11 * v22 - v12 * v21));
298 self[13] = v00 * (v21 * v32 - v22 * v31) - v20 * (v01 * v32 - v02 * v31)
299 + v30 * (v01 * v22 - v02 * v21);
300 self[14] = -(v00 * (v11 * v32 - v12 * v31) - v10 * (v01 * v32 - v02 * v31)
301 + v30 * (v01 * v12 - v02 * v11));
302 self[15] = v00 * (v11 * v22 - v12 * v21) - v10 * (v01 * v22 - v02 * v21)
303 + v20 * (v01 * v12 - v02 * v11);
304
305 self
306 }
307
308 fn translate(&mut self, direction: &[f32]) -> &mut Self {
309 debug_assert!(direction.len() >= 3);
310
311 let mut x = direction[0];
312 let mut y = direction[1];
313 let mut z = direction[2];
314
315 if direction.len() > 3 {
316 x /= direction[3];
317 y /= direction[3];
318 z /= direction[3];
319 }
320
321 self[12] += self[0] * x + self[4] * y + self[8] * z;
322 self[13] += self[1] * x + self[5] * y + self[9] * z;
323 self[14] += self[2] * x + self[6] * y + self[10] * z;
324 self[15] += self[3] * x + self[7] * y + self[11] * z;
325
326 self
327 }
328
329 fn rotate(&mut self, angle: f32, axis: &[f32]) -> &mut Self {
330 debug_assert!(axis.len() >= 3);
331
332 let mut x = axis[0];
333 let mut y = axis[1];
334 let mut z = axis[2];
335
336 if axis.len() > 3 {
337 x /= axis[3];
338 y /= axis[3];
339 z /= axis[3];
340 }
341
342 let len = (x * x + y * y + z * z).sqrt();
343
344 if len.abs() <= EPSILON {
346 debug_assert!(len.abs() > EPSILON);
347 return self;
348 }
349
350 x /= len;
351 y /= len;
352 z /= len;
353
354 let (s, c) = angle.sin_cos();
355 let t = 1. - c;
356
357 let v00 = self[0];
358 let v01 = self[1];
359 let v02 = self[2];
360 let v03 = self[3];
361 let v10 = self[4];
362 let v11 = self[5];
363 let v12 = self[6];
364 let v13 = self[7];
365 let v20 = self[8];
366 let v21 = self[9];
367 let v22 = self[10];
368 let v23 = self[11];
369
370 let rot00 = x * x * t + c;
371 let rot01 = y * x * t + z * s;
372 let rot02 = z * x * t - y * s;
373
374 let rot10 = x * y * t - z * s;
375 let rot11 = y * y * t + c;
376 let rot12 = z * y * t + x * s;
377
378 let rot20 = x * z * t + y * s;
379 let rot21 = y * z * t - x * s;
380 let rot22 = z * z * t + c;
381
382 self[0] = v00 * rot00 + v10 * rot01 + v20 * rot02;
383 self[1] = v01 * rot00 + v11 * rot01 + v21 * rot02;
384 self[2] = v02 * rot00 + v12 * rot01 + v22 * rot02;
385 self[3] = v03 * rot00 + v13 * rot01 + v23 * rot02;
386 self[4] = v00 * rot10 + v10 * rot11 + v20 * rot12;
387 self[5] = v01 * rot10 + v11 * rot11 + v21 * rot12;
388 self[6] = v02 * rot10 + v12 * rot11 + v22 * rot12;
389 self[7] = v03 * rot10 + v13 * rot11 + v23 * rot12;
390 self[8] = v00 * rot20 + v10 * rot21 + v20 * rot22;
391 self[9] = v01 * rot20 + v11 * rot21 + v21 * rot22;
392 self[10] = v02 * rot20 + v12 * rot21 + v22 * rot22;
393 self[11] = v03 * rot20 + v13 * rot21 + v23 * rot22;
394
395 self
396 }
397}
398
399pub trait ProjectionMatrix {
400 fn create_perspective(fov_y: f32, aspect_ratio: f32, near: f32, far: f32) -> Mat4;
401 fn create_perspective_from_viewport(
402 vp_left: f32,
403 vp_right: f32,
404 vp_bot: f32,
405 vp_top: f32,
406 near: f32,
407 far: f32,
408 ) -> Mat4;
409
410 fn create_orthogonal_from_viewport(
411 vp_left: f32,
412 vp_right: f32,
413 vp_bot: f32,
414 vp_top: f32,
415 near: f32,
416 far: f32,
417 ) -> Mat4;
418}
419
420impl ProjectionMatrix for Mat4 {
421 fn create_perspective(fov_y: f32, aspect_ratio: f32, near: f32, far: f32) -> Self {
422 let f = 1. / (fov_y / 2.).tan();
423 let nf = 1. / (near - far);
424 [
425 f / aspect_ratio,
426 0.,
427 0.,
428 0.,
429 0.,
430 f,
431 0.,
432 0.,
433 0.,
434 0.,
435 (far + near) * nf,
436 -1.,
437 0.,
438 0.,
439 2. * far * near * nf,
440 0.,
441 ]
442 }
443 fn create_perspective_from_viewport(
444 vp_left: f32,
445 vp_right: f32,
446 vp_bot: f32,
447 vp_top: f32,
448 near: f32,
449 far: f32,
450 ) -> Self {
451 let wi = 1. / (vp_right - vp_left);
452 let hi = 1. / (vp_top - vp_bot);
453 let nf = 1. / (near - far);
454
455 [
456 near * 2. * wi,
457 0.,
458 0.,
459 0.,
460 0.,
461 near * 2. * hi,
462 0.,
463 0.,
464 (vp_right + vp_left) * wi,
465 (vp_top + vp_bot) * hi,
466 (far + near) * nf,
467 -1.,
468 0.,
469 0.,
470 far * near * 2. * nf,
471 0.,
472 ]
473 }
474
475 fn create_orthogonal_from_viewport(
476 vp_left: f32,
477 vp_right: f32,
478 vp_bot: f32,
479 vp_top: f32,
480 near: f32,
481 far: f32,
482 ) -> Self {
483 let wi = 1. / (vp_right - vp_left);
484 let hi = 1. / (vp_top - vp_bot);
485 let nf = 1. / (near - far);
486
487 [
488 2. * wi,
489 0.,
490 0.,
491 0.,
492 0.,
493 2. * hi,
494 0.,
495 0.,
496 0.,
497 0.,
498 2. * nf,
499 0.,
500 -(vp_left + vp_right) * wi,
501 -(vp_top + vp_bot) * hi,
502 (far + near) * nf,
503 1.,
504 ]
505 }
506}
507
508#[cfg(test)]
509mod tests {
510 use super::*;
511 use crate::utils::almost_eq;
512
513 #[test]
514 fn mat4_zeros() {
515 let zeros = Mat4::zeros();
516 assert!(zeros.iter().all(|&x| x == 0.0));
517 }
518
519 #[test]
520 fn mat4_ones() {
521 let zeros = Mat4::ones();
522 assert!(zeros.iter().all(|&x| x == 1.0));
523 }
524
525 #[test]
526 fn mat4_identity() {
527 let i = Mat4::identity();
528 assert_eq!(i[0], 1.0);
529 assert_eq!(i[1], 0.0);
530 assert_eq!(i[2], 0.0);
531 assert_eq!(i[3], 0.0);
532
533 assert_eq!(i[4], 0.0);
534 assert_eq!(i[5], 1.0);
535 assert_eq!(i[6], 0.0);
536 assert_eq!(i[7], 0.0);
537
538 assert_eq!(i[8], 0.0);
539 assert_eq!(i[9], 0.0);
540 assert_eq!(i[10], 1.0);
541 assert_eq!(i[11], 0.0);
542
543 assert_eq!(i[12], 0.0);
544 assert_eq!(i[13], 0.0);
545 assert_eq!(i[14], 0.0);
546 assert_eq!(i[15], 1.0);
547 }
548
549 #[test]
550 fn mat4_copy_to() {
551 let mut a = Mat4::zeros();
552 let b = Mat4::ones();
553
554 b.copy_to(&mut a);
555 assert!(a.iter().all(|&x| x == 1.0));
556 }
557
558 #[test]
559 fn mat4_transpose() {
560 let mut a = [
572 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16.,
573 ];
574 a.transpose();
575 let b = [
576 1., 5., 9., 13., 2., 6., 10., 14., 3., 7., 11., 15., 4., 8., 12., 16.,
577 ];
578
579 assert_eq!(a, b);
580 }
581
582 #[test]
583 fn mat4_mul() {
584 let mut a = [
585 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16.,
586 ];
587 let b = [
588 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., 22., 23., 24., 25., 26.,
589 ];
590
591 let c = [
592 190., 200., 210., 220., 462., 488., 514., 540., 734., 776., 818., 860., 1006., 1064.,
593 1122., 1180.,
594 ];
595
596 assert_eq!(a.mul(&b), &c);
597 }
598
599 #[test]
600 fn mat4_mul_identity() {
601 let a = [
602 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16.,
603 ];
604 let mut b = Mat4::identity();
605
606 assert_eq!(b.mul(&a), &a);
607 }
608
609 #[test]
610 fn mat4_add() {
611 let mut a = [
612 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16.,
613 ];
614 let b = [
615 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., 22., 23., 24., 25., 26.,
616 ];
617
618 let c = [
619 12., 14., 16., 18., 20., 22., 24., 26., 28., 30., 32., 34., 36., 38., 40., 42.,
620 ];
621
622 assert_eq!(a.add(&b), &c);
623 }
624
625 #[test]
626 fn mat4_sub() {
627 let mut a = [
628 16., 15., 14., 13., 12., 11., 10., 9., 8., 7., 6., 5., 4., 3., 2., 1.,
629 ];
630 let b = [
631 11., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., 22., 23., 24., 25., 26.,
632 ];
633
634 let c = [
635 5., 3., 1., -1., -3., -5., -7., -9., -11., -13., -15., -17., -19., -21., -23., -25.,
636 ];
637
638 assert_eq!(a.sub(&b), &c);
639 }
640
641 #[test]
642 fn mat4_scale() {
643 let mut a = [
644 16., 15., 14., 13., 12., 11., 10., 9., 8., 7., 6., 5., 4., 3., 2., 1.,
645 ];
646 let b = [
647 32., 30., 28., 26., 24., 22., 20., 18., 16., 14., 12., 10., 8., 6., 4., 2.,
648 ];
649
650 assert_eq!(a.scale(2.0), &b);
651 }
652
653 #[test]
654 fn mat4_inverse_valid() {
655 let mut a = [
656 3., 4., 1., 2., 3., 6., 10., 12., 2., 7., 3., 14., 16., 4., 8., 18.,
657 ];
658 let b = a.clone();
659
660 a.inverse().expect("Inverse should exist");
661
662 let inv = [
663 0.0976342, -0.0401802, -0.0548254, 0.0585805, 0.2482163, 0.0093879, 0.0221555,
664 -0.0510702, -0.0168982, 0.1415697, -0.1058956, -0.0101389, -0.1344348, -0.0292903,
665 0.0908750, 0.0193391,
666 ];
667
668 assert!(almost_eq(&inv, &a));
669
670 assert!(almost_eq(a.mul(&b), &Mat4::identity()));
671 }
672
673 #[test]
674 fn mat4_inverse_invalid() {
675 let mut a = [
676 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16.,
677 ];
678 assert_eq!(a.inverse(), None);
679 }
680
681 #[test]
682 fn mat4_det() {
683 let a = [
684 3., 4., 1., 2., 3., 6., 10., 12., 2., 7., 3., 14., 16., 4., 8., 18.,
685 ];
686 assert_eq!(a.det(), -5326.0);
687 }
688
689 #[test]
690 fn mat4_adjugate() {
691 let mut a = [
692 3., 4., 1., 2., 3., 6., 10., 12., 2., 7., 3., 14., 16., 4., 8., 18.,
693 ];
694 let b = [
695 -520., 214., 292., -312., -1322., -50., -118., 272., 90., -754., 564., 54., 716., 156.,
696 -484., -103.,
697 ];
698 assert_eq!(a.adjugate(), &b);
699 }
700
701 #[test]
702 fn mat4_mul_vector() {
703 let a = [
704 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16.,
705 ];
706 let b = [17., 18., 19., 20.];
707
708 let c = a.mul_vector(&b);
709 assert_eq!(c, [190., 486., 782., 1078.]);
710 }
711
712 #[test]
713 fn mat4_mul_vector_left() {
714 let a = [
715 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15., 16.,
716 ];
717 let b = [17., 18., 19., 20.];
718
719 let c = a.mul_vector_left(&b);
720 assert_eq!(c, [538., 612., 686., 760.]);
721 }
722
723 #[test]
724 fn mat4_translate() {
725 let d = [3., -5., 7., 1.];
726 let mut m = Mat4::identity();
727 m.translate(&d);
728
729 let a = [-3., 5., -7., 1.];
730 assert_eq!(m.mul_vector_left(&a), [0., 0., 0., 1.]);
731 }
732
733 #[test]
734 fn mat4_rotate_x() {
735 let mut m = Mat4::identity();
736 m.rotate(f32::consts::FRAC_PI_2, &[1., 0., 0., 1.]);
737 let v = [-1., 3., 5., 1.];
738
739 let r = m.mul_vector_left(&v);
740 assert!(almost_eq(&r, &[-1., -5., 3., 1.]));
741 }
742
743 #[test]
744 fn mat4_rotate_y() {
745 let mut m = Mat4::identity();
746 m.rotate(f32::consts::FRAC_PI_2, &[0., 1., 0., 1.]);
747 let v = [-1., 3., 5., 1.];
748
749 let r = m.mul_vector_left(&v);
750 assert!(almost_eq(&r, &[5., 3., 1., 1.]));
751 }
752
753 #[test]
754 fn mat4_rotate_z() {
755 let mut m = Mat4::identity();
756 m.rotate(f32::consts::FRAC_PI_2, &[0., 0., 1., 1.]);
757 let v = [-1., 3., 5., 1.];
758
759 let r = m.mul_vector_left(&v);
760 assert!(almost_eq(&r, &[-3., -1., 5., 1.]));
761 }
762}