1 // Generated from mat.rs.tera template. Edit the template, not the generated file.
2
3 use crate::{f64::math, swizzles::*, DMat3, DVec2, Mat2};
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]
dmat2(x_axis: DVec2, y_axis: DVec2) -> DMat211 pub const fn dmat2(x_axis: DVec2, y_axis: DVec2) -> DMat2 {
12 DMat2::from_cols(x_axis, y_axis)
13 }
14
15 /// A 2x2 column major matrix.
16 #[derive(Clone, Copy)]
17 #[cfg_attr(feature = "cuda", repr(align(16)))]
18 #[repr(C)]
19 pub struct DMat2 {
20 pub x_axis: DVec2,
21 pub y_axis: DVec2,
22 }
23
24 impl DMat2 {
25 /// A 2x2 matrix with all elements set to `0.0`.
26 pub const ZERO: Self = Self::from_cols(DVec2::ZERO, DVec2::ZERO);
27
28 /// A 2x2 identity matrix, where all diagonal elements are `1`, and all off-diagonal elements are `0`.
29 pub const IDENTITY: Self = Self::from_cols(DVec2::X, DVec2::Y);
30
31 /// All NAN:s.
32 pub const NAN: Self = Self::from_cols(DVec2::NAN, DVec2::NAN);
33
34 #[allow(clippy::too_many_arguments)]
35 #[inline(always)]
36 #[must_use]
new(m00: f64, m01: f64, m10: f64, m11: f64) -> Self37 const fn new(m00: f64, m01: f64, m10: f64, m11: f64) -> Self {
38 Self {
39 x_axis: DVec2::new(m00, m01),
40 y_axis: DVec2::new(m10, m11),
41 }
42 }
43
44 /// Creates a 2x2 matrix from two column vectors.
45 #[inline(always)]
46 #[must_use]
from_cols(x_axis: DVec2, y_axis: DVec2) -> Self47 pub const fn from_cols(x_axis: DVec2, y_axis: DVec2) -> Self {
48 Self { x_axis, y_axis }
49 }
50
51 /// Creates a 2x2 matrix from a `[f64; 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: &[f64; 4]) -> Self56 pub const fn from_cols_array(m: &[f64; 4]) -> Self {
57 Self::new(m[0], m[1], m[2], m[3])
58 }
59
60 /// Creates a `[f64; 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) -> [f64; 4]64 pub const fn to_cols_array(&self) -> [f64; 4] {
65 [self.x_axis.x, self.x_axis.y, self.y_axis.x, self.y_axis.y]
66 }
67
68 /// Creates a 2x2 matrix from a `[[f64; 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: &[[f64; 2]; 2]) -> Self73 pub const fn from_cols_array_2d(m: &[[f64; 2]; 2]) -> Self {
74 Self::from_cols(DVec2::from_array(m[0]), DVec2::from_array(m[1]))
75 }
76
77 /// Creates a `[[f64; 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) -> [[f64; 2]; 2]81 pub const fn to_cols_array_2d(&self) -> [[f64; 2]; 2] {
82 [self.x_axis.to_array(), self.y_axis.to_array()]
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: DVec2) -> Self89 pub const fn from_diagonal(diagonal: DVec2) -> 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: DVec2, angle: f64) -> Self97 pub fn from_scale_angle(scale: DVec2, angle: f64) -> 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: f64) -> Self105 pub fn from_angle(angle: f64) -> 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: DMat3) -> Self113 pub fn from_mat3(m: DMat3) -> Self {
114 Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
115 }
116
117 /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
118 /// and `j`th row.
119 ///
120 /// # Panics
121 ///
122 /// Panics if `i` or `j` is greater than 2.
123 #[inline]
124 #[must_use]
from_mat3_minor(m: DMat3, i: usize, j: usize) -> Self125 pub fn from_mat3_minor(m: DMat3, i: usize, j: usize) -> Self {
126 match (i, j) {
127 (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
128 (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
129 (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
130 (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
131 (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
132 (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
133 (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
134 (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
135 (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
136 _ => panic!("index out of bounds"),
137 }
138 }
139
140 /// Creates a 2x2 matrix from the first 4 values in `slice`.
141 ///
142 /// # Panics
143 ///
144 /// Panics if `slice` is less than 4 elements long.
145 #[inline]
146 #[must_use]
from_cols_slice(slice: &[f64]) -> Self147 pub const fn from_cols_slice(slice: &[f64]) -> Self {
148 Self::new(slice[0], slice[1], slice[2], slice[3])
149 }
150
151 /// Writes the columns of `self` to the first 4 elements in `slice`.
152 ///
153 /// # Panics
154 ///
155 /// Panics if `slice` is less than 4 elements long.
156 #[inline]
write_cols_to_slice(self, slice: &mut [f64])157 pub fn write_cols_to_slice(self, slice: &mut [f64]) {
158 slice[0] = self.x_axis.x;
159 slice[1] = self.x_axis.y;
160 slice[2] = self.y_axis.x;
161 slice[3] = self.y_axis.y;
162 }
163
164 /// Returns the matrix column for the given `index`.
165 ///
166 /// # Panics
167 ///
168 /// Panics if `index` is greater than 1.
169 #[inline]
170 #[must_use]
col(&self, index: usize) -> DVec2171 pub fn col(&self, index: usize) -> DVec2 {
172 match index {
173 0 => self.x_axis,
174 1 => self.y_axis,
175 _ => panic!("index out of bounds"),
176 }
177 }
178
179 /// Returns a mutable reference to the matrix column for the given `index`.
180 ///
181 /// # Panics
182 ///
183 /// Panics if `index` is greater than 1.
184 #[inline]
col_mut(&mut self, index: usize) -> &mut DVec2185 pub fn col_mut(&mut self, index: usize) -> &mut DVec2 {
186 match index {
187 0 => &mut self.x_axis,
188 1 => &mut self.y_axis,
189 _ => panic!("index out of bounds"),
190 }
191 }
192
193 /// Returns the matrix row for the given `index`.
194 ///
195 /// # Panics
196 ///
197 /// Panics if `index` is greater than 1.
198 #[inline]
199 #[must_use]
row(&self, index: usize) -> DVec2200 pub fn row(&self, index: usize) -> DVec2 {
201 match index {
202 0 => DVec2::new(self.x_axis.x, self.y_axis.x),
203 1 => DVec2::new(self.x_axis.y, self.y_axis.y),
204 _ => panic!("index out of bounds"),
205 }
206 }
207
208 /// Returns `true` if, and only if, all elements are finite.
209 /// If any element is either `NaN`, positive or negative infinity, this will return `false`.
210 #[inline]
211 #[must_use]
is_finite(&self) -> bool212 pub fn is_finite(&self) -> bool {
213 self.x_axis.is_finite() && self.y_axis.is_finite()
214 }
215
216 /// Returns `true` if any elements are `NaN`.
217 #[inline]
218 #[must_use]
is_nan(&self) -> bool219 pub fn is_nan(&self) -> bool {
220 self.x_axis.is_nan() || self.y_axis.is_nan()
221 }
222
223 /// Returns the transpose of `self`.
224 #[inline]
225 #[must_use]
transpose(&self) -> Self226 pub fn transpose(&self) -> Self {
227 Self {
228 x_axis: DVec2::new(self.x_axis.x, self.y_axis.x),
229 y_axis: DVec2::new(self.x_axis.y, self.y_axis.y),
230 }
231 }
232
233 /// Returns the determinant of `self`.
234 #[inline]
235 #[must_use]
determinant(&self) -> f64236 pub fn determinant(&self) -> f64 {
237 self.x_axis.x * self.y_axis.y - self.x_axis.y * self.y_axis.x
238 }
239
240 /// Returns the inverse of `self`.
241 ///
242 /// If the matrix is not invertible the returned matrix will be invalid.
243 ///
244 /// # Panics
245 ///
246 /// Will panic if the determinant of `self` is zero when `glam_assert` is enabled.
247 #[inline]
248 #[must_use]
inverse(&self) -> Self249 pub fn inverse(&self) -> Self {
250 let inv_det = {
251 let det = self.determinant();
252 glam_assert!(det != 0.0);
253 det.recip()
254 };
255 Self::new(
256 self.y_axis.y * inv_det,
257 self.x_axis.y * -inv_det,
258 self.y_axis.x * -inv_det,
259 self.x_axis.x * inv_det,
260 )
261 }
262
263 /// Transforms a 2D vector.
264 #[inline]
265 #[must_use]
mul_vec2(&self, rhs: DVec2) -> DVec2266 pub fn mul_vec2(&self, rhs: DVec2) -> DVec2 {
267 #[allow(clippy::suspicious_operation_groupings)]
268 DVec2::new(
269 (self.x_axis.x * rhs.x) + (self.y_axis.x * rhs.y),
270 (self.x_axis.y * rhs.x) + (self.y_axis.y * rhs.y),
271 )
272 }
273
274 /// Multiplies two 2x2 matrices.
275 #[inline]
276 #[must_use]
mul_mat2(&self, rhs: &Self) -> Self277 pub fn mul_mat2(&self, rhs: &Self) -> Self {
278 Self::from_cols(self.mul(rhs.x_axis), self.mul(rhs.y_axis))
279 }
280
281 /// Adds two 2x2 matrices.
282 #[inline]
283 #[must_use]
add_mat2(&self, rhs: &Self) -> Self284 pub fn add_mat2(&self, rhs: &Self) -> Self {
285 Self::from_cols(self.x_axis.add(rhs.x_axis), self.y_axis.add(rhs.y_axis))
286 }
287
288 /// Subtracts two 2x2 matrices.
289 #[inline]
290 #[must_use]
sub_mat2(&self, rhs: &Self) -> Self291 pub fn sub_mat2(&self, rhs: &Self) -> Self {
292 Self::from_cols(self.x_axis.sub(rhs.x_axis), self.y_axis.sub(rhs.y_axis))
293 }
294
295 /// Multiplies a 2x2 matrix by a scalar.
296 #[inline]
297 #[must_use]
mul_scalar(&self, rhs: f64) -> Self298 pub fn mul_scalar(&self, rhs: f64) -> Self {
299 Self::from_cols(self.x_axis.mul(rhs), self.y_axis.mul(rhs))
300 }
301
302 /// Divides a 2x2 matrix by a scalar.
303 #[inline]
304 #[must_use]
div_scalar(&self, rhs: f64) -> Self305 pub fn div_scalar(&self, rhs: f64) -> Self {
306 let rhs = DVec2::splat(rhs);
307 Self::from_cols(self.x_axis.div(rhs), self.y_axis.div(rhs))
308 }
309
310 /// Returns true if the absolute difference of all elements between `self` and `rhs`
311 /// is less than or equal to `max_abs_diff`.
312 ///
313 /// This can be used to compare if two matrices contain similar elements. It works best
314 /// when comparing with a known value. The `max_abs_diff` that should be used used
315 /// depends on the values being compared against.
316 ///
317 /// For more see
318 /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
319 #[inline]
320 #[must_use]
abs_diff_eq(&self, rhs: Self, max_abs_diff: f64) -> bool321 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f64) -> bool {
322 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
323 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
324 }
325
326 /// Takes the absolute value of each element in `self`
327 #[inline]
328 #[must_use]
abs(&self) -> Self329 pub fn abs(&self) -> Self {
330 Self::from_cols(self.x_axis.abs(), self.y_axis.abs())
331 }
332
333 #[inline]
as_mat2(&self) -> Mat2334 pub fn as_mat2(&self) -> Mat2 {
335 Mat2::from_cols(self.x_axis.as_vec2(), self.y_axis.as_vec2())
336 }
337 }
338
339 impl Default for DMat2 {
340 #[inline]
default() -> Self341 fn default() -> Self {
342 Self::IDENTITY
343 }
344 }
345
346 impl Add<DMat2> for DMat2 {
347 type Output = Self;
348 #[inline]
add(self, rhs: Self) -> Self::Output349 fn add(self, rhs: Self) -> Self::Output {
350 self.add_mat2(&rhs)
351 }
352 }
353
354 impl AddAssign<DMat2> for DMat2 {
355 #[inline]
add_assign(&mut self, rhs: Self)356 fn add_assign(&mut self, rhs: Self) {
357 *self = self.add_mat2(&rhs);
358 }
359 }
360
361 impl Sub<DMat2> for DMat2 {
362 type Output = Self;
363 #[inline]
sub(self, rhs: Self) -> Self::Output364 fn sub(self, rhs: Self) -> Self::Output {
365 self.sub_mat2(&rhs)
366 }
367 }
368
369 impl SubAssign<DMat2> for DMat2 {
370 #[inline]
sub_assign(&mut self, rhs: Self)371 fn sub_assign(&mut self, rhs: Self) {
372 *self = self.sub_mat2(&rhs);
373 }
374 }
375
376 impl Neg for DMat2 {
377 type Output = Self;
378 #[inline]
neg(self) -> Self::Output379 fn neg(self) -> Self::Output {
380 Self::from_cols(self.x_axis.neg(), self.y_axis.neg())
381 }
382 }
383
384 impl Mul<DMat2> for DMat2 {
385 type Output = Self;
386 #[inline]
mul(self, rhs: Self) -> Self::Output387 fn mul(self, rhs: Self) -> Self::Output {
388 self.mul_mat2(&rhs)
389 }
390 }
391
392 impl MulAssign<DMat2> for DMat2 {
393 #[inline]
mul_assign(&mut self, rhs: Self)394 fn mul_assign(&mut self, rhs: Self) {
395 *self = self.mul_mat2(&rhs);
396 }
397 }
398
399 impl Mul<DVec2> for DMat2 {
400 type Output = DVec2;
401 #[inline]
mul(self, rhs: DVec2) -> Self::Output402 fn mul(self, rhs: DVec2) -> Self::Output {
403 self.mul_vec2(rhs)
404 }
405 }
406
407 impl Mul<DMat2> for f64 {
408 type Output = DMat2;
409 #[inline]
mul(self, rhs: DMat2) -> Self::Output410 fn mul(self, rhs: DMat2) -> Self::Output {
411 rhs.mul_scalar(self)
412 }
413 }
414
415 impl Mul<f64> for DMat2 {
416 type Output = Self;
417 #[inline]
mul(self, rhs: f64) -> Self::Output418 fn mul(self, rhs: f64) -> Self::Output {
419 self.mul_scalar(rhs)
420 }
421 }
422
423 impl MulAssign<f64> for DMat2 {
424 #[inline]
mul_assign(&mut self, rhs: f64)425 fn mul_assign(&mut self, rhs: f64) {
426 *self = self.mul_scalar(rhs);
427 }
428 }
429
430 impl Div<DMat2> for f64 {
431 type Output = DMat2;
432 #[inline]
div(self, rhs: DMat2) -> Self::Output433 fn div(self, rhs: DMat2) -> Self::Output {
434 rhs.div_scalar(self)
435 }
436 }
437
438 impl Div<f64> for DMat2 {
439 type Output = Self;
440 #[inline]
div(self, rhs: f64) -> Self::Output441 fn div(self, rhs: f64) -> Self::Output {
442 self.div_scalar(rhs)
443 }
444 }
445
446 impl DivAssign<f64> for DMat2 {
447 #[inline]
div_assign(&mut self, rhs: f64)448 fn div_assign(&mut self, rhs: f64) {
449 *self = self.div_scalar(rhs);
450 }
451 }
452
453 impl Sum<Self> for DMat2 {
sum<I>(iter: I) -> Self where I: Iterator<Item = Self>,454 fn sum<I>(iter: I) -> Self
455 where
456 I: Iterator<Item = Self>,
457 {
458 iter.fold(Self::ZERO, Self::add)
459 }
460 }
461
462 impl<'a> Sum<&'a Self> for DMat2 {
sum<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,463 fn sum<I>(iter: I) -> Self
464 where
465 I: Iterator<Item = &'a Self>,
466 {
467 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
468 }
469 }
470
471 impl Product for DMat2 {
product<I>(iter: I) -> Self where I: Iterator<Item = Self>,472 fn product<I>(iter: I) -> Self
473 where
474 I: Iterator<Item = Self>,
475 {
476 iter.fold(Self::IDENTITY, Self::mul)
477 }
478 }
479
480 impl<'a> Product<&'a Self> for DMat2 {
product<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,481 fn product<I>(iter: I) -> Self
482 where
483 I: Iterator<Item = &'a Self>,
484 {
485 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
486 }
487 }
488
489 impl PartialEq for DMat2 {
490 #[inline]
eq(&self, rhs: &Self) -> bool491 fn eq(&self, rhs: &Self) -> bool {
492 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis)
493 }
494 }
495
496 #[cfg(not(target_arch = "spirv"))]
497 impl AsRef<[f64; 4]> for DMat2 {
498 #[inline]
as_ref(&self) -> &[f64; 4]499 fn as_ref(&self) -> &[f64; 4] {
500 unsafe { &*(self as *const Self as *const [f64; 4]) }
501 }
502 }
503
504 #[cfg(not(target_arch = "spirv"))]
505 impl AsMut<[f64; 4]> for DMat2 {
506 #[inline]
as_mut(&mut self) -> &mut [f64; 4]507 fn as_mut(&mut self) -> &mut [f64; 4] {
508 unsafe { &mut *(self as *mut Self as *mut [f64; 4]) }
509 }
510 }
511
512 impl fmt::Debug for DMat2 {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result513 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
514 fmt.debug_struct(stringify!(DMat2))
515 .field("x_axis", &self.x_axis)
516 .field("y_axis", &self.y_axis)
517 .finish()
518 }
519 }
520
521 impl fmt::Display for DMat2 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result522 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
523 if let Some(p) = f.precision() {
524 write!(f, "[{:.*}, {:.*}]", p, self.x_axis, p, self.y_axis)
525 } else {
526 write!(f, "[{}, {}]", self.x_axis, self.y_axis)
527 }
528 }
529 }
530