1use crate::{
4    euler::{FromEuler, ToEuler},
5    f64::math,
6    swizzles::*,
7    DMat2, DMat4, DQuat, DVec2, DVec3, EulerRot, Mat3,
8};
9use core::fmt;
10use core::iter::{Product, Sum};
11use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
12
13#[inline(always)]
15#[must_use]
16pub const fn dmat3(x_axis: DVec3, y_axis: DVec3, z_axis: DVec3) -> DMat3 {
17    DMat3::from_cols(x_axis, y_axis, z_axis)
18}
19
20#[derive(Clone, Copy)]
45#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
46#[repr(C)]
47pub struct DMat3 {
48    pub x_axis: DVec3,
49    pub y_axis: DVec3,
50    pub z_axis: DVec3,
51}
52
53impl DMat3 {
54    pub const ZERO: Self = Self::from_cols(DVec3::ZERO, DVec3::ZERO, DVec3::ZERO);
56
57    pub const IDENTITY: Self = Self::from_cols(DVec3::X, DVec3::Y, DVec3::Z);
59
60    pub const NAN: Self = Self::from_cols(DVec3::NAN, DVec3::NAN, DVec3::NAN);
62
63    #[allow(clippy::too_many_arguments)]
64    #[inline(always)]
65    #[must_use]
66    const fn new(
67        m00: f64,
68        m01: f64,
69        m02: f64,
70        m10: f64,
71        m11: f64,
72        m12: f64,
73        m20: f64,
74        m21: f64,
75        m22: f64,
76    ) -> Self {
77        Self {
78            x_axis: DVec3::new(m00, m01, m02),
79            y_axis: DVec3::new(m10, m11, m12),
80            z_axis: DVec3::new(m20, m21, m22),
81        }
82    }
83
84    #[inline(always)]
86    #[must_use]
87    pub const fn from_cols(x_axis: DVec3, y_axis: DVec3, z_axis: DVec3) -> Self {
88        Self {
89            x_axis,
90            y_axis,
91            z_axis,
92        }
93    }
94
95    #[inline]
99    #[must_use]
100    pub const fn from_cols_array(m: &[f64; 9]) -> Self {
101        Self::new(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8])
102    }
103
104    #[inline]
107    #[must_use]
108    pub const fn to_cols_array(&self) -> [f64; 9] {
109        [
110            self.x_axis.x,
111            self.x_axis.y,
112            self.x_axis.z,
113            self.y_axis.x,
114            self.y_axis.y,
115            self.y_axis.z,
116            self.z_axis.x,
117            self.z_axis.y,
118            self.z_axis.z,
119        ]
120    }
121
122    #[inline]
126    #[must_use]
127    pub const fn from_cols_array_2d(m: &[[f64; 3]; 3]) -> Self {
128        Self::from_cols(
129            DVec3::from_array(m[0]),
130            DVec3::from_array(m[1]),
131            DVec3::from_array(m[2]),
132        )
133    }
134
135    #[inline]
138    #[must_use]
139    pub const fn to_cols_array_2d(&self) -> [[f64; 3]; 3] {
140        [
141            self.x_axis.to_array(),
142            self.y_axis.to_array(),
143            self.z_axis.to_array(),
144        ]
145    }
146
147    #[doc(alias = "scale")]
149    #[inline]
150    #[must_use]
151    pub const fn from_diagonal(diagonal: DVec3) -> Self {
152        Self::new(
153            diagonal.x, 0.0, 0.0, 0.0, diagonal.y, 0.0, 0.0, 0.0, diagonal.z,
154        )
155    }
156
157    #[inline]
159    #[must_use]
160    pub fn from_mat4(m: DMat4) -> Self {
161        Self::from_cols(
162            DVec3::from_vec4(m.x_axis),
163            DVec3::from_vec4(m.y_axis),
164            DVec3::from_vec4(m.z_axis),
165        )
166    }
167
168    #[inline]
175    #[must_use]
176    pub fn from_mat4_minor(m: DMat4, i: usize, j: usize) -> Self {
177        match (i, j) {
178            (0, 0) => Self::from_cols(m.y_axis.yzw(), m.z_axis.yzw(), m.w_axis.yzw()),
179            (0, 1) => Self::from_cols(m.y_axis.xzw(), m.z_axis.xzw(), m.w_axis.xzw()),
180            (0, 2) => Self::from_cols(m.y_axis.xyw(), m.z_axis.xyw(), m.w_axis.xyw()),
181            (0, 3) => Self::from_cols(m.y_axis.xyz(), m.z_axis.xyz(), m.w_axis.xyz()),
182            (1, 0) => Self::from_cols(m.x_axis.yzw(), m.z_axis.yzw(), m.w_axis.yzw()),
183            (1, 1) => Self::from_cols(m.x_axis.xzw(), m.z_axis.xzw(), m.w_axis.xzw()),
184            (1, 2) => Self::from_cols(m.x_axis.xyw(), m.z_axis.xyw(), m.w_axis.xyw()),
185            (1, 3) => Self::from_cols(m.x_axis.xyz(), m.z_axis.xyz(), m.w_axis.xyz()),
186            (2, 0) => Self::from_cols(m.x_axis.yzw(), m.y_axis.yzw(), m.w_axis.yzw()),
187            (2, 1) => Self::from_cols(m.x_axis.xzw(), m.y_axis.xzw(), m.w_axis.xzw()),
188            (2, 2) => Self::from_cols(m.x_axis.xyw(), m.y_axis.xyw(), m.w_axis.xyw()),
189            (2, 3) => Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.w_axis.xyz()),
190            (3, 0) => Self::from_cols(m.x_axis.yzw(), m.y_axis.yzw(), m.z_axis.yzw()),
191            (3, 1) => Self::from_cols(m.x_axis.xzw(), m.y_axis.xzw(), m.z_axis.xzw()),
192            (3, 2) => Self::from_cols(m.x_axis.xyw(), m.y_axis.xyw(), m.z_axis.xyw()),
193            (3, 3) => Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.z_axis.xyz()),
194            _ => panic!("index out of bounds"),
195        }
196    }
197
198    #[inline]
204    #[must_use]
205    pub fn from_quat(rotation: DQuat) -> Self {
206        glam_assert!(rotation.is_normalized());
207
208        let x2 = rotation.x + rotation.x;
209        let y2 = rotation.y + rotation.y;
210        let z2 = rotation.z + rotation.z;
211        let xx = rotation.x * x2;
212        let xy = rotation.x * y2;
213        let xz = rotation.x * z2;
214        let yy = rotation.y * y2;
215        let yz = rotation.y * z2;
216        let zz = rotation.z * z2;
217        let wx = rotation.w * x2;
218        let wy = rotation.w * y2;
219        let wz = rotation.w * z2;
220
221        Self::from_cols(
222            DVec3::new(1.0 - (yy + zz), xy + wz, xz - wy),
223            DVec3::new(xy - wz, 1.0 - (xx + zz), yz + wx),
224            DVec3::new(xz + wy, yz - wx, 1.0 - (xx + yy)),
225        )
226    }
227
228    #[inline]
235    #[must_use]
236    pub fn from_axis_angle(axis: DVec3, angle: f64) -> Self {
237        glam_assert!(axis.is_normalized());
238
239        let (sin, cos) = math::sin_cos(angle);
240        let (xsin, ysin, zsin) = axis.mul(sin).into();
241        let (x, y, z) = axis.into();
242        let (x2, y2, z2) = axis.mul(axis).into();
243        let omc = 1.0 - cos;
244        let xyomc = x * y * omc;
245        let xzomc = x * z * omc;
246        let yzomc = y * z * omc;
247        Self::from_cols(
248            DVec3::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
249            DVec3::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
250            DVec3::new(xzomc + ysin, yzomc - xsin, z2 * omc + cos),
251        )
252    }
253
254    #[inline]
257    #[must_use]
258    pub fn from_euler(order: EulerRot, a: f64, b: f64, c: f64) -> Self {
259        Self::from_euler_angles(order, a, b, c)
260    }
261
262    #[inline]
271    #[must_use]
272    pub fn to_euler(&self, order: EulerRot) -> (f64, f64, f64) {
273        glam_assert!(
274            self.x_axis.is_normalized()
275                && self.y_axis.is_normalized()
276                && self.z_axis.is_normalized()
277        );
278        self.to_euler_angles(order)
279    }
280
281    #[inline]
283    #[must_use]
284    pub fn from_rotation_x(angle: f64) -> Self {
285        let (sina, cosa) = math::sin_cos(angle);
286        Self::from_cols(
287            DVec3::X,
288            DVec3::new(0.0, cosa, sina),
289            DVec3::new(0.0, -sina, cosa),
290        )
291    }
292
293    #[inline]
295    #[must_use]
296    pub fn from_rotation_y(angle: f64) -> Self {
297        let (sina, cosa) = math::sin_cos(angle);
298        Self::from_cols(
299            DVec3::new(cosa, 0.0, -sina),
300            DVec3::Y,
301            DVec3::new(sina, 0.0, cosa),
302        )
303    }
304
305    #[inline]
307    #[must_use]
308    pub fn from_rotation_z(angle: f64) -> Self {
309        let (sina, cosa) = math::sin_cos(angle);
310        Self::from_cols(
311            DVec3::new(cosa, sina, 0.0),
312            DVec3::new(-sina, cosa, 0.0),
313            DVec3::Z,
314        )
315    }
316
317    #[inline]
322    #[must_use]
323    pub fn from_translation(translation: DVec2) -> Self {
324        Self::from_cols(
325            DVec3::X,
326            DVec3::Y,
327            DVec3::new(translation.x, translation.y, 1.0),
328        )
329    }
330
331    #[inline]
337    #[must_use]
338    pub fn from_angle(angle: f64) -> Self {
339        let (sin, cos) = math::sin_cos(angle);
340        Self::from_cols(
341            DVec3::new(cos, sin, 0.0),
342            DVec3::new(-sin, cos, 0.0),
343            DVec3::Z,
344        )
345    }
346
347    #[inline]
353    #[must_use]
354    pub fn from_scale_angle_translation(scale: DVec2, angle: f64, translation: DVec2) -> Self {
355        let (sin, cos) = math::sin_cos(angle);
356        Self::from_cols(
357            DVec3::new(cos * scale.x, sin * scale.x, 0.0),
358            DVec3::new(-sin * scale.y, cos * scale.y, 0.0),
359            DVec3::new(translation.x, translation.y, 1.0),
360        )
361    }
362
363    #[inline]
372    #[must_use]
373    pub fn from_scale(scale: DVec2) -> Self {
374        glam_assert!(scale.cmpne(DVec2::ZERO).any());
376
377        Self::from_cols(
378            DVec3::new(scale.x, 0.0, 0.0),
379            DVec3::new(0.0, scale.y, 0.0),
380            DVec3::Z,
381        )
382    }
383
384    #[inline]
389    pub fn from_mat2(m: DMat2) -> Self {
390        Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), DVec3::Z)
391    }
392
393    #[inline]
399    #[must_use]
400    pub const fn from_cols_slice(slice: &[f64]) -> Self {
401        Self::new(
402            slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
403            slice[8],
404        )
405    }
406
407    #[inline]
413    pub fn write_cols_to_slice(self, slice: &mut [f64]) {
414        slice[0] = self.x_axis.x;
415        slice[1] = self.x_axis.y;
416        slice[2] = self.x_axis.z;
417        slice[3] = self.y_axis.x;
418        slice[4] = self.y_axis.y;
419        slice[5] = self.y_axis.z;
420        slice[6] = self.z_axis.x;
421        slice[7] = self.z_axis.y;
422        slice[8] = self.z_axis.z;
423    }
424
425    #[inline]
431    #[must_use]
432    pub fn col(&self, index: usize) -> DVec3 {
433        match index {
434            0 => self.x_axis,
435            1 => self.y_axis,
436            2 => self.z_axis,
437            _ => panic!("index out of bounds"),
438        }
439    }
440
441    #[inline]
447    pub fn col_mut(&mut self, index: usize) -> &mut DVec3 {
448        match index {
449            0 => &mut self.x_axis,
450            1 => &mut self.y_axis,
451            2 => &mut self.z_axis,
452            _ => panic!("index out of bounds"),
453        }
454    }
455
456    #[inline]
462    #[must_use]
463    pub fn row(&self, index: usize) -> DVec3 {
464        match index {
465            0 => DVec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
466            1 => DVec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
467            2 => DVec3::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
468            _ => panic!("index out of bounds"),
469        }
470    }
471
472    #[inline]
475    #[must_use]
476    pub fn is_finite(&self) -> bool {
477        self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
478    }
479
480    #[inline]
482    #[must_use]
483    pub fn is_nan(&self) -> bool {
484        self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
485    }
486
487    #[inline]
489    #[must_use]
490    pub fn transpose(&self) -> Self {
491        Self {
492            x_axis: DVec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
493            y_axis: DVec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
494            z_axis: DVec3::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
495        }
496    }
497
498    #[inline]
500    #[must_use]
501    pub fn determinant(&self) -> f64 {
502        self.z_axis.dot(self.x_axis.cross(self.y_axis))
503    }
504
505    #[inline]
513    #[must_use]
514    pub fn inverse(&self) -> Self {
515        let tmp0 = self.y_axis.cross(self.z_axis);
516        let tmp1 = self.z_axis.cross(self.x_axis);
517        let tmp2 = self.x_axis.cross(self.y_axis);
518        let det = self.z_axis.dot(tmp2);
519        glam_assert!(det != 0.0);
520        let inv_det = DVec3::splat(det.recip());
521        Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose()
522    }
523
524    #[inline]
534    #[must_use]
535    pub fn transform_point2(&self, rhs: DVec2) -> DVec2 {
536        glam_assert!(self.row(2).abs_diff_eq(DVec3::Z, 1e-6));
537        DMat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
538    }
539
540    #[inline]
550    #[must_use]
551    pub fn transform_vector2(&self, rhs: DVec2) -> DVec2 {
552        glam_assert!(self.row(2).abs_diff_eq(DVec3::Z, 1e-6));
553        DMat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
554    }
555
556    #[inline]
564    #[must_use]
565    pub fn look_to_lh(dir: DVec3, up: DVec3) -> Self {
566        Self::look_to_rh(-dir, up)
567    }
568
569    #[inline]
577    #[must_use]
578    pub fn look_to_rh(dir: DVec3, up: DVec3) -> Self {
579        glam_assert!(dir.is_normalized());
580        glam_assert!(up.is_normalized());
581        let f = dir;
582        let s = f.cross(up).normalize();
583        let u = s.cross(f);
584
585        Self::from_cols(
586            DVec3::new(s.x, u.x, -f.x),
587            DVec3::new(s.y, u.y, -f.y),
588            DVec3::new(s.z, u.z, -f.z),
589        )
590    }
591
592    #[inline]
601    #[must_use]
602    pub fn look_at_lh(eye: DVec3, center: DVec3, up: DVec3) -> Self {
603        Self::look_to_lh(center.sub(eye).normalize(), up)
604    }
605
606    #[inline]
615    pub fn look_at_rh(eye: DVec3, center: DVec3, up: DVec3) -> Self {
616        Self::look_to_rh(center.sub(eye).normalize(), up)
617    }
618
619    #[inline]
621    #[must_use]
622    pub fn mul_vec3(&self, rhs: DVec3) -> DVec3 {
623        let mut res = self.x_axis.mul(rhs.x);
624        res = res.add(self.y_axis.mul(rhs.y));
625        res = res.add(self.z_axis.mul(rhs.z));
626        res
627    }
628
629    #[inline]
631    #[must_use]
632    pub fn mul_mat3(&self, rhs: &Self) -> Self {
633        self.mul(rhs)
634    }
635
636    #[inline]
638    #[must_use]
639    pub fn add_mat3(&self, rhs: &Self) -> Self {
640        self.add(rhs)
641    }
642
643    #[inline]
645    #[must_use]
646    pub fn sub_mat3(&self, rhs: &Self) -> Self {
647        self.sub(rhs)
648    }
649
650    #[inline]
652    #[must_use]
653    pub fn mul_scalar(&self, rhs: f64) -> Self {
654        Self::from_cols(
655            self.x_axis.mul(rhs),
656            self.y_axis.mul(rhs),
657            self.z_axis.mul(rhs),
658        )
659    }
660
661    #[inline]
663    #[must_use]
664    pub fn div_scalar(&self, rhs: f64) -> Self {
665        let rhs = DVec3::splat(rhs);
666        Self::from_cols(
667            self.x_axis.div(rhs),
668            self.y_axis.div(rhs),
669            self.z_axis.div(rhs),
670        )
671    }
672
673    #[inline]
683    #[must_use]
684    pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f64) -> bool {
685        self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
686            && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
687            && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
688    }
689
690    #[inline]
692    #[must_use]
693    pub fn abs(&self) -> Self {
694        Self::from_cols(self.x_axis.abs(), self.y_axis.abs(), self.z_axis.abs())
695    }
696
697    #[inline]
698    pub fn as_mat3(&self) -> Mat3 {
699        Mat3::from_cols(
700            self.x_axis.as_vec3(),
701            self.y_axis.as_vec3(),
702            self.z_axis.as_vec3(),
703        )
704    }
705}
706
707impl Default for DMat3 {
708    #[inline]
709    fn default() -> Self {
710        Self::IDENTITY
711    }
712}
713
714impl Add for DMat3 {
715    type Output = Self;
716    #[inline]
717    fn add(self, rhs: Self) -> Self {
718        Self::from_cols(
719            self.x_axis.add(rhs.x_axis),
720            self.y_axis.add(rhs.y_axis),
721            self.z_axis.add(rhs.z_axis),
722        )
723    }
724}
725
726impl Add<&Self> for DMat3 {
727    type Output = Self;
728    #[inline]
729    fn add(self, rhs: &Self) -> Self {
730        self.add(*rhs)
731    }
732}
733
734impl Add<&DMat3> for &DMat3 {
735    type Output = DMat3;
736    #[inline]
737    fn add(self, rhs: &DMat3) -> DMat3 {
738        (*self).add(*rhs)
739    }
740}
741
742impl Add<DMat3> for &DMat3 {
743    type Output = DMat3;
744    #[inline]
745    fn add(self, rhs: DMat3) -> DMat3 {
746        (*self).add(rhs)
747    }
748}
749
750impl AddAssign for DMat3 {
751    #[inline]
752    fn add_assign(&mut self, rhs: Self) {
753        *self = self.add(rhs);
754    }
755}
756
757impl AddAssign<&Self> for DMat3 {
758    #[inline]
759    fn add_assign(&mut self, rhs: &Self) {
760        self.add_assign(*rhs);
761    }
762}
763
764impl Sub for DMat3 {
765    type Output = Self;
766    #[inline]
767    fn sub(self, rhs: Self) -> Self {
768        Self::from_cols(
769            self.x_axis.sub(rhs.x_axis),
770            self.y_axis.sub(rhs.y_axis),
771            self.z_axis.sub(rhs.z_axis),
772        )
773    }
774}
775
776impl Sub<&Self> for DMat3 {
777    type Output = Self;
778    #[inline]
779    fn sub(self, rhs: &Self) -> Self {
780        self.sub(*rhs)
781    }
782}
783
784impl Sub<&DMat3> for &DMat3 {
785    type Output = DMat3;
786    #[inline]
787    fn sub(self, rhs: &DMat3) -> DMat3 {
788        (*self).sub(*rhs)
789    }
790}
791
792impl Sub<DMat3> for &DMat3 {
793    type Output = DMat3;
794    #[inline]
795    fn sub(self, rhs: DMat3) -> DMat3 {
796        (*self).sub(rhs)
797    }
798}
799
800impl SubAssign for DMat3 {
801    #[inline]
802    fn sub_assign(&mut self, rhs: Self) {
803        *self = self.sub(rhs);
804    }
805}
806
807impl SubAssign<&Self> for DMat3 {
808    #[inline]
809    fn sub_assign(&mut self, rhs: &Self) {
810        self.sub_assign(*rhs);
811    }
812}
813
814impl Neg for DMat3 {
815    type Output = Self;
816    #[inline]
817    fn neg(self) -> Self::Output {
818        Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
819    }
820}
821
822impl Neg for &DMat3 {
823    type Output = DMat3;
824    #[inline]
825    fn neg(self) -> DMat3 {
826        (*self).neg()
827    }
828}
829
830impl Mul for DMat3 {
831    type Output = Self;
832    #[inline]
833    fn mul(self, rhs: Self) -> Self {
834        Self::from_cols(
835            self.mul(rhs.x_axis),
836            self.mul(rhs.y_axis),
837            self.mul(rhs.z_axis),
838        )
839    }
840}
841
842impl Mul<&Self> for DMat3 {
843    type Output = Self;
844    #[inline]
845    fn mul(self, rhs: &Self) -> Self {
846        self.mul(*rhs)
847    }
848}
849
850impl Mul<&DMat3> for &DMat3 {
851    type Output = DMat3;
852    #[inline]
853    fn mul(self, rhs: &DMat3) -> DMat3 {
854        (*self).mul(*rhs)
855    }
856}
857
858impl Mul<DMat3> for &DMat3 {
859    type Output = DMat3;
860    #[inline]
861    fn mul(self, rhs: DMat3) -> DMat3 {
862        (*self).mul(rhs)
863    }
864}
865
866impl MulAssign for DMat3 {
867    #[inline]
868    fn mul_assign(&mut self, rhs: Self) {
869        *self = self.mul(rhs);
870    }
871}
872
873impl MulAssign<&Self> for DMat3 {
874    #[inline]
875    fn mul_assign(&mut self, rhs: &Self) {
876        self.mul_assign(*rhs);
877    }
878}
879
880impl Mul<DVec3> for DMat3 {
881    type Output = DVec3;
882    #[inline]
883    fn mul(self, rhs: DVec3) -> Self::Output {
884        self.mul_vec3(rhs)
885    }
886}
887
888impl Mul<&DVec3> for DMat3 {
889    type Output = DVec3;
890    #[inline]
891    fn mul(self, rhs: &DVec3) -> DVec3 {
892        self.mul(*rhs)
893    }
894}
895
896impl Mul<&DVec3> for &DMat3 {
897    type Output = DVec3;
898    #[inline]
899    fn mul(self, rhs: &DVec3) -> DVec3 {
900        (*self).mul(*rhs)
901    }
902}
903
904impl Mul<DVec3> for &DMat3 {
905    type Output = DVec3;
906    #[inline]
907    fn mul(self, rhs: DVec3) -> DVec3 {
908        (*self).mul(rhs)
909    }
910}
911
912impl Mul<DMat3> for f64 {
913    type Output = DMat3;
914    #[inline]
915    fn mul(self, rhs: DMat3) -> Self::Output {
916        rhs.mul_scalar(self)
917    }
918}
919
920impl Mul<&DMat3> for f64 {
921    type Output = DMat3;
922    #[inline]
923    fn mul(self, rhs: &DMat3) -> DMat3 {
924        self.mul(*rhs)
925    }
926}
927
928impl Mul<&DMat3> for &f64 {
929    type Output = DMat3;
930    #[inline]
931    fn mul(self, rhs: &DMat3) -> DMat3 {
932        (*self).mul(*rhs)
933    }
934}
935
936impl Mul<DMat3> for &f64 {
937    type Output = DMat3;
938    #[inline]
939    fn mul(self, rhs: DMat3) -> DMat3 {
940        (*self).mul(rhs)
941    }
942}
943
944impl Mul<f64> for DMat3 {
945    type Output = Self;
946    #[inline]
947    fn mul(self, rhs: f64) -> Self {
948        self.mul_scalar(rhs)
949    }
950}
951
952impl Mul<&f64> for DMat3 {
953    type Output = Self;
954    #[inline]
955    fn mul(self, rhs: &f64) -> Self {
956        self.mul(*rhs)
957    }
958}
959
960impl Mul<&f64> for &DMat3 {
961    type Output = DMat3;
962    #[inline]
963    fn mul(self, rhs: &f64) -> DMat3 {
964        (*self).mul(*rhs)
965    }
966}
967
968impl Mul<f64> for &DMat3 {
969    type Output = DMat3;
970    #[inline]
971    fn mul(self, rhs: f64) -> DMat3 {
972        (*self).mul(rhs)
973    }
974}
975
976impl MulAssign<f64> for DMat3 {
977    #[inline]
978    fn mul_assign(&mut self, rhs: f64) {
979        *self = self.mul(rhs);
980    }
981}
982
983impl MulAssign<&f64> for DMat3 {
984    #[inline]
985    fn mul_assign(&mut self, rhs: &f64) {
986        self.mul_assign(*rhs);
987    }
988}
989
990impl Div<DMat3> for f64 {
991    type Output = DMat3;
992    #[inline]
993    fn div(self, rhs: DMat3) -> Self::Output {
994        rhs.div_scalar(self)
995    }
996}
997
998impl Div<&DMat3> for f64 {
999    type Output = DMat3;
1000    #[inline]
1001    fn div(self, rhs: &DMat3) -> DMat3 {
1002        self.div(*rhs)
1003    }
1004}
1005
1006impl Div<&DMat3> for &f64 {
1007    type Output = DMat3;
1008    #[inline]
1009    fn div(self, rhs: &DMat3) -> DMat3 {
1010        (*self).div(*rhs)
1011    }
1012}
1013
1014impl Div<DMat3> for &f64 {
1015    type Output = DMat3;
1016    #[inline]
1017    fn div(self, rhs: DMat3) -> DMat3 {
1018        (*self).div(rhs)
1019    }
1020}
1021
1022impl Div<f64> for DMat3 {
1023    type Output = Self;
1024    #[inline]
1025    fn div(self, rhs: f64) -> Self {
1026        self.div_scalar(rhs)
1027    }
1028}
1029
1030impl Div<&f64> for DMat3 {
1031    type Output = Self;
1032    #[inline]
1033    fn div(self, rhs: &f64) -> Self {
1034        self.div(*rhs)
1035    }
1036}
1037
1038impl Div<&f64> for &DMat3 {
1039    type Output = DMat3;
1040    #[inline]
1041    fn div(self, rhs: &f64) -> DMat3 {
1042        (*self).div(*rhs)
1043    }
1044}
1045
1046impl Div<f64> for &DMat3 {
1047    type Output = DMat3;
1048    #[inline]
1049    fn div(self, rhs: f64) -> DMat3 {
1050        (*self).div(rhs)
1051    }
1052}
1053
1054impl DivAssign<f64> for DMat3 {
1055    #[inline]
1056    fn div_assign(&mut self, rhs: f64) {
1057        *self = self.div(rhs);
1058    }
1059}
1060
1061impl DivAssign<&f64> for DMat3 {
1062    #[inline]
1063    fn div_assign(&mut self, rhs: &f64) {
1064        self.div_assign(*rhs);
1065    }
1066}
1067
1068impl Sum<Self> for DMat3 {
1069    fn sum<I>(iter: I) -> Self
1070    where
1071        I: Iterator<Item = Self>,
1072    {
1073        iter.fold(Self::ZERO, Self::add)
1074    }
1075}
1076
1077impl<'a> Sum<&'a Self> for DMat3 {
1078    fn sum<I>(iter: I) -> Self
1079    where
1080        I: Iterator<Item = &'a Self>,
1081    {
1082        iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1083    }
1084}
1085
1086impl Product for DMat3 {
1087    fn product<I>(iter: I) -> Self
1088    where
1089        I: Iterator<Item = Self>,
1090    {
1091        iter.fold(Self::IDENTITY, Self::mul)
1092    }
1093}
1094
1095impl<'a> Product<&'a Self> for DMat3 {
1096    fn product<I>(iter: I) -> Self
1097    where
1098        I: Iterator<Item = &'a Self>,
1099    {
1100        iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1101    }
1102}
1103
1104impl PartialEq for DMat3 {
1105    #[inline]
1106    fn eq(&self, rhs: &Self) -> bool {
1107        self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
1108    }
1109}
1110
1111impl AsRef<[f64; 9]> for DMat3 {
1112    #[inline]
1113    fn as_ref(&self) -> &[f64; 9] {
1114        unsafe { &*(self as *const Self as *const [f64; 9]) }
1115    }
1116}
1117
1118impl AsMut<[f64; 9]> for DMat3 {
1119    #[inline]
1120    fn as_mut(&mut self) -> &mut [f64; 9] {
1121        unsafe { &mut *(self as *mut Self as *mut [f64; 9]) }
1122    }
1123}
1124
1125impl fmt::Debug for DMat3 {
1126    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1127        fmt.debug_struct(stringify!(DMat3))
1128            .field("x_axis", &self.x_axis)
1129            .field("y_axis", &self.y_axis)
1130            .field("z_axis", &self.z_axis)
1131            .finish()
1132    }
1133}
1134
1135impl fmt::Display for DMat3 {
1136    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1137        if let Some(p) = f.precision() {
1138            write!(
1139                f,
1140                "[{:.*}, {:.*}, {:.*}]",
1141                p, self.x_axis, p, self.y_axis, p, self.z_axis
1142            )
1143        } else {
1144            write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
1145        }
1146    }
1147}