1 // Generated from mat.rs.tera template. Edit the template, not the generated file.
2 
3 use crate::{f64::math, swizzles::*, DMat2, DMat4, DQuat, DVec2, DVec3, EulerRot, Mat3};
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]
dmat3(x_axis: DVec3, y_axis: DVec3, z_axis: DVec3) -> DMat312 pub const fn dmat3(x_axis: DVec3, y_axis: DVec3, z_axis: DVec3) -> DMat3 {
13     DMat3::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 /// [`DAffine2`](crate::DAffine2) 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 DMat3 {
43     pub x_axis: DVec3,
44     pub y_axis: DVec3,
45     pub z_axis: DVec3,
46 }
47 
48 impl DMat3 {
49     /// A 3x3 matrix with all elements set to `0.0`.
50     pub const ZERO: Self = Self::from_cols(DVec3::ZERO, DVec3::ZERO, DVec3::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(DVec3::X, DVec3::Y, DVec3::Z);
54 
55     /// All NAN:s.
56     pub const NAN: Self = Self::from_cols(DVec3::NAN, DVec3::NAN, DVec3::NAN);
57 
58     #[allow(clippy::too_many_arguments)]
59     #[inline(always)]
60     #[must_use]
new( m00: f64, m01: f64, m02: f64, m10: f64, m11: f64, m12: f64, m20: f64, m21: f64, m22: f64, ) -> Self61     const fn new(
62         m00: f64,
63         m01: f64,
64         m02: f64,
65         m10: f64,
66         m11: f64,
67         m12: f64,
68         m20: f64,
69         m21: f64,
70         m22: f64,
71     ) -> Self {
72         Self {
73             x_axis: DVec3::new(m00, m01, m02),
74             y_axis: DVec3::new(m10, m11, m12),
75             z_axis: DVec3::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: DVec3, y_axis: DVec3, z_axis: DVec3) -> Self82     pub const fn from_cols(x_axis: DVec3, y_axis: DVec3, z_axis: DVec3) -> Self {
83         Self {
84             x_axis,
85             y_axis,
86             z_axis,
87         }
88     }
89 
90     /// Creates a 3x3 matrix from a `[f64; 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: &[f64; 9]) -> Self95     pub const fn from_cols_array(m: &[f64; 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 `[f64; 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) -> [f64; 9]103     pub const fn to_cols_array(&self) -> [f64; 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 `[[f64; 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: &[[f64; 3]; 3]) -> Self122     pub const fn from_cols_array_2d(m: &[[f64; 3]; 3]) -> Self {
123         Self::from_cols(
124             DVec3::from_array(m[0]),
125             DVec3::from_array(m[1]),
126             DVec3::from_array(m[2]),
127         )
128     }
129 
130     /// Creates a `[[f64; 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) -> [[f64; 3]; 3]134     pub const fn to_cols_array_2d(&self) -> [[f64; 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: DVec3) -> Self146     pub const fn from_diagonal(diagonal: DVec3) -> 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: DMat4) -> Self155     pub fn from_mat4(m: DMat4) -> 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: DQuat) -> Self166     pub fn from_quat(rotation: DQuat) -> 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             DVec3::new(1.0 - (yy + zz), xy + wz, xz - wy),
184             DVec3::new(xy - wz, 1.0 - (xx + zz), yz + wx),
185             DVec3::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: DVec3, angle: f64) -> Self197     pub fn from_axis_angle(axis: DVec3, angle: f64) -> 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             DVec3::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
210             DVec3::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
211             DVec3::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: f64, b: f64, c: f64) -> Self219     pub fn from_euler(order: EulerRot, a: f64, b: f64, c: f64) -> Self {
220         let quat = DQuat::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: f64) -> Self227     pub fn from_rotation_x(angle: f64) -> Self {
228         let (sina, cosa) = math::sin_cos(angle);
229         Self::from_cols(
230             DVec3::X,
231             DVec3::new(0.0, cosa, sina),
232             DVec3::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: f64) -> Self239     pub fn from_rotation_y(angle: f64) -> Self {
240         let (sina, cosa) = math::sin_cos(angle);
241         Self::from_cols(
242             DVec3::new(cosa, 0.0, -sina),
243             DVec3::Y,
244             DVec3::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: f64) -> Self251     pub fn from_rotation_z(angle: f64) -> Self {
252         let (sina, cosa) = math::sin_cos(angle);
253         Self::from_cols(
254             DVec3::new(cosa, sina, 0.0),
255             DVec3::new(-sina, cosa, 0.0),
256             DVec3::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: DVec2) -> Self266     pub fn from_translation(translation: DVec2) -> Self {
267         Self::from_cols(
268             DVec3::X,
269             DVec3::Y,
270             DVec3::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: f64) -> Self281     pub fn from_angle(angle: f64) -> Self {
282         let (sin, cos) = math::sin_cos(angle);
283         Self::from_cols(
284             DVec3::new(cos, sin, 0.0),
285             DVec3::new(-sin, cos, 0.0),
286             DVec3::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: DVec2, angle: f64, translation: DVec2) -> Self297     pub fn from_scale_angle_translation(scale: DVec2, angle: f64, translation: DVec2) -> Self {
298         let (sin, cos) = math::sin_cos(angle);
299         Self::from_cols(
300             DVec3::new(cos * scale.x, sin * scale.x, 0.0),
301             DVec3::new(-sin * scale.y, cos * scale.y, 0.0),
302             DVec3::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: DVec2) -> Self316     pub fn from_scale(scale: DVec2) -> Self {
317         // Do not panic as long as any component is non-zero
318         glam_assert!(scale.cmpne(DVec2::ZERO).any());
319 
320         Self::from_cols(
321             DVec3::new(scale.x, 0.0, 0.0),
322             DVec3::new(0.0, scale.y, 0.0),
323             DVec3::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: DMat2) -> Self332     pub fn from_mat2(m: DMat2) -> Self {
333         Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), DVec3::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: &[f64]) -> Self343     pub const fn from_cols_slice(slice: &[f64]) -> 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 [f64])356     pub fn write_cols_to_slice(self, slice: &mut [f64]) {
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) -> DVec3375     pub fn col(&self, index: usize) -> DVec3 {
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 DVec3390     pub fn col_mut(&mut self, index: usize) -> &mut DVec3 {
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) -> DVec3406     pub fn row(&self, index: usize) -> DVec3 {
407         match index {
408             0 => DVec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
409             1 => DVec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
410             2 => DVec3::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: DVec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
436             y_axis: DVec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
437             z_axis: DVec3::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) -> f64444     pub fn determinant(&self) -> f64 {
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 = DVec3::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: DVec2) -> DVec2478     pub fn transform_point2(&self, rhs: DVec2) -> DVec2 {
479         glam_assert!(self.row(2).abs_diff_eq(DVec3::Z, 1e-6));
480         DMat2::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: DVec2) -> DVec2494     pub fn transform_vector2(&self, rhs: DVec2) -> DVec2 {
495         glam_assert!(self.row(2).abs_diff_eq(DVec3::Z, 1e-6));
496         DMat2::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: DVec3) -> DVec3502     pub fn mul_vec3(&self, rhs: DVec3) -> DVec3 {
503         let mut res = self.x_axis.mul(rhs.x);
504         res = res.add(self.y_axis.mul(rhs.y));
505         res = res.add(self.z_axis.mul(rhs.z));
506         res
507     }
508 
509     /// Multiplies two 3x3 matrices.
510     #[inline]
511     #[must_use]
mul_mat3(&self, rhs: &Self) -> Self512     pub fn mul_mat3(&self, rhs: &Self) -> Self {
513         Self::from_cols(
514             self.mul(rhs.x_axis),
515             self.mul(rhs.y_axis),
516             self.mul(rhs.z_axis),
517         )
518     }
519 
520     /// Adds two 3x3 matrices.
521     #[inline]
522     #[must_use]
add_mat3(&self, rhs: &Self) -> Self523     pub fn add_mat3(&self, rhs: &Self) -> Self {
524         Self::from_cols(
525             self.x_axis.add(rhs.x_axis),
526             self.y_axis.add(rhs.y_axis),
527             self.z_axis.add(rhs.z_axis),
528         )
529     }
530 
531     /// Subtracts two 3x3 matrices.
532     #[inline]
533     #[must_use]
sub_mat3(&self, rhs: &Self) -> Self534     pub fn sub_mat3(&self, rhs: &Self) -> Self {
535         Self::from_cols(
536             self.x_axis.sub(rhs.x_axis),
537             self.y_axis.sub(rhs.y_axis),
538             self.z_axis.sub(rhs.z_axis),
539         )
540     }
541 
542     /// Multiplies a 3x3 matrix by a scalar.
543     #[inline]
544     #[must_use]
mul_scalar(&self, rhs: f64) -> Self545     pub fn mul_scalar(&self, rhs: f64) -> Self {
546         Self::from_cols(
547             self.x_axis.mul(rhs),
548             self.y_axis.mul(rhs),
549             self.z_axis.mul(rhs),
550         )
551     }
552 
553     /// Returns true if the absolute difference of all elements between `self` and `rhs`
554     /// is less than or equal to `max_abs_diff`.
555     ///
556     /// This can be used to compare if two matrices contain similar elements. It works best
557     /// when comparing with a known value. The `max_abs_diff` that should be used used
558     /// depends on the values being compared against.
559     ///
560     /// For more see
561     /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
562     #[inline]
563     #[must_use]
abs_diff_eq(&self, rhs: Self, max_abs_diff: f64) -> bool564     pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f64) -> bool {
565         self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
566             && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
567             && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
568     }
569 
570     #[inline]
as_mat3(&self) -> Mat3571     pub fn as_mat3(&self) -> Mat3 {
572         Mat3::from_cols(
573             self.x_axis.as_vec3(),
574             self.y_axis.as_vec3(),
575             self.z_axis.as_vec3(),
576         )
577     }
578 }
579 
580 impl Default for DMat3 {
581     #[inline]
default() -> Self582     fn default() -> Self {
583         Self::IDENTITY
584     }
585 }
586 
587 impl Add<DMat3> for DMat3 {
588     type Output = Self;
589     #[inline]
add(self, rhs: Self) -> Self::Output590     fn add(self, rhs: Self) -> Self::Output {
591         self.add_mat3(&rhs)
592     }
593 }
594 
595 impl AddAssign<DMat3> for DMat3 {
596     #[inline]
add_assign(&mut self, rhs: Self)597     fn add_assign(&mut self, rhs: Self) {
598         *self = self.add_mat3(&rhs);
599     }
600 }
601 
602 impl Sub<DMat3> for DMat3 {
603     type Output = Self;
604     #[inline]
sub(self, rhs: Self) -> Self::Output605     fn sub(self, rhs: Self) -> Self::Output {
606         self.sub_mat3(&rhs)
607     }
608 }
609 
610 impl SubAssign<DMat3> for DMat3 {
611     #[inline]
sub_assign(&mut self, rhs: Self)612     fn sub_assign(&mut self, rhs: Self) {
613         *self = self.sub_mat3(&rhs);
614     }
615 }
616 
617 impl Neg for DMat3 {
618     type Output = Self;
619     #[inline]
neg(self) -> Self::Output620     fn neg(self) -> Self::Output {
621         Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
622     }
623 }
624 
625 impl Mul<DMat3> for DMat3 {
626     type Output = Self;
627     #[inline]
mul(self, rhs: Self) -> Self::Output628     fn mul(self, rhs: Self) -> Self::Output {
629         self.mul_mat3(&rhs)
630     }
631 }
632 
633 impl MulAssign<DMat3> for DMat3 {
634     #[inline]
mul_assign(&mut self, rhs: Self)635     fn mul_assign(&mut self, rhs: Self) {
636         *self = self.mul_mat3(&rhs);
637     }
638 }
639 
640 impl Mul<DVec3> for DMat3 {
641     type Output = DVec3;
642     #[inline]
mul(self, rhs: DVec3) -> Self::Output643     fn mul(self, rhs: DVec3) -> Self::Output {
644         self.mul_vec3(rhs)
645     }
646 }
647 
648 impl Mul<DMat3> for f64 {
649     type Output = DMat3;
650     #[inline]
mul(self, rhs: DMat3) -> Self::Output651     fn mul(self, rhs: DMat3) -> Self::Output {
652         rhs.mul_scalar(self)
653     }
654 }
655 
656 impl Mul<f64> for DMat3 {
657     type Output = Self;
658     #[inline]
mul(self, rhs: f64) -> Self::Output659     fn mul(self, rhs: f64) -> Self::Output {
660         self.mul_scalar(rhs)
661     }
662 }
663 
664 impl MulAssign<f64> for DMat3 {
665     #[inline]
mul_assign(&mut self, rhs: f64)666     fn mul_assign(&mut self, rhs: f64) {
667         *self = self.mul_scalar(rhs);
668     }
669 }
670 
671 impl Sum<Self> for DMat3 {
sum<I>(iter: I) -> Self where I: Iterator<Item = Self>,672     fn sum<I>(iter: I) -> Self
673     where
674         I: Iterator<Item = Self>,
675     {
676         iter.fold(Self::ZERO, Self::add)
677     }
678 }
679 
680 impl<'a> Sum<&'a Self> for DMat3 {
sum<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,681     fn sum<I>(iter: I) -> Self
682     where
683         I: Iterator<Item = &'a Self>,
684     {
685         iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
686     }
687 }
688 
689 impl Product for DMat3 {
product<I>(iter: I) -> Self where I: Iterator<Item = Self>,690     fn product<I>(iter: I) -> Self
691     where
692         I: Iterator<Item = Self>,
693     {
694         iter.fold(Self::IDENTITY, Self::mul)
695     }
696 }
697 
698 impl<'a> Product<&'a Self> for DMat3 {
product<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,699     fn product<I>(iter: I) -> Self
700     where
701         I: Iterator<Item = &'a Self>,
702     {
703         iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
704     }
705 }
706 
707 impl PartialEq for DMat3 {
708     #[inline]
eq(&self, rhs: &Self) -> bool709     fn eq(&self, rhs: &Self) -> bool {
710         self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
711     }
712 }
713 
714 #[cfg(not(target_arch = "spirv"))]
715 impl AsRef<[f64; 9]> for DMat3 {
716     #[inline]
as_ref(&self) -> &[f64; 9]717     fn as_ref(&self) -> &[f64; 9] {
718         unsafe { &*(self as *const Self as *const [f64; 9]) }
719     }
720 }
721 
722 #[cfg(not(target_arch = "spirv"))]
723 impl AsMut<[f64; 9]> for DMat3 {
724     #[inline]
as_mut(&mut self) -> &mut [f64; 9]725     fn as_mut(&mut self) -> &mut [f64; 9] {
726         unsafe { &mut *(self as *mut Self as *mut [f64; 9]) }
727     }
728 }
729 
730 #[cfg(not(target_arch = "spirv"))]
731 impl fmt::Debug for DMat3 {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result732     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
733         fmt.debug_struct(stringify!(DMat3))
734             .field("x_axis", &self.x_axis)
735             .field("y_axis", &self.y_axis)
736             .field("z_axis", &self.z_axis)
737             .finish()
738     }
739 }
740 
741 #[cfg(not(target_arch = "spirv"))]
742 impl fmt::Display for DMat3 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result743     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
744         write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
745     }
746 }
747