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