1use crate::{Mat3, Mat3A, Mat4, Quat, Vec3, Vec3A};
4use core::ops::{Deref, DerefMut, Mul, MulAssign};
5
6#[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 pub const ZERO: Self = Self {
26 matrix3: Mat3A::ZERO,
27 translation: Vec3A::ZERO,
28 };
29
30 pub const IDENTITY: Self = Self {
34 matrix3: Mat3A::IDENTITY,
35 translation: Vec3A::ZERO,
36 };
37
38 pub const NAN: Self = Self {
40 matrix3: Mat3A::NAN,
41 translation: Vec3A::NAN,
42 };
43
44 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline]
401 #[must_use]
402 pub fn transform_point3a(&self, rhs: Vec3A) -> Vec3A {
403 self.matrix3 * rhs + self.translation
404 }
405
406 #[inline]
411 #[must_use]
412 pub fn transform_vector3a(&self, rhs: Vec3A) -> Vec3A {
413 self.matrix3 * rhs
414 }
415
416 #[inline]
421 #[must_use]
422 pub fn is_finite(&self) -> bool {
423 self.matrix3.is_finite() && self.translation.is_finite()
424 }
425
426 #[inline]
428 #[must_use]
429 pub fn is_nan(&self) -> bool {
430 self.matrix3.is_nan() || self.translation.is_nan()
431 }
432
433 #[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 #[inline]
453 #[must_use]
454 pub fn inverse(&self) -> Self {
455 let matrix3 = self.matrix3.inverse();
456 let translation = -(matrix3 * self.translation);
458
459 Self {
460 matrix3,
461 translation,
462 }
463 }
464
465 #[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}