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 use core::fmt;
5 use core::iter::{Product, Sum};
6 use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
7
8 /// Creates a 2x2 matrix from two column vectors.
9 #[inline(always)]
10 #[must_use]
mat2(x_axis: Vec2, y_axis: Vec2) -> Mat211 pub const fn mat2(x_axis: Vec2, y_axis: Vec2) -> Mat2 {
12 Mat2::from_cols(x_axis, y_axis)
13 }
14
15 /// A 2x2 column major matrix.
16 #[derive(Clone, Copy)]
17 #[cfg_attr(
18 not(any(feature = "scalar-math", target_arch = "spirv")),
19 repr(align(16))
20 )]
21 #[cfg_attr(feature = "cuda", repr(align(8)))]
22 #[repr(C)]
23 pub struct Mat2 {
24 pub x_axis: Vec2,
25 pub y_axis: Vec2,
26 }
27
28 impl Mat2 {
29 /// A 2x2 matrix with all elements set to `0.0`.
30 pub const ZERO: Self = Self::from_cols(Vec2::ZERO, Vec2::ZERO);
31
32 /// A 2x2 identity matrix, where all diagonal elements are `1`, and all off-diagonal elements are `0`.
33 pub const IDENTITY: Self = Self::from_cols(Vec2::X, Vec2::Y);
34
35 /// All NAN:s.
36 pub const NAN: Self = Self::from_cols(Vec2::NAN, Vec2::NAN);
37
38 #[allow(clippy::too_many_arguments)]
39 #[inline(always)]
40 #[must_use]
new(m00: f32, m01: f32, m10: f32, m11: f32) -> Self41 const fn new(m00: f32, m01: f32, m10: f32, m11: f32) -> Self {
42 Self {
43 x_axis: Vec2::new(m00, m01),
44 y_axis: Vec2::new(m10, m11),
45 }
46 }
47
48 /// Creates a 2x2 matrix from two column vectors.
49 #[inline(always)]
50 #[must_use]
from_cols(x_axis: Vec2, y_axis: Vec2) -> Self51 pub const fn from_cols(x_axis: Vec2, y_axis: Vec2) -> Self {
52 Self { x_axis, y_axis }
53 }
54
55 /// Creates a 2x2 matrix from a `[f32; 4]` array stored in column major order.
56 /// If your data is stored in row major you will need to `transpose` the returned
57 /// matrix.
58 #[inline]
59 #[must_use]
from_cols_array(m: &[f32; 4]) -> Self60 pub const fn from_cols_array(m: &[f32; 4]) -> Self {
61 Self::new(m[0], m[1], m[2], m[3])
62 }
63
64 /// Creates a `[f32; 4]` array storing data in column major order.
65 /// If you require data in row major order `transpose` the matrix first.
66 #[inline]
67 #[must_use]
to_cols_array(&self) -> [f32; 4]68 pub const fn to_cols_array(&self) -> [f32; 4] {
69 [self.x_axis.x, self.x_axis.y, self.y_axis.x, self.y_axis.y]
70 }
71
72 /// Creates a 2x2 matrix from a `[[f32; 2]; 2]` 2D array stored in column major order.
73 /// If your data is in row major order you will need to `transpose` the returned
74 /// matrix.
75 #[inline]
76 #[must_use]
from_cols_array_2d(m: &[[f32; 2]; 2]) -> Self77 pub const fn from_cols_array_2d(m: &[[f32; 2]; 2]) -> Self {
78 Self::from_cols(Vec2::from_array(m[0]), Vec2::from_array(m[1]))
79 }
80
81 /// Creates a `[[f32; 2]; 2]` 2D array storing data in column major order.
82 /// If you require data in row major order `transpose` the matrix first.
83 #[inline]
84 #[must_use]
to_cols_array_2d(&self) -> [[f32; 2]; 2]85 pub const fn to_cols_array_2d(&self) -> [[f32; 2]; 2] {
86 [self.x_axis.to_array(), self.y_axis.to_array()]
87 }
88
89 /// Creates a 2x2 matrix with its diagonal set to `diagonal` and all other entries set to 0.
90 #[doc(alias = "scale")]
91 #[inline]
92 #[must_use]
from_diagonal(diagonal: Vec2) -> Self93 pub const fn from_diagonal(diagonal: Vec2) -> Self {
94 Self::new(diagonal.x, 0.0, 0.0, diagonal.y)
95 }
96
97 /// Creates a 2x2 matrix containing the combining non-uniform `scale` and rotation of
98 /// `angle` (in radians).
99 #[inline]
100 #[must_use]
from_scale_angle(scale: Vec2, angle: f32) -> Self101 pub fn from_scale_angle(scale: Vec2, angle: f32) -> Self {
102 let (sin, cos) = math::sin_cos(angle);
103 Self::new(cos * scale.x, sin * scale.x, -sin * scale.y, cos * scale.y)
104 }
105
106 /// Creates a 2x2 matrix containing a rotation of `angle` (in radians).
107 #[inline]
108 #[must_use]
from_angle(angle: f32) -> Self109 pub fn from_angle(angle: f32) -> Self {
110 let (sin, cos) = math::sin_cos(angle);
111 Self::new(cos, sin, -sin, cos)
112 }
113
114 /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column.
115 #[inline]
116 #[must_use]
from_mat3(m: Mat3) -> Self117 pub fn from_mat3(m: Mat3) -> Self {
118 Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
119 }
120
121 /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
122 /// and `j`th row.
123 ///
124 /// # Panics
125 ///
126 /// Panics if `i` or `j` is greater than 2.
127 #[inline]
128 #[must_use]
from_mat3_minor(m: Mat3, i: usize, j: usize) -> Self129 pub fn from_mat3_minor(m: Mat3, i: usize, j: usize) -> Self {
130 match (i, j) {
131 (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
132 (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
133 (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
134 (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
135 (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
136 (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
137 (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
138 (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
139 (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
140 _ => panic!("index out of bounds"),
141 }
142 }
143
144 /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column.
145 #[inline]
146 #[must_use]
from_mat3a(m: Mat3A) -> Self147 pub fn from_mat3a(m: Mat3A) -> Self {
148 Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
149 }
150
151 /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
152 /// and `j`th row.
153 ///
154 /// # Panics
155 ///
156 /// Panics if `i` or `j` is greater than 2.
157 #[inline]
158 #[must_use]
from_mat3a_minor(m: Mat3A, i: usize, j: usize) -> Self159 pub fn from_mat3a_minor(m: Mat3A, i: usize, j: usize) -> Self {
160 match (i, j) {
161 (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
162 (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
163 (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
164 (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
165 (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
166 (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
167 (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
168 (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
169 (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
170 _ => panic!("index out of bounds"),
171 }
172 }
173
174 /// Creates a 2x2 matrix from the first 4 values in `slice`.
175 ///
176 /// # Panics
177 ///
178 /// Panics if `slice` is less than 4 elements long.
179 #[inline]
180 #[must_use]
from_cols_slice(slice: &[f32]) -> Self181 pub const fn from_cols_slice(slice: &[f32]) -> Self {
182 Self::new(slice[0], slice[1], slice[2], slice[3])
183 }
184
185 /// Writes the columns of `self` to the first 4 elements in `slice`.
186 ///
187 /// # Panics
188 ///
189 /// Panics if `slice` is less than 4 elements long.
190 #[inline]
write_cols_to_slice(self, slice: &mut [f32])191 pub fn write_cols_to_slice(self, slice: &mut [f32]) {
192 slice[0] = self.x_axis.x;
193 slice[1] = self.x_axis.y;
194 slice[2] = self.y_axis.x;
195 slice[3] = self.y_axis.y;
196 }
197
198 /// Returns the matrix column for the given `index`.
199 ///
200 /// # Panics
201 ///
202 /// Panics if `index` is greater than 1.
203 #[inline]
204 #[must_use]
col(&self, index: usize) -> Vec2205 pub fn col(&self, index: usize) -> Vec2 {
206 match index {
207 0 => self.x_axis,
208 1 => self.y_axis,
209 _ => panic!("index out of bounds"),
210 }
211 }
212
213 /// Returns a mutable reference to the matrix column for the given `index`.
214 ///
215 /// # Panics
216 ///
217 /// Panics if `index` is greater than 1.
218 #[inline]
col_mut(&mut self, index: usize) -> &mut Vec2219 pub fn col_mut(&mut self, index: usize) -> &mut Vec2 {
220 match index {
221 0 => &mut self.x_axis,
222 1 => &mut self.y_axis,
223 _ => panic!("index out of bounds"),
224 }
225 }
226
227 /// Returns the matrix row for the given `index`.
228 ///
229 /// # Panics
230 ///
231 /// Panics if `index` is greater than 1.
232 #[inline]
233 #[must_use]
row(&self, index: usize) -> Vec2234 pub fn row(&self, index: usize) -> Vec2 {
235 match index {
236 0 => Vec2::new(self.x_axis.x, self.y_axis.x),
237 1 => Vec2::new(self.x_axis.y, self.y_axis.y),
238 _ => panic!("index out of bounds"),
239 }
240 }
241
242 /// Returns `true` if, and only if, all elements are finite.
243 /// If any element is either `NaN`, positive or negative infinity, this will return `false`.
244 #[inline]
245 #[must_use]
is_finite(&self) -> bool246 pub fn is_finite(&self) -> bool {
247 self.x_axis.is_finite() && self.y_axis.is_finite()
248 }
249
250 /// Returns `true` if any elements are `NaN`.
251 #[inline]
252 #[must_use]
is_nan(&self) -> bool253 pub fn is_nan(&self) -> bool {
254 self.x_axis.is_nan() || self.y_axis.is_nan()
255 }
256
257 /// Returns the transpose of `self`.
258 #[inline]
259 #[must_use]
transpose(&self) -> Self260 pub fn transpose(&self) -> Self {
261 Self {
262 x_axis: Vec2::new(self.x_axis.x, self.y_axis.x),
263 y_axis: Vec2::new(self.x_axis.y, self.y_axis.y),
264 }
265 }
266
267 /// Returns the determinant of `self`.
268 #[inline]
269 #[must_use]
determinant(&self) -> f32270 pub fn determinant(&self) -> f32 {
271 self.x_axis.x * self.y_axis.y - self.x_axis.y * self.y_axis.x
272 }
273
274 /// Returns the inverse of `self`.
275 ///
276 /// If the matrix is not invertible the returned matrix will be invalid.
277 ///
278 /// # Panics
279 ///
280 /// Will panic if the determinant of `self` is zero when `glam_assert` is enabled.
281 #[inline]
282 #[must_use]
inverse(&self) -> Self283 pub fn inverse(&self) -> Self {
284 let inv_det = {
285 let det = self.determinant();
286 glam_assert!(det != 0.0);
287 det.recip()
288 };
289 Self::new(
290 self.y_axis.y * inv_det,
291 self.x_axis.y * -inv_det,
292 self.y_axis.x * -inv_det,
293 self.x_axis.x * inv_det,
294 )
295 }
296
297 /// Transforms a 2D vector.
298 #[inline]
299 #[must_use]
mul_vec2(&self, rhs: Vec2) -> Vec2300 pub fn mul_vec2(&self, rhs: Vec2) -> Vec2 {
301 #[allow(clippy::suspicious_operation_groupings)]
302 Vec2::new(
303 (self.x_axis.x * rhs.x) + (self.y_axis.x * rhs.y),
304 (self.x_axis.y * rhs.x) + (self.y_axis.y * rhs.y),
305 )
306 }
307
308 /// Multiplies two 2x2 matrices.
309 #[inline]
310 #[must_use]
mul_mat2(&self, rhs: &Self) -> Self311 pub fn mul_mat2(&self, rhs: &Self) -> Self {
312 Self::from_cols(self.mul(rhs.x_axis), self.mul(rhs.y_axis))
313 }
314
315 /// Adds two 2x2 matrices.
316 #[inline]
317 #[must_use]
add_mat2(&self, rhs: &Self) -> Self318 pub fn add_mat2(&self, rhs: &Self) -> Self {
319 Self::from_cols(self.x_axis.add(rhs.x_axis), self.y_axis.add(rhs.y_axis))
320 }
321
322 /// Subtracts two 2x2 matrices.
323 #[inline]
324 #[must_use]
sub_mat2(&self, rhs: &Self) -> Self325 pub fn sub_mat2(&self, rhs: &Self) -> Self {
326 Self::from_cols(self.x_axis.sub(rhs.x_axis), self.y_axis.sub(rhs.y_axis))
327 }
328
329 /// Multiplies a 2x2 matrix by a scalar.
330 #[inline]
331 #[must_use]
mul_scalar(&self, rhs: f32) -> Self332 pub fn mul_scalar(&self, rhs: f32) -> Self {
333 Self::from_cols(self.x_axis.mul(rhs), self.y_axis.mul(rhs))
334 }
335
336 /// Divides a 2x2 matrix by a scalar.
337 #[inline]
338 #[must_use]
div_scalar(&self, rhs: f32) -> Self339 pub fn div_scalar(&self, rhs: f32) -> Self {
340 let rhs = Vec2::splat(rhs);
341 Self::from_cols(self.x_axis.div(rhs), self.y_axis.div(rhs))
342 }
343
344 /// Returns true if the absolute difference of all elements between `self` and `rhs`
345 /// is less than or equal to `max_abs_diff`.
346 ///
347 /// This can be used to compare if two matrices contain similar elements. It works best
348 /// when comparing with a known value. The `max_abs_diff` that should be used used
349 /// depends on the values being compared against.
350 ///
351 /// For more see
352 /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
353 #[inline]
354 #[must_use]
abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool355 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
356 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
357 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
358 }
359
360 /// Takes the absolute value of each element in `self`
361 #[inline]
362 #[must_use]
abs(&self) -> Self363 pub fn abs(&self) -> Self {
364 Self::from_cols(self.x_axis.abs(), self.y_axis.abs())
365 }
366
367 #[inline]
as_dmat2(&self) -> DMat2368 pub fn as_dmat2(&self) -> DMat2 {
369 DMat2::from_cols(self.x_axis.as_dvec2(), self.y_axis.as_dvec2())
370 }
371 }
372
373 impl Default for Mat2 {
374 #[inline]
default() -> Self375 fn default() -> Self {
376 Self::IDENTITY
377 }
378 }
379
380 impl Add<Mat2> for Mat2 {
381 type Output = Self;
382 #[inline]
add(self, rhs: Self) -> Self::Output383 fn add(self, rhs: Self) -> Self::Output {
384 self.add_mat2(&rhs)
385 }
386 }
387
388 impl AddAssign<Mat2> for Mat2 {
389 #[inline]
add_assign(&mut self, rhs: Self)390 fn add_assign(&mut self, rhs: Self) {
391 *self = self.add_mat2(&rhs);
392 }
393 }
394
395 impl Sub<Mat2> for Mat2 {
396 type Output = Self;
397 #[inline]
sub(self, rhs: Self) -> Self::Output398 fn sub(self, rhs: Self) -> Self::Output {
399 self.sub_mat2(&rhs)
400 }
401 }
402
403 impl SubAssign<Mat2> for Mat2 {
404 #[inline]
sub_assign(&mut self, rhs: Self)405 fn sub_assign(&mut self, rhs: Self) {
406 *self = self.sub_mat2(&rhs);
407 }
408 }
409
410 impl Neg for Mat2 {
411 type Output = Self;
412 #[inline]
neg(self) -> Self::Output413 fn neg(self) -> Self::Output {
414 Self::from_cols(self.x_axis.neg(), self.y_axis.neg())
415 }
416 }
417
418 impl Mul<Mat2> for Mat2 {
419 type Output = Self;
420 #[inline]
mul(self, rhs: Self) -> Self::Output421 fn mul(self, rhs: Self) -> Self::Output {
422 self.mul_mat2(&rhs)
423 }
424 }
425
426 impl MulAssign<Mat2> for Mat2 {
427 #[inline]
mul_assign(&mut self, rhs: Self)428 fn mul_assign(&mut self, rhs: Self) {
429 *self = self.mul_mat2(&rhs);
430 }
431 }
432
433 impl Mul<Vec2> for Mat2 {
434 type Output = Vec2;
435 #[inline]
mul(self, rhs: Vec2) -> Self::Output436 fn mul(self, rhs: Vec2) -> Self::Output {
437 self.mul_vec2(rhs)
438 }
439 }
440
441 impl Mul<Mat2> for f32 {
442 type Output = Mat2;
443 #[inline]
mul(self, rhs: Mat2) -> Self::Output444 fn mul(self, rhs: Mat2) -> Self::Output {
445 rhs.mul_scalar(self)
446 }
447 }
448
449 impl Mul<f32> for Mat2 {
450 type Output = Self;
451 #[inline]
mul(self, rhs: f32) -> Self::Output452 fn mul(self, rhs: f32) -> Self::Output {
453 self.mul_scalar(rhs)
454 }
455 }
456
457 impl MulAssign<f32> for Mat2 {
458 #[inline]
mul_assign(&mut self, rhs: f32)459 fn mul_assign(&mut self, rhs: f32) {
460 *self = self.mul_scalar(rhs);
461 }
462 }
463
464 impl Div<Mat2> for f32 {
465 type Output = Mat2;
466 #[inline]
div(self, rhs: Mat2) -> Self::Output467 fn div(self, rhs: Mat2) -> Self::Output {
468 rhs.div_scalar(self)
469 }
470 }
471
472 impl Div<f32> for Mat2 {
473 type Output = Self;
474 #[inline]
div(self, rhs: f32) -> Self::Output475 fn div(self, rhs: f32) -> Self::Output {
476 self.div_scalar(rhs)
477 }
478 }
479
480 impl DivAssign<f32> for Mat2 {
481 #[inline]
div_assign(&mut self, rhs: f32)482 fn div_assign(&mut self, rhs: f32) {
483 *self = self.div_scalar(rhs);
484 }
485 }
486
487 impl Sum<Self> for Mat2 {
sum<I>(iter: I) -> Self where I: Iterator<Item = Self>,488 fn sum<I>(iter: I) -> Self
489 where
490 I: Iterator<Item = Self>,
491 {
492 iter.fold(Self::ZERO, Self::add)
493 }
494 }
495
496 impl<'a> Sum<&'a Self> for Mat2 {
sum<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,497 fn sum<I>(iter: I) -> Self
498 where
499 I: Iterator<Item = &'a Self>,
500 {
501 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
502 }
503 }
504
505 impl Product for Mat2 {
product<I>(iter: I) -> Self where I: Iterator<Item = Self>,506 fn product<I>(iter: I) -> Self
507 where
508 I: Iterator<Item = Self>,
509 {
510 iter.fold(Self::IDENTITY, Self::mul)
511 }
512 }
513
514 impl<'a> Product<&'a Self> for Mat2 {
product<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,515 fn product<I>(iter: I) -> Self
516 where
517 I: Iterator<Item = &'a Self>,
518 {
519 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
520 }
521 }
522
523 impl PartialEq for Mat2 {
524 #[inline]
eq(&self, rhs: &Self) -> bool525 fn eq(&self, rhs: &Self) -> bool {
526 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis)
527 }
528 }
529
530 #[cfg(not(target_arch = "spirv"))]
531 impl AsRef<[f32; 4]> for Mat2 {
532 #[inline]
as_ref(&self) -> &[f32; 4]533 fn as_ref(&self) -> &[f32; 4] {
534 unsafe { &*(self as *const Self as *const [f32; 4]) }
535 }
536 }
537
538 #[cfg(not(target_arch = "spirv"))]
539 impl AsMut<[f32; 4]> for Mat2 {
540 #[inline]
as_mut(&mut self) -> &mut [f32; 4]541 fn as_mut(&mut self) -> &mut [f32; 4] {
542 unsafe { &mut *(self as *mut Self as *mut [f32; 4]) }
543 }
544 }
545
546 impl fmt::Debug for Mat2 {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result547 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
548 fmt.debug_struct(stringify!(Mat2))
549 .field("x_axis", &self.x_axis)
550 .field("y_axis", &self.y_axis)
551 .finish()
552 }
553 }
554
555 impl fmt::Display for Mat2 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result556 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
557 if let Some(p) = f.precision() {
558 write!(f, "[{:.*}, {:.*}]", p, self.x_axis, p, self.y_axis)
559 } else {
560 write!(f, "[{}, {}]", self.x_axis, self.y_axis)
561 }
562 }
563 }
564