1 // Generated from mat.rs.tera template. Edit the template, not the generated file.
2
3 use crate::{
4 euler::{FromEuler, ToEuler},
5 f32::math,
6 swizzles::*,
7 DMat3, EulerRot, Mat2, Mat3, Mat4, Quat, Vec2, Vec3, Vec3A,
8 };
9 use core::fmt;
10 use core::iter::{Product, Sum};
11 use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
12
13 /// Creates a 3x3 matrix from three column vectors.
14 #[inline(always)]
15 #[must_use]
mat3a(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Mat3A16 pub const fn mat3a(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Mat3A {
17 Mat3A::from_cols(x_axis, y_axis, z_axis)
18 }
19
20 /// A 3x3 column major matrix.
21 ///
22 /// This 3x3 matrix type features convenience methods for creating and using linear and
23 /// affine transformations. If you are primarily dealing with 2D affine transformations the
24 /// [`Affine2`](crate::Affine2) type is much faster and more space efficient than
25 /// using a 3x3 matrix.
26 ///
27 /// Linear transformations including 3D rotation and scale can be created using methods
28 /// such as [`Self::from_diagonal()`], [`Self::from_quat()`], [`Self::from_axis_angle()`],
29 /// [`Self::from_rotation_x()`], [`Self::from_rotation_y()`], or
30 /// [`Self::from_rotation_z()`].
31 ///
32 /// The resulting matrices can be use to transform 3D vectors using regular vector
33 /// multiplication.
34 ///
35 /// Affine transformations including 2D translation, rotation and scale can be created
36 /// using methods such as [`Self::from_translation()`], [`Self::from_angle()`],
37 /// [`Self::from_scale()`] and [`Self::from_scale_angle_translation()`].
38 ///
39 /// The [`Self::transform_point2()`] and [`Self::transform_vector2()`] convenience methods
40 /// are provided for performing affine transforms on 2D vectors and points. These multiply
41 /// 2D inputs as 3D vectors with an implicit `z` value of `1` for points and `0` for
42 /// vectors respectively. These methods assume that `Self` contains a valid affine
43 /// transform.
44 #[derive(Clone, Copy)]
45 #[repr(C)]
46 pub struct Mat3A {
47 pub x_axis: Vec3A,
48 pub y_axis: Vec3A,
49 pub z_axis: Vec3A,
50 }
51
52 impl Mat3A {
53 /// A 3x3 matrix with all elements set to `0.0`.
54 pub const ZERO: Self = Self::from_cols(Vec3A::ZERO, Vec3A::ZERO, Vec3A::ZERO);
55
56 /// A 3x3 identity matrix, where all diagonal elements are `1`, and all off-diagonal elements are `0`.
57 pub const IDENTITY: Self = Self::from_cols(Vec3A::X, Vec3A::Y, Vec3A::Z);
58
59 /// All NAN:s.
60 pub const NAN: Self = Self::from_cols(Vec3A::NAN, Vec3A::NAN, Vec3A::NAN);
61
62 #[allow(clippy::too_many_arguments)]
63 #[inline(always)]
64 #[must_use]
new( m00: f32, m01: f32, m02: f32, m10: f32, m11: f32, m12: f32, m20: f32, m21: f32, m22: f32, ) -> Self65 const fn new(
66 m00: f32,
67 m01: f32,
68 m02: f32,
69 m10: f32,
70 m11: f32,
71 m12: f32,
72 m20: f32,
73 m21: f32,
74 m22: f32,
75 ) -> Self {
76 Self {
77 x_axis: Vec3A::new(m00, m01, m02),
78 y_axis: Vec3A::new(m10, m11, m12),
79 z_axis: Vec3A::new(m20, m21, m22),
80 }
81 }
82
83 /// Creates a 3x3 matrix from three column vectors.
84 #[inline(always)]
85 #[must_use]
from_cols(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Self86 pub const fn from_cols(x_axis: Vec3A, y_axis: Vec3A, z_axis: Vec3A) -> Self {
87 Self {
88 x_axis,
89 y_axis,
90 z_axis,
91 }
92 }
93
94 /// Creates a 3x3 matrix from a `[f32; 9]` array stored in column major order.
95 /// If your data is stored in row major you will need to `transpose` the returned
96 /// matrix.
97 #[inline]
98 #[must_use]
from_cols_array(m: &[f32; 9]) -> Self99 pub const fn from_cols_array(m: &[f32; 9]) -> Self {
100 Self::new(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8])
101 }
102
103 /// Creates a `[f32; 9]` array storing data in column major order.
104 /// If you require data in row major order `transpose` the matrix first.
105 #[inline]
106 #[must_use]
to_cols_array(&self) -> [f32; 9]107 pub const fn to_cols_array(&self) -> [f32; 9] {
108 [
109 self.x_axis.x,
110 self.x_axis.y,
111 self.x_axis.z,
112 self.y_axis.x,
113 self.y_axis.y,
114 self.y_axis.z,
115 self.z_axis.x,
116 self.z_axis.y,
117 self.z_axis.z,
118 ]
119 }
120
121 /// Creates a 3x3 matrix from a `[[f32; 3]; 3]` 3D array stored in column major order.
122 /// If your data is in row major order you will need to `transpose` the returned
123 /// matrix.
124 #[inline]
125 #[must_use]
from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self126 pub const fn from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self {
127 Self::from_cols(
128 Vec3A::from_array(m[0]),
129 Vec3A::from_array(m[1]),
130 Vec3A::from_array(m[2]),
131 )
132 }
133
134 /// Creates a `[[f32; 3]; 3]` 3D array storing data in column major order.
135 /// If you require data in row major order `transpose` the matrix first.
136 #[inline]
137 #[must_use]
to_cols_array_2d(&self) -> [[f32; 3]; 3]138 pub const fn to_cols_array_2d(&self) -> [[f32; 3]; 3] {
139 [
140 self.x_axis.to_array(),
141 self.y_axis.to_array(),
142 self.z_axis.to_array(),
143 ]
144 }
145
146 /// Creates a 3x3 matrix with its diagonal set to `diagonal` and all other entries set to 0.
147 #[doc(alias = "scale")]
148 #[inline]
149 #[must_use]
from_diagonal(diagonal: Vec3) -> Self150 pub const fn from_diagonal(diagonal: Vec3) -> Self {
151 Self::new(
152 diagonal.x, 0.0, 0.0, 0.0, diagonal.y, 0.0, 0.0, 0.0, diagonal.z,
153 )
154 }
155
156 /// Creates a 3x3 matrix from a 4x4 matrix, discarding the 4th row and column.
157 #[inline]
158 #[must_use]
from_mat4(m: Mat4) -> Self159 pub fn from_mat4(m: Mat4) -> Self {
160 Self::from_cols(
161 Vec3A::from_vec4(m.x_axis),
162 Vec3A::from_vec4(m.y_axis),
163 Vec3A::from_vec4(m.z_axis),
164 )
165 }
166
167 /// Creates a 3x3 matrix from the minor of the given 4x4 matrix, discarding the `i`th column
168 /// and `j`th row.
169 ///
170 /// # Panics
171 ///
172 /// Panics if `i` or `j` is greater than 3.
173 #[inline]
174 #[must_use]
from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self175 pub fn from_mat4_minor(m: Mat4, i: usize, j: usize) -> Self {
176 match (i, j) {
177 (0, 0) => Self::from_cols(
178 Vec3A::from_vec4(m.y_axis.yzww()),
179 Vec3A::from_vec4(m.z_axis.yzww()),
180 Vec3A::from_vec4(m.w_axis.yzww()),
181 ),
182 (0, 1) => Self::from_cols(
183 Vec3A::from_vec4(m.y_axis.xzww()),
184 Vec3A::from_vec4(m.z_axis.xzww()),
185 Vec3A::from_vec4(m.w_axis.xzww()),
186 ),
187 (0, 2) => Self::from_cols(
188 Vec3A::from_vec4(m.y_axis.xyww()),
189 Vec3A::from_vec4(m.z_axis.xyww()),
190 Vec3A::from_vec4(m.w_axis.xyww()),
191 ),
192 (0, 3) => Self::from_cols(
193 Vec3A::from_vec4(m.y_axis.xyzw()),
194 Vec3A::from_vec4(m.z_axis.xyzw()),
195 Vec3A::from_vec4(m.w_axis.xyzw()),
196 ),
197 (1, 0) => Self::from_cols(
198 Vec3A::from_vec4(m.x_axis.yzww()),
199 Vec3A::from_vec4(m.z_axis.yzww()),
200 Vec3A::from_vec4(m.w_axis.yzww()),
201 ),
202 (1, 1) => Self::from_cols(
203 Vec3A::from_vec4(m.x_axis.xzww()),
204 Vec3A::from_vec4(m.z_axis.xzww()),
205 Vec3A::from_vec4(m.w_axis.xzww()),
206 ),
207 (1, 2) => Self::from_cols(
208 Vec3A::from_vec4(m.x_axis.xyww()),
209 Vec3A::from_vec4(m.z_axis.xyww()),
210 Vec3A::from_vec4(m.w_axis.xyww()),
211 ),
212 (1, 3) => Self::from_cols(
213 Vec3A::from_vec4(m.x_axis.xyzw()),
214 Vec3A::from_vec4(m.z_axis.xyzw()),
215 Vec3A::from_vec4(m.w_axis.xyzw()),
216 ),
217 (2, 0) => Self::from_cols(
218 Vec3A::from_vec4(m.x_axis.yzww()),
219 Vec3A::from_vec4(m.y_axis.yzww()),
220 Vec3A::from_vec4(m.w_axis.yzww()),
221 ),
222 (2, 1) => Self::from_cols(
223 Vec3A::from_vec4(m.x_axis.xzww()),
224 Vec3A::from_vec4(m.y_axis.xzww()),
225 Vec3A::from_vec4(m.w_axis.xzww()),
226 ),
227 (2, 2) => Self::from_cols(
228 Vec3A::from_vec4(m.x_axis.xyww()),
229 Vec3A::from_vec4(m.y_axis.xyww()),
230 Vec3A::from_vec4(m.w_axis.xyww()),
231 ),
232 (2, 3) => Self::from_cols(
233 Vec3A::from_vec4(m.x_axis.xyzw()),
234 Vec3A::from_vec4(m.y_axis.xyzw()),
235 Vec3A::from_vec4(m.w_axis.xyzw()),
236 ),
237 (3, 0) => Self::from_cols(
238 Vec3A::from_vec4(m.x_axis.yzww()),
239 Vec3A::from_vec4(m.y_axis.yzww()),
240 Vec3A::from_vec4(m.z_axis.yzww()),
241 ),
242 (3, 1) => Self::from_cols(
243 Vec3A::from_vec4(m.x_axis.xzww()),
244 Vec3A::from_vec4(m.y_axis.xzww()),
245 Vec3A::from_vec4(m.z_axis.xzww()),
246 ),
247 (3, 2) => Self::from_cols(
248 Vec3A::from_vec4(m.x_axis.xyww()),
249 Vec3A::from_vec4(m.y_axis.xyww()),
250 Vec3A::from_vec4(m.z_axis.xyww()),
251 ),
252 (3, 3) => Self::from_cols(
253 Vec3A::from_vec4(m.x_axis.xyzw()),
254 Vec3A::from_vec4(m.y_axis.xyzw()),
255 Vec3A::from_vec4(m.z_axis.xyzw()),
256 ),
257 _ => panic!("index out of bounds"),
258 }
259 }
260
261 /// Creates a 3D rotation matrix from the given quaternion.
262 ///
263 /// # Panics
264 ///
265 /// Will panic if `rotation` is not normalized when `glam_assert` is enabled.
266 #[inline]
267 #[must_use]
from_quat(rotation: Quat) -> Self268 pub fn from_quat(rotation: Quat) -> Self {
269 glam_assert!(rotation.is_normalized());
270
271 let x2 = rotation.x + rotation.x;
272 let y2 = rotation.y + rotation.y;
273 let z2 = rotation.z + rotation.z;
274 let xx = rotation.x * x2;
275 let xy = rotation.x * y2;
276 let xz = rotation.x * z2;
277 let yy = rotation.y * y2;
278 let yz = rotation.y * z2;
279 let zz = rotation.z * z2;
280 let wx = rotation.w * x2;
281 let wy = rotation.w * y2;
282 let wz = rotation.w * z2;
283
284 Self::from_cols(
285 Vec3A::new(1.0 - (yy + zz), xy + wz, xz - wy),
286 Vec3A::new(xy - wz, 1.0 - (xx + zz), yz + wx),
287 Vec3A::new(xz + wy, yz - wx, 1.0 - (xx + yy)),
288 )
289 }
290
291 /// Creates a 3D rotation matrix from a normalized rotation `axis` and `angle` (in
292 /// radians).
293 ///
294 /// # Panics
295 ///
296 /// Will panic if `axis` is not normalized when `glam_assert` is enabled.
297 #[inline]
298 #[must_use]
from_axis_angle(axis: Vec3, angle: f32) -> Self299 pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
300 glam_assert!(axis.is_normalized());
301
302 let (sin, cos) = math::sin_cos(angle);
303 let (xsin, ysin, zsin) = axis.mul(sin).into();
304 let (x, y, z) = axis.into();
305 let (x2, y2, z2) = axis.mul(axis).into();
306 let omc = 1.0 - cos;
307 let xyomc = x * y * omc;
308 let xzomc = x * z * omc;
309 let yzomc = y * z * omc;
310 Self::from_cols(
311 Vec3A::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
312 Vec3A::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
313 Vec3A::new(xzomc + ysin, yzomc - xsin, z2 * omc + cos),
314 )
315 }
316
317 /// Creates a 3D rotation matrix from the given euler rotation sequence and the angles (in
318 /// radians).
319 #[inline]
320 #[must_use]
from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self321 pub fn from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self {
322 Self::from_euler_angles(order, a, b, c)
323 }
324
325 /// Extract Euler angles with the given Euler rotation order.
326 ///
327 /// Note if the input matrix contains scales, shears, or other non-rotation transformations then
328 /// the resulting Euler angles will be ill-defined.
329 ///
330 /// # Panics
331 ///
332 /// Will panic if any input matrix column is not normalized when `glam_assert` is enabled.
333 #[inline]
334 #[must_use]
to_euler(&self, order: EulerRot) -> (f32, f32, f32)335 pub fn to_euler(&self, order: EulerRot) -> (f32, f32, f32) {
336 glam_assert!(
337 self.x_axis.is_normalized()
338 && self.y_axis.is_normalized()
339 && self.z_axis.is_normalized()
340 );
341 self.to_euler_angles(order)
342 }
343
344 /// Creates a 3D rotation matrix from `angle` (in radians) around the x axis.
345 #[inline]
346 #[must_use]
from_rotation_x(angle: f32) -> Self347 pub fn from_rotation_x(angle: f32) -> Self {
348 let (sina, cosa) = math::sin_cos(angle);
349 Self::from_cols(
350 Vec3A::X,
351 Vec3A::new(0.0, cosa, sina),
352 Vec3A::new(0.0, -sina, cosa),
353 )
354 }
355
356 /// Creates a 3D rotation matrix from `angle` (in radians) around the y axis.
357 #[inline]
358 #[must_use]
from_rotation_y(angle: f32) -> Self359 pub fn from_rotation_y(angle: f32) -> Self {
360 let (sina, cosa) = math::sin_cos(angle);
361 Self::from_cols(
362 Vec3A::new(cosa, 0.0, -sina),
363 Vec3A::Y,
364 Vec3A::new(sina, 0.0, cosa),
365 )
366 }
367
368 /// Creates a 3D rotation matrix from `angle` (in radians) around the z axis.
369 #[inline]
370 #[must_use]
from_rotation_z(angle: f32) -> Self371 pub fn from_rotation_z(angle: f32) -> Self {
372 let (sina, cosa) = math::sin_cos(angle);
373 Self::from_cols(
374 Vec3A::new(cosa, sina, 0.0),
375 Vec3A::new(-sina, cosa, 0.0),
376 Vec3A::Z,
377 )
378 }
379
380 /// Creates an affine transformation matrix from the given 2D `translation`.
381 ///
382 /// The resulting matrix can be used to transform 2D points and vectors. See
383 /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
384 #[inline]
385 #[must_use]
from_translation(translation: Vec2) -> Self386 pub fn from_translation(translation: Vec2) -> Self {
387 Self::from_cols(
388 Vec3A::X,
389 Vec3A::Y,
390 Vec3A::new(translation.x, translation.y, 1.0),
391 )
392 }
393
394 /// Creates an affine transformation matrix from the given 2D rotation `angle` (in
395 /// radians).
396 ///
397 /// The resulting matrix can be used to transform 2D points and vectors. See
398 /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
399 #[inline]
400 #[must_use]
from_angle(angle: f32) -> Self401 pub fn from_angle(angle: f32) -> Self {
402 let (sin, cos) = math::sin_cos(angle);
403 Self::from_cols(
404 Vec3A::new(cos, sin, 0.0),
405 Vec3A::new(-sin, cos, 0.0),
406 Vec3A::Z,
407 )
408 }
409
410 /// Creates an affine transformation matrix from the given 2D `scale`, rotation `angle` (in
411 /// radians) and `translation`.
412 ///
413 /// The resulting matrix can be used to transform 2D points and vectors. See
414 /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
415 #[inline]
416 #[must_use]
from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self417 pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
418 let (sin, cos) = math::sin_cos(angle);
419 Self::from_cols(
420 Vec3A::new(cos * scale.x, sin * scale.x, 0.0),
421 Vec3A::new(-sin * scale.y, cos * scale.y, 0.0),
422 Vec3A::new(translation.x, translation.y, 1.0),
423 )
424 }
425
426 /// Creates an affine transformation matrix from the given non-uniform 2D `scale`.
427 ///
428 /// The resulting matrix can be used to transform 2D points and vectors. See
429 /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
430 ///
431 /// # Panics
432 ///
433 /// Will panic if all elements of `scale` are zero when `glam_assert` is enabled.
434 #[inline]
435 #[must_use]
from_scale(scale: Vec2) -> Self436 pub fn from_scale(scale: Vec2) -> Self {
437 // Do not panic as long as any component is non-zero
438 glam_assert!(scale.cmpne(Vec2::ZERO).any());
439
440 Self::from_cols(
441 Vec3A::new(scale.x, 0.0, 0.0),
442 Vec3A::new(0.0, scale.y, 0.0),
443 Vec3A::Z,
444 )
445 }
446
447 /// Creates an affine transformation matrix from the given 2x2 matrix.
448 ///
449 /// The resulting matrix can be used to transform 2D points and vectors. See
450 /// [`Self::transform_point2()`] and [`Self::transform_vector2()`].
451 #[inline]
from_mat2(m: Mat2) -> Self452 pub fn from_mat2(m: Mat2) -> Self {
453 Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), Vec3A::Z)
454 }
455
456 /// Creates a 3x3 matrix from the first 9 values in `slice`.
457 ///
458 /// # Panics
459 ///
460 /// Panics if `slice` is less than 9 elements long.
461 #[inline]
462 #[must_use]
from_cols_slice(slice: &[f32]) -> Self463 pub const fn from_cols_slice(slice: &[f32]) -> Self {
464 Self::new(
465 slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
466 slice[8],
467 )
468 }
469
470 /// Writes the columns of `self` to the first 9 elements in `slice`.
471 ///
472 /// # Panics
473 ///
474 /// Panics if `slice` is less than 9 elements long.
475 #[inline]
write_cols_to_slice(self, slice: &mut [f32])476 pub fn write_cols_to_slice(self, slice: &mut [f32]) {
477 slice[0] = self.x_axis.x;
478 slice[1] = self.x_axis.y;
479 slice[2] = self.x_axis.z;
480 slice[3] = self.y_axis.x;
481 slice[4] = self.y_axis.y;
482 slice[5] = self.y_axis.z;
483 slice[6] = self.z_axis.x;
484 slice[7] = self.z_axis.y;
485 slice[8] = self.z_axis.z;
486 }
487
488 /// Returns the matrix column for the given `index`.
489 ///
490 /// # Panics
491 ///
492 /// Panics if `index` is greater than 2.
493 #[inline]
494 #[must_use]
col(&self, index: usize) -> Vec3A495 pub fn col(&self, index: usize) -> Vec3A {
496 match index {
497 0 => self.x_axis,
498 1 => self.y_axis,
499 2 => self.z_axis,
500 _ => panic!("index out of bounds"),
501 }
502 }
503
504 /// Returns a mutable reference to the matrix column for the given `index`.
505 ///
506 /// # Panics
507 ///
508 /// Panics if `index` is greater than 2.
509 #[inline]
col_mut(&mut self, index: usize) -> &mut Vec3A510 pub fn col_mut(&mut self, index: usize) -> &mut Vec3A {
511 match index {
512 0 => &mut self.x_axis,
513 1 => &mut self.y_axis,
514 2 => &mut self.z_axis,
515 _ => panic!("index out of bounds"),
516 }
517 }
518
519 /// Returns the matrix row for the given `index`.
520 ///
521 /// # Panics
522 ///
523 /// Panics if `index` is greater than 2.
524 #[inline]
525 #[must_use]
row(&self, index: usize) -> Vec3A526 pub fn row(&self, index: usize) -> Vec3A {
527 match index {
528 0 => Vec3A::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
529 1 => Vec3A::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
530 2 => Vec3A::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
531 _ => panic!("index out of bounds"),
532 }
533 }
534
535 /// Returns `true` if, and only if, all elements are finite.
536 /// If any element is either `NaN`, positive or negative infinity, this will return `false`.
537 #[inline]
538 #[must_use]
is_finite(&self) -> bool539 pub fn is_finite(&self) -> bool {
540 self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
541 }
542
543 /// Returns `true` if any elements are `NaN`.
544 #[inline]
545 #[must_use]
is_nan(&self) -> bool546 pub fn is_nan(&self) -> bool {
547 self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
548 }
549
550 /// Returns the transpose of `self`.
551 #[inline]
552 #[must_use]
transpose(&self) -> Self553 pub fn transpose(&self) -> Self {
554 Self {
555 x_axis: Vec3A::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
556 y_axis: Vec3A::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
557 z_axis: Vec3A::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
558 }
559 }
560
561 /// Returns the determinant of `self`.
562 #[inline]
563 #[must_use]
determinant(&self) -> f32564 pub fn determinant(&self) -> f32 {
565 self.z_axis.dot(self.x_axis.cross(self.y_axis))
566 }
567
568 /// Returns the inverse of `self`.
569 ///
570 /// If the matrix is not invertible the returned matrix will be invalid.
571 ///
572 /// # Panics
573 ///
574 /// Will panic if the determinant of `self` is zero when `glam_assert` is enabled.
575 #[inline]
576 #[must_use]
inverse(&self) -> Self577 pub fn inverse(&self) -> Self {
578 let tmp0 = self.y_axis.cross(self.z_axis);
579 let tmp1 = self.z_axis.cross(self.x_axis);
580 let tmp2 = self.x_axis.cross(self.y_axis);
581 let det = self.z_axis.dot(tmp2);
582 glam_assert!(det != 0.0);
583 let inv_det = Vec3A::splat(det.recip());
584 Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose()
585 }
586
587 /// Transforms the given 2D vector as a point.
588 ///
589 /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `1`.
590 ///
591 /// This method assumes that `self` contains a valid affine transform.
592 ///
593 /// # Panics
594 ///
595 /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
596 #[inline]
597 #[must_use]
transform_point2(&self, rhs: Vec2) -> Vec2598 pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
599 glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
600 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
601 }
602
603 /// Rotates the given 2D vector.
604 ///
605 /// This is the equivalent of multiplying `rhs` as a 3D vector where `z` is `0`.
606 ///
607 /// This method assumes that `self` contains a valid affine transform.
608 ///
609 /// # Panics
610 ///
611 /// Will panic if the 2nd row of `self` is not `(0, 0, 1)` when `glam_assert` is enabled.
612 #[inline]
613 #[must_use]
transform_vector2(&self, rhs: Vec2) -> Vec2614 pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
615 glam_assert!(self.row(2).abs_diff_eq(Vec3A::Z, 1e-6));
616 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
617 }
618
619 /// Creates a left-handed view matrix using a facing direction and an up direction.
620 ///
621 /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`.
622 ///
623 /// # Panics
624 ///
625 /// Will panic if `dir` or `up` are not normalized when `glam_assert` is enabled.
626 #[inline]
627 #[must_use]
look_to_lh(dir: Vec3, up: Vec3) -> Self628 pub fn look_to_lh(dir: Vec3, up: Vec3) -> Self {
629 Self::look_to_rh(-dir, up)
630 }
631
632 /// Creates a right-handed view matrix using a facing direction and an up direction.
633 ///
634 /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`.
635 ///
636 /// # Panics
637 ///
638 /// Will panic if `dir` or `up` are not normalized when `glam_assert` is enabled.
639 #[inline]
640 #[must_use]
look_to_rh(dir: Vec3, up: Vec3) -> Self641 pub fn look_to_rh(dir: Vec3, up: Vec3) -> Self {
642 glam_assert!(dir.is_normalized());
643 glam_assert!(up.is_normalized());
644 let f = dir;
645 let s = f.cross(up).normalize();
646 let u = s.cross(f);
647
648 Self::from_cols(
649 Vec3A::new(s.x, u.x, -f.x),
650 Vec3A::new(s.y, u.y, -f.y),
651 Vec3A::new(s.z, u.z, -f.z),
652 )
653 }
654
655 /// Creates a left-handed view matrix using a camera position, a focal point and an up
656 /// direction.
657 ///
658 /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=forward`.
659 ///
660 /// # Panics
661 ///
662 /// Will panic if `up` is not normalized when `glam_assert` is enabled.
663 #[inline]
664 #[must_use]
look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self665 pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
666 Self::look_to_lh(center.sub(eye).normalize(), up)
667 }
668
669 /// Creates a right-handed view matrix using a camera position, a focal point and an up
670 /// direction.
671 ///
672 /// For a view coordinate system with `+X=right`, `+Y=up` and `+Z=back`.
673 ///
674 /// # Panics
675 ///
676 /// Will panic if `up` is not normalized when `glam_assert` is enabled.
677 #[inline]
look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self678 pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
679 Self::look_to_rh(center.sub(eye).normalize(), up)
680 }
681
682 /// Transforms a 3D vector.
683 #[inline]
684 #[must_use]
mul_vec3(&self, rhs: Vec3) -> Vec3685 pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
686 self.mul_vec3a(rhs.into()).into()
687 }
688
689 /// Transforms a [`Vec3A`].
690 #[inline]
691 #[must_use]
mul_vec3a(&self, rhs: Vec3A) -> Vec3A692 pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
693 let mut res = self.x_axis.mul(rhs.xxx());
694 res = res.add(self.y_axis.mul(rhs.yyy()));
695 res = res.add(self.z_axis.mul(rhs.zzz()));
696 res
697 }
698
699 /// Multiplies two 3x3 matrices.
700 #[inline]
701 #[must_use]
mul_mat3(&self, rhs: &Self) -> Self702 pub fn mul_mat3(&self, rhs: &Self) -> Self {
703 Self::from_cols(
704 self.mul(rhs.x_axis),
705 self.mul(rhs.y_axis),
706 self.mul(rhs.z_axis),
707 )
708 }
709
710 /// Adds two 3x3 matrices.
711 #[inline]
712 #[must_use]
add_mat3(&self, rhs: &Self) -> Self713 pub fn add_mat3(&self, rhs: &Self) -> Self {
714 Self::from_cols(
715 self.x_axis.add(rhs.x_axis),
716 self.y_axis.add(rhs.y_axis),
717 self.z_axis.add(rhs.z_axis),
718 )
719 }
720
721 /// Subtracts two 3x3 matrices.
722 #[inline]
723 #[must_use]
sub_mat3(&self, rhs: &Self) -> Self724 pub fn sub_mat3(&self, rhs: &Self) -> Self {
725 Self::from_cols(
726 self.x_axis.sub(rhs.x_axis),
727 self.y_axis.sub(rhs.y_axis),
728 self.z_axis.sub(rhs.z_axis),
729 )
730 }
731
732 /// Multiplies a 3x3 matrix by a scalar.
733 #[inline]
734 #[must_use]
mul_scalar(&self, rhs: f32) -> Self735 pub fn mul_scalar(&self, rhs: f32) -> Self {
736 Self::from_cols(
737 self.x_axis.mul(rhs),
738 self.y_axis.mul(rhs),
739 self.z_axis.mul(rhs),
740 )
741 }
742
743 /// Divides a 3x3 matrix by a scalar.
744 #[inline]
745 #[must_use]
div_scalar(&self, rhs: f32) -> Self746 pub fn div_scalar(&self, rhs: f32) -> Self {
747 let rhs = Vec3A::splat(rhs);
748 Self::from_cols(
749 self.x_axis.div(rhs),
750 self.y_axis.div(rhs),
751 self.z_axis.div(rhs),
752 )
753 }
754
755 /// Returns true if the absolute difference of all elements between `self` and `rhs`
756 /// is less than or equal to `max_abs_diff`.
757 ///
758 /// This can be used to compare if two matrices contain similar elements. It works best
759 /// when comparing with a known value. The `max_abs_diff` that should be used used
760 /// depends on the values being compared against.
761 ///
762 /// For more see
763 /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
764 #[inline]
765 #[must_use]
abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool766 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
767 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
768 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
769 && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
770 }
771
772 /// Takes the absolute value of each element in `self`
773 #[inline]
774 #[must_use]
abs(&self) -> Self775 pub fn abs(&self) -> Self {
776 Self::from_cols(self.x_axis.abs(), self.y_axis.abs(), self.z_axis.abs())
777 }
778
779 #[inline]
as_dmat3(&self) -> DMat3780 pub fn as_dmat3(&self) -> DMat3 {
781 DMat3::from_cols(
782 self.x_axis.as_dvec3(),
783 self.y_axis.as_dvec3(),
784 self.z_axis.as_dvec3(),
785 )
786 }
787 }
788
789 impl Default for Mat3A {
790 #[inline]
default() -> Self791 fn default() -> Self {
792 Self::IDENTITY
793 }
794 }
795
796 impl Add<Mat3A> for Mat3A {
797 type Output = Self;
798 #[inline]
add(self, rhs: Self) -> Self::Output799 fn add(self, rhs: Self) -> Self::Output {
800 self.add_mat3(&rhs)
801 }
802 }
803
804 impl AddAssign<Mat3A> for Mat3A {
805 #[inline]
add_assign(&mut self, rhs: Self)806 fn add_assign(&mut self, rhs: Self) {
807 *self = self.add_mat3(&rhs);
808 }
809 }
810
811 impl Sub<Mat3A> for Mat3A {
812 type Output = Self;
813 #[inline]
sub(self, rhs: Self) -> Self::Output814 fn sub(self, rhs: Self) -> Self::Output {
815 self.sub_mat3(&rhs)
816 }
817 }
818
819 impl SubAssign<Mat3A> for Mat3A {
820 #[inline]
sub_assign(&mut self, rhs: Self)821 fn sub_assign(&mut self, rhs: Self) {
822 *self = self.sub_mat3(&rhs);
823 }
824 }
825
826 impl Neg for Mat3A {
827 type Output = Self;
828 #[inline]
neg(self) -> Self::Output829 fn neg(self) -> Self::Output {
830 Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
831 }
832 }
833
834 impl Mul<Mat3A> for Mat3A {
835 type Output = Self;
836 #[inline]
mul(self, rhs: Self) -> Self::Output837 fn mul(self, rhs: Self) -> Self::Output {
838 self.mul_mat3(&rhs)
839 }
840 }
841
842 impl MulAssign<Mat3A> for Mat3A {
843 #[inline]
mul_assign(&mut self, rhs: Self)844 fn mul_assign(&mut self, rhs: Self) {
845 *self = self.mul_mat3(&rhs);
846 }
847 }
848
849 impl Mul<Vec3A> for Mat3A {
850 type Output = Vec3A;
851 #[inline]
mul(self, rhs: Vec3A) -> Self::Output852 fn mul(self, rhs: Vec3A) -> Self::Output {
853 self.mul_vec3a(rhs)
854 }
855 }
856
857 impl Mul<Mat3A> for f32 {
858 type Output = Mat3A;
859 #[inline]
mul(self, rhs: Mat3A) -> Self::Output860 fn mul(self, rhs: Mat3A) -> Self::Output {
861 rhs.mul_scalar(self)
862 }
863 }
864
865 impl Mul<f32> for Mat3A {
866 type Output = Self;
867 #[inline]
mul(self, rhs: f32) -> Self::Output868 fn mul(self, rhs: f32) -> Self::Output {
869 self.mul_scalar(rhs)
870 }
871 }
872
873 impl MulAssign<f32> for Mat3A {
874 #[inline]
mul_assign(&mut self, rhs: f32)875 fn mul_assign(&mut self, rhs: f32) {
876 *self = self.mul_scalar(rhs);
877 }
878 }
879
880 impl Div<Mat3A> for f32 {
881 type Output = Mat3A;
882 #[inline]
div(self, rhs: Mat3A) -> Self::Output883 fn div(self, rhs: Mat3A) -> Self::Output {
884 rhs.div_scalar(self)
885 }
886 }
887
888 impl Div<f32> for Mat3A {
889 type Output = Self;
890 #[inline]
div(self, rhs: f32) -> Self::Output891 fn div(self, rhs: f32) -> Self::Output {
892 self.div_scalar(rhs)
893 }
894 }
895
896 impl DivAssign<f32> for Mat3A {
897 #[inline]
div_assign(&mut self, rhs: f32)898 fn div_assign(&mut self, rhs: f32) {
899 *self = self.div_scalar(rhs);
900 }
901 }
902
903 impl Mul<Vec3> for Mat3A {
904 type Output = Vec3;
905 #[inline]
mul(self, rhs: Vec3) -> Vec3906 fn mul(self, rhs: Vec3) -> Vec3 {
907 self.mul_vec3a(rhs.into()).into()
908 }
909 }
910
911 impl From<Mat3> for Mat3A {
912 #[inline]
from(m: Mat3) -> Self913 fn from(m: Mat3) -> Self {
914 Self {
915 x_axis: m.x_axis.into(),
916 y_axis: m.y_axis.into(),
917 z_axis: m.z_axis.into(),
918 }
919 }
920 }
921
922 impl Sum<Self> for Mat3A {
sum<I>(iter: I) -> Self where I: Iterator<Item = Self>,923 fn sum<I>(iter: I) -> Self
924 where
925 I: Iterator<Item = Self>,
926 {
927 iter.fold(Self::ZERO, Self::add)
928 }
929 }
930
931 impl<'a> Sum<&'a Self> for Mat3A {
sum<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,932 fn sum<I>(iter: I) -> Self
933 where
934 I: Iterator<Item = &'a Self>,
935 {
936 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
937 }
938 }
939
940 impl Product for Mat3A {
product<I>(iter: I) -> Self where I: Iterator<Item = Self>,941 fn product<I>(iter: I) -> Self
942 where
943 I: Iterator<Item = Self>,
944 {
945 iter.fold(Self::IDENTITY, Self::mul)
946 }
947 }
948
949 impl<'a> Product<&'a Self> for Mat3A {
product<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,950 fn product<I>(iter: I) -> Self
951 where
952 I: Iterator<Item = &'a Self>,
953 {
954 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
955 }
956 }
957
958 impl PartialEq for Mat3A {
959 #[inline]
eq(&self, rhs: &Self) -> bool960 fn eq(&self, rhs: &Self) -> bool {
961 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
962 }
963 }
964
965 impl fmt::Debug for Mat3A {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result966 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
967 fmt.debug_struct(stringify!(Mat3A))
968 .field("x_axis", &self.x_axis)
969 .field("y_axis", &self.y_axis)
970 .field("z_axis", &self.z_axis)
971 .finish()
972 }
973 }
974
975 impl fmt::Display for Mat3A {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result976 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
977 if let Some(p) = f.precision() {
978 write!(
979 f,
980 "[{:.*}, {:.*}, {:.*}]",
981 p, self.x_axis, p, self.y_axis, p, self.z_axis
982 )
983 } else {
984 write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
985 }
986 }
987 }
988