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