1 // Generated from mat.rs.tera template. Edit the template, not the generated file.
2
3 use crate::{f32::math, swizzles::*, DMat3, EulerRot, Mat2, Mat3A, 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]
mat3(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Mat312 pub const fn mat3(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Mat3 {
13 Mat3::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 Mat3 {
43 pub x_axis: Vec3,
44 pub y_axis: Vec3,
45 pub z_axis: Vec3,
46 }
47
48 impl Mat3 {
49 /// A 3x3 matrix with all elements set to `0.0`.
50 pub const ZERO: Self = Self::from_cols(Vec3::ZERO, Vec3::ZERO, Vec3::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(Vec3::X, Vec3::Y, Vec3::Z);
54
55 /// All NAN:s.
56 pub const NAN: Self = Self::from_cols(Vec3::NAN, Vec3::NAN, Vec3::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: Vec3::new(m00, m01, m02),
74 y_axis: Vec3::new(m10, m11, m12),
75 z_axis: Vec3::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: Vec3, y_axis: Vec3, z_axis: Vec3) -> Self82 pub const fn from_cols(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> 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 Vec3::from_array(m[0]),
125 Vec3::from_array(m[1]),
126 Vec3::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.xyz(), m.y_axis.xyz(), m.z_axis.xyz())
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 Vec3::new(1.0 - (yy + zz), xy + wz, xz - wy),
184 Vec3::new(xy - wz, 1.0 - (xx + zz), yz + wx),
185 Vec3::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 Vec3::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
210 Vec3::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
211 Vec3::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 Vec3::X,
231 Vec3::new(0.0, cosa, sina),
232 Vec3::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 Vec3::new(cosa, 0.0, -sina),
243 Vec3::Y,
244 Vec3::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 Vec3::new(cosa, sina, 0.0),
255 Vec3::new(-sina, cosa, 0.0),
256 Vec3::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 Vec3::X,
269 Vec3::Y,
270 Vec3::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(Vec3::new(cos, sin, 0.0), Vec3::new(-sin, cos, 0.0), Vec3::Z)
284 }
285
286 /// Creates an affine transformation matrix from the given 2D `scale`, rotation `angle` (in
287 /// radians) and `translation`.
288 ///
289 /// The resulting matrix can be used to transform 2D points and vectors. See
290 /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
291 #[inline]
292 #[must_use]
from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self293 pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
294 let (sin, cos) = math::sin_cos(angle);
295 Self::from_cols(
296 Vec3::new(cos * scale.x, sin * scale.x, 0.0),
297 Vec3::new(-sin * scale.y, cos * scale.y, 0.0),
298 Vec3::new(translation.x, translation.y, 1.0),
299 )
300 }
301
302 /// Creates an affine transformation matrix from the given non-uniform 2D `scale`.
303 ///
304 /// The resulting matrix can be used to transform 2D points and vectors. See
305 /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
306 ///
307 /// # Panics
308 ///
309 /// Will panic if all elements of `scale` are zero when `glam_assert` is enabled.
310 #[inline]
311 #[must_use]
from_scale(scale: Vec2) -> Self312 pub fn from_scale(scale: Vec2) -> Self {
313 // Do not panic as long as any component is non-zero
314 glam_assert!(scale.cmpne(Vec2::ZERO).any());
315
316 Self::from_cols(
317 Vec3::new(scale.x, 0.0, 0.0),
318 Vec3::new(0.0, scale.y, 0.0),
319 Vec3::Z,
320 )
321 }
322
323 /// Creates an affine transformation matrix from the given 2x2 matrix.
324 ///
325 /// The resulting matrix can be used to transform 2D points and vectors. See
326 /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
327 #[inline]
from_mat2(m: Mat2) -> Self328 pub fn from_mat2(m: Mat2) -> Self {
329 Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), Vec3::Z)
330 }
331
332 /// Creates a 3x3 matrix from the first 9 values in `slice`.
333 ///
334 /// # Panics
335 ///
336 /// Panics if `slice` is less than 9 elements long.
337 #[inline]
338 #[must_use]
from_cols_slice(slice: &[f32]) -> Self339 pub const fn from_cols_slice(slice: &[f32]) -> Self {
340 Self::new(
341 slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
342 slice[8],
343 )
344 }
345
346 /// Writes the columns of `self` to the first 9 elements in `slice`.
347 ///
348 /// # Panics
349 ///
350 /// Panics if `slice` is less than 9 elements long.
351 #[inline]
write_cols_to_slice(self, slice: &mut [f32])352 pub fn write_cols_to_slice(self, slice: &mut [f32]) {
353 slice[0] = self.x_axis.x;
354 slice[1] = self.x_axis.y;
355 slice[2] = self.x_axis.z;
356 slice[3] = self.y_axis.x;
357 slice[4] = self.y_axis.y;
358 slice[5] = self.y_axis.z;
359 slice[6] = self.z_axis.x;
360 slice[7] = self.z_axis.y;
361 slice[8] = self.z_axis.z;
362 }
363
364 /// Returns the matrix column for the given `index`.
365 ///
366 /// # Panics
367 ///
368 /// Panics if `index` is greater than 2.
369 #[inline]
370 #[must_use]
col(&self, index: usize) -> Vec3371 pub fn col(&self, index: usize) -> Vec3 {
372 match index {
373 0 => self.x_axis,
374 1 => self.y_axis,
375 2 => self.z_axis,
376 _ => panic!("index out of bounds"),
377 }
378 }
379
380 /// Returns a mutable reference to the matrix column for the given `index`.
381 ///
382 /// # Panics
383 ///
384 /// Panics if `index` is greater than 2.
385 #[inline]
col_mut(&mut self, index: usize) -> &mut Vec3386 pub fn col_mut(&mut self, index: usize) -> &mut Vec3 {
387 match index {
388 0 => &mut self.x_axis,
389 1 => &mut self.y_axis,
390 2 => &mut self.z_axis,
391 _ => panic!("index out of bounds"),
392 }
393 }
394
395 /// Returns the matrix row for the given `index`.
396 ///
397 /// # Panics
398 ///
399 /// Panics if `index` is greater than 2.
400 #[inline]
401 #[must_use]
row(&self, index: usize) -> Vec3402 pub fn row(&self, index: usize) -> Vec3 {
403 match index {
404 0 => Vec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
405 1 => Vec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
406 2 => Vec3::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
407 _ => panic!("index out of bounds"),
408 }
409 }
410
411 /// Returns `true` if, and only if, all elements are finite.
412 /// If any element is either `NaN`, positive or negative infinity, this will return `false`.
413 #[inline]
414 #[must_use]
is_finite(&self) -> bool415 pub fn is_finite(&self) -> bool {
416 self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
417 }
418
419 /// Returns `true` if any elements are `NaN`.
420 #[inline]
421 #[must_use]
is_nan(&self) -> bool422 pub fn is_nan(&self) -> bool {
423 self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
424 }
425
426 /// Returns the transpose of `self`.
427 #[inline]
428 #[must_use]
transpose(&self) -> Self429 pub fn transpose(&self) -> Self {
430 Self {
431 x_axis: Vec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
432 y_axis: Vec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
433 z_axis: Vec3::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
434 }
435 }
436
437 /// Returns the determinant of `self`.
438 #[inline]
439 #[must_use]
determinant(&self) -> f32440 pub fn determinant(&self) -> f32 {
441 self.z_axis.dot(self.x_axis.cross(self.y_axis))
442 }
443
444 /// Returns the inverse of `self`.
445 ///
446 /// If the matrix is not invertible the returned matrix will be invalid.
447 ///
448 /// # Panics
449 ///
450 /// Will panic if the determinant of `self` is zero when `glam_assert` is enabled.
451 #[inline]
452 #[must_use]
inverse(&self) -> Self453 pub fn inverse(&self) -> Self {
454 let tmp0 = self.y_axis.cross(self.z_axis);
455 let tmp1 = self.z_axis.cross(self.x_axis);
456 let tmp2 = self.x_axis.cross(self.y_axis);
457 let det = self.z_axis.dot(tmp2);
458 glam_assert!(det != 0.0);
459 let inv_det = Vec3::splat(det.recip());
460 Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose()
461 }
462
463 /// Transforms the given 2D vector as a point.
464 ///
465 /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `1`.
466 ///
467 /// This method assumes that `self` contains a valid affine transform.
468 ///
469 /// # Panics
470 ///
471 /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
472 #[inline]
473 #[must_use]
transform_point2(&self, rhs: Vec2) -> Vec2474 pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
475 glam_assert!(self.row(2).abs_diff_eq(Vec3::Z, 1e-6));
476 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
477 }
478
479 /// Rotates the given 2D vector.
480 ///
481 /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `0`.
482 ///
483 /// This method assumes that `self` contains a valid affine transform.
484 ///
485 /// # Panics
486 ///
487 /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
488 #[inline]
489 #[must_use]
transform_vector2(&self, rhs: Vec2) -> Vec2490 pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
491 glam_assert!(self.row(2).abs_diff_eq(Vec3::Z, 1e-6));
492 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
493 }
494
495 /// Transforms a 3D vector.
496 #[inline]
497 #[must_use]
mul_vec3(&self, rhs: Vec3) -> Vec3498 pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
499 let mut res = self.x_axis.mul(rhs.x);
500 res = res.add(self.y_axis.mul(rhs.y));
501 res = res.add(self.z_axis.mul(rhs.z));
502 res
503 }
504
505 /// Transforms a [`Vec3A`].
506 #[inline]
507 #[must_use]
mul_vec3a(&self, rhs: Vec3A) -> Vec3A508 pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
509 self.mul_vec3(rhs.into()).into()
510 }
511
512 /// Multiplies two 3x3 matrices.
513 #[inline]
514 #[must_use]
mul_mat3(&self, rhs: &Self) -> Self515 pub fn mul_mat3(&self, rhs: &Self) -> Self {
516 Self::from_cols(
517 self.mul(rhs.x_axis),
518 self.mul(rhs.y_axis),
519 self.mul(rhs.z_axis),
520 )
521 }
522
523 /// Adds two 3x3 matrices.
524 #[inline]
525 #[must_use]
add_mat3(&self, rhs: &Self) -> Self526 pub fn add_mat3(&self, rhs: &Self) -> Self {
527 Self::from_cols(
528 self.x_axis.add(rhs.x_axis),
529 self.y_axis.add(rhs.y_axis),
530 self.z_axis.add(rhs.z_axis),
531 )
532 }
533
534 /// Subtracts two 3x3 matrices.
535 #[inline]
536 #[must_use]
sub_mat3(&self, rhs: &Self) -> Self537 pub fn sub_mat3(&self, rhs: &Self) -> Self {
538 Self::from_cols(
539 self.x_axis.sub(rhs.x_axis),
540 self.y_axis.sub(rhs.y_axis),
541 self.z_axis.sub(rhs.z_axis),
542 )
543 }
544
545 /// Multiplies a 3x3 matrix by a scalar.
546 #[inline]
547 #[must_use]
mul_scalar(&self, rhs: f32) -> Self548 pub fn mul_scalar(&self, rhs: f32) -> Self {
549 Self::from_cols(
550 self.x_axis.mul(rhs),
551 self.y_axis.mul(rhs),
552 self.z_axis.mul(rhs),
553 )
554 }
555
556 /// Returns true if the absolute difference of all elements between `self` and `rhs`
557 /// is less than or equal to `max_abs_diff`.
558 ///
559 /// This can be used to compare if two matrices contain similar elements. It works best
560 /// when comparing with a known value. The `max_abs_diff` that should be used used
561 /// depends on the values being compared against.
562 ///
563 /// For more see
564 /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
565 #[inline]
566 #[must_use]
abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool567 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
568 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
569 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
570 && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
571 }
572
573 #[inline]
as_dmat3(&self) -> DMat3574 pub fn as_dmat3(&self) -> DMat3 {
575 DMat3::from_cols(
576 self.x_axis.as_dvec3(),
577 self.y_axis.as_dvec3(),
578 self.z_axis.as_dvec3(),
579 )
580 }
581 }
582
583 impl Default for Mat3 {
584 #[inline]
default() -> Self585 fn default() -> Self {
586 Self::IDENTITY
587 }
588 }
589
590 impl Add<Mat3> for Mat3 {
591 type Output = Self;
592 #[inline]
add(self, rhs: Self) -> Self::Output593 fn add(self, rhs: Self) -> Self::Output {
594 self.add_mat3(&rhs)
595 }
596 }
597
598 impl AddAssign<Mat3> for Mat3 {
599 #[inline]
add_assign(&mut self, rhs: Self)600 fn add_assign(&mut self, rhs: Self) {
601 *self = self.add_mat3(&rhs);
602 }
603 }
604
605 impl Sub<Mat3> for Mat3 {
606 type Output = Self;
607 #[inline]
sub(self, rhs: Self) -> Self::Output608 fn sub(self, rhs: Self) -> Self::Output {
609 self.sub_mat3(&rhs)
610 }
611 }
612
613 impl SubAssign<Mat3> for Mat3 {
614 #[inline]
sub_assign(&mut self, rhs: Self)615 fn sub_assign(&mut self, rhs: Self) {
616 *self = self.sub_mat3(&rhs);
617 }
618 }
619
620 impl Neg for Mat3 {
621 type Output = Self;
622 #[inline]
neg(self) -> Self::Output623 fn neg(self) -> Self::Output {
624 Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
625 }
626 }
627
628 impl Mul<Mat3> for Mat3 {
629 type Output = Self;
630 #[inline]
mul(self, rhs: Self) -> Self::Output631 fn mul(self, rhs: Self) -> Self::Output {
632 self.mul_mat3(&rhs)
633 }
634 }
635
636 impl MulAssign<Mat3> for Mat3 {
637 #[inline]
mul_assign(&mut self, rhs: Self)638 fn mul_assign(&mut self, rhs: Self) {
639 *self = self.mul_mat3(&rhs);
640 }
641 }
642
643 impl Mul<Vec3> for Mat3 {
644 type Output = Vec3;
645 #[inline]
mul(self, rhs: Vec3) -> Self::Output646 fn mul(self, rhs: Vec3) -> Self::Output {
647 self.mul_vec3(rhs)
648 }
649 }
650
651 impl Mul<Mat3> for f32 {
652 type Output = Mat3;
653 #[inline]
mul(self, rhs: Mat3) -> Self::Output654 fn mul(self, rhs: Mat3) -> Self::Output {
655 rhs.mul_scalar(self)
656 }
657 }
658
659 impl Mul<f32> for Mat3 {
660 type Output = Self;
661 #[inline]
mul(self, rhs: f32) -> Self::Output662 fn mul(self, rhs: f32) -> Self::Output {
663 self.mul_scalar(rhs)
664 }
665 }
666
667 impl MulAssign<f32> for Mat3 {
668 #[inline]
mul_assign(&mut self, rhs: f32)669 fn mul_assign(&mut self, rhs: f32) {
670 *self = self.mul_scalar(rhs);
671 }
672 }
673
674 impl Mul<Vec3A> for Mat3 {
675 type Output = Vec3A;
676 #[inline]
mul(self, rhs: Vec3A) -> Vec3A677 fn mul(self, rhs: Vec3A) -> Vec3A {
678 self.mul_vec3a(rhs)
679 }
680 }
681
682 impl From<Mat3A> for Mat3 {
683 #[inline]
from(m: Mat3A) -> Self684 fn from(m: Mat3A) -> Self {
685 Self {
686 x_axis: m.x_axis.into(),
687 y_axis: m.y_axis.into(),
688 z_axis: m.z_axis.into(),
689 }
690 }
691 }
692
693 impl Sum<Self> for Mat3 {
sum<I>(iter: I) -> Self where I: Iterator<Item = Self>,694 fn sum<I>(iter: I) -> Self
695 where
696 I: Iterator<Item = Self>,
697 {
698 iter.fold(Self::ZERO, Self::add)
699 }
700 }
701
702 impl<'a> Sum<&'a Self> for Mat3 {
sum<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,703 fn sum<I>(iter: I) -> Self
704 where
705 I: Iterator<Item = &'a Self>,
706 {
707 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
708 }
709 }
710
711 impl Product for Mat3 {
product<I>(iter: I) -> Self where I: Iterator<Item = Self>,712 fn product<I>(iter: I) -> Self
713 where
714 I: Iterator<Item = Self>,
715 {
716 iter.fold(Self::IDENTITY, Self::mul)
717 }
718 }
719
720 impl<'a> Product<&'a Self> for Mat3 {
product<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,721 fn product<I>(iter: I) -> Self
722 where
723 I: Iterator<Item = &'a Self>,
724 {
725 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
726 }
727 }
728
729 impl PartialEq for Mat3 {
730 #[inline]
eq(&self, rhs: &Self) -> bool731 fn eq(&self, rhs: &Self) -> bool {
732 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
733 }
734 }
735
736 #[cfg(not(target_arch = "spirv"))]
737 impl AsRef<[f32; 9]> for Mat3 {
738 #[inline]
as_ref(&self) -> &[f32; 9]739 fn as_ref(&self) -> &[f32; 9] {
740 unsafe { &*(self as *const Self as *const [f32; 9]) }
741 }
742 }
743
744 #[cfg(not(target_arch = "spirv"))]
745 impl AsMut<[f32; 9]> for Mat3 {
746 #[inline]
as_mut(&mut self) -> &mut [f32; 9]747 fn as_mut(&mut self) -> &mut [f32; 9] {
748 unsafe { &mut *(self as *mut Self as *mut [f32; 9]) }
749 }
750 }
751
752 #[cfg(not(target_arch = "spirv"))]
753 impl fmt::Debug for Mat3 {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result754 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
755 fmt.debug_struct(stringify!(Mat3))
756 .field("x_axis", &self.x_axis)
757 .field("y_axis", &self.y_axis)
758 .field("z_axis", &self.z_axis)
759 .finish()
760 }
761 }
762
763 #[cfg(not(target_arch = "spirv"))]
764 impl fmt::Display for Mat3 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result765 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
766 write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
767 }
768 }
769