1 // Generated from mat.rs.tera template. Edit the template, not the generated file.
2 
3 use crate::{f32::math, swizzles::*, DMat2, Mat3, Mat3A, Vec2};
4 #[cfg(not(target_arch = "spirv"))]
5 use core::fmt;
6 use core::iter::{Product, Sum};
7 use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
8 
9 use core::simd::*;
10 
11 /// Creates a 2x2 matrix from two column vectors.
12 #[inline(always)]
13 #[must_use]
mat2(x_axis: Vec2, y_axis: Vec2) -> Mat214 pub const fn mat2(x_axis: Vec2, y_axis: Vec2) -> Mat2 {
15     Mat2::from_cols(x_axis, y_axis)
16 }
17 
18 /// A 2x2 column major matrix.
19 ///
20 /// SIMD vector types are used for storage on supported platforms.
21 ///
22 /// This type is 16 byte aligned.
23 #[derive(Clone, Copy)]
24 #[repr(transparent)]
25 pub struct Mat2(pub(crate) f32x4);
26 
27 impl Mat2 {
28     /// A 2x2 matrix with all elements set to `0.0`.
29     pub const ZERO: Self = Self::from_cols(Vec2::ZERO, Vec2::ZERO);
30 
31     /// A 2x2 identity matrix, where all diagonal elements are `1`, and all off-diagonal elements are `0`.
32     pub const IDENTITY: Self = Self::from_cols(Vec2::X, Vec2::Y);
33 
34     /// All NAN:s.
35     pub const NAN: Self = Self::from_cols(Vec2::NAN, Vec2::NAN);
36 
37     #[allow(clippy::too_many_arguments)]
38     #[inline(always)]
39     #[must_use]
new(m00: f32, m01: f32, m10: f32, m11: f32) -> Self40     const fn new(m00: f32, m01: f32, m10: f32, m11: f32) -> Self {
41         Self(f32x4::from_array([m00, m01, m10, m11]))
42     }
43 
44     /// Creates a 2x2 matrix from two column vectors.
45     #[inline(always)]
46     #[must_use]
from_cols(x_axis: Vec2, y_axis: Vec2) -> Self47     pub const fn from_cols(x_axis: Vec2, y_axis: Vec2) -> Self {
48         Self(f32x4::from_array([x_axis.x, x_axis.y, y_axis.x, y_axis.y]))
49     }
50 
51     /// Creates a 2x2 matrix from a `[f32; 4]` array stored in column major order.
52     /// If your data is stored in row major you will need to `transpose` the returned
53     /// matrix.
54     #[inline]
55     #[must_use]
from_cols_array(m: &[f32; 4]) -> Self56     pub const fn from_cols_array(m: &[f32; 4]) -> Self {
57         Self(f32x4::from_array(*m))
58     }
59 
60     /// Creates a `[f32; 4]` array storing data in column major order.
61     /// If you require data in row major order `transpose` the matrix first.
62     #[inline]
63     #[must_use]
to_cols_array(&self) -> [f32; 4]64     pub const fn to_cols_array(&self) -> [f32; 4] {
65         unsafe { *(self as *const Self as *const [f32; 4]) }
66     }
67 
68     /// Creates a 2x2 matrix from a `[[f32; 2]; 2]` 2D array stored in column major order.
69     /// If your data is in row major order you will need to `transpose` the returned
70     /// matrix.
71     #[inline]
72     #[must_use]
from_cols_array_2d(m: &[[f32; 2]; 2]) -> Self73     pub const fn from_cols_array_2d(m: &[[f32; 2]; 2]) -> Self {
74         Self::from_cols(Vec2::from_array(m[0]), Vec2::from_array(m[1]))
75     }
76 
77     /// Creates a `[[f32; 2]; 2]` 2D array storing data in column major order.
78     /// If you require data in row major order `transpose` the matrix first.
79     #[inline]
80     #[must_use]
to_cols_array_2d(&self) -> [[f32; 2]; 2]81     pub const fn to_cols_array_2d(&self) -> [[f32; 2]; 2] {
82         unsafe { *(self as *const Self as *const [[f32; 2]; 2]) }
83     }
84 
85     /// Creates a 2x2 matrix with its diagonal set to `diagonal` and all other entries set to 0.
86     #[doc(alias = "scale")]
87     #[inline]
88     #[must_use]
from_diagonal(diagonal: Vec2) -> Self89     pub const fn from_diagonal(diagonal: Vec2) -> Self {
90         Self::new(diagonal.x, 0.0, 0.0, diagonal.y)
91     }
92 
93     /// Creates a 2x2 matrix containing the combining non-uniform `scale` and rotation of
94     /// `angle` (in radians).
95     #[inline]
96     #[must_use]
from_scale_angle(scale: Vec2, angle: f32) -> Self97     pub fn from_scale_angle(scale: Vec2, angle: f32) -> Self {
98         let (sin, cos) = math::sin_cos(angle);
99         Self::new(cos * scale.x, sin * scale.x, -sin * scale.y, cos * scale.y)
100     }
101 
102     /// Creates a 2x2 matrix containing a rotation of `angle` (in radians).
103     #[inline]
104     #[must_use]
from_angle(angle: f32) -> Self105     pub fn from_angle(angle: f32) -> Self {
106         let (sin, cos) = math::sin_cos(angle);
107         Self::new(cos, sin, -sin, cos)
108     }
109 
110     /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column.
111     #[inline]
112     #[must_use]
from_mat3(m: Mat3) -> Self113     pub fn from_mat3(m: Mat3) -> Self {
114         Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
115     }
116 
117     /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column.
118     #[inline]
119     #[must_use]
from_mat3a(m: Mat3A) -> Self120     pub fn from_mat3a(m: Mat3A) -> Self {
121         Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
122     }
123 
124     /// Creates a 2x2 matrix from the first 4 values in `slice`.
125     ///
126     /// # Panics
127     ///
128     /// Panics if `slice` is less than 4 elements long.
129     #[inline]
130     #[must_use]
from_cols_slice(slice: &[f32]) -> Self131     pub const fn from_cols_slice(slice: &[f32]) -> Self {
132         Self::new(slice[0], slice[1], slice[2], slice[3])
133     }
134 
135     /// Writes the columns of `self` to the first 4 elements in `slice`.
136     ///
137     /// # Panics
138     ///
139     /// Panics if `slice` is less than 4 elements long.
140     #[inline]
write_cols_to_slice(self, slice: &mut [f32])141     pub fn write_cols_to_slice(self, slice: &mut [f32]) {
142         slice[0] = self.x_axis.x;
143         slice[1] = self.x_axis.y;
144         slice[2] = self.y_axis.x;
145         slice[3] = self.y_axis.y;
146     }
147 
148     /// Returns the matrix column for the given `index`.
149     ///
150     /// # Panics
151     ///
152     /// Panics if `index` is greater than 1.
153     #[inline]
154     #[must_use]
col(&self, index: usize) -> Vec2155     pub fn col(&self, index: usize) -> Vec2 {
156         match index {
157             0 => self.x_axis,
158             1 => self.y_axis,
159             _ => panic!("index out of bounds"),
160         }
161     }
162 
163     /// Returns a mutable reference to the matrix column for the given `index`.
164     ///
165     /// # Panics
166     ///
167     /// Panics if `index` is greater than 1.
168     #[inline]
col_mut(&mut self, index: usize) -> &mut Vec2169     pub fn col_mut(&mut self, index: usize) -> &mut Vec2 {
170         match index {
171             0 => &mut self.x_axis,
172             1 => &mut self.y_axis,
173             _ => panic!("index out of bounds"),
174         }
175     }
176 
177     /// Returns the matrix row for the given `index`.
178     ///
179     /// # Panics
180     ///
181     /// Panics if `index` is greater than 1.
182     #[inline]
183     #[must_use]
row(&self, index: usize) -> Vec2184     pub fn row(&self, index: usize) -> Vec2 {
185         match index {
186             0 => Vec2::new(self.x_axis.x, self.y_axis.x),
187             1 => Vec2::new(self.x_axis.y, self.y_axis.y),
188             _ => panic!("index out of bounds"),
189         }
190     }
191 
192     /// Returns `true` if, and only if, all elements are finite.
193     /// If any element is either `NaN`, positive or negative infinity, this will return `false`.
194     #[inline]
195     #[must_use]
is_finite(&self) -> bool196     pub fn is_finite(&self) -> bool {
197         self.x_axis.is_finite() && self.y_axis.is_finite()
198     }
199 
200     /// Returns `true` if any elements are `NaN`.
201     #[inline]
202     #[must_use]
is_nan(&self) -> bool203     pub fn is_nan(&self) -> bool {
204         self.x_axis.is_nan() || self.y_axis.is_nan()
205     }
206 
207     /// Returns the transpose of `self`.
208     #[inline]
209     #[must_use]
transpose(&self) -> Self210     pub fn transpose(&self) -> Self {
211         Self(simd_swizzle!(self.0, [0, 2, 1, 3]))
212     }
213 
214     /// Returns the determinant of `self`.
215     #[inline]
216     #[must_use]
determinant(&self) -> f32217     pub fn determinant(&self) -> f32 {
218         let abcd = self.0;
219         let dcba = simd_swizzle!(abcd, [3, 2, 1, 0]);
220         let prod = abcd * dcba;
221         let det = prod - simd_swizzle!(prod, [1, 1, 1, 1]);
222         det[0]
223     }
224 
225     /// Returns the inverse of `self`.
226     ///
227     /// If the matrix is not invertible the returned matrix will be invalid.
228     ///
229     /// # Panics
230     ///
231     /// Will panic if the determinant of `self` is zero when `glam_assert` is enabled.
232     #[inline]
233     #[must_use]
inverse(&self) -> Self234     pub fn inverse(&self) -> Self {
235         const SIGN: f32x4 = f32x4::from_array([1.0, -1.0, -1.0, 1.0]);
236         let abcd = self.0;
237         let dcba = simd_swizzle!(abcd, [3, 2, 1, 0]);
238         let prod = abcd * dcba;
239         let sub = prod - simd_swizzle!(prod, [1, 1, 1, 1]);
240         let det = simd_swizzle!(sub, [0, 0, 0, 0]);
241         let tmp = SIGN / det;
242         glam_assert!(Mat2(tmp).is_finite());
243         let dbca = simd_swizzle!(abcd, [3, 1, 2, 0]);
244         Self(dbca.mul(tmp))
245     }
246 
247     /// Transforms a 2D vector.
248     #[inline]
249     #[must_use]
mul_vec2(&self, rhs: Vec2) -> Vec2250     pub fn mul_vec2(&self, rhs: Vec2) -> Vec2 {
251         let abcd = self.0;
252         let xxyy = f32x4::from_array([rhs.x, rhs.x, rhs.y, rhs.y]);
253         let axbxcydy = abcd.mul(xxyy);
254         let cydyaxbx = simd_swizzle!(axbxcydy, [2, 3, 0, 1]);
255         let result = axbxcydy.add(cydyaxbx);
256         unsafe { *(&result as *const f32x4 as *const Vec2) }
257     }
258 
259     /// Multiplies two 2x2 matrices.
260     #[inline]
261     #[must_use]
mul_mat2(&self, rhs: &Self) -> Self262     pub fn mul_mat2(&self, rhs: &Self) -> Self {
263         let abcd = self.0;
264         let xxyy0 = simd_swizzle!(rhs.0, [0, 0, 1, 1]);
265         let xxyy1 = simd_swizzle!(rhs.0, [2, 2, 3, 3]);
266         let axbxcydy0 = abcd * xxyy0;
267         let axbxcydy1 = abcd * xxyy1;
268         let cydyaxbx0 = simd_swizzle!(axbxcydy0, [2, 3, 0, 1]);
269         let cydyaxbx1 = simd_swizzle!(axbxcydy1, [2, 3, 0, 1]);
270         let result0 = axbxcydy0 + cydyaxbx0;
271         let result1 = axbxcydy1 + cydyaxbx1;
272         Self(simd_swizzle!(result0, result1, [0, 1, 4, 5]))
273     }
274 
275     /// Adds two 2x2 matrices.
276     #[inline]
277     #[must_use]
add_mat2(&self, rhs: &Self) -> Self278     pub fn add_mat2(&self, rhs: &Self) -> Self {
279         Self(self.0 + rhs.0)
280     }
281 
282     /// Subtracts two 2x2 matrices.
283     #[inline]
284     #[must_use]
sub_mat2(&self, rhs: &Self) -> Self285     pub fn sub_mat2(&self, rhs: &Self) -> Self {
286         Self(self.0 - rhs.0)
287     }
288 
289     /// Multiplies a 2x2 matrix by a scalar.
290     #[inline]
291     #[must_use]
mul_scalar(&self, rhs: f32) -> Self292     pub fn mul_scalar(&self, rhs: f32) -> Self {
293         Self(self.0 * f32x4::splat(rhs))
294     }
295 
296     /// Returns true if the absolute difference of all elements between `self` and `rhs`
297     /// is less than or equal to `max_abs_diff`.
298     ///
299     /// This can be used to compare if two matrices contain similar elements. It works best
300     /// when comparing with a known value. The `max_abs_diff` that should be used used
301     /// depends on the values being compared against.
302     ///
303     /// For more see
304     /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
305     #[inline]
306     #[must_use]
abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool307     pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
308         self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
309             && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
310     }
311 
312     #[inline]
as_dmat2(&self) -> DMat2313     pub fn as_dmat2(&self) -> DMat2 {
314         DMat2::from_cols(self.x_axis.as_dvec2(), self.y_axis.as_dvec2())
315     }
316 }
317 
318 impl Default for Mat2 {
319     #[inline]
default() -> Self320     fn default() -> Self {
321         Self::IDENTITY
322     }
323 }
324 
325 impl Add<Mat2> for Mat2 {
326     type Output = Self;
327     #[inline]
add(self, rhs: Self) -> Self::Output328     fn add(self, rhs: Self) -> Self::Output {
329         self.add_mat2(&rhs)
330     }
331 }
332 
333 impl AddAssign<Mat2> for Mat2 {
334     #[inline]
add_assign(&mut self, rhs: Self)335     fn add_assign(&mut self, rhs: Self) {
336         *self = self.add_mat2(&rhs);
337     }
338 }
339 
340 impl Sub<Mat2> for Mat2 {
341     type Output = Self;
342     #[inline]
sub(self, rhs: Self) -> Self::Output343     fn sub(self, rhs: Self) -> Self::Output {
344         self.sub_mat2(&rhs)
345     }
346 }
347 
348 impl SubAssign<Mat2> for Mat2 {
349     #[inline]
sub_assign(&mut self, rhs: Self)350     fn sub_assign(&mut self, rhs: Self) {
351         *self = self.sub_mat2(&rhs);
352     }
353 }
354 
355 impl Neg for Mat2 {
356     type Output = Self;
357     #[inline]
neg(self) -> Self::Output358     fn neg(self) -> Self::Output {
359         Self(-self.0)
360     }
361 }
362 
363 impl Mul<Mat2> for Mat2 {
364     type Output = Self;
365     #[inline]
mul(self, rhs: Self) -> Self::Output366     fn mul(self, rhs: Self) -> Self::Output {
367         self.mul_mat2(&rhs)
368     }
369 }
370 
371 impl MulAssign<Mat2> for Mat2 {
372     #[inline]
mul_assign(&mut self, rhs: Self)373     fn mul_assign(&mut self, rhs: Self) {
374         *self = self.mul_mat2(&rhs);
375     }
376 }
377 
378 impl Mul<Vec2> for Mat2 {
379     type Output = Vec2;
380     #[inline]
mul(self, rhs: Vec2) -> Self::Output381     fn mul(self, rhs: Vec2) -> Self::Output {
382         self.mul_vec2(rhs)
383     }
384 }
385 
386 impl Mul<Mat2> for f32 {
387     type Output = Mat2;
388     #[inline]
mul(self, rhs: Mat2) -> Self::Output389     fn mul(self, rhs: Mat2) -> Self::Output {
390         rhs.mul_scalar(self)
391     }
392 }
393 
394 impl Mul<f32> for Mat2 {
395     type Output = Self;
396     #[inline]
mul(self, rhs: f32) -> Self::Output397     fn mul(self, rhs: f32) -> Self::Output {
398         self.mul_scalar(rhs)
399     }
400 }
401 
402 impl MulAssign<f32> for Mat2 {
403     #[inline]
mul_assign(&mut self, rhs: f32)404     fn mul_assign(&mut self, rhs: f32) {
405         *self = self.mul_scalar(rhs);
406     }
407 }
408 
409 impl Sum<Self> for Mat2 {
sum<I>(iter: I) -> Self where I: Iterator<Item = Self>,410     fn sum<I>(iter: I) -> Self
411     where
412         I: Iterator<Item = Self>,
413     {
414         iter.fold(Self::ZERO, Self::add)
415     }
416 }
417 
418 impl<'a> Sum<&'a Self> for Mat2 {
sum<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,419     fn sum<I>(iter: I) -> Self
420     where
421         I: Iterator<Item = &'a Self>,
422     {
423         iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
424     }
425 }
426 
427 impl Product for Mat2 {
product<I>(iter: I) -> Self where I: Iterator<Item = Self>,428     fn product<I>(iter: I) -> Self
429     where
430         I: Iterator<Item = Self>,
431     {
432         iter.fold(Self::IDENTITY, Self::mul)
433     }
434 }
435 
436 impl<'a> Product<&'a Self> for Mat2 {
product<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,437     fn product<I>(iter: I) -> Self
438     where
439         I: Iterator<Item = &'a Self>,
440     {
441         iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
442     }
443 }
444 
445 impl PartialEq for Mat2 {
446     #[inline]
eq(&self, rhs: &Self) -> bool447     fn eq(&self, rhs: &Self) -> bool {
448         self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis)
449     }
450 }
451 
452 #[cfg(not(target_arch = "spirv"))]
453 impl AsRef<[f32; 4]> for Mat2 {
454     #[inline]
as_ref(&self) -> &[f32; 4]455     fn as_ref(&self) -> &[f32; 4] {
456         unsafe { &*(self as *const Self as *const [f32; 4]) }
457     }
458 }
459 
460 #[cfg(not(target_arch = "spirv"))]
461 impl AsMut<[f32; 4]> for Mat2 {
462     #[inline]
as_mut(&mut self) -> &mut [f32; 4]463     fn as_mut(&mut self) -> &mut [f32; 4] {
464         unsafe { &mut *(self as *mut Self as *mut [f32; 4]) }
465     }
466 }
467 
468 impl core::ops::Deref for Mat2 {
469     type Target = crate::deref::Cols2<Vec2>;
470     #[inline]
deref(&self) -> &Self::Target471     fn deref(&self) -> &Self::Target {
472         unsafe { &*(self as *const Self as *const Self::Target) }
473     }
474 }
475 
476 impl core::ops::DerefMut for Mat2 {
477     #[inline]
deref_mut(&mut self) -> &mut Self::Target478     fn deref_mut(&mut self) -> &mut Self::Target {
479         unsafe { &mut *(self as *mut Self as *mut Self::Target) }
480     }
481 }
482 
483 #[cfg(not(target_arch = "spirv"))]
484 impl fmt::Debug for Mat2 {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result485     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
486         fmt.debug_struct(stringify!(Mat2))
487             .field("x_axis", &self.x_axis)
488             .field("y_axis", &self.y_axis)
489             .finish()
490     }
491 }
492 
493 #[cfg(not(target_arch = "spirv"))]
494 impl fmt::Display for Mat2 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result495     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
496         write!(f, "[{}, {}]", self.x_axis, self.y_axis)
497     }
498 }
499