1 // Generated from mat.rs.tera template. Edit the template, not the generated file.
2
3 use crate::{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 #[cfg(feature = "libm")]
10 #[allow(unused_imports)]
11 use num_traits::Float;
12
13 /// Creates a 3x3 matrix from column vectors.
14 #[inline(always)]
mat3(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Mat315 pub const fn mat3(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Mat3 {
16 Mat3::from_cols(x_axis, y_axis, z_axis)
17 }
18
19 /// A 3x3 column major matrix.
20 ///
21 /// This 3x3 matrix type features convenience methods for creating and using linear and
22 /// affine transformations. If you are primarily dealing with 2D affine transformations the
23 /// [`Affine2`](crate::Affine2) type is much faster and more space efficient than
24 /// using a 3x3 matrix.
25 ///
26 /// Linear transformations including 3D rotation and scale can be created using methods
27 /// such as [`Self::from_diagonal()`], [`Self::from_quat()`], [`Self::from_axis_angle()`],
28 /// [`Self::from_rotation_x()`], [`Self::from_rotation_y()`], or
29 /// [`Self::from_rotation_z()`].
30 ///
31 /// The resulting matrices can be use to transform 3D vectors using regular vector
32 /// multiplication.
33 ///
34 /// Affine transformations including 2D translation, rotation and scale can be created
35 /// using methods such as [`Self::from_translation()`], [`Self::from_angle()`],
36 /// [`Self::from_scale()`] and [`Self::from_scale_angle_translation()`].
37 ///
38 /// The [`Self::transform_point2()`] and [`Self::transform_vector2()`] convenience methods
39 /// are provided for performing affine transforms on 2D vectors and points. These multiply
40 /// 2D inputs as 3D vectors with an implicit `z` value of `1` for points and `0` for
41 /// vectors respectively. These methods assume that `Self` contains a valid affine
42 /// transform.
43 #[derive(Clone, Copy)]
44 #[repr(C)]
45 pub struct Mat3 {
46 pub x_axis: Vec3,
47 pub y_axis: Vec3,
48 pub z_axis: Vec3,
49 }
50
51 impl Mat3 {
52 /// A 3x3 matrix with all elements set to `0.0`.
53 pub const ZERO: Self = Self::from_cols(Vec3::ZERO, Vec3::ZERO, Vec3::ZERO);
54
55 /// A 3x3 identity matrix, where all diagonal elements are `1`, and all off-diagonal elements are `0`.
56 pub const IDENTITY: Self = Self::from_cols(Vec3::X, Vec3::Y, Vec3::Z);
57
58 /// All NAN:s.
59 pub const NAN: Self = Self::from_cols(Vec3::NAN, Vec3::NAN, Vec3::NAN);
60
61 #[allow(clippy::too_many_arguments)]
62 #[inline(always)]
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: Vec3::new(m00, m01, m02),
76 y_axis: Vec3::new(m10, m11, m12),
77 z_axis: Vec3::new(m20, m21, m22),
78 }
79 }
80
81 /// Creates a 3x3 matrix from two column vectors.
82 #[inline(always)]
from_cols(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Self83 pub const fn from_cols(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Self {
84 Self {
85 x_axis,
86 y_axis,
87 z_axis,
88 }
89 }
90
91 /// Creates a 3x3 matrix from a `[f32; 9]` array stored in column major order.
92 /// If your data is stored in row major you will need to `transpose` the returned
93 /// matrix.
94 #[inline]
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]
to_cols_array(&self) -> [f32; 9]102 pub const fn to_cols_array(&self) -> [f32; 9] {
103 [
104 self.x_axis.x,
105 self.x_axis.y,
106 self.x_axis.z,
107 self.y_axis.x,
108 self.y_axis.y,
109 self.y_axis.z,
110 self.z_axis.x,
111 self.z_axis.y,
112 self.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]
from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self120 pub const fn from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self {
121 Self::from_cols(
122 Vec3::from_array(m[0]),
123 Vec3::from_array(m[1]),
124 Vec3::from_array(m[2]),
125 )
126 }
127
128 /// Creates a `[[f32; 3]; 3]` 3D array storing data in column major order.
129 /// If you require data in row major order `transpose` the matrix first.
130 #[inline]
to_cols_array_2d(&self) -> [[f32; 3]; 3]131 pub const fn to_cols_array_2d(&self) -> [[f32; 3]; 3] {
132 [
133 self.x_axis.to_array(),
134 self.y_axis.to_array(),
135 self.z_axis.to_array(),
136 ]
137 }
138
139 /// Creates a 3x3 matrix with its diagonal set to `diagonal` and all other entries set to 0.
140 #[doc(alias = "scale")]
141 #[inline]
from_diagonal(diagonal: Vec3) -> Self142 pub const fn from_diagonal(diagonal: Vec3) -> Self {
143 Self::new(
144 diagonal.x, 0.0, 0.0, 0.0, diagonal.y, 0.0, 0.0, 0.0, diagonal.z,
145 )
146 }
147
148 /// Creates a 3x3 matrix from a 4x4 matrix, discarding the 4th row and column.
from_mat4(m: Mat4) -> Self149 pub fn from_mat4(m: Mat4) -> Self {
150 Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.z_axis.xyz())
151 }
152
153 /// Creates a 3D rotation matrix from the given quaternion.
154 ///
155 /// # Panics
156 ///
157 /// Will panic if `rotation` is not normalized when `glam_assert` is enabled.
158 #[inline]
from_quat(rotation: Quat) -> Self159 pub fn from_quat(rotation: Quat) -> Self {
160 glam_assert!(rotation.is_normalized());
161
162 let x2 = rotation.x + rotation.x;
163 let y2 = rotation.y + rotation.y;
164 let z2 = rotation.z + rotation.z;
165 let xx = rotation.x * x2;
166 let xy = rotation.x * y2;
167 let xz = rotation.x * z2;
168 let yy = rotation.y * y2;
169 let yz = rotation.y * z2;
170 let zz = rotation.z * z2;
171 let wx = rotation.w * x2;
172 let wy = rotation.w * y2;
173 let wz = rotation.w * z2;
174
175 Self::from_cols(
176 Vec3::new(1.0 - (yy + zz), xy + wz, xz - wy),
177 Vec3::new(xy - wz, 1.0 - (xx + zz), yz + wx),
178 Vec3::new(xz + wy, yz - wx, 1.0 - (xx + yy)),
179 )
180 }
181
182 /// Creates a 3D rotation matrix from a normalized rotation `axis` and `angle` (in
183 /// radians).
184 ///
185 /// # Panics
186 ///
187 /// Will panic if `axis` is not normalized when `glam_assert` is enabled.
188 #[inline]
from_axis_angle(axis: Vec3, angle: f32) -> Self189 pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
190 glam_assert!(axis.is_normalized());
191
192 let (sin, cos) = angle.sin_cos();
193 let (xsin, ysin, zsin) = axis.mul(sin).into();
194 let (x, y, z) = axis.into();
195 let (x2, y2, z2) = axis.mul(axis).into();
196 let omc = 1.0 - cos;
197 let xyomc = x * y * omc;
198 let xzomc = x * z * omc;
199 let yzomc = y * z * omc;
200 Self::from_cols(
201 Vec3::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
202 Vec3::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
203 Vec3::new(xzomc + ysin, yzomc - xsin, z2 * omc + cos),
204 )
205 }
206
207 #[inline]
208 /// Creates a 3D rotation matrix from the given euler rotation sequence and the angles (in
209 /// radians).
from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self210 pub fn from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self {
211 let quat = Quat::from_euler(order, a, b, c);
212 Self::from_quat(quat)
213 }
214
215 /// Creates a 3D rotation matrix from `angle` (in radians) around the x axis.
216 #[inline]
from_rotation_x(angle: f32) -> Self217 pub fn from_rotation_x(angle: f32) -> Self {
218 let (sina, cosa) = angle.sin_cos();
219 Self::from_cols(
220 Vec3::X,
221 Vec3::new(0.0, cosa, sina),
222 Vec3::new(0.0, -sina, cosa),
223 )
224 }
225
226 /// Creates a 3D rotation matrix from `angle` (in radians) around the y axis.
227 #[inline]
from_rotation_y(angle: f32) -> Self228 pub fn from_rotation_y(angle: f32) -> Self {
229 let (sina, cosa) = angle.sin_cos();
230 Self::from_cols(
231 Vec3::new(cosa, 0.0, -sina),
232 Vec3::Y,
233 Vec3::new(sina, 0.0, cosa),
234 )
235 }
236
237 /// Creates a 3D rotation matrix from `angle` (in radians) around the z axis.
238 #[inline]
from_rotation_z(angle: f32) -> Self239 pub fn from_rotation_z(angle: f32) -> Self {
240 let (sina, cosa) = angle.sin_cos();
241 Self::from_cols(
242 Vec3::new(cosa, sina, 0.0),
243 Vec3::new(-sina, cosa, 0.0),
244 Vec3::Z,
245 )
246 }
247
248 /// Creates an affine transformation matrix from the given 2D `translation`.
249 ///
250 /// The resulting matrix can be used to transform 2D points and vectors. See
251 /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
252 #[inline]
from_translation(translation: Vec2) -> Self253 pub fn from_translation(translation: Vec2) -> Self {
254 Self::from_cols(
255 Vec3::X,
256 Vec3::Y,
257 Vec3::new(translation.x, translation.y, 1.0),
258 )
259 }
260
261 /// Creates an affine transformation matrix from the given 2D rotation `angle` (in
262 /// radians).
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]
from_angle(angle: f32) -> Self267 pub fn from_angle(angle: f32) -> Self {
268 let (sin, cos) = angle.sin_cos();
269 Self::from_cols(Vec3::new(cos, sin, 0.0), Vec3::new(-sin, cos, 0.0), Vec3::Z)
270 }
271
272 /// Creates an affine transformation matrix from the given 2D `scale`, rotation `angle` (in
273 /// radians) and `translation`.
274 ///
275 /// The resulting matrix can be used to transform 2D points and vectors. See
276 /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
277 #[inline]
from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self278 pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
279 let (sin, cos) = angle.sin_cos();
280 Self::from_cols(
281 Vec3::new(cos * scale.x, sin * scale.x, 0.0),
282 Vec3::new(-sin * scale.y, cos * scale.y, 0.0),
283 Vec3::new(translation.x, translation.y, 1.0),
284 )
285 }
286
287 /// Creates an affine transformation matrix from the given non-uniform 2D `scale`.
288 ///
289 /// The resulting matrix can be used to transform 2D points and vectors. See
290 /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
291 ///
292 /// # Panics
293 ///
294 /// Will panic if all elements of `scale` are zero when `glam_assert` is enabled.
295 #[inline]
from_scale(scale: Vec2) -> Self296 pub fn from_scale(scale: Vec2) -> Self {
297 // Do not panic as long as any component is non-zero
298 glam_assert!(scale.cmpne(Vec2::ZERO).any());
299
300 Self::from_cols(
301 Vec3::new(scale.x, 0.0, 0.0),
302 Vec3::new(0.0, scale.y, 0.0),
303 Vec3::Z,
304 )
305 }
306
307 /// Creates an affine transformation matrix from the given 2x2 matrix.
308 ///
309 /// The resulting matrix can be used to transform 2D points and vectors. See
310 /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
311 #[inline]
from_mat2(m: Mat2) -> Self312 pub fn from_mat2(m: Mat2) -> Self {
313 Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), Vec3::Z)
314 }
315
316 /// Creates a 3x3 matrix from the first 9 values in `slice`.
317 ///
318 /// # Panics
319 ///
320 /// Panics if `slice` is less than 9 elements long.
321 #[inline]
from_cols_slice(slice: &[f32]) -> Self322 pub const fn from_cols_slice(slice: &[f32]) -> Self {
323 Self::new(
324 slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
325 slice[8],
326 )
327 }
328
329 /// Writes the columns of `self` to the first 9 elements in `slice`.
330 ///
331 /// # Panics
332 ///
333 /// Panics if `slice` is less than 9 elements long.
334 #[inline]
write_cols_to_slice(self, slice: &mut [f32])335 pub fn write_cols_to_slice(self, slice: &mut [f32]) {
336 slice[0] = self.x_axis.x;
337 slice[1] = self.x_axis.y;
338 slice[2] = self.x_axis.z;
339 slice[3] = self.y_axis.x;
340 slice[4] = self.y_axis.y;
341 slice[5] = self.y_axis.z;
342 slice[6] = self.z_axis.x;
343 slice[7] = self.z_axis.y;
344 slice[8] = self.z_axis.z;
345 }
346
347 /// Returns the matrix column for the given `index`.
348 ///
349 /// # Panics
350 ///
351 /// Panics if `index` is greater than 2.
352 #[inline]
col(&self, index: usize) -> Vec3353 pub fn col(&self, index: usize) -> Vec3 {
354 match index {
355 0 => self.x_axis,
356 1 => self.y_axis,
357 2 => self.z_axis,
358 _ => panic!("index out of bounds"),
359 }
360 }
361
362 /// Returns a mutable reference to the matrix column for the given `index`.
363 ///
364 /// # Panics
365 ///
366 /// Panics if `index` is greater than 2.
367 #[inline]
col_mut(&mut self, index: usize) -> &mut Vec3368 pub fn col_mut(&mut self, index: usize) -> &mut Vec3 {
369 match index {
370 0 => &mut self.x_axis,
371 1 => &mut self.y_axis,
372 2 => &mut self.z_axis,
373 _ => panic!("index out of bounds"),
374 }
375 }
376
377 /// Returns the matrix row for the given `index`.
378 ///
379 /// # Panics
380 ///
381 /// Panics if `index` is greater than 2.
382 #[inline]
row(&self, index: usize) -> Vec3383 pub fn row(&self, index: usize) -> Vec3 {
384 match index {
385 0 => Vec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
386 1 => Vec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
387 2 => Vec3::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
388 _ => panic!("index out of bounds"),
389 }
390 }
391
392 /// Returns `true` if, and only if, all elements are finite.
393 /// If any element is either `NaN`, positive or negative infinity, this will return `false`.
394 #[inline]
is_finite(&self) -> bool395 pub fn is_finite(&self) -> bool {
396 self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
397 }
398
399 /// Returns `true` if any elements are `NaN`.
400 #[inline]
is_nan(&self) -> bool401 pub fn is_nan(&self) -> bool {
402 self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
403 }
404
405 /// Returns the transpose of `self`.
406 #[must_use]
407 #[inline]
transpose(&self) -> Self408 pub fn transpose(&self) -> Self {
409 Self {
410 x_axis: Vec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
411 y_axis: Vec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
412 z_axis: Vec3::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
413 }
414 }
415
416 /// Returns the determinant of `self`.
417 #[inline]
determinant(&self) -> f32418 pub fn determinant(&self) -> f32 {
419 self.z_axis.dot(self.x_axis.cross(self.y_axis))
420 }
421
422 /// Returns the inverse of `self`.
423 ///
424 /// If the matrix is not invertible the returned matrix will be invalid.
425 ///
426 /// # Panics
427 ///
428 /// Will panic if the determinant of `self` is zero when `glam_assert` is enabled.
429 #[must_use]
430 #[inline]
inverse(&self) -> Self431 pub fn inverse(&self) -> Self {
432 let tmp0 = self.y_axis.cross(self.z_axis);
433 let tmp1 = self.z_axis.cross(self.x_axis);
434 let tmp2 = self.x_axis.cross(self.y_axis);
435 let det = self.z_axis.dot(tmp2);
436 glam_assert!(det != 0.0);
437 let inv_det = Vec3::splat(det.recip());
438 Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose()
439 }
440
441 /// Transforms the given 2D vector as a point.
442 ///
443 /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `1`.
444 ///
445 /// This method assumes that `self` contains a valid affine transform.
446 ///
447 /// # Panics
448 ///
449 /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
450 #[inline]
transform_point2(&self, rhs: Vec2) -> Vec2451 pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
452 glam_assert!(self.row(2).abs_diff_eq(Vec3::Z, 1e-6));
453 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
454 }
455
456 /// Rotates the given 2D vector.
457 ///
458 /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `0`.
459 ///
460 /// This method assumes that `self` contains a valid affine transform.
461 ///
462 /// # Panics
463 ///
464 /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
465 #[inline]
transform_vector2(&self, rhs: Vec2) -> Vec2466 pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
467 glam_assert!(self.row(2).abs_diff_eq(Vec3::Z, 1e-6));
468 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
469 }
470
471 /// Transforms a 3D vector.
472 #[inline]
mul_vec3(&self, rhs: Vec3) -> Vec3473 pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
474 let mut res = self.x_axis.mul(rhs.x);
475 res = res.add(self.y_axis.mul(rhs.y));
476 res = res.add(self.z_axis.mul(rhs.z));
477 res
478 }
479
480 /// Transforms a `Vec3A`.
481 #[inline]
mul_vec3a(&self, rhs: Vec3A) -> Vec3A482 pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
483 self.mul_vec3(rhs.into()).into()
484 }
485
486 /// Multiplies two 3x3 matrices.
487 #[inline]
mul_mat3(&self, rhs: &Self) -> Self488 pub fn mul_mat3(&self, rhs: &Self) -> Self {
489 Self::from_cols(
490 self.mul(rhs.x_axis),
491 self.mul(rhs.y_axis),
492 self.mul(rhs.z_axis),
493 )
494 }
495
496 /// Adds two 3x3 matrices.
497 #[inline]
add_mat3(&self, rhs: &Self) -> Self498 pub fn add_mat3(&self, rhs: &Self) -> Self {
499 Self::from_cols(
500 self.x_axis.add(rhs.x_axis),
501 self.y_axis.add(rhs.y_axis),
502 self.z_axis.add(rhs.z_axis),
503 )
504 }
505
506 /// Subtracts two 3x3 matrices.
507 #[inline]
sub_mat3(&self, rhs: &Self) -> Self508 pub fn sub_mat3(&self, rhs: &Self) -> Self {
509 Self::from_cols(
510 self.x_axis.sub(rhs.x_axis),
511 self.y_axis.sub(rhs.y_axis),
512 self.z_axis.sub(rhs.z_axis),
513 )
514 }
515
516 /// Multiplies a 3x3 matrix by a scalar.
517 #[inline]
mul_scalar(&self, rhs: f32) -> Self518 pub fn mul_scalar(&self, rhs: f32) -> Self {
519 Self::from_cols(
520 self.x_axis.mul(rhs),
521 self.y_axis.mul(rhs),
522 self.z_axis.mul(rhs),
523 )
524 }
525
526 /// Returns true if the absolute difference of all elements between `self` and `rhs`
527 /// is less than or equal to `max_abs_diff`.
528 ///
529 /// This can be used to compare if two matrices contain similar elements. It works best
530 /// when comparing with a known value. The `max_abs_diff` that should be used used
531 /// depends on the values being compared against.
532 ///
533 /// For more see
534 /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
535 #[inline]
abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool536 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
537 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
538 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
539 && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
540 }
541
542 #[inline]
as_dmat3(&self) -> DMat3543 pub fn as_dmat3(&self) -> DMat3 {
544 DMat3::from_cols(
545 self.x_axis.as_dvec3(),
546 self.y_axis.as_dvec3(),
547 self.z_axis.as_dvec3(),
548 )
549 }
550 }
551
552 impl Default for Mat3 {
553 #[inline]
default() -> Self554 fn default() -> Self {
555 Self::IDENTITY
556 }
557 }
558
559 impl Add<Mat3> for Mat3 {
560 type Output = Self;
561 #[inline]
add(self, rhs: Self) -> Self::Output562 fn add(self, rhs: Self) -> Self::Output {
563 self.add_mat3(&rhs)
564 }
565 }
566
567 impl AddAssign<Mat3> for Mat3 {
568 #[inline]
add_assign(&mut self, rhs: Self)569 fn add_assign(&mut self, rhs: Self) {
570 *self = self.add_mat3(&rhs);
571 }
572 }
573
574 impl Sub<Mat3> for Mat3 {
575 type Output = Self;
576 #[inline]
sub(self, rhs: Self) -> Self::Output577 fn sub(self, rhs: Self) -> Self::Output {
578 self.sub_mat3(&rhs)
579 }
580 }
581
582 impl SubAssign<Mat3> for Mat3 {
583 #[inline]
sub_assign(&mut self, rhs: Self)584 fn sub_assign(&mut self, rhs: Self) {
585 *self = self.sub_mat3(&rhs);
586 }
587 }
588
589 impl Neg for Mat3 {
590 type Output = Self;
591 #[inline]
neg(self) -> Self::Output592 fn neg(self) -> Self::Output {
593 Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
594 }
595 }
596
597 impl Mul<Mat3> for Mat3 {
598 type Output = Self;
599 #[inline]
mul(self, rhs: Self) -> Self::Output600 fn mul(self, rhs: Self) -> Self::Output {
601 self.mul_mat3(&rhs)
602 }
603 }
604
605 impl MulAssign<Mat3> for Mat3 {
606 #[inline]
mul_assign(&mut self, rhs: Self)607 fn mul_assign(&mut self, rhs: Self) {
608 *self = self.mul_mat3(&rhs);
609 }
610 }
611
612 impl Mul<Vec3> for Mat3 {
613 type Output = Vec3;
614 #[inline]
mul(self, rhs: Vec3) -> Self::Output615 fn mul(self, rhs: Vec3) -> Self::Output {
616 self.mul_vec3(rhs)
617 }
618 }
619
620 impl Mul<Mat3> for f32 {
621 type Output = Mat3;
622 #[inline]
mul(self, rhs: Mat3) -> Self::Output623 fn mul(self, rhs: Mat3) -> Self::Output {
624 rhs.mul_scalar(self)
625 }
626 }
627
628 impl Mul<f32> for Mat3 {
629 type Output = Self;
630 #[inline]
mul(self, rhs: f32) -> Self::Output631 fn mul(self, rhs: f32) -> Self::Output {
632 self.mul_scalar(rhs)
633 }
634 }
635
636 impl MulAssign<f32> for Mat3 {
637 #[inline]
mul_assign(&mut self, rhs: f32)638 fn mul_assign(&mut self, rhs: f32) {
639 *self = self.mul_scalar(rhs);
640 }
641 }
642
643 impl Mul<Vec3A> for Mat3 {
644 type Output = Vec3A;
645 #[inline]
mul(self, rhs: Vec3A) -> Vec3A646 fn mul(self, rhs: Vec3A) -> Vec3A {
647 self.mul_vec3a(rhs)
648 }
649 }
650
651 impl From<Mat3A> for Mat3 {
652 #[inline]
from(m: Mat3A) -> Self653 fn from(m: Mat3A) -> Self {
654 Self {
655 x_axis: m.x_axis.into(),
656 y_axis: m.y_axis.into(),
657 z_axis: m.z_axis.into(),
658 }
659 }
660 }
661
662 impl Sum<Self> for Mat3 {
sum<I>(iter: I) -> Self where I: Iterator<Item = Self>,663 fn sum<I>(iter: I) -> Self
664 where
665 I: Iterator<Item = Self>,
666 {
667 iter.fold(Self::ZERO, Self::add)
668 }
669 }
670
671 impl<'a> Sum<&'a Self> for Mat3 {
sum<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,672 fn sum<I>(iter: I) -> Self
673 where
674 I: Iterator<Item = &'a Self>,
675 {
676 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
677 }
678 }
679
680 impl Product for Mat3 {
product<I>(iter: I) -> Self where I: Iterator<Item = Self>,681 fn product<I>(iter: I) -> Self
682 where
683 I: Iterator<Item = Self>,
684 {
685 iter.fold(Self::IDENTITY, Self::mul)
686 }
687 }
688
689 impl<'a> Product<&'a Self> for Mat3 {
product<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,690 fn product<I>(iter: I) -> Self
691 where
692 I: Iterator<Item = &'a Self>,
693 {
694 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
695 }
696 }
697
698 impl PartialEq for Mat3 {
699 #[inline]
eq(&self, rhs: &Self) -> bool700 fn eq(&self, rhs: &Self) -> bool {
701 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
702 }
703 }
704
705 #[cfg(not(target_arch = "spirv"))]
706 impl AsRef<[f32; 9]> for Mat3 {
707 #[inline]
as_ref(&self) -> &[f32; 9]708 fn as_ref(&self) -> &[f32; 9] {
709 unsafe { &*(self as *const Self as *const [f32; 9]) }
710 }
711 }
712
713 #[cfg(not(target_arch = "spirv"))]
714 impl AsMut<[f32; 9]> for Mat3 {
715 #[inline]
as_mut(&mut self) -> &mut [f32; 9]716 fn as_mut(&mut self) -> &mut [f32; 9] {
717 unsafe { &mut *(self as *mut Self as *mut [f32; 9]) }
718 }
719 }
720
721 #[cfg(not(target_arch = "spirv"))]
722 impl fmt::Debug for Mat3 {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result723 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
724 fmt.debug_struct(stringify!(Mat3))
725 .field("x_axis", &self.x_axis)
726 .field("y_axis", &self.y_axis)
727 .field("z_axis", &self.z_axis)
728 .finish()
729 }
730 }
731
732 #[cfg(not(target_arch = "spirv"))]
733 impl fmt::Display for Mat3 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result734 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
735 write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
736 }
737 }
738