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