1use std::{
2 fmt,
3 fmt::{
4 Display,
5 Formatter
6 },
7 ops::{
8 Add,
9 AddAssign,
10 Index,
11 IndexMut,
12 Sub,
13 SubAssign,
14 Mul,
15 MulAssign,
16 Div,
17 Neg
18 }
19};
20use crate::{Float, matrix3, matrix3::Matrix3, vec4, vector4::Vector4, vector3::Vector3};
21extern crate wasm_bindgen;
22use std::f64::consts::PI;
23use wasm_bindgen::prelude::*;
24use super::matrix::Matrix;
25
26
27
28#[macro_export]
29macro_rules! matrix4 {
30 (
31 $x1:expr, $y1:expr, $z1:expr, $t1:expr,
32 $x2:expr, $y2:expr, $z2:expr, $t2:expr,
33 $x3:expr, $y3:expr, $z3:expr, $t3:expr,
34 $x4:expr, $y4:expr, $z4:expr, $t4:expr
35 ) => {
36 {
37 Matrix4::new([
38 $x1, $y1, $z1, $t1,
39 $x2, $y2, $z2, $t2,
40 $x3, $y3, $z3, $t3,
41 $x4, $y4, $z4, $t4
42 ])
43 }
44 };
45}
46
47
48
49#[macro_export]
50macro_rules! compose_basis4 {
51 (
52 $x:expr,
53 $y:expr,
54 $z:expr,
55 $t:expr
56 ) => {
57 {
58 Matrix4::new([
59 $x[0], $y[0], $z[0], $t[0],
60 $x[1], $y[1], $z[1], $t[1],
61 $x[2], $y[2], $z[2], $t[2],
62 $x[3], $y[3], $z[3], $t[3]
63 ])
64 }
65 };
66}
67
68
69
70#[wasm_bindgen]
71extern "C" {
72 #[wasm_bindgen(js_namespace = console)]
73 fn log(s: &str);
74}
75
76
77
78#[macro_export]
79macro_rules! compose_m4 {
80 ($v:expr) => { $v };
81 ($v:expr, $($x:expr),+) => {
82
83 &( $v ) * &( compose_m4!($($x),*) )
84
85 }
86}
87
88
89
90#[derive(Clone, Debug)]
91pub struct Matrix4 {
92 pub data: [Float; 16]
93}
94
95
96
97impl Display for Matrix4 {
98 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
99 write!(f,
100 "\n [{}, {}, {}, {}] \n [{}, {}, {}, {}] \n [{}, {}, {}, {}] \n [{}, {}, {}, {}] \n",
101 self[0], self[1], self[2], self[3],
102 self[4], self[5], self[6], self[7],
103 self[8], self[9], self[10], self[11],
104 self[12], self[13], self[14], self[15]
105 )
106 }
107}
108
109
110
111impl Index<usize> for Matrix4 {
112 type Output = Float;
113
114 fn index(&self, idx:usize) -> &Float {
115 &self.data[idx]
116 }
117}
118
119
120
121impl IndexMut<usize> for Matrix4 {
122 fn index_mut(&mut self, idx:usize) -> &mut Float {
123 &mut self.data[idx]
124 }
125}
126
127
128
129impl Index<[usize;2]> for Matrix4 {
130 type Output = Float;
131
132 fn index(&self, idx:[usize;2]) -> &Float {
133 &self.data[idx[0] * 4 + idx[1]]
134 }
135}
136
137
138
139impl IndexMut<[usize;2]> for Matrix4 {
140 fn index_mut(&mut self, idx:[usize;2]) -> &mut Float {
141 &mut self.data[idx[0] * 4 + idx[1]]
142 }
143}
144
145
146
147impl Matrix4 {
148
149 pub fn new(data: [Float; 16]) -> Matrix4 {
150 Matrix4 {
151 data
152 }
153 }
154
155
156
157 pub fn id() -> Matrix4 {
158 Matrix4::new([
159 1., 0., 0., 0.,
160 0., 1., 0., 0.,
161 0., 0., 1., 0.,
162 0., 0., 0., 1.
163 ])
164 }
165
166
167
168 pub fn transpose(&self) -> Matrix4 {
169 Matrix4::new([
170 self[0], self[4], self[8], self[12],
171 self[1], self[5], self[9], self[13],
172 self[2], self[6], self[10], self[14],
173 self[3], self[7], self[11], self[15]
174 ])
175 }
176
177
178
179 pub fn det(&self) -> Float {
180 let a = matrix3![
181 self[5], self[6], self[7],
182 self[9], self[10], self[11],
183 self[13], self[14], self[15]
184 ];
185 let b = matrix3![
186 self[4], self[6], self[7],
187 self[8], self[10], self[11],
188 self[12], self[14], self[15]
189 ];
190 let c = matrix3![
191 self[4], self[5], self[7],
192 self[8], self[9], self[11],
193 self[12], self[13], self[15]
194 ];
195 let d = matrix3![
196 self[4], self[5], self[6],
197 self[8], self[9], self[10],
198 self[12], self[13], self[14]
199 ];
200
201 self[0] * a.det() - self[1] * b.det() + self[2] * c.det() - self[3] * d.det()
202 }
203
204
205
206 pub fn inv(&self) -> Option<Matrix4> {
207 let s = self.det();
208
209 if s==0. {
210 return None;
211 }
212
213 let x1 = matrix3![
214 self[5], self[6], self[7],
215 self[9], self[10], self[11],
216 self[13], self[14], self[15]
217 ];
218 let y1 = matrix3![
219 self[4], self[6], self[7],
220 self[8], self[10], self[11],
221 self[12], self[14], self[15]
222 ];
223 let z1 = matrix3![
224 self[4], self[5], self[7],
225 self[8], self[9], self[11],
226 self[12], self[13], self[15]
227 ];
228 let t1 = matrix3![
229 self[4], self[5], self[6],
230 self[8], self[9], self[10],
231 self[12], self[13], self[14]
232 ];
233
234 let x2 = matrix3![
235 self[1], self[2], self[3],
236 self[9], self[10], self[11],
237 self[13], self[14], self[15]
238 ];
239 let y2 = matrix3![
240 self[0], self[2], self[3],
241 self[8], self[10], self[11],
242 self[12], self[14], self[15]
243 ];
244 let z2 = matrix3![
245 self[0], self[1], self[3],
246 self[8], self[9], self[11],
247 self[12], self[13], self[15]
248 ];
249 let t2 = matrix3![
250 self[0], self[1], self[2],
251 self[8], self[9], self[10],
252 self[12], self[13], self[14]
253 ];
254
255 let x3 = matrix3![
256 self[1], self[2], self[3],
257 self[5], self[6], self[7],
258 self[13], self[14], self[15]
259 ];
260 let y3 = matrix3![
261 self[0], self[2], self[3],
262 self[4], self[6], self[7],
263 self[12], self[14], self[15]
264 ];
265 let z3 = matrix3![
266 self[0], self[1], self[3],
267 self[4], self[5], self[7],
268 self[12], self[13], self[15]
269 ];
270 let t3 = matrix3![
271 self[0], self[1], self[2],
272 self[4], self[5], self[6],
273 self[12], self[13], self[14]
274 ];
275
276 let x4 = matrix3![
277 self[1], self[2], self[3],
278 self[5], self[6], self[7],
279 self[9], self[10], self[11]
280 ];
281 let y4 = matrix3![
282 self[0], self[2], self[3],
283 self[4], self[6], self[7],
284 self[8], self[10], self[11]
285 ];
286 let z4 = matrix3![
287 self[0], self[1], self[3],
288 self[4], self[5], self[7],
289 self[8], self[9], self[11]
290 ];
291 let t4 = matrix3![
292 self[0], self[1], self[2],
293 self[4], self[5], self[6],
294 self[8], self[9], self[10]
295 ];
296
297 let mut m = matrix4![
298 x1.det(), -y1.det(), z1.det(), -t1.det(),
299 -x2.det(), y2.det(), -z2.det(), t2.det(),
300 x3.det(), -y3.det(), z3.det(), -t3.det(),
301 -x4.det(), y4.det(), -z4.det(), t4.det()
302 ];
303
304 m = m.transpose();
305
306 m = m * (1./s);
307
308 Some(m)
309 }
310
311
312
313 pub fn rot_x(x_rad: f64) -> Matrix4 {
314
315 let x = matrix4![
316 1., 0., 0., 0.,
317 0., x_rad.cos(),-x_rad.sin(), 0.,
318 0., x_rad.sin(), x_rad.cos(), 0.,
319 0., 0., 0., 1.
320 ];
321
322 x
323 }
324
325
326
327 pub fn rot_y(y_rad: f64) -> Matrix4 {
328
329 let y = matrix4![
330 y_rad.cos(), 0., y_rad.sin(), 0.,
331 0., 1., 0., 0.,
332 -y_rad.sin(), 0., y_rad.cos(), 0.,
333 0., 0., 0., 1.
334 ];
335
336 y
337 }
338
339
340
341 pub fn rot_z(z_rad: f64) -> Matrix4 {
342
343 let z = matrix4![
344 z_rad.cos(),-z_rad.sin(), 0., 0.,
345 z_rad.sin(), z_rad.cos(), 0., 0.,
346 0., 0., 1., 0.,
347 0., 0., 0., 1.
348 ];
349
350 z
351 }
352
353
354
355 pub fn rotation(x_rad: f64, y_rad: f64, z_rad: f64) -> Matrix4 {
356
357 let x = Matrix4::rot_x(x_rad);
358 let y = Matrix4::rot_y(y_rad);
359 let z = Matrix4::rot_z(z_rad);
360
361 x * y * z
362 }
363
364
365
366 pub fn scale(s: f64) -> Matrix4 {
367 matrix4![
368 s, 0., 0., 0.,
369 0., s, 0., 0.,
370 0., 0., s, 0.,
371 0., 0., 0., 1.
372 ]
373 }
374
375
376
377 pub fn translate(x: f64, y: f64, z:f64, t:f64) -> Matrix4 {
378 matrix4![
379 1., 0., 0., x,
380 0., 1., 0., y,
381 0., 0., 1., z,
382 0., 0., 0., t
383 ]
384 }
385
386
387
388 pub fn sheer_x(y: f64, z: f64) -> Matrix4 {
389 matrix4![
390 1., 0., 0., 0.,
391 y, 1., 0., 0.,
392 z, 0., 1., 0.,
393 0., 0., 0., 1.
394 ]
395 }
396
397
398
399 pub fn sheer_y(x: f64, z: f64) -> Matrix4 {
400 matrix4![
401 1., x, 0., 0.,
402 0., 1., 0., 0.,
403 0., z, 1., 0.,
404 0., 0., 0., 1.
405 ]
406 }
407
408
409
410 pub fn sheer_z(x: f64, y: f64) -> Matrix4 {
411 matrix4![
412 1., 0., x, 0.,
413 0., 1., y, 0.,
414 0., 0., 1., 0.,
415 0., 0., 0., 1.
416 ]
417 }
418
419
420
421 pub fn sheer(
422 xy:f64, xz:f64,
423 yx:f64, yz:f64,
424 zx:f64, zy:f64
425 ) -> Matrix4 {
426 matrix4![
427 1., yx, zx, 0.,
428 xy, 1., zy, 0.,
429 xz, yz, 1., 0.,
430 0., 0., 0., 1.
431 ]
432 }
433
434
435
436 pub fn from_basis(
437 x: Vector4,
438 y: Vector4,
439 z: Vector4,
440 t: Vector4
441 ) -> Matrix4 {
442 let r = compose_basis4![
443 &x,
444 &y,
445 &z,
446 &t
447 ];
448
449 r
450 }
451
452
453
454 pub fn into_basis(&self) -> [Vector4; 4] {
455 let x = vec4![self[0], self[4], self[8], self[12]];
456 let y = vec4![self[1], self[5], self[9], self[13]];
457 let z = vec4![self[2], self[6], self[10], self[14]];
458 let t = vec4![self[3], self[7], self[11], self[15]];
459
460 [x,y,z,t]
461 }
462
463
464
465 pub fn orthographic(left: f64, right: f64, top: f64, bottom: f64, near: f64, far: f64) -> Matrix4 {
466 let xx = 2.0 / ( right - left );
467 let yy = 2.0 / ( top - bottom );
468 let zz = -2.0 / ( far - near );
469
470 let x = ( right + left ) * xx / 2.;
471 let y = ( top + bottom ) * yy / 2.;
472 let z = ( far + near ) * -zz / 2.;
473
474 matrix4![
475 xx, 0., 0., -x,
476 0., yy, 0., -y,
477 0., 0., zz, -z,
478 0., 0., 0., 1.
479 ]
480 }
481
482
483
484 pub fn perspective(fov: f64, aspect: f64, near:f64, far:f64) -> Matrix4 {
490 let f = (PI / 2. - fov / 2.).tan();
491 let r = 1.0 / (near - far);
492
493 let xx = f / aspect;
494 let yy = f;
495 let zz = (near + far) * r;
496 let zt = near * far * r * 2.;
497 let tz = -1.;
498
499 matrix4![
500 xx, 0., 0., 0.,
501 0., yy, 0., 0.,
502 0., 0., zz, tz,
503 0., 0., zt, 1.
504 ]
505 }
506
507
508
509 pub fn into_gl(&self) -> [f32; 16] {
510 [
511 self[0] as f32, self[1] as f32, self[2] as f32, self[3] as f32,
512 self[4] as f32, self[5] as f32, self[6] as f32, self[7] as f32,
513 self[8] as f32, self[9] as f32, self[10] as f32, self[11] as f32,
514 self[12] as f32, self[13] as f32, self[14] as f32, self[15] as f32
515 ]
516 }
517
518
519
520 pub fn apply(&mut self, f: fn(f64) -> f64) {
521 self[0] = f(self[0]);
522 self[1] = f(self[1]);
523 self[2] = f(self[2]);
524 self[3] = f(self[3]);
525 self[4] = f(self[4]);
526 self[5] = f(self[5]);
527 self[6] = f(self[6]);
528 self[7] = f(self[7]);
529 self[8] = f(self[8]);
530 self[9] = f(self[9]);
531 self[10] = f(self[10]);
532 self[11] = f(self[11]);
533 self[12] = f(self[12]);
534 self[13] = f(self[13]);
535 self[14] = f(self[14]);
536 self[15] = f(self[15]);
537 }
538}
539
540
541
542impl Add for &Matrix4 {
543 type Output = Matrix4;
544
545 fn add(self, b:&Matrix4) -> Matrix4 {
546 Matrix4::new([
547 self[0] + b[0], self[1] + b[1], self[2] + b[2], self[3] + b[3],
548 self[4] + b[4], self[5] + b[5], self[6] + b[6], self[7] + b[7],
549 self[8] + b[8], self[9] + b[9], self[10] + b[10], self[11] + b[11],
550 self[12] + b[12], self[13] + b[13], self[14] + b[14], self[15] + b[15]
551 ])
552 }
553}
554
555
556
557impl AddAssign for Matrix4 {
558 fn add_assign(&mut self, b:Matrix4) {
559 self[0] += b[0];
560 self[1] += b[1];
561 self[2] += b[2];
562 self[3] += b[3];
563 self[4] += b[4];
564 self[5] += b[5];
565 self[6] += b[6];
566 self[7] += b[7];
567 self[8] += b[8];
568 self[9] += b[9];
569 self[10] += b[10];
570 self[11] += b[11];
571 self[12] += b[12];
572 self[13] += b[13];
573 self[14] += b[14];
574 self[15] += b[15];
575 }
576}
577
578
579
580impl Sub for &Matrix4 {
581 type Output = Matrix4;
582
583 fn sub(self, b:&Matrix4) -> Matrix4 {
584 Matrix4::new([
585 self[0] - b[0], self[1] - b[1], self[2] - b[2], self[3] - b[3],
586 self[4] - b[4], self[5] - b[5], self[6] - b[6], self[7] - b[7],
587 self[8] - b[8], self[9] - b[9], self[10] - b[10], self[11] - b[11],
588 self[12] - b[12], self[13] - b[13], self[14] - b[14], self[15] - b[15]
589 ])
590 }
591}
592
593
594
595impl SubAssign for Matrix4 {
596 fn sub_assign(&mut self, b:Matrix4) {
597 self[0] -= b[0];
598 self[1] -= b[1];
599 self[2] -= b[2];
600 self[3] -= b[3];
601 self[4] -= b[4];
602 self[5] -= b[5];
603 self[6] -= b[6];
604 self[7] -= b[7];
605 self[8] -= b[8];
606 self[9] -= b[9];
607 self[10] -= b[10];
608 self[11] -= b[11];
609 self[12] -= b[12];
610 self[13] -= b[13];
611 self[14] -= b[14];
612 self[15] -= b[15];
613 }
614}
615
616
617
618impl Mul for Matrix4 {
619 type Output = Matrix4;
620
621 fn mul(self, b: Matrix4) -> Matrix4 {
622 Matrix4::new([
623 self[0] * b[0] + self[1] * b[4] + self[2] * b[8] + self[3] * b[12],
624 self[0] * b[1] + self[1] * b[5] + self[2] * b[9] + self[3] * b[13],
625 self[0] * b[2] + self[1] * b[6] + self[2] * b[10] + self[3] * b[14],
626 self[0] * b[3] + self[1] * b[7] + self[2] * b[11] + self[3] * b[15],
627
628 self[4] * b[0] + self[5] * b[4] + self[6] * b[8] + self[7] * b[12],
629 self[4] * b[1] + self[5] * b[5] + self[6] * b[9] + self[7] * b[13],
630 self[4] * b[2] + self[5] * b[6] + self[6] * b[10] + self[7] * b[14],
631 self[4] * b[3] + self[5] * b[7] + self[6] * b[11] + self[7] * b[15],
632
633 self[8] * b[0] + self[9] * b[4] + self[10] * b[8] + self[11] * b[12],
634 self[8] * b[1] + self[9] * b[5] + self[10] * b[9] + self[11] * b[13],
635 self[8] * b[2] + self[9] * b[6] + self[10] * b[10] + self[11] * b[14],
636 self[8] * b[3] + self[9] * b[7] + self[10] * b[11] + self[11] * b[15],
637
638 self[12] * b[0] + self[13] * b[4] + self[14] * b[8] + self[15] * b[12],
639 self[12] * b[1] + self[13] * b[5] + self[14] * b[9] + self[15] * b[13],
640 self[12] * b[2] + self[13] * b[6] + self[14] * b[10] + self[15] * b[14],
641 self[12] * b[3] + self[13] * b[7] + self[14] * b[11] + self[15] * b[15]
642 ])
643 }
644}
645
646
647
648impl Mul for &Matrix4 {
649 type Output = Matrix4;
650
651 fn mul(self, b: &Matrix4) -> Matrix4 {
652 Matrix4::new([
653 self[0] * b[0] + self[1] * b[4] + self[2] * b[8] + self[3] * b[12],
654 self[0] * b[1] + self[1] * b[5] + self[2] * b[9] + self[3] * b[13],
655 self[0] * b[2] + self[1] * b[6] + self[2] * b[10] + self[3] * b[14],
656 self[0] * b[3] + self[1] * b[7] + self[2] * b[11] + self[3] * b[15],
657
658 self[4] * b[0] + self[5] * b[4] + self[6] * b[8] + self[7] * b[12],
659 self[4] * b[1] + self[5] * b[5] + self[6] * b[9] + self[7] * b[13],
660 self[4] * b[2] + self[5] * b[6] + self[6] * b[10] + self[7] * b[14],
661 self[4] * b[3] + self[5] * b[7] + self[6] * b[11] + self[7] * b[15],
662
663 self[8] * b[0] + self[9] * b[4] + self[10] * b[8] + self[11] * b[12],
664 self[8] * b[1] + self[9] * b[5] + self[10] * b[9] + self[11] * b[13],
665 self[8] * b[2] + self[9] * b[6] + self[10] * b[10] + self[11] * b[14],
666 self[8] * b[3] + self[9] * b[7] + self[10] * b[11] + self[11] * b[15],
667
668 self[12] * b[0] + self[13] * b[4] + self[14] * b[8] + self[15] * b[12],
669 self[12] * b[1] + self[13] * b[5] + self[14] * b[9] + self[15] * b[13],
670 self[12] * b[2] + self[13] * b[6] + self[14] * b[10] + self[15] * b[14],
671 self[12] * b[3] + self[13] * b[7] + self[14] * b[11] + self[15] * b[15]
672 ])
673 }
674}
675
676
677
678impl Mul <Float> for Matrix4 {
679 type Output = Matrix4;
680
681 fn mul(mut self, s:f64) -> Matrix4 {
682 self[0] *= s;
683 self[1] *= s;
684 self[2] *= s;
685 self[3] *= s;
686 self[4] *= s;
687 self[5] *= s;
688 self[6] *= s;
689 self[7] *= s;
690 self[8] *= s;
691 self[9] *= s;
692 self[10] *= s;
693 self[11] *= s;
694 self[12] *= s;
695 self[13] *= s;
696 self[14] *= s;
697 self[15] *= s;
698 self
699 }
700}
701
702
703
704impl Mul <Vector4> for &Matrix4 {
705 type Output = Vector4;
706
707 fn mul(self, v:Vector4) -> Vector4 {
708 vec4![
709 self[0] * v[0] + self[1] * v[1] + self[2] * v[2] + self[3] * v[3],
710 self[4] * v[0] + self[5] * v[1] + self[6] * v[2] + self[7] * v[3],
711 self[8] * v[0] + self[9] * v[1] + self[10] * v[2] + self[11] * v[3],
712 self[12] * v[0] + self[13] * v[1] + self[14] * v[2] + self[15] * v[3]
713 ]
714 }
715}
716
717
718
719impl Mul <Vector4> for Matrix4 {
720 type Output = Vector4;
721
722 fn mul(self, v:Vector4) -> Vector4 {
723 vec4![
724 self[0] * v[0] + self[1] * v[1] + self[2] * v[2] + self[3] * v[3],
725 self[4] * v[0] + self[5] * v[1] + self[6] * v[2] + self[7] * v[3],
726 self[8] * v[0] + self[9] * v[1] + self[10] * v[2] + self[11] * v[3],
727 self[12] * v[0] + self[13] * v[1] + self[14] * v[2] + self[15] * v[3]
728 ]
729 }
730}
731
732
733
734impl Div <Float> for Matrix4 {
735 type Output = Matrix4;
736
737 fn div(mut self, s:f64) -> Matrix4 {
738 self[0] /= s;
739 self[1] /= s;
740 self[2] /= s;
741 self[3] /= s;
742 self[4] /= s;
743 self[5] /= s;
744 self[6] /= s;
745 self[7] /= s;
746 self[8] /= s;
747 self[9] /= s;
748 self[10] /= s;
749 self[11] /= s;
750 self[12] /= s;
751 self[13] /= s;
752 self[14] /= s;
753 self[15] /= s;
754 self
755 }
756}
757
758
759
760fn eq(a: &Matrix4, b: &Matrix4) -> bool {
761 a[0] == b[0] &&
763 a[1] == b[1] &&
764 a[2] == b[2] &&
765 a[3] == b[3] &&
766 a[4] == b[4] &&
767 a[5] == b[5] &&
768 a[6] == b[6] &&
769 a[7] == b[7] &&
770 a[8] == b[8] &&
771 a[9] == b[8] &&
772 a[10] == b[10] &&
773 a[11] == b[11] &&
774 a[12] == b[12] &&
775 a[13] == b[13] &&
776 a[14] == b[14] &&
777 a[15] == b[15]
778}
779
780
781
782fn almost_eq(a: &Matrix4, b: &Matrix4) -> bool {
783
784 fn eq(a: Float, b: Float) -> bool {
785 (a - b).abs() < f32::EPSILON as f64
786 }
787
788 eq(a[0], b[0]) &&
789 eq(a[1], b[1]) &&
790 eq(a[2], b[2]) &&
791 eq(a[3], b[3]) &&
792 eq(a[4], b[4]) &&
793 eq(a[5], b[5]) &&
794 eq(a[6], b[6]) &&
795 eq(a[7], b[7]) &&
796 eq(a[8], b[8]) &&
797 eq(a[9], b[9]) &&
798 eq(a[10], b[10]) &&
799 eq(a[11], b[11]) &&
800 eq(a[12], b[12]) &&
801 eq(a[13], b[13]) &&
802 eq(a[14], b[14]) &&
803 eq(a[15], b[15])
804}
805
806
807
808impl PartialEq for Matrix4 {
809 fn eq(&self, b: &Matrix4) -> bool {
810 almost_eq(self, b)
812 }
813}
814
815
816
817impl Eq for Matrix4 {}
818
819
820
821impl Neg for Matrix4 {
822
823 type Output = Matrix4;
824
825 fn neg(mut self) -> Self {
826 self[0] *= -1.;
827 self[1] *= -1.;
828 self[2] *= -1.;
829 self[3] *= -1.;
830 self[4] *= -1.;
831 self[5] *= -1.;
832 self[6] *= -1.;
833 self[7] *= -1.;
834 self[8] *= -1.;
835 self[9] *= -1.;
836 self[10] *= -1.;
837 self[11] *= -1.;
838 self[12] *= -1.;
839 self[13] *= -1.;
840 self[14] *= -1.;
841 self[15] *= -1.;
842 self
843 }
844}
845
846
847
848impl From<Matrix<f64>> for Matrix4 {
849 fn from(m: Matrix<f64>) -> Matrix4 {
850 matrix4![
851 m[[0,0]], m[[0,1]], m[[0,2]], m[[0,3]],
852 m[[1,0]], m[[1,1]], m[[1,2]], m[[1,3]],
853 m[[2,0]], m[[2,1]], m[[2,2]], m[[2,3]],
854 m[[3,0]], m[[3,1]], m[[3,2]], m[[3,3]]
855 ]
856 }
857}
858
859
860
861impl From<&Matrix<f64>> for Matrix4 {
862 fn from(m: &Matrix<f64>) -> Matrix4 {
863 matrix4![
864 m[[0,0]], m[[0,1]], m[[0,2]], m[[0,3]],
865 m[[1,0]], m[[1,1]], m[[1,2]], m[[1,3]],
866 m[[2,0]], m[[2,1]], m[[2,2]], m[[2,3]],
867 m[[3,0]], m[[3,1]], m[[3,2]], m[[3,3]]
868 ]
869 }
870}
871
872
873
874impl From<Matrix3> for Matrix4 {
875 fn from(m: Matrix3) -> Matrix4 {
876 matrix4![
877 m[0], m[1], m[2], 0.,
878 m[3], m[4], m[5], 0.,
879 m[6], m[7], m[8], 0.,
880 0., 0., 0., 1.
881 ]
882 }
883}
884
885
886
887mod tests {
888 use std::{f32::EPSILON, f64::consts::PI};
889 use crate::{ vec3 };
890 use super::{
891 Vector3,
892 Matrix3,
893 Matrix4,
894 Matrix
895 };
896
897 #[test]
899 fn gimbal_lock() {
900
901 let basis = Matrix3::id().into_basis();
902 let v = vec3![2., 3., 4.];
903
904 let x_rad = PI / 10.;
905 let y_rad = PI / 5.; let z_rad = PI / 10.;
907
908 let r1: Matrix3 = Matrix4::rotation(x_rad, y_rad, z_rad).into();
909
910 let x_rad2 = PI / 10.;
911 let y_rad2 = PI / 10.;
912 let z_rad2 = PI / 10.;
913
914 let r2: Matrix3 = Matrix4::rotation(x_rad2, y_rad2, z_rad2).into();
915 let r1v = &r1 * &v;
916 let r2v = &r2 * &v;
917
918 let r3: Matrix3 = Matrix4::rotation(x_rad + x_rad2, y_rad + y_rad2, z_rad + z_rad2).into();
919 let r2r1: Matrix3 = &r2 * &r1;
920
921 let r3v = &r3 * &v;
922 let r2r1v = &r2r1 * &v;
923
924 println!("\n r1 is {} \n r2 is {} \n r3 is {} \n r2r1 is {} \n", r1, r2, r3, r2r1);
925
926 println!("\n r3v is {} \n r2r1v {} \n", r3v, r2r1v);
927
928 let x = basis[0];
929 let y = basis[1];
930 let z = basis[2];
931
932 let r3v_x = r3v.angle(&x);
933 let r3v_y = r3v.angle(&y);
934 let r3v_z = r3v.angle(&z);
935
936 let r2r1v_x = r2r1v.angle(&x);
937 let r2r1v_y = r2r1v.angle(&y);
938 let r2r1v_z = r2r1v.angle(&z);
939
940 println!("\n r3v_x is {} \n r3v_y is {} \n r3v_z is {} \n", r3v_x, r3v_y, r3v_z);
941
942 println!("\n r2r1v_x is {} \n r2r1v_y is {} \n r2r1v_z is {} \n", r2r1v_x, r2r1v_y, r2r1v_z);
943 }
944
945 #[test]
946 fn perspective() {
947
948 const fov: f32 = 45. * std::f32::consts::PI / 180.;
949 const far: f32 = 100.;
950 const near: f32 = 0.1;
951 const aspect: f32 = 1.; let p = Matrix4::perspective(fov as f64, aspect as f64, near as f64, far as f64);
955
956 }
958}