1use crate::{
4 euler::{FromEuler, ToEuler},
5 f32::math,
6 swizzles::*,
7 DMat3, EulerRot, Mat2, Mat3A, Mat4, Quat, Vec2, Vec3, Vec3A,
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 mat3(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Mat3 {
17 Mat3::from_cols(x_axis, y_axis, z_axis)
18}
19
20#[derive(Clone, Copy)]
45#[repr(C)]
46pub struct Mat3 {
47 pub x_axis: Vec3,
48 pub y_axis: Vec3,
49 pub z_axis: Vec3,
50}
51
52impl Mat3 {
53 pub const ZERO: Self = Self::from_cols(Vec3::ZERO, Vec3::ZERO, Vec3::ZERO);
55
56 pub const IDENTITY: Self = Self::from_cols(Vec3::X, Vec3::Y, Vec3::Z);
58
59 pub const NAN: Self = Self::from_cols(Vec3::NAN, Vec3::NAN, Vec3::NAN);
61
62 #[allow(clippy::too_many_arguments)]
63 #[inline(always)]
64 #[must_use]
65 const fn new(
66 m00: f32,
67 m01: f32,
68 m02: f32,
69 m10: f32,
70 m11: f32,
71 m12: f32,
72 m20: f32,
73 m21: f32,
74 m22: f32,
75 ) -> Self {
76 Self {
77 x_axis: Vec3::new(m00, m01, m02),
78 y_axis: Vec3::new(m10, m11, m12),
79 z_axis: Vec3::new(m20, m21, m22),
80 }
81 }
82
83 #[inline(always)]
85 #[must_use]
86 pub const fn from_cols(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Self {
87 Self {
88 x_axis,
89 y_axis,
90 z_axis,
91 }
92 }
93
94 #[inline]
98 #[must_use]
99 pub const fn from_cols_array(m: &[f32; 9]) -> Self {
100 Self::new(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8])
101 }
102
103 #[inline]
106 #[must_use]
107 pub const fn to_cols_array(&self) -> [f32; 9] {
108 [
109 self.x_axis.x,
110 self.x_axis.y,
111 self.x_axis.z,
112 self.y_axis.x,
113 self.y_axis.y,
114 self.y_axis.z,
115 self.z_axis.x,
116 self.z_axis.y,
117 self.z_axis.z,
118 ]
119 }
120
121 #[inline]
125 #[must_use]
126 pub const fn from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self {
127 Self::from_cols(
128 Vec3::from_array(m[0]),
129 Vec3::from_array(m[1]),
130 Vec3::from_array(m[2]),
131 )
132 }
133
134 #[inline]
137 #[must_use]
138 pub const fn to_cols_array_2d(&self) -> [[f32; 3]; 3] {
139 [
140 self.x_axis.to_array(),
141 self.y_axis.to_array(),
142 self.z_axis.to_array(),
143 ]
144 }
145
146 #[doc(alias = "scale")]
148 #[inline]
149 #[must_use]
150 pub const fn from_diagonal(diagonal: Vec3) -> Self {
151 Self::new(
152 diagonal.x, 0.0, 0.0, 0.0, diagonal.y, 0.0, 0.0, 0.0, diagonal.z,
153 )
154 }
155
156 #[inline]
158 #[must_use]
159 pub fn from_mat4(m: Mat4) -> Self {
160 Self::from_cols(
161 Vec3::from_vec4(m.x_axis),
162 Vec3::from_vec4(m.y_axis),
163 Vec3::from_vec4(m.z_axis),
164 )
165 }
166
167 #[inline]
174 #[must_use]
175 pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self {
176 match (i, j) {
177 (0, 0) => Self::from_cols(m.y_axis.yzw(), m.z_axis.yzw(), m.w_axis.yzw()),
178 (0, 1) => Self::from_cols(m.y_axis.xzw(), m.z_axis.xzw(), m.w_axis.xzw()),
179 (0, 2) => Self::from_cols(m.y_axis.xyw(), m.z_axis.xyw(), m.w_axis.xyw()),
180 (0, 3) => Self::from_cols(m.y_axis.xyz(), m.z_axis.xyz(), m.w_axis.xyz()),
181 (1, 0) => Self::from_cols(m.x_axis.yzw(), m.z_axis.yzw(), m.w_axis.yzw()),
182 (1, 1) => Self::from_cols(m.x_axis.xzw(), m.z_axis.xzw(), m.w_axis.xzw()),
183 (1, 2) => Self::from_cols(m.x_axis.xyw(), m.z_axis.xyw(), m.w_axis.xyw()),
184 (1, 3) => Self::from_cols(m.x_axis.xyz(), m.z_axis.xyz(), m.w_axis.xyz()),
185 (2, 0) => Self::from_cols(m.x_axis.yzw(), m.y_axis.yzw(), m.w_axis.yzw()),
186 (2, 1) => Self::from_cols(m.x_axis.xzw(), m.y_axis.xzw(), m.w_axis.xzw()),
187 (2, 2) => Self::from_cols(m.x_axis.xyw(), m.y_axis.xyw(), m.w_axis.xyw()),
188 (2, 3) => Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.w_axis.xyz()),
189 (3, 0) => Self::from_cols(m.x_axis.yzw(), m.y_axis.yzw(), m.z_axis.yzw()),
190 (3, 1) => Self::from_cols(m.x_axis.xzw(), m.y_axis.xzw(), m.z_axis.xzw()),
191 (3, 2) => Self::from_cols(m.x_axis.xyw(), m.y_axis.xyw(), m.z_axis.xyw()),
192 (3, 3) => Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.z_axis.xyz()),
193 _ => panic!("index out of bounds"),
194 }
195 }
196
197 #[inline]
203 #[must_use]
204 pub fn from_quat(rotation: Quat) -> Self {
205 glam_assert!(rotation.is_normalized());
206
207 let x2 = rotation.x + rotation.x;
208 let y2 = rotation.y + rotation.y;
209 let z2 = rotation.z + rotation.z;
210 let xx = rotation.x * x2;
211 let xy = rotation.x * y2;
212 let xz = rotation.x * z2;
213 let yy = rotation.y * y2;
214 let yz = rotation.y * z2;
215 let zz = rotation.z * z2;
216 let wx = rotation.w * x2;
217 let wy = rotation.w * y2;
218 let wz = rotation.w * z2;
219
220 Self::from_cols(
221 Vec3::new(1.0 - (yy + zz), xy + wz, xz - wy),
222 Vec3::new(xy - wz, 1.0 - (xx + zz), yz + wx),
223 Vec3::new(xz + wy, yz - wx, 1.0 - (xx + yy)),
224 )
225 }
226
227 #[inline]
234 #[must_use]
235 pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
236 glam_assert!(axis.is_normalized());
237
238 let (sin, cos) = math::sin_cos(angle);
239 let (xsin, ysin, zsin) = axis.mul(sin).into();
240 let (x, y, z) = axis.into();
241 let (x2, y2, z2) = axis.mul(axis).into();
242 let omc = 1.0 - cos;
243 let xyomc = x * y * omc;
244 let xzomc = x * z * omc;
245 let yzomc = y * z * omc;
246 Self::from_cols(
247 Vec3::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
248 Vec3::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
249 Vec3::new(xzomc + ysin, yzomc - xsin, z2 * omc + cos),
250 )
251 }
252
253 #[inline]
256 #[must_use]
257 pub fn from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self {
258 Self::from_euler_angles(order, a, b, c)
259 }
260
261 #[inline]
270 #[must_use]
271 pub fn to_euler(&self, order: EulerRot) -> (f32, f32, f32) {
272 glam_assert!(
273 self.x_axis.is_normalized()
274 && self.y_axis.is_normalized()
275 && self.z_axis.is_normalized()
276 );
277 self.to_euler_angles(order)
278 }
279
280 #[inline]
282 #[must_use]
283 pub fn from_rotation_x(angle: f32) -> Self {
284 let (sina, cosa) = math::sin_cos(angle);
285 Self::from_cols(
286 Vec3::X,
287 Vec3::new(0.0, cosa, sina),
288 Vec3::new(0.0, -sina, cosa),
289 )
290 }
291
292 #[inline]
294 #[must_use]
295 pub fn from_rotation_y(angle: f32) -> Self {
296 let (sina, cosa) = math::sin_cos(angle);
297 Self::from_cols(
298 Vec3::new(cosa, 0.0, -sina),
299 Vec3::Y,
300 Vec3::new(sina, 0.0, cosa),
301 )
302 }
303
304 #[inline]
306 #[must_use]
307 pub fn from_rotation_z(angle: f32) -> Self {
308 let (sina, cosa) = math::sin_cos(angle);
309 Self::from_cols(
310 Vec3::new(cosa, sina, 0.0),
311 Vec3::new(-sina, cosa, 0.0),
312 Vec3::Z,
313 )
314 }
315
316 #[inline]
321 #[must_use]
322 pub fn from_translation(translation: Vec2) -> Self {
323 Self::from_cols(
324 Vec3::X,
325 Vec3::Y,
326 Vec3::new(translation.x, translation.y, 1.0),
327 )
328 }
329
330 #[inline]
336 #[must_use]
337 pub fn from_angle(angle: f32) -> Self {
338 let (sin, cos) = math::sin_cos(angle);
339 Self::from_cols(Vec3::new(cos, sin, 0.0), Vec3::new(-sin, cos, 0.0), Vec3::Z)
340 }
341
342 #[inline]
348 #[must_use]
349 pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
350 let (sin, cos) = math::sin_cos(angle);
351 Self::from_cols(
352 Vec3::new(cos * scale.x, sin * scale.x, 0.0),
353 Vec3::new(-sin * scale.y, cos * scale.y, 0.0),
354 Vec3::new(translation.x, translation.y, 1.0),
355 )
356 }
357
358 #[inline]
367 #[must_use]
368 pub fn from_scale(scale: Vec2) -> Self {
369 glam_assert!(scale.cmpne(Vec2::ZERO).any());
371
372 Self::from_cols(
373 Vec3::new(scale.x, 0.0, 0.0),
374 Vec3::new(0.0, scale.y, 0.0),
375 Vec3::Z,
376 )
377 }
378
379 #[inline]
384 pub fn from_mat2(m: Mat2) -> Self {
385 Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), Vec3::Z)
386 }
387
388 #[inline]
394 #[must_use]
395 pub const fn from_cols_slice(slice: &[f32]) -> Self {
396 Self::new(
397 slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
398 slice[8],
399 )
400 }
401
402 #[inline]
408 pub fn write_cols_to_slice(self, slice: &mut [f32]) {
409 slice[0] = self.x_axis.x;
410 slice[1] = self.x_axis.y;
411 slice[2] = self.x_axis.z;
412 slice[3] = self.y_axis.x;
413 slice[4] = self.y_axis.y;
414 slice[5] = self.y_axis.z;
415 slice[6] = self.z_axis.x;
416 slice[7] = self.z_axis.y;
417 slice[8] = self.z_axis.z;
418 }
419
420 #[inline]
426 #[must_use]
427 pub fn col(&self, index: usize) -> Vec3 {
428 match index {
429 0 => self.x_axis,
430 1 => self.y_axis,
431 2 => self.z_axis,
432 _ => panic!("index out of bounds"),
433 }
434 }
435
436 #[inline]
442 pub fn col_mut(&mut self, index: usize) -> &mut Vec3 {
443 match index {
444 0 => &mut self.x_axis,
445 1 => &mut self.y_axis,
446 2 => &mut self.z_axis,
447 _ => panic!("index out of bounds"),
448 }
449 }
450
451 #[inline]
457 #[must_use]
458 pub fn row(&self, index: usize) -> Vec3 {
459 match index {
460 0 => Vec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
461 1 => Vec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
462 2 => Vec3::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
463 _ => panic!("index out of bounds"),
464 }
465 }
466
467 #[inline]
470 #[must_use]
471 pub fn is_finite(&self) -> bool {
472 self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
473 }
474
475 #[inline]
477 #[must_use]
478 pub fn is_nan(&self) -> bool {
479 self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
480 }
481
482 #[inline]
484 #[must_use]
485 pub fn transpose(&self) -> Self {
486 Self {
487 x_axis: Vec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
488 y_axis: Vec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
489 z_axis: Vec3::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
490 }
491 }
492
493 #[inline]
495 #[must_use]
496 pub fn determinant(&self) -> f32 {
497 self.z_axis.dot(self.x_axis.cross(self.y_axis))
498 }
499
500 #[inline]
508 #[must_use]
509 pub fn inverse(&self) -> Self {
510 let tmp0 = self.y_axis.cross(self.z_axis);
511 let tmp1 = self.z_axis.cross(self.x_axis);
512 let tmp2 = self.x_axis.cross(self.y_axis);
513 let det = self.z_axis.dot(tmp2);
514 glam_assert!(det != 0.0);
515 let inv_det = Vec3::splat(det.recip());
516 Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose()
517 }
518
519 #[inline]
529 #[must_use]
530 pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
531 glam_assert!(self.row(2).abs_diff_eq(Vec3::Z, 1e-6));
532 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
533 }
534
535 #[inline]
545 #[must_use]
546 pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
547 glam_assert!(self.row(2).abs_diff_eq(Vec3::Z, 1e-6));
548 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
549 }
550
551 #[inline]
559 #[must_use]
560 pub fn look_to_lh(dir: Vec3, up: Vec3) -> Self {
561 Self::look_to_rh(-dir, up)
562 }
563
564 #[inline]
572 #[must_use]
573 pub fn look_to_rh(dir: Vec3, up: Vec3) -> Self {
574 glam_assert!(dir.is_normalized());
575 glam_assert!(up.is_normalized());
576 let f = dir;
577 let s = f.cross(up).normalize();
578 let u = s.cross(f);
579
580 Self::from_cols(
581 Vec3::new(s.x, u.x, -f.x),
582 Vec3::new(s.y, u.y, -f.y),
583 Vec3::new(s.z, u.z, -f.z),
584 )
585 }
586
587 #[inline]
596 #[must_use]
597 pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
598 Self::look_to_lh(center.sub(eye).normalize(), up)
599 }
600
601 #[inline]
610 pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
611 Self::look_to_rh(center.sub(eye).normalize(), up)
612 }
613
614 #[inline]
616 #[must_use]
617 pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
618 let mut res = self.x_axis.mul(rhs.x);
619 res = res.add(self.y_axis.mul(rhs.y));
620 res = res.add(self.z_axis.mul(rhs.z));
621 res
622 }
623
624 #[inline]
626 #[must_use]
627 pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
628 self.mul_vec3(rhs.into()).into()
629 }
630
631 #[inline]
633 #[must_use]
634 pub fn mul_mat3(&self, rhs: &Self) -> Self {
635 Self::from_cols(
636 self.mul(rhs.x_axis),
637 self.mul(rhs.y_axis),
638 self.mul(rhs.z_axis),
639 )
640 }
641
642 #[inline]
644 #[must_use]
645 pub fn add_mat3(&self, rhs: &Self) -> Self {
646 Self::from_cols(
647 self.x_axis.add(rhs.x_axis),
648 self.y_axis.add(rhs.y_axis),
649 self.z_axis.add(rhs.z_axis),
650 )
651 }
652
653 #[inline]
655 #[must_use]
656 pub fn sub_mat3(&self, rhs: &Self) -> Self {
657 Self::from_cols(
658 self.x_axis.sub(rhs.x_axis),
659 self.y_axis.sub(rhs.y_axis),
660 self.z_axis.sub(rhs.z_axis),
661 )
662 }
663
664 #[inline]
666 #[must_use]
667 pub fn mul_scalar(&self, rhs: f32) -> Self {
668 Self::from_cols(
669 self.x_axis.mul(rhs),
670 self.y_axis.mul(rhs),
671 self.z_axis.mul(rhs),
672 )
673 }
674
675 #[inline]
677 #[must_use]
678 pub fn div_scalar(&self, rhs: f32) -> Self {
679 let rhs = Vec3::splat(rhs);
680 Self::from_cols(
681 self.x_axis.div(rhs),
682 self.y_axis.div(rhs),
683 self.z_axis.div(rhs),
684 )
685 }
686
687 #[inline]
697 #[must_use]
698 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
699 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
700 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
701 && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
702 }
703
704 #[inline]
706 #[must_use]
707 pub fn abs(&self) -> Self {
708 Self::from_cols(self.x_axis.abs(), self.y_axis.abs(), self.z_axis.abs())
709 }
710
711 #[inline]
712 pub fn as_dmat3(&self) -> DMat3 {
713 DMat3::from_cols(
714 self.x_axis.as_dvec3(),
715 self.y_axis.as_dvec3(),
716 self.z_axis.as_dvec3(),
717 )
718 }
719}
720
721impl Default for Mat3 {
722 #[inline]
723 fn default() -> Self {
724 Self::IDENTITY
725 }
726}
727
728impl Add<Mat3> for Mat3 {
729 type Output = Self;
730 #[inline]
731 fn add(self, rhs: Self) -> Self::Output {
732 self.add_mat3(&rhs)
733 }
734}
735
736impl AddAssign<Mat3> for Mat3 {
737 #[inline]
738 fn add_assign(&mut self, rhs: Self) {
739 *self = self.add_mat3(&rhs);
740 }
741}
742
743impl Sub<Mat3> for Mat3 {
744 type Output = Self;
745 #[inline]
746 fn sub(self, rhs: Self) -> Self::Output {
747 self.sub_mat3(&rhs)
748 }
749}
750
751impl SubAssign<Mat3> for Mat3 {
752 #[inline]
753 fn sub_assign(&mut self, rhs: Self) {
754 *self = self.sub_mat3(&rhs);
755 }
756}
757
758impl Neg for Mat3 {
759 type Output = Self;
760 #[inline]
761 fn neg(self) -> Self::Output {
762 Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
763 }
764}
765
766impl Mul<Mat3> for Mat3 {
767 type Output = Self;
768 #[inline]
769 fn mul(self, rhs: Self) -> Self::Output {
770 self.mul_mat3(&rhs)
771 }
772}
773
774impl MulAssign<Mat3> for Mat3 {
775 #[inline]
776 fn mul_assign(&mut self, rhs: Self) {
777 *self = self.mul_mat3(&rhs);
778 }
779}
780
781impl Mul<Vec3> for Mat3 {
782 type Output = Vec3;
783 #[inline]
784 fn mul(self, rhs: Vec3) -> Self::Output {
785 self.mul_vec3(rhs)
786 }
787}
788
789impl Mul<Mat3> for f32 {
790 type Output = Mat3;
791 #[inline]
792 fn mul(self, rhs: Mat3) -> Self::Output {
793 rhs.mul_scalar(self)
794 }
795}
796
797impl Mul<f32> for Mat3 {
798 type Output = Self;
799 #[inline]
800 fn mul(self, rhs: f32) -> Self::Output {
801 self.mul_scalar(rhs)
802 }
803}
804
805impl MulAssign<f32> for Mat3 {
806 #[inline]
807 fn mul_assign(&mut self, rhs: f32) {
808 *self = self.mul_scalar(rhs);
809 }
810}
811
812impl Div<Mat3> for f32 {
813 type Output = Mat3;
814 #[inline]
815 fn div(self, rhs: Mat3) -> Self::Output {
816 rhs.div_scalar(self)
817 }
818}
819
820impl Div<f32> for Mat3 {
821 type Output = Self;
822 #[inline]
823 fn div(self, rhs: f32) -> Self::Output {
824 self.div_scalar(rhs)
825 }
826}
827
828impl DivAssign<f32> for Mat3 {
829 #[inline]
830 fn div_assign(&mut self, rhs: f32) {
831 *self = self.div_scalar(rhs);
832 }
833}
834
835impl Mul<Vec3A> for Mat3 {
836 type Output = Vec3A;
837 #[inline]
838 fn mul(self, rhs: Vec3A) -> Vec3A {
839 self.mul_vec3a(rhs)
840 }
841}
842
843impl From<Mat3A> for Mat3 {
844 #[inline]
845 fn from(m: Mat3A) -> Self {
846 Self {
847 x_axis: m.x_axis.into(),
848 y_axis: m.y_axis.into(),
849 z_axis: m.z_axis.into(),
850 }
851 }
852}
853
854impl Sum<Self> for Mat3 {
855 fn sum<I>(iter: I) -> Self
856 where
857 I: Iterator<Item = Self>,
858 {
859 iter.fold(Self::ZERO, Self::add)
860 }
861}
862
863impl<'a> Sum<&'a Self> for Mat3 {
864 fn sum<I>(iter: I) -> Self
865 where
866 I: Iterator<Item = &'a Self>,
867 {
868 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
869 }
870}
871
872impl Product for Mat3 {
873 fn product<I>(iter: I) -> Self
874 where
875 I: Iterator<Item = Self>,
876 {
877 iter.fold(Self::IDENTITY, Self::mul)
878 }
879}
880
881impl<'a> Product<&'a Self> for Mat3 {
882 fn product<I>(iter: I) -> Self
883 where
884 I: Iterator<Item = &'a Self>,
885 {
886 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
887 }
888}
889
890impl PartialEq for Mat3 {
891 #[inline]
892 fn eq(&self, rhs: &Self) -> bool {
893 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
894 }
895}
896
897#[cfg(not(target_arch = "spirv"))]
898impl AsRef<[f32; 9]> for Mat3 {
899 #[inline]
900 fn as_ref(&self) -> &[f32; 9] {
901 unsafe { &*(self as *const Self as *const [f32; 9]) }
902 }
903}
904
905#[cfg(not(target_arch = "spirv"))]
906impl AsMut<[f32; 9]> for Mat3 {
907 #[inline]
908 fn as_mut(&mut self) -> &mut [f32; 9] {
909 unsafe { &mut *(self as *mut Self as *mut [f32; 9]) }
910 }
911}
912
913impl fmt::Debug for Mat3 {
914 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
915 fmt.debug_struct(stringify!(Mat3))
916 .field("x_axis", &self.x_axis)
917 .field("y_axis", &self.y_axis)
918 .field("z_axis", &self.z_axis)
919 .finish()
920 }
921}
922
923impl fmt::Display for Mat3 {
924 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
925 if let Some(p) = f.precision() {
926 write!(
927 f,
928 "[{:.*}, {:.*}, {:.*}]",
929 p, self.x_axis, p, self.y_axis, p, self.z_axis
930 )
931 } else {
932 write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
933 }
934 }
935}