• 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, Mat3A, 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]
mat3(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Mat316 pub const fn mat3(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Mat3 {
17     Mat3::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 Mat3 {
47     pub x_axis: Vec3,
48     pub y_axis: Vec3,
49     pub z_axis: Vec3,
50 }
51 
52 impl Mat3 {
53     /// A 3x3 matrix with all elements set to `0.0`.
54     pub const ZERO: Self = Self::from_cols(Vec3::ZERO, Vec3::ZERO, Vec3::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(Vec3::X, Vec3::Y, Vec3::Z);
58 
59     /// All NAN:s.
60     pub const NAN: Self = Self::from_cols(Vec3::NAN, Vec3::NAN, Vec3::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: Vec3::new(m00, m01, m02),
78             y_axis: Vec3::new(m10, m11, m12),
79             z_axis: Vec3::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: Vec3, y_axis: Vec3, z_axis: Vec3) -> Self86     pub const fn from_cols(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> 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             Vec3::from_array(m[0]),
129             Vec3::from_array(m[1]),
130             Vec3::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             Vec3::from_vec4(m.x_axis),
162             Vec3::from_vec4(m.y_axis),
163             Vec3::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(m.y_axis.yzw(), m.z_axis.yzw(), m.w_axis.yzw()),
178             (0, 1) => Self::from_cols(m.y_axis.xzw(), m.z_axis.xzw(), m.w_axis.xzw()),
179             (0, 2) => Self::from_cols(m.y_axis.xyw(), m.z_axis.xyw(), m.w_axis.xyw()),
180             (0, 3) => Self::from_cols(m.y_axis.xyz(), m.z_axis.xyz(), m.w_axis.xyz()),
181             (1, 0) => Self::from_cols(m.x_axis.yzw(), m.z_axis.yzw(), m.w_axis.yzw()),
182             (1, 1) => Self::from_cols(m.x_axis.xzw(), m.z_axis.xzw(), m.w_axis.xzw()),
183             (1, 2) => Self::from_cols(m.x_axis.xyw(), m.z_axis.xyw(), m.w_axis.xyw()),
184             (1, 3) => Self::from_cols(m.x_axis.xyz(), m.z_axis.xyz(), m.w_axis.xyz()),
185             (2, 0) => Self::from_cols(m.x_axis.yzw(), m.y_axis.yzw(), m.w_axis.yzw()),
186             (2, 1) => Self::from_cols(m.x_axis.xzw(), m.y_axis.xzw(), m.w_axis.xzw()),
187             (2, 2) => Self::from_cols(m.x_axis.xyw(), m.y_axis.xyw(), m.w_axis.xyw()),
188             (2, 3) => Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.w_axis.xyz()),
189             (3, 0) => Self::from_cols(m.x_axis.yzw(), m.y_axis.yzw(), m.z_axis.yzw()),
190             (3, 1) => Self::from_cols(m.x_axis.xzw(), m.y_axis.xzw(), m.z_axis.xzw()),
191             (3, 2) => Self::from_cols(m.x_axis.xyw(), m.y_axis.xyw(), m.z_axis.xyw()),
192             (3, 3) => Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.z_axis.xyz()),
193             _ => panic!("index out of bounds"),
194         }
195     }
196 
197     /// Creates a 3D rotation matrix from the given quaternion.
198     ///
199     /// # Panics
200     ///
201     /// Will panic if `rotation` is not normalized when `glam_assert` is enabled.
202     #[inline]
203     #[must_use]
from_quat(rotation: Quat) -> Self204     pub fn from_quat(rotation: Quat) -> Self {
205         glam_assert!(rotation.is_normalized());
206 
207         let x2 = rotation.x + rotation.x;
208         let y2 = rotation.y + rotation.y;
209         let z2 = rotation.z + rotation.z;
210         let xx = rotation.x * x2;
211         let xy = rotation.x * y2;
212         let xz = rotation.x * z2;
213         let yy = rotation.y * y2;
214         let yz = rotation.y * z2;
215         let zz = rotation.z * z2;
216         let wx = rotation.w * x2;
217         let wy = rotation.w * y2;
218         let wz = rotation.w * z2;
219 
220         Self::from_cols(
221             Vec3::new(1.0 - (yy + zz), xy + wz, xz - wy),
222             Vec3::new(xy - wz, 1.0 - (xx + zz), yz + wx),
223             Vec3::new(xz + wy, yz - wx, 1.0 - (xx + yy)),
224         )
225     }
226 
227     /// Creates a 3D rotation matrix from a normalized rotation `axis` and `angle` (in
228     /// radians).
229     ///
230     /// # Panics
231     ///
232     /// Will panic if `axis` is not normalized when `glam_assert` is enabled.
233     #[inline]
234     #[must_use]
from_axis_angle(axis: Vec3, angle: f32) -> Self235     pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
236         glam_assert!(axis.is_normalized());
237 
238         let (sin, cos) = math::sin_cos(angle);
239         let (xsin, ysin, zsin) = axis.mul(sin).into();
240         let (x, y, z) = axis.into();
241         let (x2, y2, z2) = axis.mul(axis).into();
242         let omc = 1.0 - cos;
243         let xyomc = x * y * omc;
244         let xzomc = x * z * omc;
245         let yzomc = y * z * omc;
246         Self::from_cols(
247             Vec3::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
248             Vec3::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
249             Vec3::new(xzomc + ysin, yzomc - xsin, z2 * omc + cos),
250         )
251     }
252 
253     /// Creates a 3D rotation matrix from the given euler rotation sequence and the angles (in
254     /// radians).
255     #[inline]
256     #[must_use]
from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self257     pub fn from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self {
258         Self::from_euler_angles(order, a, b, c)
259     }
260 
261     /// Extract Euler angles with the given Euler rotation order.
262     ///
263     /// Note if the input matrix contains scales, shears, or other non-rotation transformations then
264     /// the resulting Euler angles will be ill-defined.
265     ///
266     /// # Panics
267     ///
268     /// Will panic if any input matrix column is not normalized when `glam_assert` is enabled.
269     #[inline]
270     #[must_use]
to_euler(&self, order: EulerRot) -> (f32, f32, f32)271     pub fn to_euler(&self, order: EulerRot) -> (f32, f32, f32) {
272         glam_assert!(
273             self.x_axis.is_normalized()
274                 && self.y_axis.is_normalized()
275                 && self.z_axis.is_normalized()
276         );
277         self.to_euler_angles(order)
278     }
279 
280     /// Creates a 3D rotation matrix from `angle` (in radians) around the x axis.
281     #[inline]
282     #[must_use]
from_rotation_x(angle: f32) -> Self283     pub fn from_rotation_x(angle: f32) -> Self {
284         let (sina, cosa) = math::sin_cos(angle);
285         Self::from_cols(
286             Vec3::X,
287             Vec3::new(0.0, cosa, sina),
288             Vec3::new(0.0, -sina, cosa),
289         )
290     }
291 
292     /// Creates a 3D rotation matrix from `angle` (in radians) around the y axis.
293     #[inline]
294     #[must_use]
from_rotation_y(angle: f32) -> Self295     pub fn from_rotation_y(angle: f32) -> Self {
296         let (sina, cosa) = math::sin_cos(angle);
297         Self::from_cols(
298             Vec3::new(cosa, 0.0, -sina),
299             Vec3::Y,
300             Vec3::new(sina, 0.0, cosa),
301         )
302     }
303 
304     /// Creates a 3D rotation matrix from `angle` (in radians) around the z axis.
305     #[inline]
306     #[must_use]
from_rotation_z(angle: f32) -> Self307     pub fn from_rotation_z(angle: f32) -> Self {
308         let (sina, cosa) = math::sin_cos(angle);
309         Self::from_cols(
310             Vec3::new(cosa, sina, 0.0),
311             Vec3::new(-sina, cosa, 0.0),
312             Vec3::Z,
313         )
314     }
315 
316     /// Creates an affine transformation matrix from the given 2D `translation`.
317     ///
318     /// The resulting matrix can be used to transform 2D points and vectors. See
319     /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
320     #[inline]
321     #[must_use]
from_translation(translation: Vec2) -> Self322     pub fn from_translation(translation: Vec2) -> Self {
323         Self::from_cols(
324             Vec3::X,
325             Vec3::Y,
326             Vec3::new(translation.x, translation.y, 1.0),
327         )
328     }
329 
330     /// Creates an affine transformation matrix from the given 2D rotation `angle` (in
331     /// radians).
332     ///
333     /// The resulting matrix can be used to transform 2D points and vectors. See
334     /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
335     #[inline]
336     #[must_use]
from_angle(angle: f32) -> Self337     pub fn from_angle(angle: f32) -> Self {
338         let (sin, cos) = math::sin_cos(angle);
339         Self::from_cols(Vec3::new(cos, sin, 0.0), Vec3::new(-sin, cos, 0.0), Vec3::Z)
340     }
341 
342     /// Creates an affine transformation matrix from the given 2D `scale`, rotation `angle` (in
343     /// radians) and `translation`.
344     ///
345     /// The resulting matrix can be used to transform 2D points and vectors. See
346     /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
347     #[inline]
348     #[must_use]
from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self349     pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
350         let (sin, cos) = math::sin_cos(angle);
351         Self::from_cols(
352             Vec3::new(cos * scale.x, sin * scale.x, 0.0),
353             Vec3::new(-sin * scale.y, cos * scale.y, 0.0),
354             Vec3::new(translation.x, translation.y, 1.0),
355         )
356     }
357 
358     /// Creates an affine transformation matrix from the given non-uniform 2D `scale`.
359     ///
360     /// The resulting matrix can be used to transform 2D points and vectors. See
361     /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
362     ///
363     /// # Panics
364     ///
365     /// Will panic if all elements of `scale` are zero when `glam_assert` is enabled.
366     #[inline]
367     #[must_use]
from_scale(scale: Vec2) -> Self368     pub fn from_scale(scale: Vec2) -> Self {
369         // Do not panic as long as any component is non-zero
370         glam_assert!(scale.cmpne(Vec2::ZERO).any());
371 
372         Self::from_cols(
373             Vec3::new(scale.x, 0.0, 0.0),
374             Vec3::new(0.0, scale.y, 0.0),
375             Vec3::Z,
376         )
377     }
378 
379     /// Creates an affine transformation matrix from the given 2x2 matrix.
380     ///
381     /// The resulting matrix can be used to transform 2D points and vectors. See
382     /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
383     #[inline]
from_mat2(m: Mat2) -> Self384     pub fn from_mat2(m: Mat2) -> Self {
385         Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), Vec3::Z)
386     }
387 
388     /// Creates a 3x3 matrix from the first 9 values in `slice`.
389     ///
390     /// # Panics
391     ///
392     /// Panics if `slice` is less than 9 elements long.
393     #[inline]
394     #[must_use]
from_cols_slice(slice: &[f32]) -> Self395     pub const fn from_cols_slice(slice: &[f32]) -> Self {
396         Self::new(
397             slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
398             slice[8],
399         )
400     }
401 
402     /// Writes the columns of `self` to the first 9 elements in `slice`.
403     ///
404     /// # Panics
405     ///
406     /// Panics if `slice` is less than 9 elements long.
407     #[inline]
write_cols_to_slice(self, slice: &mut [f32])408     pub fn write_cols_to_slice(self, slice: &mut [f32]) {
409         slice[0] = self.x_axis.x;
410         slice[1] = self.x_axis.y;
411         slice[2] = self.x_axis.z;
412         slice[3] = self.y_axis.x;
413         slice[4] = self.y_axis.y;
414         slice[5] = self.y_axis.z;
415         slice[6] = self.z_axis.x;
416         slice[7] = self.z_axis.y;
417         slice[8] = self.z_axis.z;
418     }
419 
420     /// Returns the matrix column for the given `index`.
421     ///
422     /// # Panics
423     ///
424     /// Panics if `index` is greater than 2.
425     #[inline]
426     #[must_use]
col(&self, index: usize) -> Vec3427     pub fn col(&self, index: usize) -> Vec3 {
428         match index {
429             0 => self.x_axis,
430             1 => self.y_axis,
431             2 => self.z_axis,
432             _ => panic!("index out of bounds"),
433         }
434     }
435 
436     /// Returns a mutable reference to the matrix column for the given `index`.
437     ///
438     /// # Panics
439     ///
440     /// Panics if `index` is greater than 2.
441     #[inline]
col_mut(&mut self, index: usize) -> &mut Vec3442     pub fn col_mut(&mut self, index: usize) -> &mut Vec3 {
443         match index {
444             0 => &mut self.x_axis,
445             1 => &mut self.y_axis,
446             2 => &mut self.z_axis,
447             _ => panic!("index out of bounds"),
448         }
449     }
450 
451     /// Returns the matrix row for the given `index`.
452     ///
453     /// # Panics
454     ///
455     /// Panics if `index` is greater than 2.
456     #[inline]
457     #[must_use]
row(&self, index: usize) -> Vec3458     pub fn row(&self, index: usize) -> Vec3 {
459         match index {
460             0 => Vec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
461             1 => Vec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
462             2 => Vec3::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
463             _ => panic!("index out of bounds"),
464         }
465     }
466 
467     /// Returns `true` if, and only if, all elements are finite.
468     /// If any element is either `NaN`, positive or negative infinity, this will return `false`.
469     #[inline]
470     #[must_use]
is_finite(&self) -> bool471     pub fn is_finite(&self) -> bool {
472         self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
473     }
474 
475     /// Returns `true` if any elements are `NaN`.
476     #[inline]
477     #[must_use]
is_nan(&self) -> bool478     pub fn is_nan(&self) -> bool {
479         self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
480     }
481 
482     /// Returns the transpose of `self`.
483     #[inline]
484     #[must_use]
transpose(&self) -> Self485     pub fn transpose(&self) -> Self {
486         Self {
487             x_axis: Vec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
488             y_axis: Vec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
489             z_axis: Vec3::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
490         }
491     }
492 
493     /// Returns the determinant of `self`.
494     #[inline]
495     #[must_use]
determinant(&self) -> f32496     pub fn determinant(&self) -> f32 {
497         self.z_axis.dot(self.x_axis.cross(self.y_axis))
498     }
499 
500     /// Returns the inverse of `self`.
501     ///
502     /// If the matrix is not invertible the returned matrix will be invalid.
503     ///
504     /// # Panics
505     ///
506     /// Will panic if the determinant of `self` is zero when `glam_assert` is enabled.
507     #[inline]
508     #[must_use]
inverse(&self) -> Self509     pub fn inverse(&self) -> Self {
510         let tmp0 = self.y_axis.cross(self.z_axis);
511         let tmp1 = self.z_axis.cross(self.x_axis);
512         let tmp2 = self.x_axis.cross(self.y_axis);
513         let det = self.z_axis.dot(tmp2);
514         glam_assert!(det != 0.0);
515         let inv_det = Vec3::splat(det.recip());
516         Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose()
517     }
518 
519     /// Transforms the given 2D vector as a point.
520     ///
521     /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `1`.
522     ///
523     /// This method assumes that `self` contains a valid affine transform.
524     ///
525     /// # Panics
526     ///
527     /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
528     #[inline]
529     #[must_use]
transform_point2(&self, rhs: Vec2) -> Vec2530     pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
531         glam_assert!(self.row(2).abs_diff_eq(Vec3::Z, 1e-6));
532         Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
533     }
534 
535     /// Rotates the given 2D vector.
536     ///
537     /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `0`.
538     ///
539     /// This method assumes that `self` contains a valid affine transform.
540     ///
541     /// # Panics
542     ///
543     /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
544     #[inline]
545     #[must_use]
transform_vector2(&self, rhs: Vec2) -> Vec2546     pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
547         glam_assert!(self.row(2).abs_diff_eq(Vec3::Z, 1e-6));
548         Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
549     }
550 
551     /// Creates a left-handed view matrix using a facing direction and an up direction.
552     ///
553     /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`.
554     ///
555     /// # Panics
556     ///
557     /// Will panic if `dir` or `up` are not normalized when `glam_assert` is enabled.
558     #[inline]
559     #[must_use]
look_to_lh(dir: Vec3, up: Vec3) -> Self560     pub fn look_to_lh(dir: Vec3, up: Vec3) -> Self {
561         Self::look_to_rh(-dir, up)
562     }
563 
564     /// Creates a right-handed view matrix using a facing direction and an up direction.
565     ///
566     /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`.
567     ///
568     /// # Panics
569     ///
570     /// Will panic if `dir` or `up` are not normalized when `glam_assert` is enabled.
571     #[inline]
572     #[must_use]
look_to_rh(dir: Vec3, up: Vec3) -> Self573     pub fn look_to_rh(dir: Vec3, up: Vec3) -> Self {
574         glam_assert!(dir.is_normalized());
575         glam_assert!(up.is_normalized());
576         let f = dir;
577         let s = f.cross(up).normalize();
578         let u = s.cross(f);
579 
580         Self::from_cols(
581             Vec3::new(s.x, u.x, -f.x),
582             Vec3::new(s.y, u.y, -f.y),
583             Vec3::new(s.z, u.z, -f.z),
584         )
585     }
586 
587     /// Creates a left-handed view matrix using a camera position, a focal point and an up
588     /// direction.
589     ///
590     /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`.
591     ///
592     /// # Panics
593     ///
594     /// Will panic if `up` is not normalized when `glam_assert` is enabled.
595     #[inline]
596     #[must_use]
look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self597     pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
598         Self::look_to_lh(center.sub(eye).normalize(), up)
599     }
600 
601     /// Creates a right-handed view matrix using a camera position, a focal point and an up
602     /// direction.
603     ///
604     /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`.
605     ///
606     /// # Panics
607     ///
608     /// Will panic if `up` is not normalized when `glam_assert` is enabled.
609     #[inline]
look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self610     pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
611         Self::look_to_rh(center.sub(eye).normalize(), up)
612     }
613 
614     /// Transforms a 3D vector.
615     #[inline]
616     #[must_use]
mul_vec3(&self, rhs: Vec3) -> Vec3617     pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
618         let mut res = self.x_axis.mul(rhs.x);
619         res = res.add(self.y_axis.mul(rhs.y));
620         res = res.add(self.z_axis.mul(rhs.z));
621         res
622     }
623 
624     /// Transforms a [`Vec3A`].
625     #[inline]
626     #[must_use]
mul_vec3a(&self, rhs: Vec3A) -> Vec3A627     pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
628         self.mul_vec3(rhs.into()).into()
629     }
630 
631     /// Multiplies two 3x3 matrices.
632     #[inline]
633     #[must_use]
mul_mat3(&self, rhs: &Self) -> Self634     pub fn mul_mat3(&self, rhs: &Self) -> Self {
635         Self::from_cols(
636             self.mul(rhs.x_axis),
637             self.mul(rhs.y_axis),
638             self.mul(rhs.z_axis),
639         )
640     }
641 
642     /// Adds two 3x3 matrices.
643     #[inline]
644     #[must_use]
add_mat3(&self, rhs: &Self) -> Self645     pub fn add_mat3(&self, rhs: &Self) -> Self {
646         Self::from_cols(
647             self.x_axis.add(rhs.x_axis),
648             self.y_axis.add(rhs.y_axis),
649             self.z_axis.add(rhs.z_axis),
650         )
651     }
652 
653     /// Subtracts two 3x3 matrices.
654     #[inline]
655     #[must_use]
sub_mat3(&self, rhs: &Self) -> Self656     pub fn sub_mat3(&self, rhs: &Self) -> Self {
657         Self::from_cols(
658             self.x_axis.sub(rhs.x_axis),
659             self.y_axis.sub(rhs.y_axis),
660             self.z_axis.sub(rhs.z_axis),
661         )
662     }
663 
664     /// Multiplies a 3x3 matrix by a scalar.
665     #[inline]
666     #[must_use]
mul_scalar(&self, rhs: f32) -> Self667     pub fn mul_scalar(&self, rhs: f32) -> Self {
668         Self::from_cols(
669             self.x_axis.mul(rhs),
670             self.y_axis.mul(rhs),
671             self.z_axis.mul(rhs),
672         )
673     }
674 
675     /// Divides a 3x3 matrix by a scalar.
676     #[inline]
677     #[must_use]
div_scalar(&self, rhs: f32) -> Self678     pub fn div_scalar(&self, rhs: f32) -> Self {
679         let rhs = Vec3::splat(rhs);
680         Self::from_cols(
681             self.x_axis.div(rhs),
682             self.y_axis.div(rhs),
683             self.z_axis.div(rhs),
684         )
685     }
686 
687     /// Returns true if the absolute difference of all elements between `self` and `rhs`
688     /// is less than or equal to `max_abs_diff`.
689     ///
690     /// This can be used to compare if two matrices contain similar elements. It works best
691     /// when comparing with a known value. The `max_abs_diff` that should be used used
692     /// depends on the values being compared against.
693     ///
694     /// For more see
695     /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
696     #[inline]
697     #[must_use]
abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool698     pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
699         self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
700             && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
701             && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
702     }
703 
704     /// Takes the absolute value of each element in `self`
705     #[inline]
706     #[must_use]
abs(&self) -> Self707     pub fn abs(&self) -> Self {
708         Self::from_cols(self.x_axis.abs(), self.y_axis.abs(), self.z_axis.abs())
709     }
710 
711     #[inline]
as_dmat3(&self) -> DMat3712     pub fn as_dmat3(&self) -> DMat3 {
713         DMat3::from_cols(
714             self.x_axis.as_dvec3(),
715             self.y_axis.as_dvec3(),
716             self.z_axis.as_dvec3(),
717         )
718     }
719 }
720 
721 impl Default for Mat3 {
722     #[inline]
default() -> Self723     fn default() -> Self {
724         Self::IDENTITY
725     }
726 }
727 
728 impl Add<Mat3> for Mat3 {
729     type Output = Self;
730     #[inline]
add(self, rhs: Self) -> Self::Output731     fn add(self, rhs: Self) -> Self::Output {
732         self.add_mat3(&rhs)
733     }
734 }
735 
736 impl AddAssign<Mat3> for Mat3 {
737     #[inline]
add_assign(&mut self, rhs: Self)738     fn add_assign(&mut self, rhs: Self) {
739         *self = self.add_mat3(&rhs);
740     }
741 }
742 
743 impl Sub<Mat3> for Mat3 {
744     type Output = Self;
745     #[inline]
sub(self, rhs: Self) -> Self::Output746     fn sub(self, rhs: Self) -> Self::Output {
747         self.sub_mat3(&rhs)
748     }
749 }
750 
751 impl SubAssign<Mat3> for Mat3 {
752     #[inline]
sub_assign(&mut self, rhs: Self)753     fn sub_assign(&mut self, rhs: Self) {
754         *self = self.sub_mat3(&rhs);
755     }
756 }
757 
758 impl Neg for Mat3 {
759     type Output = Self;
760     #[inline]
neg(self) -> Self::Output761     fn neg(self) -> Self::Output {
762         Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
763     }
764 }
765 
766 impl Mul<Mat3> for Mat3 {
767     type Output = Self;
768     #[inline]
mul(self, rhs: Self) -> Self::Output769     fn mul(self, rhs: Self) -> Self::Output {
770         self.mul_mat3(&rhs)
771     }
772 }
773 
774 impl MulAssign<Mat3> for Mat3 {
775     #[inline]
mul_assign(&mut self, rhs: Self)776     fn mul_assign(&mut self, rhs: Self) {
777         *self = self.mul_mat3(&rhs);
778     }
779 }
780 
781 impl Mul<Vec3> for Mat3 {
782     type Output = Vec3;
783     #[inline]
mul(self, rhs: Vec3) -> Self::Output784     fn mul(self, rhs: Vec3) -> Self::Output {
785         self.mul_vec3(rhs)
786     }
787 }
788 
789 impl Mul<Mat3> for f32 {
790     type Output = Mat3;
791     #[inline]
mul(self, rhs: Mat3) -> Self::Output792     fn mul(self, rhs: Mat3) -> Self::Output {
793         rhs.mul_scalar(self)
794     }
795 }
796 
797 impl Mul<f32> for Mat3 {
798     type Output = Self;
799     #[inline]
mul(self, rhs: f32) -> Self::Output800     fn mul(self, rhs: f32) -> Self::Output {
801         self.mul_scalar(rhs)
802     }
803 }
804 
805 impl MulAssign<f32> for Mat3 {
806     #[inline]
mul_assign(&mut self, rhs: f32)807     fn mul_assign(&mut self, rhs: f32) {
808         *self = self.mul_scalar(rhs);
809     }
810 }
811 
812 impl Div<Mat3> for f32 {
813     type Output = Mat3;
814     #[inline]
div(self, rhs: Mat3) -> Self::Output815     fn div(self, rhs: Mat3) -> Self::Output {
816         rhs.div_scalar(self)
817     }
818 }
819 
820 impl Div<f32> for Mat3 {
821     type Output = Self;
822     #[inline]
div(self, rhs: f32) -> Self::Output823     fn div(self, rhs: f32) -> Self::Output {
824         self.div_scalar(rhs)
825     }
826 }
827 
828 impl DivAssign<f32> for Mat3 {
829     #[inline]
div_assign(&mut self, rhs: f32)830     fn div_assign(&mut self, rhs: f32) {
831         *self = self.div_scalar(rhs);
832     }
833 }
834 
835 impl Mul<Vec3A> for Mat3 {
836     type Output = Vec3A;
837     #[inline]
mul(self, rhs: Vec3A) -> Vec3A838     fn mul(self, rhs: Vec3A) -> Vec3A {
839         self.mul_vec3a(rhs)
840     }
841 }
842 
843 impl From<Mat3A> for Mat3 {
844     #[inline]
from(m: Mat3A) -> Self845     fn from(m: Mat3A) -> Self {
846         Self {
847             x_axis: m.x_axis.into(),
848             y_axis: m.y_axis.into(),
849             z_axis: m.z_axis.into(),
850         }
851     }
852 }
853 
854 impl Sum<Self> for Mat3 {
sum<I>(iter: I) -> Self where I: Iterator<Item = Self>,855     fn sum<I>(iter: I) -> Self
856     where
857         I: Iterator<Item = Self>,
858     {
859         iter.fold(Self::ZERO, Self::add)
860     }
861 }
862 
863 impl<'a> Sum<&'a Self> for Mat3 {
sum<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,864     fn sum<I>(iter: I) -> Self
865     where
866         I: Iterator<Item = &'a Self>,
867     {
868         iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
869     }
870 }
871 
872 impl Product for Mat3 {
product<I>(iter: I) -> Self where I: Iterator<Item = Self>,873     fn product<I>(iter: I) -> Self
874     where
875         I: Iterator<Item = Self>,
876     {
877         iter.fold(Self::IDENTITY, Self::mul)
878     }
879 }
880 
881 impl<'a> Product<&'a Self> for Mat3 {
product<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,882     fn product<I>(iter: I) -> Self
883     where
884         I: Iterator<Item = &'a Self>,
885     {
886         iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
887     }
888 }
889 
890 impl PartialEq for Mat3 {
891     #[inline]
eq(&self, rhs: &Self) -> bool892     fn eq(&self, rhs: &Self) -> bool {
893         self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
894     }
895 }
896 
897 #[cfg(not(target_arch = "spirv"))]
898 impl AsRef<[f32; 9]> for Mat3 {
899     #[inline]
as_ref(&self) -> &[f32; 9]900     fn as_ref(&self) -> &[f32; 9] {
901         unsafe { &*(self as *const Self as *const [f32; 9]) }
902     }
903 }
904 
905 #[cfg(not(target_arch = "spirv"))]
906 impl AsMut<[f32; 9]> for Mat3 {
907     #[inline]
as_mut(&mut self) -> &mut [f32; 9]908     fn as_mut(&mut self) -> &mut [f32; 9] {
909         unsafe { &mut *(self as *mut Self as *mut [f32; 9]) }
910     }
911 }
912 
913 impl fmt::Debug for Mat3 {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result914     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
915         fmt.debug_struct(stringify!(Mat3))
916             .field("x_axis", &self.x_axis)
917             .field("y_axis", &self.y_axis)
918             .field("z_axis", &self.z_axis)
919             .finish()
920     }
921 }
922 
923 impl fmt::Display for Mat3 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result924     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
925         if let Some(p) = f.precision() {
926             write!(
927                 f,
928                 "[{:.*}, {:.*}, {:.*}]",
929                 p, self.x_axis, p, self.y_axis, p, self.z_axis
930             )
931         } else {
932             write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
933         }
934     }
935 }
936