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 use core::arch::aarch64::*;
9
10 #[repr(C)]
11 union UnionCast {
12 a: [f32; 4],
13 v: Mat2,
14 }
15
16 /// Creates a 2x2 matrix from two column vectors.
17 #[inline(always)]
18 #[must_use]
mat2(x_axis: Vec2, y_axis: Vec2) -> Mat219 pub const fn mat2(x_axis: Vec2, y_axis: Vec2) -> Mat2 {
20 Mat2::from_cols(x_axis, y_axis)
21 }
22
23 /// A 2x2 column major matrix.
24 ///
25 /// SIMD vector types are used for storage on supported platforms.
26 ///
27 /// This type is 16 byte aligned.
28 #[derive(Clone, Copy)]
29 #[repr(transparent)]
30 pub struct Mat2(pub(crate) float32x4_t);
31
32 impl Mat2 {
33 /// A 2x2 matrix with all elements set to `0.0`.
34 pub const ZERO: Self = Self::from_cols(Vec2::ZERO, Vec2::ZERO);
35
36 /// A 2x2 identity matrix, where all diagonal elements are `1`, and all off-diagonal elements are `0`.
37 pub const IDENTITY: Self = Self::from_cols(Vec2::X, Vec2::Y);
38
39 /// All NAN:s.
40 pub const NAN: Self = Self::from_cols(Vec2::NAN, Vec2::NAN);
41
42 #[allow(clippy::too_many_arguments)]
43 #[inline(always)]
44 #[must_use]
new(m00: f32, m01: f32, m10: f32, m11: f32) -> Self45 const fn new(m00: f32, m01: f32, m10: f32, m11: f32) -> Self {
46 unsafe {
47 UnionCast {
48 a: [m00, m01, m10, m11],
49 }
50 .v
51 }
52 }
53
54 /// Creates a 2x2 matrix from two column vectors.
55 #[inline(always)]
56 #[must_use]
from_cols(x_axis: Vec2, y_axis: Vec2) -> Self57 pub const fn from_cols(x_axis: Vec2, y_axis: Vec2) -> Self {
58 unsafe {
59 UnionCast {
60 a: [x_axis.x, x_axis.y, y_axis.x, y_axis.y],
61 }
62 .v
63 }
64 }
65
66 /// Creates a 2x2 matrix from a `[f32; 4]` array stored in column major order.
67 /// If your data is stored in row major you will need to `transpose` the returned
68 /// matrix.
69 #[inline]
70 #[must_use]
from_cols_array(m: &[f32; 4]) -> Self71 pub const fn from_cols_array(m: &[f32; 4]) -> Self {
72 Self::new(m[0], m[1], m[2], m[3])
73 }
74
75 /// Creates a `[f32; 4]` array storing data in column major order.
76 /// If you require data in row major order `transpose` the matrix first.
77 #[inline]
78 #[must_use]
to_cols_array(&self) -> [f32; 4]79 pub const fn to_cols_array(&self) -> [f32; 4] {
80 unsafe { *(self as *const Self as *const [f32; 4]) }
81 }
82
83 /// Creates a 2x2 matrix from a `[[f32; 2]; 2]` 2D array stored in column major order.
84 /// If your data is in row major order you will need to `transpose` the returned
85 /// matrix.
86 #[inline]
87 #[must_use]
from_cols_array_2d(m: &[[f32; 2]; 2]) -> Self88 pub const fn from_cols_array_2d(m: &[[f32; 2]; 2]) -> Self {
89 Self::from_cols(Vec2::from_array(m[0]), Vec2::from_array(m[1]))
90 }
91
92 /// Creates a `[[f32; 2]; 2]` 2D array storing data in column major order.
93 /// If you require data in row major order `transpose` the matrix first.
94 #[inline]
95 #[must_use]
to_cols_array_2d(&self) -> [[f32; 2]; 2]96 pub const fn to_cols_array_2d(&self) -> [[f32; 2]; 2] {
97 unsafe { *(self as *const Self as *const [[f32; 2]; 2]) }
98 }
99
100 /// Creates a 2x2 matrix with its diagonal set to `diagonal` and all other entries set to 0.
101 #[doc(alias = "scale")]
102 #[inline]
103 #[must_use]
from_diagonal(diagonal: Vec2) -> Self104 pub const fn from_diagonal(diagonal: Vec2) -> Self {
105 Self::new(diagonal.x, 0.0, 0.0, diagonal.y)
106 }
107
108 /// Creates a 2x2 matrix containing the combining non-uniform `scale` and rotation of
109 /// `angle` (in radians).
110 #[inline]
111 #[must_use]
from_scale_angle(scale: Vec2, angle: f32) -> Self112 pub fn from_scale_angle(scale: Vec2, angle: f32) -> Self {
113 let (sin, cos) = math::sin_cos(angle);
114 Self::new(cos * scale.x, sin * scale.x, -sin * scale.y, cos * scale.y)
115 }
116
117 /// Creates a 2x2 matrix containing a rotation of `angle` (in radians).
118 #[inline]
119 #[must_use]
from_angle(angle: f32) -> Self120 pub fn from_angle(angle: f32) -> Self {
121 let (sin, cos) = math::sin_cos(angle);
122 Self::new(cos, sin, -sin, cos)
123 }
124
125 /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column.
126 #[inline]
127 #[must_use]
from_mat3(m: Mat3) -> Self128 pub fn from_mat3(m: Mat3) -> Self {
129 Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
130 }
131
132 /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
133 /// and `j`th row.
134 ///
135 /// # Panics
136 ///
137 /// Panics if `i` or `j` is greater than 2.
138 #[inline]
139 #[must_use]
from_mat3_minor(m: Mat3, i: usize, j: usize) -> Self140 pub fn from_mat3_minor(m: Mat3, i: usize, j: usize) -> Self {
141 match (i, j) {
142 (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
143 (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
144 (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
145 (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
146 (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
147 (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
148 (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
149 (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
150 (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
151 _ => panic!("index out of bounds"),
152 }
153 }
154
155 /// Creates a 2x2 matrix from a 3x3 matrix, discarding the 2nd row and column.
156 #[inline]
157 #[must_use]
from_mat3a(m: Mat3A) -> Self158 pub fn from_mat3a(m: Mat3A) -> Self {
159 Self::from_cols(m.x_axis.xy(), m.y_axis.xy())
160 }
161
162 /// Creates a 2x2 matrix from the minor of the given 3x3 matrix, discarding the `i`th column
163 /// and `j`th row.
164 ///
165 /// # Panics
166 ///
167 /// Panics if `i` or `j` is greater than 2.
168 #[inline]
169 #[must_use]
from_mat3a_minor(m: Mat3A, i: usize, j: usize) -> Self170 pub fn from_mat3a_minor(m: Mat3A, i: usize, j: usize) -> Self {
171 match (i, j) {
172 (0, 0) => Self::from_cols(m.y_axis.yz(), m.z_axis.yz()),
173 (0, 1) => Self::from_cols(m.y_axis.xz(), m.z_axis.xz()),
174 (0, 2) => Self::from_cols(m.y_axis.xy(), m.z_axis.xy()),
175 (1, 0) => Self::from_cols(m.x_axis.yz(), m.z_axis.yz()),
176 (1, 1) => Self::from_cols(m.x_axis.xz(), m.z_axis.xz()),
177 (1, 2) => Self::from_cols(m.x_axis.xy(), m.z_axis.xy()),
178 (2, 0) => Self::from_cols(m.x_axis.yz(), m.y_axis.yz()),
179 (2, 1) => Self::from_cols(m.x_axis.xz(), m.y_axis.xz()),
180 (2, 2) => Self::from_cols(m.x_axis.xy(), m.y_axis.xy()),
181 _ => panic!("index out of bounds"),
182 }
183 }
184
185 /// Creates a 2x2 matrix from the first 4 values in `slice`.
186 ///
187 /// # Panics
188 ///
189 /// Panics if `slice` is less than 4 elements long.
190 #[inline]
191 #[must_use]
from_cols_slice(slice: &[f32]) -> Self192 pub const fn from_cols_slice(slice: &[f32]) -> Self {
193 Self::new(slice[0], slice[1], slice[2], slice[3])
194 }
195
196 /// Writes the columns of `self` to the first 4 elements in `slice`.
197 ///
198 /// # Panics
199 ///
200 /// Panics if `slice` is less than 4 elements long.
201 #[inline]
write_cols_to_slice(self, slice: &mut [f32])202 pub fn write_cols_to_slice(self, slice: &mut [f32]) {
203 slice[0] = self.x_axis.x;
204 slice[1] = self.x_axis.y;
205 slice[2] = self.y_axis.x;
206 slice[3] = self.y_axis.y;
207 }
208
209 /// Returns the matrix column for the given `index`.
210 ///
211 /// # Panics
212 ///
213 /// Panics if `index` is greater than 1.
214 #[inline]
215 #[must_use]
col(&self, index: usize) -> Vec2216 pub fn col(&self, index: usize) -> Vec2 {
217 match index {
218 0 => self.x_axis,
219 1 => self.y_axis,
220 _ => panic!("index out of bounds"),
221 }
222 }
223
224 /// Returns a mutable reference to the matrix column for the given `index`.
225 ///
226 /// # Panics
227 ///
228 /// Panics if `index` is greater than 1.
229 #[inline]
col_mut(&mut self, index: usize) -> &mut Vec2230 pub fn col_mut(&mut self, index: usize) -> &mut Vec2 {
231 match index {
232 0 => &mut self.x_axis,
233 1 => &mut self.y_axis,
234 _ => panic!("index out of bounds"),
235 }
236 }
237
238 /// Returns the matrix row for the given `index`.
239 ///
240 /// # Panics
241 ///
242 /// Panics if `index` is greater than 1.
243 #[inline]
244 #[must_use]
row(&self, index: usize) -> Vec2245 pub fn row(&self, index: usize) -> Vec2 {
246 match index {
247 0 => Vec2::new(self.x_axis.x, self.y_axis.x),
248 1 => Vec2::new(self.x_axis.y, self.y_axis.y),
249 _ => panic!("index out of bounds"),
250 }
251 }
252
253 /// Returns `true` if, and only if, all elements are finite.
254 /// If any element is either `NaN`, positive or negative infinity, this will return `false`.
255 #[inline]
256 #[must_use]
is_finite(&self) -> bool257 pub fn is_finite(&self) -> bool {
258 self.x_axis.is_finite() && self.y_axis.is_finite()
259 }
260
261 /// Returns `true` if any elements are `NaN`.
262 #[inline]
263 #[must_use]
is_nan(&self) -> bool264 pub fn is_nan(&self) -> bool {
265 self.x_axis.is_nan() || self.y_axis.is_nan()
266 }
267
268 /// Returns the transpose of `self`.
269 #[inline]
270 #[must_use]
transpose(&self) -> Self271 pub fn transpose(&self) -> Self {
272 Self(unsafe {
273 vsetq_lane_f32(
274 vgetq_lane_f32(self.0, 2),
275 vsetq_lane_f32(vgetq_lane_f32(self.0, 1), self.0, 2),
276 1,
277 )
278 })
279 }
280
281 /// Returns the determinant of `self`.
282 #[inline]
283 #[must_use]
determinant(&self) -> f32284 pub fn determinant(&self) -> f32 {
285 unsafe {
286 let abcd = self.0;
287 let badc = vrev64q_f32(abcd);
288 let dcba = vextq_f32(badc, badc, 2);
289 let prod = vmulq_f32(abcd, dcba);
290 let det = vsubq_f32(prod, vdupq_laneq_f32(prod, 1));
291 vgetq_lane_f32(det, 0)
292 }
293 }
294
295 /// Returns the inverse of `self`.
296 ///
297 /// If the matrix is not invertible the returned matrix will be invalid.
298 ///
299 /// # Panics
300 ///
301 /// Will panic if the determinant of `self` is zero when `glam_assert` is enabled.
302 #[inline]
303 #[must_use]
inverse(&self) -> Self304 pub fn inverse(&self) -> Self {
305 unsafe {
306 const SIGN: float32x4_t = crate::neon::f32x4_from_array([1.0, -1.0, -1.0, 1.0]);
307 let abcd = self.0;
308 let badc = vrev64q_f32(abcd);
309 let dcba = vextq_f32(badc, badc, 2);
310 let prod = vmulq_f32(abcd, dcba);
311 let sub = vsubq_f32(prod, vdupq_laneq_f32(prod, 1));
312 let det = vdupq_laneq_f32(sub, 0);
313 let tmp = vdivq_f32(SIGN, det);
314 glam_assert!(Mat2(tmp).is_finite());
315 //let dbca = simd_swizzle!(abcd, [3, 1, 2, 0]);
316 let dbca = vsetq_lane_f32(
317 vgetq_lane_f32(abcd, 0),
318 vsetq_lane_f32(vgetq_lane_f32(abcd, 3), abcd, 0),
319 3,
320 );
321 Self(vmulq_f32(dbca, tmp))
322 }
323 }
324
325 /// Transforms a 2D vector.
326 #[inline]
327 #[must_use]
mul_vec2(&self, rhs: Vec2) -> Vec2328 pub fn mul_vec2(&self, rhs: Vec2) -> Vec2 {
329 unsafe {
330 let abcd = self.0;
331 let xxyy = vld1q_f32([rhs.x, rhs.x, rhs.y, rhs.y].as_ptr());
332 let axbxcydy = vmulq_f32(abcd, xxyy);
333 // let cydyaxbx = simd_swizzle!(axbxcydy, [2, 3, 0, 1]);
334 let cydyaxbx = vextq_f32(axbxcydy, axbxcydy, 2);
335 let result = vaddq_f32(axbxcydy, cydyaxbx);
336 *(&result as *const float32x4_t as *const Vec2)
337 }
338 }
339
340 /// Multiplies two 2x2 matrices.
341 #[inline]
342 #[must_use]
mul_mat2(&self, rhs: &Self) -> Self343 pub fn mul_mat2(&self, rhs: &Self) -> Self {
344 unsafe {
345 let abcd = self.0;
346 let xxyy0 = vzip1q_f32(rhs.0, rhs.0);
347 let xxyy1 = vzip2q_f32(rhs.0, rhs.0);
348 let axbxcydy0 = vmulq_f32(abcd, xxyy0);
349 let axbxcydy1 = vmulq_f32(abcd, xxyy1);
350 let cydyaxbx0 = vextq_f32(axbxcydy0, axbxcydy0, 2);
351 let cydyaxbx1 = vextq_f32(axbxcydy1, axbxcydy1, 2);
352 let result0 = vaddq_f32(axbxcydy0, cydyaxbx0);
353 let result1 = vaddq_f32(axbxcydy1, cydyaxbx1);
354 Self(vreinterpretq_f32_u64(vsetq_lane_u64(
355 vgetq_lane_u64(vreinterpretq_u64_f32(result1), 0),
356 vreinterpretq_u64_f32(result0),
357 1,
358 )))
359 }
360 }
361
362 /// Adds two 2x2 matrices.
363 #[inline]
364 #[must_use]
add_mat2(&self, rhs: &Self) -> Self365 pub fn add_mat2(&self, rhs: &Self) -> Self {
366 Self(unsafe { vaddq_f32(self.0, rhs.0) })
367 }
368
369 /// Subtracts two 2x2 matrices.
370 #[inline]
371 #[must_use]
sub_mat2(&self, rhs: &Self) -> Self372 pub fn sub_mat2(&self, rhs: &Self) -> Self {
373 Self(unsafe { vsubq_f32(self.0, rhs.0) })
374 }
375
376 /// Multiplies a 2x2 matrix by a scalar.
377 #[inline]
378 #[must_use]
mul_scalar(&self, rhs: f32) -> Self379 pub fn mul_scalar(&self, rhs: f32) -> Self {
380 Self(unsafe { vmulq_f32(self.0, vld1q_dup_f32(&rhs)) })
381 }
382
383 /// Divides a 2x2 matrix by a scalar.
384 #[inline]
385 #[must_use]
div_scalar(&self, rhs: f32) -> Self386 pub fn div_scalar(&self, rhs: f32) -> Self {
387 Self(unsafe { vdivq_f32(self.0, vld1q_dup_f32(&rhs)) })
388 }
389
390 /// Returns true if the absolute difference of all elements between `self` and `rhs`
391 /// is less than or equal to `max_abs_diff`.
392 ///
393 /// This can be used to compare if two matrices contain similar elements. It works best
394 /// when comparing with a known value. The `max_abs_diff` that should be used used
395 /// depends on the values being compared against.
396 ///
397 /// For more see
398 /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
399 #[inline]
400 #[must_use]
abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool401 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
402 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
403 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
404 }
405
406 /// Takes the absolute value of each element in `self`
407 #[inline]
408 #[must_use]
abs(&self) -> Self409 pub fn abs(&self) -> Self {
410 Self::from_cols(self.x_axis.abs(), self.y_axis.abs())
411 }
412
413 #[inline]
as_dmat2(&self) -> DMat2414 pub fn as_dmat2(&self) -> DMat2 {
415 DMat2::from_cols(self.x_axis.as_dvec2(), self.y_axis.as_dvec2())
416 }
417 }
418
419 impl Default for Mat2 {
420 #[inline]
default() -> Self421 fn default() -> Self {
422 Self::IDENTITY
423 }
424 }
425
426 impl Add<Mat2> for Mat2 {
427 type Output = Self;
428 #[inline]
add(self, rhs: Self) -> Self::Output429 fn add(self, rhs: Self) -> Self::Output {
430 self.add_mat2(&rhs)
431 }
432 }
433
434 impl AddAssign<Mat2> for Mat2 {
435 #[inline]
add_assign(&mut self, rhs: Self)436 fn add_assign(&mut self, rhs: Self) {
437 *self = self.add_mat2(&rhs);
438 }
439 }
440
441 impl Sub<Mat2> for Mat2 {
442 type Output = Self;
443 #[inline]
sub(self, rhs: Self) -> Self::Output444 fn sub(self, rhs: Self) -> Self::Output {
445 self.sub_mat2(&rhs)
446 }
447 }
448
449 impl SubAssign<Mat2> for Mat2 {
450 #[inline]
sub_assign(&mut self, rhs: Self)451 fn sub_assign(&mut self, rhs: Self) {
452 *self = self.sub_mat2(&rhs);
453 }
454 }
455
456 impl Neg for Mat2 {
457 type Output = Self;
458 #[inline]
neg(self) -> Self::Output459 fn neg(self) -> Self::Output {
460 Self(unsafe { vnegq_f32(self.0) })
461 }
462 }
463
464 impl Mul<Mat2> for Mat2 {
465 type Output = Self;
466 #[inline]
mul(self, rhs: Self) -> Self::Output467 fn mul(self, rhs: Self) -> Self::Output {
468 self.mul_mat2(&rhs)
469 }
470 }
471
472 impl MulAssign<Mat2> for Mat2 {
473 #[inline]
mul_assign(&mut self, rhs: Self)474 fn mul_assign(&mut self, rhs: Self) {
475 *self = self.mul_mat2(&rhs);
476 }
477 }
478
479 impl Mul<Vec2> for Mat2 {
480 type Output = Vec2;
481 #[inline]
mul(self, rhs: Vec2) -> Self::Output482 fn mul(self, rhs: Vec2) -> Self::Output {
483 self.mul_vec2(rhs)
484 }
485 }
486
487 impl Mul<Mat2> for f32 {
488 type Output = Mat2;
489 #[inline]
mul(self, rhs: Mat2) -> Self::Output490 fn mul(self, rhs: Mat2) -> Self::Output {
491 rhs.mul_scalar(self)
492 }
493 }
494
495 impl Mul<f32> for Mat2 {
496 type Output = Self;
497 #[inline]
mul(self, rhs: f32) -> Self::Output498 fn mul(self, rhs: f32) -> Self::Output {
499 self.mul_scalar(rhs)
500 }
501 }
502
503 impl MulAssign<f32> for Mat2 {
504 #[inline]
mul_assign(&mut self, rhs: f32)505 fn mul_assign(&mut self, rhs: f32) {
506 *self = self.mul_scalar(rhs);
507 }
508 }
509
510 impl Div<Mat2> for f32 {
511 type Output = Mat2;
512 #[inline]
div(self, rhs: Mat2) -> Self::Output513 fn div(self, rhs: Mat2) -> Self::Output {
514 rhs.div_scalar(self)
515 }
516 }
517
518 impl Div<f32> for Mat2 {
519 type Output = Self;
520 #[inline]
div(self, rhs: f32) -> Self::Output521 fn div(self, rhs: f32) -> Self::Output {
522 self.div_scalar(rhs)
523 }
524 }
525
526 impl DivAssign<f32> for Mat2 {
527 #[inline]
div_assign(&mut self, rhs: f32)528 fn div_assign(&mut self, rhs: f32) {
529 *self = self.div_scalar(rhs);
530 }
531 }
532
533 impl Sum<Self> for Mat2 {
sum<I>(iter: I) -> Self where I: Iterator<Item = Self>,534 fn sum<I>(iter: I) -> Self
535 where
536 I: Iterator<Item = Self>,
537 {
538 iter.fold(Self::ZERO, Self::add)
539 }
540 }
541
542 impl<'a> Sum<&'a Self> for Mat2 {
sum<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,543 fn sum<I>(iter: I) -> Self
544 where
545 I: Iterator<Item = &'a Self>,
546 {
547 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
548 }
549 }
550
551 impl Product for Mat2 {
product<I>(iter: I) -> Self where I: Iterator<Item = Self>,552 fn product<I>(iter: I) -> Self
553 where
554 I: Iterator<Item = Self>,
555 {
556 iter.fold(Self::IDENTITY, Self::mul)
557 }
558 }
559
560 impl<'a> Product<&'a Self> for Mat2 {
product<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,561 fn product<I>(iter: I) -> Self
562 where
563 I: Iterator<Item = &'a Self>,
564 {
565 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
566 }
567 }
568
569 impl PartialEq for Mat2 {
570 #[inline]
eq(&self, rhs: &Self) -> bool571 fn eq(&self, rhs: &Self) -> bool {
572 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis)
573 }
574 }
575
576 #[cfg(not(target_arch = "spirv"))]
577 impl AsRef<[f32; 4]> for Mat2 {
578 #[inline]
as_ref(&self) -> &[f32; 4]579 fn as_ref(&self) -> &[f32; 4] {
580 unsafe { &*(self as *const Self as *const [f32; 4]) }
581 }
582 }
583
584 #[cfg(not(target_arch = "spirv"))]
585 impl AsMut<[f32; 4]> for Mat2 {
586 #[inline]
as_mut(&mut self) -> &mut [f32; 4]587 fn as_mut(&mut self) -> &mut [f32; 4] {
588 unsafe { &mut *(self as *mut Self as *mut [f32; 4]) }
589 }
590 }
591
592 impl core::ops::Deref for Mat2 {
593 type Target = crate::deref::Cols2<Vec2>;
594 #[inline]
deref(&self) -> &Self::Target595 fn deref(&self) -> &Self::Target {
596 unsafe { &*(self as *const Self as *const Self::Target) }
597 }
598 }
599
600 impl core::ops::DerefMut for Mat2 {
601 #[inline]
deref_mut(&mut self) -> &mut Self::Target602 fn deref_mut(&mut self) -> &mut Self::Target {
603 unsafe { &mut *(self as *mut Self as *mut Self::Target) }
604 }
605 }
606
607 impl fmt::Debug for Mat2 {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result608 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
609 fmt.debug_struct(stringify!(Mat2))
610 .field("x_axis", &self.x_axis)
611 .field("y_axis", &self.y_axis)
612 .finish()
613 }
614 }
615
616 impl fmt::Display for Mat2 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result617 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
618 if let Some(p) = f.precision() {
619 write!(f, "[{:.*}, {:.*}]", p, self.x_axis, p, self.y_axis)
620 } else {
621 write!(f, "[{}, {}]", self.x_axis, self.y_axis)
622 }
623 }
624 }
625