1use num_traits::{cast, NumCast};
17#[cfg(feature = "rand")]
18use rand::{
19 distributions::{Distribution, Standard},
20 Rng,
21};
22use std::fmt;
23use std::iter;
24use std::mem;
25use std::ops::*;
26use std::ptr;
27
28use structure::*;
29
30use angle::Rad;
31use approx;
32use euler::Euler;
33use num::BaseFloat;
34use point::{Point2, Point3};
35use quaternion::Quaternion;
36use transform::{Transform, Transform2, Transform3};
37use vector::{Vector2, Vector3, Vector4};
38
39#[cfg(feature = "mint")]
40use mint;
41
42#[repr(C)]
46#[derive(Copy, Clone, PartialEq)]
47#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
48pub struct Matrix2<S> {
49 pub x: Vector2<S>,
51 pub y: Vector2<S>,
53}
54
55#[repr(C)]
59#[derive(Copy, Clone, PartialEq)]
60#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
61pub struct Matrix3<S> {
62 pub x: Vector3<S>,
64 pub y: Vector3<S>,
66 pub z: Vector3<S>,
68}
69
70#[repr(C)]
74#[derive(Copy, Clone, PartialEq)]
75#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
76pub struct Matrix4<S> {
77 pub x: Vector4<S>,
79 pub y: Vector4<S>,
81 pub z: Vector4<S>,
83 pub w: Vector4<S>,
85}
86
87impl<S> Matrix2<S> {
88 #[inline]
90 pub const fn new(c0r0: S, c0r1: S, c1r0: S, c1r1: S) -> Matrix2<S> {
91 Matrix2::from_cols(Vector2::new(c0r0, c0r1), Vector2::new(c1r0, c1r1))
92 }
93
94 #[inline]
96 pub const fn from_cols(c0: Vector2<S>, c1: Vector2<S>) -> Matrix2<S> {
97 Matrix2 { x: c0, y: c1 }
98 }
99}
100
101impl<S: BaseFloat> Matrix2<S> {
102 pub fn look_at(dir: Vector2<S>, up: Vector2<S>) -> Matrix2<S> {
105 Matrix2::look_at_stable(dir, up.x * dir.y >= up.y * dir.x)
106 }
107
108 pub fn look_at_stable(dir: Vector2<S>, flip: bool) -> Matrix2<S> {
112 let basis1 = dir.normalize();
113 let basis2 = if flip {
114 Vector2::new(basis1.y, -basis1.x)
115 } else {
116 Vector2::new(-basis1.y, basis1.x)
117 };
118 Matrix2::from_cols(basis1, basis2)
119 }
120
121 #[inline]
122 pub fn from_angle<A: Into<Rad<S>>>(theta: A) -> Matrix2<S> {
123 let (s, c) = Rad::sin_cos(theta.into());
124
125 Matrix2::new(c, s, -s, c)
126 }
127
128 pub fn is_finite(&self) -> bool {
130 self.x.is_finite() && self.y.is_finite()
131 }
132}
133
134impl<S> Matrix3<S> {
135 #[inline]
137 #[cfg_attr(rustfmt, rustfmt_skip)]
138 pub const fn new(
139 c0r0:S, c0r1:S, c0r2:S,
140 c1r0:S, c1r1:S, c1r2:S,
141 c2r0:S, c2r1:S, c2r2:S,
142 ) -> Matrix3<S> {
143 Matrix3::from_cols(
144 Vector3::new(c0r0, c0r1, c0r2),
145 Vector3::new(c1r0, c1r1, c1r2),
146 Vector3::new(c2r0, c2r1, c2r2),
147 )
148 }
149
150 #[inline]
152 pub const fn from_cols(c0: Vector3<S>, c1: Vector3<S>, c2: Vector3<S>) -> Matrix3<S> {
153 Matrix3 {
154 x: c0,
155 y: c1,
156 z: c2,
157 }
158 }
159}
160
161impl<S: BaseFloat> Matrix3<S> {
162 #[inline]
164 pub fn from_translation(v: Vector2<S>) -> Matrix3<S> {
165 #[cfg_attr(rustfmt, rustfmt_skip)]
166 Matrix3::new(
167 S::one(), S::zero(), S::zero(),
168 S::zero(), S::one(), S::zero(),
169 v.x, v.y, S::one(),
170 )
171 }
172
173 #[inline]
175 pub fn from_scale(value: S) -> Matrix3<S> {
176 Matrix3::from_nonuniform_scale(value, value)
177 }
178
179 #[inline]
181 pub fn from_nonuniform_scale(x: S, y: S) -> Matrix3<S> {
182 #[cfg_attr(rustfmt, rustfmt_skip)]
183 Matrix3::new(
184 x, S::zero(), S::zero(),
185 S::zero(), y, S::zero(),
186 S::zero(), S::zero(), S::one(),
187 )
188 }
189
190 #[deprecated = "Use Matrix3::look_to_lh"]
193 pub fn look_at(dir: Vector3<S>, up: Vector3<S>) -> Matrix3<S> {
194 Matrix3::look_to_lh(dir, up)
195 }
196
197 pub fn look_to_lh(dir: Vector3<S>, up: Vector3<S>) -> Matrix3<S> {
200 let dir = dir.normalize();
201 let side = up.cross(dir).normalize();
202 let up = dir.cross(side).normalize();
203
204 Matrix3::from_cols(side, up, dir).transpose()
205 }
206
207 pub fn look_to_rh(dir: Vector3<S>, up: Vector3<S>) -> Matrix3<S> {
210 Matrix3::look_to_lh(-dir, up)
211 }
212
213 pub fn from_angle_x<A: Into<Rad<S>>>(theta: A) -> Matrix3<S> {
215 let (s, c) = Rad::sin_cos(theta.into());
217
218 #[cfg_attr(rustfmt, rustfmt_skip)]
219 Matrix3::new(
220 S::one(), S::zero(), S::zero(),
221 S::zero(), c, s,
222 S::zero(), -s, c,
223 )
224 }
225
226 pub fn from_angle_y<A: Into<Rad<S>>>(theta: A) -> Matrix3<S> {
228 let (s, c) = Rad::sin_cos(theta.into());
230
231 #[cfg_attr(rustfmt, rustfmt_skip)]
232 Matrix3::new(
233 c, S::zero(), -s,
234 S::zero(), S::one(), S::zero(),
235 s, S::zero(), c,
236 )
237 }
238
239 pub fn from_angle_z<A: Into<Rad<S>>>(theta: A) -> Matrix3<S> {
241 let (s, c) = Rad::sin_cos(theta.into());
243
244 #[cfg_attr(rustfmt, rustfmt_skip)]
245 Matrix3::new(
246 c, s, S::zero(),
247 -s, c, S::zero(),
248 S::zero(), S::zero(), S::one(),
249 )
250 }
251
252 pub fn from_axis_angle<A: Into<Rad<S>>>(axis: Vector3<S>, angle: A) -> Matrix3<S> {
256 let (s, c) = Rad::sin_cos(angle.into());
257 let _1subc = S::one() - c;
258
259 #[cfg_attr(rustfmt, rustfmt_skip)]
260 Matrix3::new(
261 _1subc * axis.x * axis.x + c,
262 _1subc * axis.x * axis.y + s * axis.z,
263 _1subc * axis.x * axis.z - s * axis.y,
264
265 _1subc * axis.x * axis.y - s * axis.z,
266 _1subc * axis.y * axis.y + c,
267 _1subc * axis.y * axis.z + s * axis.x,
268
269 _1subc * axis.x * axis.z + s * axis.y,
270 _1subc * axis.y * axis.z - s * axis.x,
271 _1subc * axis.z * axis.z + c,
272 )
273 }
274
275 pub fn is_finite(&self) -> bool {
277 self.x.is_finite() && self.y.is_finite() && self.z.is_finite()
278 }
279}
280
281impl<S> Matrix4<S> {
282 #[inline]
284 #[cfg_attr(rustfmt, rustfmt_skip)]
285 pub const fn new(
286 c0r0: S, c0r1: S, c0r2: S, c0r3: S,
287 c1r0: S, c1r1: S, c1r2: S, c1r3: S,
288 c2r0: S, c2r1: S, c2r2: S, c2r3: S,
289 c3r0: S, c3r1: S, c3r2: S, c3r3: S,
290 ) -> Matrix4<S> {
291 Matrix4::from_cols(
292 Vector4::new(c0r0, c0r1, c0r2, c0r3),
293 Vector4::new(c1r0, c1r1, c1r2, c1r3),
294 Vector4::new(c2r0, c2r1, c2r2, c2r3),
295 Vector4::new(c3r0, c3r1, c3r2, c3r3),
296 )
297 }
298
299 #[inline]
301 pub const fn from_cols(
302 c0: Vector4<S>,
303 c1: Vector4<S>,
304 c2: Vector4<S>,
305 c3: Vector4<S>,
306 ) -> Matrix4<S> {
307 Matrix4 {
308 x: c0,
309 y: c1,
310 z: c2,
311 w: c3,
312 }
313 }
314}
315
316impl<S: BaseFloat> Matrix4<S> {
317 #[inline]
319 pub fn from_translation(v: Vector3<S>) -> Matrix4<S> {
320 #[cfg_attr(rustfmt, rustfmt_skip)]
321 Matrix4::new(
322 S::one(), S::zero(), S::zero(), S::zero(),
323 S::zero(), S::one(), S::zero(), S::zero(),
324 S::zero(), S::zero(), S::one(), S::zero(),
325 v.x, v.y, v.z, S::one(),
326 )
327 }
328
329 #[inline]
331 pub fn from_scale(value: S) -> Matrix4<S> {
332 Matrix4::from_nonuniform_scale(value, value, value)
333 }
334
335 #[inline]
337 pub fn from_nonuniform_scale(x: S, y: S, z: S) -> Matrix4<S> {
338 #[cfg_attr(rustfmt, rustfmt_skip)]
339 Matrix4::new(
340 x, S::zero(), S::zero(), S::zero(),
341 S::zero(), y, S::zero(), S::zero(),
342 S::zero(), S::zero(), z, S::zero(),
343 S::zero(), S::zero(), S::zero(), S::one(),
344 )
345 }
346
347 #[deprecated = "Use Matrix4::look_to_rh"]
350 pub fn look_at_dir(eye: Point3<S>, dir: Vector3<S>, up: Vector3<S>) -> Matrix4<S> {
351 let f = dir.normalize();
352 let s = f.cross(up).normalize();
353 let u = s.cross(f);
354
355 #[cfg_attr(rustfmt, rustfmt_skip)]
356 Matrix4::new(
357 s.x.clone(), u.x.clone(), -f.x.clone(), S::zero(),
358 s.y.clone(), u.y.clone(), -f.y.clone(), S::zero(),
359 s.z.clone(), u.z.clone(), -f.z.clone(), S::zero(),
360 -eye.dot(s), -eye.dot(u), eye.dot(f), S::one(),
361 )
362 }
363
364 pub fn look_to_rh(eye: Point3<S>, dir: Vector3<S>, up: Vector3<S>) -> Matrix4<S> {
367 let f = dir.normalize();
368 let s = f.cross(up).normalize();
369 let u = s.cross(f);
370
371 #[cfg_attr(rustfmt, rustfmt_skip)]
372 Matrix4::new(
373 s.x.clone(), u.x.clone(), -f.x.clone(), S::zero(),
374 s.y.clone(), u.y.clone(), -f.y.clone(), S::zero(),
375 s.z.clone(), u.z.clone(), -f.z.clone(), S::zero(),
376 -eye.dot(s), -eye.dot(u), eye.dot(f), S::one(),
377 )
378 }
379
380 pub fn look_to_lh(eye: Point3<S>, dir: Vector3<S>, up: Vector3<S>) -> Matrix4<S> {
383 Matrix4::look_to_rh(eye, -dir, up)
384 }
385
386 #[deprecated = "Use Matrix4::look_at_rh"]
389 pub fn look_at(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix4<S> {
390 Matrix4::look_at_rh(eye, center, up)
391 }
392
393 pub fn look_at_rh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix4<S> {
396 Matrix4::look_to_rh(eye, center - eye, up)
397 }
398
399 pub fn look_at_lh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix4<S> {
402 Matrix4::look_to_lh(eye, center - eye, up)
403 }
404
405 pub fn from_angle_x<A: Into<Rad<S>>>(theta: A) -> Matrix4<S> {
407 let (s, c) = Rad::sin_cos(theta.into());
409
410 #[cfg_attr(rustfmt, rustfmt_skip)]
411 Matrix4::new(
412 S::one(), S::zero(), S::zero(), S::zero(),
413 S::zero(), c, s, S::zero(),
414 S::zero(), -s, c, S::zero(),
415 S::zero(), S::zero(), S::zero(), S::one(),
416 )
417 }
418
419 pub fn from_angle_y<A: Into<Rad<S>>>(theta: A) -> Matrix4<S> {
421 let (s, c) = Rad::sin_cos(theta.into());
423
424 #[cfg_attr(rustfmt, rustfmt_skip)]
425 Matrix4::new(
426 c, S::zero(), -s, S::zero(),
427 S::zero(), S::one(), S::zero(), S::zero(),
428 s, S::zero(), c, S::zero(),
429 S::zero(), S::zero(), S::zero(), S::one(),
430 )
431 }
432
433 pub fn from_angle_z<A: Into<Rad<S>>>(theta: A) -> Matrix4<S> {
435 let (s, c) = Rad::sin_cos(theta.into());
437
438 #[cfg_attr(rustfmt, rustfmt_skip)]
439 Matrix4::new(
440 c, s, S::zero(), S::zero(),
441 -s, c, S::zero(), S::zero(),
442 S::zero(), S::zero(), S::one(), S::zero(),
443 S::zero(), S::zero(), S::zero(), S::one(),
444 )
445 }
446
447 pub fn from_axis_angle<A: Into<Rad<S>>>(axis: Vector3<S>, angle: A) -> Matrix4<S> {
451 let (s, c) = Rad::sin_cos(angle.into());
452 let _1subc = S::one() - c;
453
454 #[cfg_attr(rustfmt, rustfmt_skip)]
455 Matrix4::new(
456 _1subc * axis.x * axis.x + c,
457 _1subc * axis.x * axis.y + s * axis.z,
458 _1subc * axis.x * axis.z - s * axis.y,
459 S::zero(),
460
461 _1subc * axis.x * axis.y - s * axis.z,
462 _1subc * axis.y * axis.y + c,
463 _1subc * axis.y * axis.z + s * axis.x,
464 S::zero(),
465
466 _1subc * axis.x * axis.z + s * axis.y,
467 _1subc * axis.y * axis.z - s * axis.x,
468 _1subc * axis.z * axis.z + c,
469 S::zero(),
470
471 S::zero(), S::zero(), S::zero(), S::one(),
472 )
473 }
474
475 pub fn is_finite(&self) -> bool {
477 self.w.is_finite() && self.x.is_finite() && self.y.is_finite() && self.z.is_finite()
478 }
479}
480
481impl<S: BaseFloat> Zero for Matrix2<S> {
482 #[inline]
483 fn zero() -> Matrix2<S> {
484 #[cfg_attr(rustfmt, rustfmt_skip)]
485 Matrix2::new(
486 S::zero(), S::zero(),
487 S::zero(), S::zero(),
488 )
489 }
490
491 #[inline]
492 fn is_zero(&self) -> bool {
493 ulps_eq!(self, &Self::zero())
494 }
495}
496
497impl<S: BaseFloat> Zero for Matrix3<S> {
498 #[inline]
499 fn zero() -> Matrix3<S> {
500 #[cfg_attr(rustfmt, rustfmt_skip)]
501 Matrix3::new(
502 S::zero(), S::zero(), S::zero(),
503 S::zero(), S::zero(), S::zero(),
504 S::zero(), S::zero(), S::zero(),
505 )
506 }
507
508 #[inline]
509 fn is_zero(&self) -> bool {
510 ulps_eq!(self, &Self::zero())
511 }
512}
513
514impl<S: BaseFloat> Zero for Matrix4<S> {
515 #[inline]
516 fn zero() -> Matrix4<S> {
517 #[cfg_attr(rustfmt, rustfmt_skip)]
518 Matrix4::new(
519 S::zero(), S::zero(), S::zero(), S::zero(),
520 S::zero(), S::zero(), S::zero(), S::zero(),
521 S::zero(), S::zero(), S::zero(), S::zero(),
522 S::zero(), S::zero(), S::zero(), S::zero(),
523 )
524 }
525
526 #[inline]
527 fn is_zero(&self) -> bool {
528 ulps_eq!(self, &Self::zero())
529 }
530}
531
532impl<S: BaseFloat> One for Matrix2<S> {
533 #[inline]
534 fn one() -> Matrix2<S> {
535 Matrix2::from_value(S::one())
536 }
537}
538
539impl<S: BaseFloat> One for Matrix3<S> {
540 #[inline]
541 fn one() -> Matrix3<S> {
542 Matrix3::from_value(S::one())
543 }
544}
545
546impl<S: BaseFloat> One for Matrix4<S> {
547 #[inline]
548 fn one() -> Matrix4<S> {
549 Matrix4::from_value(S::one())
550 }
551}
552
553impl<S: BaseFloat> VectorSpace for Matrix2<S> {
554 type Scalar = S;
555}
556
557impl<S: BaseFloat> VectorSpace for Matrix3<S> {
558 type Scalar = S;
559}
560
561impl<S: BaseFloat> VectorSpace for Matrix4<S> {
562 type Scalar = S;
563}
564
565impl<S: BaseFloat> Matrix for Matrix2<S> {
566 type Column = Vector2<S>;
567 type Row = Vector2<S>;
568 type Transpose = Matrix2<S>;
569
570 #[inline]
571 fn row(&self, r: usize) -> Vector2<S> {
572 Vector2::new(self[0][r], self[1][r])
573 }
574
575 #[inline]
576 fn swap_rows(&mut self, a: usize, b: usize) {
577 self[0].swap_elements(a, b);
578 self[1].swap_elements(a, b);
579 }
580
581 #[inline]
582 fn swap_columns(&mut self, a: usize, b: usize) {
583 unsafe { ptr::swap(&mut self[a], &mut self[b]) };
584 }
585
586 #[inline]
587 fn swap_elements(&mut self, a: (usize, usize), b: (usize, usize)) {
588 let (ac, ar) = a;
589 let (bc, br) = b;
590 unsafe { ptr::swap(&mut self[ac][ar], &mut self[bc][br]) };
591 }
592
593 fn transpose(&self) -> Matrix2<S> {
594 #[cfg_attr(rustfmt, rustfmt_skip)]
595 Matrix2::new(
596 self[0][0], self[1][0],
597 self[0][1], self[1][1],
598 )
599 }
600}
601
602impl<S: BaseFloat> SquareMatrix for Matrix2<S> {
603 type ColumnRow = Vector2<S>;
604
605 #[inline]
606 fn from_value(value: S) -> Matrix2<S> {
607 #[cfg_attr(rustfmt, rustfmt_skip)]
608 Matrix2::new(
609 value, S::zero(),
610 S::zero(), value,
611 )
612 }
613
614 #[inline]
615 fn from_diagonal(value: Vector2<S>) -> Matrix2<S> {
616 #[cfg_attr(rustfmt, rustfmt_skip)]
617 Matrix2::new(
618 value.x, S::zero(),
619 S::zero(), value.y,
620 )
621 }
622
623 #[inline]
624 fn transpose_self(&mut self) {
625 self.swap_elements((0, 1), (1, 0));
626 }
627
628 #[inline]
629 fn determinant(&self) -> S {
630 self[0][0] * self[1][1] - self[1][0] * self[0][1]
631 }
632
633 #[inline]
634 fn diagonal(&self) -> Vector2<S> {
635 Vector2::new(self[0][0], self[1][1])
636 }
637
638 #[inline]
639 fn invert(&self) -> Option<Matrix2<S>> {
640 let det = self.determinant();
641 if det == S::zero() {
642 None
643 } else {
644 #[cfg_attr(rustfmt, rustfmt_skip)]
645 Some(Matrix2::new(
646 self[1][1] / det, -self[0][1] / det,
647 -self[1][0] / det, self[0][0] / det,
648 ))
649 }
650 }
651
652 #[inline]
653 fn is_diagonal(&self) -> bool {
654 ulps_eq!(self[0][1], &S::zero()) && ulps_eq!(self[1][0], &S::zero())
655 }
656
657 #[inline]
658 fn is_symmetric(&self) -> bool {
659 ulps_eq!(self[0][1], &self[1][0]) && ulps_eq!(self[1][0], &self[0][1])
660 }
661}
662
663impl<S: BaseFloat> Matrix for Matrix3<S> {
664 type Column = Vector3<S>;
665 type Row = Vector3<S>;
666 type Transpose = Matrix3<S>;
667
668 #[inline]
669 fn row(&self, r: usize) -> Vector3<S> {
670 Vector3::new(self[0][r], self[1][r], self[2][r])
671 }
672
673 #[inline]
674 fn swap_rows(&mut self, a: usize, b: usize) {
675 self[0].swap_elements(a, b);
676 self[1].swap_elements(a, b);
677 self[2].swap_elements(a, b);
678 }
679
680 #[inline]
681 fn swap_columns(&mut self, a: usize, b: usize) {
682 unsafe { ptr::swap(&mut self[a], &mut self[b]) };
683 }
684
685 #[inline]
686 fn swap_elements(&mut self, a: (usize, usize), b: (usize, usize)) {
687 let (ac, ar) = a;
688 let (bc, br) = b;
689 unsafe { ptr::swap(&mut self[ac][ar], &mut self[bc][br]) };
690 }
691
692 fn transpose(&self) -> Matrix3<S> {
693 #[cfg_attr(rustfmt, rustfmt_skip)]
694 Matrix3::new(
695 self[0][0], self[1][0], self[2][0],
696 self[0][1], self[1][1], self[2][1],
697 self[0][2], self[1][2], self[2][2],
698 )
699 }
700}
701
702impl<S: BaseFloat> SquareMatrix for Matrix3<S> {
703 type ColumnRow = Vector3<S>;
704
705 #[inline]
706 fn from_value(value: S) -> Matrix3<S> {
707 #[cfg_attr(rustfmt, rustfmt_skip)]
708 Matrix3::new(
709 value, S::zero(), S::zero(),
710 S::zero(), value, S::zero(),
711 S::zero(), S::zero(), value,
712 )
713 }
714
715 #[inline]
716 fn from_diagonal(value: Vector3<S>) -> Matrix3<S> {
717 #[cfg_attr(rustfmt, rustfmt_skip)]
718 Matrix3::new(
719 value.x, S::zero(), S::zero(),
720 S::zero(), value.y, S::zero(),
721 S::zero(), S::zero(), value.z,
722 )
723 }
724
725 #[inline]
726 fn transpose_self(&mut self) {
727 self.swap_elements((0, 1), (1, 0));
728 self.swap_elements((0, 2), (2, 0));
729 self.swap_elements((1, 2), (2, 1));
730 }
731
732 fn determinant(&self) -> S {
733 self[0][0] * (self[1][1] * self[2][2] - self[2][1] * self[1][2])
734 - self[1][0] * (self[0][1] * self[2][2] - self[2][1] * self[0][2])
735 + self[2][0] * (self[0][1] * self[1][2] - self[1][1] * self[0][2])
736 }
737
738 #[inline]
739 fn diagonal(&self) -> Vector3<S> {
740 Vector3::new(self[0][0], self[1][1], self[2][2])
741 }
742
743 fn invert(&self) -> Option<Matrix3<S>> {
744 let det = self.determinant();
745 if det == S::zero() {
746 None
747 } else {
748 Some(
749 Matrix3::from_cols(
750 self[1].cross(self[2]) / det,
751 self[2].cross(self[0]) / det,
752 self[0].cross(self[1]) / det,
753 )
754 .transpose(),
755 )
756 }
757 }
758
759 fn is_diagonal(&self) -> bool {
760 ulps_eq!(self[0][1], &S::zero())
761 && ulps_eq!(self[0][2], &S::zero())
762 && ulps_eq!(self[1][0], &S::zero())
763 && ulps_eq!(self[1][2], &S::zero())
764 && ulps_eq!(self[2][0], &S::zero())
765 && ulps_eq!(self[2][1], &S::zero())
766 }
767
768 fn is_symmetric(&self) -> bool {
769 ulps_eq!(self[0][1], &self[1][0])
770 && ulps_eq!(self[0][2], &self[2][0])
771 && ulps_eq!(self[1][0], &self[0][1])
772 && ulps_eq!(self[1][2], &self[2][1])
773 && ulps_eq!(self[2][0], &self[0][2])
774 && ulps_eq!(self[2][1], &self[1][2])
775 }
776}
777
778impl<S: BaseFloat> Matrix for Matrix4<S> {
779 type Column = Vector4<S>;
780 type Row = Vector4<S>;
781 type Transpose = Matrix4<S>;
782
783 #[inline]
784 fn row(&self, r: usize) -> Vector4<S> {
785 Vector4::new(self[0][r], self[1][r], self[2][r], self[3][r])
786 }
787
788 #[inline]
789 fn swap_rows(&mut self, a: usize, b: usize) {
790 self[0].swap_elements(a, b);
791 self[1].swap_elements(a, b);
792 self[2].swap_elements(a, b);
793 self[3].swap_elements(a, b);
794 }
795
796 #[inline]
797 fn swap_columns(&mut self, a: usize, b: usize) {
798 unsafe { ptr::swap(&mut self[a], &mut self[b]) };
799 }
800
801 #[inline]
802 fn swap_elements(&mut self, a: (usize, usize), b: (usize, usize)) {
803 let (ac, ar) = a;
804 let (bc, br) = b;
805 unsafe { ptr::swap(&mut self[ac][ar], &mut self[bc][br]) };
806 }
807
808 fn transpose(&self) -> Matrix4<S> {
809 #[cfg_attr(rustfmt, rustfmt_skip)]
810 Matrix4::new(
811 self[0][0], self[1][0], self[2][0], self[3][0],
812 self[0][1], self[1][1], self[2][1], self[3][1],
813 self[0][2], self[1][2], self[2][2], self[3][2],
814 self[0][3], self[1][3], self[2][3], self[3][3],
815 )
816 }
817}
818
819impl<S: BaseFloat> SquareMatrix for Matrix4<S> {
820 type ColumnRow = Vector4<S>;
821
822 #[inline]
823 fn from_value(value: S) -> Matrix4<S> {
824 #[cfg_attr(rustfmt, rustfmt_skip)]
825 Matrix4::new(
826 value, S::zero(), S::zero(), S::zero(),
827 S::zero(), value, S::zero(), S::zero(),
828 S::zero(), S::zero(), value, S::zero(),
829 S::zero(), S::zero(), S::zero(), value,
830 )
831 }
832
833 #[inline]
834 fn from_diagonal(value: Vector4<S>) -> Matrix4<S> {
835 #[cfg_attr(rustfmt, rustfmt_skip)]
836 Matrix4::new(
837 value.x, S::zero(), S::zero(), S::zero(),
838 S::zero(), value.y, S::zero(), S::zero(),
839 S::zero(), S::zero(), value.z, S::zero(),
840 S::zero(), S::zero(), S::zero(), value.w,
841 )
842 }
843
844 fn transpose_self(&mut self) {
845 self.swap_elements((0, 1), (1, 0));
846 self.swap_elements((0, 2), (2, 0));
847 self.swap_elements((0, 3), (3, 0));
848 self.swap_elements((1, 2), (2, 1));
849 self.swap_elements((1, 3), (3, 1));
850 self.swap_elements((2, 3), (3, 2));
851 }
852
853 fn determinant(&self) -> S {
854 let tmp = unsafe { det_sub_proc_unsafe(self, 1, 2, 3) };
855 tmp.dot(Vector4::new(self[0][0], self[1][0], self[2][0], self[3][0]))
856 }
857
858 #[inline]
859 fn diagonal(&self) -> Vector4<S> {
860 Vector4::new(self[0][0], self[1][1], self[2][2], self[3][3])
861 }
862
863 #[cfg(not(feature = "simd"))]
869 fn invert(&self) -> Option<Matrix4<S>> {
870 let det = self.determinant();
871 if det == S::zero() {
872 None
873 } else {
874 let inv_det = S::one() / det;
875 let t = self.transpose();
876 let cf = |i, j| {
877 let mat = match i {
878 0 => {
879 Matrix3::from_cols(t.y.truncate_n(j), t.z.truncate_n(j), t.w.truncate_n(j))
880 }
881 1 => {
882 Matrix3::from_cols(t.x.truncate_n(j), t.z.truncate_n(j), t.w.truncate_n(j))
883 }
884 2 => {
885 Matrix3::from_cols(t.x.truncate_n(j), t.y.truncate_n(j), t.w.truncate_n(j))
886 }
887 3 => {
888 Matrix3::from_cols(t.x.truncate_n(j), t.y.truncate_n(j), t.z.truncate_n(j))
889 }
890 _ => panic!("out of range"),
891 };
892 let sign = if (i + j) & 1 == 1 {
893 -S::one()
894 } else {
895 S::one()
896 };
897 mat.determinant() * sign * inv_det
898 };
899
900 #[cfg_attr(rustfmt, rustfmt_skip)]
901 Some(Matrix4::new(
902 cf(0, 0), cf(0, 1), cf(0, 2), cf(0, 3),
903 cf(1, 0), cf(1, 1), cf(1, 2), cf(1, 3),
904 cf(2, 0), cf(2, 1), cf(2, 2), cf(2, 3),
905 cf(3, 0), cf(3, 1), cf(3, 2), cf(3, 3),
906 ))
907 }
908 }
909 #[cfg(feature = "simd")]
910 fn invert(&self) -> Option<Matrix4<S>> {
911 let tmp0 = unsafe { det_sub_proc_unsafe(self, 1, 2, 3) };
912 let det = tmp0.dot(Vector4::new(self[0][0], self[1][0], self[2][0], self[3][0]));
913
914 if det == S::zero() {
915 None
916 } else {
917 let inv_det = S::one() / det;
918 let tmp0 = tmp0 * inv_det;
919 let tmp1 = unsafe { det_sub_proc_unsafe(self, 0, 3, 2) * inv_det };
920 let tmp2 = unsafe { det_sub_proc_unsafe(self, 0, 1, 3) * inv_det };
921 let tmp3 = unsafe { det_sub_proc_unsafe(self, 0, 2, 1) * inv_det };
922 Some(Matrix4::from_cols(tmp0, tmp1, tmp2, tmp3))
923 }
924 }
925
926 fn is_diagonal(&self) -> bool {
927 ulps_eq!(self[0][1], &S::zero())
928 && ulps_eq!(self[0][2], &S::zero())
929 && ulps_eq!(self[0][3], &S::zero())
930 && ulps_eq!(self[1][0], &S::zero())
931 && ulps_eq!(self[1][2], &S::zero())
932 && ulps_eq!(self[1][3], &S::zero())
933 && ulps_eq!(self[2][0], &S::zero())
934 && ulps_eq!(self[2][1], &S::zero())
935 && ulps_eq!(self[2][3], &S::zero())
936 && ulps_eq!(self[3][0], &S::zero())
937 && ulps_eq!(self[3][1], &S::zero())
938 && ulps_eq!(self[3][2], &S::zero())
939 }
940
941 fn is_symmetric(&self) -> bool {
942 ulps_eq!(self[0][1], &self[1][0])
943 && ulps_eq!(self[0][2], &self[2][0])
944 && ulps_eq!(self[0][3], &self[3][0])
945 && ulps_eq!(self[1][0], &self[0][1])
946 && ulps_eq!(self[1][2], &self[2][1])
947 && ulps_eq!(self[1][3], &self[3][1])
948 && ulps_eq!(self[2][0], &self[0][2])
949 && ulps_eq!(self[2][1], &self[1][2])
950 && ulps_eq!(self[2][3], &self[3][2])
951 && ulps_eq!(self[3][0], &self[0][3])
952 && ulps_eq!(self[3][1], &self[1][3])
953 && ulps_eq!(self[3][2], &self[2][3])
954 }
955}
956
957impl<S: BaseFloat> approx::AbsDiffEq for Matrix2<S> {
958 type Epsilon = S::Epsilon;
959
960 #[inline]
961 fn default_epsilon() -> S::Epsilon {
962 cast(1.0e-6f64).unwrap()
963 }
964
965 #[inline]
966 fn abs_diff_eq(&self, other: &Self, epsilon: S::Epsilon) -> bool {
967 Vector2::abs_diff_eq(&self[0], &other[0], epsilon)
968 && Vector2::abs_diff_eq(&self[1], &other[1], epsilon)
969 }
970}
971
972impl<S: BaseFloat> approx::RelativeEq for Matrix2<S> {
973 #[inline]
974 fn default_max_relative() -> S::Epsilon {
975 S::default_max_relative()
976 }
977
978 #[inline]
979 fn relative_eq(&self, other: &Self, epsilon: S::Epsilon, max_relative: S::Epsilon) -> bool {
980 Vector2::relative_eq(&self[0], &other[0], epsilon, max_relative)
981 && Vector2::relative_eq(&self[1], &other[1], epsilon, max_relative)
982 }
983}
984
985impl<S: BaseFloat> approx::UlpsEq for Matrix2<S> {
986 #[inline]
987 fn default_max_ulps() -> u32 {
988 S::default_max_ulps()
989 }
990
991 #[inline]
992 fn ulps_eq(&self, other: &Self, epsilon: S::Epsilon, max_ulps: u32) -> bool {
993 Vector2::ulps_eq(&self[0], &other[0], epsilon, max_ulps)
994 && Vector2::ulps_eq(&self[1], &other[1], epsilon, max_ulps)
995 }
996}
997
998impl<S: BaseFloat> approx::AbsDiffEq for Matrix3<S> {
999 type Epsilon = S::Epsilon;
1000
1001 #[inline]
1002 fn default_epsilon() -> S::Epsilon {
1003 cast(1.0e-6f64).unwrap()
1004 }
1005
1006 #[inline]
1007 fn abs_diff_eq(&self, other: &Self, epsilon: S::Epsilon) -> bool {
1008 Vector3::abs_diff_eq(&self[0], &other[0], epsilon)
1009 && Vector3::abs_diff_eq(&self[1], &other[1], epsilon)
1010 && Vector3::abs_diff_eq(&self[2], &other[2], epsilon)
1011 }
1012}
1013
1014impl<S: BaseFloat> approx::RelativeEq for Matrix3<S> {
1015 #[inline]
1016 fn default_max_relative() -> S::Epsilon {
1017 S::default_max_relative()
1018 }
1019
1020 #[inline]
1021 fn relative_eq(&self, other: &Self, epsilon: S::Epsilon, max_relative: S::Epsilon) -> bool {
1022 Vector3::relative_eq(&self[0], &other[0], epsilon, max_relative)
1023 && Vector3::relative_eq(&self[1], &other[1], epsilon, max_relative)
1024 && Vector3::relative_eq(&self[2], &other[2], epsilon, max_relative)
1025 }
1026}
1027
1028impl<S: BaseFloat> approx::UlpsEq for Matrix3<S> {
1029 #[inline]
1030 fn default_max_ulps() -> u32 {
1031 S::default_max_ulps()
1032 }
1033
1034 #[inline]
1035 fn ulps_eq(&self, other: &Self, epsilon: S::Epsilon, max_ulps: u32) -> bool {
1036 Vector3::ulps_eq(&self[0], &other[0], epsilon, max_ulps)
1037 && Vector3::ulps_eq(&self[1], &other[1], epsilon, max_ulps)
1038 && Vector3::ulps_eq(&self[2], &other[2], epsilon, max_ulps)
1039 }
1040}
1041
1042impl<S: BaseFloat> approx::AbsDiffEq for Matrix4<S> {
1043 type Epsilon = S::Epsilon;
1044
1045 #[inline]
1046 fn default_epsilon() -> S::Epsilon {
1047 cast(1.0e-6f64).unwrap()
1048 }
1049
1050 #[inline]
1051 fn abs_diff_eq(&self, other: &Self, epsilon: S::Epsilon) -> bool {
1052 Vector4::abs_diff_eq(&self[0], &other[0], epsilon)
1053 && Vector4::abs_diff_eq(&self[1], &other[1], epsilon)
1054 && Vector4::abs_diff_eq(&self[2], &other[2], epsilon)
1055 && Vector4::abs_diff_eq(&self[3], &other[3], epsilon)
1056 }
1057}
1058
1059impl<S: BaseFloat> approx::RelativeEq for Matrix4<S> {
1060 #[inline]
1061 fn default_max_relative() -> S::Epsilon {
1062 S::default_max_relative()
1063 }
1064
1065 #[inline]
1066 fn relative_eq(&self, other: &Self, epsilon: S::Epsilon, max_relative: S::Epsilon) -> bool {
1067 Vector4::relative_eq(&self[0], &other[0], epsilon, max_relative)
1068 && Vector4::relative_eq(&self[1], &other[1], epsilon, max_relative)
1069 && Vector4::relative_eq(&self[2], &other[2], epsilon, max_relative)
1070 && Vector4::relative_eq(&self[3], &other[3], epsilon, max_relative)
1071 }
1072}
1073
1074impl<S: BaseFloat> approx::UlpsEq for Matrix4<S> {
1075 #[inline]
1076 fn default_max_ulps() -> u32 {
1077 S::default_max_ulps()
1078 }
1079
1080 #[inline]
1081 fn ulps_eq(&self, other: &Self, epsilon: S::Epsilon, max_ulps: u32) -> bool {
1082 Vector4::ulps_eq(&self[0], &other[0], epsilon, max_ulps)
1083 && Vector4::ulps_eq(&self[1], &other[1], epsilon, max_ulps)
1084 && Vector4::ulps_eq(&self[2], &other[2], epsilon, max_ulps)
1085 && Vector4::ulps_eq(&self[3], &other[3], epsilon, max_ulps)
1086 }
1087}
1088
1089impl<S: BaseFloat> Transform<Point2<S>> for Matrix3<S> {
1090 fn look_at(eye: Point2<S>, center: Point2<S>, up: Vector2<S>) -> Matrix3<S> {
1091 let dir = center - eye;
1092 Matrix3::from(Matrix2::look_at(dir, up))
1093 }
1094
1095 fn look_at_lh(eye: Point2<S>, center: Point2<S>, up: Vector2<S>) -> Matrix3<S> {
1096 let dir = center - eye;
1097 Matrix3::from(Matrix2::look_at(dir, up))
1098 }
1099
1100 fn look_at_rh(eye: Point2<S>, center: Point2<S>, up: Vector2<S>) -> Matrix3<S> {
1101 let dir = eye - center;
1102 Matrix3::from(Matrix2::look_at(dir, up))
1103 }
1104
1105 fn transform_vector(&self, vec: Vector2<S>) -> Vector2<S> {
1106 (self * vec.extend(S::zero())).truncate()
1107 }
1108
1109 fn transform_point(&self, point: Point2<S>) -> Point2<S> {
1110 Point2::from_vec((self * Point3::new(point.x, point.y, S::one()).to_vec()).truncate())
1111 }
1112
1113 fn concat(&self, other: &Matrix3<S>) -> Matrix3<S> {
1114 self * other
1115 }
1116
1117 fn inverse_transform(&self) -> Option<Matrix3<S>> {
1118 SquareMatrix::invert(self)
1119 }
1120}
1121
1122impl<S: BaseFloat> Transform<Point3<S>> for Matrix3<S> {
1123 fn look_at(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix3<S> {
1124 let dir = center - eye;
1125 Matrix3::look_to_lh(dir, up)
1126 }
1127
1128 fn look_at_lh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix3<S> {
1129 let dir = center - eye;
1130 Matrix3::look_to_lh(dir, up)
1131 }
1132
1133 fn look_at_rh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix3<S> {
1134 let dir = center - eye;
1135 Matrix3::look_to_rh(dir, up)
1136 }
1137
1138 fn transform_vector(&self, vec: Vector3<S>) -> Vector3<S> {
1139 self * vec
1140 }
1141
1142 fn transform_point(&self, point: Point3<S>) -> Point3<S> {
1143 Point3::from_vec(self * point.to_vec())
1144 }
1145
1146 fn concat(&self, other: &Matrix3<S>) -> Matrix3<S> {
1147 self * other
1148 }
1149
1150 fn inverse_transform(&self) -> Option<Matrix3<S>> {
1151 SquareMatrix::invert(self)
1152 }
1153}
1154
1155impl<S: BaseFloat> Transform<Point3<S>> for Matrix4<S> {
1156
1157 fn look_at(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix4<S> {
1158 Matrix4::look_at_rh(eye, center, up)
1159 }
1160
1161 fn look_at_lh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix4<S> {
1162 Matrix4::look_at_lh(eye, center, up)
1163 }
1164
1165 fn look_at_rh(eye: Point3<S>, center: Point3<S>, up: Vector3<S>) -> Matrix4<S> {
1166 Matrix4::look_at_rh(eye, center, up)
1167 }
1168
1169 fn transform_vector(&self, vec: Vector3<S>) -> Vector3<S> {
1170 (self * vec.extend(S::zero())).truncate()
1171 }
1172
1173 fn transform_point(&self, point: Point3<S>) -> Point3<S> {
1174 Point3::from_homogeneous(self * point.to_homogeneous())
1175 }
1176
1177 fn concat(&self, other: &Matrix4<S>) -> Matrix4<S> {
1178 self * other
1179 }
1180
1181 fn inverse_transform(&self) -> Option<Matrix4<S>> {
1182 SquareMatrix::invert(self)
1183 }
1184}
1185
1186impl<S: BaseFloat> Transform2 for Matrix3<S> {
1187 type Scalar = S;
1188}
1189
1190impl<S: BaseFloat> Transform3 for Matrix3<S> {
1191 type Scalar = S;
1192}
1193
1194impl<S: BaseFloat> Transform3 for Matrix4<S> {
1195 type Scalar = S;
1196}
1197
1198macro_rules! impl_matrix {
1199 ($MatrixN:ident, $VectorN:ident { $($field:ident : $row_index:expr),+ }) => {
1200 impl_operator!(<S: BaseFloat> Neg for $MatrixN<S> {
1201 fn neg(matrix) -> $MatrixN<S> { $MatrixN { $($field: -matrix.$field),+ } }
1202 });
1203
1204 impl_operator!(<S: BaseFloat> Mul<S> for $MatrixN<S> {
1205 fn mul(matrix, scalar) -> $MatrixN<S> { $MatrixN { $($field: matrix.$field * scalar),+ } }
1206 });
1207 impl_operator!(<S: BaseFloat> Div<S> for $MatrixN<S> {
1208 fn div(matrix, scalar) -> $MatrixN<S> { $MatrixN { $($field: matrix.$field / scalar),+ } }
1209 });
1210 impl_operator!(<S: BaseFloat> Rem<S> for $MatrixN<S> {
1211 fn rem(matrix, scalar) -> $MatrixN<S> { $MatrixN { $($field: matrix.$field % scalar),+ } }
1212 });
1213 impl_assignment_operator!(<S: BaseFloat> MulAssign<S> for $MatrixN<S> {
1214 fn mul_assign(&mut self, scalar) { $(self.$field *= scalar);+ }
1215 });
1216 impl_assignment_operator!(<S: BaseFloat> DivAssign<S> for $MatrixN<S> {
1217 fn div_assign(&mut self, scalar) { $(self.$field /= scalar);+ }
1218 });
1219 impl_assignment_operator!(<S: BaseFloat> RemAssign<S> for $MatrixN<S> {
1220 fn rem_assign(&mut self, scalar) { $(self.$field %= scalar);+ }
1221 });
1222
1223 impl_operator!(<S: BaseFloat> Add<$MatrixN<S> > for $MatrixN<S> {
1224 fn add(lhs, rhs) -> $MatrixN<S> { $MatrixN { $($field: lhs.$field + rhs.$field),+ } }
1225 });
1226 impl_operator!(<S: BaseFloat> Sub<$MatrixN<S> > for $MatrixN<S> {
1227 fn sub(lhs, rhs) -> $MatrixN<S> { $MatrixN { $($field: lhs.$field - rhs.$field),+ } }
1228 });
1229 impl<S: BaseFloat + AddAssign<S>> AddAssign<$MatrixN<S>> for $MatrixN<S> {
1230 fn add_assign(&mut self, other: $MatrixN<S>) { $(self.$field += other.$field);+ }
1231 }
1232 impl<S: BaseFloat + SubAssign<S>> SubAssign<$MatrixN<S>> for $MatrixN<S> {
1233 fn sub_assign(&mut self, other: $MatrixN<S>) { $(self.$field -= other.$field);+ }
1234 }
1235
1236 impl<S: BaseFloat> iter::Sum<$MatrixN<S>> for $MatrixN<S> {
1237 #[inline]
1238 fn sum<I: Iterator<Item=$MatrixN<S>>>(iter: I) -> $MatrixN<S> {
1239 iter.fold($MatrixN::zero(), Add::add)
1240 }
1241 }
1242
1243 impl<'a, S: 'a + BaseFloat> iter::Sum<&'a $MatrixN<S>> for $MatrixN<S> {
1244 #[inline]
1245 fn sum<I: Iterator<Item=&'a $MatrixN<S>>>(iter: I) -> $MatrixN<S> {
1246 iter.fold($MatrixN::zero(), Add::add)
1247 }
1248 }
1249
1250 impl<S: BaseFloat> iter::Product for $MatrixN<S> {
1251 #[inline]
1252 fn product<I: Iterator<Item=$MatrixN<S>>>(iter: I) -> $MatrixN<S> {
1253 iter.fold($MatrixN::identity(), Mul::mul)
1254 }
1255 }
1256
1257 impl<'a, S: 'a + BaseFloat> iter::Product<&'a $MatrixN<S>> for $MatrixN<S> {
1258 #[inline]
1259 fn product<I: Iterator<Item=&'a $MatrixN<S>>>(iter: I) -> $MatrixN<S> {
1260 iter.fold($MatrixN::identity(), Mul::mul)
1261 }
1262 }
1263
1264 impl_scalar_ops!($MatrixN<usize> { $($field),+ });
1265 impl_scalar_ops!($MatrixN<u8> { $($field),+ });
1266 impl_scalar_ops!($MatrixN<u16> { $($field),+ });
1267 impl_scalar_ops!($MatrixN<u32> { $($field),+ });
1268 impl_scalar_ops!($MatrixN<u64> { $($field),+ });
1269 impl_scalar_ops!($MatrixN<isize> { $($field),+ });
1270 impl_scalar_ops!($MatrixN<i8> { $($field),+ });
1271 impl_scalar_ops!($MatrixN<i16> { $($field),+ });
1272 impl_scalar_ops!($MatrixN<i32> { $($field),+ });
1273 impl_scalar_ops!($MatrixN<i64> { $($field),+ });
1274 impl_scalar_ops!($MatrixN<f32> { $($field),+ });
1275 impl_scalar_ops!($MatrixN<f64> { $($field),+ });
1276
1277
1278 impl<S: NumCast + Copy> $MatrixN<S> {
1279 #[inline]
1281 pub fn cast<T: NumCast>(&self) -> Option<$MatrixN<T>> {
1282 $(
1283 let $field = match self.$field.cast() {
1284 Some(field) => field,
1285 None => return None
1286 };
1287 )+
1288 Some($MatrixN { $($field),+ })
1289 }
1290 }
1291 }
1292}
1293
1294macro_rules! impl_scalar_ops {
1295 ($MatrixN:ident<$S:ident> { $($field:ident),+ }) => {
1296 impl_operator!(Mul<$MatrixN<$S>> for $S {
1297 fn mul(scalar, matrix) -> $MatrixN<$S> { $MatrixN { $($field: scalar * matrix.$field),+ } }
1298 });
1299 impl_operator!(Div<$MatrixN<$S>> for $S {
1300 fn div(scalar, matrix) -> $MatrixN<$S> { $MatrixN { $($field: scalar / matrix.$field),+ } }
1301 });
1302 impl_operator!(Rem<$MatrixN<$S>> for $S {
1303 fn rem(scalar, matrix) -> $MatrixN<$S> { $MatrixN { $($field: scalar % matrix.$field),+ } }
1304 });
1305 };
1306}
1307
1308impl_matrix!(Matrix2, Vector2 { x: 0, y: 1 });
1309impl_matrix!(Matrix3, Vector3 { x: 0, y: 1, z: 2 });
1310#[cfg_attr(rustfmt, rustfmt_skip)]
1311impl_matrix!(Matrix4, Vector4 { x: 0, y: 1, z: 2, w: 3 });
1312
1313macro_rules! impl_mv_operator {
1314 ($MatrixN:ident, $VectorN:ident { $($field:ident : $row_index:expr),+ }) => {
1315 impl_operator!(<S: BaseFloat> Mul<$VectorN<S> > for $MatrixN<S> {
1316 fn mul(matrix, vector) -> $VectorN<S> {$VectorN::new($(matrix.row($row_index).dot(vector.clone())),+)}
1317 });
1318 }
1319}
1320
1321impl_mv_operator!(Matrix2, Vector2 { x: 0, y: 1 });
1322impl_mv_operator!(Matrix3, Vector3 { x: 0, y: 1, z: 2 });
1323#[cfg(not(feature = "simd"))]
1324#[cfg_attr(rustfmt, rustfmt_skip)]
1325impl_mv_operator!(Matrix4, Vector4 { x: 0, y: 1, z: 2, w: 3 });
1326
1327#[cfg(feature = "simd")]
1328impl_operator!(<S: BaseFloat> Mul<Vector4<S> > for Matrix4<S> {
1329 fn mul(matrix, vector) -> Vector4<S> {
1330 matrix[0] * vector[0] + matrix[1] * vector[1] + matrix[2] * vector[2] + matrix[3] * vector[3]
1331 }
1332});
1333
1334impl_operator!(<S: BaseFloat> Mul<Matrix2<S> > for Matrix2<S> {
1335 fn mul(lhs, rhs) -> Matrix2<S> {
1336 Matrix2::new(lhs.row(0).dot(rhs[0]), lhs.row(1).dot(rhs[0]),
1337 lhs.row(0).dot(rhs[1]), lhs.row(1).dot(rhs[1]))
1338 }
1339});
1340
1341impl_operator!(<S: BaseFloat> Mul<Matrix3<S> > for Matrix3<S> {
1342 fn mul(lhs, rhs) -> Matrix3<S> {
1343 Matrix3::new(lhs.row(0).dot(rhs[0]), lhs.row(1).dot(rhs[0]), lhs.row(2).dot(rhs[0]),
1344 lhs.row(0).dot(rhs[1]), lhs.row(1).dot(rhs[1]), lhs.row(2).dot(rhs[1]),
1345 lhs.row(0).dot(rhs[2]), lhs.row(1).dot(rhs[2]), lhs.row(2).dot(rhs[2]))
1346 }
1347});
1348
1349impl_operator!(<S: BaseFloat> Mul<Matrix4<S> > for Matrix4<S> {
1356 fn mul(lhs, rhs) -> Matrix4<S> {
1357 {
1358 let a = lhs[0];
1359 let b = lhs[1];
1360 let c = lhs[2];
1361 let d = lhs[3];
1362
1363 #[cfg_attr(rustfmt, rustfmt_skip)]
1364 Matrix4::from_cols(
1365 a*rhs[0][0] + b*rhs[0][1] + c*rhs[0][2] + d*rhs[0][3],
1366 a*rhs[1][0] + b*rhs[1][1] + c*rhs[1][2] + d*rhs[1][3],
1367 a*rhs[2][0] + b*rhs[2][1] + c*rhs[2][2] + d*rhs[2][3],
1368 a*rhs[3][0] + b*rhs[3][1] + c*rhs[3][2] + d*rhs[3][3],
1369 )
1370 }
1371 }
1372});
1373
1374macro_rules! index_operators {
1375 ($MatrixN:ident<$S:ident>, $n:expr, $Output:ty, $I:ty) => {
1376 impl<$S> Index<$I> for $MatrixN<$S> {
1377 type Output = $Output;
1378
1379 #[inline]
1380 fn index<'a>(&'a self, i: $I) -> &'a $Output {
1381 let v: &[[$S; $n]; $n] = self.as_ref();
1382 From::from(&v[i])
1383 }
1384 }
1385
1386 impl<$S> IndexMut<$I> for $MatrixN<$S> {
1387 #[inline]
1388 fn index_mut<'a>(&'a mut self, i: $I) -> &'a mut $Output {
1389 let v: &mut [[$S; $n]; $n] = self.as_mut();
1390 From::from(&mut v[i])
1391 }
1392 }
1393 };
1394}
1395
1396index_operators!(Matrix2<S>, 2, Vector2<S>, usize);
1397index_operators!(Matrix3<S>, 3, Vector3<S>, usize);
1398index_operators!(Matrix4<S>, 4, Vector4<S>, usize);
1399impl<A> From<Euler<A>> for Matrix3<A::Unitless>
1413where
1414 A: Angle + Into<Rad<<A as Angle>::Unitless>>,
1415{
1416 fn from(src: Euler<A>) -> Matrix3<A::Unitless> {
1417 let (sx, cx) = Rad::sin_cos(src.x.into());
1419 let (sy, cy) = Rad::sin_cos(src.y.into());
1420 let (sz, cz) = Rad::sin_cos(src.z.into());
1421
1422 #[cfg_attr(rustfmt, rustfmt_skip)]
1423 Matrix3::new(
1424 cy * cz, cx * sz + sx * sy * cz, sx * sz - cx * sy * cz,
1425 -cy * sz, cx * cz - sx * sy * sz, sx * cz + cx * sy * sz,
1426 sy, -sx * cy, cx * cy,
1427 )
1428 }
1429}
1430
1431impl<A> From<Euler<A>> for Matrix4<A::Unitless>
1432where
1433 A: Angle + Into<Rad<<A as Angle>::Unitless>>,
1434{
1435 fn from(src: Euler<A>) -> Matrix4<A::Unitless> {
1436 let (sx, cx) = Rad::sin_cos(src.x.into());
1438 let (sy, cy) = Rad::sin_cos(src.y.into());
1439 let (sz, cz) = Rad::sin_cos(src.z.into());
1440
1441 #[cfg_attr(rustfmt, rustfmt_skip)]
1442 Matrix4::new(
1443 cy * cz, cx * sz + sx * sy * cz, sx * sz - cx * sy * cz, A::Unitless::zero(),
1444 -cy * sz, cx * cz - sx * sy * sz, sx * cz + cx * sy * sz, A::Unitless::zero(),
1445 sy, -sx * cy, cx * cy, A::Unitless::zero(),
1446 A::Unitless::zero(), A::Unitless::zero(), A::Unitless::zero(), A::Unitless::one(),
1447 )
1448 }
1449}
1450
1451macro_rules! fixed_array_conversions {
1452 ($MatrixN:ident <$S:ident> { $($field:ident : $index:expr),+ }, $n:expr) => {
1453 impl<$S> Into<[[$S; $n]; $n]> for $MatrixN<$S> {
1454 #[inline]
1455 fn into(self) -> [[$S; $n]; $n] {
1456 match self { $MatrixN { $($field),+ } => [$($field.into()),+] }
1457 }
1458 }
1459
1460 impl<$S> AsRef<[[$S; $n]; $n]> for $MatrixN<$S> {
1461 #[inline]
1462 fn as_ref(&self) -> &[[$S; $n]; $n] {
1463 unsafe { mem::transmute(self) }
1464 }
1465 }
1466
1467 impl<$S> AsMut<[[$S; $n]; $n]> for $MatrixN<$S> {
1468 #[inline]
1469 fn as_mut(&mut self) -> &mut [[$S; $n]; $n] {
1470 unsafe { mem::transmute(self) }
1471 }
1472 }
1473
1474 impl<$S: Copy> From<[[$S; $n]; $n]> for $MatrixN<$S> {
1475 #[inline]
1476 fn from(m: [[$S; $n]; $n]) -> $MatrixN<$S> {
1477 $MatrixN { $($field: From::from(m[$index])),+ }
1479 }
1480 }
1481
1482 impl<'a, $S> From<&'a [[$S; $n]; $n]> for &'a $MatrixN<$S> {
1483 #[inline]
1484 fn from(m: &'a [[$S; $n]; $n]) -> &'a $MatrixN<$S> {
1485 unsafe { mem::transmute(m) }
1486 }
1487 }
1488
1489 impl<'a, $S> From<&'a mut [[$S; $n]; $n]> for &'a mut $MatrixN<$S> {
1490 #[inline]
1491 fn from(m: &'a mut [[$S; $n]; $n]) -> &'a mut $MatrixN<$S> {
1492 unsafe { mem::transmute(m) }
1493 }
1494 }
1495
1496 impl<$S> AsRef<[$S; ($n * $n)]> for $MatrixN<$S> {
1505 #[inline]
1506 fn as_ref(&self) -> &[$S; ($n * $n)] {
1507 unsafe { mem::transmute(self) }
1508 }
1509 }
1510
1511 impl<$S> AsMut<[$S; ($n * $n)]> for $MatrixN<$S> {
1512 #[inline]
1513 fn as_mut(&mut self) -> &mut [$S; ($n * $n)] {
1514 unsafe { mem::transmute(self) }
1515 }
1516 }
1517
1518 impl<'a, $S> From<&'a [$S; ($n * $n)]> for &'a $MatrixN<$S> {
1527 #[inline]
1528 fn from(m: &'a [$S; ($n * $n)]) -> &'a $MatrixN<$S> {
1529 unsafe { mem::transmute(m) }
1530 }
1531 }
1532
1533 impl<'a, $S> From<&'a mut [$S; ($n * $n)]> for &'a mut $MatrixN<$S> {
1534 #[inline]
1535 fn from(m: &'a mut [$S; ($n * $n)]) -> &'a mut $MatrixN<$S> {
1536 unsafe { mem::transmute(m) }
1537 }
1538 }
1539 }
1540}
1541
1542fixed_array_conversions!(Matrix2<S> { x:0, y:1 }, 2);
1543fixed_array_conversions!(Matrix3<S> { x:0, y:1, z:2 }, 3);
1544fixed_array_conversions!(Matrix4<S> { x:0, y:1, z:2, w:3 }, 4);
1545
1546#[cfg(feature = "mint")]
1547macro_rules! mint_conversions {
1548 ($MatrixN:ident { $($field:ident),+ }, $MintN:ident) => {
1549 impl<S: Clone> Into<mint::$MintN<S>> for $MatrixN<S> {
1550 #[inline]
1551 fn into(self) -> mint::$MintN<S> {
1552 mint::$MintN { $($field: self.$field.into()),+ }
1553 }
1554 }
1555
1556 impl<S> From<mint::$MintN<S>> for $MatrixN<S> {
1557 #[inline]
1558 fn from(m: mint::$MintN<S>) -> Self {
1559 $MatrixN { $($field: m.$field.into()),+ }
1560 }
1561 }
1562
1563 }
1564}
1565
1566#[cfg(feature = "mint")]
1567mint_conversions!(Matrix2 { x, y }, ColumnMatrix2);
1568#[cfg(feature = "mint")]
1569mint_conversions!(Matrix3 { x, y, z }, ColumnMatrix3);
1570#[cfg(feature = "mint")]
1571mint_conversions!(Matrix4 { x, y, z, w }, ColumnMatrix4);
1572
1573impl<S: BaseFloat> From<Matrix2<S>> for Matrix3<S> {
1574 fn from(m: Matrix2<S>) -> Matrix3<S> {
1577 #[cfg_attr(rustfmt, rustfmt_skip)]
1578 Matrix3::new(
1579 m[0][0], m[0][1], S::zero(),
1580 m[1][0], m[1][1], S::zero(),
1581 S::zero(), S::zero(), S::one(),
1582 )
1583 }
1584}
1585
1586impl<S: BaseFloat> From<Matrix2<S>> for Matrix4<S> {
1587 fn from(m: Matrix2<S>) -> Matrix4<S> {
1590 #[cfg_attr(rustfmt, rustfmt_skip)]
1591 Matrix4::new(
1592 m[0][0], m[0][1], S::zero(), S::zero(),
1593 m[1][0], m[1][1], S::zero(), S::zero(),
1594 S::zero(), S::zero(), S::one(), S::zero(),
1595 S::zero(), S::zero(), S::zero(), S::one(),
1596 )
1597 }
1598}
1599
1600impl<S: BaseFloat> From<Matrix3<S>> for Matrix4<S> {
1601 fn from(m: Matrix3<S>) -> Matrix4<S> {
1604 #[cfg_attr(rustfmt, rustfmt_skip)]
1605 Matrix4::new(
1606 m[0][0], m[0][1], m[0][2], S::zero(),
1607 m[1][0], m[1][1], m[1][2], S::zero(),
1608 m[2][0], m[2][1], m[2][2], S::zero(),
1609 S::zero(), S::zero(), S::zero(), S::one(),
1610 )
1611 }
1612}
1613
1614impl<S: BaseFloat> From<Matrix3<S>> for Quaternion<S> {
1615 fn from(mat: Matrix3<S>) -> Quaternion<S> {
1617 let trace = mat.trace();
1619 let half: S = cast(0.5f64).unwrap();
1620
1621 if trace >= S::zero() {
1622 let s = (S::one() + trace).sqrt();
1623 let w = half * s;
1624 let s = half / s;
1625 let x = (mat[1][2] - mat[2][1]) * s;
1626 let y = (mat[2][0] - mat[0][2]) * s;
1627 let z = (mat[0][1] - mat[1][0]) * s;
1628 Quaternion::new(w, x, y, z)
1629 } else if (mat[0][0] > mat[1][1]) && (mat[0][0] > mat[2][2]) {
1630 let s = ((mat[0][0] - mat[1][1] - mat[2][2]) + S::one()).sqrt();
1631 let x = half * s;
1632 let s = half / s;
1633 let y = (mat[1][0] + mat[0][1]) * s;
1634 let z = (mat[0][2] + mat[2][0]) * s;
1635 let w = (mat[1][2] - mat[2][1]) * s;
1636 Quaternion::new(w, x, y, z)
1637 } else if mat[1][1] > mat[2][2] {
1638 let s = ((mat[1][1] - mat[0][0] - mat[2][2]) + S::one()).sqrt();
1639 let y = half * s;
1640 let s = half / s;
1641 let z = (mat[2][1] + mat[1][2]) * s;
1642 let x = (mat[1][0] + mat[0][1]) * s;
1643 let w = (mat[2][0] - mat[0][2]) * s;
1644 Quaternion::new(w, x, y, z)
1645 } else {
1646 let s = ((mat[2][2] - mat[0][0] - mat[1][1]) + S::one()).sqrt();
1647 let z = half * s;
1648 let s = half / s;
1649 let x = (mat[0][2] + mat[2][0]) * s;
1650 let y = (mat[2][1] + mat[1][2]) * s;
1651 let w = (mat[0][1] - mat[1][0]) * s;
1652 Quaternion::new(w, x, y, z)
1653 }
1654 }
1655}
1656
1657impl<S: fmt::Debug> fmt::Debug for Matrix2<S> {
1658 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1659 write!(f, "Matrix2 ")?;
1660 <[[S; 2]; 2] as fmt::Debug>::fmt(self.as_ref(), f)
1661 }
1662}
1663
1664impl<S: fmt::Debug> fmt::Debug for Matrix3<S> {
1665 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1666 write!(f, "Matrix3 ")?;
1667 <[[S; 3]; 3] as fmt::Debug>::fmt(self.as_ref(), f)
1668 }
1669}
1670
1671impl<S: fmt::Debug> fmt::Debug for Matrix4<S> {
1672 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1673 write!(f, "Matrix4 ")?;
1674 <[[S; 4]; 4] as fmt::Debug>::fmt(self.as_ref(), f)
1675 }
1676}
1677
1678#[cfg(feature = "rand")]
1679impl<S> Distribution<Matrix2<S>> for Standard
1680where
1681 Standard: Distribution<Vector2<S>>,
1682 S: BaseFloat,
1683{
1684 #[inline]
1685 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Matrix2<S> {
1686 Matrix2 {
1687 x: self.sample(rng),
1688 y: self.sample(rng),
1689 }
1690 }
1691}
1692
1693#[cfg(feature = "rand")]
1694impl<S> Distribution<Matrix3<S>> for Standard
1695where
1696 Standard: Distribution<Vector3<S>>,
1697 S: BaseFloat,
1698{
1699 #[inline]
1700 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Matrix3<S> {
1701 Matrix3 {
1702 x: rng.gen(),
1703 y: rng.gen(),
1704 z: rng.gen(),
1705 }
1706 }
1707}
1708
1709#[cfg(feature = "rand")]
1710impl<S> Distribution<Matrix4<S>> for Standard
1711where
1712 Standard: Distribution<Vector4<S>>,
1713 S: BaseFloat,
1714{
1715 #[inline]
1716 fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Matrix4<S> {
1717 Matrix4 {
1718 x: rng.gen(),
1719 y: rng.gen(),
1720 z: rng.gen(),
1721 w: rng.gen(),
1722 }
1723 }
1724}
1725
1726#[inline]
1728unsafe fn det_sub_proc_unsafe<S: BaseFloat>(
1729 m: &Matrix4<S>,
1730 x: usize,
1731 y: usize,
1732 z: usize,
1733) -> Vector4<S> {
1734 let s: &[S; 16] = m.as_ref();
1735 let a = Vector4::new(
1736 *s.get_unchecked(4 + x),
1737 *s.get_unchecked(12 + x),
1738 *s.get_unchecked(x),
1739 *s.get_unchecked(8 + x),
1740 );
1741 let b = Vector4::new(
1742 *s.get_unchecked(8 + y),
1743 *s.get_unchecked(8 + y),
1744 *s.get_unchecked(4 + y),
1745 *s.get_unchecked(4 + y),
1746 );
1747 let c = Vector4::new(
1748 *s.get_unchecked(12 + z),
1749 *s.get_unchecked(z),
1750 *s.get_unchecked(12 + z),
1751 *s.get_unchecked(z),
1752 );
1753
1754 let d = Vector4::new(
1755 *s.get_unchecked(8 + x),
1756 *s.get_unchecked(8 + x),
1757 *s.get_unchecked(4 + x),
1758 *s.get_unchecked(4 + x),
1759 );
1760 let e = Vector4::new(
1761 *s.get_unchecked(12 + y),
1762 *s.get_unchecked(y),
1763 *s.get_unchecked(12 + y),
1764 *s.get_unchecked(y),
1765 );
1766 let f = Vector4::new(
1767 *s.get_unchecked(4 + z),
1768 *s.get_unchecked(12 + z),
1769 *s.get_unchecked(z),
1770 *s.get_unchecked(8 + z),
1771 );
1772
1773 let g = Vector4::new(
1774 *s.get_unchecked(12 + x),
1775 *s.get_unchecked(x),
1776 *s.get_unchecked(12 + x),
1777 *s.get_unchecked(x),
1778 );
1779 let h = Vector4::new(
1780 *s.get_unchecked(4 + y),
1781 *s.get_unchecked(12 + y),
1782 *s.get_unchecked(y),
1783 *s.get_unchecked(8 + y),
1784 );
1785 let i = Vector4::new(
1786 *s.get_unchecked(8 + z),
1787 *s.get_unchecked(8 + z),
1788 *s.get_unchecked(4 + z),
1789 *s.get_unchecked(4 + z),
1790 );
1791 let mut tmp = a.mul_element_wise(b.mul_element_wise(c));
1792 tmp += d.mul_element_wise(e.mul_element_wise(f));
1793 tmp += g.mul_element_wise(h.mul_element_wise(i));
1794 tmp -= a.mul_element_wise(e.mul_element_wise(i));
1795 tmp -= d.mul_element_wise(h.mul_element_wise(c));
1796 tmp -= g.mul_element_wise(b.mul_element_wise(f));
1797 tmp
1798}