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