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