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 /// Creates a 2x2 matrix from two column vectors.
10 #[inline(always)]
11 #[must_use]
mat2(x_axis: Vec2, y_axis: Vec2) -> Mat212 pub const fn mat2(x_axis: Vec2, y_axis: Vec2) -> Mat2 {
13     Mat2::from_cols(x_axis, y_axis)
14 }
15 
16 /// A 2x2 column major matrix.
17 #[derive(Clone, Copy)]
18 #[cfg_attr(
19     not(any(feature = "scalar-math", target_arch = "spirv")),
20     repr(align(16))
21 )]
22 #[cfg_attr(feature = "cuda", repr(align(8)))]
23 #[repr(C)]
24 pub struct Mat2 {
25     pub x_axis: Vec2,
26     pub y_axis: Vec2,
27 }
28 
29 impl Mat2 {
30     /// A 2x2 matrix with all elements set to `0.0`.
31     pub const ZERO: Self = Self::from_cols(Vec2::ZERO, Vec2::ZERO);
32 
33     /// A 2x2 identity matrix, where all diagonal elements are `1`, and all off-diagonal elements are `0`.
34     pub const IDENTITY: Self = Self::from_cols(Vec2::X, Vec2::Y);
35 
36     /// All NAN:s.
37     pub const NAN: Self = Self::from_cols(Vec2::NAN, Vec2::NAN);
38 
39     #[allow(clippy::too_many_arguments)]
40     #[inline(always)]
41     #[must_use]
new(m00: f32, m01: f32, m10: f32, m11: f32) -> Self42     const fn new(m00: f32, m01: f32, m10: f32, m11: f32) -> Self {
43         Self {
44             x_axis: Vec2::new(m00, m01),
45             y_axis: Vec2::new(m10, m11),
46         }
47     }
48 
49     /// Creates a 2x2 matrix from two column vectors.
50     #[inline(always)]
51     #[must_use]
from_cols(x_axis: Vec2, y_axis: Vec2) -> Self52     pub const fn from_cols(x_axis: Vec2, y_axis: Vec2) -> Self {
53         Self { x_axis, y_axis }
54     }
55 
56     /// Creates a 2x2 matrix from a `[f32; 4]` array stored in column major order.
57     /// If your data is stored in row major you will need to `transpose` the returned
58     /// matrix.
59     #[inline]
60     #[must_use]
from_cols_array(m: &[f32; 4]) -> Self61     pub const fn from_cols_array(m: &[f32; 4]) -> Self {
62         Self::new(m[0], m[1], m[2], m[3])
63     }
64 
65     /// Creates a `[f32; 4]` array storing data in column major order.
66     /// If you require data in row major order `transpose` the matrix first.
67     #[inline]
68     #[must_use]
to_cols_array(&self) -> [f32; 4]69     pub const fn to_cols_array(&self) -> [f32; 4] {
70         [self.x_axis.x, self.x_axis.y, self.y_axis.x, self.y_axis.y]
71     }
72 
73     /// Creates a 2x2 matrix from a `[[f32; 2]; 2]` 2D array stored in column major order.
74     /// If your data is in row major order you will need to `transpose` the returned
75     /// matrix.
76     #[inline]
77     #[must_use]
from_cols_array_2d(m: &[[f32; 2]; 2]) -> Self78     pub const fn from_cols_array_2d(m: &[[f32; 2]; 2]) -> Self {
79         Self::from_cols(Vec2::from_array(m[0]), Vec2::from_array(m[1]))
80     }
81 
82     /// Creates a `[[f32; 2]; 2]` 2D array storing data in column major order.
83     /// If you require data in row major order `transpose` the matrix first.
84     #[inline]
85     #[must_use]
to_cols_array_2d(&self) -> [[f32; 2]; 2]86     pub const fn to_cols_array_2d(&self) -> [[f32; 2]; 2] {
87         [self.x_axis.to_array(), self.y_axis.to_array()]
88     }
89 
90     /// Creates a 2x2 matrix with its diagonal set to `diagonal` and all other entries set to 0.
91     #[doc(alias = "scale")]
92     #[inline]
93     #[must_use]
from_diagonal(diagonal: Vec2) -> Self94     pub const fn from_diagonal(diagonal: Vec2) -> Self {
95         Self::new(diagonal.x, 0.0, 0.0, diagonal.y)
96     }
97 
98     /// Creates a 2x2 matrix containing the combining non-uniform `scale` and rotation of
99     /// `angle` (in radians).
100     #[inline]
101     #[must_use]
from_scale_angle(scale: Vec2, angle: f32) -> Self102     pub fn from_scale_angle(scale: Vec2, angle: f32) -> Self {
103         let (sin, cos) = math::sin_cos(angle);
104         Self::new(cos * scale.x, sin * scale.x, -sin * scale.y, cos * scale.y)
105     }
106 
107     /// Creates a 2x2 matrix containing a rotation of `angle` (in radians).
108     #[inline]
109     #[must_use]
from_angle(angle: f32) -> Self110     pub fn from_angle(angle: f32) -> Self {
111         let (sin, cos) = math::sin_cos(angle);
112         Self::new(cos, sin, -sin, cos)
113     }
114 
115     /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column.
116     #[inline]
117     #[must_use]
from_mat3(m: Mat3) -> Self118     pub fn from_mat3(m: Mat3) -> Self {
119         Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
120     }
121 
122     /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column.
123     #[inline]
124     #[must_use]
from_mat3a(m: Mat3A) -> Self125     pub fn from_mat3a(m: Mat3A) -> Self {
126         Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
127     }
128 
129     /// Creates a 2x2 matrix from the first 4 values in `slice`.
130     ///
131     /// # Panics
132     ///
133     /// Panics if `slice` is less than 4 elements long.
134     #[inline]
135     #[must_use]
from_cols_slice(slice: &[f32]) -> Self136     pub const fn from_cols_slice(slice: &[f32]) -> Self {
137         Self::new(slice[0], slice[1], slice[2], slice[3])
138     }
139 
140     /// Writes the columns of `self` to the first 4 elements in `slice`.
141     ///
142     /// # Panics
143     ///
144     /// Panics if `slice` is less than 4 elements long.
145     #[inline]
write_cols_to_slice(self, slice: &mut [f32])146     pub fn write_cols_to_slice(self, slice: &mut [f32]) {
147         slice[0] = self.x_axis.x;
148         slice[1] = self.x_axis.y;
149         slice[2] = self.y_axis.x;
150         slice[3] = self.y_axis.y;
151     }
152 
153     /// Returns the matrix column for the given `index`.
154     ///
155     /// # Panics
156     ///
157     /// Panics if `index` is greater than 1.
158     #[inline]
159     #[must_use]
col(&self, index: usize) -> Vec2160     pub fn col(&self, index: usize) -> Vec2 {
161         match index {
162             0 => self.x_axis,
163             1 => self.y_axis,
164             _ => panic!("index out of bounds"),
165         }
166     }
167 
168     /// Returns a mutable reference to the matrix column for the given `index`.
169     ///
170     /// # Panics
171     ///
172     /// Panics if `index` is greater than 1.
173     #[inline]
col_mut(&mut self, index: usize) -> &mut Vec2174     pub fn col_mut(&mut self, index: usize) -> &mut Vec2 {
175         match index {
176             0 => &mut self.x_axis,
177             1 => &mut self.y_axis,
178             _ => panic!("index out of bounds"),
179         }
180     }
181 
182     /// Returns the matrix row for the given `index`.
183     ///
184     /// # Panics
185     ///
186     /// Panics if `index` is greater than 1.
187     #[inline]
188     #[must_use]
row(&self, index: usize) -> Vec2189     pub fn row(&self, index: usize) -> Vec2 {
190         match index {
191             0 => Vec2::new(self.x_axis.x, self.y_axis.x),
192             1 => Vec2::new(self.x_axis.y, self.y_axis.y),
193             _ => panic!("index out of bounds"),
194         }
195     }
196 
197     /// Returns `true` if, and only if, all elements are finite.
198     /// If any element is either `NaN`, positive or negative infinity, this will return `false`.
199     #[inline]
200     #[must_use]
is_finite(&self) -> bool201     pub fn is_finite(&self) -> bool {
202         self.x_axis.is_finite() && self.y_axis.is_finite()
203     }
204 
205     /// Returns `true` if any elements are `NaN`.
206     #[inline]
207     #[must_use]
is_nan(&self) -> bool208     pub fn is_nan(&self) -> bool {
209         self.x_axis.is_nan() || self.y_axis.is_nan()
210     }
211 
212     /// Returns the transpose of `self`.
213     #[inline]
214     #[must_use]
transpose(&self) -> Self215     pub fn transpose(&self) -> Self {
216         Self {
217             x_axis: Vec2::new(self.x_axis.x, self.y_axis.x),
218             y_axis: Vec2::new(self.x_axis.y, self.y_axis.y),
219         }
220     }
221 
222     /// Returns the determinant of `self`.
223     #[inline]
224     #[must_use]
determinant(&self) -> f32225     pub fn determinant(&self) -> f32 {
226         self.x_axis.x * self.y_axis.y - self.x_axis.y * self.y_axis.x
227     }
228 
229     /// Returns the inverse of `self`.
230     ///
231     /// If the matrix is not invertible the returned matrix will be invalid.
232     ///
233     /// # Panics
234     ///
235     /// Will panic if the determinant of `self` is zero when `glam_assert` is enabled.
236     #[inline]
237     #[must_use]
inverse(&self) -> Self238     pub fn inverse(&self) -> Self {
239         let inv_det = {
240             let det = self.determinant();
241             glam_assert!(det != 0.0);
242             det.recip()
243         };
244         Self::new(
245             self.y_axis.y * inv_det,
246             self.x_axis.y * -inv_det,
247             self.y_axis.x * -inv_det,
248             self.x_axis.x * inv_det,
249         )
250     }
251 
252     /// Transforms a 2D vector.
253     #[inline]
254     #[must_use]
mul_vec2(&self, rhs: Vec2) -> Vec2255     pub fn mul_vec2(&self, rhs: Vec2) -> Vec2 {
256         #[allow(clippy::suspicious_operation_groupings)]
257         Vec2::new(
258             (self.x_axis.x * rhs.x) + (self.y_axis.x * rhs.y),
259             (self.x_axis.y * rhs.x) + (self.y_axis.y * rhs.y),
260         )
261     }
262 
263     /// Multiplies two 2x2 matrices.
264     #[inline]
265     #[must_use]
mul_mat2(&self, rhs: &Self) -> Self266     pub fn mul_mat2(&self, rhs: &Self) -> Self {
267         Self::from_cols(self.mul(rhs.x_axis), self.mul(rhs.y_axis))
268     }
269 
270     /// Adds two 2x2 matrices.
271     #[inline]
272     #[must_use]
add_mat2(&self, rhs: &Self) -> Self273     pub fn add_mat2(&self, rhs: &Self) -> Self {
274         Self::from_cols(self.x_axis.add(rhs.x_axis), self.y_axis.add(rhs.y_axis))
275     }
276 
277     /// Subtracts two 2x2 matrices.
278     #[inline]
279     #[must_use]
sub_mat2(&self, rhs: &Self) -> Self280     pub fn sub_mat2(&self, rhs: &Self) -> Self {
281         Self::from_cols(self.x_axis.sub(rhs.x_axis), self.y_axis.sub(rhs.y_axis))
282     }
283 
284     /// Multiplies a 2x2 matrix by a scalar.
285     #[inline]
286     #[must_use]
mul_scalar(&self, rhs: f32) -> Self287     pub fn mul_scalar(&self, rhs: f32) -> Self {
288         Self::from_cols(self.x_axis.mul(rhs), self.y_axis.mul(rhs))
289     }
290 
291     /// Returns true if the absolute difference of all elements between `self` and `rhs`
292     /// is less than or equal to `max_abs_diff`.
293     ///
294     /// This can be used to compare if two matrices contain similar elements. It works best
295     /// when comparing with a known value. The `max_abs_diff` that should be used used
296     /// depends on the values being compared against.
297     ///
298     /// For more see
299     /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
300     #[inline]
301     #[must_use]
abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool302     pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
303         self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
304             && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
305     }
306 
307     #[inline]
as_dmat2(&self) -> DMat2308     pub fn as_dmat2(&self) -> DMat2 {
309         DMat2::from_cols(self.x_axis.as_dvec2(), self.y_axis.as_dvec2())
310     }
311 }
312 
313 impl Default for Mat2 {
314     #[inline]
default() -> Self315     fn default() -> Self {
316         Self::IDENTITY
317     }
318 }
319 
320 impl Add<Mat2> for Mat2 {
321     type Output = Self;
322     #[inline]
add(self, rhs: Self) -> Self::Output323     fn add(self, rhs: Self) -> Self::Output {
324         self.add_mat2(&rhs)
325     }
326 }
327 
328 impl AddAssign<Mat2> for Mat2 {
329     #[inline]
add_assign(&mut self, rhs: Self)330     fn add_assign(&mut self, rhs: Self) {
331         *self = self.add_mat2(&rhs);
332     }
333 }
334 
335 impl Sub<Mat2> for Mat2 {
336     type Output = Self;
337     #[inline]
sub(self, rhs: Self) -> Self::Output338     fn sub(self, rhs: Self) -> Self::Output {
339         self.sub_mat2(&rhs)
340     }
341 }
342 
343 impl SubAssign<Mat2> for Mat2 {
344     #[inline]
sub_assign(&mut self, rhs: Self)345     fn sub_assign(&mut self, rhs: Self) {
346         *self = self.sub_mat2(&rhs);
347     }
348 }
349 
350 impl Neg for Mat2 {
351     type Output = Self;
352     #[inline]
neg(self) -> Self::Output353     fn neg(self) -> Self::Output {
354         Self::from_cols(self.x_axis.neg(), self.y_axis.neg())
355     }
356 }
357 
358 impl Mul<Mat2> for Mat2 {
359     type Output = Self;
360     #[inline]
mul(self, rhs: Self) -> Self::Output361     fn mul(self, rhs: Self) -> Self::Output {
362         self.mul_mat2(&rhs)
363     }
364 }
365 
366 impl MulAssign<Mat2> for Mat2 {
367     #[inline]
mul_assign(&mut self, rhs: Self)368     fn mul_assign(&mut self, rhs: Self) {
369         *self = self.mul_mat2(&rhs);
370     }
371 }
372 
373 impl Mul<Vec2> for Mat2 {
374     type Output = Vec2;
375     #[inline]
mul(self, rhs: Vec2) -> Self::Output376     fn mul(self, rhs: Vec2) -> Self::Output {
377         self.mul_vec2(rhs)
378     }
379 }
380 
381 impl Mul<Mat2> for f32 {
382     type Output = Mat2;
383     #[inline]
mul(self, rhs: Mat2) -> Self::Output384     fn mul(self, rhs: Mat2) -> Self::Output {
385         rhs.mul_scalar(self)
386     }
387 }
388 
389 impl Mul<f32> for Mat2 {
390     type Output = Self;
391     #[inline]
mul(self, rhs: f32) -> Self::Output392     fn mul(self, rhs: f32) -> Self::Output {
393         self.mul_scalar(rhs)
394     }
395 }
396 
397 impl MulAssign<f32> for Mat2 {
398     #[inline]
mul_assign(&mut self, rhs: f32)399     fn mul_assign(&mut self, rhs: f32) {
400         *self = self.mul_scalar(rhs);
401     }
402 }
403 
404 impl Sum<Self> for Mat2 {
sum<I>(iter: I) -> Self where I: Iterator<Item = Self>,405     fn sum<I>(iter: I) -> Self
406     where
407         I: Iterator<Item = Self>,
408     {
409         iter.fold(Self::ZERO, Self::add)
410     }
411 }
412 
413 impl<'a> Sum<&'a Self> for Mat2 {
sum<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,414     fn sum<I>(iter: I) -> Self
415     where
416         I: Iterator<Item = &'a Self>,
417     {
418         iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
419     }
420 }
421 
422 impl Product for Mat2 {
product<I>(iter: I) -> Self where I: Iterator<Item = Self>,423     fn product<I>(iter: I) -> Self
424     where
425         I: Iterator<Item = Self>,
426     {
427         iter.fold(Self::IDENTITY, Self::mul)
428     }
429 }
430 
431 impl<'a> Product<&'a Self> for Mat2 {
product<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,432     fn product<I>(iter: I) -> Self
433     where
434         I: Iterator<Item = &'a Self>,
435     {
436         iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
437     }
438 }
439 
440 impl PartialEq for Mat2 {
441     #[inline]
eq(&self, rhs: &Self) -> bool442     fn eq(&self, rhs: &Self) -> bool {
443         self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis)
444     }
445 }
446 
447 #[cfg(not(target_arch = "spirv"))]
448 impl AsRef<[f32; 4]> for Mat2 {
449     #[inline]
as_ref(&self) -> &[f32; 4]450     fn as_ref(&self) -> &[f32; 4] {
451         unsafe { &*(self as *const Self as *const [f32; 4]) }
452     }
453 }
454 
455 #[cfg(not(target_arch = "spirv"))]
456 impl AsMut<[f32; 4]> for Mat2 {
457     #[inline]
as_mut(&mut self) -> &mut [f32; 4]458     fn as_mut(&mut self) -> &mut [f32; 4] {
459         unsafe { &mut *(self as *mut Self as *mut [f32; 4]) }
460     }
461 }
462 
463 #[cfg(not(target_arch = "spirv"))]
464 impl fmt::Debug for Mat2 {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result465     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
466         fmt.debug_struct(stringify!(Mat2))
467             .field("x_axis", &self.x_axis)
468             .field("y_axis", &self.y_axis)
469             .finish()
470     }
471 }
472 
473 #[cfg(not(target_arch = "spirv"))]
474 impl fmt::Display for Mat2 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result475     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
476         write!(f, "[{}, {}]", self.x_axis, self.y_axis)
477     }
478 }
479