1use crate::{
4 euler::{FromEuler, ToEuler},
5 f64::math,
6 swizzles::*,
7 DMat3, DQuat, DVec3, DVec4, EulerRot, Mat4,
8};
9use core::fmt;
10use core::iter::{Product, Sum};
11use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
12
13#[cfg(feature = "zerocopy-08")]
14use zerocopy_derive_08::*;
15
16#[inline(always)]
18#[must_use]
19pub const fn dmat4(x_axis: DVec4, y_axis: DVec4, z_axis: DVec4, w_axis: DVec4) -> DMat4 {
20 DMat4::from_cols(x_axis, y_axis, z_axis, w_axis)
21}
22
23#[derive(Clone, Copy)]
39#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
40#[cfg_attr(
41 feature = "zerocopy-08",
42 derive(FromBytes, Immutable, IntoBytes, KnownLayout)
43)]
44#[cfg_attr(feature = "cuda", repr(align(16)))]
45#[repr(C)]
46pub struct DMat4 {
47 pub x_axis: DVec4,
48 pub y_axis: DVec4,
49 pub z_axis: DVec4,
50 pub w_axis: DVec4,
51}
52
53impl DMat4 {
54 pub const ZERO: Self = Self::from_cols(DVec4::ZERO, DVec4::ZERO, DVec4::ZERO, DVec4::ZERO);
56
57 pub const IDENTITY: Self = Self::from_cols(DVec4::X, DVec4::Y, DVec4::Z, DVec4::W);
59
60 pub const NAN: Self = Self::from_cols(DVec4::NAN, DVec4::NAN, DVec4::NAN, DVec4::NAN);
62
63 #[allow(clippy::too_many_arguments)]
64 #[inline(always)]
65 #[must_use]
66 const fn new(
67 m00: f64,
68 m01: f64,
69 m02: f64,
70 m03: f64,
71 m10: f64,
72 m11: f64,
73 m12: f64,
74 m13: f64,
75 m20: f64,
76 m21: f64,
77 m22: f64,
78 m23: f64,
79 m30: f64,
80 m31: f64,
81 m32: f64,
82 m33: f64,
83 ) -> Self {
84 Self {
85 x_axis: DVec4::new(m00, m01, m02, m03),
86 y_axis: DVec4::new(m10, m11, m12, m13),
87 z_axis: DVec4::new(m20, m21, m22, m23),
88 w_axis: DVec4::new(m30, m31, m32, m33),
89 }
90 }
91
92 #[inline(always)]
96 #[must_use]
97 pub const fn from_cols(x_axis: DVec4, y_axis: DVec4, z_axis: DVec4, w_axis: DVec4) -> Self {
98 Self {
99 x_axis,
100 y_axis,
101 z_axis,
102 w_axis,
103 }
104 }
105
106 #[inline(always)]
112 #[must_use]
113 pub const fn from_rows(row0: DVec4, row1: DVec4, row2: DVec4, row3: DVec4) -> Self {
114 let [m00, m01, m02, m03] = row0.to_array();
115 let [m10, m11, m12, m13] = row1.to_array();
116 let [m20, m21, m22, m23] = row2.to_array();
117 let [m30, m31, m32, m33] = row3.to_array();
118 Self::new(
119 m00, m10, m20, m30, m01, m11, m21, m31, m02, m12, m22, m32, m03, m13, m23, m33,
120 )
121 }
122
123 #[inline]
127 #[must_use]
128 pub const fn from_cols_array(m: &[f64; 16]) -> Self {
129 Self::new(
130 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],
131 m[14], m[15],
132 )
133 }
134
135 #[inline]
139 #[must_use]
140 pub const fn to_cols_array(&self) -> [f64; 16] {
141 [
142 self.x_axis.x,
143 self.x_axis.y,
144 self.x_axis.z,
145 self.x_axis.w,
146 self.y_axis.x,
147 self.y_axis.y,
148 self.y_axis.z,
149 self.y_axis.w,
150 self.z_axis.x,
151 self.z_axis.y,
152 self.z_axis.z,
153 self.z_axis.w,
154 self.w_axis.x,
155 self.w_axis.y,
156 self.w_axis.z,
157 self.w_axis.w,
158 ]
159 }
160
161 #[inline]
165 #[must_use]
166 pub const fn from_cols_array_2d(m: &[[f64; 4]; 4]) -> Self {
167 Self::from_cols(
168 DVec4::from_array(m[0]),
169 DVec4::from_array(m[1]),
170 DVec4::from_array(m[2]),
171 DVec4::from_array(m[3]),
172 )
173 }
174
175 #[inline]
179 #[must_use]
180 pub const fn to_cols_array_2d(&self) -> [[f64; 4]; 4] {
181 [
182 self.x_axis.to_array(),
183 self.y_axis.to_array(),
184 self.z_axis.to_array(),
185 self.w_axis.to_array(),
186 ]
187 }
188
189 #[inline]
195 #[must_use]
196 pub const fn from_rows_array(m: &[f64; 16]) -> Self {
197 Self::new(
198 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],
199 m[11], m[15],
200 )
201 }
202
203 #[inline]
209 #[must_use]
210 pub const fn to_rows_array(&self) -> [f64; 16] {
211 let m = self.to_cols_array();
212 [
213 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],
214 m[11], m[15],
215 ]
216 }
217
218 #[doc(alias = "scale")]
220 #[inline]
221 #[must_use]
222 pub const fn from_diagonal(diagonal: DVec4) -> Self {
223 Self::new(
224 diagonal.x, 0.0, 0.0, 0.0, 0.0, diagonal.y, 0.0, 0.0, 0.0, 0.0, diagonal.z, 0.0, 0.0,
225 0.0, 0.0, diagonal.w,
226 )
227 }
228
229 #[inline]
230 #[must_use]
231 fn quat_to_axes(rotation: DQuat) -> (DVec4, DVec4, DVec4) {
232 glam_assert!(rotation.is_normalized());
233
234 let (x, y, z, w) = rotation.into();
235 let x2 = x + x;
236 let y2 = y + y;
237 let z2 = z + z;
238 let xx = x * x2;
239 let xy = x * y2;
240 let xz = x * z2;
241 let yy = y * y2;
242 let yz = y * z2;
243 let zz = z * z2;
244 let wx = w * x2;
245 let wy = w * y2;
246 let wz = w * z2;
247
248 let x_axis = DVec4::new(1.0 - (yy + zz), xy + wz, xz - wy, 0.0);
249 let y_axis = DVec4::new(xy - wz, 1.0 - (xx + zz), yz + wx, 0.0);
250 let z_axis = DVec4::new(xz + wy, yz - wx, 1.0 - (xx + yy), 0.0);
251 (x_axis, y_axis, z_axis)
252 }
253
254 #[inline]
264 #[must_use]
265 pub fn from_scale_rotation_translation(
266 scale: DVec3,
267 rotation: DQuat,
268 translation: DVec3,
269 ) -> Self {
270 let (x_axis, y_axis, z_axis) = Self::quat_to_axes(rotation);
271 Self::from_cols(
272 x_axis.mul(scale.x),
273 y_axis.mul(scale.y),
274 z_axis.mul(scale.z),
275 DVec4::from((translation, 1.0)),
276 )
277 }
278
279 #[inline]
288 #[must_use]
289 pub fn from_rotation_translation(rotation: DQuat, translation: DVec3) -> Self {
290 let (x_axis, y_axis, z_axis) = Self::quat_to_axes(rotation);
291 Self::from_cols(x_axis, y_axis, z_axis, DVec4::from((translation, 1.0)))
292 }
293
294 #[inline]
302 #[must_use]
303 pub fn to_scale_rotation_translation(&self) -> (DVec3, DQuat, DVec3) {
304 glam_assert!(self.row(3).abs_diff_eq(DVec4::W, 1e-6));
305
306 let r = DMat3::from_mat4(*self);
307
308 let det = r.determinant();
309
310 glam_assert!(det != 0.0);
311
312 let scale = DVec3::new(
313 r.x_axis.length() * math::signum(det),
314 r.y_axis.length(),
315 r.z_axis.length(),
316 );
317
318 glam_assert!(scale.cmpne(DVec3::ZERO).all());
319
320 let inv_scale = scale.recip();
321
322 let rotation = DQuat::from_rotation_axes(
323 r.x_axis.mul(inv_scale.x),
324 r.y_axis.mul(inv_scale.y),
325 r.z_axis.mul(inv_scale.z),
326 );
327
328 let translation = self.w_axis.xyz();
329
330 (scale, rotation, translation)
331 }
332
333 #[inline]
342 #[must_use]
343 pub fn from_quat(rotation: DQuat) -> Self {
344 let (x_axis, y_axis, z_axis) = Self::quat_to_axes(rotation);
345 Self::from_cols(x_axis, y_axis, z_axis, DVec4::W)
346 }
347
348 #[inline]
354 #[must_use]
355 pub fn from_mat3(m: DMat3) -> Self {
356 Self::from_cols(
357 DVec4::from((m.x_axis, 0.0)),
358 DVec4::from((m.y_axis, 0.0)),
359 DVec4::from((m.z_axis, 0.0)),
360 DVec4::W,
361 )
362 }
363
364 #[inline]
369 #[must_use]
370 pub fn from_mat3_translation(mat3: DMat3, translation: DVec3) -> Self {
371 Self::from_cols(
372 DVec4::from((mat3.x_axis, 0.0)),
373 DVec4::from((mat3.y_axis, 0.0)),
374 DVec4::from((mat3.z_axis, 0.0)),
375 DVec4::from((translation, 1.0)),
376 )
377 }
378
379 #[inline]
384 #[must_use]
385 pub fn from_translation(translation: DVec3) -> Self {
386 Self::from_cols(
387 DVec4::X,
388 DVec4::Y,
389 DVec4::Z,
390 DVec4::new(translation.x, translation.y, translation.z, 1.0),
391 )
392 }
393
394 #[inline]
404 #[must_use]
405 pub fn from_axis_angle(axis: DVec3, angle: f64) -> Self {
406 glam_assert!(axis.is_normalized());
407
408 let (sin, cos) = math::sin_cos(angle);
409 let axis_sin = axis.mul(sin);
410 let axis_sq = axis.mul(axis);
411 let omc = 1.0 - cos;
412 let xyomc = axis.x * axis.y * omc;
413 let xzomc = axis.x * axis.z * omc;
414 let yzomc = axis.y * axis.z * omc;
415 Self::from_cols(
416 DVec4::new(
417 axis_sq.x * omc + cos,
418 xyomc + axis_sin.z,
419 xzomc - axis_sin.y,
420 0.0,
421 ),
422 DVec4::new(
423 xyomc - axis_sin.z,
424 axis_sq.y * omc + cos,
425 yzomc + axis_sin.x,
426 0.0,
427 ),
428 DVec4::new(
429 xzomc + axis_sin.y,
430 yzomc - axis_sin.x,
431 axis_sq.z * omc + cos,
432 0.0,
433 ),
434 DVec4::W,
435 )
436 }
437
438 #[inline]
444 #[must_use]
445 pub fn from_euler(order: EulerRot, a: f64, b: f64, c: f64) -> Self {
446 Self::from_euler_angles(order, a, b, c)
447 }
448
449 #[inline]
459 #[must_use]
460 pub fn to_euler(&self, order: EulerRot) -> (f64, f64, f64) {
461 glam_assert!(
462 self.x_axis.xyz().is_normalized()
463 && self.y_axis.xyz().is_normalized()
464 && self.z_axis.xyz().is_normalized()
465 );
466 self.to_euler_angles(order)
467 }
468
469 #[inline]
475 #[must_use]
476 pub fn from_rotation_x(angle: f64) -> Self {
477 let (sina, cosa) = math::sin_cos(angle);
478 Self::from_cols(
479 DVec4::X,
480 DVec4::new(0.0, cosa, sina, 0.0),
481 DVec4::new(0.0, -sina, cosa, 0.0),
482 DVec4::W,
483 )
484 }
485
486 #[inline]
492 #[must_use]
493 pub fn from_rotation_y(angle: f64) -> Self {
494 let (sina, cosa) = math::sin_cos(angle);
495 Self::from_cols(
496 DVec4::new(cosa, 0.0, -sina, 0.0),
497 DVec4::Y,
498 DVec4::new(sina, 0.0, cosa, 0.0),
499 DVec4::W,
500 )
501 }
502
503 #[inline]
509 #[must_use]
510 pub fn from_rotation_z(angle: f64) -> Self {
511 let (sina, cosa) = math::sin_cos(angle);
512 Self::from_cols(
513 DVec4::new(cosa, sina, 0.0, 0.0),
514 DVec4::new(-sina, cosa, 0.0, 0.0),
515 DVec4::Z,
516 DVec4::W,
517 )
518 }
519
520 #[inline]
529 #[must_use]
530 pub fn from_scale(scale: DVec3) -> Self {
531 glam_assert!(scale.cmpne(DVec3::ZERO).any());
533
534 Self::from_cols(
535 DVec4::new(scale.x, 0.0, 0.0, 0.0),
536 DVec4::new(0.0, scale.y, 0.0, 0.0),
537 DVec4::new(0.0, 0.0, scale.z, 0.0),
538 DVec4::W,
539 )
540 }
541
542 #[inline]
550 #[must_use]
551 pub const fn from_cols_slice(slice: &[f64]) -> Self {
552 Self::new(
553 slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
554 slice[8], slice[9], slice[10], slice[11], slice[12], slice[13], slice[14], slice[15],
555 )
556 }
557
558 #[inline]
564 pub fn write_cols_to_slice(&self, slice: &mut [f64]) {
565 slice[0] = self.x_axis.x;
566 slice[1] = self.x_axis.y;
567 slice[2] = self.x_axis.z;
568 slice[3] = self.x_axis.w;
569 slice[4] = self.y_axis.x;
570 slice[5] = self.y_axis.y;
571 slice[6] = self.y_axis.z;
572 slice[7] = self.y_axis.w;
573 slice[8] = self.z_axis.x;
574 slice[9] = self.z_axis.y;
575 slice[10] = self.z_axis.z;
576 slice[11] = self.z_axis.w;
577 slice[12] = self.w_axis.x;
578 slice[13] = self.w_axis.y;
579 slice[14] = self.w_axis.z;
580 slice[15] = self.w_axis.w;
581 }
582
583 #[inline]
594 #[must_use]
595 pub const fn from_rows_slice(slice: &[f64]) -> Self {
596 Self::new(
597 slice[0], slice[4], slice[8], slice[12], slice[1], slice[5], slice[9], slice[13],
598 slice[2], slice[6], slice[10], slice[14], slice[3], slice[7], slice[11], slice[15],
599 )
600 }
601
602 #[inline]
608 #[must_use]
609 pub fn col(&self, index: usize) -> DVec4 {
610 match index {
611 0 => self.x_axis,
612 1 => self.y_axis,
613 2 => self.z_axis,
614 3 => self.w_axis,
615 _ => panic!("index out of bounds"),
616 }
617 }
618
619 #[inline]
625 pub fn col_mut(&mut self, index: usize) -> &mut DVec4 {
626 match index {
627 0 => &mut self.x_axis,
628 1 => &mut self.y_axis,
629 2 => &mut self.z_axis,
630 3 => &mut self.w_axis,
631 _ => panic!("index out of bounds"),
632 }
633 }
634
635 #[inline]
643 #[must_use]
644 pub fn row(&self, index: usize) -> DVec4 {
645 match index {
646 0 => DVec4::new(self.x_axis.x, self.y_axis.x, self.z_axis.x, self.w_axis.x),
647 1 => DVec4::new(self.x_axis.y, self.y_axis.y, self.z_axis.y, self.w_axis.y),
648 2 => DVec4::new(self.x_axis.z, self.y_axis.z, self.z_axis.z, self.w_axis.z),
649 3 => DVec4::new(self.x_axis.w, self.y_axis.w, self.z_axis.w, self.w_axis.w),
650 _ => panic!("index out of bounds"),
651 }
652 }
653
654 #[inline]
664 pub fn set_row(&mut self, index: usize, row: DVec4) {
665 match index {
666 0 => {
667 self.x_axis.x = row.x;
668 self.y_axis.x = row.y;
669 self.z_axis.x = row.z;
670 self.w_axis.x = row.w;
671 }
672 1 => {
673 self.x_axis.y = row.x;
674 self.y_axis.y = row.y;
675 self.z_axis.y = row.z;
676 self.w_axis.y = row.w;
677 }
678 2 => {
679 self.x_axis.z = row.x;
680 self.y_axis.z = row.y;
681 self.z_axis.z = row.z;
682 self.w_axis.z = row.w;
683 }
684 3 => {
685 self.x_axis.w = row.x;
686 self.y_axis.w = row.y;
687 self.z_axis.w = row.z;
688 self.w_axis.w = row.w;
689 }
690 _ => panic!("index out of bounds"),
691 }
692 }
693
694 #[inline]
697 #[must_use]
698 pub fn is_finite(&self) -> bool {
699 self.x_axis.is_finite()
700 && self.y_axis.is_finite()
701 && self.z_axis.is_finite()
702 && self.w_axis.is_finite()
703 }
704
705 #[inline]
707 #[must_use]
708 pub fn is_nan(&self) -> bool {
709 self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan() || self.w_axis.is_nan()
710 }
711
712 #[inline]
714 #[must_use]
715 pub fn transpose(&self) -> Self {
716 Self {
717 x_axis: DVec4::new(self.x_axis.x, self.y_axis.x, self.z_axis.x, self.w_axis.x),
718 y_axis: DVec4::new(self.x_axis.y, self.y_axis.y, self.z_axis.y, self.w_axis.y),
719 z_axis: DVec4::new(self.x_axis.z, self.y_axis.z, self.z_axis.z, self.w_axis.z),
720 w_axis: DVec4::new(self.x_axis.w, self.y_axis.w, self.z_axis.w, self.w_axis.w),
721 }
722 }
723
724 #[inline]
726 #[must_use]
727 pub fn diagonal(&self) -> DVec4 {
728 DVec4::new(self.x_axis.x, self.y_axis.y, self.z_axis.z, self.w_axis.w)
729 }
730
731 #[must_use]
733 pub fn determinant(&self) -> f64 {
734 let (m00, m01, m02, m03) = self.x_axis.into();
735 let (m10, m11, m12, m13) = self.y_axis.into();
736 let (m20, m21, m22, m23) = self.z_axis.into();
737 let (m30, m31, m32, m33) = self.w_axis.into();
738
739 let a2323 = m22 * m33 - m23 * m32;
740 let a1323 = m21 * m33 - m23 * m31;
741 let a1223 = m21 * m32 - m22 * m31;
742 let a0323 = m20 * m33 - m23 * m30;
743 let a0223 = m20 * m32 - m22 * m30;
744 let a0123 = m20 * m31 - m21 * m30;
745
746 m00 * (m11 * a2323 - m12 * a1323 + m13 * a1223)
747 - m01 * (m10 * a2323 - m12 * a0323 + m13 * a0223)
748 + m02 * (m10 * a1323 - m11 * a0323 + m13 * a0123)
749 - m03 * (m10 * a1223 - m11 * a0223 + m12 * a0123)
750 }
751
752 #[inline(always)]
764 #[must_use]
765 fn inverse_checked<const CHECKED: bool>(&self) -> (Self, bool) {
766 let (m00, m01, m02, m03) = self.x_axis.into();
767 let (m10, m11, m12, m13) = self.y_axis.into();
768 let (m20, m21, m22, m23) = self.z_axis.into();
769 let (m30, m31, m32, m33) = self.w_axis.into();
770
771 let coef00 = m22 * m33 - m32 * m23;
772 let coef02 = m12 * m33 - m32 * m13;
773 let coef03 = m12 * m23 - m22 * m13;
774
775 let coef04 = m21 * m33 - m31 * m23;
776 let coef06 = m11 * m33 - m31 * m13;
777 let coef07 = m11 * m23 - m21 * m13;
778
779 let coef08 = m21 * m32 - m31 * m22;
780 let coef10 = m11 * m32 - m31 * m12;
781 let coef11 = m11 * m22 - m21 * m12;
782
783 let coef12 = m20 * m33 - m30 * m23;
784 let coef14 = m10 * m33 - m30 * m13;
785 let coef15 = m10 * m23 - m20 * m13;
786
787 let coef16 = m20 * m32 - m30 * m22;
788 let coef18 = m10 * m32 - m30 * m12;
789 let coef19 = m10 * m22 - m20 * m12;
790
791 let coef20 = m20 * m31 - m30 * m21;
792 let coef22 = m10 * m31 - m30 * m11;
793 let coef23 = m10 * m21 - m20 * m11;
794
795 let fac0 = DVec4::new(coef00, coef00, coef02, coef03);
796 let fac1 = DVec4::new(coef04, coef04, coef06, coef07);
797 let fac2 = DVec4::new(coef08, coef08, coef10, coef11);
798 let fac3 = DVec4::new(coef12, coef12, coef14, coef15);
799 let fac4 = DVec4::new(coef16, coef16, coef18, coef19);
800 let fac5 = DVec4::new(coef20, coef20, coef22, coef23);
801
802 let vec0 = DVec4::new(m10, m00, m00, m00);
803 let vec1 = DVec4::new(m11, m01, m01, m01);
804 let vec2 = DVec4::new(m12, m02, m02, m02);
805 let vec3 = DVec4::new(m13, m03, m03, m03);
806
807 let inv0 = vec1.mul(fac0).sub(vec2.mul(fac1)).add(vec3.mul(fac2));
808 let inv1 = vec0.mul(fac0).sub(vec2.mul(fac3)).add(vec3.mul(fac4));
809 let inv2 = vec0.mul(fac1).sub(vec1.mul(fac3)).add(vec3.mul(fac5));
810 let inv3 = vec0.mul(fac2).sub(vec1.mul(fac4)).add(vec2.mul(fac5));
811
812 let sign_a = DVec4::new(1.0, -1.0, 1.0, -1.0);
813 let sign_b = DVec4::new(-1.0, 1.0, -1.0, 1.0);
814
815 let inverse = Self::from_cols(
816 inv0.mul(sign_a),
817 inv1.mul(sign_b),
818 inv2.mul(sign_a),
819 inv3.mul(sign_b),
820 );
821
822 let col0 = DVec4::new(
823 inverse.x_axis.x,
824 inverse.y_axis.x,
825 inverse.z_axis.x,
826 inverse.w_axis.x,
827 );
828
829 let dot0 = self.x_axis.mul(col0);
830 let dot1 = dot0.x + dot0.y + dot0.z + dot0.w;
831
832 if CHECKED {
833 if dot1 == 0.0 {
834 return (Self::ZERO, false);
835 }
836 } else {
837 glam_assert!(dot1 != 0.0);
838 }
839
840 let rcp_det = 1.0 / dot1;
841 (inverse.mul(rcp_det), true)
842 }
843
844 #[must_use]
852 pub fn inverse(&self) -> Self {
853 self.inverse_checked::<false>().0
854 }
855
856 #[must_use]
858 pub fn try_inverse(&self) -> Option<Self> {
859 let (m, is_valid) = self.inverse_checked::<true>();
860 if is_valid {
861 Some(m)
862 } else {
863 None
864 }
865 }
866
867 #[must_use]
869 pub fn inverse_or_zero(&self) -> Self {
870 self.inverse_checked::<true>().0
871 }
872
873 #[deprecated(
882 since = "0.33.1",
883 note = "use the `glam::dcamera::lh::view::look_to_mat4` function instead"
884 )]
885 #[inline]
886 #[must_use]
887 pub fn look_to_lh(eye: DVec3, dir: DVec3, up: DVec3) -> Self {
888 #[allow(deprecated)]
889 Self::look_to_rh(eye, -dir, up)
890 }
891
892 #[deprecated(
901 since = "0.33.1",
902 note = "use the `glam::dcamera::rh::view::look_to_mat4` function instead"
903 )]
904 #[inline]
905 #[must_use]
906 pub fn look_to_rh(eye: DVec3, dir: DVec3, up: DVec3) -> Self {
907 glam_assert!(dir.is_normalized());
908 glam_assert!(up.is_normalized());
909 let f = dir;
910 let s = f.cross(up).normalize();
911 let u = s.cross(f);
912
913 Self::from_cols(
914 DVec4::new(s.x, u.x, -f.x, 0.0),
915 DVec4::new(s.y, u.y, -f.y, 0.0),
916 DVec4::new(s.z, u.z, -f.z, 0.0),
917 DVec4::new(-eye.dot(s), -eye.dot(u), eye.dot(f), 1.0),
918 )
919 }
920
921 #[deprecated(
930 since = "0.33.1",
931 note = "use the `glam::dcamera::lh::view::look_at_mat4` function instead"
932 )]
933 #[inline]
934 #[must_use]
935 pub fn look_at_lh(eye: DVec3, center: DVec3, up: DVec3) -> Self {
936 #[allow(deprecated)]
937 Self::look_to_lh(eye, center.sub(eye).normalize(), up)
938 }
939
940 #[deprecated(
949 since = "0.33.1",
950 note = "use the `glam::dcamera::rh::view::look_at_mat4` function instead"
951 )]
952 #[inline]
953 pub fn look_at_rh(eye: DVec3, center: DVec3, up: DVec3) -> Self {
954 #[allow(deprecated)]
955 Self::look_to_rh(eye, center.sub(eye).normalize(), up)
956 }
957
958 #[deprecated(
964 since = "0.33.1",
965 note = "use the `glam::dcamera::rh::proj::opengl::frustum` function instead"
966 )]
967 #[inline]
968 #[must_use]
969 pub fn frustum_rh_gl(
970 left: f64,
971 right: f64,
972 bottom: f64,
973 top: f64,
974 z_near: f64,
975 z_far: f64,
976 ) -> Self {
977 let inv_width = 1.0 / (right - left);
978 let inv_height = 1.0 / (top - bottom);
979 let inv_depth = 1.0 / (z_far - z_near);
980 let a = (right + left) * inv_width;
981 let b = (top + bottom) * inv_height;
982 let c = -(z_far + z_near) * inv_depth;
983 let d = -(2.0 * z_far * z_near) * inv_depth;
984 let two_z_near = 2.0 * z_near;
985 Self::from_cols(
986 DVec4::new(two_z_near * inv_width, 0.0, 0.0, 0.0),
987 DVec4::new(0.0, two_z_near * inv_height, 0.0, 0.0),
988 DVec4::new(a, b, c, -1.0),
989 DVec4::new(0.0, 0.0, d, 0.0),
990 )
991 }
992
993 #[deprecated(
1000 since = "0.33.1",
1001 note = "use the `glam::dcamera::lh::proj::directx::frustum` function instead"
1002 )]
1003 #[inline]
1004 #[must_use]
1005 pub fn frustum_lh(
1006 left: f64,
1007 right: f64,
1008 bottom: f64,
1009 top: f64,
1010 z_near: f64,
1011 z_far: f64,
1012 ) -> Self {
1013 glam_assert!(z_near > 0.0 && z_far > 0.0);
1014 let inv_width = 1.0 / (right - left);
1015 let inv_height = 1.0 / (top - bottom);
1016 let inv_depth = 1.0 / (z_far - z_near);
1017 let a = (right + left) * inv_width;
1018 let b = (top + bottom) * inv_height;
1019 let c = z_far * inv_depth;
1020 let d = -(z_far * z_near) * inv_depth;
1021 let two_z_near = 2.0 * z_near;
1022 Self::from_cols(
1023 DVec4::new(two_z_near * inv_width, 0.0, 0.0, 0.0),
1024 DVec4::new(0.0, two_z_near * inv_height, 0.0, 0.0),
1025 DVec4::new(a, b, c, 1.0),
1026 DVec4::new(0.0, 0.0, d, 0.0),
1027 )
1028 }
1029
1030 #[deprecated(
1037 since = "0.33.1",
1038 note = "use the `glam::dcamera::rh::proj::directx::frustum` function instead"
1039 )]
1040 #[inline]
1041 #[must_use]
1042 pub fn frustum_rh(
1043 left: f64,
1044 right: f64,
1045 bottom: f64,
1046 top: f64,
1047 z_near: f64,
1048 z_far: f64,
1049 ) -> Self {
1050 glam_assert!(z_near > 0.0 && z_far > 0.0);
1051 let inv_width = 1.0 / (right - left);
1052 let inv_height = 1.0 / (top - bottom);
1053 let inv_depth = 1.0 / (z_far - z_near);
1054 let a = (right + left) * inv_width;
1055 let b = (top + bottom) * inv_height;
1056 let c = -z_far * inv_depth;
1057 let d = -(z_far * z_near) * inv_depth;
1058 let two_z_near = 2.0 * z_near;
1059 Self::from_cols(
1060 DVec4::new(two_z_near * inv_width, 0.0, 0.0, 0.0),
1061 DVec4::new(0.0, two_z_near * inv_height, 0.0, 0.0),
1062 DVec4::new(a, b, c, -1.0),
1063 DVec4::new(0.0, 0.0, d, 0.0),
1064 )
1065 }
1066
1067 #[deprecated(
1074 since = "0.33.1",
1075 note = "use the `glam::dcamera::rh::proj::opengl::perspective` function instead"
1076 )]
1077 #[inline]
1078 #[must_use]
1079 pub fn perspective_rh_gl(
1080 fov_y_radians: f64,
1081 aspect_ratio: f64,
1082 z_near: f64,
1083 z_far: f64,
1084 ) -> Self {
1085 let inv_length = 1.0 / (z_near - z_far);
1086 let f = 1.0 / math::tan(0.5 * fov_y_radians);
1087 let a = f / aspect_ratio;
1088 let b = (z_near + z_far) * inv_length;
1089 let c = (2.0 * z_near * z_far) * inv_length;
1090 Self::from_cols(
1091 DVec4::new(a, 0.0, 0.0, 0.0),
1092 DVec4::new(0.0, f, 0.0, 0.0),
1093 DVec4::new(0.0, 0.0, b, -1.0),
1094 DVec4::new(0.0, 0.0, c, 0.0),
1095 )
1096 }
1097
1098 #[deprecated(
1107 since = "0.33.1",
1108 note = "use the `glam::dcamera::lh::proj::directx::perspective` function instead"
1109 )]
1110 #[inline]
1111 #[must_use]
1112 pub fn perspective_lh(fov_y_radians: f64, aspect_ratio: f64, z_near: f64, z_far: f64) -> Self {
1113 glam_assert!(z_near > 0.0 && z_far > 0.0);
1114 let (sin_fov, cos_fov) = math::sin_cos(0.5 * fov_y_radians);
1115 let h = cos_fov / sin_fov;
1116 let w = h / aspect_ratio;
1117 let r = z_far / (z_far - z_near);
1118 Self::from_cols(
1119 DVec4::new(w, 0.0, 0.0, 0.0),
1120 DVec4::new(0.0, h, 0.0, 0.0),
1121 DVec4::new(0.0, 0.0, r, 1.0),
1122 DVec4::new(0.0, 0.0, -r * z_near, 0.0),
1123 )
1124 }
1125
1126 #[deprecated(
1135 since = "0.33.1",
1136 note = "use the `glam::dcamera::rh::proj::directx::perspective` function instead"
1137 )]
1138 #[inline]
1139 #[must_use]
1140 pub fn perspective_rh(fov_y_radians: f64, aspect_ratio: f64, z_near: f64, z_far: f64) -> Self {
1141 glam_assert!(z_near > 0.0 && z_far > 0.0);
1142 let (sin_fov, cos_fov) = math::sin_cos(0.5 * fov_y_radians);
1143 let h = cos_fov / sin_fov;
1144 let w = h / aspect_ratio;
1145 let r = z_far / (z_near - z_far);
1146 Self::from_cols(
1147 DVec4::new(w, 0.0, 0.0, 0.0),
1148 DVec4::new(0.0, h, 0.0, 0.0),
1149 DVec4::new(0.0, 0.0, r, -1.0),
1150 DVec4::new(0.0, 0.0, r * z_near, 0.0),
1151 )
1152 }
1153
1154 #[deprecated(
1164 since = "0.33.1",
1165 note = "use the `glam::dcamera::lh::proj::directx::perspective_infinite` function instead"
1166 )]
1167 #[inline]
1168 #[must_use]
1169 pub fn perspective_infinite_lh(fov_y_radians: f64, aspect_ratio: f64, z_near: f64) -> Self {
1170 glam_assert!(z_near > 0.0);
1171 let (sin_fov, cos_fov) = math::sin_cos(0.5 * fov_y_radians);
1172 let h = cos_fov / sin_fov;
1173 let w = h / aspect_ratio;
1174 Self::from_cols(
1175 DVec4::new(w, 0.0, 0.0, 0.0),
1176 DVec4::new(0.0, h, 0.0, 0.0),
1177 DVec4::new(0.0, 0.0, 1.0, 1.0),
1178 DVec4::new(0.0, 0.0, -z_near, 0.0),
1179 )
1180 }
1181
1182 #[deprecated(
1190 since = "0.33.1",
1191 note = "use the `glam::dcamera::lh::proj::directx::perspective_infinite_reverse` function instead"
1192 )]
1193 #[inline]
1194 #[must_use]
1195 pub fn perspective_infinite_reverse_lh(
1196 fov_y_radians: f64,
1197 aspect_ratio: f64,
1198 z_near: f64,
1199 ) -> Self {
1200 glam_assert!(z_near > 0.0);
1201 let (sin_fov, cos_fov) = math::sin_cos(0.5 * fov_y_radians);
1202 let h = cos_fov / sin_fov;
1203 let w = h / aspect_ratio;
1204 Self::from_cols(
1205 DVec4::new(w, 0.0, 0.0, 0.0),
1206 DVec4::new(0.0, h, 0.0, 0.0),
1207 DVec4::new(0.0, 0.0, 0.0, 1.0),
1208 DVec4::new(0.0, 0.0, z_near, 0.0),
1209 )
1210 }
1211
1212 #[deprecated(
1222 since = "0.33.1",
1223 note = "use the `glam::dcamera::rh::proj::directx::perspective_infinite` function instead"
1224 )]
1225 #[inline]
1226 #[must_use]
1227 pub fn perspective_infinite_rh(fov_y_radians: f64, aspect_ratio: f64, z_near: f64) -> Self {
1228 glam_assert!(z_near > 0.0);
1229 let f = 1.0 / math::tan(0.5 * fov_y_radians);
1230 Self::from_cols(
1231 DVec4::new(f / aspect_ratio, 0.0, 0.0, 0.0),
1232 DVec4::new(0.0, f, 0.0, 0.0),
1233 DVec4::new(0.0, 0.0, -1.0, -1.0),
1234 DVec4::new(0.0, 0.0, -z_near, 0.0),
1235 )
1236 }
1237
1238 #[deprecated(
1246 since = "0.33.1",
1247 note = "use the `glam::dcamera::rh::proj::directx::perspective_infinite_reverse` function instead"
1248 )]
1249 #[inline]
1250 #[must_use]
1251 pub fn perspective_infinite_reverse_rh(
1252 fov_y_radians: f64,
1253 aspect_ratio: f64,
1254 z_near: f64,
1255 ) -> Self {
1256 glam_assert!(z_near > 0.0);
1257 let f = 1.0 / math::tan(0.5 * fov_y_radians);
1258 Self::from_cols(
1259 DVec4::new(f / aspect_ratio, 0.0, 0.0, 0.0),
1260 DVec4::new(0.0, f, 0.0, 0.0),
1261 DVec4::new(0.0, 0.0, 0.0, -1.0),
1262 DVec4::new(0.0, 0.0, z_near, 0.0),
1263 )
1264 }
1265
1266 #[deprecated(
1273 since = "0.33.1",
1274 note = "use the `glam::dcamera::rh::proj::opengl::orthographic` function instead"
1275 )]
1276 #[inline]
1277 #[must_use]
1278 pub fn orthographic_rh_gl(
1279 left: f64,
1280 right: f64,
1281 bottom: f64,
1282 top: f64,
1283 near: f64,
1284 far: f64,
1285 ) -> Self {
1286 let a = 2.0 / (right - left);
1287 let b = 2.0 / (top - bottom);
1288 let c = 2.0 / (near - far);
1289 let tx = -(right + left) / (right - left);
1290 let ty = -(top + bottom) / (top - bottom);
1291 let tz = -(far + near) / (far - near);
1292
1293 Self::from_cols(
1294 DVec4::new(a, 0.0, 0.0, 0.0),
1295 DVec4::new(0.0, b, 0.0, 0.0),
1296 DVec4::new(0.0, 0.0, c, 0.0),
1297 DVec4::new(tx, ty, tz, 1.0),
1298 )
1299 }
1300
1301 #[deprecated(
1305 since = "0.33.1",
1306 note = "use the `glam::dcamera::lh::proj::directx::orthographic` function instead"
1307 )]
1308 #[inline]
1309 #[must_use]
1310 pub fn orthographic_lh(
1311 left: f64,
1312 right: f64,
1313 bottom: f64,
1314 top: f64,
1315 near: f64,
1316 far: f64,
1317 ) -> Self {
1318 let rcp_width = 1.0 / (right - left);
1319 let rcp_height = 1.0 / (top - bottom);
1320 let r = 1.0 / (far - near);
1321 Self::from_cols(
1322 DVec4::new(rcp_width + rcp_width, 0.0, 0.0, 0.0),
1323 DVec4::new(0.0, rcp_height + rcp_height, 0.0, 0.0),
1324 DVec4::new(0.0, 0.0, r, 0.0),
1325 DVec4::new(
1326 -(left + right) * rcp_width,
1327 -(top + bottom) * rcp_height,
1328 -r * near,
1329 1.0,
1330 ),
1331 )
1332 }
1333
1334 #[deprecated(
1338 since = "0.33.1",
1339 note = "use the `glam::dcamera::rh::proj::directx::orthographic` function instead"
1340 )]
1341 #[inline]
1342 #[must_use]
1343 pub fn orthographic_rh(
1344 left: f64,
1345 right: f64,
1346 bottom: f64,
1347 top: f64,
1348 near: f64,
1349 far: f64,
1350 ) -> Self {
1351 let rcp_width = 1.0 / (right - left);
1352 let rcp_height = 1.0 / (top - bottom);
1353 let r = 1.0 / (near - far);
1354 Self::from_cols(
1355 DVec4::new(rcp_width + rcp_width, 0.0, 0.0, 0.0),
1356 DVec4::new(0.0, rcp_height + rcp_height, 0.0, 0.0),
1357 DVec4::new(0.0, 0.0, r, 0.0),
1358 DVec4::new(
1359 -(left + right) * rcp_width,
1360 -(top + bottom) * rcp_height,
1361 r * near,
1362 1.0,
1363 ),
1364 )
1365 }
1366
1367 #[inline]
1374 #[must_use]
1375 pub fn project_point3(&self, rhs: DVec3) -> DVec3 {
1376 let mut res = self.x_axis.mul(rhs.x);
1377 res = self.y_axis.mul(rhs.y).add(res);
1378 res = self.z_axis.mul(rhs.z).add(res);
1379 res = self.w_axis.add(res);
1380 res = res.div(res.w);
1381 res.xyz()
1382 }
1383
1384 #[inline]
1397 #[must_use]
1398 pub fn transform_point3(&self, rhs: DVec3) -> DVec3 {
1399 glam_assert!(self.row(3).abs_diff_eq(DVec4::W, 1e-6));
1400 let mut res = self.x_axis.mul(rhs.x);
1401 res = self.y_axis.mul(rhs.y).add(res);
1402 res = self.z_axis.mul(rhs.z).add(res);
1403 res = self.w_axis.add(res);
1404 res.xyz()
1405 }
1406
1407 #[inline]
1418 #[must_use]
1419 pub fn transform_vector3(&self, rhs: DVec3) -> DVec3 {
1420 glam_assert!(self.row(3).abs_diff_eq(DVec4::W, 1e-6));
1421 let mut res = self.x_axis.mul(rhs.x);
1422 res = self.y_axis.mul(rhs.y).add(res);
1423 res = self.z_axis.mul(rhs.z).add(res);
1424 res.xyz()
1425 }
1426
1427 #[inline]
1429 #[must_use]
1430 pub fn mul_vec4(&self, rhs: DVec4) -> DVec4 {
1431 let mut res = self.x_axis.mul(rhs.x);
1432 res = res.add(self.y_axis.mul(rhs.y));
1433 res = res.add(self.z_axis.mul(rhs.z));
1434 res = res.add(self.w_axis.mul(rhs.w));
1435 res
1436 }
1437
1438 #[inline]
1440 #[must_use]
1441 pub fn mul_transpose_vec4(&self, rhs: DVec4) -> DVec4 {
1442 DVec4::new(
1443 self.x_axis.dot(rhs),
1444 self.y_axis.dot(rhs),
1445 self.z_axis.dot(rhs),
1446 self.w_axis.dot(rhs),
1447 )
1448 }
1449
1450 #[inline]
1452 #[must_use]
1453 pub fn mul_mat4(&self, rhs: &Self) -> Self {
1454 self.mul(rhs)
1455 }
1456
1457 #[inline]
1459 #[must_use]
1460 pub fn add_mat4(&self, rhs: &Self) -> Self {
1461 self.add(rhs)
1462 }
1463
1464 #[inline]
1466 #[must_use]
1467 pub fn sub_mat4(&self, rhs: &Self) -> Self {
1468 self.sub(rhs)
1469 }
1470
1471 #[inline]
1473 #[must_use]
1474 pub fn mul_scalar(&self, rhs: f64) -> Self {
1475 Self::from_cols(
1476 self.x_axis.mul(rhs),
1477 self.y_axis.mul(rhs),
1478 self.z_axis.mul(rhs),
1479 self.w_axis.mul(rhs),
1480 )
1481 }
1482
1483 #[inline]
1487 #[must_use]
1488 pub fn mul_diagonal_scale(&self, scale: DVec4) -> Self {
1489 Self::from_cols(
1490 self.x_axis * scale.x,
1491 self.y_axis * scale.y,
1492 self.z_axis * scale.z,
1493 self.w_axis * scale.w,
1494 )
1495 }
1496
1497 #[inline]
1499 #[must_use]
1500 pub fn div_scalar(&self, rhs: f64) -> Self {
1501 let rhs = DVec4::splat(rhs);
1502 Self::from_cols(
1503 self.x_axis.div(rhs),
1504 self.y_axis.div(rhs),
1505 self.z_axis.div(rhs),
1506 self.w_axis.div(rhs),
1507 )
1508 }
1509
1510 #[inline]
1512 #[must_use]
1513 pub fn recip(&self) -> Self {
1514 Self::from_cols(
1515 self.x_axis.recip(),
1516 self.y_axis.recip(),
1517 self.z_axis.recip(),
1518 self.w_axis.recip(),
1519 )
1520 }
1521
1522 #[inline]
1532 #[must_use]
1533 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f64) -> bool {
1534 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
1535 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
1536 && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
1537 && self.w_axis.abs_diff_eq(rhs.w_axis, max_abs_diff)
1538 }
1539
1540 #[inline]
1542 #[must_use]
1543 pub fn abs(&self) -> Self {
1544 Self::from_cols(
1545 self.x_axis.abs(),
1546 self.y_axis.abs(),
1547 self.z_axis.abs(),
1548 self.w_axis.abs(),
1549 )
1550 }
1551
1552 #[cfg(feature = "f64")]
1553 #[inline]
1554 #[must_use]
1555 pub fn as_mat4(&self) -> Mat4 {
1556 Mat4::from_cols(
1557 self.x_axis.as_vec4(),
1558 self.y_axis.as_vec4(),
1559 self.z_axis.as_vec4(),
1560 self.w_axis.as_vec4(),
1561 )
1562 }
1563}
1564
1565impl Default for DMat4 {
1566 #[inline]
1567 fn default() -> Self {
1568 Self::IDENTITY
1569 }
1570}
1571
1572impl Add for DMat4 {
1573 type Output = Self;
1574 #[inline]
1575 fn add(self, rhs: Self) -> Self {
1576 Self::from_cols(
1577 self.x_axis.add(rhs.x_axis),
1578 self.y_axis.add(rhs.y_axis),
1579 self.z_axis.add(rhs.z_axis),
1580 self.w_axis.add(rhs.w_axis),
1581 )
1582 }
1583}
1584
1585impl Add<&Self> for DMat4 {
1586 type Output = Self;
1587 #[inline]
1588 fn add(self, rhs: &Self) -> Self {
1589 self.add(*rhs)
1590 }
1591}
1592
1593impl Add<&DMat4> for &DMat4 {
1594 type Output = DMat4;
1595 #[inline]
1596 fn add(self, rhs: &DMat4) -> DMat4 {
1597 (*self).add(*rhs)
1598 }
1599}
1600
1601impl Add<DMat4> for &DMat4 {
1602 type Output = DMat4;
1603 #[inline]
1604 fn add(self, rhs: DMat4) -> DMat4 {
1605 (*self).add(rhs)
1606 }
1607}
1608
1609impl AddAssign for DMat4 {
1610 #[inline]
1611 fn add_assign(&mut self, rhs: Self) {
1612 *self = self.add(rhs);
1613 }
1614}
1615
1616impl AddAssign<&Self> for DMat4 {
1617 #[inline]
1618 fn add_assign(&mut self, rhs: &Self) {
1619 self.add_assign(*rhs);
1620 }
1621}
1622
1623impl Sub for DMat4 {
1624 type Output = Self;
1625 #[inline]
1626 fn sub(self, rhs: Self) -> Self {
1627 Self::from_cols(
1628 self.x_axis.sub(rhs.x_axis),
1629 self.y_axis.sub(rhs.y_axis),
1630 self.z_axis.sub(rhs.z_axis),
1631 self.w_axis.sub(rhs.w_axis),
1632 )
1633 }
1634}
1635
1636impl Sub<&Self> for DMat4 {
1637 type Output = Self;
1638 #[inline]
1639 fn sub(self, rhs: &Self) -> Self {
1640 self.sub(*rhs)
1641 }
1642}
1643
1644impl Sub<&DMat4> for &DMat4 {
1645 type Output = DMat4;
1646 #[inline]
1647 fn sub(self, rhs: &DMat4) -> DMat4 {
1648 (*self).sub(*rhs)
1649 }
1650}
1651
1652impl Sub<DMat4> for &DMat4 {
1653 type Output = DMat4;
1654 #[inline]
1655 fn sub(self, rhs: DMat4) -> DMat4 {
1656 (*self).sub(rhs)
1657 }
1658}
1659
1660impl SubAssign for DMat4 {
1661 #[inline]
1662 fn sub_assign(&mut self, rhs: Self) {
1663 *self = self.sub(rhs);
1664 }
1665}
1666
1667impl SubAssign<&Self> for DMat4 {
1668 #[inline]
1669 fn sub_assign(&mut self, rhs: &Self) {
1670 self.sub_assign(*rhs);
1671 }
1672}
1673
1674impl Neg for DMat4 {
1675 type Output = Self;
1676 #[inline]
1677 fn neg(self) -> Self::Output {
1678 Self::from_cols(
1679 self.x_axis.neg(),
1680 self.y_axis.neg(),
1681 self.z_axis.neg(),
1682 self.w_axis.neg(),
1683 )
1684 }
1685}
1686
1687impl Neg for &DMat4 {
1688 type Output = DMat4;
1689 #[inline]
1690 fn neg(self) -> DMat4 {
1691 (*self).neg()
1692 }
1693}
1694
1695impl Mul for DMat4 {
1696 type Output = Self;
1697 #[inline]
1698 fn mul(self, rhs: Self) -> Self {
1699 Self::from_cols(
1700 self.mul(rhs.x_axis),
1701 self.mul(rhs.y_axis),
1702 self.mul(rhs.z_axis),
1703 self.mul(rhs.w_axis),
1704 )
1705 }
1706}
1707
1708impl Mul<&Self> for DMat4 {
1709 type Output = Self;
1710 #[inline]
1711 fn mul(self, rhs: &Self) -> Self {
1712 self.mul(*rhs)
1713 }
1714}
1715
1716impl Mul<&DMat4> for &DMat4 {
1717 type Output = DMat4;
1718 #[inline]
1719 fn mul(self, rhs: &DMat4) -> DMat4 {
1720 (*self).mul(*rhs)
1721 }
1722}
1723
1724impl Mul<DMat4> for &DMat4 {
1725 type Output = DMat4;
1726 #[inline]
1727 fn mul(self, rhs: DMat4) -> DMat4 {
1728 (*self).mul(rhs)
1729 }
1730}
1731
1732impl MulAssign for DMat4 {
1733 #[inline]
1734 fn mul_assign(&mut self, rhs: Self) {
1735 *self = self.mul(rhs);
1736 }
1737}
1738
1739impl MulAssign<&Self> for DMat4 {
1740 #[inline]
1741 fn mul_assign(&mut self, rhs: &Self) {
1742 self.mul_assign(*rhs);
1743 }
1744}
1745
1746impl Mul<DVec4> for DMat4 {
1747 type Output = DVec4;
1748 #[inline]
1749 fn mul(self, rhs: DVec4) -> Self::Output {
1750 self.mul_vec4(rhs)
1751 }
1752}
1753
1754impl Mul<&DVec4> for DMat4 {
1755 type Output = DVec4;
1756 #[inline]
1757 fn mul(self, rhs: &DVec4) -> DVec4 {
1758 self.mul(*rhs)
1759 }
1760}
1761
1762impl Mul<&DVec4> for &DMat4 {
1763 type Output = DVec4;
1764 #[inline]
1765 fn mul(self, rhs: &DVec4) -> DVec4 {
1766 (*self).mul(*rhs)
1767 }
1768}
1769
1770impl Mul<DVec4> for &DMat4 {
1771 type Output = DVec4;
1772 #[inline]
1773 fn mul(self, rhs: DVec4) -> DVec4 {
1774 (*self).mul(rhs)
1775 }
1776}
1777
1778impl Mul<DMat4> for f64 {
1779 type Output = DMat4;
1780 #[inline]
1781 fn mul(self, rhs: DMat4) -> Self::Output {
1782 rhs.mul_scalar(self)
1783 }
1784}
1785
1786impl Mul<&DMat4> for f64 {
1787 type Output = DMat4;
1788 #[inline]
1789 fn mul(self, rhs: &DMat4) -> DMat4 {
1790 self.mul(*rhs)
1791 }
1792}
1793
1794impl Mul<&DMat4> for &f64 {
1795 type Output = DMat4;
1796 #[inline]
1797 fn mul(self, rhs: &DMat4) -> DMat4 {
1798 (*self).mul(*rhs)
1799 }
1800}
1801
1802impl Mul<DMat4> for &f64 {
1803 type Output = DMat4;
1804 #[inline]
1805 fn mul(self, rhs: DMat4) -> DMat4 {
1806 (*self).mul(rhs)
1807 }
1808}
1809
1810impl Mul<f64> for DMat4 {
1811 type Output = Self;
1812 #[inline]
1813 fn mul(self, rhs: f64) -> Self {
1814 self.mul_scalar(rhs)
1815 }
1816}
1817
1818impl Mul<&f64> for DMat4 {
1819 type Output = Self;
1820 #[inline]
1821 fn mul(self, rhs: &f64) -> Self {
1822 self.mul(*rhs)
1823 }
1824}
1825
1826impl Mul<&f64> for &DMat4 {
1827 type Output = DMat4;
1828 #[inline]
1829 fn mul(self, rhs: &f64) -> DMat4 {
1830 (*self).mul(*rhs)
1831 }
1832}
1833
1834impl Mul<f64> for &DMat4 {
1835 type Output = DMat4;
1836 #[inline]
1837 fn mul(self, rhs: f64) -> DMat4 {
1838 (*self).mul(rhs)
1839 }
1840}
1841
1842impl MulAssign<f64> for DMat4 {
1843 #[inline]
1844 fn mul_assign(&mut self, rhs: f64) {
1845 *self = self.mul(rhs);
1846 }
1847}
1848
1849impl MulAssign<&f64> for DMat4 {
1850 #[inline]
1851 fn mul_assign(&mut self, rhs: &f64) {
1852 self.mul_assign(*rhs);
1853 }
1854}
1855
1856impl Div<DMat4> for f64 {
1857 type Output = DMat4;
1858 #[inline]
1859 fn div(self, rhs: DMat4) -> Self::Output {
1860 DMat4::from_cols(
1861 self.div(rhs.x_axis),
1862 self.div(rhs.y_axis),
1863 self.div(rhs.z_axis),
1864 self.div(rhs.w_axis),
1865 )
1866 }
1867}
1868
1869impl Div<&DMat4> for f64 {
1870 type Output = DMat4;
1871 #[inline]
1872 fn div(self, rhs: &DMat4) -> DMat4 {
1873 self.div(*rhs)
1874 }
1875}
1876
1877impl Div<&DMat4> for &f64 {
1878 type Output = DMat4;
1879 #[inline]
1880 fn div(self, rhs: &DMat4) -> DMat4 {
1881 (*self).div(*rhs)
1882 }
1883}
1884
1885impl Div<DMat4> for &f64 {
1886 type Output = DMat4;
1887 #[inline]
1888 fn div(self, rhs: DMat4) -> DMat4 {
1889 (*self).div(rhs)
1890 }
1891}
1892
1893impl Div<f64> for DMat4 {
1894 type Output = Self;
1895 #[inline]
1896 fn div(self, rhs: f64) -> Self {
1897 self.div_scalar(rhs)
1898 }
1899}
1900
1901impl Div<&f64> for DMat4 {
1902 type Output = Self;
1903 #[inline]
1904 fn div(self, rhs: &f64) -> Self {
1905 self.div(*rhs)
1906 }
1907}
1908
1909impl Div<&f64> for &DMat4 {
1910 type Output = DMat4;
1911 #[inline]
1912 fn div(self, rhs: &f64) -> DMat4 {
1913 (*self).div(*rhs)
1914 }
1915}
1916
1917impl Div<f64> for &DMat4 {
1918 type Output = DMat4;
1919 #[inline]
1920 fn div(self, rhs: f64) -> DMat4 {
1921 (*self).div(rhs)
1922 }
1923}
1924
1925impl DivAssign<f64> for DMat4 {
1926 #[inline]
1927 fn div_assign(&mut self, rhs: f64) {
1928 *self = self.div(rhs);
1929 }
1930}
1931
1932impl DivAssign<&f64> for DMat4 {
1933 #[inline]
1934 fn div_assign(&mut self, rhs: &f64) {
1935 self.div_assign(*rhs);
1936 }
1937}
1938
1939impl Sum<Self> for DMat4 {
1940 fn sum<I>(iter: I) -> Self
1941 where
1942 I: Iterator<Item = Self>,
1943 {
1944 iter.fold(Self::ZERO, Self::add)
1945 }
1946}
1947
1948impl<'a> Sum<&'a Self> for DMat4 {
1949 fn sum<I>(iter: I) -> Self
1950 where
1951 I: Iterator<Item = &'a Self>,
1952 {
1953 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1954 }
1955}
1956
1957impl Product for DMat4 {
1958 fn product<I>(iter: I) -> Self
1959 where
1960 I: Iterator<Item = Self>,
1961 {
1962 iter.fold(Self::IDENTITY, Self::mul)
1963 }
1964}
1965
1966impl<'a> Product<&'a Self> for DMat4 {
1967 fn product<I>(iter: I) -> Self
1968 where
1969 I: Iterator<Item = &'a Self>,
1970 {
1971 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1972 }
1973}
1974
1975impl PartialEq for DMat4 {
1976 #[inline]
1977 fn eq(&self, rhs: &Self) -> bool {
1978 self.x_axis.eq(&rhs.x_axis)
1979 && self.y_axis.eq(&rhs.y_axis)
1980 && self.z_axis.eq(&rhs.z_axis)
1981 && self.w_axis.eq(&rhs.w_axis)
1982 }
1983}
1984
1985impl AsRef<[f64; 16]> for DMat4 {
1986 #[inline]
1987 fn as_ref(&self) -> &[f64; 16] {
1988 unsafe { &*(self as *const Self as *const [f64; 16]) }
1989 }
1990}
1991
1992impl AsMut<[f64; 16]> for DMat4 {
1993 #[inline]
1994 fn as_mut(&mut self) -> &mut [f64; 16] {
1995 unsafe { &mut *(self as *mut Self as *mut [f64; 16]) }
1996 }
1997}
1998
1999impl fmt::Debug for DMat4 {
2000 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
2001 fmt.debug_struct(stringify!(DMat4))
2002 .field("x_axis", &self.x_axis)
2003 .field("y_axis", &self.y_axis)
2004 .field("z_axis", &self.z_axis)
2005 .field("w_axis", &self.w_axis)
2006 .finish()
2007 }
2008}
2009
2010impl fmt::Display for DMat4 {
2011 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2012 if let Some(p) = f.precision() {
2013 write!(
2014 f,
2015 "[{:.*}, {:.*}, {:.*}, {:.*}]",
2016 p, self.x_axis, p, self.y_axis, p, self.z_axis, p, self.w_axis
2017 )
2018 } else {
2019 write!(
2020 f,
2021 "[{}, {}, {}, {}]",
2022 self.x_axis, self.y_axis, self.z_axis, self.w_axis
2023 )
2024 }
2025 }
2026}