1#[cfg(feature = "f64")]
4use crate::DMat2;
5
6use crate::{Mat3, Mat3A, Vec2, f32::math, swizzles::*};
7use core::fmt;
8use core::iter::{Product, Sum};
9use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
10
11use core::arch::aarch64::*;
12
13#[cfg(feature = "zerocopy-08")]
14use zerocopy_derive_08::*;
15
16#[repr(C)]
17union UnionCast {
18 a: [f32; 4],
19 v: Mat2,
20}
21
22#[inline(always)]
24#[must_use]
25pub const fn mat2(x_axis: Vec2, y_axis: Vec2) -> Mat2 {
26 Mat2::from_cols(x_axis, y_axis)
27}
28
29#[derive(Clone, Copy)]
35#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
36#[cfg_attr(
37 feature = "zerocopy-08",
38 derive(FromBytes, Immutable, IntoBytes, KnownLayout)
39)]
40#[repr(transparent)]
41pub struct Mat2(pub(crate) float32x4_t);
42
43impl Mat2 {
44 pub const ZERO: Self = Self::from_cols(Vec2::ZERO, Vec2::ZERO);
46
47 pub const IDENTITY: Self = Self::from_cols(Vec2::X, Vec2::Y);
49
50 pub const NAN: Self = Self::from_cols(Vec2::NAN, Vec2::NAN);
52
53 #[allow(clippy::too_many_arguments)]
54 #[inline(always)]
55 #[must_use]
56 const fn new(m00: f32, m01: f32, m10: f32, m11: f32) -> Self {
57 unsafe {
58 UnionCast {
59 a: [m00, m01, m10, m11],
60 }
61 .v
62 }
63 }
64
65 #[inline(always)]
69 #[must_use]
70 pub const fn from_cols(x_axis: Vec2, y_axis: Vec2) -> Self {
71 unsafe {
72 UnionCast {
73 a: [x_axis.x, x_axis.y, y_axis.x, y_axis.y],
74 }
75 .v
76 }
77 }
78
79 #[inline(always)]
85 #[must_use]
86 pub const fn from_rows(row0: Vec2, row1: Vec2) -> Self {
87 let [m00, m01] = row0.to_array();
88 let [m10, m11] = row1.to_array();
89 Self::new(m00, m10, m01, m11)
90 }
91
92 #[inline]
96 #[must_use]
97 pub const fn from_cols_array(m: &[f32; 4]) -> Self {
98 Self::new(m[0], m[1], m[2], m[3])
99 }
100
101 #[inline]
105 #[must_use]
106 pub const fn to_cols_array(&self) -> [f32; 4] {
107 unsafe { *(self as *const Self as *const [f32; 4]) }
108 }
109
110 #[inline]
114 #[must_use]
115 pub const fn from_cols_array_2d(m: &[[f32; 2]; 2]) -> Self {
116 Self::from_cols(Vec2::from_array(m[0]), Vec2::from_array(m[1]))
117 }
118
119 #[inline]
123 #[must_use]
124 pub const fn to_cols_array_2d(&self) -> [[f32; 2]; 2] {
125 unsafe { *(self as *const Self as *const [[f32; 2]; 2]) }
126 }
127
128 #[inline]
134 #[must_use]
135 pub const fn from_rows_array(m: &[f32; 4]) -> Self {
136 Self::new(m[0], m[2], m[1], m[3])
137 }
138
139 #[inline]
145 #[must_use]
146 pub const fn to_rows_array(&self) -> [f32; 4] {
147 let m = self.to_cols_array();
148 [m[0], m[2], m[1], m[3]]
149 }
150
151 #[doc(alias = "scale")]
153 #[inline]
154 #[must_use]
155 pub const fn from_diagonal(diagonal: Vec2) -> Self {
156 Self::new(diagonal.x, 0.0, 0.0, diagonal.y)
157 }
158
159 #[inline]
162 #[must_use]
163 pub fn from_scale_angle(scale: Vec2, angle: f32) -> Self {
164 let (sin, cos) = math::sin_cos(angle);
165 Self::new(cos * scale.x, sin * scale.x, -sin * scale.y, cos * scale.y)
166 }
167
168 #[inline]
170 #[must_use]
171 pub fn from_angle(angle: f32) -> Self {
172 let (sin, cos) = math::sin_cos(angle);
173 Self::new(cos, sin, -sin, cos)
174 }
175
176 #[inline]
178 #[must_use]
179 pub fn from_mat3(m: Mat3) -> Self {
180 Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
181 }
182
183 #[inline]
190 #[must_use]
191 #[track_caller]
192 pub fn from_mat3_minor(m: Mat3, i: usize, j: usize) -> Self {
193 match (i, j) {
194 (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
195 (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
196 (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
197 (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
198 (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
199 (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
200 (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
201 (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
202 (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
203 _ => panic!("index out of bounds"),
204 }
205 }
206
207 #[inline]
209 #[must_use]
210 pub fn from_mat3a(m: Mat3A) -> Self {
211 Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
212 }
213
214 #[inline]
221 #[must_use]
222 #[track_caller]
223 pub fn from_mat3a_minor(m: Mat3A, i: usize, j: usize) -> Self {
224 match (i, j) {
225 (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
226 (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
227 (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
228 (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
229 (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
230 (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
231 (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
232 (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
233 (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
234 _ => panic!("index out of bounds"),
235 }
236 }
237
238 #[inline]
246 #[must_use]
247 #[track_caller]
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 #[track_caller]
259 pub fn write_cols_to_slice(&self, slice: &mut [f32]) {
260 slice[0] = self.x_axis.x;
261 slice[1] = self.x_axis.y;
262 slice[2] = self.y_axis.x;
263 slice[3] = self.y_axis.y;
264 }
265
266 #[inline]
277 #[must_use]
278 #[track_caller]
279 pub const fn from_rows_slice(slice: &[f32]) -> Self {
280 Self::new(slice[0], slice[2], slice[1], slice[3])
281 }
282
283 #[inline]
289 #[must_use]
290 #[track_caller]
291 pub fn col(&self, index: usize) -> Vec2 {
292 match index {
293 0 => self.x_axis,
294 1 => self.y_axis,
295 _ => panic!("index out of bounds"),
296 }
297 }
298
299 #[inline]
305 #[track_caller]
306 pub fn col_mut(&mut self, index: usize) -> &mut Vec2 {
307 match index {
308 0 => &mut self.x_axis,
309 1 => &mut self.y_axis,
310 _ => panic!("index out of bounds"),
311 }
312 }
313
314 #[inline]
322 #[must_use]
323 #[track_caller]
324 pub fn row(&self, index: usize) -> Vec2 {
325 match index {
326 0 => Vec2::new(self.x_axis.x, self.y_axis.x),
327 1 => Vec2::new(self.x_axis.y, self.y_axis.y),
328 _ => panic!("index out of bounds"),
329 }
330 }
331
332 #[inline]
342 #[track_caller]
343 pub fn set_row(&mut self, index: usize, row: Vec2) {
344 match index {
345 0 => {
346 self.x_axis.x = row.x;
347 self.y_axis.x = row.y;
348 }
349 1 => {
350 self.x_axis.y = row.x;
351 self.y_axis.y = row.y;
352 }
353 _ => panic!("index out of bounds"),
354 }
355 }
356
357 #[inline]
360 #[must_use]
361 pub fn is_finite(&self) -> bool {
362 self.x_axis.is_finite() && self.y_axis.is_finite()
363 }
364
365 #[inline]
367 #[must_use]
368 pub fn is_nan(&self) -> bool {
369 self.x_axis.is_nan() || self.y_axis.is_nan()
370 }
371
372 #[inline]
374 #[must_use]
375 pub fn transpose(&self) -> Self {
376 Self(unsafe {
377 vsetq_lane_f32(
378 vgetq_lane_f32(self.0, 2),
379 vsetq_lane_f32(vgetq_lane_f32(self.0, 1), self.0, 2),
380 1,
381 )
382 })
383 }
384
385 #[inline]
387 #[must_use]
388 pub fn diagonal(&self) -> Vec2 {
389 Vec2::new(self.x_axis.x, self.y_axis.y)
390 }
391
392 #[inline]
394 #[must_use]
395 pub fn determinant(&self) -> f32 {
396 self.x_axis.x * self.y_axis.y - self.x_axis.y * self.y_axis.x
397 }
398
399 #[inline(always)]
411 #[must_use]
412 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
413 fn inverse_checked<const CHECKED: bool>(&self) -> (Self, bool) {
414 unsafe {
415 const SIGN: float32x4_t = crate::neon::f32x4_from_array([1.0, -1.0, -1.0, 1.0]);
416 let abcd = self.0;
417 let ab = vget_low_f32(abcd);
418 let cd = vget_high_f32(abcd);
419 let ad = vmul_lane_f32(ab, cd, 1);
420 let bc = vmul_lane_f32(cd, ab, 1);
421 let det = vget_lane_f32(vsub_f32(ad, bc), 0);
422 let tmp = vmulq_n_f32(SIGN, 1.0f32 / det);
423 let dbca = vsetq_lane_f32(
424 vgetq_lane_f32(abcd, 0),
425 vsetq_lane_f32(vgetq_lane_f32(abcd, 3), abcd, 0),
426 3,
427 );
428 let m = Self(vmulq_f32(dbca, tmp));
429 if CHECKED {
430 if !m.is_finite() {
431 return (Self::ZERO, false);
432 }
433 } else {
434 glam_assert!(m.is_finite());
435 }
436 (m, true)
437 }
438 }
439
440 #[inline]
452 #[must_use]
453 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
454 pub fn inverse(&self) -> Self {
455 self.inverse_checked::<false>().0
456 }
457
458 #[inline]
461 #[must_use]
462 pub fn try_inverse(&self) -> Option<Self> {
463 let (m, is_valid) = self.inverse_checked::<true>();
464 if is_valid { Some(m) } else { None }
465 }
466
467 #[inline]
470 #[must_use]
471 pub fn inverse_or_zero(&self) -> Self {
472 self.inverse_checked::<true>().0
473 }
474
475 #[inline]
477 #[must_use]
478 pub fn mul_vec2(&self, rhs: Vec2) -> Vec2 {
479 unsafe {
480 let abcd = self.0;
481 let xxyy = vld1q_f32([rhs.x, rhs.x, rhs.y, rhs.y].as_ptr());
482 let axbxcydy = vmulq_f32(abcd, xxyy);
483 let cydyaxbx = vextq_f32(axbxcydy, axbxcydy, 2);
485 let result = vaddq_f32(axbxcydy, cydyaxbx);
486 *(&result as *const float32x4_t as *const Vec2)
487 }
488 }
489
490 #[inline]
492 #[must_use]
493 pub fn mul_transpose_vec2(&self, rhs: Vec2) -> Vec2 {
494 Vec2::new(self.x_axis.dot(rhs), self.y_axis.dot(rhs))
495 }
496
497 #[inline]
499 #[must_use]
500 pub fn mul_mat2(&self, rhs: &Self) -> Self {
501 self.mul(rhs)
502 }
503
504 #[inline]
506 #[must_use]
507 pub fn add_mat2(&self, rhs: &Self) -> Self {
508 self.add(rhs)
509 }
510
511 #[inline]
513 #[must_use]
514 pub fn sub_mat2(&self, rhs: &Self) -> Self {
515 self.sub(rhs)
516 }
517
518 #[inline]
520 #[must_use]
521 pub fn mul_scalar(&self, rhs: f32) -> Self {
522 Self(unsafe { vmulq_f32(self.0, vld1q_dup_f32(&rhs)) })
523 }
524
525 #[inline]
529 #[must_use]
530 pub fn mul_diagonal_scale(&self, scale: Vec2) -> Self {
531 Self::from_cols(self.x_axis * scale.x, self.y_axis * scale.y)
532 }
533
534 #[inline]
536 #[must_use]
537 pub fn div_scalar(&self, rhs: f32) -> Self {
538 Self(unsafe { vdivq_f32(self.0, vld1q_dup_f32(&rhs)) })
539 }
540
541 #[inline]
543 #[must_use]
544 pub fn recip(&self) -> Self {
545 Self::from_cols(self.x_axis.recip(), self.y_axis.recip())
546 }
547
548 #[inline]
558 #[must_use]
559 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
560 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
561 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
562 }
563
564 #[inline]
566 #[must_use]
567 pub fn abs(&self) -> Self {
568 Self::from_cols(self.x_axis.abs(), self.y_axis.abs())
569 }
570
571 #[cfg(feature = "f64")]
572 #[inline]
573 #[must_use]
574 pub fn as_dmat2(&self) -> DMat2 {
575 DMat2::from_cols(self.x_axis.as_dvec2(), self.y_axis.as_dvec2())
576 }
577}
578
579impl Default for Mat2 {
580 #[inline]
581 fn default() -> Self {
582 Self::IDENTITY
583 }
584}
585
586impl Add for Mat2 {
587 type Output = Self;
588 #[inline]
589 fn add(self, rhs: Self) -> Self {
590 Self(unsafe { vaddq_f32(self.0, rhs.0) })
591 }
592}
593
594impl Add<&Self> for Mat2 {
595 type Output = Self;
596 #[inline]
597 fn add(self, rhs: &Self) -> Self {
598 self.add(*rhs)
599 }
600}
601
602impl Add<&Mat2> for &Mat2 {
603 type Output = Mat2;
604 #[inline]
605 fn add(self, rhs: &Mat2) -> Mat2 {
606 (*self).add(*rhs)
607 }
608}
609
610impl Add<Mat2> for &Mat2 {
611 type Output = Mat2;
612 #[inline]
613 fn add(self, rhs: Mat2) -> Mat2 {
614 (*self).add(rhs)
615 }
616}
617
618impl AddAssign for Mat2 {
619 #[inline]
620 fn add_assign(&mut self, rhs: Self) {
621 *self = self.add(rhs);
622 }
623}
624
625impl AddAssign<&Self> for Mat2 {
626 #[inline]
627 fn add_assign(&mut self, rhs: &Self) {
628 self.add_assign(*rhs);
629 }
630}
631
632impl Sub for Mat2 {
633 type Output = Self;
634 #[inline]
635 fn sub(self, rhs: Self) -> Self {
636 Self(unsafe { vsubq_f32(self.0, rhs.0) })
637 }
638}
639
640impl Sub<&Self> for Mat2 {
641 type Output = Self;
642 #[inline]
643 fn sub(self, rhs: &Self) -> Self {
644 self.sub(*rhs)
645 }
646}
647
648impl Sub<&Mat2> for &Mat2 {
649 type Output = Mat2;
650 #[inline]
651 fn sub(self, rhs: &Mat2) -> Mat2 {
652 (*self).sub(*rhs)
653 }
654}
655
656impl Sub<Mat2> for &Mat2 {
657 type Output = Mat2;
658 #[inline]
659 fn sub(self, rhs: Mat2) -> Mat2 {
660 (*self).sub(rhs)
661 }
662}
663
664impl SubAssign for Mat2 {
665 #[inline]
666 fn sub_assign(&mut self, rhs: Self) {
667 *self = self.sub(rhs);
668 }
669}
670
671impl SubAssign<&Self> for Mat2 {
672 #[inline]
673 fn sub_assign(&mut self, rhs: &Self) {
674 self.sub_assign(*rhs);
675 }
676}
677
678impl Neg for Mat2 {
679 type Output = Self;
680 #[inline]
681 fn neg(self) -> Self::Output {
682 Self(unsafe { vnegq_f32(self.0) })
683 }
684}
685
686impl Neg for &Mat2 {
687 type Output = Mat2;
688 #[inline]
689 fn neg(self) -> Mat2 {
690 (*self).neg()
691 }
692}
693
694impl Mul for Mat2 {
695 type Output = Self;
696 #[inline]
697 fn mul(self, rhs: Self) -> Self {
698 unsafe {
699 let abcd = self.0;
700 let xxyy0 = vzip1q_f32(rhs.0, rhs.0);
701 let xxyy1 = vzip2q_f32(rhs.0, rhs.0);
702 let axbxcydy0 = vmulq_f32(abcd, xxyy0);
703 let axbxcydy1 = vmulq_f32(abcd, xxyy1);
704 let cydyaxbx0 = vextq_f32(axbxcydy0, axbxcydy0, 2);
705 let cydyaxbx1 = vextq_f32(axbxcydy1, axbxcydy1, 2);
706 let result0 = vaddq_f32(axbxcydy0, cydyaxbx0);
707 let result1 = vaddq_f32(axbxcydy1, cydyaxbx1);
708 Self(vreinterpretq_f32_u64(vsetq_lane_u64(
709 vgetq_lane_u64(vreinterpretq_u64_f32(result1), 0),
710 vreinterpretq_u64_f32(result0),
711 1,
712 )))
713 }
714 }
715}
716
717impl Mul<&Self> for Mat2 {
718 type Output = Self;
719 #[inline]
720 fn mul(self, rhs: &Self) -> Self {
721 self.mul(*rhs)
722 }
723}
724
725impl Mul<&Mat2> for &Mat2 {
726 type Output = Mat2;
727 #[inline]
728 fn mul(self, rhs: &Mat2) -> Mat2 {
729 (*self).mul(*rhs)
730 }
731}
732
733impl Mul<Mat2> for &Mat2 {
734 type Output = Mat2;
735 #[inline]
736 fn mul(self, rhs: Mat2) -> Mat2 {
737 (*self).mul(rhs)
738 }
739}
740
741impl MulAssign for Mat2 {
742 #[inline]
743 fn mul_assign(&mut self, rhs: Self) {
744 *self = self.mul(rhs);
745 }
746}
747
748impl MulAssign<&Self> for Mat2 {
749 #[inline]
750 fn mul_assign(&mut self, rhs: &Self) {
751 self.mul_assign(*rhs);
752 }
753}
754
755impl Mul<Vec2> for Mat2 {
756 type Output = Vec2;
757 #[inline]
758 fn mul(self, rhs: Vec2) -> Self::Output {
759 self.mul_vec2(rhs)
760 }
761}
762
763impl Mul<&Vec2> for Mat2 {
764 type Output = Vec2;
765 #[inline]
766 fn mul(self, rhs: &Vec2) -> Vec2 {
767 self.mul(*rhs)
768 }
769}
770
771impl Mul<&Vec2> for &Mat2 {
772 type Output = Vec2;
773 #[inline]
774 fn mul(self, rhs: &Vec2) -> Vec2 {
775 (*self).mul(*rhs)
776 }
777}
778
779impl Mul<Vec2> for &Mat2 {
780 type Output = Vec2;
781 #[inline]
782 fn mul(self, rhs: Vec2) -> Vec2 {
783 (*self).mul(rhs)
784 }
785}
786
787impl Mul<Mat2> for f32 {
788 type Output = Mat2;
789 #[inline]
790 fn mul(self, rhs: Mat2) -> Self::Output {
791 rhs.mul_scalar(self)
792 }
793}
794
795impl Mul<&Mat2> for f32 {
796 type Output = Mat2;
797 #[inline]
798 fn mul(self, rhs: &Mat2) -> Mat2 {
799 self.mul(*rhs)
800 }
801}
802
803impl Mul<&Mat2> for &f32 {
804 type Output = Mat2;
805 #[inline]
806 fn mul(self, rhs: &Mat2) -> Mat2 {
807 (*self).mul(*rhs)
808 }
809}
810
811impl Mul<Mat2> for &f32 {
812 type Output = Mat2;
813 #[inline]
814 fn mul(self, rhs: Mat2) -> Mat2 {
815 (*self).mul(rhs)
816 }
817}
818
819impl Mul<f32> for Mat2 {
820 type Output = Self;
821 #[inline]
822 fn mul(self, rhs: f32) -> Self {
823 self.mul_scalar(rhs)
824 }
825}
826
827impl Mul<&f32> for Mat2 {
828 type Output = Self;
829 #[inline]
830 fn mul(self, rhs: &f32) -> Self {
831 self.mul(*rhs)
832 }
833}
834
835impl Mul<&f32> for &Mat2 {
836 type Output = Mat2;
837 #[inline]
838 fn mul(self, rhs: &f32) -> Mat2 {
839 (*self).mul(*rhs)
840 }
841}
842
843impl Mul<f32> for &Mat2 {
844 type Output = Mat2;
845 #[inline]
846 fn mul(self, rhs: f32) -> Mat2 {
847 (*self).mul(rhs)
848 }
849}
850
851impl MulAssign<f32> for Mat2 {
852 #[inline]
853 fn mul_assign(&mut self, rhs: f32) {
854 *self = self.mul(rhs);
855 }
856}
857
858impl MulAssign<&f32> for Mat2 {
859 #[inline]
860 fn mul_assign(&mut self, rhs: &f32) {
861 self.mul_assign(*rhs);
862 }
863}
864
865impl Div<Mat2> for f32 {
866 type Output = Mat2;
867 #[inline]
868 fn div(self, rhs: Mat2) -> Self::Output {
869 Mat2(unsafe { vdivq_f32(vld1q_dup_f32(&self), rhs.0) })
870 }
871}
872
873impl Div<&Mat2> for f32 {
874 type Output = Mat2;
875 #[inline]
876 fn div(self, rhs: &Mat2) -> Mat2 {
877 self.div(*rhs)
878 }
879}
880
881impl Div<&Mat2> for &f32 {
882 type Output = Mat2;
883 #[inline]
884 fn div(self, rhs: &Mat2) -> Mat2 {
885 (*self).div(*rhs)
886 }
887}
888
889impl Div<Mat2> for &f32 {
890 type Output = Mat2;
891 #[inline]
892 fn div(self, rhs: Mat2) -> Mat2 {
893 (*self).div(rhs)
894 }
895}
896
897impl Div<f32> for Mat2 {
898 type Output = Self;
899 #[inline]
900 fn div(self, rhs: f32) -> Self {
901 self.div_scalar(rhs)
902 }
903}
904
905impl Div<&f32> for Mat2 {
906 type Output = Self;
907 #[inline]
908 fn div(self, rhs: &f32) -> Self {
909 self.div(*rhs)
910 }
911}
912
913impl Div<&f32> for &Mat2 {
914 type Output = Mat2;
915 #[inline]
916 fn div(self, rhs: &f32) -> Mat2 {
917 (*self).div(*rhs)
918 }
919}
920
921impl Div<f32> for &Mat2 {
922 type Output = Mat2;
923 #[inline]
924 fn div(self, rhs: f32) -> Mat2 {
925 (*self).div(rhs)
926 }
927}
928
929impl DivAssign<f32> for Mat2 {
930 #[inline]
931 fn div_assign(&mut self, rhs: f32) {
932 *self = self.div(rhs);
933 }
934}
935
936impl DivAssign<&f32> for Mat2 {
937 #[inline]
938 fn div_assign(&mut self, rhs: &f32) {
939 self.div_assign(*rhs);
940 }
941}
942
943impl Sum<Self> for Mat2 {
944 fn sum<I>(iter: I) -> Self
945 where
946 I: Iterator<Item = Self>,
947 {
948 iter.fold(Self::ZERO, Self::add)
949 }
950}
951
952impl<'a> Sum<&'a Self> for Mat2 {
953 fn sum<I>(iter: I) -> Self
954 where
955 I: Iterator<Item = &'a Self>,
956 {
957 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
958 }
959}
960
961impl Product for Mat2 {
962 fn product<I>(iter: I) -> Self
963 where
964 I: Iterator<Item = Self>,
965 {
966 iter.fold(Self::IDENTITY, Self::mul)
967 }
968}
969
970impl<'a> Product<&'a Self> for Mat2 {
971 fn product<I>(iter: I) -> Self
972 where
973 I: Iterator<Item = &'a Self>,
974 {
975 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
976 }
977}
978
979impl PartialEq for Mat2 {
980 #[inline]
981 fn eq(&self, rhs: &Self) -> bool {
982 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis)
983 }
984}
985
986impl AsRef<[f32; 4]> for Mat2 {
987 #[inline]
988 fn as_ref(&self) -> &[f32; 4] {
989 unsafe { &*(self as *const Self as *const [f32; 4]) }
990 }
991}
992
993impl AsMut<[f32; 4]> for Mat2 {
994 #[inline]
995 fn as_mut(&mut self) -> &mut [f32; 4] {
996 unsafe { &mut *(self as *mut Self as *mut [f32; 4]) }
997 }
998}
999
1000impl core::ops::Deref for Mat2 {
1001 type Target = crate::deref::Cols2<Vec2>;
1002 #[inline]
1003 fn deref(&self) -> &Self::Target {
1004 unsafe { &*(self as *const Self as *const Self::Target) }
1005 }
1006}
1007
1008impl core::ops::DerefMut for Mat2 {
1009 #[inline]
1010 fn deref_mut(&mut self) -> &mut Self::Target {
1011 unsafe { &mut *(self as *mut Self as *mut Self::Target) }
1012 }
1013}
1014
1015impl fmt::Debug for Mat2 {
1016 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1017 fmt.debug_struct(stringify!(Mat2))
1018 .field("x_axis", &self.x_axis)
1019 .field("y_axis", &self.y_axis)
1020 .finish()
1021 }
1022}
1023
1024impl fmt::Display for Mat2 {
1025 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1026 if let Some(p) = f.precision() {
1027 write!(f, "[{:.*}, {:.*}]", p, self.x_axis, p, self.y_axis)
1028 } else {
1029 write!(f, "[{}, {}]", self.x_axis, self.y_axis)
1030 }
1031 }
1032}