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