1use crate::{
4 euler::{FromEuler, ToEuler},
5 f32::math,
6 neon::*,
7 swizzles::*,
8 DMat4, EulerRot, Mat3, Mat3A, Quat, Vec3, Vec3A, Vec4,
9};
10use core::fmt;
11use core::iter::{Product, Sum};
12use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
13
14use core::arch::aarch64::*;
15
16#[inline(always)]
18#[must_use]
19pub const fn mat4(x_axis: Vec4, y_axis: Vec4, z_axis: Vec4, w_axis: Vec4) -> Mat4 {
20 Mat4::from_cols(x_axis, y_axis, z_axis, w_axis)
21}
22
23#[derive(Clone, Copy)]
53#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
54#[repr(C)]
55pub struct Mat4 {
56 pub x_axis: Vec4,
57 pub y_axis: Vec4,
58 pub z_axis: Vec4,
59 pub w_axis: Vec4,
60}
61
62impl Mat4 {
63 pub const ZERO: Self = Self::from_cols(Vec4::ZERO, Vec4::ZERO, Vec4::ZERO, Vec4::ZERO);
65
66 pub const IDENTITY: Self = Self::from_cols(Vec4::X, Vec4::Y, Vec4::Z, Vec4::W);
68
69 pub const NAN: Self = Self::from_cols(Vec4::NAN, Vec4::NAN, Vec4::NAN, Vec4::NAN);
71
72 #[allow(clippy::too_many_arguments)]
73 #[inline(always)]
74 #[must_use]
75 const fn new(
76 m00: f32,
77 m01: f32,
78 m02: f32,
79 m03: f32,
80 m10: f32,
81 m11: f32,
82 m12: f32,
83 m13: f32,
84 m20: f32,
85 m21: f32,
86 m22: f32,
87 m23: f32,
88 m30: f32,
89 m31: f32,
90 m32: f32,
91 m33: f32,
92 ) -> Self {
93 Self {
94 x_axis: Vec4::new(m00, m01, m02, m03),
95 y_axis: Vec4::new(m10, m11, m12, m13),
96 z_axis: Vec4::new(m20, m21, m22, m23),
97 w_axis: Vec4::new(m30, m31, m32, m33),
98 }
99 }
100
101 #[inline(always)]
103 #[must_use]
104 pub const fn from_cols(x_axis: Vec4, y_axis: Vec4, z_axis: Vec4, w_axis: Vec4) -> Self {
105 Self {
106 x_axis,
107 y_axis,
108 z_axis,
109 w_axis,
110 }
111 }
112
113 #[inline]
117 #[must_use]
118 pub const fn from_cols_array(m: &[f32; 16]) -> Self {
119 Self::new(
120 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],
121 m[14], m[15],
122 )
123 }
124
125 #[inline]
128 #[must_use]
129 pub const fn to_cols_array(&self) -> [f32; 16] {
130 let [x_axis_x, x_axis_y, x_axis_z, x_axis_w] = self.x_axis.to_array();
131 let [y_axis_x, y_axis_y, y_axis_z, y_axis_w] = self.y_axis.to_array();
132 let [z_axis_x, z_axis_y, z_axis_z, z_axis_w] = self.z_axis.to_array();
133 let [w_axis_x, w_axis_y, w_axis_z, w_axis_w] = self.w_axis.to_array();
134
135 [
136 x_axis_x, x_axis_y, x_axis_z, x_axis_w, y_axis_x, y_axis_y, y_axis_z, y_axis_w,
137 z_axis_x, z_axis_y, z_axis_z, z_axis_w, w_axis_x, w_axis_y, w_axis_z, w_axis_w,
138 ]
139 }
140
141 #[inline]
145 #[must_use]
146 pub const fn from_cols_array_2d(m: &[[f32; 4]; 4]) -> Self {
147 Self::from_cols(
148 Vec4::from_array(m[0]),
149 Vec4::from_array(m[1]),
150 Vec4::from_array(m[2]),
151 Vec4::from_array(m[3]),
152 )
153 }
154
155 #[inline]
158 #[must_use]
159 pub const fn to_cols_array_2d(&self) -> [[f32; 4]; 4] {
160 [
161 self.x_axis.to_array(),
162 self.y_axis.to_array(),
163 self.z_axis.to_array(),
164 self.w_axis.to_array(),
165 ]
166 }
167
168 #[doc(alias = "scale")]
170 #[inline]
171 #[must_use]
172 pub const fn from_diagonal(diagonal: Vec4) -> Self {
173 let [x, y, z, w] = diagonal.to_array();
175 Self::new(
176 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,
177 )
178 }
179
180 #[inline]
181 #[must_use]
182 fn quat_to_axes(rotation: Quat) -> (Vec4, Vec4, Vec4) {
183 glam_assert!(rotation.is_normalized());
184
185 let (x, y, z, w) = rotation.into();
186 let x2 = x + x;
187 let y2 = y + y;
188 let z2 = z + z;
189 let xx = x * x2;
190 let xy = x * y2;
191 let xz = x * z2;
192 let yy = y * y2;
193 let yz = y * z2;
194 let zz = z * z2;
195 let wx = w * x2;
196 let wy = w * y2;
197 let wz = w * z2;
198
199 let x_axis = Vec4::new(1.0 - (yy + zz), xy + wz, xz - wy, 0.0);
200 let y_axis = Vec4::new(xy - wz, 1.0 - (xx + zz), yz + wx, 0.0);
201 let z_axis = Vec4::new(xz + wy, yz - wx, 1.0 - (xx + yy), 0.0);
202 (x_axis, y_axis, z_axis)
203 }
204
205 #[inline]
215 #[must_use]
216 pub fn from_scale_rotation_translation(scale: Vec3, rotation: Quat, translation: Vec3) -> Self {
217 let (x_axis, y_axis, z_axis) = Self::quat_to_axes(rotation);
218 Self::from_cols(
219 x_axis.mul(scale.x),
220 y_axis.mul(scale.y),
221 z_axis.mul(scale.z),
222 Vec4::from((translation, 1.0)),
223 )
224 }
225
226 #[inline]
235 #[must_use]
236 pub fn from_rotation_translation(rotation: Quat, translation: Vec3) -> Self {
237 let (x_axis, y_axis, z_axis) = Self::quat_to_axes(rotation);
238 Self::from_cols(x_axis, y_axis, z_axis, Vec4::from((translation, 1.0)))
239 }
240
241 #[inline]
249 #[must_use]
250 pub fn to_scale_rotation_translation(&self) -> (Vec3, Quat, Vec3) {
251 let det = self.determinant();
252 glam_assert!(det != 0.0);
253
254 let scale = Vec3::new(
255 self.x_axis.length() * math::signum(det),
256 self.y_axis.length(),
257 self.z_axis.length(),
258 );
259
260 glam_assert!(scale.cmpne(Vec3::ZERO).all());
261
262 let inv_scale = scale.recip();
263
264 let rotation = Quat::from_rotation_axes(
265 self.x_axis.mul(inv_scale.x).xyz(),
266 self.y_axis.mul(inv_scale.y).xyz(),
267 self.z_axis.mul(inv_scale.z).xyz(),
268 );
269
270 let translation = self.w_axis.xyz();
271
272 (scale, rotation, translation)
273 }
274
275 #[inline]
284 #[must_use]
285 pub fn from_quat(rotation: Quat) -> Self {
286 let (x_axis, y_axis, z_axis) = Self::quat_to_axes(rotation);
287 Self::from_cols(x_axis, y_axis, z_axis, Vec4::W)
288 }
289
290 #[inline]
296 #[must_use]
297 pub fn from_mat3(m: Mat3) -> Self {
298 Self::from_cols(
299 Vec4::from((m.x_axis, 0.0)),
300 Vec4::from((m.y_axis, 0.0)),
301 Vec4::from((m.z_axis, 0.0)),
302 Vec4::W,
303 )
304 }
305
306 #[inline]
311 #[must_use]
312 pub fn from_mat3_translation(mat3: Mat3, translation: Vec3) -> Self {
313 Self::from_cols(
314 Vec4::from((mat3.x_axis, 0.0)),
315 Vec4::from((mat3.y_axis, 0.0)),
316 Vec4::from((mat3.z_axis, 0.0)),
317 Vec4::from((translation, 1.0)),
318 )
319 }
320
321 #[inline]
327 #[must_use]
328 pub fn from_mat3a(m: Mat3A) -> Self {
329 Self::from_cols(
330 Vec4::from((m.x_axis, 0.0)),
331 Vec4::from((m.y_axis, 0.0)),
332 Vec4::from((m.z_axis, 0.0)),
333 Vec4::W,
334 )
335 }
336
337 #[inline]
342 #[must_use]
343 pub fn from_translation(translation: Vec3) -> Self {
344 Self::from_cols(
345 Vec4::X,
346 Vec4::Y,
347 Vec4::Z,
348 Vec4::new(translation.x, translation.y, translation.z, 1.0),
349 )
350 }
351
352 #[inline]
362 #[must_use]
363 pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
364 glam_assert!(axis.is_normalized());
365
366 let (sin, cos) = math::sin_cos(angle);
367 let axis_sin = axis.mul(sin);
368 let axis_sq = axis.mul(axis);
369 let omc = 1.0 - cos;
370 let xyomc = axis.x * axis.y * omc;
371 let xzomc = axis.x * axis.z * omc;
372 let yzomc = axis.y * axis.z * omc;
373 Self::from_cols(
374 Vec4::new(
375 axis_sq.x * omc + cos,
376 xyomc + axis_sin.z,
377 xzomc - axis_sin.y,
378 0.0,
379 ),
380 Vec4::new(
381 xyomc - axis_sin.z,
382 axis_sq.y * omc + cos,
383 yzomc + axis_sin.x,
384 0.0,
385 ),
386 Vec4::new(
387 xzomc + axis_sin.y,
388 yzomc - axis_sin.x,
389 axis_sq.z * omc + cos,
390 0.0,
391 ),
392 Vec4::W,
393 )
394 }
395
396 #[inline]
402 #[must_use]
403 pub fn from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self {
404 Self::from_euler_angles(order, a, b, c)
405 }
406
407 #[inline]
417 #[must_use]
418 pub fn to_euler(&self, order: EulerRot) -> (f32, f32, f32) {
419 glam_assert!(
420 self.x_axis.xyz().is_normalized()
421 && self.y_axis.xyz().is_normalized()
422 && self.z_axis.xyz().is_normalized()
423 );
424 self.to_euler_angles(order)
425 }
426
427 #[inline]
433 #[must_use]
434 pub fn from_rotation_x(angle: f32) -> Self {
435 let (sina, cosa) = math::sin_cos(angle);
436 Self::from_cols(
437 Vec4::X,
438 Vec4::new(0.0, cosa, sina, 0.0),
439 Vec4::new(0.0, -sina, cosa, 0.0),
440 Vec4::W,
441 )
442 }
443
444 #[inline]
450 #[must_use]
451 pub fn from_rotation_y(angle: f32) -> Self {
452 let (sina, cosa) = math::sin_cos(angle);
453 Self::from_cols(
454 Vec4::new(cosa, 0.0, -sina, 0.0),
455 Vec4::Y,
456 Vec4::new(sina, 0.0, cosa, 0.0),
457 Vec4::W,
458 )
459 }
460
461 #[inline]
467 #[must_use]
468 pub fn from_rotation_z(angle: f32) -> Self {
469 let (sina, cosa) = math::sin_cos(angle);
470 Self::from_cols(
471 Vec4::new(cosa, sina, 0.0, 0.0),
472 Vec4::new(-sina, cosa, 0.0, 0.0),
473 Vec4::Z,
474 Vec4::W,
475 )
476 }
477
478 #[inline]
487 #[must_use]
488 pub fn from_scale(scale: Vec3) -> Self {
489 glam_assert!(scale.cmpne(Vec3::ZERO).any());
491
492 Self::from_cols(
493 Vec4::new(scale.x, 0.0, 0.0, 0.0),
494 Vec4::new(0.0, scale.y, 0.0, 0.0),
495 Vec4::new(0.0, 0.0, scale.z, 0.0),
496 Vec4::W,
497 )
498 }
499
500 #[inline]
506 #[must_use]
507 pub const fn from_cols_slice(slice: &[f32]) -> Self {
508 Self::new(
509 slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
510 slice[8], slice[9], slice[10], slice[11], slice[12], slice[13], slice[14], slice[15],
511 )
512 }
513
514 #[inline]
520 pub fn write_cols_to_slice(self, slice: &mut [f32]) {
521 slice[0] = self.x_axis.x;
522 slice[1] = self.x_axis.y;
523 slice[2] = self.x_axis.z;
524 slice[3] = self.x_axis.w;
525 slice[4] = self.y_axis.x;
526 slice[5] = self.y_axis.y;
527 slice[6] = self.y_axis.z;
528 slice[7] = self.y_axis.w;
529 slice[8] = self.z_axis.x;
530 slice[9] = self.z_axis.y;
531 slice[10] = self.z_axis.z;
532 slice[11] = self.z_axis.w;
533 slice[12] = self.w_axis.x;
534 slice[13] = self.w_axis.y;
535 slice[14] = self.w_axis.z;
536 slice[15] = self.w_axis.w;
537 }
538
539 #[inline]
545 #[must_use]
546 pub fn col(&self, index: usize) -> Vec4 {
547 match index {
548 0 => self.x_axis,
549 1 => self.y_axis,
550 2 => self.z_axis,
551 3 => self.w_axis,
552 _ => panic!("index out of bounds"),
553 }
554 }
555
556 #[inline]
562 pub fn col_mut(&mut self, index: usize) -> &mut Vec4 {
563 match index {
564 0 => &mut self.x_axis,
565 1 => &mut self.y_axis,
566 2 => &mut self.z_axis,
567 3 => &mut self.w_axis,
568 _ => panic!("index out of bounds"),
569 }
570 }
571
572 #[inline]
578 #[must_use]
579 pub fn row(&self, index: usize) -> Vec4 {
580 match index {
581 0 => Vec4::new(self.x_axis.x, self.y_axis.x, self.z_axis.x, self.w_axis.x),
582 1 => Vec4::new(self.x_axis.y, self.y_axis.y, self.z_axis.y, self.w_axis.y),
583 2 => Vec4::new(self.x_axis.z, self.y_axis.z, self.z_axis.z, self.w_axis.z),
584 3 => Vec4::new(self.x_axis.w, self.y_axis.w, self.z_axis.w, self.w_axis.w),
585 _ => panic!("index out of bounds"),
586 }
587 }
588
589 #[inline]
592 #[must_use]
593 pub fn is_finite(&self) -> bool {
594 self.x_axis.is_finite()
595 && self.y_axis.is_finite()
596 && self.z_axis.is_finite()
597 && self.w_axis.is_finite()
598 }
599
600 #[inline]
602 #[must_use]
603 pub fn is_nan(&self) -> bool {
604 self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan() || self.w_axis.is_nan()
605 }
606
607 #[inline]
609 #[must_use]
610 pub fn transpose(&self) -> Self {
611 Self {
612 x_axis: Vec4::new(self.x_axis.x, self.y_axis.x, self.z_axis.x, self.w_axis.x),
613 y_axis: Vec4::new(self.x_axis.y, self.y_axis.y, self.z_axis.y, self.w_axis.y),
614 z_axis: Vec4::new(self.x_axis.z, self.y_axis.z, self.z_axis.z, self.w_axis.z),
615 w_axis: Vec4::new(self.x_axis.w, self.y_axis.w, self.z_axis.w, self.w_axis.w),
616 }
617 }
618
619 #[must_use]
621 pub fn determinant(&self) -> f32 {
622 let (m00, m01, m02, m03) = self.x_axis.into();
623 let (m10, m11, m12, m13) = self.y_axis.into();
624 let (m20, m21, m22, m23) = self.z_axis.into();
625 let (m30, m31, m32, m33) = self.w_axis.into();
626
627 let a2323 = m22 * m33 - m23 * m32;
628 let a1323 = m21 * m33 - m23 * m31;
629 let a1223 = m21 * m32 - m22 * m31;
630 let a0323 = m20 * m33 - m23 * m30;
631 let a0223 = m20 * m32 - m22 * m30;
632 let a0123 = m20 * m31 - m21 * m30;
633
634 m00 * (m11 * a2323 - m12 * a1323 + m13 * a1223)
635 - m01 * (m10 * a2323 - m12 * a0323 + m13 * a0223)
636 + m02 * (m10 * a1323 - m11 * a0323 + m13 * a0123)
637 - m03 * (m10 * a1223 - m11 * a0223 + m12 * a0123)
638 }
639
640 #[must_use]
648 pub fn inverse(&self) -> Self {
649 unsafe {
650 let swizzle3377 = |a: float32x4_t, b: float32x4_t| -> float32x4_t {
652 let r = vuzp2q_f32(a, b);
653 vtrn2q_f32(r, r)
654 };
655 let swizzle2266 = |a: float32x4_t, b: float32x4_t| -> float32x4_t {
656 let r = vuzp1q_f32(a, b);
657 vtrn2q_f32(r, r)
658 };
659 let swizzle0046 = |a: float32x4_t, b: float32x4_t| -> float32x4_t {
660 let r = vuzp1q_f32(a, a);
661 vuzp1q_f32(r, b)
662 };
663 let swizzle1155 = |a: float32x4_t, b: float32x4_t| -> float32x4_t {
664 let r = vzip1q_f32(a, b);
665 vzip2q_f32(r, r)
666 };
667 let swizzle0044 = |a: float32x4_t, b: float32x4_t| -> float32x4_t {
668 let r = vuzp1q_f32(a, b);
669 vtrn1q_f32(r, r)
670 };
671 let swizzle0266 = |a: float32x4_t, b: float32x4_t| -> float32x4_t {
672 let r = vuzp1q_f32(a, b);
673 vsetq_lane_f32(vgetq_lane_f32(b, 2), r, 2)
674 };
675 let swizzle0246 = |a: float32x4_t, b: float32x4_t| -> float32x4_t { vuzp1q_f32(a, b) };
676 let fac0 = {
677 let swp0a = swizzle3377(self.w_axis.0, self.z_axis.0);
678 let swp0b = swizzle2266(self.w_axis.0, self.z_axis.0);
679
680 let swp00 = swizzle2266(self.z_axis.0, self.y_axis.0);
681 let swp01 = swizzle0046(swp0a, swp0a);
682 let swp02 = swizzle0046(swp0b, swp0b);
683 let swp03 = swizzle3377(self.z_axis.0, self.y_axis.0);
684
685 let mul00 = vmulq_f32(swp00, swp01);
686 let mul01 = vmulq_f32(swp02, swp03);
687 vsubq_f32(mul00, mul01)
688 };
689 let fac1 = {
690 let swp0a = swizzle3377(self.w_axis.0, self.z_axis.0);
691 let swp0b = swizzle1155(self.w_axis.0, self.z_axis.0);
692
693 let swp00 = swizzle1155(self.z_axis.0, self.y_axis.0);
694 let swp01 = swizzle0046(swp0a, swp0a);
695 let swp02 = swizzle0046(swp0b, swp0b);
696 let swp03 = swizzle3377(self.z_axis.0, self.y_axis.0);
697
698 let mul00 = vmulq_f32(swp00, swp01);
699 let mul01 = vmulq_f32(swp02, swp03);
700 vsubq_f32(mul00, mul01)
701 };
702 let fac2 = {
703 let swp0a = swizzle2266(self.w_axis.0, self.z_axis.0);
704 let swp0b = swizzle1155(self.w_axis.0, self.z_axis.0);
705
706 let swp00 = swizzle1155(self.z_axis.0, self.y_axis.0);
707 let swp01 = swizzle0046(swp0a, swp0a);
708 let swp02 = swizzle0046(swp0b, swp0b);
709 let swp03 = swizzle2266(self.z_axis.0, self.y_axis.0);
710
711 let mul00 = vmulq_f32(swp00, swp01);
712 let mul01 = vmulq_f32(swp02, swp03);
713 vsubq_f32(mul00, mul01)
714 };
715 let fac3 = {
716 let swp0a = swizzle3377(self.w_axis.0, self.z_axis.0);
717 let swp0b = swizzle0044(self.w_axis.0, self.z_axis.0);
718
719 let swp00 = swizzle0044(self.z_axis.0, self.y_axis.0);
720 let swp01 = swizzle0046(swp0a, swp0a);
721 let swp02 = swizzle0046(swp0b, swp0b);
722 let swp03 = swizzle3377(self.z_axis.0, self.y_axis.0);
723
724 let mul00 = vmulq_f32(swp00, swp01);
725 let mul01 = vmulq_f32(swp02, swp03);
726 vsubq_f32(mul00, mul01)
727 };
728 let fac4 = {
729 let swp0a = swizzle2266(self.w_axis.0, self.z_axis.0);
730 let swp0b = swizzle0044(self.w_axis.0, self.z_axis.0);
731
732 let swp00 = swizzle0044(self.z_axis.0, self.y_axis.0);
733 let swp01 = swizzle0046(swp0a, swp0a);
734 let swp02 = swizzle0046(swp0b, swp0b);
735 let swp03 = swizzle2266(self.z_axis.0, self.y_axis.0);
736
737 let mul00 = vmulq_f32(swp00, swp01);
738 let mul01 = vmulq_f32(swp02, swp03);
739 vsubq_f32(mul00, mul01)
740 };
741 let fac5 = {
742 let swp0a = swizzle1155(self.w_axis.0, self.z_axis.0);
743 let swp0b = swizzle0044(self.w_axis.0, self.z_axis.0);
744
745 let swp00 = swizzle0044(self.z_axis.0, self.y_axis.0);
746 let swp01 = swizzle0046(swp0a, swp0a);
747 let swp02 = swizzle0046(swp0b, swp0b);
748 let swp03 = swizzle1155(self.z_axis.0, self.y_axis.0);
749
750 let mul00 = vmulq_f32(swp00, swp01);
751 let mul01 = vmulq_f32(swp02, swp03);
752 vsubq_f32(mul00, mul01)
753 };
754
755 const SIGN_A: float32x4_t = Vec4::new(-1.0, 1.0, -1.0, 1.0).0;
756 const SIGN_B: float32x4_t = Vec4::new(1.0, -1.0, 1.0, -1.0).0;
757
758 let temp0 = swizzle0044(self.y_axis.0, self.x_axis.0);
759 let vec0 = swizzle0266(temp0, temp0);
760
761 let temp1 = swizzle1155(self.y_axis.0, self.x_axis.0);
762 let vec1 = swizzle0266(temp1, temp1);
763
764 let temp2 = swizzle2266(self.y_axis.0, self.x_axis.0);
765 let vec2 = swizzle0266(temp2, temp2);
766
767 let temp3 = swizzle3377(self.y_axis.0, self.x_axis.0);
768 let vec3 = swizzle0266(temp3, temp3);
769
770 let mul00 = vmulq_f32(vec1, fac0);
771 let mul01 = vmulq_f32(vec2, fac1);
772 let mul02 = vmulq_f32(vec3, fac2);
773 let sub00 = vsubq_f32(mul00, mul01);
774 let add00 = vaddq_f32(sub00, mul02);
775 let inv0 = vmulq_f32(SIGN_B, add00);
776
777 let mul03 = vmulq_f32(vec0, fac0);
778 let mul04 = vmulq_f32(vec2, fac3);
779 let mul05 = vmulq_f32(vec3, fac4);
780 let sub01 = vsubq_f32(mul03, mul04);
781 let add01 = vaddq_f32(sub01, mul05);
782 let inv1 = vmulq_f32(SIGN_A, add01);
783
784 let mul06 = vmulq_f32(vec0, fac1);
785 let mul07 = vmulq_f32(vec1, fac3);
786 let mul08 = vmulq_f32(vec3, fac5);
787 let sub02 = vsubq_f32(mul06, mul07);
788 let add02 = vaddq_f32(sub02, mul08);
789 let inv2 = vmulq_f32(SIGN_B, add02);
790
791 let mul09 = vmulq_f32(vec0, fac2);
792 let mul10 = vmulq_f32(vec1, fac4);
793 let mul11 = vmulq_f32(vec2, fac5);
794 let sub03 = vsubq_f32(mul09, mul10);
795 let add03 = vaddq_f32(sub03, mul11);
796 let inv3 = vmulq_f32(SIGN_A, add03);
797
798 let row0 = swizzle0044(inv0, inv1);
799 let row1 = swizzle0044(inv2, inv3);
800 let row2 = swizzle0246(row0, row1);
801
802 let dot0 = dot4(self.x_axis.0, row2);
803 glam_assert!(dot0 != 0.0);
804
805 let rcp0 = dot0.recip();
806
807 Self {
808 x_axis: Vec4(vmulq_n_f32(inv0, rcp0)),
809 y_axis: Vec4(vmulq_n_f32(inv1, rcp0)),
810 z_axis: Vec4(vmulq_n_f32(inv2, rcp0)),
811 w_axis: Vec4(vmulq_n_f32(inv3, rcp0)),
812 }
813 }
814 }
815
816 #[inline]
825 #[must_use]
826 pub fn look_to_lh(eye: Vec3, dir: Vec3, up: Vec3) -> Self {
827 Self::look_to_rh(eye, -dir, up)
828 }
829
830 #[inline]
839 #[must_use]
840 pub fn look_to_rh(eye: Vec3, dir: Vec3, up: Vec3) -> Self {
841 glam_assert!(dir.is_normalized());
842 glam_assert!(up.is_normalized());
843 let f = dir;
844 let s = f.cross(up).normalize();
845 let u = s.cross(f);
846
847 Self::from_cols(
848 Vec4::new(s.x, u.x, -f.x, 0.0),
849 Vec4::new(s.y, u.y, -f.y, 0.0),
850 Vec4::new(s.z, u.z, -f.z, 0.0),
851 Vec4::new(-eye.dot(s), -eye.dot(u), eye.dot(f), 1.0),
852 )
853 }
854
855 #[inline]
864 #[must_use]
865 pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
866 Self::look_to_lh(eye, center.sub(eye).normalize(), up)
867 }
868
869 #[inline]
878 pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
879 Self::look_to_rh(eye, center.sub(eye).normalize(), up)
880 }
881
882 #[inline]
888 #[must_use]
889 pub fn frustum_rh_gl(
890 left: f32,
891 right: f32,
892 bottom: f32,
893 top: f32,
894 z_near: f32,
895 z_far: f32,
896 ) -> Self {
897 let inv_width = 1.0 / (right - left);
898 let inv_height = 1.0 / (top - bottom);
899 let inv_depth = 1.0 / (z_far - z_near);
900 let a = (right + left) * inv_width;
901 let b = (top + bottom) * inv_height;
902 let c = -(z_far + z_near) * inv_depth;
903 let d = -(2.0 * z_far * z_near) * inv_depth;
904 let two_z_near = 2.0 * z_near;
905 Self::from_cols(
906 Vec4::new(two_z_near * inv_width, 0.0, 0.0, 0.0),
907 Vec4::new(0.0, two_z_near * inv_height, 0.0, 0.0),
908 Vec4::new(a, b, c, -1.0),
909 Vec4::new(0.0, 0.0, d, 0.0),
910 )
911 }
912
913 #[inline]
920 #[must_use]
921 pub fn frustum_lh(
922 left: f32,
923 right: f32,
924 bottom: f32,
925 top: f32,
926 z_near: f32,
927 z_far: f32,
928 ) -> Self {
929 glam_assert!(z_near > 0.0 && z_far > 0.0);
930 let inv_width = 1.0 / (right - left);
931 let inv_height = 1.0 / (top - bottom);
932 let inv_depth = 1.0 / (z_far - z_near);
933 let a = (right + left) * inv_width;
934 let b = (top + bottom) * inv_height;
935 let c = z_far * inv_depth;
936 let d = -(z_far * z_near) * inv_depth;
937 let two_z_near = 2.0 * z_near;
938 Self::from_cols(
939 Vec4::new(two_z_near * inv_width, 0.0, 0.0, 0.0),
940 Vec4::new(0.0, two_z_near * inv_height, 0.0, 0.0),
941 Vec4::new(a, b, c, 1.0),
942 Vec4::new(0.0, 0.0, d, 0.0),
943 )
944 }
945
946 #[inline]
953 #[must_use]
954 pub fn frustum_rh(
955 left: f32,
956 right: f32,
957 bottom: f32,
958 top: f32,
959 z_near: f32,
960 z_far: f32,
961 ) -> Self {
962 glam_assert!(z_near > 0.0 && z_far > 0.0);
963 let inv_width = 1.0 / (right - left);
964 let inv_height = 1.0 / (top - bottom);
965 let inv_depth = 1.0 / (z_far - z_near);
966 let a = (right + left) * inv_width;
967 let b = (top + bottom) * inv_height;
968 let c = -z_far * inv_depth;
969 let d = -(z_far * z_near) * inv_depth;
970 let two_z_near = 2.0 * z_near;
971 Self::from_cols(
972 Vec4::new(two_z_near * inv_width, 0.0, 0.0, 0.0),
973 Vec4::new(0.0, two_z_near * inv_height, 0.0, 0.0),
974 Vec4::new(a, b, c, -1.0),
975 Vec4::new(0.0, 0.0, d, 0.0),
976 )
977 }
978
979 #[inline]
986 #[must_use]
987 pub fn perspective_rh_gl(
988 fov_y_radians: f32,
989 aspect_ratio: f32,
990 z_near: f32,
991 z_far: f32,
992 ) -> Self {
993 let inv_length = 1.0 / (z_near - z_far);
994 let f = 1.0 / math::tan(0.5 * fov_y_radians);
995 let a = f / aspect_ratio;
996 let b = (z_near + z_far) * inv_length;
997 let c = (2.0 * z_near * z_far) * inv_length;
998 Self::from_cols(
999 Vec4::new(a, 0.0, 0.0, 0.0),
1000 Vec4::new(0.0, f, 0.0, 0.0),
1001 Vec4::new(0.0, 0.0, b, -1.0),
1002 Vec4::new(0.0, 0.0, c, 0.0),
1003 )
1004 }
1005
1006 #[inline]
1015 #[must_use]
1016 pub fn perspective_lh(fov_y_radians: f32, aspect_ratio: f32, z_near: f32, z_far: f32) -> Self {
1017 glam_assert!(z_near > 0.0 && z_far > 0.0);
1018 let (sin_fov, cos_fov) = math::sin_cos(0.5 * fov_y_radians);
1019 let h = cos_fov / sin_fov;
1020 let w = h / aspect_ratio;
1021 let r = z_far / (z_far - z_near);
1022 Self::from_cols(
1023 Vec4::new(w, 0.0, 0.0, 0.0),
1024 Vec4::new(0.0, h, 0.0, 0.0),
1025 Vec4::new(0.0, 0.0, r, 1.0),
1026 Vec4::new(0.0, 0.0, -r * z_near, 0.0),
1027 )
1028 }
1029
1030 #[inline]
1039 #[must_use]
1040 pub fn perspective_rh(fov_y_radians: f32, aspect_ratio: f32, z_near: f32, z_far: f32) -> Self {
1041 glam_assert!(z_near > 0.0 && z_far > 0.0);
1042 let (sin_fov, cos_fov) = math::sin_cos(0.5 * fov_y_radians);
1043 let h = cos_fov / sin_fov;
1044 let w = h / aspect_ratio;
1045 let r = z_far / (z_near - z_far);
1046 Self::from_cols(
1047 Vec4::new(w, 0.0, 0.0, 0.0),
1048 Vec4::new(0.0, h, 0.0, 0.0),
1049 Vec4::new(0.0, 0.0, r, -1.0),
1050 Vec4::new(0.0, 0.0, r * z_near, 0.0),
1051 )
1052 }
1053
1054 #[inline]
1064 #[must_use]
1065 pub fn perspective_infinite_lh(fov_y_radians: f32, aspect_ratio: f32, z_near: f32) -> Self {
1066 glam_assert!(z_near > 0.0);
1067 let (sin_fov, cos_fov) = math::sin_cos(0.5 * fov_y_radians);
1068 let h = cos_fov / sin_fov;
1069 let w = h / aspect_ratio;
1070 Self::from_cols(
1071 Vec4::new(w, 0.0, 0.0, 0.0),
1072 Vec4::new(0.0, h, 0.0, 0.0),
1073 Vec4::new(0.0, 0.0, 1.0, 1.0),
1074 Vec4::new(0.0, 0.0, -z_near, 0.0),
1075 )
1076 }
1077
1078 #[inline]
1086 #[must_use]
1087 pub fn perspective_infinite_reverse_lh(
1088 fov_y_radians: f32,
1089 aspect_ratio: f32,
1090 z_near: f32,
1091 ) -> Self {
1092 glam_assert!(z_near > 0.0);
1093 let (sin_fov, cos_fov) = math::sin_cos(0.5 * fov_y_radians);
1094 let h = cos_fov / sin_fov;
1095 let w = h / aspect_ratio;
1096 Self::from_cols(
1097 Vec4::new(w, 0.0, 0.0, 0.0),
1098 Vec4::new(0.0, h, 0.0, 0.0),
1099 Vec4::new(0.0, 0.0, 0.0, 1.0),
1100 Vec4::new(0.0, 0.0, z_near, 0.0),
1101 )
1102 }
1103
1104 #[inline]
1114 #[must_use]
1115 pub fn perspective_infinite_rh(fov_y_radians: f32, aspect_ratio: f32, z_near: f32) -> Self {
1116 glam_assert!(z_near > 0.0);
1117 let f = 1.0 / math::tan(0.5 * fov_y_radians);
1118 Self::from_cols(
1119 Vec4::new(f / aspect_ratio, 0.0, 0.0, 0.0),
1120 Vec4::new(0.0, f, 0.0, 0.0),
1121 Vec4::new(0.0, 0.0, -1.0, -1.0),
1122 Vec4::new(0.0, 0.0, -z_near, 0.0),
1123 )
1124 }
1125
1126 #[inline]
1134 #[must_use]
1135 pub fn perspective_infinite_reverse_rh(
1136 fov_y_radians: f32,
1137 aspect_ratio: f32,
1138 z_near: f32,
1139 ) -> Self {
1140 glam_assert!(z_near > 0.0);
1141 let f = 1.0 / math::tan(0.5 * fov_y_radians);
1142 Self::from_cols(
1143 Vec4::new(f / aspect_ratio, 0.0, 0.0, 0.0),
1144 Vec4::new(0.0, f, 0.0, 0.0),
1145 Vec4::new(0.0, 0.0, 0.0, -1.0),
1146 Vec4::new(0.0, 0.0, z_near, 0.0),
1147 )
1148 }
1149
1150 #[inline]
1157 #[must_use]
1158 pub fn orthographic_rh_gl(
1159 left: f32,
1160 right: f32,
1161 bottom: f32,
1162 top: f32,
1163 near: f32,
1164 far: f32,
1165 ) -> Self {
1166 let a = 2.0 / (right - left);
1167 let b = 2.0 / (top - bottom);
1168 let c = -2.0 / (far - near);
1169 let tx = -(right + left) / (right - left);
1170 let ty = -(top + bottom) / (top - bottom);
1171 let tz = -(far + near) / (far - near);
1172
1173 Self::from_cols(
1174 Vec4::new(a, 0.0, 0.0, 0.0),
1175 Vec4::new(0.0, b, 0.0, 0.0),
1176 Vec4::new(0.0, 0.0, c, 0.0),
1177 Vec4::new(tx, ty, tz, 1.0),
1178 )
1179 }
1180
1181 #[inline]
1185 #[must_use]
1186 pub fn orthographic_lh(
1187 left: f32,
1188 right: f32,
1189 bottom: f32,
1190 top: f32,
1191 near: f32,
1192 far: f32,
1193 ) -> Self {
1194 let rcp_width = 1.0 / (right - left);
1195 let rcp_height = 1.0 / (top - bottom);
1196 let r = 1.0 / (far - near);
1197 Self::from_cols(
1198 Vec4::new(rcp_width + rcp_width, 0.0, 0.0, 0.0),
1199 Vec4::new(0.0, rcp_height + rcp_height, 0.0, 0.0),
1200 Vec4::new(0.0, 0.0, r, 0.0),
1201 Vec4::new(
1202 -(left + right) * rcp_width,
1203 -(top + bottom) * rcp_height,
1204 -r * near,
1205 1.0,
1206 ),
1207 )
1208 }
1209
1210 #[inline]
1214 #[must_use]
1215 pub fn orthographic_rh(
1216 left: f32,
1217 right: f32,
1218 bottom: f32,
1219 top: f32,
1220 near: f32,
1221 far: f32,
1222 ) -> Self {
1223 let rcp_width = 1.0 / (right - left);
1224 let rcp_height = 1.0 / (top - bottom);
1225 let r = 1.0 / (near - far);
1226 Self::from_cols(
1227 Vec4::new(rcp_width + rcp_width, 0.0, 0.0, 0.0),
1228 Vec4::new(0.0, rcp_height + rcp_height, 0.0, 0.0),
1229 Vec4::new(0.0, 0.0, r, 0.0),
1230 Vec4::new(
1231 -(left + right) * rcp_width,
1232 -(top + bottom) * rcp_height,
1233 r * near,
1234 1.0,
1235 ),
1236 )
1237 }
1238
1239 #[inline]
1246 #[must_use]
1247 pub fn project_point3(&self, rhs: Vec3) -> Vec3 {
1248 let mut res = self.x_axis.mul(rhs.x);
1249 res = self.y_axis.mul(rhs.y).add(res);
1250 res = self.z_axis.mul(rhs.z).add(res);
1251 res = self.w_axis.add(res);
1252 res = res.div(res.w);
1253 res.xyz()
1254 }
1255
1256 #[inline]
1269 #[must_use]
1270 pub fn transform_point3(&self, rhs: Vec3) -> Vec3 {
1271 glam_assert!(self.row(3).abs_diff_eq(Vec4::W, 1e-6));
1272 let mut res = self.x_axis.mul(rhs.x);
1273 res = self.y_axis.mul(rhs.y).add(res);
1274 res = self.z_axis.mul(rhs.z).add(res);
1275 res = self.w_axis.add(res);
1276 res.xyz()
1277 }
1278
1279 #[inline]
1290 #[must_use]
1291 pub fn transform_vector3(&self, rhs: Vec3) -> Vec3 {
1292 glam_assert!(self.row(3).abs_diff_eq(Vec4::W, 1e-6));
1293 let mut res = self.x_axis.mul(rhs.x);
1294 res = self.y_axis.mul(rhs.y).add(res);
1295 res = self.z_axis.mul(rhs.z).add(res);
1296 res.xyz()
1297 }
1298
1299 #[inline]
1306 #[must_use]
1307 pub fn project_point3a(&self, rhs: Vec3A) -> Vec3A {
1308 let mut res = self.x_axis.mul(rhs.xxxx());
1309 res = self.y_axis.mul(rhs.yyyy()).add(res);
1310 res = self.z_axis.mul(rhs.zzzz()).add(res);
1311 res = self.w_axis.add(res);
1312 res = res.div(res.wwww());
1313 Vec3A::from_vec4(res)
1314 }
1315
1316 #[inline]
1320 #[must_use]
1321 pub fn transform_point3a(&self, rhs: Vec3A) -> Vec3A {
1322 glam_assert!(self.row(3).abs_diff_eq(Vec4::W, 1e-6));
1323 let mut res = self.x_axis.mul(rhs.xxxx());
1324 res = self.y_axis.mul(rhs.yyyy()).add(res);
1325 res = self.z_axis.mul(rhs.zzzz()).add(res);
1326 res = self.w_axis.add(res);
1327 Vec3A::from_vec4(res)
1328 }
1329
1330 #[inline]
1334 #[must_use]
1335 pub fn transform_vector3a(&self, rhs: Vec3A) -> Vec3A {
1336 glam_assert!(self.row(3).abs_diff_eq(Vec4::W, 1e-6));
1337 let mut res = self.x_axis.mul(rhs.xxxx());
1338 res = self.y_axis.mul(rhs.yyyy()).add(res);
1339 res = self.z_axis.mul(rhs.zzzz()).add(res);
1340 Vec3A::from_vec4(res)
1341 }
1342
1343 #[inline]
1345 #[must_use]
1346 pub fn mul_vec4(&self, rhs: Vec4) -> Vec4 {
1347 let mut res = self.x_axis.mul(rhs.xxxx());
1348 res = res.add(self.y_axis.mul(rhs.yyyy()));
1349 res = res.add(self.z_axis.mul(rhs.zzzz()));
1350 res = res.add(self.w_axis.mul(rhs.wwww()));
1351 res
1352 }
1353
1354 #[inline]
1356 #[must_use]
1357 pub fn mul_mat4(&self, rhs: &Self) -> Self {
1358 self.mul(rhs)
1359 }
1360
1361 #[inline]
1363 #[must_use]
1364 pub fn add_mat4(&self, rhs: &Self) -> Self {
1365 self.add(rhs)
1366 }
1367
1368 #[inline]
1370 #[must_use]
1371 pub fn sub_mat4(&self, rhs: &Self) -> Self {
1372 self.sub(rhs)
1373 }
1374
1375 #[inline]
1377 #[must_use]
1378 pub fn mul_scalar(&self, rhs: f32) -> Self {
1379 Self::from_cols(
1380 self.x_axis.mul(rhs),
1381 self.y_axis.mul(rhs),
1382 self.z_axis.mul(rhs),
1383 self.w_axis.mul(rhs),
1384 )
1385 }
1386
1387 #[inline]
1389 #[must_use]
1390 pub fn div_scalar(&self, rhs: f32) -> Self {
1391 let rhs = Vec4::splat(rhs);
1392 Self::from_cols(
1393 self.x_axis.div(rhs),
1394 self.y_axis.div(rhs),
1395 self.z_axis.div(rhs),
1396 self.w_axis.div(rhs),
1397 )
1398 }
1399
1400 #[inline]
1410 #[must_use]
1411 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
1412 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
1413 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
1414 && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
1415 && self.w_axis.abs_diff_eq(rhs.w_axis, max_abs_diff)
1416 }
1417
1418 #[inline]
1420 #[must_use]
1421 pub fn abs(&self) -> Self {
1422 Self::from_cols(
1423 self.x_axis.abs(),
1424 self.y_axis.abs(),
1425 self.z_axis.abs(),
1426 self.w_axis.abs(),
1427 )
1428 }
1429
1430 #[inline]
1431 pub fn as_dmat4(&self) -> DMat4 {
1432 DMat4::from_cols(
1433 self.x_axis.as_dvec4(),
1434 self.y_axis.as_dvec4(),
1435 self.z_axis.as_dvec4(),
1436 self.w_axis.as_dvec4(),
1437 )
1438 }
1439}
1440
1441impl Default for Mat4 {
1442 #[inline]
1443 fn default() -> Self {
1444 Self::IDENTITY
1445 }
1446}
1447
1448impl Add for Mat4 {
1449 type Output = Self;
1450 #[inline]
1451 fn add(self, rhs: Self) -> Self {
1452 Self::from_cols(
1453 self.x_axis.add(rhs.x_axis),
1454 self.y_axis.add(rhs.y_axis),
1455 self.z_axis.add(rhs.z_axis),
1456 self.w_axis.add(rhs.w_axis),
1457 )
1458 }
1459}
1460
1461impl Add<&Self> for Mat4 {
1462 type Output = Self;
1463 #[inline]
1464 fn add(self, rhs: &Self) -> Self {
1465 self.add(*rhs)
1466 }
1467}
1468
1469impl Add<&Mat4> for &Mat4 {
1470 type Output = Mat4;
1471 #[inline]
1472 fn add(self, rhs: &Mat4) -> Mat4 {
1473 (*self).add(*rhs)
1474 }
1475}
1476
1477impl Add<Mat4> for &Mat4 {
1478 type Output = Mat4;
1479 #[inline]
1480 fn add(self, rhs: Mat4) -> Mat4 {
1481 (*self).add(rhs)
1482 }
1483}
1484
1485impl AddAssign for Mat4 {
1486 #[inline]
1487 fn add_assign(&mut self, rhs: Self) {
1488 *self = self.add(rhs);
1489 }
1490}
1491
1492impl AddAssign<&Self> for Mat4 {
1493 #[inline]
1494 fn add_assign(&mut self, rhs: &Self) {
1495 self.add_assign(*rhs);
1496 }
1497}
1498
1499impl Sub for Mat4 {
1500 type Output = Self;
1501 #[inline]
1502 fn sub(self, rhs: Self) -> Self {
1503 Self::from_cols(
1504 self.x_axis.sub(rhs.x_axis),
1505 self.y_axis.sub(rhs.y_axis),
1506 self.z_axis.sub(rhs.z_axis),
1507 self.w_axis.sub(rhs.w_axis),
1508 )
1509 }
1510}
1511
1512impl Sub<&Self> for Mat4 {
1513 type Output = Self;
1514 #[inline]
1515 fn sub(self, rhs: &Self) -> Self {
1516 self.sub(*rhs)
1517 }
1518}
1519
1520impl Sub<&Mat4> for &Mat4 {
1521 type Output = Mat4;
1522 #[inline]
1523 fn sub(self, rhs: &Mat4) -> Mat4 {
1524 (*self).sub(*rhs)
1525 }
1526}
1527
1528impl Sub<Mat4> for &Mat4 {
1529 type Output = Mat4;
1530 #[inline]
1531 fn sub(self, rhs: Mat4) -> Mat4 {
1532 (*self).sub(rhs)
1533 }
1534}
1535
1536impl SubAssign for Mat4 {
1537 #[inline]
1538 fn sub_assign(&mut self, rhs: Self) {
1539 *self = self.sub(rhs);
1540 }
1541}
1542
1543impl SubAssign<&Self> for Mat4 {
1544 #[inline]
1545 fn sub_assign(&mut self, rhs: &Self) {
1546 self.sub_assign(*rhs);
1547 }
1548}
1549
1550impl Neg for Mat4 {
1551 type Output = Self;
1552 #[inline]
1553 fn neg(self) -> Self::Output {
1554 Self::from_cols(
1555 self.x_axis.neg(),
1556 self.y_axis.neg(),
1557 self.z_axis.neg(),
1558 self.w_axis.neg(),
1559 )
1560 }
1561}
1562
1563impl Neg for &Mat4 {
1564 type Output = Mat4;
1565 #[inline]
1566 fn neg(self) -> Mat4 {
1567 (*self).neg()
1568 }
1569}
1570
1571impl Mul for Mat4 {
1572 type Output = Self;
1573 #[inline]
1574 fn mul(self, rhs: Self) -> Self {
1575 Self::from_cols(
1576 self.mul(rhs.x_axis),
1577 self.mul(rhs.y_axis),
1578 self.mul(rhs.z_axis),
1579 self.mul(rhs.w_axis),
1580 )
1581 }
1582}
1583
1584impl Mul<&Self> for Mat4 {
1585 type Output = Self;
1586 #[inline]
1587 fn mul(self, rhs: &Self) -> Self {
1588 self.mul(*rhs)
1589 }
1590}
1591
1592impl Mul<&Mat4> for &Mat4 {
1593 type Output = Mat4;
1594 #[inline]
1595 fn mul(self, rhs: &Mat4) -> Mat4 {
1596 (*self).mul(*rhs)
1597 }
1598}
1599
1600impl Mul<Mat4> for &Mat4 {
1601 type Output = Mat4;
1602 #[inline]
1603 fn mul(self, rhs: Mat4) -> Mat4 {
1604 (*self).mul(rhs)
1605 }
1606}
1607
1608impl MulAssign for Mat4 {
1609 #[inline]
1610 fn mul_assign(&mut self, rhs: Self) {
1611 *self = self.mul(rhs);
1612 }
1613}
1614
1615impl MulAssign<&Self> for Mat4 {
1616 #[inline]
1617 fn mul_assign(&mut self, rhs: &Self) {
1618 self.mul_assign(*rhs);
1619 }
1620}
1621
1622impl Mul<Vec4> for Mat4 {
1623 type Output = Vec4;
1624 #[inline]
1625 fn mul(self, rhs: Vec4) -> Self::Output {
1626 self.mul_vec4(rhs)
1627 }
1628}
1629
1630impl Mul<&Vec4> for Mat4 {
1631 type Output = Vec4;
1632 #[inline]
1633 fn mul(self, rhs: &Vec4) -> Vec4 {
1634 self.mul(*rhs)
1635 }
1636}
1637
1638impl Mul<&Vec4> for &Mat4 {
1639 type Output = Vec4;
1640 #[inline]
1641 fn mul(self, rhs: &Vec4) -> Vec4 {
1642 (*self).mul(*rhs)
1643 }
1644}
1645
1646impl Mul<Vec4> for &Mat4 {
1647 type Output = Vec4;
1648 #[inline]
1649 fn mul(self, rhs: Vec4) -> Vec4 {
1650 (*self).mul(rhs)
1651 }
1652}
1653
1654impl Mul<Mat4> for f32 {
1655 type Output = Mat4;
1656 #[inline]
1657 fn mul(self, rhs: Mat4) -> Self::Output {
1658 rhs.mul_scalar(self)
1659 }
1660}
1661
1662impl Mul<&Mat4> for f32 {
1663 type Output = Mat4;
1664 #[inline]
1665 fn mul(self, rhs: &Mat4) -> Mat4 {
1666 self.mul(*rhs)
1667 }
1668}
1669
1670impl Mul<&Mat4> for &f32 {
1671 type Output = Mat4;
1672 #[inline]
1673 fn mul(self, rhs: &Mat4) -> Mat4 {
1674 (*self).mul(*rhs)
1675 }
1676}
1677
1678impl Mul<Mat4> for &f32 {
1679 type Output = Mat4;
1680 #[inline]
1681 fn mul(self, rhs: Mat4) -> Mat4 {
1682 (*self).mul(rhs)
1683 }
1684}
1685
1686impl Mul<f32> for Mat4 {
1687 type Output = Self;
1688 #[inline]
1689 fn mul(self, rhs: f32) -> Self {
1690 self.mul_scalar(rhs)
1691 }
1692}
1693
1694impl Mul<&f32> for Mat4 {
1695 type Output = Self;
1696 #[inline]
1697 fn mul(self, rhs: &f32) -> Self {
1698 self.mul(*rhs)
1699 }
1700}
1701
1702impl Mul<&f32> for &Mat4 {
1703 type Output = Mat4;
1704 #[inline]
1705 fn mul(self, rhs: &f32) -> Mat4 {
1706 (*self).mul(*rhs)
1707 }
1708}
1709
1710impl Mul<f32> for &Mat4 {
1711 type Output = Mat4;
1712 #[inline]
1713 fn mul(self, rhs: f32) -> Mat4 {
1714 (*self).mul(rhs)
1715 }
1716}
1717
1718impl MulAssign<f32> for Mat4 {
1719 #[inline]
1720 fn mul_assign(&mut self, rhs: f32) {
1721 *self = self.mul(rhs);
1722 }
1723}
1724
1725impl MulAssign<&f32> for Mat4 {
1726 #[inline]
1727 fn mul_assign(&mut self, rhs: &f32) {
1728 self.mul_assign(*rhs);
1729 }
1730}
1731
1732impl Div<Mat4> for f32 {
1733 type Output = Mat4;
1734 #[inline]
1735 fn div(self, rhs: Mat4) -> Self::Output {
1736 rhs.div_scalar(self)
1737 }
1738}
1739
1740impl Div<&Mat4> for f32 {
1741 type Output = Mat4;
1742 #[inline]
1743 fn div(self, rhs: &Mat4) -> Mat4 {
1744 self.div(*rhs)
1745 }
1746}
1747
1748impl Div<&Mat4> for &f32 {
1749 type Output = Mat4;
1750 #[inline]
1751 fn div(self, rhs: &Mat4) -> Mat4 {
1752 (*self).div(*rhs)
1753 }
1754}
1755
1756impl Div<Mat4> for &f32 {
1757 type Output = Mat4;
1758 #[inline]
1759 fn div(self, rhs: Mat4) -> Mat4 {
1760 (*self).div(rhs)
1761 }
1762}
1763
1764impl Div<f32> for Mat4 {
1765 type Output = Self;
1766 #[inline]
1767 fn div(self, rhs: f32) -> Self {
1768 self.div_scalar(rhs)
1769 }
1770}
1771
1772impl Div<&f32> for Mat4 {
1773 type Output = Self;
1774 #[inline]
1775 fn div(self, rhs: &f32) -> Self {
1776 self.div(*rhs)
1777 }
1778}
1779
1780impl Div<&f32> for &Mat4 {
1781 type Output = Mat4;
1782 #[inline]
1783 fn div(self, rhs: &f32) -> Mat4 {
1784 (*self).div(*rhs)
1785 }
1786}
1787
1788impl Div<f32> for &Mat4 {
1789 type Output = Mat4;
1790 #[inline]
1791 fn div(self, rhs: f32) -> Mat4 {
1792 (*self).div(rhs)
1793 }
1794}
1795
1796impl DivAssign<f32> for Mat4 {
1797 #[inline]
1798 fn div_assign(&mut self, rhs: f32) {
1799 *self = self.div(rhs);
1800 }
1801}
1802
1803impl DivAssign<&f32> for Mat4 {
1804 #[inline]
1805 fn div_assign(&mut self, rhs: &f32) {
1806 self.div_assign(*rhs);
1807 }
1808}
1809
1810impl Sum<Self> for Mat4 {
1811 fn sum<I>(iter: I) -> Self
1812 where
1813 I: Iterator<Item = Self>,
1814 {
1815 iter.fold(Self::ZERO, Self::add)
1816 }
1817}
1818
1819impl<'a> Sum<&'a Self> for Mat4 {
1820 fn sum<I>(iter: I) -> Self
1821 where
1822 I: Iterator<Item = &'a Self>,
1823 {
1824 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1825 }
1826}
1827
1828impl Product for Mat4 {
1829 fn product<I>(iter: I) -> Self
1830 where
1831 I: Iterator<Item = Self>,
1832 {
1833 iter.fold(Self::IDENTITY, Self::mul)
1834 }
1835}
1836
1837impl<'a> Product<&'a Self> for Mat4 {
1838 fn product<I>(iter: I) -> Self
1839 where
1840 I: Iterator<Item = &'a Self>,
1841 {
1842 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1843 }
1844}
1845
1846impl PartialEq for Mat4 {
1847 #[inline]
1848 fn eq(&self, rhs: &Self) -> bool {
1849 self.x_axis.eq(&rhs.x_axis)
1850 && self.y_axis.eq(&rhs.y_axis)
1851 && self.z_axis.eq(&rhs.z_axis)
1852 && self.w_axis.eq(&rhs.w_axis)
1853 }
1854}
1855
1856impl AsRef<[f32; 16]> for Mat4 {
1857 #[inline]
1858 fn as_ref(&self) -> &[f32; 16] {
1859 unsafe { &*(self as *const Self as *const [f32; 16]) }
1860 }
1861}
1862
1863impl AsMut<[f32; 16]> for Mat4 {
1864 #[inline]
1865 fn as_mut(&mut self) -> &mut [f32; 16] {
1866 unsafe { &mut *(self as *mut Self as *mut [f32; 16]) }
1867 }
1868}
1869
1870impl fmt::Debug for Mat4 {
1871 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1872 fmt.debug_struct(stringify!(Mat4))
1873 .field("x_axis", &self.x_axis)
1874 .field("y_axis", &self.y_axis)
1875 .field("z_axis", &self.z_axis)
1876 .field("w_axis", &self.w_axis)
1877 .finish()
1878 }
1879}
1880
1881impl fmt::Display for Mat4 {
1882 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1883 if let Some(p) = f.precision() {
1884 write!(
1885 f,
1886 "[{:.*}, {:.*}, {:.*}, {:.*}]",
1887 p, self.x_axis, p, self.y_axis, p, self.z_axis, p, self.w_axis
1888 )
1889 } else {
1890 write!(
1891 f,
1892 "[{}, {}, {}, {}]",
1893 self.x_axis, self.y_axis, self.z_axis, self.w_axis
1894 )
1895 }
1896 }
1897}