glam_matrix_extras/rectangular/
mat32.rs

1use core::iter::Sum;
2use core::ops::*;
3#[cfg(feature = "f64")]
4use glam::{DMat2, DMat3, DVec2, DVec3};
5#[cfg(feature = "f32")]
6use glam::{Mat2, Mat3, Vec2, Vec3};
7
8#[cfg(feature = "bevy_reflect")]
9use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize, std_traits::ReflectDefault};
10
11#[cfg(feature = "f64")]
12use crate::rectangular::DMat23;
13#[cfg(feature = "f32")]
14use crate::rectangular::Mat23;
15#[cfg(feature = "f64")]
16use crate::symmetric::SymmetricDMat2;
17#[cfg(feature = "f32")]
18use crate::symmetric::SymmetricMat2;
19
20macro_rules! mat32s {
21    ($($n:ident => $m23t:ident, $symmetricm2t:ident, $m2t:ident, $m3t:ident, $v2t:ident, $v3t:ident, $t:ident),+) => {
22        $(
23        /// A 3x2 column-major matrix.
24        #[derive(Clone, Copy, PartialEq)]
25        #[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
26        #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
27        #[cfg_attr(
28            all(feature = "bevy_reflect", feature = "serde"),
29            reflect(Debug, Default, PartialEq, Serialize, Deserialize)
30        )]
31        pub struct $n {
32            /// The first column of the matrix.
33            pub x_axis: $v3t,
34            /// The second column of the matrix.
35            pub y_axis: $v3t,
36        }
37
38        impl $n {
39            /// A 3x2 matrix with all elements set to `0.0`.
40            pub const ZERO: Self = Self::from_cols($v3t::ZERO, $v3t::ZERO);
41
42            /// All NaNs.
43            pub const NAN: Self = Self::from_cols($v3t::NAN, $v3t::NAN);
44
45            /// Creates a 3x2 matrix from two column vectors.
46            #[inline(always)]
47            #[must_use]
48            pub const fn from_cols(x_axis: $v3t, y_axis: $v3t) -> Self {
49                Self { x_axis, y_axis }
50            }
51
52            /// Creates a 3x2 matrix from an array stored in column major order.
53            #[inline]
54            #[must_use]
55            pub const fn from_cols_array(m: &[$t; 6]) -> Self {
56                Self::from_cols(
57                    $v3t::new(m[0], m[1], m[2]),
58                    $v3t::new(m[3], m[4], m[5]),
59                )
60            }
61
62            /// Creates an array storing data in column major order.
63            #[inline]
64            #[must_use]
65            pub const fn to_cols_array(&self) -> [$t; 6] {
66                [
67                    self.x_axis.x,
68                    self.x_axis.y,
69                    self.x_axis.z,
70                    self.y_axis.x,
71                    self.y_axis.y,
72                    self.y_axis.z,
73                ]
74            }
75
76            /// Creates a 3x2 matrix from a 2D array stored in column major order.
77            #[inline]
78            #[must_use]
79            pub const fn from_cols_array_2d(m: &[[$t; 3]; 2]) -> Self {
80                Self::from_cols($v3t::from_array(m[0]), $v3t::from_array(m[1]))
81            }
82
83            /// Creates a 2D array storing data in column major order.
84            #[inline]
85            #[must_use]
86            pub const fn to_cols_array_2d(&self) -> [[$t; 3]; 2] {
87                [self.x_axis.to_array(), self.y_axis.to_array()]
88            }
89
90            /// Creates a 3x2 matrix from the first 6 values in `slice`.
91            ///
92            /// # Panics
93            ///
94            /// Panics if `slice` is less than 6 elements long.
95            #[inline]
96            #[must_use]
97            pub const fn from_cols_slice(slice: &[$t]) -> Self {
98                Self::from_cols(
99                    $v3t::new(slice[0], slice[1], slice[2]),
100                    $v3t::new(slice[3], slice[4], slice[5]),
101                )
102            }
103
104            /// Creates a 3x2 matrix from three row vectors.
105            pub const fn from_rows(row0: $v2t, row1: $v2t, row2: $v2t) -> Self {
106                Self::from_cols(
107                    $v3t::new(row0.x, row1.x, row2.x),
108                    $v3t::new(row0.y, row1.y, row2.y),
109                )
110            }
111
112            /// Creates a 2x3 matrix from an array stored in row major order.
113            #[inline]
114            #[must_use]
115            pub const fn from_rows_array(m: &[$t; 6]) -> Self {
116                Self::from_rows(
117                    $v2t::new(m[0], m[1]),
118                    $v2t::new(m[2], m[3]),
119                    $v2t::new(m[4], m[5]),
120                )
121            }
122
123            /// Creates an array storing data in row major order.
124            #[inline]
125            #[must_use]
126            pub const fn to_rows_array(&self) -> [$t; 6] {
127                [
128                    self.x_axis.x,
129                    self.y_axis.x,
130                    self.x_axis.y,
131                    self.y_axis.y,
132                    self.x_axis.z,
133                    self.y_axis.z,
134                ]
135            }
136
137            /// Creates a 2x3 matrix from a 2D array stored in row major order.
138            #[inline]
139            #[must_use]
140            pub const fn from_rows_array_2d(m: &[[$t; 2]; 3]) -> Self {
141                Self::from_rows(
142                    $v2t::new(m[0][0], m[0][1]),
143                    $v2t::new(m[1][0], m[1][1]),
144                    $v2t::new(m[2][0], m[2][1]),
145                )
146            }
147
148            /// Creates a 2D array storing data in row major order.
149            #[inline]
150            #[must_use]
151            pub const fn to_rows_array_2d(&self) -> [[$t; 2]; 3] {
152                [
153                    [self.x_axis.x, self.y_axis.x],
154                    [self.x_axis.y, self.y_axis.y],
155                    [self.x_axis.z, self.y_axis.z],
156                ]
157            }
158
159            /// Creates a 2x3 matrix from the first 6 values in `slice`.
160            ///
161            /// # Panics
162            ///
163            /// Panics if `slice` is less than 6 elements long.
164            #[inline]
165            #[must_use]
166            pub const fn from_rows_slice(slice: &[$t]) -> Self {
167                Self::from_rows(
168                    $v2t::new(slice[0], slice[1]),
169                    $v2t::new(slice[2], slice[3]),
170                    $v2t::new(slice[4], slice[5]),
171                )
172            }
173
174            /// Creates a new 3x2 matrix from the outer product `a * b^T`.
175            #[inline(always)]
176            #[must_use]
177            pub fn from_outer_product(a: $v3t, b: $v2t) -> Self {
178                Self::from_cols(
179                    $v3t::new(a.x * b.x, a.y * b.x, a.z * b.x),
180                    $v3t::new(a.x * b.y, a.y * b.y, a.z * b.y),
181                )
182            }
183
184            /// Returns the matrix column for the given `index`.
185            ///
186            /// # Panics
187            ///
188            /// Panics if `index` is greater than 1.
189            #[inline]
190            #[must_use]
191            pub const fn col(&self, index: usize) -> $v3t {
192                match index {
193                    0 => self.x_axis,
194                    1 => self.y_axis,
195                    _ => panic!("index out of bounds"),
196                }
197            }
198
199            /// Returns the matrix row for the given `index`.
200            ///
201            /// # Panics
202            ///
203            /// Panics if `index` is greater than 2.
204            #[inline]
205            #[must_use]
206            pub const fn row(&self, index: usize) -> $v2t {
207                match index {
208                    0 => $v2t::new(self.x_axis.x, self.y_axis.x),
209                    1 => $v2t::new(self.x_axis.y, self.y_axis.y),
210                    2 => $v2t::new(self.x_axis.z, self.y_axis.z),
211                    _ => panic!("index out of bounds"),
212                }
213            }
214
215            /// Returns `true` if, and only if, all elements are finite.
216            /// If any element is either `NaN` or positive or negative infinity, this will return `false`.
217            #[inline]
218            #[must_use]
219            pub fn is_finite(&self) -> bool {
220                self.x_axis.is_finite() && self.y_axis.is_finite()
221            }
222
223            /// Returns `true` if any elements are `NaN`.
224            #[inline]
225            #[must_use]
226            pub fn is_nan(&self) -> bool {
227                self.x_axis.is_nan() || self.y_axis.is_nan()
228            }
229
230            /// Returns the transpose of `self`.
231            #[inline]
232            #[must_use]
233            pub fn transpose(&self) -> $m23t {
234                $m23t::from_rows(self.x_axis, self.y_axis)
235            }
236
237            /// Takes the absolute value of each element in `self`.
238            #[inline]
239            #[must_use]
240            pub fn abs(&self) -> Self {
241                Self::from_cols(self.x_axis.abs(), self.y_axis.abs())
242            }
243
244            /// Transforms a 2D vector into a 3D vector.
245            #[inline]
246            #[must_use]
247            pub fn mul_vec2(&self, rhs: $v2t) -> $v3t {
248                $v3t::new(
249                    rhs.dot(self.row(0)),
250                    rhs.dot(self.row(1)),
251                    rhs.dot(self.row(2)),
252                )
253            }
254
255            /// Multiplies `self` by a 2x2 matrix, `self * rhs`.
256            #[inline]
257            #[must_use]
258            pub fn mul_mat2(&self, rhs: &$m2t) -> Self {
259                self.mul(rhs)
260            }
261
262            /// Multiplies `self` by a symmetric 2x2 matrix, `self * rhs`.
263            #[inline]
264            #[must_use]
265            pub fn mul_symmetric_mat2(&self, rhs: &$symmetricm2t) -> Self {
266                self.mul(rhs)
267            }
268
269            /// Multiplies `self` by a 2x3 matrix, `self * rhs`.
270            #[inline]
271            #[must_use]
272            pub fn mul_mat23(&self, rhs: &$m23t) -> $m3t {
273                self.mul(rhs)
274            }
275
276            /// Multiplies `self` by another matrix that is treated as transposed, `self * rhs.transpose()`.
277            #[inline]
278            #[must_use]
279            pub fn mul_transposed_mat32(&self, rhs: &Self) -> $m3t {
280                $m3t::from_cols(
281                    $v3t::new(
282                        self.row(0).dot(rhs.row(0)),
283                        self.row(1).dot(rhs.row(0)),
284                        self.row(2).dot(rhs.row(0)),
285                    ),
286                    $v3t::new(
287                        self.row(0).dot(rhs.row(1)),
288                        self.row(1).dot(rhs.row(1)),
289                        self.row(2).dot(rhs.row(1)),
290                    ),
291                    $v3t::new(
292                        self.row(0).dot(rhs.row(2)),
293                        self.row(1).dot(rhs.row(2)),
294                        self.row(2).dot(rhs.row(2)),
295                    ),
296                )
297            }
298
299            /// Adds two 2x2 matrices.
300            #[inline]
301            #[must_use]
302            pub fn add_mat32(&self, rhs: &Self) -> Self {
303                self.add(rhs)
304            }
305
306            /// Subtracts two 2x2 matrices.
307            #[inline]
308            #[must_use]
309            pub fn sub_mat32(&self, rhs: &Self) -> Self {
310                self.sub(rhs)
311            }
312
313            /// Multiplies a 3x2 matrix by a scalar.
314            #[inline]
315            #[must_use]
316            pub fn mul_scalar(&self, rhs: $t) -> Self {
317                Self::from_cols(self.x_axis * rhs, self.y_axis * rhs)
318            }
319
320            /// Divides a 3x2 matrix by a scalar.
321            #[inline]
322            #[must_use]
323            pub fn div_scalar(&self, rhs: $t) -> Self {
324                Self::from_cols(self.x_axis / rhs, self.y_axis / rhs)
325            }
326        }
327
328        impl Default for $n {
329            #[inline(always)]
330            fn default() -> Self {
331                Self::ZERO
332            }
333        }
334
335        impl Add for $n {
336            type Output = Self;
337            #[inline]
338            fn add(self, rhs: Self) -> Self::Output {
339                Self::from_cols(self.x_axis + rhs.x_axis, self.y_axis + rhs.y_axis)
340            }
341        }
342
343        impl Add<&Self> for $n {
344            type Output = Self;
345            #[inline]
346            fn add(self, rhs: &Self) -> Self::Output {
347                self.add(*rhs)
348            }
349        }
350
351        impl Add<Self> for &$n {
352            type Output = $n;
353            #[inline]
354            fn add(self, rhs: Self) -> Self::Output {
355                (*self).add(rhs)
356            }
357        }
358
359        impl Add<&Self> for &$n {
360            type Output = $n;
361            #[inline]
362            fn add(self, rhs: &Self) -> Self::Output {
363                (*self).add(*rhs)
364            }
365        }
366
367        impl AddAssign for $n {
368            #[inline]
369            fn add_assign(&mut self, rhs: Self) {
370                *self = self.add(rhs);
371            }
372        }
373
374        impl AddAssign<&Self> for $n {
375            #[inline]
376            fn add_assign(&mut self, rhs: &Self) {
377                self.add_assign(*rhs);
378            }
379        }
380
381        impl Sub for $n {
382            type Output = Self;
383            #[inline]
384            fn sub(self, rhs: Self) -> Self::Output {
385                Self::from_cols(self.x_axis - rhs.x_axis, self.y_axis - rhs.y_axis)
386            }
387        }
388
389        impl Sub<&Self> for $n {
390            type Output = Self;
391            #[inline]
392            fn sub(self, rhs: &Self) -> Self::Output {
393                self.sub(*rhs)
394            }
395        }
396
397        impl Sub<Self> for &$n {
398            type Output = $n;
399            #[inline]
400            fn sub(self, rhs: Self) -> Self::Output {
401                (*self).sub(rhs)
402            }
403        }
404
405        impl Sub<&Self> for &$n {
406            type Output = $n;
407            #[inline]
408            fn sub(self, rhs: &Self) -> Self::Output {
409                (*self).sub(*rhs)
410            }
411        }
412
413        impl SubAssign for $n {
414            #[inline]
415            fn sub_assign(&mut self, rhs: Self) {
416                *self = self.sub(rhs);
417            }
418        }
419
420        impl SubAssign<&Self> for $n {
421            #[inline]
422            fn sub_assign(&mut self, rhs: &Self) {
423                self.sub_assign(*rhs);
424            }
425        }
426
427        impl Neg for $n {
428            type Output = Self;
429            #[inline]
430            fn neg(self) -> Self::Output {
431                Self::from_cols(-self.x_axis, -self.y_axis)
432            }
433        }
434
435        impl Neg for &$n {
436            type Output = $n;
437            #[inline]
438            fn neg(self) -> Self::Output {
439                (*self).neg()
440            }
441        }
442
443        impl Mul<$m2t> for $n {
444            type Output = Self;
445            #[inline]
446            fn mul(self, rhs: $m2t) -> Self::Output {
447                Self::from_cols(
448                    $v3t::new(
449                        self.row(0).dot(rhs.x_axis),
450                        self.row(1).dot(rhs.x_axis),
451                        self.row(2).dot(rhs.x_axis),
452                    ),
453                    $v3t::new(
454                        self.row(0).dot(rhs.y_axis),
455                        self.row(1).dot(rhs.y_axis),
456                        self.row(2).dot(rhs.y_axis),
457                    )
458                )
459            }
460        }
461
462        impl Mul<&$m2t> for $n {
463            type Output = Self;
464            #[inline]
465            fn mul(self, rhs: &$m2t) -> Self::Output {
466                self.mul(*rhs)
467            }
468        }
469
470        impl Mul<$m2t> for &$n {
471            type Output = $n;
472            #[inline]
473            fn mul(self, rhs: $m2t) -> Self::Output {
474                (*self).mul(rhs)
475            }
476        }
477
478        impl Mul<&$m2t> for &$n {
479            type Output = $n;
480            #[inline]
481            fn mul(self, rhs: &$m2t) -> Self::Output {
482                (*self).mul(*rhs)
483            }
484        }
485
486        impl Mul<$symmetricm2t> for $n {
487            type Output = Self;
488            #[inline]
489            fn mul(self, rhs: $symmetricm2t) -> Self::Output {
490                Self::from_cols(
491                    $v3t::new(
492                        self.row(0).dot(rhs.col(0)),
493                        self.row(1).dot(rhs.col(0)),
494                        self.row(2).dot(rhs.col(0)),
495                    ),
496                    $v3t::new(
497                        self.row(0).dot(rhs.col(1)),
498                        self.row(1).dot(rhs.col(1)),
499                        self.row(2).dot(rhs.col(1)),
500                    ),
501                )
502            }
503        }
504
505        impl Mul<&$symmetricm2t> for $n {
506            type Output = Self;
507            #[inline]
508            fn mul(self, rhs: &$symmetricm2t) -> Self::Output {
509                self.mul(*rhs)
510            }
511        }
512
513        impl Mul<$symmetricm2t> for &$n {
514            type Output = $n;
515            #[inline]
516            fn mul(self, rhs: $symmetricm2t) -> Self::Output {
517                (*self).mul(rhs)
518            }
519        }
520
521        impl Mul<&$symmetricm2t> for &$n {
522            type Output = $n;
523            #[inline]
524            fn mul(self, rhs: &$symmetricm2t) -> Self::Output {
525                (*self).mul(*rhs)
526            }
527        }
528
529        impl Mul<$m23t> for $n {
530            type Output = $m3t;
531            #[inline]
532            fn mul(self, rhs: $m23t) -> Self::Output {
533                $m3t::from_cols(
534                    $v3t::new(
535                        self.row(0).dot(rhs.x_axis),
536                        self.row(1).dot(rhs.x_axis),
537                        self.row(2).dot(rhs.x_axis),
538                    ),
539                    $v3t::new(
540                        self.row(0).dot(rhs.y_axis),
541                        self.row(1).dot(rhs.y_axis),
542                        self.row(2).dot(rhs.y_axis),
543                    ),
544                    $v3t::new(
545                        self.row(0).dot(rhs.z_axis),
546                        self.row(1).dot(rhs.z_axis),
547                        self.row(2).dot(rhs.z_axis),
548                    ),
549                )
550            }
551        }
552
553        impl Mul<&$m23t> for $n {
554            type Output = $m3t;
555            #[inline]
556            fn mul(self, rhs: &$m23t) -> Self::Output {
557                self.mul(*rhs)
558            }
559        }
560
561        impl Mul<$m23t> for &$n {
562            type Output = $m3t;
563            #[inline]
564            fn mul(self, rhs: $m23t) -> Self::Output {
565                (*self).mul(rhs)
566            }
567        }
568
569        impl Mul<&$m23t> for &$n {
570            type Output = $m3t;
571            #[inline]
572            fn mul(self, rhs: &$m23t) -> Self::Output {
573                (*self).mul(*rhs)
574            }
575        }
576
577        impl Mul<$v2t> for $n {
578            type Output = $v3t;
579            #[inline]
580            fn mul(self, rhs: $v2t) -> Self::Output {
581                self.mul_vec2(rhs)
582            }
583        }
584
585        impl Mul<&$v2t> for $n {
586            type Output = $v3t;
587            #[inline]
588            fn mul(self, rhs: &$v2t) -> Self::Output {
589                self.mul(*rhs)
590            }
591        }
592
593        impl Mul<$v2t> for &$n {
594            type Output = $v3t;
595            #[inline]
596            fn mul(self, rhs: $v2t) -> Self::Output {
597                (*self).mul(rhs)
598            }
599        }
600
601        impl Mul<&$v2t> for &$n {
602            type Output = $v3t;
603            #[inline]
604            fn mul(self, rhs: &$v2t) -> Self::Output {
605                (*self).mul(*rhs)
606            }
607        }
608
609        impl Mul<$n> for $t {
610            type Output = $n;
611            #[inline]
612            fn mul(self, rhs: $n) -> Self::Output {
613                rhs.mul_scalar(self)
614            }
615        }
616
617        impl Mul<&$n> for $t {
618            type Output = $n;
619            #[inline]
620            fn mul(self, rhs: &$n) -> Self::Output {
621                self.mul(*rhs)
622            }
623        }
624
625        impl Mul<$n> for &$t {
626            type Output = $n;
627            #[inline]
628            fn mul(self, rhs: $n) -> Self::Output {
629                (*self).mul(rhs)
630            }
631        }
632
633        impl Mul<&$n> for &$t {
634            type Output = $n;
635            #[inline]
636            fn mul(self, rhs: &$n) -> Self::Output {
637                (*self).mul(*rhs)
638            }
639        }
640
641        impl Mul<$t> for $n {
642            type Output = Self;
643            #[inline]
644            fn mul(self, rhs: $t) -> Self::Output {
645                self.mul_scalar(rhs)
646            }
647        }
648
649        impl Mul<&$t> for $n {
650            type Output = Self;
651            #[inline]
652            fn mul(self, rhs: &$t) -> Self::Output {
653                self.mul(*rhs)
654            }
655        }
656
657        impl Mul<$t> for &$n {
658            type Output = $n;
659            #[inline]
660            fn mul(self, rhs: $t) -> Self::Output {
661                (*self).mul(rhs)
662            }
663        }
664
665        impl Mul<&$t> for &$n {
666            type Output = $n;
667            #[inline]
668            fn mul(self, rhs: &$t) -> Self::Output {
669                (*self).mul(*rhs)
670            }
671        }
672
673        impl MulAssign<$t> for $n {
674            #[inline]
675            fn mul_assign(&mut self, rhs: $t) {
676                *self = self.mul(rhs);
677            }
678        }
679
680        impl MulAssign<&$t> for $n {
681            #[inline]
682            fn mul_assign(&mut self, rhs: &$t) {
683                self.mul_assign(*rhs);
684            }
685        }
686
687        impl Div<$n> for $t {
688            type Output = $n;
689            #[inline]
690            fn div(self, rhs: $n) -> Self::Output {
691                rhs.div_scalar(self)
692            }
693        }
694
695        impl Div<&$n> for $t {
696            type Output = $n;
697            #[inline]
698            fn div(self, rhs: &$n) -> Self::Output {
699                self.div(*rhs)
700            }
701        }
702
703        impl Div<$n> for &$t {
704            type Output = $n;
705            #[inline]
706            fn div(self, rhs: $n) -> Self::Output {
707                (*self).div(rhs)
708            }
709        }
710
711        impl Div<&$n> for &$t {
712            type Output = $n;
713            #[inline]
714            fn div(self, rhs: &$n) -> Self::Output {
715                (*self).div(*rhs)
716            }
717        }
718
719        impl Div<$t> for $n {
720            type Output = Self;
721            #[inline]
722            fn div(self, rhs: $t) -> Self::Output {
723                self.div_scalar(rhs)
724            }
725        }
726
727        impl Div<&$t> for $n {
728            type Output = Self;
729            #[inline]
730            fn div(self, rhs: &$t) -> Self::Output {
731                self.div(*rhs)
732            }
733        }
734
735        impl Div<$t> for &$n {
736            type Output = $n;
737            #[inline]
738            fn div(self, rhs: $t) -> Self::Output {
739                (*self).div(rhs)
740            }
741        }
742
743        impl Div<&$t> for &$n {
744            type Output = $n;
745            #[inline]
746            fn div(self, rhs: &$t) -> Self::Output {
747                (*self).div(*rhs)
748            }
749        }
750
751        impl DivAssign<$t> for $n {
752            #[inline]
753            fn div_assign(&mut self, rhs: $t) {
754                *self = self.div(rhs);
755            }
756        }
757
758        impl DivAssign<&$t> for $n {
759            #[inline]
760            fn div_assign(&mut self, rhs: &$t) {
761                self.div_assign(*rhs);
762            }
763        }
764
765        impl Sum<$n> for $n {
766            fn sum<I: Iterator<Item = $n>>(iter: I) -> Self {
767                iter.fold(Self::ZERO, Self::add)
768            }
769        }
770
771        impl<'a> Sum<&'a $n> for $n {
772            fn sum<I: Iterator<Item = &'a $n>>(iter: I) -> Self {
773                iter.fold(Self::ZERO, |a, &b| a.add(b))
774            }
775        }
776
777        #[cfg(feature = "approx")]
778        impl approx::AbsDiffEq for $n {
779            type Epsilon = $t;
780
781            #[inline]
782            fn default_epsilon() -> Self::Epsilon {
783                $t::default_epsilon()
784            }
785
786            #[inline]
787            fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool {
788                self.x_axis.abs_diff_eq(other.x_axis, epsilon)
789                    && self.y_axis.abs_diff_eq(other.y_axis, epsilon)
790            }
791        }
792
793        #[cfg(feature = "approx")]
794        impl approx::RelativeEq for $n {
795            #[inline]
796            fn default_max_relative() -> Self::Epsilon {
797                $t::default_max_relative()
798            }
799
800            #[inline]
801            fn relative_eq(
802                &self,
803                other: &Self,
804                epsilon: Self::Epsilon,
805                max_relative: Self::Epsilon,
806            ) -> bool {
807                self.x_axis.relative_eq(&other.x_axis, epsilon, max_relative)
808                    && self.y_axis.relative_eq(&other.y_axis, epsilon, max_relative)
809            }
810        }
811
812        #[cfg(feature = "approx")]
813        impl approx::UlpsEq for $n {
814            #[inline]
815            fn default_max_ulps() -> u32 {
816                $t::default_max_ulps()
817            }
818
819            #[inline]
820            fn ulps_eq(
821                &self,
822                other: &Self,
823                epsilon: Self::Epsilon,
824                max_ulps: u32,
825            ) -> bool {
826                self.x_axis.ulps_eq(&other.x_axis, epsilon, max_ulps)
827                    && self.y_axis.ulps_eq(&other.y_axis, epsilon, max_ulps)
828            }
829        }
830
831        impl core::fmt::Debug for $n {
832            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
833                f.debug_struct(stringify!($n))
834                    .field("x_axis", &self.x_axis)
835                    .field("y_axis", &self.y_axis)
836                    .finish()
837            }
838        }
839
840        impl core::fmt::Display for $n {
841            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
842                if let Some(p) = f.precision() {
843                    write!(
844                        f,
845                        "[[{:.*}, {:.*}, {:.*}], [{:.*}, {:.*}, {:.*}]]",
846                        p, self.x_axis.x, p, self.x_axis.y, p, self.x_axis.z,
847                        p, self.y_axis.x, p, self.y_axis.y, p, self.y_axis.z
848                    )
849                } else {
850                    write!(
851                        f,
852                        "[[{}, {}, {}], [{}, {}, {}]]",
853                        self.x_axis.x, self.x_axis.y, self.x_axis.z,
854                        self.y_axis.x, self.y_axis.y, self.y_axis.z
855                    )
856                }
857            }
858        }
859        )+
860    }
861}
862
863#[cfg(feature = "f32")]
864mat32s!(Mat32 => Mat23, SymmetricMat2, Mat2, Mat3, Vec2, Vec3, f32);
865
866#[cfg(feature = "f64")]
867mat32s!(DMat32 => DMat23, SymmetricDMat2, DMat2, DMat3, DVec2, DVec3, f64);
868
869#[cfg(all(feature = "f32", feature = "f64"))]
870impl Mat32 {
871    /// Returns the double precision version of `self`.
872    #[inline]
873    #[must_use]
874    pub fn as_dmat32(&self) -> DMat32 {
875        DMat32 {
876            x_axis: self.x_axis.as_dvec3(),
877            y_axis: self.y_axis.as_dvec3(),
878        }
879    }
880}
881
882#[cfg(all(feature = "f32", feature = "f64"))]
883impl DMat32 {
884    /// Returns the single precision version of `self`.
885    #[inline]
886    #[must_use]
887    pub fn as_mat32(&self) -> Mat32 {
888        Mat32 {
889            x_axis: self.x_axis.as_vec3(),
890            y_axis: self.y_axis.as_vec3(),
891        }
892    }
893}
894
895#[cfg(test)]
896mod tests {
897    use glam::{Mat2, Mat3, vec2, vec3};
898
899    use crate::{Mat23, Mat32};
900
901    #[test]
902    fn mat32_mul_vec2() {
903        let mat = Mat32::from_cols(vec3(4.0, 1.0, 6.0), vec3(7.0, 9.0, 2.0));
904        let vec = vec2(1.0, 2.0);
905
906        let expected = vec3(18.0, 19.0, 10.0);
907        let result = mat.mul_vec2(vec);
908
909        assert_eq!(result, expected);
910    }
911
912    #[test]
913    fn mat32_mul_mat2() {
914        let mat32 = Mat32::from_cols(vec3(4.0, 1.0, 6.0), vec3(7.0, 9.0, 2.0));
915        let mat2 = Mat2::from_cols(vec2(2.0, 5.0), vec2(1.0, 8.0));
916
917        let expected = Mat32::from_cols(vec3(43.0, 47.0, 22.0), vec3(60.0, 73.0, 22.0));
918        let result = mat32.mul_mat2(&mat2);
919
920        assert_eq!(result, expected);
921    }
922
923    #[test]
924    fn mat32_mul_mat23() {
925        let mat32 = Mat32::from_cols(vec3(4.0, 1.0, 6.0), vec3(7.0, 9.0, 2.0));
926        let mat23 = Mat23::from_rows(vec3(2.0, 5.0, 1.0), vec3(8.0, 3.0, 4.0));
927
928        let expected = Mat3::from_cols(
929            vec3(64.0, 74.0, 28.0),
930            vec3(41.0, 32.0, 36.0),
931            vec3(32.0, 37.0, 14.0),
932        );
933        let result = mat32.mul_mat23(&mat23);
934
935        assert_eq!(result, expected);
936    }
937
938    #[test]
939    fn mat32_mul_transposed_mat32() {
940        let mat32_a = Mat32::from_cols(vec3(4.0, 1.0, 6.0), vec3(7.0, 9.0, 2.0));
941        let mat32_b = Mat32::from_cols(vec3(2.0, 5.0, 1.0), vec3(8.0, 3.0, 4.0));
942
943        let expected = Mat3::from_cols(
944            vec3(64.0, 74.0, 28.0),
945            vec3(41.0, 32.0, 36.0),
946            vec3(32.0, 37.0, 14.0),
947        );
948        let result = mat32_a.mul_transposed_mat32(&mat32_b);
949
950        assert_eq!(result, expected);
951        assert_eq!(result, mat32_a * mat32_b.transpose());
952    }
953}