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 #[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 pub x_axis: $v3t,
34 pub y_axis: $v3t,
36 }
37
38 impl $n {
39 pub const ZERO: Self = Self::from_cols($v3t::ZERO, $v3t::ZERO);
41
42 pub const NAN: Self = Self::from_cols($v3t::NAN, $v3t::NAN);
44
45 #[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 #[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 #[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 #[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 #[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 #[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 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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline]
232 #[must_use]
233 pub fn transpose(&self) -> $m23t {
234 $m23t::from_rows(self.x_axis, self.y_axis)
235 }
236
237 #[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 #[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 #[inline]
257 #[must_use]
258 pub fn mul_mat2(&self, rhs: &$m2t) -> Self {
259 self.mul(rhs)
260 }
261
262 #[inline]
264 #[must_use]
265 pub fn mul_symmetric_mat2(&self, rhs: &$symmetricm2t) -> Self {
266 self.mul(rhs)
267 }
268
269 #[inline]
271 #[must_use]
272 pub fn mul_mat23(&self, rhs: &$m23t) -> $m3t {
273 self.mul(rhs)
274 }
275
276 #[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 #[inline]
301 #[must_use]
302 pub fn add_mat32(&self, rhs: &Self) -> Self {
303 self.add(rhs)
304 }
305
306 #[inline]
308 #[must_use]
309 pub fn sub_mat32(&self, rhs: &Self) -> Self {
310 self.sub(rhs)
311 }
312
313 #[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 #[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 #[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 #[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}