• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Generated from mat.rs.tera template. Edit the template, not the generated file.
2 
3 use crate::{
4     euler::{FromEuler, ToEuler},
5     f32::math,
6     swizzles::*,
7     DMat3, EulerRot, Mat2, Mat3, Mat4, Quat, Vec2, Vec3, Vec3A,
8 };
9 use core::fmt;
10 use core::iter::{Product, Sum};
11 use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
12 
13 /// Creates a 3x3 matrix from three column vectors.
14 #[inline(always)]
15 #[must_use]
mat3a(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Mat3A16 pub const fn mat3a(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Mat3A {
17     Mat3A::from_cols(x_axis, y_axis, z_axis)
18 }
19 
20 /// A 3x3 column major matrix.
21 ///
22 /// This 3x3 matrix type features convenience methods for creating and using linear and
23 /// affine transformations. If you are primarily dealing with 2D affine transformations the
24 /// [`Affine2`](crate::Affine2) type is much faster and more space efficient than
25 /// using a 3x3 matrix.
26 ///
27 /// Linear transformations including 3D rotation and scale can be created using methods
28 /// such as [`Self::from_diagonal()`], [`Self::from_quat()`], [`Self::from_axis_angle()`],
29 /// [`Self::from_rotation_x()`], [`Self::from_rotation_y()`], or
30 /// [`Self::from_rotation_z()`].
31 ///
32 /// The resulting matrices can be use to transform 3D vectors using regular vector
33 /// multiplication.
34 ///
35 /// Affine transformations including 2D translation, rotation and scale can be created
36 /// using methods such as [`Self::from_translation()`], [`Self::from_angle()`],
37 /// [`Self::from_scale()`] and [`Self::from_scale_angle_translation()`].
38 ///
39 /// The [`Self::transform_point2()`] and [`Self::transform_vector2()`] convenience methods
40 /// are provided for performing affine transforms on 2D vectors and points. These multiply
41 /// 2D inputs as 3D vectors with an implicit `z` value of `1` for points and `0` for
42 /// vectors respectively. These methods assume that `Self` contains a valid affine
43 /// transform.
44 #[derive(Clone, Copy)]
45 #[repr(C)]
46 pub struct Mat3A {
47     pub x_axis: Vec3A,
48     pub y_axis: Vec3A,
49     pub z_axis: Vec3A,
50 }
51 
52 impl Mat3A {
53     /// A 3x3 matrix with all elements set to `0.0`.
54     pub const ZERO: Self = Self::from_cols(Vec3A::ZERO, Vec3A::ZERO, Vec3A::ZERO);
55 
56     /// A 3x3 identity matrix, where all diagonal elements are `1`, and all off-diagonal elements are `0`.
57     pub const IDENTITY: Self = Self::from_cols(Vec3A::X, Vec3A::Y, Vec3A::Z);
58 
59     /// All NAN:s.
60     pub const NAN: Self = Self::from_cols(Vec3A::NAN, Vec3A::NAN, Vec3A::NAN);
61 
62     #[allow(clippy::too_many_arguments)]
63     #[inline(always)]
64     #[must_use]
new( m00: f32, m01: f32, m02: f32, m10: f32, m11: f32, m12: f32, m20: f32, m21: f32, m22: f32, ) -> Self65     const fn new(
66         m00: f32,
67         m01: f32,
68         m02: f32,
69         m10: f32,
70         m11: f32,
71         m12: f32,
72         m20: f32,
73         m21: f32,
74         m22: f32,
75     ) -> Self {
76         Self {
77             x_axis: Vec3A::new(m00, m01, m02),
78             y_axis: Vec3A::new(m10, m11, m12),
79             z_axis: Vec3A::new(m20, m21, m22),
80         }
81     }
82 
83     /// Creates a 3x3 matrix from three column vectors.
84     #[inline(always)]
85     #[must_use]
from_cols(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Self86     pub const fn from_cols(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Self {
87         Self {
88             x_axis,
89             y_axis,
90             z_axis,
91         }
92     }
93 
94     /// Creates a 3x3 matrix from a `[f32; 9]` array stored in column major order.
95     /// If your data is stored in row major you will need to `transpose` the returned
96     /// matrix.
97     #[inline]
98     #[must_use]
from_cols_array(m: &[f32; 9]) -> Self99     pub const fn from_cols_array(m: &[f32; 9]) -> Self {
100         Self::new(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8])
101     }
102 
103     /// Creates a `[f32; 9]` array storing data in column major order.
104     /// If you require data in row major order `transpose` the matrix first.
105     #[inline]
106     #[must_use]
to_cols_array(&self) -> [f32; 9]107     pub const fn to_cols_array(&self) -> [f32; 9] {
108         [
109             self.x_axis.x,
110             self.x_axis.y,
111             self.x_axis.z,
112             self.y_axis.x,
113             self.y_axis.y,
114             self.y_axis.z,
115             self.z_axis.x,
116             self.z_axis.y,
117             self.z_axis.z,
118         ]
119     }
120 
121     /// Creates a 3x3 matrix from a `[[f32; 3]; 3]` 3D array stored in column major order.
122     /// If your data is in row major order you will need to `transpose` the returned
123     /// matrix.
124     #[inline]
125     #[must_use]
from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self126     pub const fn from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self {
127         Self::from_cols(
128             Vec3A::from_array(m[0]),
129             Vec3A::from_array(m[1]),
130             Vec3A::from_array(m[2]),
131         )
132     }
133 
134     /// Creates a `[[f32; 3]; 3]` 3D array storing data in column major order.
135     /// If you require data in row major order `transpose` the matrix first.
136     #[inline]
137     #[must_use]
to_cols_array_2d(&self) -> [[f32; 3]; 3]138     pub const fn to_cols_array_2d(&self) -> [[f32; 3]; 3] {
139         [
140             self.x_axis.to_array(),
141             self.y_axis.to_array(),
142             self.z_axis.to_array(),
143         ]
144     }
145 
146     /// Creates a 3x3 matrix with its diagonal set to `diagonal` and all other entries set to 0.
147     #[doc(alias = "scale")]
148     #[inline]
149     #[must_use]
from_diagonal(diagonal: Vec3) -> Self150     pub const fn from_diagonal(diagonal: Vec3) -> Self {
151         Self::new(
152             diagonal.x, 0.0, 0.0, 0.0, diagonal.y, 0.0, 0.0, 0.0, diagonal.z,
153         )
154     }
155 
156     /// Creates a 3x3 matrix from a 4x4 matrix, discarding the 4th row and column.
157     #[inline]
158     #[must_use]
from_mat4(m: Mat4) -> Self159     pub fn from_mat4(m: Mat4) -> Self {
160         Self::from_cols(
161             Vec3A::from_vec4(m.x_axis),
162             Vec3A::from_vec4(m.y_axis),
163             Vec3A::from_vec4(m.z_axis),
164         )
165     }
166 
167     /// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column
168     /// and `j`th row.
169     ///
170     /// # Panics
171     ///
172     /// Panics if `i` or `j` is greater than 3.
173     #[inline]
174     #[must_use]
from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self175     pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self {
176         match (i, j) {
177             (0, 0) => Self::from_cols(
178                 Vec3A::from_vec4(m.y_axis.yzww()),
179                 Vec3A::from_vec4(m.z_axis.yzww()),
180                 Vec3A::from_vec4(m.w_axis.yzww()),
181             ),
182             (0, 1) => Self::from_cols(
183                 Vec3A::from_vec4(m.y_axis.xzww()),
184                 Vec3A::from_vec4(m.z_axis.xzww()),
185                 Vec3A::from_vec4(m.w_axis.xzww()),
186             ),
187             (0, 2) => Self::from_cols(
188                 Vec3A::from_vec4(m.y_axis.xyww()),
189                 Vec3A::from_vec4(m.z_axis.xyww()),
190                 Vec3A::from_vec4(m.w_axis.xyww()),
191             ),
192             (0, 3) => Self::from_cols(
193                 Vec3A::from_vec4(m.y_axis.xyzw()),
194                 Vec3A::from_vec4(m.z_axis.xyzw()),
195                 Vec3A::from_vec4(m.w_axis.xyzw()),
196             ),
197             (1, 0) => Self::from_cols(
198                 Vec3A::from_vec4(m.x_axis.yzww()),
199                 Vec3A::from_vec4(m.z_axis.yzww()),
200                 Vec3A::from_vec4(m.w_axis.yzww()),
201             ),
202             (1, 1) => Self::from_cols(
203                 Vec3A::from_vec4(m.x_axis.xzww()),
204                 Vec3A::from_vec4(m.z_axis.xzww()),
205                 Vec3A::from_vec4(m.w_axis.xzww()),
206             ),
207             (1, 2) => Self::from_cols(
208                 Vec3A::from_vec4(m.x_axis.xyww()),
209                 Vec3A::from_vec4(m.z_axis.xyww()),
210                 Vec3A::from_vec4(m.w_axis.xyww()),
211             ),
212             (1, 3) => Self::from_cols(
213                 Vec3A::from_vec4(m.x_axis.xyzw()),
214                 Vec3A::from_vec4(m.z_axis.xyzw()),
215                 Vec3A::from_vec4(m.w_axis.xyzw()),
216             ),
217             (2, 0) => Self::from_cols(
218                 Vec3A::from_vec4(m.x_axis.yzww()),
219                 Vec3A::from_vec4(m.y_axis.yzww()),
220                 Vec3A::from_vec4(m.w_axis.yzww()),
221             ),
222             (2, 1) => Self::from_cols(
223                 Vec3A::from_vec4(m.x_axis.xzww()),
224                 Vec3A::from_vec4(m.y_axis.xzww()),
225                 Vec3A::from_vec4(m.w_axis.xzww()),
226             ),
227             (2, 2) => Self::from_cols(
228                 Vec3A::from_vec4(m.x_axis.xyww()),
229                 Vec3A::from_vec4(m.y_axis.xyww()),
230                 Vec3A::from_vec4(m.w_axis.xyww()),
231             ),
232             (2, 3) => Self::from_cols(
233                 Vec3A::from_vec4(m.x_axis.xyzw()),
234                 Vec3A::from_vec4(m.y_axis.xyzw()),
235                 Vec3A::from_vec4(m.w_axis.xyzw()),
236             ),
237             (3, 0) => Self::from_cols(
238                 Vec3A::from_vec4(m.x_axis.yzww()),
239                 Vec3A::from_vec4(m.y_axis.yzww()),
240                 Vec3A::from_vec4(m.z_axis.yzww()),
241             ),
242             (3, 1) => Self::from_cols(
243                 Vec3A::from_vec4(m.x_axis.xzww()),
244                 Vec3A::from_vec4(m.y_axis.xzww()),
245                 Vec3A::from_vec4(m.z_axis.xzww()),
246             ),
247             (3, 2) => Self::from_cols(
248                 Vec3A::from_vec4(m.x_axis.xyww()),
249                 Vec3A::from_vec4(m.y_axis.xyww()),
250                 Vec3A::from_vec4(m.z_axis.xyww()),
251             ),
252             (3, 3) => Self::from_cols(
253                 Vec3A::from_vec4(m.x_axis.xyzw()),
254                 Vec3A::from_vec4(m.y_axis.xyzw()),
255                 Vec3A::from_vec4(m.z_axis.xyzw()),
256             ),
257             _ => panic!("index out of bounds"),
258         }
259     }
260 
261     /// Creates a 3D rotation matrix from the given quaternion.
262     ///
263     /// # Panics
264     ///
265     /// Will panic if `rotation` is not normalized when `glam_assert` is enabled.
266     #[inline]
267     #[must_use]
from_quat(rotation: Quat) -> Self268     pub fn from_quat(rotation: Quat) -> Self {
269         glam_assert!(rotation.is_normalized());
270 
271         let x2 = rotation.x + rotation.x;
272         let y2 = rotation.y + rotation.y;
273         let z2 = rotation.z + rotation.z;
274         let xx = rotation.x * x2;
275         let xy = rotation.x * y2;
276         let xz = rotation.x * z2;
277         let yy = rotation.y * y2;
278         let yz = rotation.y * z2;
279         let zz = rotation.z * z2;
280         let wx = rotation.w * x2;
281         let wy = rotation.w * y2;
282         let wz = rotation.w * z2;
283 
284         Self::from_cols(
285             Vec3A::new(1.0 - (yy + zz), xy + wz, xz - wy),
286             Vec3A::new(xy - wz, 1.0 - (xx + zz), yz + wx),
287             Vec3A::new(xz + wy, yz - wx, 1.0 - (xx + yy)),
288         )
289     }
290 
291     /// Creates a 3D rotation matrix from a normalized rotation `axis` and `angle` (in
292     /// radians).
293     ///
294     /// # Panics
295     ///
296     /// Will panic if `axis` is not normalized when `glam_assert` is enabled.
297     #[inline]
298     #[must_use]
from_axis_angle(axis: Vec3, angle: f32) -> Self299     pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
300         glam_assert!(axis.is_normalized());
301 
302         let (sin, cos) = math::sin_cos(angle);
303         let (xsin, ysin, zsin) = axis.mul(sin).into();
304         let (x, y, z) = axis.into();
305         let (x2, y2, z2) = axis.mul(axis).into();
306         let omc = 1.0 - cos;
307         let xyomc = x * y * omc;
308         let xzomc = x * z * omc;
309         let yzomc = y * z * omc;
310         Self::from_cols(
311             Vec3A::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
312             Vec3A::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
313             Vec3A::new(xzomc + ysin, yzomc - xsin, z2 * omc + cos),
314         )
315     }
316 
317     /// Creates a 3D rotation matrix from the given euler rotation sequence and the angles (in
318     /// radians).
319     #[inline]
320     #[must_use]
from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self321     pub fn from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self {
322         Self::from_euler_angles(order, a, b, c)
323     }
324 
325     /// Extract Euler angles with the given Euler rotation order.
326     ///
327     /// Note if the input matrix contains scales, shears, or other non-rotation transformations then
328     /// the resulting Euler angles will be ill-defined.
329     ///
330     /// # Panics
331     ///
332     /// Will panic if any input matrix column is not normalized when `glam_assert` is enabled.
333     #[inline]
334     #[must_use]
to_euler(&self, order: EulerRot) -> (f32, f32, f32)335     pub fn to_euler(&self, order: EulerRot) -> (f32, f32, f32) {
336         glam_assert!(
337             self.x_axis.is_normalized()
338                 && self.y_axis.is_normalized()
339                 && self.z_axis.is_normalized()
340         );
341         self.to_euler_angles(order)
342     }
343 
344     /// Creates a 3D rotation matrix from `angle` (in radians) around the x axis.
345     #[inline]
346     #[must_use]
from_rotation_x(angle: f32) -> Self347     pub fn from_rotation_x(angle: f32) -> Self {
348         let (sina, cosa) = math::sin_cos(angle);
349         Self::from_cols(
350             Vec3A::X,
351             Vec3A::new(0.0, cosa, sina),
352             Vec3A::new(0.0, -sina, cosa),
353         )
354     }
355 
356     /// Creates a 3D rotation matrix from `angle` (in radians) around the y axis.
357     #[inline]
358     #[must_use]
from_rotation_y(angle: f32) -> Self359     pub fn from_rotation_y(angle: f32) -> Self {
360         let (sina, cosa) = math::sin_cos(angle);
361         Self::from_cols(
362             Vec3A::new(cosa, 0.0, -sina),
363             Vec3A::Y,
364             Vec3A::new(sina, 0.0, cosa),
365         )
366     }
367 
368     /// Creates a 3D rotation matrix from `angle` (in radians) around the z axis.
369     #[inline]
370     #[must_use]
from_rotation_z(angle: f32) -> Self371     pub fn from_rotation_z(angle: f32) -> Self {
372         let (sina, cosa) = math::sin_cos(angle);
373         Self::from_cols(
374             Vec3A::new(cosa, sina, 0.0),
375             Vec3A::new(-sina, cosa, 0.0),
376             Vec3A::Z,
377         )
378     }
379 
380     /// Creates an affine transformation matrix from the given 2D `translation`.
381     ///
382     /// The resulting matrix can be used to transform 2D points and vectors. See
383     /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
384     #[inline]
385     #[must_use]
from_translation(translation: Vec2) -> Self386     pub fn from_translation(translation: Vec2) -> Self {
387         Self::from_cols(
388             Vec3A::X,
389             Vec3A::Y,
390             Vec3A::new(translation.x, translation.y, 1.0),
391         )
392     }
393 
394     /// Creates an affine transformation matrix from the given 2D rotation `angle` (in
395     /// radians).
396     ///
397     /// The resulting matrix can be used to transform 2D points and vectors. See
398     /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
399     #[inline]
400     #[must_use]
from_angle(angle: f32) -> Self401     pub fn from_angle(angle: f32) -> Self {
402         let (sin, cos) = math::sin_cos(angle);
403         Self::from_cols(
404             Vec3A::new(cos, sin, 0.0),
405             Vec3A::new(-sin, cos, 0.0),
406             Vec3A::Z,
407         )
408     }
409 
410     /// Creates an affine transformation matrix from the given 2D `scale`, rotation `angle` (in
411     /// radians) and `translation`.
412     ///
413     /// The resulting matrix can be used to transform 2D points and vectors. See
414     /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
415     #[inline]
416     #[must_use]
from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self417     pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
418         let (sin, cos) = math::sin_cos(angle);
419         Self::from_cols(
420             Vec3A::new(cos * scale.x, sin * scale.x, 0.0),
421             Vec3A::new(-sin * scale.y, cos * scale.y, 0.0),
422             Vec3A::new(translation.x, translation.y, 1.0),
423         )
424     }
425 
426     /// Creates an affine transformation matrix from the given non-uniform 2D `scale`.
427     ///
428     /// The resulting matrix can be used to transform 2D points and vectors. See
429     /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
430     ///
431     /// # Panics
432     ///
433     /// Will panic if all elements of `scale` are zero when `glam_assert` is enabled.
434     #[inline]
435     #[must_use]
from_scale(scale: Vec2) -> Self436     pub fn from_scale(scale: Vec2) -> Self {
437         // Do not panic as long as any component is non-zero
438         glam_assert!(scale.cmpne(Vec2::ZERO).any());
439 
440         Self::from_cols(
441             Vec3A::new(scale.x, 0.0, 0.0),
442             Vec3A::new(0.0, scale.y, 0.0),
443             Vec3A::Z,
444         )
445     }
446 
447     /// Creates an affine transformation matrix from the given 2x2 matrix.
448     ///
449     /// The resulting matrix can be used to transform 2D points and vectors. See
450     /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
451     #[inline]
from_mat2(m: Mat2) -> Self452     pub fn from_mat2(m: Mat2) -> Self {
453         Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), Vec3A::Z)
454     }
455 
456     /// Creates a 3x3 matrix from the first 9 values in `slice`.
457     ///
458     /// # Panics
459     ///
460     /// Panics if `slice` is less than 9 elements long.
461     #[inline]
462     #[must_use]
from_cols_slice(slice: &[f32]) -> Self463     pub const fn from_cols_slice(slice: &[f32]) -> Self {
464         Self::new(
465             slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
466             slice[8],
467         )
468     }
469 
470     /// Writes the columns of `self` to the first 9 elements in `slice`.
471     ///
472     /// # Panics
473     ///
474     /// Panics if `slice` is less than 9 elements long.
475     #[inline]
write_cols_to_slice(self, slice: &mut [f32])476     pub fn write_cols_to_slice(self, slice: &mut [f32]) {
477         slice[0] = self.x_axis.x;
478         slice[1] = self.x_axis.y;
479         slice[2] = self.x_axis.z;
480         slice[3] = self.y_axis.x;
481         slice[4] = self.y_axis.y;
482         slice[5] = self.y_axis.z;
483         slice[6] = self.z_axis.x;
484         slice[7] = self.z_axis.y;
485         slice[8] = self.z_axis.z;
486     }
487 
488     /// Returns the matrix column for the given `index`.
489     ///
490     /// # Panics
491     ///
492     /// Panics if `index` is greater than 2.
493     #[inline]
494     #[must_use]
col(&self, index: usize) -> Vec3A495     pub fn col(&self, index: usize) -> Vec3A {
496         match index {
497             0 => self.x_axis,
498             1 => self.y_axis,
499             2 => self.z_axis,
500             _ => panic!("index out of bounds"),
501         }
502     }
503 
504     /// Returns a mutable reference to the matrix column for the given `index`.
505     ///
506     /// # Panics
507     ///
508     /// Panics if `index` is greater than 2.
509     #[inline]
col_mut(&mut self, index: usize) -> &mut Vec3A510     pub fn col_mut(&mut self, index: usize) -> &mut Vec3A {
511         match index {
512             0 => &mut self.x_axis,
513             1 => &mut self.y_axis,
514             2 => &mut self.z_axis,
515             _ => panic!("index out of bounds"),
516         }
517     }
518 
519     /// Returns the matrix row for the given `index`.
520     ///
521     /// # Panics
522     ///
523     /// Panics if `index` is greater than 2.
524     #[inline]
525     #[must_use]
row(&self, index: usize) -> Vec3A526     pub fn row(&self, index: usize) -> Vec3A {
527         match index {
528             0 => Vec3A::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
529             1 => Vec3A::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
530             2 => Vec3A::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
531             _ => panic!("index out of bounds"),
532         }
533     }
534 
535     /// Returns `true` if, and only if, all elements are finite.
536     /// If any element is either `NaN`, positive or negative infinity, this will return `false`.
537     #[inline]
538     #[must_use]
is_finite(&self) -> bool539     pub fn is_finite(&self) -> bool {
540         self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
541     }
542 
543     /// Returns `true` if any elements are `NaN`.
544     #[inline]
545     #[must_use]
is_nan(&self) -> bool546     pub fn is_nan(&self) -> bool {
547         self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
548     }
549 
550     /// Returns the transpose of `self`.
551     #[inline]
552     #[must_use]
transpose(&self) -> Self553     pub fn transpose(&self) -> Self {
554         Self {
555             x_axis: Vec3A::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
556             y_axis: Vec3A::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
557             z_axis: Vec3A::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
558         }
559     }
560 
561     /// Returns the determinant of `self`.
562     #[inline]
563     #[must_use]
determinant(&self) -> f32564     pub fn determinant(&self) -> f32 {
565         self.z_axis.dot(self.x_axis.cross(self.y_axis))
566     }
567 
568     /// Returns the inverse of `self`.
569     ///
570     /// If the matrix is not invertible the returned matrix will be invalid.
571     ///
572     /// # Panics
573     ///
574     /// Will panic if the determinant of `self` is zero when `glam_assert` is enabled.
575     #[inline]
576     #[must_use]
inverse(&self) -> Self577     pub fn inverse(&self) -> Self {
578         let tmp0 = self.y_axis.cross(self.z_axis);
579         let tmp1 = self.z_axis.cross(self.x_axis);
580         let tmp2 = self.x_axis.cross(self.y_axis);
581         let det = self.z_axis.dot(tmp2);
582         glam_assert!(det != 0.0);
583         let inv_det = Vec3A::splat(det.recip());
584         Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose()
585     }
586 
587     /// Transforms the given 2D vector as a point.
588     ///
589     /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `1`.
590     ///
591     /// This method assumes that `self` contains a valid affine transform.
592     ///
593     /// # Panics
594     ///
595     /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
596     #[inline]
597     #[must_use]
transform_point2(&self, rhs: Vec2) -> Vec2598     pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
599         glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
600         Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
601     }
602 
603     /// Rotates the given 2D vector.
604     ///
605     /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `0`.
606     ///
607     /// This method assumes that `self` contains a valid affine transform.
608     ///
609     /// # Panics
610     ///
611     /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
612     #[inline]
613     #[must_use]
transform_vector2(&self, rhs: Vec2) -> Vec2614     pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
615         glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
616         Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
617     }
618 
619     /// Creates a left-handed view matrix using a facing direction and an up direction.
620     ///
621     /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`.
622     ///
623     /// # Panics
624     ///
625     /// Will panic if `dir` or `up` are not normalized when `glam_assert` is enabled.
626     #[inline]
627     #[must_use]
look_to_lh(dir: Vec3, up: Vec3) -> Self628     pub fn look_to_lh(dir: Vec3, up: Vec3) -> Self {
629         Self::look_to_rh(-dir, up)
630     }
631 
632     /// Creates a right-handed view matrix using a facing direction and an up direction.
633     ///
634     /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`.
635     ///
636     /// # Panics
637     ///
638     /// Will panic if `dir` or `up` are not normalized when `glam_assert` is enabled.
639     #[inline]
640     #[must_use]
look_to_rh(dir: Vec3, up: Vec3) -> Self641     pub fn look_to_rh(dir: Vec3, up: Vec3) -> Self {
642         glam_assert!(dir.is_normalized());
643         glam_assert!(up.is_normalized());
644         let f = dir;
645         let s = f.cross(up).normalize();
646         let u = s.cross(f);
647 
648         Self::from_cols(
649             Vec3A::new(s.x, u.x, -f.x),
650             Vec3A::new(s.y, u.y, -f.y),
651             Vec3A::new(s.z, u.z, -f.z),
652         )
653     }
654 
655     /// Creates a left-handed view matrix using a camera position, a focal point and an up
656     /// direction.
657     ///
658     /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`.
659     ///
660     /// # Panics
661     ///
662     /// Will panic if `up` is not normalized when `glam_assert` is enabled.
663     #[inline]
664     #[must_use]
look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self665     pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
666         Self::look_to_lh(center.sub(eye).normalize(), up)
667     }
668 
669     /// Creates a right-handed view matrix using a camera position, a focal point and an up
670     /// direction.
671     ///
672     /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`.
673     ///
674     /// # Panics
675     ///
676     /// Will panic if `up` is not normalized when `glam_assert` is enabled.
677     #[inline]
look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self678     pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
679         Self::look_to_rh(center.sub(eye).normalize(), up)
680     }
681 
682     /// Transforms a 3D vector.
683     #[inline]
684     #[must_use]
mul_vec3(&self, rhs: Vec3) -> Vec3685     pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
686         self.mul_vec3a(rhs.into()).into()
687     }
688 
689     /// Transforms a [`Vec3A`].
690     #[inline]
691     #[must_use]
mul_vec3a(&self, rhs: Vec3A) -> Vec3A692     pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
693         let mut res = self.x_axis.mul(rhs.xxx());
694         res = res.add(self.y_axis.mul(rhs.yyy()));
695         res = res.add(self.z_axis.mul(rhs.zzz()));
696         res
697     }
698 
699     /// Multiplies two 3x3 matrices.
700     #[inline]
701     #[must_use]
mul_mat3(&self, rhs: &Self) -> Self702     pub fn mul_mat3(&self, rhs: &Self) -> Self {
703         Self::from_cols(
704             self.mul(rhs.x_axis),
705             self.mul(rhs.y_axis),
706             self.mul(rhs.z_axis),
707         )
708     }
709 
710     /// Adds two 3x3 matrices.
711     #[inline]
712     #[must_use]
add_mat3(&self, rhs: &Self) -> Self713     pub fn add_mat3(&self, rhs: &Self) -> Self {
714         Self::from_cols(
715             self.x_axis.add(rhs.x_axis),
716             self.y_axis.add(rhs.y_axis),
717             self.z_axis.add(rhs.z_axis),
718         )
719     }
720 
721     /// Subtracts two 3x3 matrices.
722     #[inline]
723     #[must_use]
sub_mat3(&self, rhs: &Self) -> Self724     pub fn sub_mat3(&self, rhs: &Self) -> Self {
725         Self::from_cols(
726             self.x_axis.sub(rhs.x_axis),
727             self.y_axis.sub(rhs.y_axis),
728             self.z_axis.sub(rhs.z_axis),
729         )
730     }
731 
732     /// Multiplies a 3x3 matrix by a scalar.
733     #[inline]
734     #[must_use]
mul_scalar(&self, rhs: f32) -> Self735     pub fn mul_scalar(&self, rhs: f32) -> Self {
736         Self::from_cols(
737             self.x_axis.mul(rhs),
738             self.y_axis.mul(rhs),
739             self.z_axis.mul(rhs),
740         )
741     }
742 
743     /// Divides a 3x3 matrix by a scalar.
744     #[inline]
745     #[must_use]
div_scalar(&self, rhs: f32) -> Self746     pub fn div_scalar(&self, rhs: f32) -> Self {
747         let rhs = Vec3A::splat(rhs);
748         Self::from_cols(
749             self.x_axis.div(rhs),
750             self.y_axis.div(rhs),
751             self.z_axis.div(rhs),
752         )
753     }
754 
755     /// Returns true if the absolute difference of all elements between `self` and `rhs`
756     /// is less than or equal to `max_abs_diff`.
757     ///
758     /// This can be used to compare if two matrices contain similar elements. It works best
759     /// when comparing with a known value. The `max_abs_diff` that should be used used
760     /// depends on the values being compared against.
761     ///
762     /// For more see
763     /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
764     #[inline]
765     #[must_use]
abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool766     pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
767         self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
768             && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
769             && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
770     }
771 
772     /// Takes the absolute value of each element in `self`
773     #[inline]
774     #[must_use]
abs(&self) -> Self775     pub fn abs(&self) -> Self {
776         Self::from_cols(self.x_axis.abs(), self.y_axis.abs(), self.z_axis.abs())
777     }
778 
779     #[inline]
as_dmat3(&self) -> DMat3780     pub fn as_dmat3(&self) -> DMat3 {
781         DMat3::from_cols(
782             self.x_axis.as_dvec3(),
783             self.y_axis.as_dvec3(),
784             self.z_axis.as_dvec3(),
785         )
786     }
787 }
788 
789 impl Default for Mat3A {
790     #[inline]
default() -> Self791     fn default() -> Self {
792         Self::IDENTITY
793     }
794 }
795 
796 impl Add<Mat3A> for Mat3A {
797     type Output = Self;
798     #[inline]
add(self, rhs: Self) -> Self::Output799     fn add(self, rhs: Self) -> Self::Output {
800         self.add_mat3(&rhs)
801     }
802 }
803 
804 impl AddAssign<Mat3A> for Mat3A {
805     #[inline]
add_assign(&mut self, rhs: Self)806     fn add_assign(&mut self, rhs: Self) {
807         *self = self.add_mat3(&rhs);
808     }
809 }
810 
811 impl Sub<Mat3A> for Mat3A {
812     type Output = Self;
813     #[inline]
sub(self, rhs: Self) -> Self::Output814     fn sub(self, rhs: Self) -> Self::Output {
815         self.sub_mat3(&rhs)
816     }
817 }
818 
819 impl SubAssign<Mat3A> for Mat3A {
820     #[inline]
sub_assign(&mut self, rhs: Self)821     fn sub_assign(&mut self, rhs: Self) {
822         *self = self.sub_mat3(&rhs);
823     }
824 }
825 
826 impl Neg for Mat3A {
827     type Output = Self;
828     #[inline]
neg(self) -> Self::Output829     fn neg(self) -> Self::Output {
830         Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
831     }
832 }
833 
834 impl Mul<Mat3A> for Mat3A {
835     type Output = Self;
836     #[inline]
mul(self, rhs: Self) -> Self::Output837     fn mul(self, rhs: Self) -> Self::Output {
838         self.mul_mat3(&rhs)
839     }
840 }
841 
842 impl MulAssign<Mat3A> for Mat3A {
843     #[inline]
mul_assign(&mut self, rhs: Self)844     fn mul_assign(&mut self, rhs: Self) {
845         *self = self.mul_mat3(&rhs);
846     }
847 }
848 
849 impl Mul<Vec3A> for Mat3A {
850     type Output = Vec3A;
851     #[inline]
mul(self, rhs: Vec3A) -> Self::Output852     fn mul(self, rhs: Vec3A) -> Self::Output {
853         self.mul_vec3a(rhs)
854     }
855 }
856 
857 impl Mul<Mat3A> for f32 {
858     type Output = Mat3A;
859     #[inline]
mul(self, rhs: Mat3A) -> Self::Output860     fn mul(self, rhs: Mat3A) -> Self::Output {
861         rhs.mul_scalar(self)
862     }
863 }
864 
865 impl Mul<f32> for Mat3A {
866     type Output = Self;
867     #[inline]
mul(self, rhs: f32) -> Self::Output868     fn mul(self, rhs: f32) -> Self::Output {
869         self.mul_scalar(rhs)
870     }
871 }
872 
873 impl MulAssign<f32> for Mat3A {
874     #[inline]
mul_assign(&mut self, rhs: f32)875     fn mul_assign(&mut self, rhs: f32) {
876         *self = self.mul_scalar(rhs);
877     }
878 }
879 
880 impl Div<Mat3A> for f32 {
881     type Output = Mat3A;
882     #[inline]
div(self, rhs: Mat3A) -> Self::Output883     fn div(self, rhs: Mat3A) -> Self::Output {
884         rhs.div_scalar(self)
885     }
886 }
887 
888 impl Div<f32> for Mat3A {
889     type Output = Self;
890     #[inline]
div(self, rhs: f32) -> Self::Output891     fn div(self, rhs: f32) -> Self::Output {
892         self.div_scalar(rhs)
893     }
894 }
895 
896 impl DivAssign<f32> for Mat3A {
897     #[inline]
div_assign(&mut self, rhs: f32)898     fn div_assign(&mut self, rhs: f32) {
899         *self = self.div_scalar(rhs);
900     }
901 }
902 
903 impl Mul<Vec3> for Mat3A {
904     type Output = Vec3;
905     #[inline]
mul(self, rhs: Vec3) -> Vec3906     fn mul(self, rhs: Vec3) -> Vec3 {
907         self.mul_vec3a(rhs.into()).into()
908     }
909 }
910 
911 impl From<Mat3> for Mat3A {
912     #[inline]
from(m: Mat3) -> Self913     fn from(m: Mat3) -> Self {
914         Self {
915             x_axis: m.x_axis.into(),
916             y_axis: m.y_axis.into(),
917             z_axis: m.z_axis.into(),
918         }
919     }
920 }
921 
922 impl Sum<Self> for Mat3A {
sum<I>(iter: I) -> Self where I: Iterator<Item = Self>,923     fn sum<I>(iter: I) -> Self
924     where
925         I: Iterator<Item = Self>,
926     {
927         iter.fold(Self::ZERO, Self::add)
928     }
929 }
930 
931 impl<'a> Sum<&'a Self> for Mat3A {
sum<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,932     fn sum<I>(iter: I) -> Self
933     where
934         I: Iterator<Item = &'a Self>,
935     {
936         iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
937     }
938 }
939 
940 impl Product for Mat3A {
product<I>(iter: I) -> Self where I: Iterator<Item = Self>,941     fn product<I>(iter: I) -> Self
942     where
943         I: Iterator<Item = Self>,
944     {
945         iter.fold(Self::IDENTITY, Self::mul)
946     }
947 }
948 
949 impl<'a> Product<&'a Self> for Mat3A {
product<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,950     fn product<I>(iter: I) -> Self
951     where
952         I: Iterator<Item = &'a Self>,
953     {
954         iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
955     }
956 }
957 
958 impl PartialEq for Mat3A {
959     #[inline]
eq(&self, rhs: &Self) -> bool960     fn eq(&self, rhs: &Self) -> bool {
961         self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
962     }
963 }
964 
965 impl fmt::Debug for Mat3A {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result966     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
967         fmt.debug_struct(stringify!(Mat3A))
968             .field("x_axis", &self.x_axis)
969             .field("y_axis", &self.y_axis)
970             .field("z_axis", &self.z_axis)
971             .finish()
972     }
973 }
974 
975 impl fmt::Display for Mat3A {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result976     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
977         if let Some(p) = f.precision() {
978             write!(
979                 f,
980                 "[{:.*}, {:.*}, {:.*}]",
981                 p, self.x_axis, p, self.y_axis, p, self.z_axis
982             )
983         } else {
984             write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
985         }
986     }
987 }
988