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