1use crate::{DMat2, DMat3, DVec2};
4use core::ops::{Deref, DerefMut, Mul, MulAssign};
5
6#[cfg(feature = "zerocopy")]
7use zerocopy_derive::*;
8
9#[derive(Copy, Clone)]
11#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
12#[cfg_attr(
13 feature = "zerocopy",
14 derive(FromBytes, Immutable, IntoBytes, KnownLayout)
15)]
16#[repr(C)]
17pub struct DAffine2 {
18 pub matrix2: DMat2,
19 pub translation: DVec2,
20}
21
22impl DAffine2 {
23 pub const ZERO: Self = Self {
28 matrix2: DMat2::ZERO,
29 translation: DVec2::ZERO,
30 };
31
32 pub const IDENTITY: Self = Self {
36 matrix2: DMat2::IDENTITY,
37 translation: DVec2::ZERO,
38 };
39
40 pub const NAN: Self = Self {
42 matrix2: DMat2::NAN,
43 translation: DVec2::NAN,
44 };
45
46 #[inline(always)]
48 #[must_use]
49 pub const fn from_cols(x_axis: DVec2, y_axis: DVec2, z_axis: DVec2) -> Self {
50 Self {
51 matrix2: DMat2::from_cols(x_axis, y_axis),
52 translation: z_axis,
53 }
54 }
55
56 #[inline]
58 #[must_use]
59 pub fn from_cols_array(m: &[f64; 6]) -> Self {
60 Self {
61 matrix2: DMat2::from_cols_array(&[m[0], m[1], m[2], m[3]]),
62 translation: DVec2::from_array([m[4], m[5]]),
63 }
64 }
65
66 #[inline]
68 #[must_use]
69 pub fn to_cols_array(&self) -> [f64; 6] {
70 let x = &self.matrix2.x_axis;
71 let y = &self.matrix2.y_axis;
72 let z = &self.translation;
73 [x.x, x.y, y.x, y.y, z.x, z.y]
74 }
75
76 #[inline]
81 #[must_use]
82 pub fn from_cols_array_2d(m: &[[f64; 2]; 3]) -> Self {
83 Self {
84 matrix2: DMat2::from_cols(m[0].into(), m[1].into()),
85 translation: m[2].into(),
86 }
87 }
88
89 #[inline]
93 #[must_use]
94 pub fn to_cols_array_2d(&self) -> [[f64; 2]; 3] {
95 [
96 self.matrix2.x_axis.into(),
97 self.matrix2.y_axis.into(),
98 self.translation.into(),
99 ]
100 }
101
102 #[inline]
108 #[must_use]
109 pub fn from_cols_slice(slice: &[f64]) -> Self {
110 Self {
111 matrix2: DMat2::from_cols_slice(&slice[0..4]),
112 translation: DVec2::from_slice(&slice[4..6]),
113 }
114 }
115
116 #[inline]
122 pub fn write_cols_to_slice(self, slice: &mut [f64]) {
123 self.matrix2.write_cols_to_slice(&mut slice[0..4]);
124 self.translation.write_to_slice(&mut slice[4..6]);
125 }
126
127 #[inline]
130 #[must_use]
131 pub fn from_scale(scale: DVec2) -> Self {
132 Self {
133 matrix2: DMat2::from_diagonal(scale),
134 translation: DVec2::ZERO,
135 }
136 }
137
138 #[inline]
140 #[must_use]
141 pub fn from_angle(angle: f64) -> Self {
142 Self {
143 matrix2: DMat2::from_angle(angle),
144 translation: DVec2::ZERO,
145 }
146 }
147
148 #[inline]
150 #[must_use]
151 pub fn from_translation(translation: DVec2) -> Self {
152 Self {
153 matrix2: DMat2::IDENTITY,
154 translation,
155 }
156 }
157
158 #[inline]
160 #[must_use]
161 pub fn from_mat2(matrix2: DMat2) -> Self {
162 Self {
163 matrix2,
164 translation: DVec2::ZERO,
165 }
166 }
167
168 #[inline]
174 #[must_use]
175 pub fn from_mat2_translation(matrix2: DMat2, translation: DVec2) -> Self {
176 Self {
177 matrix2,
178 translation,
179 }
180 }
181
182 #[inline]
188 #[must_use]
189 pub fn from_scale_angle_translation(scale: DVec2, angle: f64, translation: DVec2) -> Self {
190 let rotation = DMat2::from_angle(angle);
191 Self {
192 matrix2: DMat2::from_cols(rotation.x_axis * scale.x, rotation.y_axis * scale.y),
193 translation,
194 }
195 }
196
197 #[inline]
202 #[must_use]
203 pub fn from_angle_translation(angle: f64, translation: DVec2) -> Self {
204 Self {
205 matrix2: DMat2::from_angle(angle),
206 translation,
207 }
208 }
209
210 #[inline]
212 #[must_use]
213 pub fn from_mat3(m: DMat3) -> Self {
214 use crate::swizzles::Vec3Swizzles;
215 Self {
216 matrix2: DMat2::from_cols(m.x_axis.xy(), m.y_axis.xy()),
217 translation: m.z_axis.xy(),
218 }
219 }
220
221 #[inline]
231 #[must_use]
232 pub fn to_scale_angle_translation(self) -> (DVec2, f64, DVec2) {
233 use crate::f64::math;
234 let det = self.matrix2.determinant();
235 glam_assert!(det != 0.0);
236
237 let scale = DVec2::new(
238 self.matrix2.x_axis.length() * math::signum(det),
239 self.matrix2.y_axis.length(),
240 );
241
242 glam_assert!(scale.cmpne(DVec2::ZERO).all());
243
244 let angle = math::atan2(-self.matrix2.y_axis.x, self.matrix2.y_axis.y);
245
246 (scale, angle, self.translation)
247 }
248
249 #[inline]
251 #[must_use]
252 pub fn transform_point2(&self, rhs: DVec2) -> DVec2 {
253 self.matrix2 * rhs + self.translation
254 }
255
256 #[inline]
261 pub fn transform_vector2(&self, rhs: DVec2) -> DVec2 {
262 self.matrix2 * rhs
263 }
264
265 #[inline]
270 #[must_use]
271 pub fn is_finite(&self) -> bool {
272 self.matrix2.is_finite() && self.translation.is_finite()
273 }
274
275 #[inline]
277 #[must_use]
278 pub fn is_nan(&self) -> bool {
279 self.matrix2.is_nan() || self.translation.is_nan()
280 }
281
282 #[inline]
292 #[must_use]
293 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f64) -> bool {
294 self.matrix2.abs_diff_eq(rhs.matrix2, max_abs_diff)
295 && self.translation.abs_diff_eq(rhs.translation, max_abs_diff)
296 }
297
298 #[inline]
302 #[must_use]
303 pub fn inverse(&self) -> Self {
304 let matrix2 = self.matrix2.inverse();
305 let translation = -(matrix2 * self.translation);
307
308 Self {
309 matrix2,
310 translation,
311 }
312 }
313
314 #[inline]
316 #[must_use]
317 pub fn as_affine2(&self) -> crate::Affine2 {
318 crate::Affine2::from_mat2_translation(self.matrix2.as_mat2(), self.translation.as_vec2())
319 }
320}
321
322impl Default for DAffine2 {
323 #[inline(always)]
324 fn default() -> Self {
325 Self::IDENTITY
326 }
327}
328
329impl Deref for DAffine2 {
330 type Target = crate::deref::Cols3<DVec2>;
331 #[inline(always)]
332 fn deref(&self) -> &Self::Target {
333 unsafe { &*(self as *const Self as *const Self::Target) }
334 }
335}
336
337impl DerefMut for DAffine2 {
338 #[inline(always)]
339 fn deref_mut(&mut self) -> &mut Self::Target {
340 unsafe { &mut *(self as *mut Self as *mut Self::Target) }
341 }
342}
343
344impl PartialEq for DAffine2 {
345 #[inline]
346 fn eq(&self, rhs: &Self) -> bool {
347 self.matrix2.eq(&rhs.matrix2) && self.translation.eq(&rhs.translation)
348 }
349}
350
351impl core::fmt::Debug for DAffine2 {
352 fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
353 fmt.debug_struct(stringify!(DAffine2))
354 .field("matrix2", &self.matrix2)
355 .field("translation", &self.translation)
356 .finish()
357 }
358}
359
360impl core::fmt::Display for DAffine2 {
361 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
362 if let Some(p) = f.precision() {
363 write!(
364 f,
365 "[{:.*}, {:.*}, {:.*}]",
366 p, self.matrix2.x_axis, p, self.matrix2.y_axis, p, self.translation
367 )
368 } else {
369 write!(
370 f,
371 "[{}, {}, {}]",
372 self.matrix2.x_axis, self.matrix2.y_axis, self.translation
373 )
374 }
375 }
376}
377
378impl<'a> core::iter::Product<&'a Self> for DAffine2 {
379 fn product<I>(iter: I) -> Self
380 where
381 I: Iterator<Item = &'a Self>,
382 {
383 iter.fold(Self::IDENTITY, |a, &b| a * b)
384 }
385}
386
387impl Mul for DAffine2 {
388 type Output = Self;
389
390 #[inline]
391 fn mul(self, rhs: Self) -> Self {
392 Self {
393 matrix2: self.matrix2 * rhs.matrix2,
394 translation: self.matrix2 * rhs.translation + self.translation,
395 }
396 }
397}
398
399impl Mul<&Self> for DAffine2 {
400 type Output = Self;
401 #[inline]
402 fn mul(self, rhs: &Self) -> Self {
403 self.mul(*rhs)
404 }
405}
406
407impl Mul<&DAffine2> for &DAffine2 {
408 type Output = DAffine2;
409 #[inline]
410 fn mul(self, rhs: &DAffine2) -> DAffine2 {
411 (*self).mul(*rhs)
412 }
413}
414
415impl Mul<DAffine2> for &DAffine2 {
416 type Output = DAffine2;
417 #[inline]
418 fn mul(self, rhs: DAffine2) -> DAffine2 {
419 (*self).mul(rhs)
420 }
421}
422
423impl MulAssign for DAffine2 {
424 #[inline]
425 fn mul_assign(&mut self, rhs: Self) {
426 *self = self.mul(rhs);
427 }
428}
429
430impl MulAssign<&Self> for DAffine2 {
431 #[inline]
432 fn mul_assign(&mut self, rhs: &Self) {
433 self.mul_assign(*rhs);
434 }
435}
436
437impl From<DAffine2> for DMat3 {
438 #[inline]
439 fn from(m: DAffine2) -> Self {
440 Self::from_cols(
441 m.matrix2.x_axis.extend(0.0),
442 m.matrix2.y_axis.extend(0.0),
443 m.translation.extend(1.0),
444 )
445 }
446}
447
448impl Mul<DMat3> for DAffine2 {
449 type Output = DMat3;
450
451 #[inline]
452 fn mul(self, rhs: DMat3) -> Self::Output {
453 DMat3::from(self) * rhs
454 }
455}
456
457impl Mul<&DMat3> for DAffine2 {
458 type Output = DMat3;
459 #[inline]
460 fn mul(self, rhs: &DMat3) -> DMat3 {
461 self.mul(*rhs)
462 }
463}
464
465impl Mul<&DMat3> for &DAffine2 {
466 type Output = DMat3;
467 #[inline]
468 fn mul(self, rhs: &DMat3) -> DMat3 {
469 (*self).mul(*rhs)
470 }
471}
472
473impl Mul<DMat3> for &DAffine2 {
474 type Output = DMat3;
475 #[inline]
476 fn mul(self, rhs: DMat3) -> DMat3 {
477 (*self).mul(rhs)
478 }
479}
480
481impl Mul<DAffine2> for DMat3 {
482 type Output = Self;
483
484 #[inline]
485 fn mul(self, rhs: DAffine2) -> Self {
486 self * Self::from(rhs)
487 }
488}
489
490impl Mul<&DAffine2> for DMat3 {
491 type Output = Self;
492 #[inline]
493 fn mul(self, rhs: &DAffine2) -> Self {
494 self.mul(*rhs)
495 }
496}
497
498impl Mul<&DAffine2> for &DMat3 {
499 type Output = DMat3;
500 #[inline]
501 fn mul(self, rhs: &DAffine2) -> DMat3 {
502 (*self).mul(*rhs)
503 }
504}
505
506impl Mul<DAffine2> for &DMat3 {
507 type Output = DMat3;
508 #[inline]
509 fn mul(self, rhs: DAffine2) -> DMat3 {
510 (*self).mul(rhs)
511 }
512}
513
514impl MulAssign<DAffine2> for DMat3 {
515 #[inline]
516 fn mul_assign(&mut self, rhs: DAffine2) {
517 *self = self.mul(rhs);
518 }
519}
520
521impl MulAssign<&DAffine2> for DMat3 {
522 #[inline]
523 fn mul_assign(&mut self, rhs: &DAffine2) {
524 self.mul_assign(*rhs);
525 }
526}