1use crate::{Mat3, Mat3A, Mat4, Quat, Vec3, Vec3A};
4use core::ops::{Deref, DerefMut, Mul, MulAssign};
5
6#[derive(Copy, Clone)]
10#[cfg_attr(feature = "bytemuck", derive(bytemuck::AnyBitPattern))]
11#[repr(C)]
12pub struct Affine3A {
13    pub matrix3: Mat3A,
14    pub translation: Vec3A,
15}
16
17impl Affine3A {
18    pub const ZERO: Self = Self {
23        matrix3: Mat3A::ZERO,
24        translation: Vec3A::ZERO,
25    };
26
27    pub const IDENTITY: Self = Self {
31        matrix3: Mat3A::IDENTITY,
32        translation: Vec3A::ZERO,
33    };
34
35    pub const NAN: Self = Self {
37        matrix3: Mat3A::NAN,
38        translation: Vec3A::NAN,
39    };
40
41    #[inline(always)]
43    #[must_use]
44    pub const fn from_cols(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A, w_axis: Vec3A) -> Self {
45        Self {
46            matrix3: Mat3A::from_cols(x_axis, y_axis, z_axis),
47            translation: w_axis,
48        }
49    }
50
51    #[inline]
53    #[must_use]
54    pub fn from_cols_array(m: &[f32; 12]) -> Self {
55        Self {
56            matrix3: Mat3A::from_cols_array(&[
57                m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8],
58            ]),
59            translation: Vec3A::from_array([m[9], m[10], m[11]]),
60        }
61    }
62
63    #[inline]
65    #[must_use]
66    pub fn to_cols_array(&self) -> [f32; 12] {
67        let x = &self.matrix3.x_axis;
68        let y = &self.matrix3.y_axis;
69        let z = &self.matrix3.z_axis;
70        let w = &self.translation;
71        [x.x, x.y, x.z, y.x, y.y, y.z, z.x, z.y, z.z, w.x, w.y, w.z]
72    }
73
74    #[inline]
79    #[must_use]
80    pub fn from_cols_array_2d(m: &[[f32; 3]; 4]) -> Self {
81        Self {
82            matrix3: Mat3A::from_cols(m[0].into(), m[1].into(), m[2].into()),
83            translation: m[3].into(),
84        }
85    }
86
87    #[inline]
91    #[must_use]
92    pub fn to_cols_array_2d(&self) -> [[f32; 3]; 4] {
93        [
94            self.matrix3.x_axis.into(),
95            self.matrix3.y_axis.into(),
96            self.matrix3.z_axis.into(),
97            self.translation.into(),
98        ]
99    }
100
101    #[inline]
107    #[must_use]
108    pub fn from_cols_slice(slice: &[f32]) -> Self {
109        Self {
110            matrix3: Mat3A::from_cols_slice(&slice[0..9]),
111            translation: Vec3A::from_slice(&slice[9..12]),
112        }
113    }
114
115    #[inline]
121    pub fn write_cols_to_slice(self, slice: &mut [f32]) {
122        self.matrix3.write_cols_to_slice(&mut slice[0..9]);
123        self.translation.write_to_slice(&mut slice[9..12]);
124    }
125
126    #[inline]
129    #[must_use]
130    pub fn from_scale(scale: Vec3) -> Self {
131        Self {
132            matrix3: Mat3A::from_diagonal(scale),
133            translation: Vec3A::ZERO,
134        }
135    }
136    #[inline]
138    #[must_use]
139    pub fn from_quat(rotation: Quat) -> Self {
140        Self {
141            matrix3: Mat3A::from_quat(rotation),
142            translation: Vec3A::ZERO,
143        }
144    }
145
146    #[inline]
149    #[must_use]
150    pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
151        Self {
152            matrix3: Mat3A::from_axis_angle(axis, angle),
153            translation: Vec3A::ZERO,
154        }
155    }
156
157    #[inline]
160    #[must_use]
161    pub fn from_rotation_x(angle: f32) -> Self {
162        Self {
163            matrix3: Mat3A::from_rotation_x(angle),
164            translation: Vec3A::ZERO,
165        }
166    }
167
168    #[inline]
171    #[must_use]
172    pub fn from_rotation_y(angle: f32) -> Self {
173        Self {
174            matrix3: Mat3A::from_rotation_y(angle),
175            translation: Vec3A::ZERO,
176        }
177    }
178
179    #[inline]
182    #[must_use]
183    pub fn from_rotation_z(angle: f32) -> Self {
184        Self {
185            matrix3: Mat3A::from_rotation_z(angle),
186            translation: Vec3A::ZERO,
187        }
188    }
189
190    #[inline]
192    #[must_use]
193    pub fn from_translation(translation: Vec3) -> Self {
194        #[allow(clippy::useless_conversion)]
195        Self {
196            matrix3: Mat3A::IDENTITY,
197            translation: translation.into(),
198        }
199    }
200
201    #[inline]
204    #[must_use]
205    pub fn from_mat3(mat3: Mat3) -> Self {
206        #[allow(clippy::useless_conversion)]
207        Self {
208            matrix3: mat3.into(),
209            translation: Vec3A::ZERO,
210        }
211    }
212
213    #[inline]
218    #[must_use]
219    pub fn from_mat3_translation(mat3: Mat3, translation: Vec3) -> Self {
220        #[allow(clippy::useless_conversion)]
221        Self {
222            matrix3: mat3.into(),
223            translation: translation.into(),
224        }
225    }
226
227    #[inline]
233    #[must_use]
234    pub fn from_scale_rotation_translation(scale: Vec3, rotation: Quat, translation: Vec3) -> Self {
235        let rotation = Mat3A::from_quat(rotation);
236        #[allow(clippy::useless_conversion)]
237        Self {
238            matrix3: Mat3A::from_cols(
239                rotation.x_axis * scale.x,
240                rotation.y_axis * scale.y,
241                rotation.z_axis * scale.z,
242            ),
243            translation: translation.into(),
244        }
245    }
246
247    #[inline]
251    #[must_use]
252    pub fn from_rotation_translation(rotation: Quat, translation: Vec3) -> Self {
253        #[allow(clippy::useless_conversion)]
254        Self {
255            matrix3: Mat3A::from_quat(rotation),
256            translation: translation.into(),
257        }
258    }
259
260    #[inline]
263    #[must_use]
264    pub fn from_mat4(m: Mat4) -> Self {
265        Self {
266            matrix3: Mat3A::from_cols(
267                Vec3A::from_vec4(m.x_axis),
268                Vec3A::from_vec4(m.y_axis),
269                Vec3A::from_vec4(m.z_axis),
270            ),
271            translation: Vec3A::from_vec4(m.w_axis),
272        }
273    }
274
275    #[inline]
285    #[must_use]
286    pub fn to_scale_rotation_translation(&self) -> (Vec3, Quat, Vec3) {
287        use crate::f32::math;
288        let det = self.matrix3.determinant();
289        glam_assert!(det != 0.0);
290
291        let scale = Vec3::new(
292            self.matrix3.x_axis.length() * math::signum(det),
293            self.matrix3.y_axis.length(),
294            self.matrix3.z_axis.length(),
295        );
296
297        glam_assert!(scale.cmpne(Vec3::ZERO).all());
298
299        let inv_scale = scale.recip();
300
301        #[allow(clippy::useless_conversion)]
302        let rotation = Quat::from_mat3(&Mat3::from_cols(
303            (self.matrix3.x_axis * inv_scale.x).into(),
304            (self.matrix3.y_axis * inv_scale.y).into(),
305            (self.matrix3.z_axis * inv_scale.z).into(),
306        ));
307
308        #[allow(clippy::useless_conversion)]
309        (scale, rotation, self.translation.into())
310    }
311
312    #[inline]
317    #[must_use]
318    pub fn look_to_lh(eye: Vec3, dir: Vec3, up: Vec3) -> Self {
319        Self::look_to_rh(eye, -dir, up)
320    }
321
322    #[inline]
327    #[must_use]
328    pub fn look_to_rh(eye: Vec3, dir: Vec3, up: Vec3) -> Self {
329        let f = dir.normalize();
330        let s = f.cross(up).normalize();
331        let u = s.cross(f);
332
333        Self {
334            matrix3: Mat3A::from_cols(
335                Vec3A::new(s.x, u.x, -f.x),
336                Vec3A::new(s.y, u.y, -f.y),
337                Vec3A::new(s.z, u.z, -f.z),
338            ),
339            translation: Vec3A::new(-eye.dot(s), -eye.dot(u), eye.dot(f)),
340        }
341    }
342
343    #[inline]
351    #[must_use]
352    pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
353        glam_assert!(up.is_normalized());
354        Self::look_to_lh(eye, center - eye, up)
355    }
356
357    #[inline]
365    #[must_use]
366    pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
367        glam_assert!(up.is_normalized());
368        Self::look_to_rh(eye, center - eye, up)
369    }
370
371    #[inline]
373    pub fn transform_point3(&self, rhs: Vec3) -> Vec3 {
374        #[allow(clippy::useless_conversion)]
375        ((self.matrix3.x_axis * rhs.x)
376            + (self.matrix3.y_axis * rhs.y)
377            + (self.matrix3.z_axis * rhs.z)
378            + self.translation)
379            .into()
380    }
381
382    #[inline]
387    #[must_use]
388    pub fn transform_vector3(&self, rhs: Vec3) -> Vec3 {
389        #[allow(clippy::useless_conversion)]
390        ((self.matrix3.x_axis * rhs.x)
391            + (self.matrix3.y_axis * rhs.y)
392            + (self.matrix3.z_axis * rhs.z))
393            .into()
394    }
395
396    #[inline]
398    #[must_use]
399    pub fn transform_point3a(&self, rhs: Vec3A) -> Vec3A {
400        self.matrix3 * rhs + self.translation
401    }
402
403    #[inline]
408    #[must_use]
409    pub fn transform_vector3a(&self, rhs: Vec3A) -> Vec3A {
410        self.matrix3 * rhs
411    }
412
413    #[inline]
418    #[must_use]
419    pub fn is_finite(&self) -> bool {
420        self.matrix3.is_finite() && self.translation.is_finite()
421    }
422
423    #[inline]
425    #[must_use]
426    pub fn is_nan(&self) -> bool {
427        self.matrix3.is_nan() || self.translation.is_nan()
428    }
429
430    #[inline]
440    #[must_use]
441    pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
442        self.matrix3.abs_diff_eq(rhs.matrix3, max_abs_diff)
443            && self.translation.abs_diff_eq(rhs.translation, max_abs_diff)
444    }
445
446    #[inline]
450    #[must_use]
451    pub fn inverse(&self) -> Self {
452        let matrix3 = self.matrix3.inverse();
453        let translation = -(matrix3 * self.translation);
455
456        Self {
457            matrix3,
458            translation,
459        }
460    }
461
462    #[inline]
464    #[must_use]
465    pub fn as_daffine3(&self) -> crate::DAffine3 {
466        crate::DAffine3::from_mat3_translation(self.matrix3.as_dmat3(), self.translation.as_dvec3())
467    }
468}
469
470impl Default for Affine3A {
471    #[inline(always)]
472    fn default() -> Self {
473        Self::IDENTITY
474    }
475}
476
477impl Deref for Affine3A {
478    type Target = crate::deref::Cols4<Vec3A>;
479    #[inline(always)]
480    fn deref(&self) -> &Self::Target {
481        unsafe { &*(self as *const Self as *const Self::Target) }
482    }
483}
484
485impl DerefMut for Affine3A {
486    #[inline(always)]
487    fn deref_mut(&mut self) -> &mut Self::Target {
488        unsafe { &mut *(self as *mut Self as *mut Self::Target) }
489    }
490}
491
492impl PartialEq for Affine3A {
493    #[inline]
494    fn eq(&self, rhs: &Self) -> bool {
495        self.matrix3.eq(&rhs.matrix3) && self.translation.eq(&rhs.translation)
496    }
497}
498
499impl core::fmt::Debug for Affine3A {
500    fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
501        fmt.debug_struct(stringify!(Affine3A))
502            .field("matrix3", &self.matrix3)
503            .field("translation", &self.translation)
504            .finish()
505    }
506}
507
508impl core::fmt::Display for Affine3A {
509    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
510        if let Some(p) = f.precision() {
511            write!(
512                f,
513                "[{:.*}, {:.*}, {:.*}, {:.*}]",
514                p,
515                self.matrix3.x_axis,
516                p,
517                self.matrix3.y_axis,
518                p,
519                self.matrix3.z_axis,
520                p,
521                self.translation
522            )
523        } else {
524            write!(
525                f,
526                "[{}, {}, {}, {}]",
527                self.matrix3.x_axis, self.matrix3.y_axis, self.matrix3.z_axis, self.translation
528            )
529        }
530    }
531}
532
533impl<'a> core::iter::Product<&'a Self> for Affine3A {
534    fn product<I>(iter: I) -> Self
535    where
536        I: Iterator<Item = &'a Self>,
537    {
538        iter.fold(Self::IDENTITY, |a, &b| a * b)
539    }
540}
541
542impl Mul for Affine3A {
543    type Output = Self;
544
545    #[inline]
546    fn mul(self, rhs: Self) -> Self {
547        Self {
548            matrix3: self.matrix3 * rhs.matrix3,
549            translation: self.matrix3 * rhs.translation + self.translation,
550        }
551    }
552}
553
554impl Mul<&Self> for Affine3A {
555    type Output = Self;
556    #[inline]
557    fn mul(self, rhs: &Self) -> Self {
558        self.mul(*rhs)
559    }
560}
561
562impl Mul<&Affine3A> for &Affine3A {
563    type Output = Affine3A;
564    #[inline]
565    fn mul(self, rhs: &Affine3A) -> Affine3A {
566        (*self).mul(*rhs)
567    }
568}
569
570impl Mul<Affine3A> for &Affine3A {
571    type Output = Affine3A;
572    #[inline]
573    fn mul(self, rhs: Affine3A) -> Affine3A {
574        (*self).mul(rhs)
575    }
576}
577
578impl MulAssign for Affine3A {
579    #[inline]
580    fn mul_assign(&mut self, rhs: Self) {
581        *self = self.mul(rhs);
582    }
583}
584
585impl MulAssign<&Self> for Affine3A {
586    #[inline]
587    fn mul_assign(&mut self, rhs: &Self) {
588        self.mul_assign(*rhs);
589    }
590}
591
592impl Mul<Mat4> for Affine3A {
593    type Output = Mat4;
594
595    #[inline]
596    fn mul(self, rhs: Mat4) -> Self::Output {
597        Mat4::from(self) * rhs
598    }
599}
600
601impl Mul<&Mat4> for Affine3A {
602    type Output = Mat4;
603    #[inline]
604    fn mul(self, rhs: &Mat4) -> Mat4 {
605        self.mul(*rhs)
606    }
607}
608
609impl Mul<&Mat4> for &Affine3A {
610    type Output = Mat4;
611    #[inline]
612    fn mul(self, rhs: &Mat4) -> Mat4 {
613        (*self).mul(*rhs)
614    }
615}
616
617impl Mul<Mat4> for &Affine3A {
618    type Output = Mat4;
619    #[inline]
620    fn mul(self, rhs: Mat4) -> Mat4 {
621        (*self).mul(rhs)
622    }
623}
624
625impl Mul<Affine3A> for Mat4 {
626    type Output = Self;
627
628    #[inline]
629    fn mul(self, rhs: Affine3A) -> Self {
630        self * Self::from(rhs)
631    }
632}
633
634impl Mul<&Affine3A> for Mat4 {
635    type Output = Self;
636    #[inline]
637    fn mul(self, rhs: &Affine3A) -> Self {
638        self.mul(*rhs)
639    }
640}
641
642impl Mul<&Affine3A> for &Mat4 {
643    type Output = Mat4;
644    #[inline]
645    fn mul(self, rhs: &Affine3A) -> Mat4 {
646        (*self).mul(*rhs)
647    }
648}
649
650impl Mul<Affine3A> for &Mat4 {
651    type Output = Mat4;
652    #[inline]
653    fn mul(self, rhs: Affine3A) -> Mat4 {
654        (*self).mul(rhs)
655    }
656}
657
658impl MulAssign<Affine3A> for Mat4 {
659    #[inline]
660    fn mul_assign(&mut self, rhs: Affine3A) {
661        *self = self.mul(rhs);
662    }
663}
664
665impl MulAssign<&Affine3A> for Mat4 {
666    #[inline]
667    fn mul_assign(&mut self, rhs: &Affine3A) {
668        self.mul_assign(*rhs);
669    }
670}
671
672impl From<Affine3A> for Mat4 {
673    #[inline]
674    fn from(m: Affine3A) -> Self {
675        Self::from_cols(
676            m.matrix3.x_axis.extend(0.0),
677            m.matrix3.y_axis.extend(0.0),
678            m.matrix3.z_axis.extend(0.0),
679            m.translation.extend(1.0),
680        )
681    }
682}