1 // Generated from mat.rs.tera template. Edit the template, not the generated file.
2 
3 use crate::{f32::math, swizzles::*, DMat3, EulerRot, Mat2, Mat3A, Mat4, Quat, Vec2, Vec3, Vec3A};
4 #[cfg(not(target_arch = "spirv"))]
5 use core::fmt;
6 use core::iter::{Product, Sum};
7 use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
8 
9 /// Creates a 3x3 matrix from three column vectors.
10 #[inline(always)]
11 #[must_use]
mat3(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Mat312 pub const fn mat3(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Mat3 {
13     Mat3::from_cols(x_axis, y_axis, z_axis)
14 }
15 
16 /// A 3x3 column major matrix.
17 ///
18 /// This 3x3 matrix type features convenience methods for creating and using linear and
19 /// affine transformations. If you are primarily dealing with 2D affine transformations the
20 /// [`Affine2`](crate::Affine2) type is much faster and more space efficient than
21 /// using a 3x3 matrix.
22 ///
23 /// Linear transformations including 3D rotation and scale can be created using methods
24 /// such as [`Self::from_diagonal()`], [`Self::from_quat()`], [`Self::from_axis_angle()`],
25 /// [`Self::from_rotation_x()`], [`Self::from_rotation_y()`], or
26 /// [`Self::from_rotation_z()`].
27 ///
28 /// The resulting matrices can be use to transform 3D vectors using regular vector
29 /// multiplication.
30 ///
31 /// Affine transformations including 2D translation, rotation and scale can be created
32 /// using methods such as [`Self::from_translation()`], [`Self::from_angle()`],
33 /// [`Self::from_scale()`] and [`Self::from_scale_angle_translation()`].
34 ///
35 /// The [`Self::transform_point2()`] and [`Self::transform_vector2()`] convenience methods
36 /// are provided for performing affine transforms on 2D vectors and points. These multiply
37 /// 2D inputs as 3D vectors with an implicit `z` value of `1` for points and `0` for
38 /// vectors respectively. These methods assume that `Self` contains a valid affine
39 /// transform.
40 #[derive(Clone, Copy)]
41 #[repr(C)]
42 pub struct Mat3 {
43     pub x_axis: Vec3,
44     pub y_axis: Vec3,
45     pub z_axis: Vec3,
46 }
47 
48 impl Mat3 {
49     /// A 3x3 matrix with all elements set to `0.0`.
50     pub const ZERO: Self = Self::from_cols(Vec3::ZERO, Vec3::ZERO, Vec3::ZERO);
51 
52     /// A 3x3 identity matrix, where all diagonal elements are `1`, and all off-diagonal elements are `0`.
53     pub const IDENTITY: Self = Self::from_cols(Vec3::X, Vec3::Y, Vec3::Z);
54 
55     /// All NAN:s.
56     pub const NAN: Self = Self::from_cols(Vec3::NAN, Vec3::NAN, Vec3::NAN);
57 
58     #[allow(clippy::too_many_arguments)]
59     #[inline(always)]
60     #[must_use]
new( m00: f32, m01: f32, m02: f32, m10: f32, m11: f32, m12: f32, m20: f32, m21: f32, m22: f32, ) -> Self61     const fn new(
62         m00: f32,
63         m01: f32,
64         m02: f32,
65         m10: f32,
66         m11: f32,
67         m12: f32,
68         m20: f32,
69         m21: f32,
70         m22: f32,
71     ) -> Self {
72         Self {
73             x_axis: Vec3::new(m00, m01, m02),
74             y_axis: Vec3::new(m10, m11, m12),
75             z_axis: Vec3::new(m20, m21, m22),
76         }
77     }
78 
79     /// Creates a 3x3 matrix from three column vectors.
80     #[inline(always)]
81     #[must_use]
from_cols(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Self82     pub const fn from_cols(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Self {
83         Self {
84             x_axis,
85             y_axis,
86             z_axis,
87         }
88     }
89 
90     /// Creates a 3x3 matrix from a `[f32; 9]` array stored in column major order.
91     /// If your data is stored in row major you will need to `transpose` the returned
92     /// matrix.
93     #[inline]
94     #[must_use]
from_cols_array(m: &[f32; 9]) -> Self95     pub const fn from_cols_array(m: &[f32; 9]) -> Self {
96         Self::new(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8])
97     }
98 
99     /// Creates a `[f32; 9]` array storing data in column major order.
100     /// If you require data in row major order `transpose` the matrix first.
101     #[inline]
102     #[must_use]
to_cols_array(&self) -> [f32; 9]103     pub const fn to_cols_array(&self) -> [f32; 9] {
104         [
105             self.x_axis.x,
106             self.x_axis.y,
107             self.x_axis.z,
108             self.y_axis.x,
109             self.y_axis.y,
110             self.y_axis.z,
111             self.z_axis.x,
112             self.z_axis.y,
113             self.z_axis.z,
114         ]
115     }
116 
117     /// Creates a 3x3 matrix from a `[[f32; 3]; 3]` 3D array stored in column major order.
118     /// If your data is in row major order you will need to `transpose` the returned
119     /// matrix.
120     #[inline]
121     #[must_use]
from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self122     pub const fn from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self {
123         Self::from_cols(
124             Vec3::from_array(m[0]),
125             Vec3::from_array(m[1]),
126             Vec3::from_array(m[2]),
127         )
128     }
129 
130     /// Creates a `[[f32; 3]; 3]` 3D array storing data in column major order.
131     /// If you require data in row major order `transpose` the matrix first.
132     #[inline]
133     #[must_use]
to_cols_array_2d(&self) -> [[f32; 3]; 3]134     pub const fn to_cols_array_2d(&self) -> [[f32; 3]; 3] {
135         [
136             self.x_axis.to_array(),
137             self.y_axis.to_array(),
138             self.z_axis.to_array(),
139         ]
140     }
141 
142     /// Creates a 3x3 matrix with its diagonal set to `diagonal` and all other entries set to 0.
143     #[doc(alias = "scale")]
144     #[inline]
145     #[must_use]
from_diagonal(diagonal: Vec3) -> Self146     pub const fn from_diagonal(diagonal: Vec3) -> Self {
147         Self::new(
148             diagonal.x, 0.0, 0.0, 0.0, diagonal.y, 0.0, 0.0, 0.0, diagonal.z,
149         )
150     }
151 
152     /// Creates a 3x3 matrix from a 4x4 matrix, discarding the 4th row and column.
153     #[inline]
154     #[must_use]
from_mat4(m: Mat4) -> Self155     pub fn from_mat4(m: Mat4) -> Self {
156         Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.z_axis.xyz())
157     }
158 
159     /// Creates a 3D rotation matrix from the given quaternion.
160     ///
161     /// # Panics
162     ///
163     /// Will panic if `rotation` is not normalized when `glam_assert` is enabled.
164     #[inline]
165     #[must_use]
from_quat(rotation: Quat) -> Self166     pub fn from_quat(rotation: Quat) -> Self {
167         glam_assert!(rotation.is_normalized());
168 
169         let x2 = rotation.x + rotation.x;
170         let y2 = rotation.y + rotation.y;
171         let z2 = rotation.z + rotation.z;
172         let xx = rotation.x * x2;
173         let xy = rotation.x * y2;
174         let xz = rotation.x * z2;
175         let yy = rotation.y * y2;
176         let yz = rotation.y * z2;
177         let zz = rotation.z * z2;
178         let wx = rotation.w * x2;
179         let wy = rotation.w * y2;
180         let wz = rotation.w * z2;
181 
182         Self::from_cols(
183             Vec3::new(1.0 - (yy + zz), xy + wz, xz - wy),
184             Vec3::new(xy - wz, 1.0 - (xx + zz), yz + wx),
185             Vec3::new(xz + wy, yz - wx, 1.0 - (xx + yy)),
186         )
187     }
188 
189     /// Creates a 3D rotation matrix from a normalized rotation `axis` and `angle` (in
190     /// radians).
191     ///
192     /// # Panics
193     ///
194     /// Will panic if `axis` is not normalized when `glam_assert` is enabled.
195     #[inline]
196     #[must_use]
from_axis_angle(axis: Vec3, angle: f32) -> Self197     pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
198         glam_assert!(axis.is_normalized());
199 
200         let (sin, cos) = math::sin_cos(angle);
201         let (xsin, ysin, zsin) = axis.mul(sin).into();
202         let (x, y, z) = axis.into();
203         let (x2, y2, z2) = axis.mul(axis).into();
204         let omc = 1.0 - cos;
205         let xyomc = x * y * omc;
206         let xzomc = x * z * omc;
207         let yzomc = y * z * omc;
208         Self::from_cols(
209             Vec3::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
210             Vec3::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
211             Vec3::new(xzomc + ysin, yzomc - xsin, z2 * omc + cos),
212         )
213     }
214 
215     /// Creates a 3D rotation matrix from the given euler rotation sequence and the angles (in
216     /// radians).
217     #[inline]
218     #[must_use]
from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self219     pub fn from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self {
220         let quat = Quat::from_euler(order, a, b, c);
221         Self::from_quat(quat)
222     }
223 
224     /// Creates a 3D rotation matrix from `angle` (in radians) around the x axis.
225     #[inline]
226     #[must_use]
from_rotation_x(angle: f32) -> Self227     pub fn from_rotation_x(angle: f32) -> Self {
228         let (sina, cosa) = math::sin_cos(angle);
229         Self::from_cols(
230             Vec3::X,
231             Vec3::new(0.0, cosa, sina),
232             Vec3::new(0.0, -sina, cosa),
233         )
234     }
235 
236     /// Creates a 3D rotation matrix from `angle` (in radians) around the y axis.
237     #[inline]
238     #[must_use]
from_rotation_y(angle: f32) -> Self239     pub fn from_rotation_y(angle: f32) -> Self {
240         let (sina, cosa) = math::sin_cos(angle);
241         Self::from_cols(
242             Vec3::new(cosa, 0.0, -sina),
243             Vec3::Y,
244             Vec3::new(sina, 0.0, cosa),
245         )
246     }
247 
248     /// Creates a 3D rotation matrix from `angle` (in radians) around the z axis.
249     #[inline]
250     #[must_use]
from_rotation_z(angle: f32) -> Self251     pub fn from_rotation_z(angle: f32) -> Self {
252         let (sina, cosa) = math::sin_cos(angle);
253         Self::from_cols(
254             Vec3::new(cosa, sina, 0.0),
255             Vec3::new(-sina, cosa, 0.0),
256             Vec3::Z,
257         )
258     }
259 
260     /// Creates an affine transformation matrix from the given 2D `translation`.
261     ///
262     /// The resulting matrix can be used to transform 2D points and vectors. See
263     /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
264     #[inline]
265     #[must_use]
from_translation(translation: Vec2) -> Self266     pub fn from_translation(translation: Vec2) -> Self {
267         Self::from_cols(
268             Vec3::X,
269             Vec3::Y,
270             Vec3::new(translation.x, translation.y, 1.0),
271         )
272     }
273 
274     /// Creates an affine transformation matrix from the given 2D rotation `angle` (in
275     /// radians).
276     ///
277     /// The resulting matrix can be used to transform 2D points and vectors. See
278     /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
279     #[inline]
280     #[must_use]
from_angle(angle: f32) -> Self281     pub fn from_angle(angle: f32) -> Self {
282         let (sin, cos) = math::sin_cos(angle);
283         Self::from_cols(Vec3::new(cos, sin, 0.0), Vec3::new(-sin, cos, 0.0), Vec3::Z)
284     }
285 
286     /// Creates an affine transformation matrix from the given 2D `scale`, rotation `angle` (in
287     /// radians) and `translation`.
288     ///
289     /// The resulting matrix can be used to transform 2D points and vectors. See
290     /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
291     #[inline]
292     #[must_use]
from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self293     pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
294         let (sin, cos) = math::sin_cos(angle);
295         Self::from_cols(
296             Vec3::new(cos * scale.x, sin * scale.x, 0.0),
297             Vec3::new(-sin * scale.y, cos * scale.y, 0.0),
298             Vec3::new(translation.x, translation.y, 1.0),
299         )
300     }
301 
302     /// Creates an affine transformation matrix from the given non-uniform 2D `scale`.
303     ///
304     /// The resulting matrix can be used to transform 2D points and vectors. See
305     /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
306     ///
307     /// # Panics
308     ///
309     /// Will panic if all elements of `scale` are zero when `glam_assert` is enabled.
310     #[inline]
311     #[must_use]
from_scale(scale: Vec2) -> Self312     pub fn from_scale(scale: Vec2) -> Self {
313         // Do not panic as long as any component is non-zero
314         glam_assert!(scale.cmpne(Vec2::ZERO).any());
315 
316         Self::from_cols(
317             Vec3::new(scale.x, 0.0, 0.0),
318             Vec3::new(0.0, scale.y, 0.0),
319             Vec3::Z,
320         )
321     }
322 
323     /// Creates an affine transformation matrix from the given 2x2 matrix.
324     ///
325     /// The resulting matrix can be used to transform 2D points and vectors. See
326     /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
327     #[inline]
from_mat2(m: Mat2) -> Self328     pub fn from_mat2(m: Mat2) -> Self {
329         Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), Vec3::Z)
330     }
331 
332     /// Creates a 3x3 matrix from the first 9 values in `slice`.
333     ///
334     /// # Panics
335     ///
336     /// Panics if `slice` is less than 9 elements long.
337     #[inline]
338     #[must_use]
from_cols_slice(slice: &[f32]) -> Self339     pub const fn from_cols_slice(slice: &[f32]) -> Self {
340         Self::new(
341             slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
342             slice[8],
343         )
344     }
345 
346     /// Writes the columns of `self` to the first 9 elements in `slice`.
347     ///
348     /// # Panics
349     ///
350     /// Panics if `slice` is less than 9 elements long.
351     #[inline]
write_cols_to_slice(self, slice: &mut [f32])352     pub fn write_cols_to_slice(self, slice: &mut [f32]) {
353         slice[0] = self.x_axis.x;
354         slice[1] = self.x_axis.y;
355         slice[2] = self.x_axis.z;
356         slice[3] = self.y_axis.x;
357         slice[4] = self.y_axis.y;
358         slice[5] = self.y_axis.z;
359         slice[6] = self.z_axis.x;
360         slice[7] = self.z_axis.y;
361         slice[8] = self.z_axis.z;
362     }
363 
364     /// Returns the matrix column for the given `index`.
365     ///
366     /// # Panics
367     ///
368     /// Panics if `index` is greater than 2.
369     #[inline]
370     #[must_use]
col(&self, index: usize) -> Vec3371     pub fn col(&self, index: usize) -> Vec3 {
372         match index {
373             0 => self.x_axis,
374             1 => self.y_axis,
375             2 => self.z_axis,
376             _ => panic!("index out of bounds"),
377         }
378     }
379 
380     /// Returns a mutable reference to the matrix column for the given `index`.
381     ///
382     /// # Panics
383     ///
384     /// Panics if `index` is greater than 2.
385     #[inline]
col_mut(&mut self, index: usize) -> &mut Vec3386     pub fn col_mut(&mut self, index: usize) -> &mut Vec3 {
387         match index {
388             0 => &mut self.x_axis,
389             1 => &mut self.y_axis,
390             2 => &mut self.z_axis,
391             _ => panic!("index out of bounds"),
392         }
393     }
394 
395     /// Returns the matrix row for the given `index`.
396     ///
397     /// # Panics
398     ///
399     /// Panics if `index` is greater than 2.
400     #[inline]
401     #[must_use]
row(&self, index: usize) -> Vec3402     pub fn row(&self, index: usize) -> Vec3 {
403         match index {
404             0 => Vec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
405             1 => Vec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
406             2 => Vec3::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
407             _ => panic!("index out of bounds"),
408         }
409     }
410 
411     /// Returns `true` if, and only if, all elements are finite.
412     /// If any element is either `NaN`, positive or negative infinity, this will return `false`.
413     #[inline]
414     #[must_use]
is_finite(&self) -> bool415     pub fn is_finite(&self) -> bool {
416         self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
417     }
418 
419     /// Returns `true` if any elements are `NaN`.
420     #[inline]
421     #[must_use]
is_nan(&self) -> bool422     pub fn is_nan(&self) -> bool {
423         self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
424     }
425 
426     /// Returns the transpose of `self`.
427     #[inline]
428     #[must_use]
transpose(&self) -> Self429     pub fn transpose(&self) -> Self {
430         Self {
431             x_axis: Vec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
432             y_axis: Vec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
433             z_axis: Vec3::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
434         }
435     }
436 
437     /// Returns the determinant of `self`.
438     #[inline]
439     #[must_use]
determinant(&self) -> f32440     pub fn determinant(&self) -> f32 {
441         self.z_axis.dot(self.x_axis.cross(self.y_axis))
442     }
443 
444     /// Returns the inverse of `self`.
445     ///
446     /// If the matrix is not invertible the returned matrix will be invalid.
447     ///
448     /// # Panics
449     ///
450     /// Will panic if the determinant of `self` is zero when `glam_assert` is enabled.
451     #[inline]
452     #[must_use]
inverse(&self) -> Self453     pub fn inverse(&self) -> Self {
454         let tmp0 = self.y_axis.cross(self.z_axis);
455         let tmp1 = self.z_axis.cross(self.x_axis);
456         let tmp2 = self.x_axis.cross(self.y_axis);
457         let det = self.z_axis.dot(tmp2);
458         glam_assert!(det != 0.0);
459         let inv_det = Vec3::splat(det.recip());
460         Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose()
461     }
462 
463     /// Transforms the given 2D vector as a point.
464     ///
465     /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `1`.
466     ///
467     /// This method assumes that `self` contains a valid affine transform.
468     ///
469     /// # Panics
470     ///
471     /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
472     #[inline]
473     #[must_use]
transform_point2(&self, rhs: Vec2) -> Vec2474     pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
475         glam_assert!(self.row(2).abs_diff_eq(Vec3::Z, 1e-6));
476         Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
477     }
478 
479     /// Rotates the given 2D vector.
480     ///
481     /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `0`.
482     ///
483     /// This method assumes that `self` contains a valid affine transform.
484     ///
485     /// # Panics
486     ///
487     /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
488     #[inline]
489     #[must_use]
transform_vector2(&self, rhs: Vec2) -> Vec2490     pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
491         glam_assert!(self.row(2).abs_diff_eq(Vec3::Z, 1e-6));
492         Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
493     }
494 
495     /// Transforms a 3D vector.
496     #[inline]
497     #[must_use]
mul_vec3(&self, rhs: Vec3) -> Vec3498     pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
499         let mut res = self.x_axis.mul(rhs.x);
500         res = res.add(self.y_axis.mul(rhs.y));
501         res = res.add(self.z_axis.mul(rhs.z));
502         res
503     }
504 
505     /// Transforms a [`Vec3A`].
506     #[inline]
507     #[must_use]
mul_vec3a(&self, rhs: Vec3A) -> Vec3A508     pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
509         self.mul_vec3(rhs.into()).into()
510     }
511 
512     /// Multiplies two 3x3 matrices.
513     #[inline]
514     #[must_use]
mul_mat3(&self, rhs: &Self) -> Self515     pub fn mul_mat3(&self, rhs: &Self) -> Self {
516         Self::from_cols(
517             self.mul(rhs.x_axis),
518             self.mul(rhs.y_axis),
519             self.mul(rhs.z_axis),
520         )
521     }
522 
523     /// Adds two 3x3 matrices.
524     #[inline]
525     #[must_use]
add_mat3(&self, rhs: &Self) -> Self526     pub fn add_mat3(&self, rhs: &Self) -> Self {
527         Self::from_cols(
528             self.x_axis.add(rhs.x_axis),
529             self.y_axis.add(rhs.y_axis),
530             self.z_axis.add(rhs.z_axis),
531         )
532     }
533 
534     /// Subtracts two 3x3 matrices.
535     #[inline]
536     #[must_use]
sub_mat3(&self, rhs: &Self) -> Self537     pub fn sub_mat3(&self, rhs: &Self) -> Self {
538         Self::from_cols(
539             self.x_axis.sub(rhs.x_axis),
540             self.y_axis.sub(rhs.y_axis),
541             self.z_axis.sub(rhs.z_axis),
542         )
543     }
544 
545     /// Multiplies a 3x3 matrix by a scalar.
546     #[inline]
547     #[must_use]
mul_scalar(&self, rhs: f32) -> Self548     pub fn mul_scalar(&self, rhs: f32) -> Self {
549         Self::from_cols(
550             self.x_axis.mul(rhs),
551             self.y_axis.mul(rhs),
552             self.z_axis.mul(rhs),
553         )
554     }
555 
556     /// Returns true if the absolute difference of all elements between `self` and `rhs`
557     /// is less than or equal to `max_abs_diff`.
558     ///
559     /// This can be used to compare if two matrices contain similar elements. It works best
560     /// when comparing with a known value. The `max_abs_diff` that should be used used
561     /// depends on the values being compared against.
562     ///
563     /// For more see
564     /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
565     #[inline]
566     #[must_use]
abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool567     pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
568         self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
569             && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
570             && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
571     }
572 
573     #[inline]
as_dmat3(&self) -> DMat3574     pub fn as_dmat3(&self) -> DMat3 {
575         DMat3::from_cols(
576             self.x_axis.as_dvec3(),
577             self.y_axis.as_dvec3(),
578             self.z_axis.as_dvec3(),
579         )
580     }
581 }
582 
583 impl Default for Mat3 {
584     #[inline]
default() -> Self585     fn default() -> Self {
586         Self::IDENTITY
587     }
588 }
589 
590 impl Add<Mat3> for Mat3 {
591     type Output = Self;
592     #[inline]
add(self, rhs: Self) -> Self::Output593     fn add(self, rhs: Self) -> Self::Output {
594         self.add_mat3(&rhs)
595     }
596 }
597 
598 impl AddAssign<Mat3> for Mat3 {
599     #[inline]
add_assign(&mut self, rhs: Self)600     fn add_assign(&mut self, rhs: Self) {
601         *self = self.add_mat3(&rhs);
602     }
603 }
604 
605 impl Sub<Mat3> for Mat3 {
606     type Output = Self;
607     #[inline]
sub(self, rhs: Self) -> Self::Output608     fn sub(self, rhs: Self) -> Self::Output {
609         self.sub_mat3(&rhs)
610     }
611 }
612 
613 impl SubAssign<Mat3> for Mat3 {
614     #[inline]
sub_assign(&mut self, rhs: Self)615     fn sub_assign(&mut self, rhs: Self) {
616         *self = self.sub_mat3(&rhs);
617     }
618 }
619 
620 impl Neg for Mat3 {
621     type Output = Self;
622     #[inline]
neg(self) -> Self::Output623     fn neg(self) -> Self::Output {
624         Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
625     }
626 }
627 
628 impl Mul<Mat3> for Mat3 {
629     type Output = Self;
630     #[inline]
mul(self, rhs: Self) -> Self::Output631     fn mul(self, rhs: Self) -> Self::Output {
632         self.mul_mat3(&rhs)
633     }
634 }
635 
636 impl MulAssign<Mat3> for Mat3 {
637     #[inline]
mul_assign(&mut self, rhs: Self)638     fn mul_assign(&mut self, rhs: Self) {
639         *self = self.mul_mat3(&rhs);
640     }
641 }
642 
643 impl Mul<Vec3> for Mat3 {
644     type Output = Vec3;
645     #[inline]
mul(self, rhs: Vec3) -> Self::Output646     fn mul(self, rhs: Vec3) -> Self::Output {
647         self.mul_vec3(rhs)
648     }
649 }
650 
651 impl Mul<Mat3> for f32 {
652     type Output = Mat3;
653     #[inline]
mul(self, rhs: Mat3) -> Self::Output654     fn mul(self, rhs: Mat3) -> Self::Output {
655         rhs.mul_scalar(self)
656     }
657 }
658 
659 impl Mul<f32> for Mat3 {
660     type Output = Self;
661     #[inline]
mul(self, rhs: f32) -> Self::Output662     fn mul(self, rhs: f32) -> Self::Output {
663         self.mul_scalar(rhs)
664     }
665 }
666 
667 impl MulAssign<f32> for Mat3 {
668     #[inline]
mul_assign(&mut self, rhs: f32)669     fn mul_assign(&mut self, rhs: f32) {
670         *self = self.mul_scalar(rhs);
671     }
672 }
673 
674 impl Mul<Vec3A> for Mat3 {
675     type Output = Vec3A;
676     #[inline]
mul(self, rhs: Vec3A) -> Vec3A677     fn mul(self, rhs: Vec3A) -> Vec3A {
678         self.mul_vec3a(rhs)
679     }
680 }
681 
682 impl From<Mat3A> for Mat3 {
683     #[inline]
from(m: Mat3A) -> Self684     fn from(m: Mat3A) -> Self {
685         Self {
686             x_axis: m.x_axis.into(),
687             y_axis: m.y_axis.into(),
688             z_axis: m.z_axis.into(),
689         }
690     }
691 }
692 
693 impl Sum<Self> for Mat3 {
sum<I>(iter: I) -> Self where I: Iterator<Item = Self>,694     fn sum<I>(iter: I) -> Self
695     where
696         I: Iterator<Item = Self>,
697     {
698         iter.fold(Self::ZERO, Self::add)
699     }
700 }
701 
702 impl<'a> Sum<&'a Self> for Mat3 {
sum<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,703     fn sum<I>(iter: I) -> Self
704     where
705         I: Iterator<Item = &'a Self>,
706     {
707         iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
708     }
709 }
710 
711 impl Product for Mat3 {
product<I>(iter: I) -> Self where I: Iterator<Item = Self>,712     fn product<I>(iter: I) -> Self
713     where
714         I: Iterator<Item = Self>,
715     {
716         iter.fold(Self::IDENTITY, Self::mul)
717     }
718 }
719 
720 impl<'a> Product<&'a Self> for Mat3 {
product<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,721     fn product<I>(iter: I) -> Self
722     where
723         I: Iterator<Item = &'a Self>,
724     {
725         iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
726     }
727 }
728 
729 impl PartialEq for Mat3 {
730     #[inline]
eq(&self, rhs: &Self) -> bool731     fn eq(&self, rhs: &Self) -> bool {
732         self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
733     }
734 }
735 
736 #[cfg(not(target_arch = "spirv"))]
737 impl AsRef<[f32; 9]> for Mat3 {
738     #[inline]
as_ref(&self) -> &[f32; 9]739     fn as_ref(&self) -> &[f32; 9] {
740         unsafe { &*(self as *const Self as *const [f32; 9]) }
741     }
742 }
743 
744 #[cfg(not(target_arch = "spirv"))]
745 impl AsMut<[f32; 9]> for Mat3 {
746     #[inline]
as_mut(&mut self) -> &mut [f32; 9]747     fn as_mut(&mut self) -> &mut [f32; 9] {
748         unsafe { &mut *(self as *mut Self as *mut [f32; 9]) }
749     }
750 }
751 
752 #[cfg(not(target_arch = "spirv"))]
753 impl fmt::Debug for Mat3 {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result754     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
755         fmt.debug_struct(stringify!(Mat3))
756             .field("x_axis", &self.x_axis)
757             .field("y_axis", &self.y_axis)
758             .field("z_axis", &self.z_axis)
759             .finish()
760     }
761 }
762 
763 #[cfg(not(target_arch = "spirv"))]
764 impl fmt::Display for Mat3 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result765     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
766         write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
767     }
768 }
769