1#[cfg(feature = "f64")]
4use crate::DMat2;
5
6use crate::{f32::math, swizzles::*, Mat3, Mat3A, Vec2};
7use core::fmt;
8use core::iter::{Product, Sum};
9use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
10
11#[cfg(target_arch = "x86")]
12use core::arch::x86::*;
13#[cfg(target_arch = "x86_64")]
14use core::arch::x86_64::*;
15
16#[cfg(feature = "zerocopy-08")]
17use zerocopy_derive_08::*;
18
19#[repr(C)]
20union UnionCast {
21 a: [f32; 4],
22 v: Mat2,
23}
24
25#[inline(always)]
27#[must_use]
28pub const fn mat2(x_axis: Vec2, y_axis: Vec2) -> Mat2 {
29 Mat2::from_cols(x_axis, y_axis)
30}
31
32#[derive(Clone, Copy)]
38#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
39#[cfg_attr(
40 feature = "zerocopy-08",
41 derive(FromBytes, Immutable, IntoBytes, KnownLayout)
42)]
43#[repr(transparent)]
44pub struct Mat2(pub(crate) __m128);
45
46impl Mat2 {
47 pub const ZERO: Self = Self::from_cols(Vec2::ZERO, Vec2::ZERO);
49
50 pub const IDENTITY: Self = Self::from_cols(Vec2::X, Vec2::Y);
52
53 pub const NAN: Self = Self::from_cols(Vec2::NAN, Vec2::NAN);
55
56 #[allow(clippy::too_many_arguments)]
57 #[inline(always)]
58 #[must_use]
59 const fn new(m00: f32, m01: f32, m10: f32, m11: f32) -> Self {
60 unsafe {
61 UnionCast {
62 a: [m00, m01, m10, m11],
63 }
64 .v
65 }
66 }
67
68 #[inline(always)]
72 #[must_use]
73 pub const fn from_cols(x_axis: Vec2, y_axis: Vec2) -> Self {
74 unsafe {
75 UnionCast {
76 a: [x_axis.x, x_axis.y, y_axis.x, y_axis.y],
77 }
78 .v
79 }
80 }
81
82 #[inline(always)]
88 #[must_use]
89 pub const fn from_rows(row0: Vec2, row1: Vec2) -> Self {
90 let [m00, m01] = row0.to_array();
91 let [m10, m11] = row1.to_array();
92 Self::new(m00, m10, m01, m11)
93 }
94
95 #[inline]
99 #[must_use]
100 pub const fn from_cols_array(m: &[f32; 4]) -> Self {
101 Self::new(m[0], m[1], m[2], m[3])
102 }
103
104 #[inline]
108 #[must_use]
109 pub const fn to_cols_array(&self) -> [f32; 4] {
110 unsafe { *(self as *const Self as *const [f32; 4]) }
111 }
112
113 #[inline]
117 #[must_use]
118 pub const fn from_cols_array_2d(m: &[[f32; 2]; 2]) -> Self {
119 Self::from_cols(Vec2::from_array(m[0]), Vec2::from_array(m[1]))
120 }
121
122 #[inline]
126 #[must_use]
127 pub const fn to_cols_array_2d(&self) -> [[f32; 2]; 2] {
128 unsafe { *(self as *const Self as *const [[f32; 2]; 2]) }
129 }
130
131 #[inline]
137 #[must_use]
138 pub const fn from_rows_array(m: &[f32; 4]) -> Self {
139 Self::new(m[0], m[2], m[1], m[3])
140 }
141
142 #[inline]
148 #[must_use]
149 pub const fn to_rows_array(&self) -> [f32; 4] {
150 let m = self.to_cols_array();
151 [m[0], m[2], m[1], m[3]]
152 }
153
154 #[doc(alias = "scale")]
156 #[inline]
157 #[must_use]
158 pub const fn from_diagonal(diagonal: Vec2) -> Self {
159 Self::new(diagonal.x, 0.0, 0.0, diagonal.y)
160 }
161
162 #[inline]
165 #[must_use]
166 pub fn from_scale_angle(scale: Vec2, angle: f32) -> Self {
167 let (sin, cos) = math::sin_cos(angle);
168 Self::new(cos * scale.x, sin * scale.x, -sin * scale.y, cos * scale.y)
169 }
170
171 #[inline]
173 #[must_use]
174 pub fn from_angle(angle: f32) -> Self {
175 let (sin, cos) = math::sin_cos(angle);
176 Self::new(cos, sin, -sin, cos)
177 }
178
179 #[inline]
181 #[must_use]
182 pub fn from_mat3(m: Mat3) -> Self {
183 Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
184 }
185
186 #[inline]
193 #[must_use]
194 pub fn from_mat3_minor(m: Mat3, i: usize, j: usize) -> Self {
195 match (i, j) {
196 (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
197 (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
198 (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
199 (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
200 (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
201 (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
202 (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
203 (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
204 (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
205 _ => panic!("index out of bounds"),
206 }
207 }
208
209 #[inline]
211 #[must_use]
212 pub fn from_mat3a(m: Mat3A) -> Self {
213 Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
214 }
215
216 #[inline]
223 #[must_use]
224 pub fn from_mat3a_minor(m: Mat3A, i: usize, j: usize) -> Self {
225 match (i, j) {
226 (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
227 (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
228 (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
229 (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
230 (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
231 (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
232 (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
233 (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
234 (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
235 _ => panic!("index out of bounds"),
236 }
237 }
238
239 #[inline]
247 #[must_use]
248 pub const fn from_cols_slice(slice: &[f32]) -> Self {
249 Self::new(slice[0], slice[1], slice[2], slice[3])
250 }
251
252 #[inline]
258 pub fn write_cols_to_slice(&self, slice: &mut [f32]) {
259 slice[0] = self.x_axis.x;
260 slice[1] = self.x_axis.y;
261 slice[2] = self.y_axis.x;
262 slice[3] = self.y_axis.y;
263 }
264
265 #[inline]
276 #[must_use]
277 pub const fn from_rows_slice(slice: &[f32]) -> Self {
278 Self::new(slice[0], slice[2], slice[1], slice[3])
279 }
280
281 #[inline]
287 #[must_use]
288 pub fn col(&self, index: usize) -> Vec2 {
289 match index {
290 0 => self.x_axis,
291 1 => self.y_axis,
292 _ => panic!("index out of bounds"),
293 }
294 }
295
296 #[inline]
302 pub fn col_mut(&mut self, index: usize) -> &mut Vec2 {
303 match index {
304 0 => &mut self.x_axis,
305 1 => &mut self.y_axis,
306 _ => panic!("index out of bounds"),
307 }
308 }
309
310 #[inline]
318 #[must_use]
319 pub fn row(&self, index: usize) -> Vec2 {
320 match index {
321 0 => Vec2::new(self.x_axis.x, self.y_axis.x),
322 1 => Vec2::new(self.x_axis.y, self.y_axis.y),
323 _ => panic!("index out of bounds"),
324 }
325 }
326
327 #[inline]
337 pub fn set_row(&mut self, index: usize, row: Vec2) {
338 match index {
339 0 => {
340 self.x_axis.x = row.x;
341 self.y_axis.x = row.y;
342 }
343 1 => {
344 self.x_axis.y = row.x;
345 self.y_axis.y = row.y;
346 }
347 _ => panic!("index out of bounds"),
348 }
349 }
350
351 #[inline]
354 #[must_use]
355 pub fn is_finite(&self) -> bool {
356 self.x_axis.is_finite() && self.y_axis.is_finite()
357 }
358
359 #[inline]
361 #[must_use]
362 pub fn is_nan(&self) -> bool {
363 self.x_axis.is_nan() || self.y_axis.is_nan()
364 }
365
366 #[inline]
368 #[must_use]
369 pub fn transpose(&self) -> Self {
370 Self(unsafe { _mm_shuffle_ps(self.0, self.0, 0b11_01_10_00) })
371 }
372
373 #[inline]
375 #[must_use]
376 pub fn diagonal(&self) -> Vec2 {
377 Vec2::new(self.x_axis.x, self.y_axis.y)
378 }
379
380 #[inline]
382 #[must_use]
383 pub fn determinant(&self) -> f32 {
384 unsafe {
385 let abcd = self.0;
386 let dcba = _mm_shuffle_ps(abcd, abcd, 0b00_01_10_11);
387 let prod = _mm_mul_ps(abcd, dcba);
388 let det = _mm_sub_ps(prod, _mm_shuffle_ps(prod, prod, 0b01_01_01_01));
389 _mm_cvtss_f32(det)
390 }
391 }
392
393 #[inline(always)]
405 #[must_use]
406 fn inverse_checked<const CHECKED: bool>(&self) -> (Self, bool) {
407 unsafe {
408 use crate::Vec4;
409 const SIGN: __m128 = crate::sse2::m128_from_f32x4([1.0, -1.0, -1.0, 1.0]);
410 let abcd = self.0;
411 let dcba = _mm_shuffle_ps(abcd, abcd, 0b00_01_10_11);
412 let prod = _mm_mul_ps(abcd, dcba);
413 let sub = _mm_sub_ps(prod, _mm_shuffle_ps(prod, prod, 0b01_01_01_01));
414 let det = _mm_shuffle_ps(sub, sub, 0b00_00_00_00);
415 if CHECKED {
416 if Vec4(det) == Vec4::ZERO {
417 return (Self::ZERO, false);
418 }
419 } else {
420 glam_assert!(Vec4(det).cmpne(Vec4::ZERO).all());
421 }
422 let tmp = _mm_div_ps(SIGN, det);
423 let dbca = _mm_shuffle_ps(abcd, abcd, 0b00_10_01_11);
424 (Self(_mm_mul_ps(dbca, tmp)), true)
425 }
426 }
427
428 #[inline]
436 #[must_use]
437 pub fn inverse(&self) -> Self {
438 self.inverse_checked::<false>().0
439 }
440
441 #[inline]
443 #[must_use]
444 pub fn try_inverse(&self) -> Option<Self> {
445 let (m, is_valid) = self.inverse_checked::<true>();
446 if is_valid {
447 Some(m)
448 } else {
449 None
450 }
451 }
452
453 #[inline]
455 #[must_use]
456 pub fn inverse_or_zero(&self) -> Self {
457 self.inverse_checked::<true>().0
458 }
459
460 #[inline]
462 #[must_use]
463 pub fn mul_vec2(&self, rhs: Vec2) -> Vec2 {
464 unsafe {
465 use crate::Align16;
466 use core::mem::MaybeUninit;
467 let abcd = self.0;
468 let xxyy = _mm_set_ps(rhs.y, rhs.y, rhs.x, rhs.x);
469 let axbxcydy = _mm_mul_ps(abcd, xxyy);
470 let cydyaxbx = _mm_shuffle_ps(axbxcydy, axbxcydy, 0b01_00_11_10);
471 let result = _mm_add_ps(axbxcydy, cydyaxbx);
472 let mut out: MaybeUninit<Align16<Vec2>> = MaybeUninit::uninit();
473 _mm_store_ps(out.as_mut_ptr().cast(), result);
474 out.assume_init().0
475 }
476 }
477
478 #[inline]
480 #[must_use]
481 pub fn mul_transpose_vec2(&self, rhs: Vec2) -> Vec2 {
482 Vec2::new(self.x_axis.dot(rhs), self.y_axis.dot(rhs))
483 }
484
485 #[inline]
487 #[must_use]
488 pub fn mul_mat2(&self, rhs: &Self) -> Self {
489 self.mul(rhs)
490 }
491
492 #[inline]
494 #[must_use]
495 pub fn add_mat2(&self, rhs: &Self) -> Self {
496 self.add(rhs)
497 }
498
499 #[inline]
501 #[must_use]
502 pub fn sub_mat2(&self, rhs: &Self) -> Self {
503 self.sub(rhs)
504 }
505
506 #[inline]
508 #[must_use]
509 pub fn mul_scalar(&self, rhs: f32) -> Self {
510 Self(unsafe { _mm_mul_ps(self.0, _mm_set_ps1(rhs)) })
511 }
512
513 #[inline]
517 #[must_use]
518 pub fn mul_diagonal_scale(&self, scale: Vec2) -> Self {
519 Self::from_cols(self.x_axis * scale.x, self.y_axis * scale.y)
520 }
521
522 #[inline]
524 #[must_use]
525 pub fn div_scalar(&self, rhs: f32) -> Self {
526 Self(unsafe { _mm_div_ps(self.0, _mm_set_ps1(rhs)) })
527 }
528
529 #[inline]
531 #[must_use]
532 pub fn recip(&self) -> Self {
533 Self::from_cols(self.x_axis.recip(), self.y_axis.recip())
534 }
535
536 #[inline]
546 #[must_use]
547 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
548 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
549 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
550 }
551
552 #[inline]
554 #[must_use]
555 pub fn abs(&self) -> Self {
556 Self::from_cols(self.x_axis.abs(), self.y_axis.abs())
557 }
558
559 #[cfg(feature = "f64")]
560 #[inline]
561 #[must_use]
562 pub fn as_dmat2(&self) -> DMat2 {
563 DMat2::from_cols(self.x_axis.as_dvec2(), self.y_axis.as_dvec2())
564 }
565}
566
567impl Default for Mat2 {
568 #[inline]
569 fn default() -> Self {
570 Self::IDENTITY
571 }
572}
573
574impl Add for Mat2 {
575 type Output = Self;
576 #[inline]
577 fn add(self, rhs: Self) -> Self {
578 Self(unsafe { _mm_add_ps(self.0, rhs.0) })
579 }
580}
581
582impl Add<&Self> for Mat2 {
583 type Output = Self;
584 #[inline]
585 fn add(self, rhs: &Self) -> Self {
586 self.add(*rhs)
587 }
588}
589
590impl Add<&Mat2> for &Mat2 {
591 type Output = Mat2;
592 #[inline]
593 fn add(self, rhs: &Mat2) -> Mat2 {
594 (*self).add(*rhs)
595 }
596}
597
598impl Add<Mat2> for &Mat2 {
599 type Output = Mat2;
600 #[inline]
601 fn add(self, rhs: Mat2) -> Mat2 {
602 (*self).add(rhs)
603 }
604}
605
606impl AddAssign for Mat2 {
607 #[inline]
608 fn add_assign(&mut self, rhs: Self) {
609 *self = self.add(rhs);
610 }
611}
612
613impl AddAssign<&Self> for Mat2 {
614 #[inline]
615 fn add_assign(&mut self, rhs: &Self) {
616 self.add_assign(*rhs);
617 }
618}
619
620impl Sub for Mat2 {
621 type Output = Self;
622 #[inline]
623 fn sub(self, rhs: Self) -> Self {
624 Self(unsafe { _mm_sub_ps(self.0, rhs.0) })
625 }
626}
627
628impl Sub<&Self> for Mat2 {
629 type Output = Self;
630 #[inline]
631 fn sub(self, rhs: &Self) -> Self {
632 self.sub(*rhs)
633 }
634}
635
636impl Sub<&Mat2> for &Mat2 {
637 type Output = Mat2;
638 #[inline]
639 fn sub(self, rhs: &Mat2) -> Mat2 {
640 (*self).sub(*rhs)
641 }
642}
643
644impl Sub<Mat2> for &Mat2 {
645 type Output = Mat2;
646 #[inline]
647 fn sub(self, rhs: Mat2) -> Mat2 {
648 (*self).sub(rhs)
649 }
650}
651
652impl SubAssign for Mat2 {
653 #[inline]
654 fn sub_assign(&mut self, rhs: Self) {
655 *self = self.sub(rhs);
656 }
657}
658
659impl SubAssign<&Self> for Mat2 {
660 #[inline]
661 fn sub_assign(&mut self, rhs: &Self) {
662 self.sub_assign(*rhs);
663 }
664}
665
666impl Neg for Mat2 {
667 type Output = Self;
668 #[inline]
669 fn neg(self) -> Self::Output {
670 Self(unsafe { _mm_xor_ps(self.0, _mm_set1_ps(-0.0)) })
671 }
672}
673
674impl Neg for &Mat2 {
675 type Output = Mat2;
676 #[inline]
677 fn neg(self) -> Mat2 {
678 (*self).neg()
679 }
680}
681
682impl Mul for Mat2 {
683 type Output = Self;
684 #[inline]
685 fn mul(self, rhs: Self) -> Self {
686 unsafe {
687 let abcd = self.0;
688 let rhs = rhs.0;
689 let xxyy0 = _mm_shuffle_ps(rhs, rhs, 0b01_01_00_00);
690 let xxyy1 = _mm_shuffle_ps(rhs, rhs, 0b11_11_10_10);
691 let axbxcydy0 = _mm_mul_ps(abcd, xxyy0);
692 let axbxcydy1 = _mm_mul_ps(abcd, xxyy1);
693 let cydyaxbx0 = _mm_shuffle_ps(axbxcydy0, axbxcydy0, 0b01_00_11_10);
694 let cydyaxbx1 = _mm_shuffle_ps(axbxcydy1, axbxcydy1, 0b01_00_11_10);
695 let result0 = _mm_add_ps(axbxcydy0, cydyaxbx0);
696 let result1 = _mm_add_ps(axbxcydy1, cydyaxbx1);
697 Self(_mm_shuffle_ps(result0, result1, 0b01_00_01_00))
698 }
699 }
700}
701
702impl Mul<&Self> for Mat2 {
703 type Output = Self;
704 #[inline]
705 fn mul(self, rhs: &Self) -> Self {
706 self.mul(*rhs)
707 }
708}
709
710impl Mul<&Mat2> for &Mat2 {
711 type Output = Mat2;
712 #[inline]
713 fn mul(self, rhs: &Mat2) -> Mat2 {
714 (*self).mul(*rhs)
715 }
716}
717
718impl Mul<Mat2> for &Mat2 {
719 type Output = Mat2;
720 #[inline]
721 fn mul(self, rhs: Mat2) -> Mat2 {
722 (*self).mul(rhs)
723 }
724}
725
726impl MulAssign for Mat2 {
727 #[inline]
728 fn mul_assign(&mut self, rhs: Self) {
729 *self = self.mul(rhs);
730 }
731}
732
733impl MulAssign<&Self> for Mat2 {
734 #[inline]
735 fn mul_assign(&mut self, rhs: &Self) {
736 self.mul_assign(*rhs);
737 }
738}
739
740impl Mul<Vec2> for Mat2 {
741 type Output = Vec2;
742 #[inline]
743 fn mul(self, rhs: Vec2) -> Self::Output {
744 self.mul_vec2(rhs)
745 }
746}
747
748impl Mul<&Vec2> for Mat2 {
749 type Output = Vec2;
750 #[inline]
751 fn mul(self, rhs: &Vec2) -> Vec2 {
752 self.mul(*rhs)
753 }
754}
755
756impl Mul<&Vec2> for &Mat2 {
757 type Output = Vec2;
758 #[inline]
759 fn mul(self, rhs: &Vec2) -> Vec2 {
760 (*self).mul(*rhs)
761 }
762}
763
764impl Mul<Vec2> for &Mat2 {
765 type Output = Vec2;
766 #[inline]
767 fn mul(self, rhs: Vec2) -> Vec2 {
768 (*self).mul(rhs)
769 }
770}
771
772impl Mul<Mat2> for f32 {
773 type Output = Mat2;
774 #[inline]
775 fn mul(self, rhs: Mat2) -> Self::Output {
776 rhs.mul_scalar(self)
777 }
778}
779
780impl Mul<&Mat2> for f32 {
781 type Output = Mat2;
782 #[inline]
783 fn mul(self, rhs: &Mat2) -> Mat2 {
784 self.mul(*rhs)
785 }
786}
787
788impl Mul<&Mat2> for &f32 {
789 type Output = Mat2;
790 #[inline]
791 fn mul(self, rhs: &Mat2) -> Mat2 {
792 (*self).mul(*rhs)
793 }
794}
795
796impl Mul<Mat2> for &f32 {
797 type Output = Mat2;
798 #[inline]
799 fn mul(self, rhs: Mat2) -> Mat2 {
800 (*self).mul(rhs)
801 }
802}
803
804impl Mul<f32> for Mat2 {
805 type Output = Self;
806 #[inline]
807 fn mul(self, rhs: f32) -> Self {
808 self.mul_scalar(rhs)
809 }
810}
811
812impl Mul<&f32> for Mat2 {
813 type Output = Self;
814 #[inline]
815 fn mul(self, rhs: &f32) -> Self {
816 self.mul(*rhs)
817 }
818}
819
820impl Mul<&f32> for &Mat2 {
821 type Output = Mat2;
822 #[inline]
823 fn mul(self, rhs: &f32) -> Mat2 {
824 (*self).mul(*rhs)
825 }
826}
827
828impl Mul<f32> for &Mat2 {
829 type Output = Mat2;
830 #[inline]
831 fn mul(self, rhs: f32) -> Mat2 {
832 (*self).mul(rhs)
833 }
834}
835
836impl MulAssign<f32> for Mat2 {
837 #[inline]
838 fn mul_assign(&mut self, rhs: f32) {
839 *self = self.mul(rhs);
840 }
841}
842
843impl MulAssign<&f32> for Mat2 {
844 #[inline]
845 fn mul_assign(&mut self, rhs: &f32) {
846 self.mul_assign(*rhs);
847 }
848}
849
850impl Div<Mat2> for f32 {
851 type Output = Mat2;
852 #[inline]
853 fn div(self, rhs: Mat2) -> Self::Output {
854 Mat2(unsafe { _mm_div_ps(_mm_set_ps1(self), rhs.0) })
855 }
856}
857
858impl Div<&Mat2> for f32 {
859 type Output = Mat2;
860 #[inline]
861 fn div(self, rhs: &Mat2) -> Mat2 {
862 self.div(*rhs)
863 }
864}
865
866impl Div<&Mat2> for &f32 {
867 type Output = Mat2;
868 #[inline]
869 fn div(self, rhs: &Mat2) -> Mat2 {
870 (*self).div(*rhs)
871 }
872}
873
874impl Div<Mat2> for &f32 {
875 type Output = Mat2;
876 #[inline]
877 fn div(self, rhs: Mat2) -> Mat2 {
878 (*self).div(rhs)
879 }
880}
881
882impl Div<f32> for Mat2 {
883 type Output = Self;
884 #[inline]
885 fn div(self, rhs: f32) -> Self {
886 self.div_scalar(rhs)
887 }
888}
889
890impl Div<&f32> for Mat2 {
891 type Output = Self;
892 #[inline]
893 fn div(self, rhs: &f32) -> Self {
894 self.div(*rhs)
895 }
896}
897
898impl Div<&f32> for &Mat2 {
899 type Output = Mat2;
900 #[inline]
901 fn div(self, rhs: &f32) -> Mat2 {
902 (*self).div(*rhs)
903 }
904}
905
906impl Div<f32> for &Mat2 {
907 type Output = Mat2;
908 #[inline]
909 fn div(self, rhs: f32) -> Mat2 {
910 (*self).div(rhs)
911 }
912}
913
914impl DivAssign<f32> for Mat2 {
915 #[inline]
916 fn div_assign(&mut self, rhs: f32) {
917 *self = self.div(rhs);
918 }
919}
920
921impl DivAssign<&f32> for Mat2 {
922 #[inline]
923 fn div_assign(&mut self, rhs: &f32) {
924 self.div_assign(*rhs);
925 }
926}
927
928impl Sum<Self> for Mat2 {
929 fn sum<I>(iter: I) -> Self
930 where
931 I: Iterator<Item = Self>,
932 {
933 iter.fold(Self::ZERO, Self::add)
934 }
935}
936
937impl<'a> Sum<&'a Self> for Mat2 {
938 fn sum<I>(iter: I) -> Self
939 where
940 I: Iterator<Item = &'a Self>,
941 {
942 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
943 }
944}
945
946impl Product for Mat2 {
947 fn product<I>(iter: I) -> Self
948 where
949 I: Iterator<Item = Self>,
950 {
951 iter.fold(Self::IDENTITY, Self::mul)
952 }
953}
954
955impl<'a> Product<&'a Self> for Mat2 {
956 fn product<I>(iter: I) -> Self
957 where
958 I: Iterator<Item = &'a Self>,
959 {
960 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
961 }
962}
963
964impl PartialEq for Mat2 {
965 #[inline]
966 fn eq(&self, rhs: &Self) -> bool {
967 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis)
968 }
969}
970
971impl AsRef<[f32; 4]> for Mat2 {
972 #[inline]
973 fn as_ref(&self) -> &[f32; 4] {
974 unsafe { &*(self as *const Self as *const [f32; 4]) }
975 }
976}
977
978impl AsMut<[f32; 4]> for Mat2 {
979 #[inline]
980 fn as_mut(&mut self) -> &mut [f32; 4] {
981 unsafe { &mut *(self as *mut Self as *mut [f32; 4]) }
982 }
983}
984
985impl core::ops::Deref for Mat2 {
986 type Target = crate::deref::Cols2<Vec2>;
987 #[inline]
988 fn deref(&self) -> &Self::Target {
989 unsafe { &*(self as *const Self as *const Self::Target) }
990 }
991}
992
993impl core::ops::DerefMut for Mat2 {
994 #[inline]
995 fn deref_mut(&mut self) -> &mut Self::Target {
996 unsafe { &mut *(self as *mut Self as *mut Self::Target) }
997 }
998}
999
1000impl fmt::Debug for Mat2 {
1001 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1002 fmt.debug_struct(stringify!(Mat2))
1003 .field("x_axis", &self.x_axis)
1004 .field("y_axis", &self.y_axis)
1005 .finish()
1006 }
1007}
1008
1009impl fmt::Display for Mat2 {
1010 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1011 if let Some(p) = f.precision() {
1012 write!(f, "[{:.*}, {:.*}]", p, self.x_axis, p, self.y_axis)
1013 } else {
1014 write!(f, "[{}, {}]", self.x_axis, self.y_axis)
1015 }
1016 }
1017}