1 // Generated from mat.rs.tera template. Edit the template, not the generated file.
2
3 use crate::{f32::math, swizzles::*, DMat3, EulerRot, Mat2, Mat3, Mat4, Quat, Vec2, Vec3, Vec3A};
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 #[cfg(target_arch = "x86")]
10 use core::arch::x86::*;
11 #[cfg(target_arch = "x86_64")]
12 use core::arch::x86_64::*;
13
14 /// Creates a 3x3 matrix from three column vectors.
15 #[inline(always)]
16 #[must_use]
mat3a(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Mat3A17 pub const fn mat3a(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Mat3A {
18 Mat3A::from_cols(x_axis, y_axis, z_axis)
19 }
20
21 /// A 3x3 column major matrix.
22 ///
23 /// This 3x3 matrix type features convenience methods for creating and using linear and
24 /// affine transformations. If you are primarily dealing with 2D affine transformations the
25 /// [`Affine2`](crate::Affine2) type is much faster and more space efficient than
26 /// using a 3x3 matrix.
27 ///
28 /// Linear transformations including 3D rotation and scale can be created using methods
29 /// such as [`Self::from_diagonal()`], [`Self::from_quat()`], [`Self::from_axis_angle()`],
30 /// [`Self::from_rotation_x()`], [`Self::from_rotation_y()`], or
31 /// [`Self::from_rotation_z()`].
32 ///
33 /// The resulting matrices can be use to transform 3D vectors using regular vector
34 /// multiplication.
35 ///
36 /// Affine transformations including 2D translation, rotation and scale can be created
37 /// using methods such as [`Self::from_translation()`], [`Self::from_angle()`],
38 /// [`Self::from_scale()`] and [`Self::from_scale_angle_translation()`].
39 ///
40 /// The [`Self::transform_point2()`] and [`Self::transform_vector2()`] convenience methods
41 /// are provided for performing affine transforms on 2D vectors and points. These multiply
42 /// 2D inputs as 3D vectors with an implicit `z` value of `1` for points and `0` for
43 /// vectors respectively. These methods assume that `Self` contains a valid affine
44 /// transform.
45 #[derive(Clone, Copy)]
46 #[repr(C)]
47 pub struct Mat3A {
48 pub x_axis: Vec3A,
49 pub y_axis: Vec3A,
50 pub z_axis: Vec3A,
51 }
52
53 impl Mat3A {
54 /// A 3x3 matrix with all elements set to `0.0`.
55 pub const ZERO: Self = Self::from_cols(Vec3A::ZERO, Vec3A::ZERO, Vec3A::ZERO);
56
57 /// A 3x3 identity matrix, where all diagonal elements are `1`, and all off-diagonal elements are `0`.
58 pub const IDENTITY: Self = Self::from_cols(Vec3A::X, Vec3A::Y, Vec3A::Z);
59
60 /// All NAN:s.
61 pub const NAN: Self = Self::from_cols(Vec3A::NAN, Vec3A::NAN, Vec3A::NAN);
62
63 #[allow(clippy::too_many_arguments)]
64 #[inline(always)]
65 #[must_use]
new( m00: f32, m01: f32, m02: f32, m10: f32, m11: f32, m12: f32, m20: f32, m21: f32, m22: f32, ) -> Self66 const fn new(
67 m00: f32,
68 m01: f32,
69 m02: f32,
70 m10: f32,
71 m11: f32,
72 m12: f32,
73 m20: f32,
74 m21: f32,
75 m22: f32,
76 ) -> Self {
77 Self {
78 x_axis: Vec3A::new(m00, m01, m02),
79 y_axis: Vec3A::new(m10, m11, m12),
80 z_axis: Vec3A::new(m20, m21, m22),
81 }
82 }
83
84 /// Creates a 3x3 matrix from three column vectors.
85 #[inline(always)]
86 #[must_use]
from_cols(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Self87 pub const fn from_cols(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Self {
88 Self {
89 x_axis,
90 y_axis,
91 z_axis,
92 }
93 }
94
95 /// Creates a 3x3 matrix from a `[f32; 9]` array stored in column major order.
96 /// If your data is stored in row major you will need to `transpose` the returned
97 /// matrix.
98 #[inline]
99 #[must_use]
from_cols_array(m: &[f32; 9]) -> Self100 pub const fn from_cols_array(m: &[f32; 9]) -> Self {
101 Self::new(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8])
102 }
103
104 /// Creates a `[f32; 9]` array storing data in column major order.
105 /// If you require data in row major order `transpose` the matrix first.
106 #[inline]
107 #[must_use]
to_cols_array(&self) -> [f32; 9]108 pub const fn to_cols_array(&self) -> [f32; 9] {
109 let [x_axis_x, x_axis_y, x_axis_z] = self.x_axis.to_array();
110 let [y_axis_x, y_axis_y, y_axis_z] = self.y_axis.to_array();
111 let [z_axis_x, z_axis_y, z_axis_z] = self.z_axis.to_array();
112
113 [
114 x_axis_x, x_axis_y, x_axis_z, y_axis_x, y_axis_y, y_axis_z, z_axis_x, z_axis_y,
115 z_axis_z,
116 ]
117 }
118
119 /// Creates a 3x3 matrix from a `[[f32; 3]; 3]` 3D array stored in column major order.
120 /// If your data is in row major order you will need to `transpose` the returned
121 /// matrix.
122 #[inline]
123 #[must_use]
from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self124 pub const fn from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self {
125 Self::from_cols(
126 Vec3A::from_array(m[0]),
127 Vec3A::from_array(m[1]),
128 Vec3A::from_array(m[2]),
129 )
130 }
131
132 /// Creates a `[[f32; 3]; 3]` 3D array storing data in column major order.
133 /// If you require data in row major order `transpose` the matrix first.
134 #[inline]
135 #[must_use]
to_cols_array_2d(&self) -> [[f32; 3]; 3]136 pub const fn to_cols_array_2d(&self) -> [[f32; 3]; 3] {
137 [
138 self.x_axis.to_array(),
139 self.y_axis.to_array(),
140 self.z_axis.to_array(),
141 ]
142 }
143
144 /// Creates a 3x3 matrix with its diagonal set to `diagonal` and all other entries set to 0.
145 #[doc(alias = "scale")]
146 #[inline]
147 #[must_use]
from_diagonal(diagonal: Vec3) -> Self148 pub const fn from_diagonal(diagonal: Vec3) -> Self {
149 Self::new(
150 diagonal.x, 0.0, 0.0, 0.0, diagonal.y, 0.0, 0.0, 0.0, diagonal.z,
151 )
152 }
153
154 /// Creates a 3x3 matrix from a 4x4 matrix, discarding the 4th row and column.
155 #[inline]
156 #[must_use]
from_mat4(m: Mat4) -> Self157 pub fn from_mat4(m: Mat4) -> Self {
158 Self::from_cols(m.x_axis.into(), m.y_axis.into(), m.z_axis.into())
159 }
160
161 /// Creates a 3D rotation matrix from the given quaternion.
162 ///
163 /// # Panics
164 ///
165 /// Will panic if `rotation` is not normalized when `glam_assert` is enabled.
166 #[inline]
167 #[must_use]
from_quat(rotation: Quat) -> Self168 pub fn from_quat(rotation: Quat) -> Self {
169 glam_assert!(rotation.is_normalized());
170
171 let x2 = rotation.x + rotation.x;
172 let y2 = rotation.y + rotation.y;
173 let z2 = rotation.z + rotation.z;
174 let xx = rotation.x * x2;
175 let xy = rotation.x * y2;
176 let xz = rotation.x * z2;
177 let yy = rotation.y * y2;
178 let yz = rotation.y * z2;
179 let zz = rotation.z * z2;
180 let wx = rotation.w * x2;
181 let wy = rotation.w * y2;
182 let wz = rotation.w * z2;
183
184 Self::from_cols(
185 Vec3A::new(1.0 - (yy + zz), xy + wz, xz - wy),
186 Vec3A::new(xy - wz, 1.0 - (xx + zz), yz + wx),
187 Vec3A::new(xz + wy, yz - wx, 1.0 - (xx + yy)),
188 )
189 }
190
191 /// Creates a 3D rotation matrix from a normalized rotation `axis` and `angle` (in
192 /// radians).
193 ///
194 /// # Panics
195 ///
196 /// Will panic if `axis` is not normalized when `glam_assert` is enabled.
197 #[inline]
198 #[must_use]
from_axis_angle(axis: Vec3, angle: f32) -> Self199 pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
200 glam_assert!(axis.is_normalized());
201
202 let (sin, cos) = math::sin_cos(angle);
203 let (xsin, ysin, zsin) = axis.mul(sin).into();
204 let (x, y, z) = axis.into();
205 let (x2, y2, z2) = axis.mul(axis).into();
206 let omc = 1.0 - cos;
207 let xyomc = x * y * omc;
208 let xzomc = x * z * omc;
209 let yzomc = y * z * omc;
210 Self::from_cols(
211 Vec3A::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
212 Vec3A::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
213 Vec3A::new(xzomc + ysin, yzomc - xsin, z2 * omc + cos),
214 )
215 }
216
217 /// Creates a 3D rotation matrix from the given euler rotation sequence and the angles (in
218 /// radians).
219 #[inline]
220 #[must_use]
from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self221 pub fn from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self {
222 let quat = Quat::from_euler(order, a, b, c);
223 Self::from_quat(quat)
224 }
225
226 /// Creates a 3D rotation matrix from `angle` (in radians) around the x axis.
227 #[inline]
228 #[must_use]
from_rotation_x(angle: f32) -> Self229 pub fn from_rotation_x(angle: f32) -> Self {
230 let (sina, cosa) = math::sin_cos(angle);
231 Self::from_cols(
232 Vec3A::X,
233 Vec3A::new(0.0, cosa, sina),
234 Vec3A::new(0.0, -sina, cosa),
235 )
236 }
237
238 /// Creates a 3D rotation matrix from `angle` (in radians) around the y axis.
239 #[inline]
240 #[must_use]
from_rotation_y(angle: f32) -> Self241 pub fn from_rotation_y(angle: f32) -> Self {
242 let (sina, cosa) = math::sin_cos(angle);
243 Self::from_cols(
244 Vec3A::new(cosa, 0.0, -sina),
245 Vec3A::Y,
246 Vec3A::new(sina, 0.0, cosa),
247 )
248 }
249
250 /// Creates a 3D rotation matrix from `angle` (in radians) around the z axis.
251 #[inline]
252 #[must_use]
from_rotation_z(angle: f32) -> Self253 pub fn from_rotation_z(angle: f32) -> Self {
254 let (sina, cosa) = math::sin_cos(angle);
255 Self::from_cols(
256 Vec3A::new(cosa, sina, 0.0),
257 Vec3A::new(-sina, cosa, 0.0),
258 Vec3A::Z,
259 )
260 }
261
262 /// Creates an affine transformation matrix from the given 2D `translation`.
263 ///
264 /// The resulting matrix can be used to transform 2D points and vectors. See
265 /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
266 #[inline]
267 #[must_use]
from_translation(translation: Vec2) -> Self268 pub fn from_translation(translation: Vec2) -> Self {
269 Self::from_cols(
270 Vec3A::X,
271 Vec3A::Y,
272 Vec3A::new(translation.x, translation.y, 1.0),
273 )
274 }
275
276 /// Creates an affine transformation matrix from the given 2D rotation `angle` (in
277 /// radians).
278 ///
279 /// The resulting matrix can be used to transform 2D points and vectors. See
280 /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
281 #[inline]
282 #[must_use]
from_angle(angle: f32) -> Self283 pub fn from_angle(angle: f32) -> Self {
284 let (sin, cos) = math::sin_cos(angle);
285 Self::from_cols(
286 Vec3A::new(cos, sin, 0.0),
287 Vec3A::new(-sin, cos, 0.0),
288 Vec3A::Z,
289 )
290 }
291
292 /// Creates an affine transformation matrix from the given 2D `scale`, rotation `angle` (in
293 /// radians) and `translation`.
294 ///
295 /// The resulting matrix can be used to transform 2D points and vectors. See
296 /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
297 #[inline]
298 #[must_use]
from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self299 pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
300 let (sin, cos) = math::sin_cos(angle);
301 Self::from_cols(
302 Vec3A::new(cos * scale.x, sin * scale.x, 0.0),
303 Vec3A::new(-sin * scale.y, cos * scale.y, 0.0),
304 Vec3A::new(translation.x, translation.y, 1.0),
305 )
306 }
307
308 /// Creates an affine transformation matrix from the given non-uniform 2D `scale`.
309 ///
310 /// The resulting matrix can be used to transform 2D points and vectors. See
311 /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
312 ///
313 /// # Panics
314 ///
315 /// Will panic if all elements of `scale` are zero when `glam_assert` is enabled.
316 #[inline]
317 #[must_use]
from_scale(scale: Vec2) -> Self318 pub fn from_scale(scale: Vec2) -> Self {
319 // Do not panic as long as any component is non-zero
320 glam_assert!(scale.cmpne(Vec2::ZERO).any());
321
322 Self::from_cols(
323 Vec3A::new(scale.x, 0.0, 0.0),
324 Vec3A::new(0.0, scale.y, 0.0),
325 Vec3A::Z,
326 )
327 }
328
329 /// Creates an affine transformation matrix from the given 2x2 matrix.
330 ///
331 /// The resulting matrix can be used to transform 2D points and vectors. See
332 /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
333 #[inline]
from_mat2(m: Mat2) -> Self334 pub fn from_mat2(m: Mat2) -> Self {
335 Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), Vec3A::Z)
336 }
337
338 /// Creates a 3x3 matrix from the first 9 values in `slice`.
339 ///
340 /// # Panics
341 ///
342 /// Panics if `slice` is less than 9 elements long.
343 #[inline]
344 #[must_use]
from_cols_slice(slice: &[f32]) -> Self345 pub const fn from_cols_slice(slice: &[f32]) -> Self {
346 Self::new(
347 slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
348 slice[8],
349 )
350 }
351
352 /// Writes the columns of `self` to the first 9 elements in `slice`.
353 ///
354 /// # Panics
355 ///
356 /// Panics if `slice` is less than 9 elements long.
357 #[inline]
write_cols_to_slice(self, slice: &mut [f32])358 pub fn write_cols_to_slice(self, slice: &mut [f32]) {
359 slice[0] = self.x_axis.x;
360 slice[1] = self.x_axis.y;
361 slice[2] = self.x_axis.z;
362 slice[3] = self.y_axis.x;
363 slice[4] = self.y_axis.y;
364 slice[5] = self.y_axis.z;
365 slice[6] = self.z_axis.x;
366 slice[7] = self.z_axis.y;
367 slice[8] = self.z_axis.z;
368 }
369
370 /// Returns the matrix column for the given `index`.
371 ///
372 /// # Panics
373 ///
374 /// Panics if `index` is greater than 2.
375 #[inline]
376 #[must_use]
col(&self, index: usize) -> Vec3A377 pub fn col(&self, index: usize) -> Vec3A {
378 match index {
379 0 => self.x_axis,
380 1 => self.y_axis,
381 2 => self.z_axis,
382 _ => panic!("index out of bounds"),
383 }
384 }
385
386 /// Returns a mutable reference to the matrix column for the given `index`.
387 ///
388 /// # Panics
389 ///
390 /// Panics if `index` is greater than 2.
391 #[inline]
col_mut(&mut self, index: usize) -> &mut Vec3A392 pub fn col_mut(&mut self, index: usize) -> &mut Vec3A {
393 match index {
394 0 => &mut self.x_axis,
395 1 => &mut self.y_axis,
396 2 => &mut self.z_axis,
397 _ => panic!("index out of bounds"),
398 }
399 }
400
401 /// Returns the matrix row for the given `index`.
402 ///
403 /// # Panics
404 ///
405 /// Panics if `index` is greater than 2.
406 #[inline]
407 #[must_use]
row(&self, index: usize) -> Vec3A408 pub fn row(&self, index: usize) -> Vec3A {
409 match index {
410 0 => Vec3A::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
411 1 => Vec3A::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
412 2 => Vec3A::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
413 _ => panic!("index out of bounds"),
414 }
415 }
416
417 /// Returns `true` if, and only if, all elements are finite.
418 /// If any element is either `NaN`, positive or negative infinity, this will return `false`.
419 #[inline]
420 #[must_use]
is_finite(&self) -> bool421 pub fn is_finite(&self) -> bool {
422 self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
423 }
424
425 /// Returns `true` if any elements are `NaN`.
426 #[inline]
427 #[must_use]
is_nan(&self) -> bool428 pub fn is_nan(&self) -> bool {
429 self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
430 }
431
432 /// Returns the transpose of `self`.
433 #[inline]
434 #[must_use]
transpose(&self) -> Self435 pub fn transpose(&self) -> Self {
436 unsafe {
437 let tmp0 = _mm_shuffle_ps(self.x_axis.0, self.y_axis.0, 0b01_00_01_00);
438 let tmp1 = _mm_shuffle_ps(self.x_axis.0, self.y_axis.0, 0b11_10_11_10);
439
440 Self {
441 x_axis: Vec3A(_mm_shuffle_ps(tmp0, self.z_axis.0, 0b00_00_10_00)),
442 y_axis: Vec3A(_mm_shuffle_ps(tmp0, self.z_axis.0, 0b01_01_11_01)),
443 z_axis: Vec3A(_mm_shuffle_ps(tmp1, self.z_axis.0, 0b10_10_10_00)),
444 }
445 }
446 }
447
448 /// Returns the determinant of `self`.
449 #[inline]
450 #[must_use]
determinant(&self) -> f32451 pub fn determinant(&self) -> f32 {
452 self.z_axis.dot(self.x_axis.cross(self.y_axis))
453 }
454
455 /// Returns the inverse of `self`.
456 ///
457 /// If the matrix is not invertible the returned matrix will be invalid.
458 ///
459 /// # Panics
460 ///
461 /// Will panic if the determinant of `self` is zero when `glam_assert` is enabled.
462 #[inline]
463 #[must_use]
inverse(&self) -> Self464 pub fn inverse(&self) -> Self {
465 let tmp0 = self.y_axis.cross(self.z_axis);
466 let tmp1 = self.z_axis.cross(self.x_axis);
467 let tmp2 = self.x_axis.cross(self.y_axis);
468 let det = self.z_axis.dot(tmp2);
469 glam_assert!(det != 0.0);
470 let inv_det = Vec3A::splat(det.recip());
471 Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose()
472 }
473
474 /// Transforms the given 2D vector as a point.
475 ///
476 /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `1`.
477 ///
478 /// This method assumes that `self` contains a valid affine transform.
479 ///
480 /// # Panics
481 ///
482 /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
483 #[inline]
484 #[must_use]
transform_point2(&self, rhs: Vec2) -> Vec2485 pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
486 glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
487 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
488 }
489
490 /// Rotates the given 2D vector.
491 ///
492 /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `0`.
493 ///
494 /// This method assumes that `self` contains a valid affine transform.
495 ///
496 /// # Panics
497 ///
498 /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
499 #[inline]
500 #[must_use]
transform_vector2(&self, rhs: Vec2) -> Vec2501 pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
502 glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
503 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
504 }
505
506 /// Transforms a 3D vector.
507 #[inline]
508 #[must_use]
mul_vec3(&self, rhs: Vec3) -> Vec3509 pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
510 self.mul_vec3a(rhs.into()).into()
511 }
512
513 /// Transforms a [`Vec3A`].
514 #[inline]
515 #[must_use]
mul_vec3a(&self, rhs: Vec3A) -> Vec3A516 pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
517 let mut res = self.x_axis.mul(rhs.xxx());
518 res = res.add(self.y_axis.mul(rhs.yyy()));
519 res = res.add(self.z_axis.mul(rhs.zzz()));
520 res
521 }
522
523 /// Multiplies two 3x3 matrices.
524 #[inline]
525 #[must_use]
mul_mat3(&self, rhs: &Self) -> Self526 pub fn mul_mat3(&self, rhs: &Self) -> Self {
527 Self::from_cols(
528 self.mul(rhs.x_axis),
529 self.mul(rhs.y_axis),
530 self.mul(rhs.z_axis),
531 )
532 }
533
534 /// Adds two 3x3 matrices.
535 #[inline]
536 #[must_use]
add_mat3(&self, rhs: &Self) -> Self537 pub fn add_mat3(&self, rhs: &Self) -> Self {
538 Self::from_cols(
539 self.x_axis.add(rhs.x_axis),
540 self.y_axis.add(rhs.y_axis),
541 self.z_axis.add(rhs.z_axis),
542 )
543 }
544
545 /// Subtracts two 3x3 matrices.
546 #[inline]
547 #[must_use]
sub_mat3(&self, rhs: &Self) -> Self548 pub fn sub_mat3(&self, rhs: &Self) -> Self {
549 Self::from_cols(
550 self.x_axis.sub(rhs.x_axis),
551 self.y_axis.sub(rhs.y_axis),
552 self.z_axis.sub(rhs.z_axis),
553 )
554 }
555
556 /// Multiplies a 3x3 matrix by a scalar.
557 #[inline]
558 #[must_use]
mul_scalar(&self, rhs: f32) -> Self559 pub fn mul_scalar(&self, rhs: f32) -> Self {
560 Self::from_cols(
561 self.x_axis.mul(rhs),
562 self.y_axis.mul(rhs),
563 self.z_axis.mul(rhs),
564 )
565 }
566
567 /// Returns true if the absolute difference of all elements between `self` and `rhs`
568 /// is less than or equal to `max_abs_diff`.
569 ///
570 /// This can be used to compare if two matrices contain similar elements. It works best
571 /// when comparing with a known value. The `max_abs_diff` that should be used used
572 /// depends on the values being compared against.
573 ///
574 /// For more see
575 /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
576 #[inline]
577 #[must_use]
abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool578 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
579 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
580 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
581 && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
582 }
583
584 #[inline]
as_dmat3(&self) -> DMat3585 pub fn as_dmat3(&self) -> DMat3 {
586 DMat3::from_cols(
587 self.x_axis.as_dvec3(),
588 self.y_axis.as_dvec3(),
589 self.z_axis.as_dvec3(),
590 )
591 }
592 }
593
594 impl Default for Mat3A {
595 #[inline]
default() -> Self596 fn default() -> Self {
597 Self::IDENTITY
598 }
599 }
600
601 impl Add<Mat3A> for Mat3A {
602 type Output = Self;
603 #[inline]
add(self, rhs: Self) -> Self::Output604 fn add(self, rhs: Self) -> Self::Output {
605 self.add_mat3(&rhs)
606 }
607 }
608
609 impl AddAssign<Mat3A> for Mat3A {
610 #[inline]
add_assign(&mut self, rhs: Self)611 fn add_assign(&mut self, rhs: Self) {
612 *self = self.add_mat3(&rhs);
613 }
614 }
615
616 impl Sub<Mat3A> for Mat3A {
617 type Output = Self;
618 #[inline]
sub(self, rhs: Self) -> Self::Output619 fn sub(self, rhs: Self) -> Self::Output {
620 self.sub_mat3(&rhs)
621 }
622 }
623
624 impl SubAssign<Mat3A> for Mat3A {
625 #[inline]
sub_assign(&mut self, rhs: Self)626 fn sub_assign(&mut self, rhs: Self) {
627 *self = self.sub_mat3(&rhs);
628 }
629 }
630
631 impl Neg for Mat3A {
632 type Output = Self;
633 #[inline]
neg(self) -> Self::Output634 fn neg(self) -> Self::Output {
635 Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
636 }
637 }
638
639 impl Mul<Mat3A> for Mat3A {
640 type Output = Self;
641 #[inline]
mul(self, rhs: Self) -> Self::Output642 fn mul(self, rhs: Self) -> Self::Output {
643 self.mul_mat3(&rhs)
644 }
645 }
646
647 impl MulAssign<Mat3A> for Mat3A {
648 #[inline]
mul_assign(&mut self, rhs: Self)649 fn mul_assign(&mut self, rhs: Self) {
650 *self = self.mul_mat3(&rhs);
651 }
652 }
653
654 impl Mul<Vec3A> for Mat3A {
655 type Output = Vec3A;
656 #[inline]
mul(self, rhs: Vec3A) -> Self::Output657 fn mul(self, rhs: Vec3A) -> Self::Output {
658 self.mul_vec3a(rhs)
659 }
660 }
661
662 impl Mul<Mat3A> for f32 {
663 type Output = Mat3A;
664 #[inline]
mul(self, rhs: Mat3A) -> Self::Output665 fn mul(self, rhs: Mat3A) -> Self::Output {
666 rhs.mul_scalar(self)
667 }
668 }
669
670 impl Mul<f32> for Mat3A {
671 type Output = Self;
672 #[inline]
mul(self, rhs: f32) -> Self::Output673 fn mul(self, rhs: f32) -> Self::Output {
674 self.mul_scalar(rhs)
675 }
676 }
677
678 impl MulAssign<f32> for Mat3A {
679 #[inline]
mul_assign(&mut self, rhs: f32)680 fn mul_assign(&mut self, rhs: f32) {
681 *self = self.mul_scalar(rhs);
682 }
683 }
684
685 impl Mul<Vec3> for Mat3A {
686 type Output = Vec3;
687 #[inline]
mul(self, rhs: Vec3) -> Vec3688 fn mul(self, rhs: Vec3) -> Vec3 {
689 self.mul_vec3a(rhs.into()).into()
690 }
691 }
692
693 impl From<Mat3> for Mat3A {
694 #[inline]
from(m: Mat3) -> Self695 fn from(m: Mat3) -> Self {
696 Self {
697 x_axis: m.x_axis.into(),
698 y_axis: m.y_axis.into(),
699 z_axis: m.z_axis.into(),
700 }
701 }
702 }
703
704 impl Sum<Self> for Mat3A {
sum<I>(iter: I) -> Self where I: Iterator<Item = Self>,705 fn sum<I>(iter: I) -> Self
706 where
707 I: Iterator<Item = Self>,
708 {
709 iter.fold(Self::ZERO, Self::add)
710 }
711 }
712
713 impl<'a> Sum<&'a Self> for Mat3A {
sum<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,714 fn sum<I>(iter: I) -> Self
715 where
716 I: Iterator<Item = &'a Self>,
717 {
718 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
719 }
720 }
721
722 impl Product for Mat3A {
product<I>(iter: I) -> Self where I: Iterator<Item = Self>,723 fn product<I>(iter: I) -> Self
724 where
725 I: Iterator<Item = Self>,
726 {
727 iter.fold(Self::IDENTITY, Self::mul)
728 }
729 }
730
731 impl<'a> Product<&'a Self> for Mat3A {
product<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,732 fn product<I>(iter: I) -> Self
733 where
734 I: Iterator<Item = &'a Self>,
735 {
736 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
737 }
738 }
739
740 impl PartialEq for Mat3A {
741 #[inline]
eq(&self, rhs: &Self) -> bool742 fn eq(&self, rhs: &Self) -> bool {
743 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
744 }
745 }
746
747 #[cfg(not(target_arch = "spirv"))]
748 impl fmt::Debug for Mat3A {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result749 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
750 fmt.debug_struct(stringify!(Mat3A))
751 .field("x_axis", &self.x_axis)
752 .field("y_axis", &self.y_axis)
753 .field("z_axis", &self.z_axis)
754 .finish()
755 }
756 }
757
758 #[cfg(not(target_arch = "spirv"))]
759 impl fmt::Display for Mat3A {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result760 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
761 write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
762 }
763 }
764