1 // Generated from mat.rs.tera template. Edit the template, not the generated file.
2 
3 use crate::{f32::math, swizzles::*, DMat3, EulerRot, Mat2, Mat3, 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]
mat3a(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Mat3A12 pub const fn mat3a(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Mat3A {
13     Mat3A::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 Mat3A {
43     pub x_axis: Vec3A,
44     pub y_axis: Vec3A,
45     pub z_axis: Vec3A,
46 }
47 
48 impl Mat3A {
49     /// A 3x3 matrix with all elements set to `0.0`.
50     pub const ZERO: Self = Self::from_cols(Vec3A::ZERO, Vec3A::ZERO, Vec3A::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(Vec3A::X, Vec3A::Y, Vec3A::Z);
54 
55     /// All NAN:s.
56     pub const NAN: Self = Self::from_cols(Vec3A::NAN, Vec3A::NAN, Vec3A::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: Vec3A::new(m00, m01, m02),
74             y_axis: Vec3A::new(m10, m11, m12),
75             z_axis: Vec3A::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: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Self82     pub const fn from_cols(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> 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             Vec3A::from_array(m[0]),
125             Vec3A::from_array(m[1]),
126             Vec3A::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.into(), m.y_axis.into(), m.z_axis.into())
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             Vec3A::new(1.0 - (yy + zz), xy + wz, xz - wy),
184             Vec3A::new(xy - wz, 1.0 - (xx + zz), yz + wx),
185             Vec3A::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             Vec3A::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
210             Vec3A::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
211             Vec3A::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             Vec3A::X,
231             Vec3A::new(0.0, cosa, sina),
232             Vec3A::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             Vec3A::new(cosa, 0.0, -sina),
243             Vec3A::Y,
244             Vec3A::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             Vec3A::new(cosa, sina, 0.0),
255             Vec3A::new(-sina, cosa, 0.0),
256             Vec3A::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             Vec3A::X,
269             Vec3A::Y,
270             Vec3A::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(
284             Vec3A::new(cos, sin, 0.0),
285             Vec3A::new(-sin, cos, 0.0),
286             Vec3A::Z,
287         )
288     }
289 
290     /// Creates an affine transformation matrix from the given 2D `scale`, rotation `angle` (in
291     /// radians) and `translation`.
292     ///
293     /// The resulting matrix can be used to transform 2D points and vectors. See
294     /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
295     #[inline]
296     #[must_use]
from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self297     pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
298         let (sin, cos) = math::sin_cos(angle);
299         Self::from_cols(
300             Vec3A::new(cos * scale.x, sin * scale.x, 0.0),
301             Vec3A::new(-sin * scale.y, cos * scale.y, 0.0),
302             Vec3A::new(translation.x, translation.y, 1.0),
303         )
304     }
305 
306     /// Creates an affine transformation matrix from the given non-uniform 2D `scale`.
307     ///
308     /// The resulting matrix can be used to transform 2D points and vectors. See
309     /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
310     ///
311     /// # Panics
312     ///
313     /// Will panic if all elements of `scale` are zero when `glam_assert` is enabled.
314     #[inline]
315     #[must_use]
from_scale(scale: Vec2) -> Self316     pub fn from_scale(scale: Vec2) -> Self {
317         // Do not panic as long as any component is non-zero
318         glam_assert!(scale.cmpne(Vec2::ZERO).any());
319 
320         Self::from_cols(
321             Vec3A::new(scale.x, 0.0, 0.0),
322             Vec3A::new(0.0, scale.y, 0.0),
323             Vec3A::Z,
324         )
325     }
326 
327     /// Creates an affine transformation matrix from the given 2x2 matrix.
328     ///
329     /// The resulting matrix can be used to transform 2D points and vectors. See
330     /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
331     #[inline]
from_mat2(m: Mat2) -> Self332     pub fn from_mat2(m: Mat2) -> Self {
333         Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), Vec3A::Z)
334     }
335 
336     /// Creates a 3x3 matrix from the first 9 values in `slice`.
337     ///
338     /// # Panics
339     ///
340     /// Panics if `slice` is less than 9 elements long.
341     #[inline]
342     #[must_use]
from_cols_slice(slice: &[f32]) -> Self343     pub const fn from_cols_slice(slice: &[f32]) -> Self {
344         Self::new(
345             slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
346             slice[8],
347         )
348     }
349 
350     /// Writes the columns of `self` to the first 9 elements in `slice`.
351     ///
352     /// # Panics
353     ///
354     /// Panics if `slice` is less than 9 elements long.
355     #[inline]
write_cols_to_slice(self, slice: &mut [f32])356     pub fn write_cols_to_slice(self, slice: &mut [f32]) {
357         slice[0] = self.x_axis.x;
358         slice[1] = self.x_axis.y;
359         slice[2] = self.x_axis.z;
360         slice[3] = self.y_axis.x;
361         slice[4] = self.y_axis.y;
362         slice[5] = self.y_axis.z;
363         slice[6] = self.z_axis.x;
364         slice[7] = self.z_axis.y;
365         slice[8] = self.z_axis.z;
366     }
367 
368     /// Returns the matrix column for the given `index`.
369     ///
370     /// # Panics
371     ///
372     /// Panics if `index` is greater than 2.
373     #[inline]
374     #[must_use]
col(&self, index: usize) -> Vec3A375     pub fn col(&self, index: usize) -> Vec3A {
376         match index {
377             0 => self.x_axis,
378             1 => self.y_axis,
379             2 => self.z_axis,
380             _ => panic!("index out of bounds"),
381         }
382     }
383 
384     /// Returns a mutable reference to the matrix column for the given `index`.
385     ///
386     /// # Panics
387     ///
388     /// Panics if `index` is greater than 2.
389     #[inline]
col_mut(&mut self, index: usize) -> &mut Vec3A390     pub fn col_mut(&mut self, index: usize) -> &mut Vec3A {
391         match index {
392             0 => &mut self.x_axis,
393             1 => &mut self.y_axis,
394             2 => &mut self.z_axis,
395             _ => panic!("index out of bounds"),
396         }
397     }
398 
399     /// Returns the matrix row for the given `index`.
400     ///
401     /// # Panics
402     ///
403     /// Panics if `index` is greater than 2.
404     #[inline]
405     #[must_use]
row(&self, index: usize) -> Vec3A406     pub fn row(&self, index: usize) -> Vec3A {
407         match index {
408             0 => Vec3A::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
409             1 => Vec3A::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
410             2 => Vec3A::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
411             _ => panic!("index out of bounds"),
412         }
413     }
414 
415     /// Returns `true` if, and only if, all elements are finite.
416     /// If any element is either `NaN`, positive or negative infinity, this will return `false`.
417     #[inline]
418     #[must_use]
is_finite(&self) -> bool419     pub fn is_finite(&self) -> bool {
420         self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
421     }
422 
423     /// Returns `true` if any elements are `NaN`.
424     #[inline]
425     #[must_use]
is_nan(&self) -> bool426     pub fn is_nan(&self) -> bool {
427         self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
428     }
429 
430     /// Returns the transpose of `self`.
431     #[inline]
432     #[must_use]
transpose(&self) -> Self433     pub fn transpose(&self) -> Self {
434         Self {
435             x_axis: Vec3A::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
436             y_axis: Vec3A::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
437             z_axis: Vec3A::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
438         }
439     }
440 
441     /// Returns the determinant of `self`.
442     #[inline]
443     #[must_use]
determinant(&self) -> f32444     pub fn determinant(&self) -> f32 {
445         self.z_axis.dot(self.x_axis.cross(self.y_axis))
446     }
447 
448     /// Returns the inverse of `self`.
449     ///
450     /// If the matrix is not invertible the returned matrix will be invalid.
451     ///
452     /// # Panics
453     ///
454     /// Will panic if the determinant of `self` is zero when `glam_assert` is enabled.
455     #[inline]
456     #[must_use]
inverse(&self) -> Self457     pub fn inverse(&self) -> Self {
458         let tmp0 = self.y_axis.cross(self.z_axis);
459         let tmp1 = self.z_axis.cross(self.x_axis);
460         let tmp2 = self.x_axis.cross(self.y_axis);
461         let det = self.z_axis.dot(tmp2);
462         glam_assert!(det != 0.0);
463         let inv_det = Vec3A::splat(det.recip());
464         Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose()
465     }
466 
467     /// Transforms the given 2D vector as a point.
468     ///
469     /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `1`.
470     ///
471     /// This method assumes that `self` contains a valid affine transform.
472     ///
473     /// # Panics
474     ///
475     /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
476     #[inline]
477     #[must_use]
transform_point2(&self, rhs: Vec2) -> Vec2478     pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
479         glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
480         Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
481     }
482 
483     /// Rotates the given 2D vector.
484     ///
485     /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `0`.
486     ///
487     /// This method assumes that `self` contains a valid affine transform.
488     ///
489     /// # Panics
490     ///
491     /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
492     #[inline]
493     #[must_use]
transform_vector2(&self, rhs: Vec2) -> Vec2494     pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
495         glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
496         Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
497     }
498 
499     /// Transforms a 3D vector.
500     #[inline]
501     #[must_use]
mul_vec3(&self, rhs: Vec3) -> Vec3502     pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
503         self.mul_vec3a(rhs.into()).into()
504     }
505 
506     /// Transforms a [`Vec3A`].
507     #[inline]
508     #[must_use]
mul_vec3a(&self, rhs: Vec3A) -> Vec3A509     pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
510         let mut res = self.x_axis.mul(rhs.xxx());
511         res = res.add(self.y_axis.mul(rhs.yyy()));
512         res = res.add(self.z_axis.mul(rhs.zzz()));
513         res
514     }
515 
516     /// Multiplies two 3x3 matrices.
517     #[inline]
518     #[must_use]
mul_mat3(&self, rhs: &Self) -> Self519     pub fn mul_mat3(&self, rhs: &Self) -> Self {
520         Self::from_cols(
521             self.mul(rhs.x_axis),
522             self.mul(rhs.y_axis),
523             self.mul(rhs.z_axis),
524         )
525     }
526 
527     /// Adds two 3x3 matrices.
528     #[inline]
529     #[must_use]
add_mat3(&self, rhs: &Self) -> Self530     pub fn add_mat3(&self, rhs: &Self) -> Self {
531         Self::from_cols(
532             self.x_axis.add(rhs.x_axis),
533             self.y_axis.add(rhs.y_axis),
534             self.z_axis.add(rhs.z_axis),
535         )
536     }
537 
538     /// Subtracts two 3x3 matrices.
539     #[inline]
540     #[must_use]
sub_mat3(&self, rhs: &Self) -> Self541     pub fn sub_mat3(&self, rhs: &Self) -> Self {
542         Self::from_cols(
543             self.x_axis.sub(rhs.x_axis),
544             self.y_axis.sub(rhs.y_axis),
545             self.z_axis.sub(rhs.z_axis),
546         )
547     }
548 
549     /// Multiplies a 3x3 matrix by a scalar.
550     #[inline]
551     #[must_use]
mul_scalar(&self, rhs: f32) -> Self552     pub fn mul_scalar(&self, rhs: f32) -> Self {
553         Self::from_cols(
554             self.x_axis.mul(rhs),
555             self.y_axis.mul(rhs),
556             self.z_axis.mul(rhs),
557         )
558     }
559 
560     /// Returns true if the absolute difference of all elements between `self` and `rhs`
561     /// is less than or equal to `max_abs_diff`.
562     ///
563     /// This can be used to compare if two matrices contain similar elements. It works best
564     /// when comparing with a known value. The `max_abs_diff` that should be used used
565     /// depends on the values being compared against.
566     ///
567     /// For more see
568     /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
569     #[inline]
570     #[must_use]
abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool571     pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
572         self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
573             && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
574             && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
575     }
576 
577     #[inline]
as_dmat3(&self) -> DMat3578     pub fn as_dmat3(&self) -> DMat3 {
579         DMat3::from_cols(
580             self.x_axis.as_dvec3(),
581             self.y_axis.as_dvec3(),
582             self.z_axis.as_dvec3(),
583         )
584     }
585 }
586 
587 impl Default for Mat3A {
588     #[inline]
default() -> Self589     fn default() -> Self {
590         Self::IDENTITY
591     }
592 }
593 
594 impl Add<Mat3A> for Mat3A {
595     type Output = Self;
596     #[inline]
add(self, rhs: Self) -> Self::Output597     fn add(self, rhs: Self) -> Self::Output {
598         self.add_mat3(&rhs)
599     }
600 }
601 
602 impl AddAssign<Mat3A> for Mat3A {
603     #[inline]
add_assign(&mut self, rhs: Self)604     fn add_assign(&mut self, rhs: Self) {
605         *self = self.add_mat3(&rhs);
606     }
607 }
608 
609 impl Sub<Mat3A> for Mat3A {
610     type Output = Self;
611     #[inline]
sub(self, rhs: Self) -> Self::Output612     fn sub(self, rhs: Self) -> Self::Output {
613         self.sub_mat3(&rhs)
614     }
615 }
616 
617 impl SubAssign<Mat3A> for Mat3A {
618     #[inline]
sub_assign(&mut self, rhs: Self)619     fn sub_assign(&mut self, rhs: Self) {
620         *self = self.sub_mat3(&rhs);
621     }
622 }
623 
624 impl Neg for Mat3A {
625     type Output = Self;
626     #[inline]
neg(self) -> Self::Output627     fn neg(self) -> Self::Output {
628         Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
629     }
630 }
631 
632 impl Mul<Mat3A> for Mat3A {
633     type Output = Self;
634     #[inline]
mul(self, rhs: Self) -> Self::Output635     fn mul(self, rhs: Self) -> Self::Output {
636         self.mul_mat3(&rhs)
637     }
638 }
639 
640 impl MulAssign<Mat3A> for Mat3A {
641     #[inline]
mul_assign(&mut self, rhs: Self)642     fn mul_assign(&mut self, rhs: Self) {
643         *self = self.mul_mat3(&rhs);
644     }
645 }
646 
647 impl Mul<Vec3A> for Mat3A {
648     type Output = Vec3A;
649     #[inline]
mul(self, rhs: Vec3A) -> Self::Output650     fn mul(self, rhs: Vec3A) -> Self::Output {
651         self.mul_vec3a(rhs)
652     }
653 }
654 
655 impl Mul<Mat3A> for f32 {
656     type Output = Mat3A;
657     #[inline]
mul(self, rhs: Mat3A) -> Self::Output658     fn mul(self, rhs: Mat3A) -> Self::Output {
659         rhs.mul_scalar(self)
660     }
661 }
662 
663 impl Mul<f32> for Mat3A {
664     type Output = Self;
665     #[inline]
mul(self, rhs: f32) -> Self::Output666     fn mul(self, rhs: f32) -> Self::Output {
667         self.mul_scalar(rhs)
668     }
669 }
670 
671 impl MulAssign<f32> for Mat3A {
672     #[inline]
mul_assign(&mut self, rhs: f32)673     fn mul_assign(&mut self, rhs: f32) {
674         *self = self.mul_scalar(rhs);
675     }
676 }
677 
678 impl Mul<Vec3> for Mat3A {
679     type Output = Vec3;
680     #[inline]
mul(self, rhs: Vec3) -> Vec3681     fn mul(self, rhs: Vec3) -> Vec3 {
682         self.mul_vec3a(rhs.into()).into()
683     }
684 }
685 
686 impl From<Mat3> for Mat3A {
687     #[inline]
from(m: Mat3) -> Self688     fn from(m: Mat3) -> Self {
689         Self {
690             x_axis: m.x_axis.into(),
691             y_axis: m.y_axis.into(),
692             z_axis: m.z_axis.into(),
693         }
694     }
695 }
696 
697 impl Sum<Self> for Mat3A {
sum<I>(iter: I) -> Self where I: Iterator<Item = Self>,698     fn sum<I>(iter: I) -> Self
699     where
700         I: Iterator<Item = Self>,
701     {
702         iter.fold(Self::ZERO, Self::add)
703     }
704 }
705 
706 impl<'a> Sum<&'a Self> for Mat3A {
sum<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,707     fn sum<I>(iter: I) -> Self
708     where
709         I: Iterator<Item = &'a Self>,
710     {
711         iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
712     }
713 }
714 
715 impl Product for Mat3A {
product<I>(iter: I) -> Self where I: Iterator<Item = Self>,716     fn product<I>(iter: I) -> Self
717     where
718         I: Iterator<Item = Self>,
719     {
720         iter.fold(Self::IDENTITY, Self::mul)
721     }
722 }
723 
724 impl<'a> Product<&'a Self> for Mat3A {
product<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,725     fn product<I>(iter: I) -> Self
726     where
727         I: Iterator<Item = &'a Self>,
728     {
729         iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
730     }
731 }
732 
733 impl PartialEq for Mat3A {
734     #[inline]
eq(&self, rhs: &Self) -> bool735     fn eq(&self, rhs: &Self) -> bool {
736         self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
737     }
738 }
739 
740 #[cfg(not(target_arch = "spirv"))]
741 impl fmt::Debug for Mat3A {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result742     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
743         fmt.debug_struct(stringify!(Mat3A))
744             .field("x_axis", &self.x_axis)
745             .field("y_axis", &self.y_axis)
746             .field("z_axis", &self.z_axis)
747             .finish()
748     }
749 }
750 
751 #[cfg(not(target_arch = "spirv"))]
752 impl fmt::Display for Mat3A {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result753     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
754         write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
755     }
756 }
757