1#[cfg(feature = "f64")]
4use crate::DMat4;
5
6use crate::{
7 EulerRot, Mat3, Mat3A, Quat, Vec3, Vec3A, Vec4,
8 euler::{FromEuler, ToEuler},
9 f32::math,
10 sse2::*,
11 swizzles::*,
12};
13use core::fmt;
14use core::iter::{Product, Sum};
15use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
16
17#[cfg(target_arch = "x86")]
18use core::arch::x86::*;
19#[cfg(target_arch = "x86_64")]
20use core::arch::x86_64::*;
21
22#[cfg(feature = "zerocopy-08")]
23use zerocopy_derive_08::*;
24
25#[inline(always)]
27#[must_use]
28pub const fn mat4(x_axis: Vec4, y_axis: Vec4, z_axis: Vec4, w_axis: Vec4) -> Mat4 {
29 Mat4::from_cols(x_axis, y_axis, z_axis, w_axis)
30}
31
32#[derive(Clone, Copy)]
52#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
53#[cfg_attr(
54 feature = "zerocopy-08",
55 derive(FromBytes, Immutable, IntoBytes, KnownLayout)
56)]
57#[repr(C)]
58pub struct Mat4 {
59 pub x_axis: Vec4,
60 pub y_axis: Vec4,
61 pub z_axis: Vec4,
62 pub w_axis: Vec4,
63}
64
65impl Mat4 {
66 pub const ZERO: Self = Self::from_cols(Vec4::ZERO, Vec4::ZERO, Vec4::ZERO, Vec4::ZERO);
68
69 pub const IDENTITY: Self = Self::from_cols(Vec4::X, Vec4::Y, Vec4::Z, Vec4::W);
71
72 pub const NAN: Self = Self::from_cols(Vec4::NAN, Vec4::NAN, Vec4::NAN, Vec4::NAN);
74
75 #[allow(clippy::too_many_arguments)]
76 #[inline(always)]
77 #[must_use]
78 const fn new(
79 m00: f32,
80 m01: f32,
81 m02: f32,
82 m03: f32,
83 m10: f32,
84 m11: f32,
85 m12: f32,
86 m13: f32,
87 m20: f32,
88 m21: f32,
89 m22: f32,
90 m23: f32,
91 m30: f32,
92 m31: f32,
93 m32: f32,
94 m33: f32,
95 ) -> Self {
96 Self {
97 x_axis: Vec4::new(m00, m01, m02, m03),
98 y_axis: Vec4::new(m10, m11, m12, m13),
99 z_axis: Vec4::new(m20, m21, m22, m23),
100 w_axis: Vec4::new(m30, m31, m32, m33),
101 }
102 }
103
104 #[inline(always)]
108 #[must_use]
109 pub const fn from_cols(x_axis: Vec4, y_axis: Vec4, z_axis: Vec4, w_axis: Vec4) -> Self {
110 Self {
111 x_axis,
112 y_axis,
113 z_axis,
114 w_axis,
115 }
116 }
117
118 #[inline(always)]
124 #[must_use]
125 pub const fn from_rows(row0: Vec4, row1: Vec4, row2: Vec4, row3: Vec4) -> Self {
126 let [m00, m01, m02, m03] = row0.to_array();
127 let [m10, m11, m12, m13] = row1.to_array();
128 let [m20, m21, m22, m23] = row2.to_array();
129 let [m30, m31, m32, m33] = row3.to_array();
130 Self::new(
131 m00, m10, m20, m30, m01, m11, m21, m31, m02, m12, m22, m32, m03, m13, m23, m33,
132 )
133 }
134
135 #[inline]
139 #[must_use]
140 pub const fn from_cols_array(m: &[f32; 16]) -> Self {
141 Self::new(
142 m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11], m[12], m[13],
143 m[14], m[15],
144 )
145 }
146
147 #[inline]
151 #[must_use]
152 pub const fn to_cols_array(&self) -> [f32; 16] {
153 let [x_axis_x, x_axis_y, x_axis_z, x_axis_w] = self.x_axis.to_array();
154 let [y_axis_x, y_axis_y, y_axis_z, y_axis_w] = self.y_axis.to_array();
155 let [z_axis_x, z_axis_y, z_axis_z, z_axis_w] = self.z_axis.to_array();
156 let [w_axis_x, w_axis_y, w_axis_z, w_axis_w] = self.w_axis.to_array();
157
158 [
159 x_axis_x, x_axis_y, x_axis_z, x_axis_w, y_axis_x, y_axis_y, y_axis_z, y_axis_w,
160 z_axis_x, z_axis_y, z_axis_z, z_axis_w, w_axis_x, w_axis_y, w_axis_z, w_axis_w,
161 ]
162 }
163
164 #[inline]
168 #[must_use]
169 pub const fn from_cols_array_2d(m: &[[f32; 4]; 4]) -> Self {
170 Self::from_cols(
171 Vec4::from_array(m[0]),
172 Vec4::from_array(m[1]),
173 Vec4::from_array(m[2]),
174 Vec4::from_array(m[3]),
175 )
176 }
177
178 #[inline]
182 #[must_use]
183 pub const fn to_cols_array_2d(&self) -> [[f32; 4]; 4] {
184 [
185 self.x_axis.to_array(),
186 self.y_axis.to_array(),
187 self.z_axis.to_array(),
188 self.w_axis.to_array(),
189 ]
190 }
191
192 #[inline]
198 #[must_use]
199 pub const fn from_rows_array(m: &[f32; 16]) -> Self {
200 Self::new(
201 m[0], m[4], m[8], m[12], m[1], m[5], m[9], m[13], m[2], m[6], m[10], m[14], m[3], m[7],
202 m[11], m[15],
203 )
204 }
205
206 #[inline]
212 #[must_use]
213 pub const fn to_rows_array(&self) -> [f32; 16] {
214 let m = self.to_cols_array();
215 [
216 m[0], m[4], m[8], m[12], m[1], m[5], m[9], m[13], m[2], m[6], m[10], m[14], m[3], m[7],
217 m[11], m[15],
218 ]
219 }
220
221 #[doc(alias = "scale")]
223 #[inline]
224 #[must_use]
225 pub const fn from_diagonal(diagonal: Vec4) -> Self {
226 let [x, y, z, w] = diagonal.to_array();
228 Self::new(
229 x, 0.0, 0.0, 0.0, 0.0, y, 0.0, 0.0, 0.0, 0.0, z, 0.0, 0.0, 0.0, 0.0, w,
230 )
231 }
232
233 #[inline]
234 #[must_use]
235 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
236 fn quat_to_axes(rotation: Quat) -> (Vec4, Vec4, Vec4) {
237 glam_assert!(rotation.is_normalized());
238
239 let (x, y, z, w) = rotation.into();
240 let x2 = x + x;
241 let y2 = y + y;
242 let z2 = z + z;
243 let xx = x * x2;
244 let xy = x * y2;
245 let xz = x * z2;
246 let yy = y * y2;
247 let yz = y * z2;
248 let zz = z * z2;
249 let wx = w * x2;
250 let wy = w * y2;
251 let wz = w * z2;
252
253 let x_axis = Vec4::new(1.0 - (yy + zz), xy + wz, xz - wy, 0.0);
254 let y_axis = Vec4::new(xy - wz, 1.0 - (xx + zz), yz + wx, 0.0);
255 let z_axis = Vec4::new(xz + wy, yz - wx, 1.0 - (xx + yy), 0.0);
256 (x_axis, y_axis, z_axis)
257 }
258
259 #[inline]
269 #[must_use]
270 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
271 pub fn from_scale_rotation_translation(scale: Vec3, rotation: Quat, translation: Vec3) -> Self {
272 let (x_axis, y_axis, z_axis) = Self::quat_to_axes(rotation);
273 Self::from_cols(
274 x_axis.mul(scale.x),
275 y_axis.mul(scale.y),
276 z_axis.mul(scale.z),
277 Vec4::from((translation, 1.0)),
278 )
279 }
280
281 #[inline]
290 #[must_use]
291 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
292 pub fn from_rotation_translation(rotation: Quat, translation: Vec3) -> Self {
293 let (x_axis, y_axis, z_axis) = Self::quat_to_axes(rotation);
294 Self::from_cols(x_axis, y_axis, z_axis, Vec4::from((translation, 1.0)))
295 }
296
297 #[inline]
305 #[must_use]
306 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
307 pub fn to_scale_rotation_translation(&self) -> (Vec3, Quat, Vec3) {
308 glam_assert!(self.row(3).abs_diff_eq(Vec4::W, 1e-6));
309
310 let r = Mat3A::from_mat4(*self);
311
312 let det = r.determinant();
313
314 glam_assert!(det != 0.0);
315
316 let scale = Vec3::new(
317 r.x_axis.length() * det.signum(),
318 r.y_axis.length(),
319 r.z_axis.length(),
320 );
321
322 glam_assert!(scale.cmpne(Vec3::ZERO).all());
323
324 let inv_scale = scale.recip();
325
326 let rotation = Quat::from_mat3a(&Mat3A::from_cols(
327 r.x_axis.mul(inv_scale.x),
328 r.y_axis.mul(inv_scale.y),
329 r.z_axis.mul(inv_scale.z),
330 ));
331
332 let translation = self.w_axis.xyz();
333
334 (scale, rotation, translation)
335 }
336
337 #[inline]
346 #[must_use]
347 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
348 pub fn from_quat(rotation: Quat) -> Self {
349 let (x_axis, y_axis, z_axis) = Self::quat_to_axes(rotation);
350 Self::from_cols(x_axis, y_axis, z_axis, Vec4::W)
351 }
352
353 #[inline]
359 #[must_use]
360 pub fn from_mat3(m: Mat3) -> Self {
361 Self::from_cols(
362 Vec4::from((m.x_axis, 0.0)),
363 Vec4::from((m.y_axis, 0.0)),
364 Vec4::from((m.z_axis, 0.0)),
365 Vec4::W,
366 )
367 }
368
369 #[inline]
374 #[must_use]
375 pub fn from_mat3_translation(mat3: Mat3, translation: Vec3) -> Self {
376 Self::from_cols(
377 Vec4::from((mat3.x_axis, 0.0)),
378 Vec4::from((mat3.y_axis, 0.0)),
379 Vec4::from((mat3.z_axis, 0.0)),
380 Vec4::from((translation, 1.0)),
381 )
382 }
383
384 #[inline]
390 #[must_use]
391 pub fn from_mat3a(m: Mat3A) -> Self {
392 Self::from_cols(
393 Vec4::from((m.x_axis, 0.0)),
394 Vec4::from((m.y_axis, 0.0)),
395 Vec4::from((m.z_axis, 0.0)),
396 Vec4::W,
397 )
398 }
399
400 #[inline]
405 #[must_use]
406 pub fn from_translation(translation: Vec3) -> Self {
407 Self::from_cols(
408 Vec4::X,
409 Vec4::Y,
410 Vec4::Z,
411 Vec4::new(translation.x, translation.y, translation.z, 1.0),
412 )
413 }
414
415 #[inline]
425 #[must_use]
426 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
427 pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
428 glam_assert!(axis.is_normalized());
429
430 let (sin, cos) = math::sin_cos(angle);
431 let axis_sin = axis.mul(sin);
432 let axis_sq = axis.mul(axis);
433 let omc = 1.0 - cos;
434 let xyomc = axis.x * axis.y * omc;
435 let xzomc = axis.x * axis.z * omc;
436 let yzomc = axis.y * axis.z * omc;
437 Self::from_cols(
438 Vec4::new(
439 axis_sq.x * omc + cos,
440 xyomc + axis_sin.z,
441 xzomc - axis_sin.y,
442 0.0,
443 ),
444 Vec4::new(
445 xyomc - axis_sin.z,
446 axis_sq.y * omc + cos,
447 yzomc + axis_sin.x,
448 0.0,
449 ),
450 Vec4::new(
451 xzomc + axis_sin.y,
452 yzomc - axis_sin.x,
453 axis_sq.z * omc + cos,
454 0.0,
455 ),
456 Vec4::W,
457 )
458 }
459
460 #[inline]
466 #[must_use]
467 pub fn from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self {
468 Self::from_euler_angles(order, a, b, c)
469 }
470
471 #[inline]
481 #[must_use]
482 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
483 pub fn to_euler(&self, order: EulerRot) -> (f32, f32, f32) {
484 glam_assert!(
485 self.x_axis.xyz().is_normalized()
486 && self.y_axis.xyz().is_normalized()
487 && self.z_axis.xyz().is_normalized()
488 );
489 Mat3::from_mat4(*self).to_euler_angles(order)
490 }
491
492 #[inline]
498 #[must_use]
499 pub fn from_rotation_x(angle: f32) -> Self {
500 let (sina, cosa) = math::sin_cos(angle);
501 Self::from_cols(
502 Vec4::X,
503 Vec4::new(0.0, cosa, sina, 0.0),
504 Vec4::new(0.0, -sina, cosa, 0.0),
505 Vec4::W,
506 )
507 }
508
509 #[inline]
515 #[must_use]
516 pub fn from_rotation_y(angle: f32) -> Self {
517 let (sina, cosa) = math::sin_cos(angle);
518 Self::from_cols(
519 Vec4::new(cosa, 0.0, -sina, 0.0),
520 Vec4::Y,
521 Vec4::new(sina, 0.0, cosa, 0.0),
522 Vec4::W,
523 )
524 }
525
526 #[inline]
532 #[must_use]
533 pub fn from_rotation_z(angle: f32) -> Self {
534 let (sina, cosa) = math::sin_cos(angle);
535 Self::from_cols(
536 Vec4::new(cosa, sina, 0.0, 0.0),
537 Vec4::new(-sina, cosa, 0.0, 0.0),
538 Vec4::Z,
539 Vec4::W,
540 )
541 }
542
543 #[inline]
552 #[must_use]
553 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
554 pub fn from_scale(scale: Vec3) -> Self {
555 glam_assert!(scale.cmpne(Vec3::ZERO).any());
557
558 Self::from_cols(
559 Vec4::new(scale.x, 0.0, 0.0, 0.0),
560 Vec4::new(0.0, scale.y, 0.0, 0.0),
561 Vec4::new(0.0, 0.0, scale.z, 0.0),
562 Vec4::W,
563 )
564 }
565
566 #[inline]
574 #[must_use]
575 #[track_caller]
576 pub const fn from_cols_slice(slice: &[f32]) -> Self {
577 Self::new(
578 slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
579 slice[8], slice[9], slice[10], slice[11], slice[12], slice[13], slice[14], slice[15],
580 )
581 }
582
583 #[inline]
589 #[track_caller]
590 pub fn write_cols_to_slice(&self, slice: &mut [f32]) {
591 slice[0] = self.x_axis.x;
592 slice[1] = self.x_axis.y;
593 slice[2] = self.x_axis.z;
594 slice[3] = self.x_axis.w;
595 slice[4] = self.y_axis.x;
596 slice[5] = self.y_axis.y;
597 slice[6] = self.y_axis.z;
598 slice[7] = self.y_axis.w;
599 slice[8] = self.z_axis.x;
600 slice[9] = self.z_axis.y;
601 slice[10] = self.z_axis.z;
602 slice[11] = self.z_axis.w;
603 slice[12] = self.w_axis.x;
604 slice[13] = self.w_axis.y;
605 slice[14] = self.w_axis.z;
606 slice[15] = self.w_axis.w;
607 }
608
609 #[inline]
620 #[must_use]
621 #[track_caller]
622 pub const fn from_rows_slice(slice: &[f32]) -> Self {
623 Self::new(
624 slice[0], slice[4], slice[8], slice[12], slice[1], slice[5], slice[9], slice[13],
625 slice[2], slice[6], slice[10], slice[14], slice[3], slice[7], slice[11], slice[15],
626 )
627 }
628
629 #[inline]
635 #[must_use]
636 #[track_caller]
637 pub fn col(&self, index: usize) -> Vec4 {
638 match index {
639 0 => self.x_axis,
640 1 => self.y_axis,
641 2 => self.z_axis,
642 3 => self.w_axis,
643 _ => panic!("index out of bounds"),
644 }
645 }
646
647 #[inline]
653 #[track_caller]
654 pub fn col_mut(&mut self, index: usize) -> &mut Vec4 {
655 match index {
656 0 => &mut self.x_axis,
657 1 => &mut self.y_axis,
658 2 => &mut self.z_axis,
659 3 => &mut self.w_axis,
660 _ => panic!("index out of bounds"),
661 }
662 }
663
664 #[inline]
672 #[must_use]
673 #[track_caller]
674 pub fn row(&self, index: usize) -> Vec4 {
675 match index {
676 0 => Vec4::new(self.x_axis.x, self.y_axis.x, self.z_axis.x, self.w_axis.x),
677 1 => Vec4::new(self.x_axis.y, self.y_axis.y, self.z_axis.y, self.w_axis.y),
678 2 => Vec4::new(self.x_axis.z, self.y_axis.z, self.z_axis.z, self.w_axis.z),
679 3 => Vec4::new(self.x_axis.w, self.y_axis.w, self.z_axis.w, self.w_axis.w),
680 _ => panic!("index out of bounds"),
681 }
682 }
683
684 #[inline]
694 #[track_caller]
695 pub fn set_row(&mut self, index: usize, row: Vec4) {
696 match index {
697 0 => {
698 self.x_axis.x = row.x;
699 self.y_axis.x = row.y;
700 self.z_axis.x = row.z;
701 self.w_axis.x = row.w;
702 }
703 1 => {
704 self.x_axis.y = row.x;
705 self.y_axis.y = row.y;
706 self.z_axis.y = row.z;
707 self.w_axis.y = row.w;
708 }
709 2 => {
710 self.x_axis.z = row.x;
711 self.y_axis.z = row.y;
712 self.z_axis.z = row.z;
713 self.w_axis.z = row.w;
714 }
715 3 => {
716 self.x_axis.w = row.x;
717 self.y_axis.w = row.y;
718 self.z_axis.w = row.z;
719 self.w_axis.w = row.w;
720 }
721 _ => panic!("index out of bounds"),
722 }
723 }
724
725 #[inline]
728 #[must_use]
729 pub fn is_finite(&self) -> bool {
730 self.x_axis.is_finite()
731 && self.y_axis.is_finite()
732 && self.z_axis.is_finite()
733 && self.w_axis.is_finite()
734 }
735
736 #[inline]
738 #[must_use]
739 pub fn is_nan(&self) -> bool {
740 self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan() || self.w_axis.is_nan()
741 }
742
743 #[inline]
745 #[must_use]
746 pub fn transpose(&self) -> Self {
747 unsafe {
748 let tmp0 = _mm_shuffle_ps(self.x_axis.0, self.y_axis.0, 0b01_00_01_00);
750 let tmp1 = _mm_shuffle_ps(self.x_axis.0, self.y_axis.0, 0b11_10_11_10);
751 let tmp2 = _mm_shuffle_ps(self.z_axis.0, self.w_axis.0, 0b01_00_01_00);
752 let tmp3 = _mm_shuffle_ps(self.z_axis.0, self.w_axis.0, 0b11_10_11_10);
753
754 Self {
755 x_axis: Vec4(_mm_shuffle_ps(tmp0, tmp2, 0b10_00_10_00)),
756 y_axis: Vec4(_mm_shuffle_ps(tmp0, tmp2, 0b11_01_11_01)),
757 z_axis: Vec4(_mm_shuffle_ps(tmp1, tmp3, 0b10_00_10_00)),
758 w_axis: Vec4(_mm_shuffle_ps(tmp1, tmp3, 0b11_01_11_01)),
759 }
760 }
761 }
762
763 #[inline]
765 #[must_use]
766 pub fn diagonal(&self) -> Vec4 {
767 Vec4::new(self.x_axis.x, self.y_axis.y, self.z_axis.z, self.w_axis.w)
768 }
769
770 #[must_use]
772 pub fn determinant(&self) -> f32 {
773 unsafe {
774 let swp2a = _mm_shuffle_ps(self.z_axis.0, self.z_axis.0, 0b00_01_01_10);
776 let swp3a = _mm_shuffle_ps(self.w_axis.0, self.w_axis.0, 0b11_10_11_11);
777 let swp2b = _mm_shuffle_ps(self.z_axis.0, self.z_axis.0, 0b11_10_11_11);
778 let swp3b = _mm_shuffle_ps(self.w_axis.0, self.w_axis.0, 0b00_01_01_10);
779 let swp2c = _mm_shuffle_ps(self.z_axis.0, self.z_axis.0, 0b00_00_01_10);
780 let swp3c = _mm_shuffle_ps(self.w_axis.0, self.w_axis.0, 0b01_10_00_00);
781
782 let mula = _mm_mul_ps(swp2a, swp3a);
783 let mulb = _mm_mul_ps(swp2b, swp3b);
784 let mulc = _mm_mul_ps(swp2c, swp3c);
785 let sube = _mm_sub_ps(mula, mulb);
786 let subf = _mm_sub_ps(_mm_movehl_ps(mulc, mulc), mulc);
787
788 let subfaca = _mm_shuffle_ps(sube, sube, 0b10_01_00_00);
789 let swpfaca = _mm_shuffle_ps(self.y_axis.0, self.y_axis.0, 0b00_00_00_01);
790 let mulfaca = _mm_mul_ps(swpfaca, subfaca);
791
792 let subtmpb = _mm_shuffle_ps(sube, subf, 0b00_00_11_01);
793 let subfacb = _mm_shuffle_ps(subtmpb, subtmpb, 0b11_01_01_00);
794 let swpfacb = _mm_shuffle_ps(self.y_axis.0, self.y_axis.0, 0b01_01_10_10);
795 let mulfacb = _mm_mul_ps(swpfacb, subfacb);
796
797 let subres = _mm_sub_ps(mulfaca, mulfacb);
798 let subtmpc = _mm_shuffle_ps(sube, subf, 0b01_00_10_10);
799 let subfacc = _mm_shuffle_ps(subtmpc, subtmpc, 0b11_11_10_00);
800 let swpfacc = _mm_shuffle_ps(self.y_axis.0, self.y_axis.0, 0b10_11_11_11);
801 let mulfacc = _mm_mul_ps(swpfacc, subfacc);
802
803 let addres = _mm_add_ps(subres, mulfacc);
804 let detcof = _mm_mul_ps(addres, _mm_setr_ps(1.0, -1.0, 1.0, -1.0));
805
806 dot4(self.x_axis.0, detcof)
807 }
808 }
809
810 #[inline(always)]
822 #[must_use]
823 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
824 fn inverse_checked<const CHECKED: bool>(&self) -> (Self, bool) {
825 unsafe {
826 let fac0 = {
828 let swp0a = _mm_shuffle_ps(self.w_axis.0, self.z_axis.0, 0b11_11_11_11);
829 let swp0b = _mm_shuffle_ps(self.w_axis.0, self.z_axis.0, 0b10_10_10_10);
830
831 let swp00 = _mm_shuffle_ps(self.z_axis.0, self.y_axis.0, 0b10_10_10_10);
832 let swp01 = _mm_shuffle_ps(swp0a, swp0a, 0b10_00_00_00);
833 let swp02 = _mm_shuffle_ps(swp0b, swp0b, 0b10_00_00_00);
834 let swp03 = _mm_shuffle_ps(self.z_axis.0, self.y_axis.0, 0b11_11_11_11);
835
836 let mul00 = _mm_mul_ps(swp00, swp01);
837 let mul01 = _mm_mul_ps(swp02, swp03);
838 _mm_sub_ps(mul00, mul01)
839 };
840 let fac1 = {
841 let swp0a = _mm_shuffle_ps(self.w_axis.0, self.z_axis.0, 0b11_11_11_11);
842 let swp0b = _mm_shuffle_ps(self.w_axis.0, self.z_axis.0, 0b01_01_01_01);
843
844 let swp00 = _mm_shuffle_ps(self.z_axis.0, self.y_axis.0, 0b01_01_01_01);
845 let swp01 = _mm_shuffle_ps(swp0a, swp0a, 0b10_00_00_00);
846 let swp02 = _mm_shuffle_ps(swp0b, swp0b, 0b10_00_00_00);
847 let swp03 = _mm_shuffle_ps(self.z_axis.0, self.y_axis.0, 0b11_11_11_11);
848
849 let mul00 = _mm_mul_ps(swp00, swp01);
850 let mul01 = _mm_mul_ps(swp02, swp03);
851 _mm_sub_ps(mul00, mul01)
852 };
853 let fac2 = {
854 let swp0a = _mm_shuffle_ps(self.w_axis.0, self.z_axis.0, 0b10_10_10_10);
855 let swp0b = _mm_shuffle_ps(self.w_axis.0, self.z_axis.0, 0b01_01_01_01);
856
857 let swp00 = _mm_shuffle_ps(self.z_axis.0, self.y_axis.0, 0b01_01_01_01);
858 let swp01 = _mm_shuffle_ps(swp0a, swp0a, 0b10_00_00_00);
859 let swp02 = _mm_shuffle_ps(swp0b, swp0b, 0b10_00_00_00);
860 let swp03 = _mm_shuffle_ps(self.z_axis.0, self.y_axis.0, 0b10_10_10_10);
861
862 let mul00 = _mm_mul_ps(swp00, swp01);
863 let mul01 = _mm_mul_ps(swp02, swp03);
864 _mm_sub_ps(mul00, mul01)
865 };
866 let fac3 = {
867 let swp0a = _mm_shuffle_ps(self.w_axis.0, self.z_axis.0, 0b11_11_11_11);
868 let swp0b = _mm_shuffle_ps(self.w_axis.0, self.z_axis.0, 0b00_00_00_00);
869
870 let swp00 = _mm_shuffle_ps(self.z_axis.0, self.y_axis.0, 0b00_00_00_00);
871 let swp01 = _mm_shuffle_ps(swp0a, swp0a, 0b10_00_00_00);
872 let swp02 = _mm_shuffle_ps(swp0b, swp0b, 0b10_00_00_00);
873 let swp03 = _mm_shuffle_ps(self.z_axis.0, self.y_axis.0, 0b11_11_11_11);
874
875 let mul00 = _mm_mul_ps(swp00, swp01);
876 let mul01 = _mm_mul_ps(swp02, swp03);
877 _mm_sub_ps(mul00, mul01)
878 };
879 let fac4 = {
880 let swp0a = _mm_shuffle_ps(self.w_axis.0, self.z_axis.0, 0b10_10_10_10);
881 let swp0b = _mm_shuffle_ps(self.w_axis.0, self.z_axis.0, 0b00_00_00_00);
882
883 let swp00 = _mm_shuffle_ps(self.z_axis.0, self.y_axis.0, 0b00_00_00_00);
884 let swp01 = _mm_shuffle_ps(swp0a, swp0a, 0b10_00_00_00);
885 let swp02 = _mm_shuffle_ps(swp0b, swp0b, 0b10_00_00_00);
886 let swp03 = _mm_shuffle_ps(self.z_axis.0, self.y_axis.0, 0b10_10_10_10);
887
888 let mul00 = _mm_mul_ps(swp00, swp01);
889 let mul01 = _mm_mul_ps(swp02, swp03);
890 _mm_sub_ps(mul00, mul01)
891 };
892 let fac5 = {
893 let swp0a = _mm_shuffle_ps(self.w_axis.0, self.z_axis.0, 0b01_01_01_01);
894 let swp0b = _mm_shuffle_ps(self.w_axis.0, self.z_axis.0, 0b00_00_00_00);
895
896 let swp00 = _mm_shuffle_ps(self.z_axis.0, self.y_axis.0, 0b00_00_00_00);
897 let swp01 = _mm_shuffle_ps(swp0a, swp0a, 0b10_00_00_00);
898 let swp02 = _mm_shuffle_ps(swp0b, swp0b, 0b10_00_00_00);
899 let swp03 = _mm_shuffle_ps(self.z_axis.0, self.y_axis.0, 0b01_01_01_01);
900
901 let mul00 = _mm_mul_ps(swp00, swp01);
902 let mul01 = _mm_mul_ps(swp02, swp03);
903 _mm_sub_ps(mul00, mul01)
904 };
905 let sign_a = _mm_set_ps(1.0, -1.0, 1.0, -1.0);
906 let sign_b = _mm_set_ps(-1.0, 1.0, -1.0, 1.0);
907
908 let temp0 = _mm_shuffle_ps(self.y_axis.0, self.x_axis.0, 0b00_00_00_00);
909 let vec0 = _mm_shuffle_ps(temp0, temp0, 0b10_10_10_00);
910
911 let temp1 = _mm_shuffle_ps(self.y_axis.0, self.x_axis.0, 0b01_01_01_01);
912 let vec1 = _mm_shuffle_ps(temp1, temp1, 0b10_10_10_00);
913
914 let temp2 = _mm_shuffle_ps(self.y_axis.0, self.x_axis.0, 0b10_10_10_10);
915 let vec2 = _mm_shuffle_ps(temp2, temp2, 0b10_10_10_00);
916
917 let temp3 = _mm_shuffle_ps(self.y_axis.0, self.x_axis.0, 0b11_11_11_11);
918 let vec3 = _mm_shuffle_ps(temp3, temp3, 0b10_10_10_00);
919
920 let mul00 = _mm_mul_ps(vec1, fac0);
921 let mul01 = _mm_mul_ps(vec2, fac1);
922 let mul02 = _mm_mul_ps(vec3, fac2);
923 let sub00 = _mm_sub_ps(mul00, mul01);
924 let add00 = _mm_add_ps(sub00, mul02);
925 let inv0 = _mm_mul_ps(sign_b, add00);
926
927 let mul03 = _mm_mul_ps(vec0, fac0);
928 let mul04 = _mm_mul_ps(vec2, fac3);
929 let mul05 = _mm_mul_ps(vec3, fac4);
930 let sub01 = _mm_sub_ps(mul03, mul04);
931 let add01 = _mm_add_ps(sub01, mul05);
932 let inv1 = _mm_mul_ps(sign_a, add01);
933
934 let mul06 = _mm_mul_ps(vec0, fac1);
935 let mul07 = _mm_mul_ps(vec1, fac3);
936 let mul08 = _mm_mul_ps(vec3, fac5);
937 let sub02 = _mm_sub_ps(mul06, mul07);
938 let add02 = _mm_add_ps(sub02, mul08);
939 let inv2 = _mm_mul_ps(sign_b, add02);
940
941 let mul09 = _mm_mul_ps(vec0, fac2);
942 let mul10 = _mm_mul_ps(vec1, fac4);
943 let mul11 = _mm_mul_ps(vec2, fac5);
944 let sub03 = _mm_sub_ps(mul09, mul10);
945 let add03 = _mm_add_ps(sub03, mul11);
946 let inv3 = _mm_mul_ps(sign_a, add03);
947
948 let row0 = _mm_shuffle_ps(inv0, inv1, 0b00_00_00_00);
949 let row1 = _mm_shuffle_ps(inv2, inv3, 0b00_00_00_00);
950 let row2 = _mm_shuffle_ps(row0, row1, 0b10_00_10_00);
951
952 let dot0 = dot4(self.x_axis.0, row2);
953
954 let rcp0 = _mm_set1_ps(dot0.recip());
955 let m = Self {
956 x_axis: Vec4(_mm_mul_ps(inv0, rcp0)),
957 y_axis: Vec4(_mm_mul_ps(inv1, rcp0)),
958 z_axis: Vec4(_mm_mul_ps(inv2, rcp0)),
959 w_axis: Vec4(_mm_mul_ps(inv3, rcp0)),
960 };
961 if CHECKED {
962 if !m.is_finite() {
963 return (Self::ZERO, false);
964 }
965 } else {
966 glam_assert!(m.is_finite());
967 }
968 (m, true)
969 }
970 }
971
972 #[must_use]
984 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
985 pub fn inverse(&self) -> Self {
986 self.inverse_checked::<false>().0
987 }
988
989 #[must_use]
992 pub fn try_inverse(&self) -> Option<Self> {
993 let (m, is_valid) = self.inverse_checked::<true>();
994 if is_valid { Some(m) } else { None }
995 }
996
997 #[must_use]
1000 pub fn inverse_or_zero(&self) -> Self {
1001 self.inverse_checked::<true>().0
1002 }
1003
1004 #[inline]
1011 #[must_use]
1012 pub fn project_point3(&self, rhs: Vec3) -> Vec3 {
1013 let mut res = self.x_axis.mul(rhs.x);
1014 res = self.y_axis.mul(rhs.y).add(res);
1015 res = self.z_axis.mul(rhs.z).add(res);
1016 res = self.w_axis.add(res);
1017 res = res.div(res.w);
1018 res.xyz()
1019 }
1020
1021 #[inline]
1034 #[must_use]
1035 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1036 pub fn transform_point3(&self, rhs: Vec3) -> Vec3 {
1037 glam_assert!(self.row(3).abs_diff_eq(Vec4::W, 1e-6));
1038 let mut res = self.x_axis.mul(rhs.x);
1039 res = self.y_axis.mul(rhs.y).add(res);
1040 res = self.z_axis.mul(rhs.z).add(res);
1041 res = self.w_axis.add(res);
1042 res.xyz()
1043 }
1044
1045 #[inline]
1056 #[must_use]
1057 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1058 pub fn transform_vector3(&self, rhs: Vec3) -> Vec3 {
1059 glam_assert!(self.row(3).abs_diff_eq(Vec4::W, 1e-6));
1060 let mut res = self.x_axis.mul(rhs.x);
1061 res = self.y_axis.mul(rhs.y).add(res);
1062 res = self.z_axis.mul(rhs.z).add(res);
1063 res.xyz()
1064 }
1065
1066 #[inline]
1073 #[must_use]
1074 pub fn project_point3a(&self, rhs: Vec3A) -> Vec3A {
1075 let mut res = self.x_axis.mul(rhs.xxxx());
1076 res = self.y_axis.mul(rhs.yyyy()).add(res);
1077 res = self.z_axis.mul(rhs.zzzz()).add(res);
1078 res = self.w_axis.add(res);
1079 res = res.div(res.wwww());
1080 Vec3A::from_vec4(res)
1081 }
1082
1083 #[inline]
1095 #[must_use]
1096 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1097 pub fn transform_point3a(&self, rhs: Vec3A) -> Vec3A {
1098 glam_assert!(self.row(3).abs_diff_eq(Vec4::W, 1e-6));
1099 let mut res = self.x_axis.mul(rhs.xxxx());
1100 res = self.y_axis.mul(rhs.yyyy()).add(res);
1101 res = self.z_axis.mul(rhs.zzzz()).add(res);
1102 res = self.w_axis.add(res);
1103 Vec3A::from_vec4(res)
1104 }
1105
1106 #[inline]
1116 #[must_use]
1117 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1118 pub fn transform_vector3a(&self, rhs: Vec3A) -> Vec3A {
1119 glam_assert!(self.row(3).abs_diff_eq(Vec4::W, 1e-6));
1120 let mut res = self.x_axis.mul(rhs.xxxx());
1121 res = self.y_axis.mul(rhs.yyyy()).add(res);
1122 res = self.z_axis.mul(rhs.zzzz()).add(res);
1123 Vec3A::from_vec4(res)
1124 }
1125
1126 #[inline]
1128 #[must_use]
1129 pub fn mul_vec4(&self, rhs: Vec4) -> Vec4 {
1130 let mut res = self.x_axis.mul(rhs.xxxx());
1131 res = res.add(self.y_axis.mul(rhs.yyyy()));
1132 res = res.add(self.z_axis.mul(rhs.zzzz()));
1133 res = res.add(self.w_axis.mul(rhs.wwww()));
1134 res
1135 }
1136
1137 #[inline]
1139 #[must_use]
1140 pub fn mul_transpose_vec4(&self, rhs: Vec4) -> Vec4 {
1141 Vec4::new(
1142 self.x_axis.dot(rhs),
1143 self.y_axis.dot(rhs),
1144 self.z_axis.dot(rhs),
1145 self.w_axis.dot(rhs),
1146 )
1147 }
1148
1149 #[inline]
1151 #[must_use]
1152 pub fn mul_mat4(&self, rhs: &Self) -> Self {
1153 self.mul(rhs)
1154 }
1155
1156 #[inline]
1158 #[must_use]
1159 pub fn add_mat4(&self, rhs: &Self) -> Self {
1160 self.add(rhs)
1161 }
1162
1163 #[inline]
1165 #[must_use]
1166 pub fn sub_mat4(&self, rhs: &Self) -> Self {
1167 self.sub(rhs)
1168 }
1169
1170 #[inline]
1172 #[must_use]
1173 pub fn mul_scalar(&self, rhs: f32) -> Self {
1174 Self::from_cols(
1175 self.x_axis.mul(rhs),
1176 self.y_axis.mul(rhs),
1177 self.z_axis.mul(rhs),
1178 self.w_axis.mul(rhs),
1179 )
1180 }
1181
1182 #[inline]
1186 #[must_use]
1187 pub fn mul_diagonal_scale(&self, scale: Vec4) -> Self {
1188 Self::from_cols(
1189 self.x_axis * scale.x,
1190 self.y_axis * scale.y,
1191 self.z_axis * scale.z,
1192 self.w_axis * scale.w,
1193 )
1194 }
1195
1196 #[inline]
1198 #[must_use]
1199 pub fn div_scalar(&self, rhs: f32) -> Self {
1200 let rhs = Vec4::splat(rhs);
1201 Self::from_cols(
1202 self.x_axis.div(rhs),
1203 self.y_axis.div(rhs),
1204 self.z_axis.div(rhs),
1205 self.w_axis.div(rhs),
1206 )
1207 }
1208
1209 #[inline]
1211 #[must_use]
1212 pub fn recip(&self) -> Self {
1213 Self::from_cols(
1214 self.x_axis.recip(),
1215 self.y_axis.recip(),
1216 self.z_axis.recip(),
1217 self.w_axis.recip(),
1218 )
1219 }
1220
1221 #[inline]
1231 #[must_use]
1232 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
1233 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
1234 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
1235 && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
1236 && self.w_axis.abs_diff_eq(rhs.w_axis, max_abs_diff)
1237 }
1238
1239 #[inline]
1241 #[must_use]
1242 pub fn abs(&self) -> Self {
1243 Self::from_cols(
1244 self.x_axis.abs(),
1245 self.y_axis.abs(),
1246 self.z_axis.abs(),
1247 self.w_axis.abs(),
1248 )
1249 }
1250
1251 #[cfg(feature = "f64")]
1252 #[inline]
1253 #[must_use]
1254 pub fn as_dmat4(&self) -> DMat4 {
1255 DMat4::from_cols(
1256 self.x_axis.as_dvec4(),
1257 self.y_axis.as_dvec4(),
1258 self.z_axis.as_dvec4(),
1259 self.w_axis.as_dvec4(),
1260 )
1261 }
1262}
1263
1264impl Default for Mat4 {
1265 #[inline]
1266 fn default() -> Self {
1267 Self::IDENTITY
1268 }
1269}
1270
1271impl Add for Mat4 {
1272 type Output = Self;
1273 #[inline]
1274 fn add(self, rhs: Self) -> Self {
1275 Self::from_cols(
1276 self.x_axis.add(rhs.x_axis),
1277 self.y_axis.add(rhs.y_axis),
1278 self.z_axis.add(rhs.z_axis),
1279 self.w_axis.add(rhs.w_axis),
1280 )
1281 }
1282}
1283
1284impl Add<&Self> for Mat4 {
1285 type Output = Self;
1286 #[inline]
1287 fn add(self, rhs: &Self) -> Self {
1288 self.add(*rhs)
1289 }
1290}
1291
1292impl Add<&Mat4> for &Mat4 {
1293 type Output = Mat4;
1294 #[inline]
1295 fn add(self, rhs: &Mat4) -> Mat4 {
1296 (*self).add(*rhs)
1297 }
1298}
1299
1300impl Add<Mat4> for &Mat4 {
1301 type Output = Mat4;
1302 #[inline]
1303 fn add(self, rhs: Mat4) -> Mat4 {
1304 (*self).add(rhs)
1305 }
1306}
1307
1308impl AddAssign for Mat4 {
1309 #[inline]
1310 fn add_assign(&mut self, rhs: Self) {
1311 *self = self.add(rhs);
1312 }
1313}
1314
1315impl AddAssign<&Self> for Mat4 {
1316 #[inline]
1317 fn add_assign(&mut self, rhs: &Self) {
1318 self.add_assign(*rhs);
1319 }
1320}
1321
1322impl Sub for Mat4 {
1323 type Output = Self;
1324 #[inline]
1325 fn sub(self, rhs: Self) -> Self {
1326 Self::from_cols(
1327 self.x_axis.sub(rhs.x_axis),
1328 self.y_axis.sub(rhs.y_axis),
1329 self.z_axis.sub(rhs.z_axis),
1330 self.w_axis.sub(rhs.w_axis),
1331 )
1332 }
1333}
1334
1335impl Sub<&Self> for Mat4 {
1336 type Output = Self;
1337 #[inline]
1338 fn sub(self, rhs: &Self) -> Self {
1339 self.sub(*rhs)
1340 }
1341}
1342
1343impl Sub<&Mat4> for &Mat4 {
1344 type Output = Mat4;
1345 #[inline]
1346 fn sub(self, rhs: &Mat4) -> Mat4 {
1347 (*self).sub(*rhs)
1348 }
1349}
1350
1351impl Sub<Mat4> for &Mat4 {
1352 type Output = Mat4;
1353 #[inline]
1354 fn sub(self, rhs: Mat4) -> Mat4 {
1355 (*self).sub(rhs)
1356 }
1357}
1358
1359impl SubAssign for Mat4 {
1360 #[inline]
1361 fn sub_assign(&mut self, rhs: Self) {
1362 *self = self.sub(rhs);
1363 }
1364}
1365
1366impl SubAssign<&Self> for Mat4 {
1367 #[inline]
1368 fn sub_assign(&mut self, rhs: &Self) {
1369 self.sub_assign(*rhs);
1370 }
1371}
1372
1373impl Neg for Mat4 {
1374 type Output = Self;
1375 #[inline]
1376 fn neg(self) -> Self::Output {
1377 Self::from_cols(
1378 self.x_axis.neg(),
1379 self.y_axis.neg(),
1380 self.z_axis.neg(),
1381 self.w_axis.neg(),
1382 )
1383 }
1384}
1385
1386impl Neg for &Mat4 {
1387 type Output = Mat4;
1388 #[inline]
1389 fn neg(self) -> Mat4 {
1390 (*self).neg()
1391 }
1392}
1393
1394impl Mul for Mat4 {
1395 type Output = Self;
1396 #[inline]
1397 fn mul(self, rhs: Self) -> Self {
1398 Self::from_cols(
1399 self.mul(rhs.x_axis),
1400 self.mul(rhs.y_axis),
1401 self.mul(rhs.z_axis),
1402 self.mul(rhs.w_axis),
1403 )
1404 }
1405}
1406
1407impl Mul<&Self> for Mat4 {
1408 type Output = Self;
1409 #[inline]
1410 fn mul(self, rhs: &Self) -> Self {
1411 self.mul(*rhs)
1412 }
1413}
1414
1415impl Mul<&Mat4> for &Mat4 {
1416 type Output = Mat4;
1417 #[inline]
1418 fn mul(self, rhs: &Mat4) -> Mat4 {
1419 (*self).mul(*rhs)
1420 }
1421}
1422
1423impl Mul<Mat4> for &Mat4 {
1424 type Output = Mat4;
1425 #[inline]
1426 fn mul(self, rhs: Mat4) -> Mat4 {
1427 (*self).mul(rhs)
1428 }
1429}
1430
1431impl MulAssign for Mat4 {
1432 #[inline]
1433 fn mul_assign(&mut self, rhs: Self) {
1434 *self = self.mul(rhs);
1435 }
1436}
1437
1438impl MulAssign<&Self> for Mat4 {
1439 #[inline]
1440 fn mul_assign(&mut self, rhs: &Self) {
1441 self.mul_assign(*rhs);
1442 }
1443}
1444
1445impl Mul<Vec4> for Mat4 {
1446 type Output = Vec4;
1447 #[inline]
1448 fn mul(self, rhs: Vec4) -> Self::Output {
1449 self.mul_vec4(rhs)
1450 }
1451}
1452
1453impl Mul<&Vec4> for Mat4 {
1454 type Output = Vec4;
1455 #[inline]
1456 fn mul(self, rhs: &Vec4) -> Vec4 {
1457 self.mul(*rhs)
1458 }
1459}
1460
1461impl Mul<&Vec4> for &Mat4 {
1462 type Output = Vec4;
1463 #[inline]
1464 fn mul(self, rhs: &Vec4) -> Vec4 {
1465 (*self).mul(*rhs)
1466 }
1467}
1468
1469impl Mul<Vec4> for &Mat4 {
1470 type Output = Vec4;
1471 #[inline]
1472 fn mul(self, rhs: Vec4) -> Vec4 {
1473 (*self).mul(rhs)
1474 }
1475}
1476
1477impl Mul<Mat4> for f32 {
1478 type Output = Mat4;
1479 #[inline]
1480 fn mul(self, rhs: Mat4) -> Self::Output {
1481 rhs.mul_scalar(self)
1482 }
1483}
1484
1485impl Mul<&Mat4> for f32 {
1486 type Output = Mat4;
1487 #[inline]
1488 fn mul(self, rhs: &Mat4) -> Mat4 {
1489 self.mul(*rhs)
1490 }
1491}
1492
1493impl Mul<&Mat4> for &f32 {
1494 type Output = Mat4;
1495 #[inline]
1496 fn mul(self, rhs: &Mat4) -> Mat4 {
1497 (*self).mul(*rhs)
1498 }
1499}
1500
1501impl Mul<Mat4> for &f32 {
1502 type Output = Mat4;
1503 #[inline]
1504 fn mul(self, rhs: Mat4) -> Mat4 {
1505 (*self).mul(rhs)
1506 }
1507}
1508
1509impl Mul<f32> for Mat4 {
1510 type Output = Self;
1511 #[inline]
1512 fn mul(self, rhs: f32) -> Self {
1513 self.mul_scalar(rhs)
1514 }
1515}
1516
1517impl Mul<&f32> for Mat4 {
1518 type Output = Self;
1519 #[inline]
1520 fn mul(self, rhs: &f32) -> Self {
1521 self.mul(*rhs)
1522 }
1523}
1524
1525impl Mul<&f32> for &Mat4 {
1526 type Output = Mat4;
1527 #[inline]
1528 fn mul(self, rhs: &f32) -> Mat4 {
1529 (*self).mul(*rhs)
1530 }
1531}
1532
1533impl Mul<f32> for &Mat4 {
1534 type Output = Mat4;
1535 #[inline]
1536 fn mul(self, rhs: f32) -> Mat4 {
1537 (*self).mul(rhs)
1538 }
1539}
1540
1541impl MulAssign<f32> for Mat4 {
1542 #[inline]
1543 fn mul_assign(&mut self, rhs: f32) {
1544 *self = self.mul(rhs);
1545 }
1546}
1547
1548impl MulAssign<&f32> for Mat4 {
1549 #[inline]
1550 fn mul_assign(&mut self, rhs: &f32) {
1551 self.mul_assign(*rhs);
1552 }
1553}
1554
1555impl Div<Mat4> for f32 {
1556 type Output = Mat4;
1557 #[inline]
1558 fn div(self, rhs: Mat4) -> Self::Output {
1559 Mat4::from_cols(
1560 self.div(rhs.x_axis),
1561 self.div(rhs.y_axis),
1562 self.div(rhs.z_axis),
1563 self.div(rhs.w_axis),
1564 )
1565 }
1566}
1567
1568impl Div<&Mat4> for f32 {
1569 type Output = Mat4;
1570 #[inline]
1571 fn div(self, rhs: &Mat4) -> Mat4 {
1572 self.div(*rhs)
1573 }
1574}
1575
1576impl Div<&Mat4> for &f32 {
1577 type Output = Mat4;
1578 #[inline]
1579 fn div(self, rhs: &Mat4) -> Mat4 {
1580 (*self).div(*rhs)
1581 }
1582}
1583
1584impl Div<Mat4> for &f32 {
1585 type Output = Mat4;
1586 #[inline]
1587 fn div(self, rhs: Mat4) -> Mat4 {
1588 (*self).div(rhs)
1589 }
1590}
1591
1592impl Div<f32> for Mat4 {
1593 type Output = Self;
1594 #[inline]
1595 fn div(self, rhs: f32) -> Self {
1596 self.div_scalar(rhs)
1597 }
1598}
1599
1600impl Div<&f32> for Mat4 {
1601 type Output = Self;
1602 #[inline]
1603 fn div(self, rhs: &f32) -> Self {
1604 self.div(*rhs)
1605 }
1606}
1607
1608impl Div<&f32> for &Mat4 {
1609 type Output = Mat4;
1610 #[inline]
1611 fn div(self, rhs: &f32) -> Mat4 {
1612 (*self).div(*rhs)
1613 }
1614}
1615
1616impl Div<f32> for &Mat4 {
1617 type Output = Mat4;
1618 #[inline]
1619 fn div(self, rhs: f32) -> Mat4 {
1620 (*self).div(rhs)
1621 }
1622}
1623
1624impl DivAssign<f32> for Mat4 {
1625 #[inline]
1626 fn div_assign(&mut self, rhs: f32) {
1627 *self = self.div(rhs);
1628 }
1629}
1630
1631impl DivAssign<&f32> for Mat4 {
1632 #[inline]
1633 fn div_assign(&mut self, rhs: &f32) {
1634 self.div_assign(*rhs);
1635 }
1636}
1637
1638impl Sum<Self> for Mat4 {
1639 fn sum<I>(iter: I) -> Self
1640 where
1641 I: Iterator<Item = Self>,
1642 {
1643 iter.fold(Self::ZERO, Self::add)
1644 }
1645}
1646
1647impl<'a> Sum<&'a Self> for Mat4 {
1648 fn sum<I>(iter: I) -> Self
1649 where
1650 I: Iterator<Item = &'a Self>,
1651 {
1652 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1653 }
1654}
1655
1656impl Product for Mat4 {
1657 fn product<I>(iter: I) -> Self
1658 where
1659 I: Iterator<Item = Self>,
1660 {
1661 iter.fold(Self::IDENTITY, Self::mul)
1662 }
1663}
1664
1665impl<'a> Product<&'a Self> for Mat4 {
1666 fn product<I>(iter: I) -> Self
1667 where
1668 I: Iterator<Item = &'a Self>,
1669 {
1670 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1671 }
1672}
1673
1674impl PartialEq for Mat4 {
1675 #[inline]
1676 fn eq(&self, rhs: &Self) -> bool {
1677 self.x_axis.eq(&rhs.x_axis)
1678 && self.y_axis.eq(&rhs.y_axis)
1679 && self.z_axis.eq(&rhs.z_axis)
1680 && self.w_axis.eq(&rhs.w_axis)
1681 }
1682}
1683
1684impl AsRef<[f32; 16]> for Mat4 {
1685 #[inline]
1686 fn as_ref(&self) -> &[f32; 16] {
1687 unsafe { &*(self as *const Self as *const [f32; 16]) }
1688 }
1689}
1690
1691impl AsMut<[f32; 16]> for Mat4 {
1692 #[inline]
1693 fn as_mut(&mut self) -> &mut [f32; 16] {
1694 unsafe { &mut *(self as *mut Self as *mut [f32; 16]) }
1695 }
1696}
1697
1698impl fmt::Debug for Mat4 {
1699 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1700 fmt.debug_struct(stringify!(Mat4))
1701 .field("x_axis", &self.x_axis)
1702 .field("y_axis", &self.y_axis)
1703 .field("z_axis", &self.z_axis)
1704 .field("w_axis", &self.w_axis)
1705 .finish()
1706 }
1707}
1708
1709impl fmt::Display for Mat4 {
1710 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1711 if let Some(p) = f.precision() {
1712 write!(
1713 f,
1714 "[{:.*}, {:.*}, {:.*}, {:.*}]",
1715 p, self.x_axis, p, self.y_axis, p, self.z_axis, p, self.w_axis
1716 )
1717 } else {
1718 write!(
1719 f,
1720 "[{}, {}, {}, {}]",
1721 self.x_axis, self.y_axis, self.z_axis, self.w_axis
1722 )
1723 }
1724 }
1725}