glam/f32/sse2/
mat3a.rs

1// Generated from mat.rs.tera template. Edit the template, not the generated file.
2
3use crate::{
4    euler::{FromEuler, ToEuler},
5    f32::math,
6    swizzles::*,
7    DMat3, EulerRot, Mat2, Mat3, Mat4, Quat, Vec2, Vec3, Vec3A,
8};
9use core::fmt;
10use core::iter::{Product, Sum};
11use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
12
13#[cfg(target_arch = "x86")]
14use core::arch::x86::*;
15#[cfg(target_arch = "x86_64")]
16use core::arch::x86_64::*;
17
18/// Creates a 3x3 matrix from three column vectors.
19#[inline(always)]
20#[must_use]
21pub const fn mat3a(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Mat3A {
22    Mat3A::from_cols(x_axis, y_axis, z_axis)
23}
24
25/// A 3x3 column major matrix.
26///
27/// This 3x3 matrix type features convenience methods for creating and using linear and
28/// affine transformations. If you are primarily dealing with 2D affine transformations the
29/// [`Affine2`](crate::Affine2) type is much faster and more space efficient than
30/// using a 3x3 matrix.
31///
32/// Linear transformations including 3D rotation and scale can be created using methods
33/// such as [`Self::from_diagonal()`], [`Self::from_quat()`], [`Self::from_axis_angle()`],
34/// [`Self::from_rotation_x()`], [`Self::from_rotation_y()`], or
35/// [`Self::from_rotation_z()`].
36///
37/// The resulting matrices can be use to transform 3D vectors using regular vector
38/// multiplication.
39///
40/// Affine transformations including 2D translation, rotation and scale can be created
41/// using methods such as [`Self::from_translation()`], [`Self::from_angle()`],
42/// [`Self::from_scale()`] and [`Self::from_scale_angle_translation()`].
43///
44/// The [`Self::transform_point2()`] and [`Self::transform_vector2()`] convenience methods
45/// are provided for performing affine transforms on 2D vectors and points. These multiply
46/// 2D inputs as 3D vectors with an implicit `z` value of `1` for points and `0` for
47/// vectors respectively. These methods assume that `Self` contains a valid affine
48/// transform.
49#[derive(Clone, Copy)]
50#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
51#[repr(C)]
52pub struct Mat3A {
53    pub x_axis: Vec3A,
54    pub y_axis: Vec3A,
55    pub z_axis: Vec3A,
56}
57
58impl Mat3A {
59    /// A 3x3 matrix with all elements set to `0.0`.
60    pub const ZERO: Self = Self::from_cols(Vec3A::ZERO, Vec3A::ZERO, Vec3A::ZERO);
61
62    /// A 3x3 identity matrix, where all diagonal elements are `1`, and all off-diagonal elements are `0`.
63    pub const IDENTITY: Self = Self::from_cols(Vec3A::X, Vec3A::Y, Vec3A::Z);
64
65    /// All NAN:s.
66    pub const NAN: Self = Self::from_cols(Vec3A::NAN, Vec3A::NAN, Vec3A::NAN);
67
68    #[allow(clippy::too_many_arguments)]
69    #[inline(always)]
70    #[must_use]
71    const fn new(
72        m00: f32,
73        m01: f32,
74        m02: f32,
75        m10: f32,
76        m11: f32,
77        m12: f32,
78        m20: f32,
79        m21: f32,
80        m22: f32,
81    ) -> Self {
82        Self {
83            x_axis: Vec3A::new(m00, m01, m02),
84            y_axis: Vec3A::new(m10, m11, m12),
85            z_axis: Vec3A::new(m20, m21, m22),
86        }
87    }
88
89    /// Creates a 3x3 matrix from three column vectors.
90    #[inline(always)]
91    #[must_use]
92    pub const fn from_cols(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Self {
93        Self {
94            x_axis,
95            y_axis,
96            z_axis,
97        }
98    }
99
100    /// Creates a 3x3 matrix from a `[f32; 9]` array stored in column major order.
101    /// If your data is stored in row major you will need to `transpose` the returned
102    /// matrix.
103    #[inline]
104    #[must_use]
105    pub const fn from_cols_array(m: &[f32; 9]) -> Self {
106        Self::new(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8])
107    }
108
109    /// Creates a `[f32; 9]` array storing data in column major order.
110    /// If you require data in row major order `transpose` the matrix first.
111    #[inline]
112    #[must_use]
113    pub const fn to_cols_array(&self) -> [f32; 9] {
114        let [x_axis_x, x_axis_y, x_axis_z] = self.x_axis.to_array();
115        let [y_axis_x, y_axis_y, y_axis_z] = self.y_axis.to_array();
116        let [z_axis_x, z_axis_y, z_axis_z] = self.z_axis.to_array();
117
118        [
119            x_axis_x, x_axis_y, x_axis_z, y_axis_x, y_axis_y, y_axis_z, z_axis_x, z_axis_y,
120            z_axis_z,
121        ]
122    }
123
124    /// Creates a 3x3 matrix from a `[[f32; 3]; 3]` 3D array stored in column major order.
125    /// If your data is in row major order you will need to `transpose` the returned
126    /// matrix.
127    #[inline]
128    #[must_use]
129    pub const fn from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self {
130        Self::from_cols(
131            Vec3A::from_array(m[0]),
132            Vec3A::from_array(m[1]),
133            Vec3A::from_array(m[2]),
134        )
135    }
136
137    /// Creates a `[[f32; 3]; 3]` 3D array storing data in column major order.
138    /// If you require data in row major order `transpose` the matrix first.
139    #[inline]
140    #[must_use]
141    pub const fn to_cols_array_2d(&self) -> [[f32; 3]; 3] {
142        [
143            self.x_axis.to_array(),
144            self.y_axis.to_array(),
145            self.z_axis.to_array(),
146        ]
147    }
148
149    /// Creates a 3x3 matrix with its diagonal set to `diagonal` and all other entries set to 0.
150    #[doc(alias = "scale")]
151    #[inline]
152    #[must_use]
153    pub const fn from_diagonal(diagonal: Vec3) -> Self {
154        Self::new(
155            diagonal.x, 0.0, 0.0, 0.0, diagonal.y, 0.0, 0.0, 0.0, diagonal.z,
156        )
157    }
158
159    /// Creates a 3x3 matrix from a 4x4 matrix, discarding the 4th row and column.
160    #[inline]
161    #[must_use]
162    pub fn from_mat4(m: Mat4) -> Self {
163        Self::from_cols(
164            Vec3A::from_vec4(m.x_axis),
165            Vec3A::from_vec4(m.y_axis),
166            Vec3A::from_vec4(m.z_axis),
167        )
168    }
169
170    /// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column
171    /// and `j`th row.
172    ///
173    /// # Panics
174    ///
175    /// Panics if `i` or `j` is greater than 3.
176    #[inline]
177    #[must_use]
178    pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self {
179        match (i, j) {
180            (0, 0) => Self::from_cols(
181                Vec3A::from_vec4(m.y_axis.yzww()),
182                Vec3A::from_vec4(m.z_axis.yzww()),
183                Vec3A::from_vec4(m.w_axis.yzww()),
184            ),
185            (0, 1) => Self::from_cols(
186                Vec3A::from_vec4(m.y_axis.xzww()),
187                Vec3A::from_vec4(m.z_axis.xzww()),
188                Vec3A::from_vec4(m.w_axis.xzww()),
189            ),
190            (0, 2) => Self::from_cols(
191                Vec3A::from_vec4(m.y_axis.xyww()),
192                Vec3A::from_vec4(m.z_axis.xyww()),
193                Vec3A::from_vec4(m.w_axis.xyww()),
194            ),
195            (0, 3) => Self::from_cols(
196                Vec3A::from_vec4(m.y_axis.xyzw()),
197                Vec3A::from_vec4(m.z_axis.xyzw()),
198                Vec3A::from_vec4(m.w_axis.xyzw()),
199            ),
200            (1, 0) => Self::from_cols(
201                Vec3A::from_vec4(m.x_axis.yzww()),
202                Vec3A::from_vec4(m.z_axis.yzww()),
203                Vec3A::from_vec4(m.w_axis.yzww()),
204            ),
205            (1, 1) => Self::from_cols(
206                Vec3A::from_vec4(m.x_axis.xzww()),
207                Vec3A::from_vec4(m.z_axis.xzww()),
208                Vec3A::from_vec4(m.w_axis.xzww()),
209            ),
210            (1, 2) => Self::from_cols(
211                Vec3A::from_vec4(m.x_axis.xyww()),
212                Vec3A::from_vec4(m.z_axis.xyww()),
213                Vec3A::from_vec4(m.w_axis.xyww()),
214            ),
215            (1, 3) => Self::from_cols(
216                Vec3A::from_vec4(m.x_axis.xyzw()),
217                Vec3A::from_vec4(m.z_axis.xyzw()),
218                Vec3A::from_vec4(m.w_axis.xyzw()),
219            ),
220            (2, 0) => Self::from_cols(
221                Vec3A::from_vec4(m.x_axis.yzww()),
222                Vec3A::from_vec4(m.y_axis.yzww()),
223                Vec3A::from_vec4(m.w_axis.yzww()),
224            ),
225            (2, 1) => Self::from_cols(
226                Vec3A::from_vec4(m.x_axis.xzww()),
227                Vec3A::from_vec4(m.y_axis.xzww()),
228                Vec3A::from_vec4(m.w_axis.xzww()),
229            ),
230            (2, 2) => Self::from_cols(
231                Vec3A::from_vec4(m.x_axis.xyww()),
232                Vec3A::from_vec4(m.y_axis.xyww()),
233                Vec3A::from_vec4(m.w_axis.xyww()),
234            ),
235            (2, 3) => Self::from_cols(
236                Vec3A::from_vec4(m.x_axis.xyzw()),
237                Vec3A::from_vec4(m.y_axis.xyzw()),
238                Vec3A::from_vec4(m.w_axis.xyzw()),
239            ),
240            (3, 0) => Self::from_cols(
241                Vec3A::from_vec4(m.x_axis.yzww()),
242                Vec3A::from_vec4(m.y_axis.yzww()),
243                Vec3A::from_vec4(m.z_axis.yzww()),
244            ),
245            (3, 1) => Self::from_cols(
246                Vec3A::from_vec4(m.x_axis.xzww()),
247                Vec3A::from_vec4(m.y_axis.xzww()),
248                Vec3A::from_vec4(m.z_axis.xzww()),
249            ),
250            (3, 2) => Self::from_cols(
251                Vec3A::from_vec4(m.x_axis.xyww()),
252                Vec3A::from_vec4(m.y_axis.xyww()),
253                Vec3A::from_vec4(m.z_axis.xyww()),
254            ),
255            (3, 3) => Self::from_cols(
256                Vec3A::from_vec4(m.x_axis.xyzw()),
257                Vec3A::from_vec4(m.y_axis.xyzw()),
258                Vec3A::from_vec4(m.z_axis.xyzw()),
259            ),
260            _ => panic!("index out of bounds"),
261        }
262    }
263
264    /// Creates a 3D rotation matrix from the given quaternion.
265    ///
266    /// # Panics
267    ///
268    /// Will panic if `rotation` is not normalized when `glam_assert` is enabled.
269    #[inline]
270    #[must_use]
271    pub fn from_quat(rotation: Quat) -> Self {
272        glam_assert!(rotation.is_normalized());
273
274        let x2 = rotation.x + rotation.x;
275        let y2 = rotation.y + rotation.y;
276        let z2 = rotation.z + rotation.z;
277        let xx = rotation.x * x2;
278        let xy = rotation.x * y2;
279        let xz = rotation.x * z2;
280        let yy = rotation.y * y2;
281        let yz = rotation.y * z2;
282        let zz = rotation.z * z2;
283        let wx = rotation.w * x2;
284        let wy = rotation.w * y2;
285        let wz = rotation.w * z2;
286
287        Self::from_cols(
288            Vec3A::new(1.0 - (yy + zz), xy + wz, xz - wy),
289            Vec3A::new(xy - wz, 1.0 - (xx + zz), yz + wx),
290            Vec3A::new(xz + wy, yz - wx, 1.0 - (xx + yy)),
291        )
292    }
293
294    /// Creates a 3D rotation matrix from a normalized rotation `axis` and `angle` (in
295    /// radians).
296    ///
297    /// # Panics
298    ///
299    /// Will panic if `axis` is not normalized when `glam_assert` is enabled.
300    #[inline]
301    #[must_use]
302    pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
303        glam_assert!(axis.is_normalized());
304
305        let (sin, cos) = math::sin_cos(angle);
306        let (xsin, ysin, zsin) = axis.mul(sin).into();
307        let (x, y, z) = axis.into();
308        let (x2, y2, z2) = axis.mul(axis).into();
309        let omc = 1.0 - cos;
310        let xyomc = x * y * omc;
311        let xzomc = x * z * omc;
312        let yzomc = y * z * omc;
313        Self::from_cols(
314            Vec3A::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
315            Vec3A::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
316            Vec3A::new(xzomc + ysin, yzomc - xsin, z2 * omc + cos),
317        )
318    }
319
320    /// Creates a 3D rotation matrix from the given euler rotation sequence and the angles (in
321    /// radians).
322    #[inline]
323    #[must_use]
324    pub fn from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self {
325        Self::from_euler_angles(order, a, b, c)
326    }
327
328    /// Extract Euler angles with the given Euler rotation order.
329    ///
330    /// Note if the input matrix contains scales, shears, or other non-rotation transformations then
331    /// the resulting Euler angles will be ill-defined.
332    ///
333    /// # Panics
334    ///
335    /// Will panic if any input matrix column is not normalized when `glam_assert` is enabled.
336    #[inline]
337    #[must_use]
338    pub fn to_euler(&self, order: EulerRot) -> (f32, f32, f32) {
339        glam_assert!(
340            self.x_axis.is_normalized()
341                && self.y_axis.is_normalized()
342                && self.z_axis.is_normalized()
343        );
344        self.to_euler_angles(order)
345    }
346
347    /// Creates a 3D rotation matrix from `angle` (in radians) around the x axis.
348    #[inline]
349    #[must_use]
350    pub fn from_rotation_x(angle: f32) -> Self {
351        let (sina, cosa) = math::sin_cos(angle);
352        Self::from_cols(
353            Vec3A::X,
354            Vec3A::new(0.0, cosa, sina),
355            Vec3A::new(0.0, -sina, cosa),
356        )
357    }
358
359    /// Creates a 3D rotation matrix from `angle` (in radians) around the y axis.
360    #[inline]
361    #[must_use]
362    pub fn from_rotation_y(angle: f32) -> Self {
363        let (sina, cosa) = math::sin_cos(angle);
364        Self::from_cols(
365            Vec3A::new(cosa, 0.0, -sina),
366            Vec3A::Y,
367            Vec3A::new(sina, 0.0, cosa),
368        )
369    }
370
371    /// Creates a 3D rotation matrix from `angle` (in radians) around the z axis.
372    #[inline]
373    #[must_use]
374    pub fn from_rotation_z(angle: f32) -> Self {
375        let (sina, cosa) = math::sin_cos(angle);
376        Self::from_cols(
377            Vec3A::new(cosa, sina, 0.0),
378            Vec3A::new(-sina, cosa, 0.0),
379            Vec3A::Z,
380        )
381    }
382
383    /// Creates an affine transformation matrix from the given 2D `translation`.
384    ///
385    /// The resulting matrix can be used to transform 2D points and vectors. See
386    /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
387    #[inline]
388    #[must_use]
389    pub fn from_translation(translation: Vec2) -> Self {
390        Self::from_cols(
391            Vec3A::X,
392            Vec3A::Y,
393            Vec3A::new(translation.x, translation.y, 1.0),
394        )
395    }
396
397    /// Creates an affine transformation matrix from the given 2D rotation `angle` (in
398    /// radians).
399    ///
400    /// The resulting matrix can be used to transform 2D points and vectors. See
401    /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
402    #[inline]
403    #[must_use]
404    pub fn from_angle(angle: f32) -> Self {
405        let (sin, cos) = math::sin_cos(angle);
406        Self::from_cols(
407            Vec3A::new(cos, sin, 0.0),
408            Vec3A::new(-sin, cos, 0.0),
409            Vec3A::Z,
410        )
411    }
412
413    /// Creates an affine transformation matrix from the given 2D `scale`, rotation `angle` (in
414    /// radians) and `translation`.
415    ///
416    /// The resulting matrix can be used to transform 2D points and vectors. See
417    /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
418    #[inline]
419    #[must_use]
420    pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
421        let (sin, cos) = math::sin_cos(angle);
422        Self::from_cols(
423            Vec3A::new(cos * scale.x, sin * scale.x, 0.0),
424            Vec3A::new(-sin * scale.y, cos * scale.y, 0.0),
425            Vec3A::new(translation.x, translation.y, 1.0),
426        )
427    }
428
429    /// Creates an affine transformation matrix from the given non-uniform 2D `scale`.
430    ///
431    /// The resulting matrix can be used to transform 2D points and vectors. See
432    /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
433    ///
434    /// # Panics
435    ///
436    /// Will panic if all elements of `scale` are zero when `glam_assert` is enabled.
437    #[inline]
438    #[must_use]
439    pub fn from_scale(scale: Vec2) -> Self {
440        // Do not panic as long as any component is non-zero
441        glam_assert!(scale.cmpne(Vec2::ZERO).any());
442
443        Self::from_cols(
444            Vec3A::new(scale.x, 0.0, 0.0),
445            Vec3A::new(0.0, scale.y, 0.0),
446            Vec3A::Z,
447        )
448    }
449
450    /// Creates an affine transformation matrix from the given 2x2 matrix.
451    ///
452    /// The resulting matrix can be used to transform 2D points and vectors. See
453    /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
454    #[inline]
455    pub fn from_mat2(m: Mat2) -> Self {
456        Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), Vec3A::Z)
457    }
458
459    /// Creates a 3x3 matrix from the first 9 values in `slice`.
460    ///
461    /// # Panics
462    ///
463    /// Panics if `slice` is less than 9 elements long.
464    #[inline]
465    #[must_use]
466    pub const fn from_cols_slice(slice: &[f32]) -> Self {
467        Self::new(
468            slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
469            slice[8],
470        )
471    }
472
473    /// Writes the columns of `self` to the first 9 elements in `slice`.
474    ///
475    /// # Panics
476    ///
477    /// Panics if `slice` is less than 9 elements long.
478    #[inline]
479    pub fn write_cols_to_slice(self, slice: &mut [f32]) {
480        slice[0] = self.x_axis.x;
481        slice[1] = self.x_axis.y;
482        slice[2] = self.x_axis.z;
483        slice[3] = self.y_axis.x;
484        slice[4] = self.y_axis.y;
485        slice[5] = self.y_axis.z;
486        slice[6] = self.z_axis.x;
487        slice[7] = self.z_axis.y;
488        slice[8] = self.z_axis.z;
489    }
490
491    /// Returns the matrix column for the given `index`.
492    ///
493    /// # Panics
494    ///
495    /// Panics if `index` is greater than 2.
496    #[inline]
497    #[must_use]
498    pub fn col(&self, index: usize) -> Vec3A {
499        match index {
500            0 => self.x_axis,
501            1 => self.y_axis,
502            2 => self.z_axis,
503            _ => panic!("index out of bounds"),
504        }
505    }
506
507    /// Returns a mutable reference to the matrix column for the given `index`.
508    ///
509    /// # Panics
510    ///
511    /// Panics if `index` is greater than 2.
512    #[inline]
513    pub fn col_mut(&mut self, index: usize) -> &mut Vec3A {
514        match index {
515            0 => &mut self.x_axis,
516            1 => &mut self.y_axis,
517            2 => &mut self.z_axis,
518            _ => panic!("index out of bounds"),
519        }
520    }
521
522    /// Returns the matrix row for the given `index`.
523    ///
524    /// # Panics
525    ///
526    /// Panics if `index` is greater than 2.
527    #[inline]
528    #[must_use]
529    pub fn row(&self, index: usize) -> Vec3A {
530        match index {
531            0 => Vec3A::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
532            1 => Vec3A::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
533            2 => Vec3A::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
534            _ => panic!("index out of bounds"),
535        }
536    }
537
538    /// Returns `true` if, and only if, all elements are finite.
539    /// If any element is either `NaN`, positive or negative infinity, this will return `false`.
540    #[inline]
541    #[must_use]
542    pub fn is_finite(&self) -> bool {
543        self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
544    }
545
546    /// Returns `true` if any elements are `NaN`.
547    #[inline]
548    #[must_use]
549    pub fn is_nan(&self) -> bool {
550        self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
551    }
552
553    /// Returns the transpose of `self`.
554    #[inline]
555    #[must_use]
556    pub fn transpose(&self) -> Self {
557        unsafe {
558            let tmp0 = _mm_shuffle_ps(self.x_axis.0, self.y_axis.0, 0b01_00_01_00);
559            let tmp1 = _mm_shuffle_ps(self.x_axis.0, self.y_axis.0, 0b11_10_11_10);
560
561            Self {
562                x_axis: Vec3A(_mm_shuffle_ps(tmp0, self.z_axis.0, 0b00_00_10_00)),
563                y_axis: Vec3A(_mm_shuffle_ps(tmp0, self.z_axis.0, 0b01_01_11_01)),
564                z_axis: Vec3A(_mm_shuffle_ps(tmp1, self.z_axis.0, 0b10_10_10_00)),
565            }
566        }
567    }
568
569    /// Returns the determinant of `self`.
570    #[inline]
571    #[must_use]
572    pub fn determinant(&self) -> f32 {
573        self.z_axis.dot(self.x_axis.cross(self.y_axis))
574    }
575
576    /// Returns the inverse of `self`.
577    ///
578    /// If the matrix is not invertible the returned matrix will be invalid.
579    ///
580    /// # Panics
581    ///
582    /// Will panic if the determinant of `self` is zero when `glam_assert` is enabled.
583    #[inline]
584    #[must_use]
585    pub fn inverse(&self) -> Self {
586        let tmp0 = self.y_axis.cross(self.z_axis);
587        let tmp1 = self.z_axis.cross(self.x_axis);
588        let tmp2 = self.x_axis.cross(self.y_axis);
589        let det = self.z_axis.dot(tmp2);
590        glam_assert!(det != 0.0);
591        let inv_det = Vec3A::splat(det.recip());
592        Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose()
593    }
594
595    /// Transforms the given 2D vector as a point.
596    ///
597    /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `1`.
598    ///
599    /// This method assumes that `self` contains a valid affine transform.
600    ///
601    /// # Panics
602    ///
603    /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
604    #[inline]
605    #[must_use]
606    pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
607        glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
608        Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
609    }
610
611    /// Rotates the given 2D vector.
612    ///
613    /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `0`.
614    ///
615    /// This method assumes that `self` contains a valid affine transform.
616    ///
617    /// # Panics
618    ///
619    /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
620    #[inline]
621    #[must_use]
622    pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
623        glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
624        Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
625    }
626
627    /// Creates a left-handed view matrix using a facing direction and an up direction.
628    ///
629    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`.
630    ///
631    /// # Panics
632    ///
633    /// Will panic if `dir` or `up` are not normalized when `glam_assert` is enabled.
634    #[inline]
635    #[must_use]
636    pub fn look_to_lh(dir: Vec3, up: Vec3) -> Self {
637        Self::look_to_rh(-dir, up)
638    }
639
640    /// Creates a right-handed view matrix using a facing direction and an up direction.
641    ///
642    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`.
643    ///
644    /// # Panics
645    ///
646    /// Will panic if `dir` or `up` are not normalized when `glam_assert` is enabled.
647    #[inline]
648    #[must_use]
649    pub fn look_to_rh(dir: Vec3, up: Vec3) -> Self {
650        glam_assert!(dir.is_normalized());
651        glam_assert!(up.is_normalized());
652        let f = dir;
653        let s = f.cross(up).normalize();
654        let u = s.cross(f);
655
656        Self::from_cols(
657            Vec3A::new(s.x, u.x, -f.x),
658            Vec3A::new(s.y, u.y, -f.y),
659            Vec3A::new(s.z, u.z, -f.z),
660        )
661    }
662
663    /// Creates a left-handed view matrix using a camera position, a focal point and an up
664    /// direction.
665    ///
666    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`.
667    ///
668    /// # Panics
669    ///
670    /// Will panic if `up` is not normalized when `glam_assert` is enabled.
671    #[inline]
672    #[must_use]
673    pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
674        Self::look_to_lh(center.sub(eye).normalize(), up)
675    }
676
677    /// Creates a right-handed view matrix using a camera position, a focal point and an up
678    /// direction.
679    ///
680    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`.
681    ///
682    /// # Panics
683    ///
684    /// Will panic if `up` is not normalized when `glam_assert` is enabled.
685    #[inline]
686    pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
687        Self::look_to_rh(center.sub(eye).normalize(), up)
688    }
689
690    /// Transforms a 3D vector.
691    #[inline]
692    #[must_use]
693    pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
694        self.mul_vec3a(rhs.into()).into()
695    }
696
697    /// Transforms a [`Vec3A`].
698    #[inline]
699    #[must_use]
700    pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
701        let mut res = self.x_axis.mul(rhs.xxx());
702        res = res.add(self.y_axis.mul(rhs.yyy()));
703        res = res.add(self.z_axis.mul(rhs.zzz()));
704        res
705    }
706
707    /// Multiplies two 3x3 matrices.
708    #[inline]
709    #[must_use]
710    pub fn mul_mat3(&self, rhs: &Self) -> Self {
711        self.mul(rhs)
712    }
713
714    /// Adds two 3x3 matrices.
715    #[inline]
716    #[must_use]
717    pub fn add_mat3(&self, rhs: &Self) -> Self {
718        self.add(rhs)
719    }
720
721    /// Subtracts two 3x3 matrices.
722    #[inline]
723    #[must_use]
724    pub fn sub_mat3(&self, rhs: &Self) -> Self {
725        self.sub(rhs)
726    }
727
728    /// Multiplies a 3x3 matrix by a scalar.
729    #[inline]
730    #[must_use]
731    pub fn mul_scalar(&self, rhs: f32) -> Self {
732        Self::from_cols(
733            self.x_axis.mul(rhs),
734            self.y_axis.mul(rhs),
735            self.z_axis.mul(rhs),
736        )
737    }
738
739    /// Divides a 3x3 matrix by a scalar.
740    #[inline]
741    #[must_use]
742    pub fn div_scalar(&self, rhs: f32) -> Self {
743        let rhs = Vec3A::splat(rhs);
744        Self::from_cols(
745            self.x_axis.div(rhs),
746            self.y_axis.div(rhs),
747            self.z_axis.div(rhs),
748        )
749    }
750
751    /// Returns true if the absolute difference of all elements between `self` and `rhs`
752    /// is less than or equal to `max_abs_diff`.
753    ///
754    /// This can be used to compare if two matrices contain similar elements. It works best
755    /// when comparing with a known value. The `max_abs_diff` that should be used used
756    /// depends on the values being compared against.
757    ///
758    /// For more see
759    /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
760    #[inline]
761    #[must_use]
762    pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
763        self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
764            && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
765            && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
766    }
767
768    /// Takes the absolute value of each element in `self`
769    #[inline]
770    #[must_use]
771    pub fn abs(&self) -> Self {
772        Self::from_cols(self.x_axis.abs(), self.y_axis.abs(), self.z_axis.abs())
773    }
774
775    #[inline]
776    pub fn as_dmat3(&self) -> DMat3 {
777        DMat3::from_cols(
778            self.x_axis.as_dvec3(),
779            self.y_axis.as_dvec3(),
780            self.z_axis.as_dvec3(),
781        )
782    }
783}
784
785impl Default for Mat3A {
786    #[inline]
787    fn default() -> Self {
788        Self::IDENTITY
789    }
790}
791
792impl Add for Mat3A {
793    type Output = Self;
794    #[inline]
795    fn add(self, rhs: Self) -> Self {
796        Self::from_cols(
797            self.x_axis.add(rhs.x_axis),
798            self.y_axis.add(rhs.y_axis),
799            self.z_axis.add(rhs.z_axis),
800        )
801    }
802}
803
804impl Add<&Self> for Mat3A {
805    type Output = Self;
806    #[inline]
807    fn add(self, rhs: &Self) -> Self {
808        self.add(*rhs)
809    }
810}
811
812impl Add<&Mat3A> for &Mat3A {
813    type Output = Mat3A;
814    #[inline]
815    fn add(self, rhs: &Mat3A) -> Mat3A {
816        (*self).add(*rhs)
817    }
818}
819
820impl Add<Mat3A> for &Mat3A {
821    type Output = Mat3A;
822    #[inline]
823    fn add(self, rhs: Mat3A) -> Mat3A {
824        (*self).add(rhs)
825    }
826}
827
828impl AddAssign for Mat3A {
829    #[inline]
830    fn add_assign(&mut self, rhs: Self) {
831        *self = self.add(rhs);
832    }
833}
834
835impl AddAssign<&Self> for Mat3A {
836    #[inline]
837    fn add_assign(&mut self, rhs: &Self) {
838        self.add_assign(*rhs);
839    }
840}
841
842impl Sub for Mat3A {
843    type Output = Self;
844    #[inline]
845    fn sub(self, rhs: Self) -> Self {
846        Self::from_cols(
847            self.x_axis.sub(rhs.x_axis),
848            self.y_axis.sub(rhs.y_axis),
849            self.z_axis.sub(rhs.z_axis),
850        )
851    }
852}
853
854impl Sub<&Self> for Mat3A {
855    type Output = Self;
856    #[inline]
857    fn sub(self, rhs: &Self) -> Self {
858        self.sub(*rhs)
859    }
860}
861
862impl Sub<&Mat3A> for &Mat3A {
863    type Output = Mat3A;
864    #[inline]
865    fn sub(self, rhs: &Mat3A) -> Mat3A {
866        (*self).sub(*rhs)
867    }
868}
869
870impl Sub<Mat3A> for &Mat3A {
871    type Output = Mat3A;
872    #[inline]
873    fn sub(self, rhs: Mat3A) -> Mat3A {
874        (*self).sub(rhs)
875    }
876}
877
878impl SubAssign for Mat3A {
879    #[inline]
880    fn sub_assign(&mut self, rhs: Self) {
881        *self = self.sub(rhs);
882    }
883}
884
885impl SubAssign<&Self> for Mat3A {
886    #[inline]
887    fn sub_assign(&mut self, rhs: &Self) {
888        self.sub_assign(*rhs);
889    }
890}
891
892impl Neg for Mat3A {
893    type Output = Self;
894    #[inline]
895    fn neg(self) -> Self::Output {
896        Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
897    }
898}
899
900impl Neg for &Mat3A {
901    type Output = Mat3A;
902    #[inline]
903    fn neg(self) -> Mat3A {
904        (*self).neg()
905    }
906}
907
908impl Mul for Mat3A {
909    type Output = Self;
910    #[inline]
911    fn mul(self, rhs: Self) -> Self {
912        Self::from_cols(
913            self.mul(rhs.x_axis),
914            self.mul(rhs.y_axis),
915            self.mul(rhs.z_axis),
916        )
917    }
918}
919
920impl Mul<&Self> for Mat3A {
921    type Output = Self;
922    #[inline]
923    fn mul(self, rhs: &Self) -> Self {
924        self.mul(*rhs)
925    }
926}
927
928impl Mul<&Mat3A> for &Mat3A {
929    type Output = Mat3A;
930    #[inline]
931    fn mul(self, rhs: &Mat3A) -> Mat3A {
932        (*self).mul(*rhs)
933    }
934}
935
936impl Mul<Mat3A> for &Mat3A {
937    type Output = Mat3A;
938    #[inline]
939    fn mul(self, rhs: Mat3A) -> Mat3A {
940        (*self).mul(rhs)
941    }
942}
943
944impl MulAssign for Mat3A {
945    #[inline]
946    fn mul_assign(&mut self, rhs: Self) {
947        *self = self.mul(rhs);
948    }
949}
950
951impl MulAssign<&Self> for Mat3A {
952    #[inline]
953    fn mul_assign(&mut self, rhs: &Self) {
954        self.mul_assign(*rhs);
955    }
956}
957
958impl Mul<Vec3A> for Mat3A {
959    type Output = Vec3A;
960    #[inline]
961    fn mul(self, rhs: Vec3A) -> Self::Output {
962        self.mul_vec3a(rhs)
963    }
964}
965
966impl Mul<&Vec3A> for Mat3A {
967    type Output = Vec3A;
968    #[inline]
969    fn mul(self, rhs: &Vec3A) -> Vec3A {
970        self.mul(*rhs)
971    }
972}
973
974impl Mul<&Vec3A> for &Mat3A {
975    type Output = Vec3A;
976    #[inline]
977    fn mul(self, rhs: &Vec3A) -> Vec3A {
978        (*self).mul(*rhs)
979    }
980}
981
982impl Mul<Vec3A> for &Mat3A {
983    type Output = Vec3A;
984    #[inline]
985    fn mul(self, rhs: Vec3A) -> Vec3A {
986        (*self).mul(rhs)
987    }
988}
989
990impl Mul<Mat3A> for f32 {
991    type Output = Mat3A;
992    #[inline]
993    fn mul(self, rhs: Mat3A) -> Self::Output {
994        rhs.mul_scalar(self)
995    }
996}
997
998impl Mul<&Mat3A> for f32 {
999    type Output = Mat3A;
1000    #[inline]
1001    fn mul(self, rhs: &Mat3A) -> Mat3A {
1002        self.mul(*rhs)
1003    }
1004}
1005
1006impl Mul<&Mat3A> for &f32 {
1007    type Output = Mat3A;
1008    #[inline]
1009    fn mul(self, rhs: &Mat3A) -> Mat3A {
1010        (*self).mul(*rhs)
1011    }
1012}
1013
1014impl Mul<Mat3A> for &f32 {
1015    type Output = Mat3A;
1016    #[inline]
1017    fn mul(self, rhs: Mat3A) -> Mat3A {
1018        (*self).mul(rhs)
1019    }
1020}
1021
1022impl Mul<f32> for Mat3A {
1023    type Output = Self;
1024    #[inline]
1025    fn mul(self, rhs: f32) -> Self {
1026        self.mul_scalar(rhs)
1027    }
1028}
1029
1030impl Mul<&f32> for Mat3A {
1031    type Output = Self;
1032    #[inline]
1033    fn mul(self, rhs: &f32) -> Self {
1034        self.mul(*rhs)
1035    }
1036}
1037
1038impl Mul<&f32> for &Mat3A {
1039    type Output = Mat3A;
1040    #[inline]
1041    fn mul(self, rhs: &f32) -> Mat3A {
1042        (*self).mul(*rhs)
1043    }
1044}
1045
1046impl Mul<f32> for &Mat3A {
1047    type Output = Mat3A;
1048    #[inline]
1049    fn mul(self, rhs: f32) -> Mat3A {
1050        (*self).mul(rhs)
1051    }
1052}
1053
1054impl MulAssign<f32> for Mat3A {
1055    #[inline]
1056    fn mul_assign(&mut self, rhs: f32) {
1057        *self = self.mul(rhs);
1058    }
1059}
1060
1061impl MulAssign<&f32> for Mat3A {
1062    #[inline]
1063    fn mul_assign(&mut self, rhs: &f32) {
1064        self.mul_assign(*rhs);
1065    }
1066}
1067
1068impl Div<Mat3A> for f32 {
1069    type Output = Mat3A;
1070    #[inline]
1071    fn div(self, rhs: Mat3A) -> Self::Output {
1072        rhs.div_scalar(self)
1073    }
1074}
1075
1076impl Div<&Mat3A> for f32 {
1077    type Output = Mat3A;
1078    #[inline]
1079    fn div(self, rhs: &Mat3A) -> Mat3A {
1080        self.div(*rhs)
1081    }
1082}
1083
1084impl Div<&Mat3A> for &f32 {
1085    type Output = Mat3A;
1086    #[inline]
1087    fn div(self, rhs: &Mat3A) -> Mat3A {
1088        (*self).div(*rhs)
1089    }
1090}
1091
1092impl Div<Mat3A> for &f32 {
1093    type Output = Mat3A;
1094    #[inline]
1095    fn div(self, rhs: Mat3A) -> Mat3A {
1096        (*self).div(rhs)
1097    }
1098}
1099
1100impl Div<f32> for Mat3A {
1101    type Output = Self;
1102    #[inline]
1103    fn div(self, rhs: f32) -> Self {
1104        self.div_scalar(rhs)
1105    }
1106}
1107
1108impl Div<&f32> for Mat3A {
1109    type Output = Self;
1110    #[inline]
1111    fn div(self, rhs: &f32) -> Self {
1112        self.div(*rhs)
1113    }
1114}
1115
1116impl Div<&f32> for &Mat3A {
1117    type Output = Mat3A;
1118    #[inline]
1119    fn div(self, rhs: &f32) -> Mat3A {
1120        (*self).div(*rhs)
1121    }
1122}
1123
1124impl Div<f32> for &Mat3A {
1125    type Output = Mat3A;
1126    #[inline]
1127    fn div(self, rhs: f32) -> Mat3A {
1128        (*self).div(rhs)
1129    }
1130}
1131
1132impl DivAssign<f32> for Mat3A {
1133    #[inline]
1134    fn div_assign(&mut self, rhs: f32) {
1135        *self = self.div(rhs);
1136    }
1137}
1138
1139impl DivAssign<&f32> for Mat3A {
1140    #[inline]
1141    fn div_assign(&mut self, rhs: &f32) {
1142        self.div_assign(*rhs);
1143    }
1144}
1145
1146impl Mul<Vec3> for Mat3A {
1147    type Output = Vec3;
1148    #[inline]
1149    fn mul(self, rhs: Vec3) -> Vec3 {
1150        self.mul_vec3a(rhs.into()).into()
1151    }
1152}
1153
1154impl Mul<&Vec3> for Mat3A {
1155    type Output = Vec3;
1156    #[inline]
1157    fn mul(self, rhs: &Vec3) -> Vec3 {
1158        self.mul(*rhs)
1159    }
1160}
1161
1162impl Mul<&Vec3> for &Mat3A {
1163    type Output = Vec3;
1164    #[inline]
1165    fn mul(self, rhs: &Vec3) -> Vec3 {
1166        (*self).mul(*rhs)
1167    }
1168}
1169
1170impl Mul<Vec3> for &Mat3A {
1171    type Output = Vec3;
1172    #[inline]
1173    fn mul(self, rhs: Vec3) -> Vec3 {
1174        (*self).mul(rhs)
1175    }
1176}
1177
1178impl From<Mat3> for Mat3A {
1179    #[inline]
1180    fn from(m: Mat3) -> Self {
1181        Self {
1182            x_axis: m.x_axis.into(),
1183            y_axis: m.y_axis.into(),
1184            z_axis: m.z_axis.into(),
1185        }
1186    }
1187}
1188
1189impl Sum<Self> for Mat3A {
1190    fn sum<I>(iter: I) -> Self
1191    where
1192        I: Iterator<Item = Self>,
1193    {
1194        iter.fold(Self::ZERO, Self::add)
1195    }
1196}
1197
1198impl<'a> Sum<&'a Self> for Mat3A {
1199    fn sum<I>(iter: I) -> Self
1200    where
1201        I: Iterator<Item = &'a Self>,
1202    {
1203        iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1204    }
1205}
1206
1207impl Product for Mat3A {
1208    fn product<I>(iter: I) -> Self
1209    where
1210        I: Iterator<Item = Self>,
1211    {
1212        iter.fold(Self::IDENTITY, Self::mul)
1213    }
1214}
1215
1216impl<'a> Product<&'a Self> for Mat3A {
1217    fn product<I>(iter: I) -> Self
1218    where
1219        I: Iterator<Item = &'a Self>,
1220    {
1221        iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1222    }
1223}
1224
1225impl PartialEq for Mat3A {
1226    #[inline]
1227    fn eq(&self, rhs: &Self) -> bool {
1228        self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
1229    }
1230}
1231
1232impl fmt::Debug for Mat3A {
1233    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1234        fmt.debug_struct(stringify!(Mat3A))
1235            .field("x_axis", &self.x_axis)
1236            .field("y_axis", &self.y_axis)
1237            .field("z_axis", &self.z_axis)
1238            .finish()
1239    }
1240}
1241
1242impl fmt::Display for Mat3A {
1243    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1244        if let Some(p) = f.precision() {
1245            write!(
1246                f,
1247                "[{:.*}, {:.*}, {:.*}]",
1248                p, self.x_axis, p, self.y_axis, p, self.z_axis
1249            )
1250        } else {
1251            write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
1252        }
1253    }
1254}