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
11use core::arch::aarch64::*;
12
13#[cfg(feature = "zerocopy")]
14use zerocopy_derive::*;
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",
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)]
67 #[must_use]
68 pub const fn from_cols(x_axis: Vec2, y_axis: Vec2) -> Self {
69 unsafe {
70 UnionCast {
71 a: [x_axis.x, x_axis.y, y_axis.x, y_axis.y],
72 }
73 .v
74 }
75 }
76
77 #[inline]
81 #[must_use]
82 pub const fn from_cols_array(m: &[f32; 4]) -> Self {
83 Self::new(m[0], m[1], m[2], m[3])
84 }
85
86 #[inline]
89 #[must_use]
90 pub const fn to_cols_array(&self) -> [f32; 4] {
91 unsafe { *(self as *const Self as *const [f32; 4]) }
92 }
93
94 #[inline]
98 #[must_use]
99 pub const fn from_cols_array_2d(m: &[[f32; 2]; 2]) -> Self {
100 Self::from_cols(Vec2::from_array(m[0]), Vec2::from_array(m[1]))
101 }
102
103 #[inline]
106 #[must_use]
107 pub const fn to_cols_array_2d(&self) -> [[f32; 2]; 2] {
108 unsafe { *(self as *const Self as *const [[f32; 2]; 2]) }
109 }
110
111 #[doc(alias = "scale")]
113 #[inline]
114 #[must_use]
115 pub const fn from_diagonal(diagonal: Vec2) -> Self {
116 Self::new(diagonal.x, 0.0, 0.0, diagonal.y)
117 }
118
119 #[inline]
122 #[must_use]
123 pub fn from_scale_angle(scale: Vec2, angle: f32) -> Self {
124 let (sin, cos) = math::sin_cos(angle);
125 Self::new(cos * scale.x, sin * scale.x, -sin * scale.y, cos * scale.y)
126 }
127
128 #[inline]
130 #[must_use]
131 pub fn from_angle(angle: f32) -> Self {
132 let (sin, cos) = math::sin_cos(angle);
133 Self::new(cos, sin, -sin, cos)
134 }
135
136 #[inline]
138 #[must_use]
139 pub fn from_mat3(m: Mat3) -> Self {
140 Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
141 }
142
143 #[inline]
150 #[must_use]
151 pub fn from_mat3_minor(m: Mat3, i: usize, j: usize) -> Self {
152 match (i, j) {
153 (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
154 (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
155 (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
156 (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
157 (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
158 (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
159 (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
160 (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
161 (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
162 _ => panic!("index out of bounds"),
163 }
164 }
165
166 #[inline]
168 #[must_use]
169 pub fn from_mat3a(m: Mat3A) -> Self {
170 Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
171 }
172
173 #[inline]
180 #[must_use]
181 pub fn from_mat3a_minor(m: Mat3A, i: usize, j: usize) -> Self {
182 match (i, j) {
183 (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
184 (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
185 (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
186 (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
187 (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
188 (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
189 (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
190 (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
191 (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
192 _ => panic!("index out of bounds"),
193 }
194 }
195
196 #[inline]
202 #[must_use]
203 pub const fn from_cols_slice(slice: &[f32]) -> Self {
204 Self::new(slice[0], slice[1], slice[2], slice[3])
205 }
206
207 #[inline]
213 pub fn write_cols_to_slice(&self, slice: &mut [f32]) {
214 slice[0] = self.x_axis.x;
215 slice[1] = self.x_axis.y;
216 slice[2] = self.y_axis.x;
217 slice[3] = self.y_axis.y;
218 }
219
220 #[inline]
226 #[must_use]
227 pub fn col(&self, index: usize) -> Vec2 {
228 match index {
229 0 => self.x_axis,
230 1 => self.y_axis,
231 _ => panic!("index out of bounds"),
232 }
233 }
234
235 #[inline]
241 pub fn col_mut(&mut self, index: usize) -> &mut Vec2 {
242 match index {
243 0 => &mut self.x_axis,
244 1 => &mut self.y_axis,
245 _ => panic!("index out of bounds"),
246 }
247 }
248
249 #[inline]
255 #[must_use]
256 pub fn row(&self, index: usize) -> Vec2 {
257 match index {
258 0 => Vec2::new(self.x_axis.x, self.y_axis.x),
259 1 => Vec2::new(self.x_axis.y, self.y_axis.y),
260 _ => panic!("index out of bounds"),
261 }
262 }
263
264 #[inline]
267 #[must_use]
268 pub fn is_finite(&self) -> bool {
269 self.x_axis.is_finite() && self.y_axis.is_finite()
270 }
271
272 #[inline]
274 #[must_use]
275 pub fn is_nan(&self) -> bool {
276 self.x_axis.is_nan() || self.y_axis.is_nan()
277 }
278
279 #[inline]
281 #[must_use]
282 pub fn transpose(&self) -> Self {
283 Self(unsafe {
284 vsetq_lane_f32(
285 vgetq_lane_f32(self.0, 2),
286 vsetq_lane_f32(vgetq_lane_f32(self.0, 1), self.0, 2),
287 1,
288 )
289 })
290 }
291
292 #[inline]
294 #[must_use]
295 pub fn diagonal(&self) -> Vec2 {
296 Vec2::new(self.x_axis.x, self.y_axis.y)
297 }
298
299 #[inline]
301 #[must_use]
302 pub fn determinant(&self) -> f32 {
303 unsafe {
304 let abcd = self.0;
305 let badc = vrev64q_f32(abcd);
306 let dcba = vextq_f32(badc, badc, 2);
307 let prod = vmulq_f32(abcd, dcba);
308 let det = vsubq_f32(prod, vdupq_laneq_f32(prod, 1));
309 vgetq_lane_f32(det, 0)
310 }
311 }
312
313 #[inline(always)]
325 #[must_use]
326 fn inverse_checked<const CHECKED: bool>(&self) -> (Self, bool) {
327 unsafe {
328 use crate::Vec4;
329 const SIGN: float32x4_t = crate::neon::f32x4_from_array([1.0, -1.0, -1.0, 1.0]);
330 let abcd = self.0;
331 let badc = vrev64q_f32(abcd);
332 let dcba = vextq_f32(badc, badc, 2);
333 let prod = vmulq_f32(abcd, dcba);
334 let sub = vsubq_f32(prod, vdupq_laneq_f32(prod, 1));
335 let det = vdupq_laneq_f32(sub, 0);
336 if CHECKED {
337 if Vec4(det) == Vec4::ZERO {
338 return (Self::ZERO, false);
339 }
340 } else {
341 glam_assert!(Vec4(det).cmpne(Vec4::ZERO).all());
342 }
343 let tmp = vdivq_f32(SIGN, det);
344 let dbca = vsetq_lane_f32(
345 vgetq_lane_f32(abcd, 0),
346 vsetq_lane_f32(vgetq_lane_f32(abcd, 3), abcd, 0),
347 3,
348 );
349 (Self(vmulq_f32(dbca, tmp)), true)
350 }
351 }
352
353 #[inline]
361 #[must_use]
362 pub fn inverse(&self) -> Self {
363 self.inverse_checked::<false>().0
364 }
365
366 #[inline]
368 #[must_use]
369 pub fn try_inverse(&self) -> Option<Self> {
370 let (m, is_valid) = self.inverse_checked::<true>();
371 if is_valid {
372 Some(m)
373 } else {
374 None
375 }
376 }
377
378 #[inline]
380 #[must_use]
381 pub fn inverse_or_zero(&self) -> Self {
382 self.inverse_checked::<true>().0
383 }
384
385 #[inline]
387 #[must_use]
388 pub fn mul_vec2(&self, rhs: Vec2) -> Vec2 {
389 unsafe {
390 let abcd = self.0;
391 let xxyy = vld1q_f32([rhs.x, rhs.x, rhs.y, rhs.y].as_ptr());
392 let axbxcydy = vmulq_f32(abcd, xxyy);
393 let cydyaxbx = vextq_f32(axbxcydy, axbxcydy, 2);
395 let result = vaddq_f32(axbxcydy, cydyaxbx);
396 *(&result as *const float32x4_t as *const Vec2)
397 }
398 }
399
400 #[inline]
402 #[must_use]
403 pub fn mul_transpose_vec2(&self, rhs: Vec2) -> Vec2 {
404 Vec2::new(self.x_axis.dot(rhs), self.y_axis.dot(rhs))
405 }
406
407 #[inline]
409 #[must_use]
410 pub fn mul_mat2(&self, rhs: &Self) -> Self {
411 self.mul(rhs)
412 }
413
414 #[inline]
416 #[must_use]
417 pub fn add_mat2(&self, rhs: &Self) -> Self {
418 self.add(rhs)
419 }
420
421 #[inline]
423 #[must_use]
424 pub fn sub_mat2(&self, rhs: &Self) -> Self {
425 self.sub(rhs)
426 }
427
428 #[inline]
430 #[must_use]
431 pub fn mul_scalar(&self, rhs: f32) -> Self {
432 Self(unsafe { vmulq_f32(self.0, vld1q_dup_f32(&rhs)) })
433 }
434
435 #[inline]
439 #[must_use]
440 pub fn mul_diagonal_scale(&self, scale: Vec2) -> Self {
441 Self::from_cols(self.x_axis * scale.x, self.y_axis * scale.y)
442 }
443
444 #[inline]
446 #[must_use]
447 pub fn div_scalar(&self, rhs: f32) -> Self {
448 Self(unsafe { vdivq_f32(self.0, vld1q_dup_f32(&rhs)) })
449 }
450
451 #[inline]
453 #[must_use]
454 pub fn recip(&self) -> Self {
455 Self::from_cols(self.x_axis.recip(), self.y_axis.recip())
456 }
457
458 #[inline]
468 #[must_use]
469 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
470 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
471 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
472 }
473
474 #[inline]
476 #[must_use]
477 pub fn abs(&self) -> Self {
478 Self::from_cols(self.x_axis.abs(), self.y_axis.abs())
479 }
480
481 #[cfg(feature = "f64")]
482 #[inline]
483 #[must_use]
484 pub fn as_dmat2(&self) -> DMat2 {
485 DMat2::from_cols(self.x_axis.as_dvec2(), self.y_axis.as_dvec2())
486 }
487}
488
489impl Default for Mat2 {
490 #[inline]
491 fn default() -> Self {
492 Self::IDENTITY
493 }
494}
495
496impl Add for Mat2 {
497 type Output = Self;
498 #[inline]
499 fn add(self, rhs: Self) -> Self {
500 Self(unsafe { vaddq_f32(self.0, rhs.0) })
501 }
502}
503
504impl Add<&Self> for Mat2 {
505 type Output = Self;
506 #[inline]
507 fn add(self, rhs: &Self) -> Self {
508 self.add(*rhs)
509 }
510}
511
512impl Add<&Mat2> for &Mat2 {
513 type Output = Mat2;
514 #[inline]
515 fn add(self, rhs: &Mat2) -> Mat2 {
516 (*self).add(*rhs)
517 }
518}
519
520impl Add<Mat2> for &Mat2 {
521 type Output = Mat2;
522 #[inline]
523 fn add(self, rhs: Mat2) -> Mat2 {
524 (*self).add(rhs)
525 }
526}
527
528impl AddAssign for Mat2 {
529 #[inline]
530 fn add_assign(&mut self, rhs: Self) {
531 *self = self.add(rhs);
532 }
533}
534
535impl AddAssign<&Self> for Mat2 {
536 #[inline]
537 fn add_assign(&mut self, rhs: &Self) {
538 self.add_assign(*rhs);
539 }
540}
541
542impl Sub for Mat2 {
543 type Output = Self;
544 #[inline]
545 fn sub(self, rhs: Self) -> Self {
546 Self(unsafe { vsubq_f32(self.0, rhs.0) })
547 }
548}
549
550impl Sub<&Self> for Mat2 {
551 type Output = Self;
552 #[inline]
553 fn sub(self, rhs: &Self) -> Self {
554 self.sub(*rhs)
555 }
556}
557
558impl Sub<&Mat2> for &Mat2 {
559 type Output = Mat2;
560 #[inline]
561 fn sub(self, rhs: &Mat2) -> Mat2 {
562 (*self).sub(*rhs)
563 }
564}
565
566impl Sub<Mat2> for &Mat2 {
567 type Output = Mat2;
568 #[inline]
569 fn sub(self, rhs: Mat2) -> Mat2 {
570 (*self).sub(rhs)
571 }
572}
573
574impl SubAssign for Mat2 {
575 #[inline]
576 fn sub_assign(&mut self, rhs: Self) {
577 *self = self.sub(rhs);
578 }
579}
580
581impl SubAssign<&Self> for Mat2 {
582 #[inline]
583 fn sub_assign(&mut self, rhs: &Self) {
584 self.sub_assign(*rhs);
585 }
586}
587
588impl Neg for Mat2 {
589 type Output = Self;
590 #[inline]
591 fn neg(self) -> Self::Output {
592 Self(unsafe { vnegq_f32(self.0) })
593 }
594}
595
596impl Neg for &Mat2 {
597 type Output = Mat2;
598 #[inline]
599 fn neg(self) -> Mat2 {
600 (*self).neg()
601 }
602}
603
604impl Mul for Mat2 {
605 type Output = Self;
606 #[inline]
607 fn mul(self, rhs: Self) -> Self {
608 unsafe {
609 let abcd = self.0;
610 let xxyy0 = vzip1q_f32(rhs.0, rhs.0);
611 let xxyy1 = vzip2q_f32(rhs.0, rhs.0);
612 let axbxcydy0 = vmulq_f32(abcd, xxyy0);
613 let axbxcydy1 = vmulq_f32(abcd, xxyy1);
614 let cydyaxbx0 = vextq_f32(axbxcydy0, axbxcydy0, 2);
615 let cydyaxbx1 = vextq_f32(axbxcydy1, axbxcydy1, 2);
616 let result0 = vaddq_f32(axbxcydy0, cydyaxbx0);
617 let result1 = vaddq_f32(axbxcydy1, cydyaxbx1);
618 Self(vreinterpretq_f32_u64(vsetq_lane_u64(
619 vgetq_lane_u64(vreinterpretq_u64_f32(result1), 0),
620 vreinterpretq_u64_f32(result0),
621 1,
622 )))
623 }
624 }
625}
626
627impl Mul<&Self> for Mat2 {
628 type Output = Self;
629 #[inline]
630 fn mul(self, rhs: &Self) -> Self {
631 self.mul(*rhs)
632 }
633}
634
635impl Mul<&Mat2> for &Mat2 {
636 type Output = Mat2;
637 #[inline]
638 fn mul(self, rhs: &Mat2) -> Mat2 {
639 (*self).mul(*rhs)
640 }
641}
642
643impl Mul<Mat2> for &Mat2 {
644 type Output = Mat2;
645 #[inline]
646 fn mul(self, rhs: Mat2) -> Mat2 {
647 (*self).mul(rhs)
648 }
649}
650
651impl MulAssign for Mat2 {
652 #[inline]
653 fn mul_assign(&mut self, rhs: Self) {
654 *self = self.mul(rhs);
655 }
656}
657
658impl MulAssign<&Self> for Mat2 {
659 #[inline]
660 fn mul_assign(&mut self, rhs: &Self) {
661 self.mul_assign(*rhs);
662 }
663}
664
665impl Mul<Vec2> for Mat2 {
666 type Output = Vec2;
667 #[inline]
668 fn mul(self, rhs: Vec2) -> Self::Output {
669 self.mul_vec2(rhs)
670 }
671}
672
673impl Mul<&Vec2> for Mat2 {
674 type Output = Vec2;
675 #[inline]
676 fn mul(self, rhs: &Vec2) -> Vec2 {
677 self.mul(*rhs)
678 }
679}
680
681impl Mul<&Vec2> for &Mat2 {
682 type Output = Vec2;
683 #[inline]
684 fn mul(self, rhs: &Vec2) -> Vec2 {
685 (*self).mul(*rhs)
686 }
687}
688
689impl Mul<Vec2> for &Mat2 {
690 type Output = Vec2;
691 #[inline]
692 fn mul(self, rhs: Vec2) -> Vec2 {
693 (*self).mul(rhs)
694 }
695}
696
697impl Mul<Mat2> for f32 {
698 type Output = Mat2;
699 #[inline]
700 fn mul(self, rhs: Mat2) -> Self::Output {
701 rhs.mul_scalar(self)
702 }
703}
704
705impl Mul<&Mat2> for f32 {
706 type Output = Mat2;
707 #[inline]
708 fn mul(self, rhs: &Mat2) -> Mat2 {
709 self.mul(*rhs)
710 }
711}
712
713impl Mul<&Mat2> for &f32 {
714 type Output = Mat2;
715 #[inline]
716 fn mul(self, rhs: &Mat2) -> Mat2 {
717 (*self).mul(*rhs)
718 }
719}
720
721impl Mul<Mat2> for &f32 {
722 type Output = Mat2;
723 #[inline]
724 fn mul(self, rhs: Mat2) -> Mat2 {
725 (*self).mul(rhs)
726 }
727}
728
729impl Mul<f32> for Mat2 {
730 type Output = Self;
731 #[inline]
732 fn mul(self, rhs: f32) -> Self {
733 self.mul_scalar(rhs)
734 }
735}
736
737impl Mul<&f32> for Mat2 {
738 type Output = Self;
739 #[inline]
740 fn mul(self, rhs: &f32) -> Self {
741 self.mul(*rhs)
742 }
743}
744
745impl Mul<&f32> for &Mat2 {
746 type Output = Mat2;
747 #[inline]
748 fn mul(self, rhs: &f32) -> Mat2 {
749 (*self).mul(*rhs)
750 }
751}
752
753impl Mul<f32> for &Mat2 {
754 type Output = Mat2;
755 #[inline]
756 fn mul(self, rhs: f32) -> Mat2 {
757 (*self).mul(rhs)
758 }
759}
760
761impl MulAssign<f32> for Mat2 {
762 #[inline]
763 fn mul_assign(&mut self, rhs: f32) {
764 *self = self.mul(rhs);
765 }
766}
767
768impl MulAssign<&f32> for Mat2 {
769 #[inline]
770 fn mul_assign(&mut self, rhs: &f32) {
771 self.mul_assign(*rhs);
772 }
773}
774
775impl Div<Mat2> for f32 {
776 type Output = Mat2;
777 #[inline]
778 fn div(self, rhs: Mat2) -> Self::Output {
779 Mat2(unsafe { vdivq_f32(vld1q_dup_f32(&self), rhs.0) })
780 }
781}
782
783impl Div<&Mat2> for f32 {
784 type Output = Mat2;
785 #[inline]
786 fn div(self, rhs: &Mat2) -> Mat2 {
787 self.div(*rhs)
788 }
789}
790
791impl Div<&Mat2> for &f32 {
792 type Output = Mat2;
793 #[inline]
794 fn div(self, rhs: &Mat2) -> Mat2 {
795 (*self).div(*rhs)
796 }
797}
798
799impl Div<Mat2> for &f32 {
800 type Output = Mat2;
801 #[inline]
802 fn div(self, rhs: Mat2) -> Mat2 {
803 (*self).div(rhs)
804 }
805}
806
807impl Div<f32> for Mat2 {
808 type Output = Self;
809 #[inline]
810 fn div(self, rhs: f32) -> Self {
811 self.div_scalar(rhs)
812 }
813}
814
815impl Div<&f32> for Mat2 {
816 type Output = Self;
817 #[inline]
818 fn div(self, rhs: &f32) -> Self {
819 self.div(*rhs)
820 }
821}
822
823impl Div<&f32> for &Mat2 {
824 type Output = Mat2;
825 #[inline]
826 fn div(self, rhs: &f32) -> Mat2 {
827 (*self).div(*rhs)
828 }
829}
830
831impl Div<f32> for &Mat2 {
832 type Output = Mat2;
833 #[inline]
834 fn div(self, rhs: f32) -> Mat2 {
835 (*self).div(rhs)
836 }
837}
838
839impl DivAssign<f32> for Mat2 {
840 #[inline]
841 fn div_assign(&mut self, rhs: f32) {
842 *self = self.div(rhs);
843 }
844}
845
846impl DivAssign<&f32> for Mat2 {
847 #[inline]
848 fn div_assign(&mut self, rhs: &f32) {
849 self.div_assign(*rhs);
850 }
851}
852
853impl Sum<Self> for Mat2 {
854 fn sum<I>(iter: I) -> Self
855 where
856 I: Iterator<Item = Self>,
857 {
858 iter.fold(Self::ZERO, Self::add)
859 }
860}
861
862impl<'a> Sum<&'a Self> for Mat2 {
863 fn sum<I>(iter: I) -> Self
864 where
865 I: Iterator<Item = &'a Self>,
866 {
867 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
868 }
869}
870
871impl Product for Mat2 {
872 fn product<I>(iter: I) -> Self
873 where
874 I: Iterator<Item = Self>,
875 {
876 iter.fold(Self::IDENTITY, Self::mul)
877 }
878}
879
880impl<'a> Product<&'a Self> for Mat2 {
881 fn product<I>(iter: I) -> Self
882 where
883 I: Iterator<Item = &'a Self>,
884 {
885 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
886 }
887}
888
889impl PartialEq for Mat2 {
890 #[inline]
891 fn eq(&self, rhs: &Self) -> bool {
892 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis)
893 }
894}
895
896impl AsRef<[f32; 4]> for Mat2 {
897 #[inline]
898 fn as_ref(&self) -> &[f32; 4] {
899 unsafe { &*(self as *const Self as *const [f32; 4]) }
900 }
901}
902
903impl AsMut<[f32; 4]> for Mat2 {
904 #[inline]
905 fn as_mut(&mut self) -> &mut [f32; 4] {
906 unsafe { &mut *(self as *mut Self as *mut [f32; 4]) }
907 }
908}
909
910impl core::ops::Deref for Mat2 {
911 type Target = crate::deref::Cols2<Vec2>;
912 #[inline]
913 fn deref(&self) -> &Self::Target {
914 unsafe { &*(self as *const Self as *const Self::Target) }
915 }
916}
917
918impl core::ops::DerefMut for Mat2 {
919 #[inline]
920 fn deref_mut(&mut self) -> &mut Self::Target {
921 unsafe { &mut *(self as *mut Self as *mut Self::Target) }
922 }
923}
924
925impl fmt::Debug for Mat2 {
926 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
927 fmt.debug_struct(stringify!(Mat2))
928 .field("x_axis", &self.x_axis)
929 .field("y_axis", &self.y_axis)
930 .finish()
931 }
932}
933
934impl fmt::Display for Mat2 {
935 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
936 if let Some(p) = f.precision() {
937 write!(f, "[{:.*}, {:.*}]", p, self.x_axis, p, self.y_axis)
938 } else {
939 write!(f, "[{}, {}]", self.x_axis, self.y_axis)
940 }
941 }
942}