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