glam/f32/
affine3a.rs

1// Generated from affine.rs.tera template. Edit the template, not the generated file.
2
3use crate::{Mat3, Mat3A, Mat4, Quat, Vec3, Vec3A};
4use core::ops::{Deref, DerefMut, Mul, MulAssign};
5
6/// A 3D affine transform, which can represent translation, rotation, scaling and shear.
7///
8/// This type is 16 byte aligned.
9#[derive(Copy, Clone)]
10#[cfg_attr(
11    all(feature = "bytemuck", not(target_arch = "spirv")),
12    derive(bytemuck::AnyBitPattern)
13)]
14#[repr(C)]
15pub struct Affine3A {
16    pub matrix3: Mat3A,
17    pub translation: Vec3A,
18}
19
20impl Affine3A {
21    /// The degenerate zero transform.
22    ///
23    /// This transforms any finite vector and point to zero.
24    /// The zero transform is non-invertible.
25    pub const ZERO: Self = Self {
26        matrix3: Mat3A::ZERO,
27        translation: Vec3A::ZERO,
28    };
29
30    /// The identity transform.
31    ///
32    /// Multiplying a vector with this returns the same vector.
33    pub const IDENTITY: Self = Self {
34        matrix3: Mat3A::IDENTITY,
35        translation: Vec3A::ZERO,
36    };
37
38    /// All NAN:s.
39    pub const NAN: Self = Self {
40        matrix3: Mat3A::NAN,
41        translation: Vec3A::NAN,
42    };
43
44    /// Creates an affine transform from three column vectors.
45    #[inline(always)]
46    #[must_use]
47    pub const fn from_cols(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A, w_axis: Vec3A) -> Self {
48        Self {
49            matrix3: Mat3A::from_cols(x_axis, y_axis, z_axis),
50            translation: w_axis,
51        }
52    }
53
54    /// Creates an affine transform from a `[f32; 12]` array stored in column major order.
55    #[inline]
56    #[must_use]
57    pub fn from_cols_array(m: &[f32; 12]) -> Self {
58        Self {
59            matrix3: Mat3A::from_cols_array(&[
60                m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8],
61            ]),
62            translation: Vec3A::from_array([m[9], m[10], m[11]]),
63        }
64    }
65
66    /// Creates a `[f32; 12]` array storing data in column major order.
67    #[inline]
68    #[must_use]
69    pub fn to_cols_array(&self) -> [f32; 12] {
70        let x = &self.matrix3.x_axis;
71        let y = &self.matrix3.y_axis;
72        let z = &self.matrix3.z_axis;
73        let w = &self.translation;
74        [x.x, x.y, x.z, y.x, y.y, y.z, z.x, z.y, z.z, w.x, w.y, w.z]
75    }
76
77    /// Creates an affine transform from a `[[f32; 3]; 4]`
78    /// 3D array stored in column major order.
79    /// If your data is in row major order you will need to `transpose` the returned
80    /// matrix.
81    #[inline]
82    #[must_use]
83    pub fn from_cols_array_2d(m: &[[f32; 3]; 4]) -> Self {
84        Self {
85            matrix3: Mat3A::from_cols(m[0].into(), m[1].into(), m[2].into()),
86            translation: m[3].into(),
87        }
88    }
89
90    /// Creates a `[[f32; 3]; 4]` 3D array storing data in
91    /// column major order.
92    /// If you require data in row major order `transpose` the matrix first.
93    #[inline]
94    #[must_use]
95    pub fn to_cols_array_2d(&self) -> [[f32; 3]; 4] {
96        [
97            self.matrix3.x_axis.into(),
98            self.matrix3.y_axis.into(),
99            self.matrix3.z_axis.into(),
100            self.translation.into(),
101        ]
102    }
103
104    /// Creates an affine transform from the first 12 values in `slice`.
105    ///
106    /// # Panics
107    ///
108    /// Panics if `slice` is less than 12 elements long.
109    #[inline]
110    #[must_use]
111    pub fn from_cols_slice(slice: &[f32]) -> Self {
112        Self {
113            matrix3: Mat3A::from_cols_slice(&slice[0..9]),
114            translation: Vec3A::from_slice(&slice[9..12]),
115        }
116    }
117
118    /// Writes the columns of `self` to the first 12 elements in `slice`.
119    ///
120    /// # Panics
121    ///
122    /// Panics if `slice` is less than 12 elements long.
123    #[inline]
124    pub fn write_cols_to_slice(self, slice: &mut [f32]) {
125        self.matrix3.write_cols_to_slice(&mut slice[0..9]);
126        self.translation.write_to_slice(&mut slice[9..12]);
127    }
128
129    /// Creates an affine transform that changes scale.
130    /// Note that if any scale is zero the transform will be non-invertible.
131    #[inline]
132    #[must_use]
133    pub fn from_scale(scale: Vec3) -> Self {
134        Self {
135            matrix3: Mat3A::from_diagonal(scale),
136            translation: Vec3A::ZERO,
137        }
138    }
139    /// Creates an affine transform from the given `rotation` quaternion.
140    #[inline]
141    #[must_use]
142    pub fn from_quat(rotation: Quat) -> Self {
143        Self {
144            matrix3: Mat3A::from_quat(rotation),
145            translation: Vec3A::ZERO,
146        }
147    }
148
149    /// Creates an affine transform containing a 3D rotation around a normalized
150    /// rotation `axis` of `angle` (in radians).
151    #[inline]
152    #[must_use]
153    pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
154        Self {
155            matrix3: Mat3A::from_axis_angle(axis, angle),
156            translation: Vec3A::ZERO,
157        }
158    }
159
160    /// Creates an affine transform containing a 3D rotation around the x axis of
161    /// `angle` (in radians).
162    #[inline]
163    #[must_use]
164    pub fn from_rotation_x(angle: f32) -> Self {
165        Self {
166            matrix3: Mat3A::from_rotation_x(angle),
167            translation: Vec3A::ZERO,
168        }
169    }
170
171    /// Creates an affine transform containing a 3D rotation around the y axis of
172    /// `angle` (in radians).
173    #[inline]
174    #[must_use]
175    pub fn from_rotation_y(angle: f32) -> Self {
176        Self {
177            matrix3: Mat3A::from_rotation_y(angle),
178            translation: Vec3A::ZERO,
179        }
180    }
181
182    /// Creates an affine transform containing a 3D rotation around the z axis of
183    /// `angle` (in radians).
184    #[inline]
185    #[must_use]
186    pub fn from_rotation_z(angle: f32) -> Self {
187        Self {
188            matrix3: Mat3A::from_rotation_z(angle),
189            translation: Vec3A::ZERO,
190        }
191    }
192
193    /// Creates an affine transformation from the given 3D `translation`.
194    #[inline]
195    #[must_use]
196    pub fn from_translation(translation: Vec3) -> Self {
197        #[allow(clippy::useless_conversion)]
198        Self {
199            matrix3: Mat3A::IDENTITY,
200            translation: translation.into(),
201        }
202    }
203
204    /// Creates an affine transform from a 3x3 matrix (expressing scale, shear and
205    /// rotation)
206    #[inline]
207    #[must_use]
208    pub fn from_mat3(mat3: Mat3) -> Self {
209        #[allow(clippy::useless_conversion)]
210        Self {
211            matrix3: mat3.into(),
212            translation: Vec3A::ZERO,
213        }
214    }
215
216    /// Creates an affine transform from a 3x3 matrix (expressing scale, shear and rotation)
217    /// and a translation vector.
218    ///
219    /// Equivalent to `Affine3A::from_translation(translation) * Affine3A::from_mat3(mat3)`
220    #[inline]
221    #[must_use]
222    pub fn from_mat3_translation(mat3: Mat3, translation: Vec3) -> Self {
223        #[allow(clippy::useless_conversion)]
224        Self {
225            matrix3: mat3.into(),
226            translation: translation.into(),
227        }
228    }
229
230    /// Creates an affine transform from the given 3D `scale`, `rotation` and
231    /// `translation`.
232    ///
233    /// Equivalent to `Affine3A::from_translation(translation) *
234    /// Affine3A::from_quat(rotation) * Affine3A::from_scale(scale)`
235    #[inline]
236    #[must_use]
237    pub fn from_scale_rotation_translation(scale: Vec3, rotation: Quat, translation: Vec3) -> Self {
238        let rotation = Mat3A::from_quat(rotation);
239        #[allow(clippy::useless_conversion)]
240        Self {
241            matrix3: Mat3A::from_cols(
242                rotation.x_axis * scale.x,
243                rotation.y_axis * scale.y,
244                rotation.z_axis * scale.z,
245            ),
246            translation: translation.into(),
247        }
248    }
249
250    /// Creates an affine transform from the given 3D `rotation` and `translation`.
251    ///
252    /// Equivalent to `Affine3A::from_translation(translation) * Affine3A::from_quat(rotation)`
253    #[inline]
254    #[must_use]
255    pub fn from_rotation_translation(rotation: Quat, translation: Vec3) -> Self {
256        #[allow(clippy::useless_conversion)]
257        Self {
258            matrix3: Mat3A::from_quat(rotation),
259            translation: translation.into(),
260        }
261    }
262
263    /// The given `Mat4` must be an affine transform,
264    /// i.e. contain no perspective transform.
265    #[inline]
266    #[must_use]
267    pub fn from_mat4(m: Mat4) -> Self {
268        Self {
269            matrix3: Mat3A::from_cols(
270                Vec3A::from_vec4(m.x_axis),
271                Vec3A::from_vec4(m.y_axis),
272                Vec3A::from_vec4(m.z_axis),
273            ),
274            translation: Vec3A::from_vec4(m.w_axis),
275        }
276    }
277
278    /// Extracts `scale`, `rotation` and `translation` from `self`.
279    ///
280    /// The transform is expected to be non-degenerate and without shearing, or the output
281    /// will be invalid.
282    ///
283    /// # Panics
284    ///
285    /// Will panic if the determinant `self.matrix3` is zero or if the resulting scale
286    /// vector contains any zero elements when `glam_assert` is enabled.
287    #[inline]
288    #[must_use]
289    pub fn to_scale_rotation_translation(&self) -> (Vec3, Quat, Vec3) {
290        use crate::f32::math;
291        let det = self.matrix3.determinant();
292        glam_assert!(det != 0.0);
293
294        let scale = Vec3::new(
295            self.matrix3.x_axis.length() * math::signum(det),
296            self.matrix3.y_axis.length(),
297            self.matrix3.z_axis.length(),
298        );
299
300        glam_assert!(scale.cmpne(Vec3::ZERO).all());
301
302        let inv_scale = scale.recip();
303
304        #[allow(clippy::useless_conversion)]
305        let rotation = Quat::from_mat3(&Mat3::from_cols(
306            (self.matrix3.x_axis * inv_scale.x).into(),
307            (self.matrix3.y_axis * inv_scale.y).into(),
308            (self.matrix3.z_axis * inv_scale.z).into(),
309        ));
310
311        #[allow(clippy::useless_conversion)]
312        (scale, rotation, self.translation.into())
313    }
314
315    /// Creates a left-handed view transform using a camera position, an up direction, and a facing
316    /// direction.
317    ///
318    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`.
319    #[inline]
320    #[must_use]
321    pub fn look_to_lh(eye: Vec3, dir: Vec3, up: Vec3) -> Self {
322        Self::look_to_rh(eye, -dir, up)
323    }
324
325    /// Creates a right-handed view transform using a camera position, an up direction, and a facing
326    /// direction.
327    ///
328    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`.
329    #[inline]
330    #[must_use]
331    pub fn look_to_rh(eye: Vec3, dir: Vec3, up: Vec3) -> Self {
332        let f = dir.normalize();
333        let s = f.cross(up).normalize();
334        let u = s.cross(f);
335
336        Self {
337            matrix3: Mat3A::from_cols(
338                Vec3A::new(s.x, u.x, -f.x),
339                Vec3A::new(s.y, u.y, -f.y),
340                Vec3A::new(s.z, u.z, -f.z),
341            ),
342            translation: Vec3A::new(-eye.dot(s), -eye.dot(u), eye.dot(f)),
343        }
344    }
345
346    /// Creates a left-handed view transform using a camera position, an up direction, and a focal
347    /// point.
348    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`.
349    ///
350    /// # Panics
351    ///
352    /// Will panic if `up` is not normalized when `glam_assert` is enabled.
353    #[inline]
354    #[must_use]
355    pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
356        glam_assert!(up.is_normalized());
357        Self::look_to_lh(eye, center - eye, up)
358    }
359
360    /// Creates a right-handed view transform using a camera position, an up direction, and a focal
361    /// point.
362    /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`.
363    ///
364    /// # Panics
365    ///
366    /// Will panic if `up` is not normalized when `glam_assert` is enabled.
367    #[inline]
368    #[must_use]
369    pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
370        glam_assert!(up.is_normalized());
371        Self::look_to_rh(eye, center - eye, up)
372    }
373
374    /// Transforms the given 3D points, applying shear, scale, rotation and translation.
375    #[inline]
376    pub fn transform_point3(&self, rhs: Vec3) -> Vec3 {
377        #[allow(clippy::useless_conversion)]
378        ((self.matrix3.x_axis * rhs.x)
379            + (self.matrix3.y_axis * rhs.y)
380            + (self.matrix3.z_axis * rhs.z)
381            + self.translation)
382            .into()
383    }
384
385    /// Transforms the given 3D vector, applying shear, scale and rotation (but NOT
386    /// translation).
387    ///
388    /// To also apply translation, use [`Self::transform_point3()`] instead.
389    #[inline]
390    #[must_use]
391    pub fn transform_vector3(&self, rhs: Vec3) -> Vec3 {
392        #[allow(clippy::useless_conversion)]
393        ((self.matrix3.x_axis * rhs.x)
394            + (self.matrix3.y_axis * rhs.y)
395            + (self.matrix3.z_axis * rhs.z))
396            .into()
397    }
398
399    /// Transforms the given [`Vec3A`], applying shear, scale, rotation and translation.
400    #[inline]
401    #[must_use]
402    pub fn transform_point3a(&self, rhs: Vec3A) -> Vec3A {
403        self.matrix3 * rhs + self.translation
404    }
405
406    /// Transforms the given [`Vec3A`], applying shear, scale and rotation (but NOT
407    /// translation).
408    ///
409    /// To also apply translation, use [`Self::transform_point3a()`] instead.
410    #[inline]
411    #[must_use]
412    pub fn transform_vector3a(&self, rhs: Vec3A) -> Vec3A {
413        self.matrix3 * rhs
414    }
415
416    /// Returns `true` if, and only if, all elements are finite.
417    ///
418    /// If any element is either `NaN`, positive or negative infinity, this will return
419    /// `false`.
420    #[inline]
421    #[must_use]
422    pub fn is_finite(&self) -> bool {
423        self.matrix3.is_finite() && self.translation.is_finite()
424    }
425
426    /// Returns `true` if any elements are `NaN`.
427    #[inline]
428    #[must_use]
429    pub fn is_nan(&self) -> bool {
430        self.matrix3.is_nan() || self.translation.is_nan()
431    }
432
433    /// Returns true if the absolute difference of all elements between `self` and `rhs`
434    /// is less than or equal to `max_abs_diff`.
435    ///
436    /// This can be used to compare if two 3x4 matrices contain similar elements. It works
437    /// best when comparing with a known value. The `max_abs_diff` that should be used used
438    /// depends on the values being compared against.
439    ///
440    /// For more see
441    /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
442    #[inline]
443    #[must_use]
444    pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
445        self.matrix3.abs_diff_eq(rhs.matrix3, max_abs_diff)
446            && self.translation.abs_diff_eq(rhs.translation, max_abs_diff)
447    }
448
449    /// Return the inverse of this transform.
450    ///
451    /// Note that if the transform is not invertible the result will be invalid.
452    #[inline]
453    #[must_use]
454    pub fn inverse(&self) -> Self {
455        let matrix3 = self.matrix3.inverse();
456        // transform negative translation by the matrix inverse:
457        let translation = -(matrix3 * self.translation);
458
459        Self {
460            matrix3,
461            translation,
462        }
463    }
464
465    /// Casts all elements of `self` to `f64`.
466    #[inline]
467    #[must_use]
468    pub fn as_daffine3(&self) -> crate::DAffine3 {
469        crate::DAffine3::from_mat3_translation(self.matrix3.as_dmat3(), self.translation.as_dvec3())
470    }
471}
472
473impl Default for Affine3A {
474    #[inline(always)]
475    fn default() -> Self {
476        Self::IDENTITY
477    }
478}
479
480impl Deref for Affine3A {
481    type Target = crate::deref::Cols4<Vec3A>;
482    #[inline(always)]
483    fn deref(&self) -> &Self::Target {
484        unsafe { &*(self as *const Self as *const Self::Target) }
485    }
486}
487
488impl DerefMut for Affine3A {
489    #[inline(always)]
490    fn deref_mut(&mut self) -> &mut Self::Target {
491        unsafe { &mut *(self as *mut Self as *mut Self::Target) }
492    }
493}
494
495impl PartialEq for Affine3A {
496    #[inline]
497    fn eq(&self, rhs: &Self) -> bool {
498        self.matrix3.eq(&rhs.matrix3) && self.translation.eq(&rhs.translation)
499    }
500}
501
502impl core::fmt::Debug for Affine3A {
503    fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
504        fmt.debug_struct(stringify!(Affine3A))
505            .field("matrix3", &self.matrix3)
506            .field("translation", &self.translation)
507            .finish()
508    }
509}
510
511impl core::fmt::Display for Affine3A {
512    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
513        if let Some(p) = f.precision() {
514            write!(
515                f,
516                "[{:.*}, {:.*}, {:.*}, {:.*}]",
517                p,
518                self.matrix3.x_axis,
519                p,
520                self.matrix3.y_axis,
521                p,
522                self.matrix3.z_axis,
523                p,
524                self.translation
525            )
526        } else {
527            write!(
528                f,
529                "[{}, {}, {}, {}]",
530                self.matrix3.x_axis, self.matrix3.y_axis, self.matrix3.z_axis, self.translation
531            )
532        }
533    }
534}
535
536impl<'a> core::iter::Product<&'a Self> for Affine3A {
537    fn product<I>(iter: I) -> Self
538    where
539        I: Iterator<Item = &'a Self>,
540    {
541        iter.fold(Self::IDENTITY, |a, &b| a * b)
542    }
543}
544
545impl Mul for Affine3A {
546    type Output = Self;
547
548    #[inline]
549    fn mul(self, rhs: Self) -> Self {
550        Self {
551            matrix3: self.matrix3 * rhs.matrix3,
552            translation: self.matrix3 * rhs.translation + self.translation,
553        }
554    }
555}
556
557impl Mul<&Self> for Affine3A {
558    type Output = Self;
559    #[inline]
560    fn mul(self, rhs: &Self) -> Self {
561        self.mul(*rhs)
562    }
563}
564
565impl Mul<&Affine3A> for &Affine3A {
566    type Output = Affine3A;
567    #[inline]
568    fn mul(self, rhs: &Affine3A) -> Affine3A {
569        (*self).mul(*rhs)
570    }
571}
572
573impl Mul<Affine3A> for &Affine3A {
574    type Output = Affine3A;
575    #[inline]
576    fn mul(self, rhs: Affine3A) -> Affine3A {
577        (*self).mul(rhs)
578    }
579}
580
581impl MulAssign for Affine3A {
582    #[inline]
583    fn mul_assign(&mut self, rhs: Self) {
584        *self = self.mul(rhs);
585    }
586}
587
588impl MulAssign<&Self> for Affine3A {
589    #[inline]
590    fn mul_assign(&mut self, rhs: &Self) {
591        self.mul_assign(*rhs);
592    }
593}
594
595impl Mul<Mat4> for Affine3A {
596    type Output = Mat4;
597
598    #[inline]
599    fn mul(self, rhs: Mat4) -> Self::Output {
600        Mat4::from(self) * rhs
601    }
602}
603
604impl Mul<&Mat4> for Affine3A {
605    type Output = Mat4;
606    #[inline]
607    fn mul(self, rhs: &Mat4) -> Mat4 {
608        self.mul(*rhs)
609    }
610}
611
612impl Mul<&Mat4> for &Affine3A {
613    type Output = Mat4;
614    #[inline]
615    fn mul(self, rhs: &Mat4) -> Mat4 {
616        (*self).mul(*rhs)
617    }
618}
619
620impl Mul<Mat4> for &Affine3A {
621    type Output = Mat4;
622    #[inline]
623    fn mul(self, rhs: Mat4) -> Mat4 {
624        (*self).mul(rhs)
625    }
626}
627
628impl Mul<Affine3A> for Mat4 {
629    type Output = Self;
630
631    #[inline]
632    fn mul(self, rhs: Affine3A) -> Self {
633        self * Self::from(rhs)
634    }
635}
636
637impl Mul<&Affine3A> for Mat4 {
638    type Output = Self;
639    #[inline]
640    fn mul(self, rhs: &Affine3A) -> Self {
641        self.mul(*rhs)
642    }
643}
644
645impl Mul<&Affine3A> for &Mat4 {
646    type Output = Mat4;
647    #[inline]
648    fn mul(self, rhs: &Affine3A) -> Mat4 {
649        (*self).mul(*rhs)
650    }
651}
652
653impl Mul<Affine3A> for &Mat4 {
654    type Output = Mat4;
655    #[inline]
656    fn mul(self, rhs: Affine3A) -> Mat4 {
657        (*self).mul(rhs)
658    }
659}
660
661impl MulAssign<Affine3A> for Mat4 {
662    #[inline]
663    fn mul_assign(&mut self, rhs: Affine3A) {
664        *self = self.mul(rhs);
665    }
666}
667
668impl MulAssign<&Affine3A> for Mat4 {
669    #[inline]
670    fn mul_assign(&mut self, rhs: &Affine3A) {
671        self.mul_assign(*rhs);
672    }
673}
674
675impl From<Affine3A> for Mat4 {
676    #[inline]
677    fn from(m: Affine3A) -> Self {
678        Self::from_cols(
679            m.matrix3.x_axis.extend(0.0),
680            m.matrix3.y_axis.extend(0.0),
681            m.matrix3.z_axis.extend(0.0),
682            m.translation.extend(1.0),
683        )
684    }
685}