1use crate::{
4 euler::{FromEuler, ToEuler},
5 f64::math,
6 swizzles::*,
7 DMat2, DMat4, DQuat, DVec2, DVec3, EulerRot, Mat3,
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 dmat3(x_axis: DVec3, y_axis: DVec3, z_axis: DVec3) -> DMat3 {
20 DMat3::from_cols(x_axis, y_axis, z_axis)
21}
22
23#[derive(Clone, Copy)]
48#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
49#[cfg_attr(
50 feature = "zerocopy-08",
51 derive(FromBytes, Immutable, IntoBytes, KnownLayout)
52)]
53#[repr(C)]
54pub struct DMat3 {
55 pub x_axis: DVec3,
56 pub y_axis: DVec3,
57 pub z_axis: DVec3,
58}
59
60impl DMat3 {
61 pub const ZERO: Self = Self::from_cols(DVec3::ZERO, DVec3::ZERO, DVec3::ZERO);
63
64 pub const IDENTITY: Self = Self::from_cols(DVec3::X, DVec3::Y, DVec3::Z);
66
67 pub const NAN: Self = Self::from_cols(DVec3::NAN, DVec3::NAN, DVec3::NAN);
69
70 #[allow(clippy::too_many_arguments)]
71 #[inline(always)]
72 #[must_use]
73 const fn new(
74 m00: f64,
75 m01: f64,
76 m02: f64,
77 m10: f64,
78 m11: f64,
79 m12: f64,
80 m20: f64,
81 m21: f64,
82 m22: f64,
83 ) -> Self {
84 Self {
85 x_axis: DVec3::new(m00, m01, m02),
86 y_axis: DVec3::new(m10, m11, m12),
87 z_axis: DVec3::new(m20, m21, m22),
88 }
89 }
90
91 #[inline(always)]
95 #[must_use]
96 pub const fn from_cols(x_axis: DVec3, y_axis: DVec3, z_axis: DVec3) -> Self {
97 Self {
98 x_axis,
99 y_axis,
100 z_axis,
101 }
102 }
103
104 #[inline(always)]
110 #[must_use]
111 pub const fn from_rows(row0: DVec3, row1: DVec3, row2: DVec3) -> Self {
112 let [m00, m01, m02] = row0.to_array();
113 let [m10, m11, m12] = row1.to_array();
114 let [m20, m21, m22] = row2.to_array();
115 Self::new(m00, m10, m20, m01, m11, m21, m02, m12, m22)
116 }
117
118 #[inline]
122 #[must_use]
123 pub const fn from_cols_array(m: &[f64; 9]) -> Self {
124 Self::new(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8])
125 }
126
127 #[inline]
131 #[must_use]
132 pub const fn to_cols_array(&self) -> [f64; 9] {
133 [
134 self.x_axis.x,
135 self.x_axis.y,
136 self.x_axis.z,
137 self.y_axis.x,
138 self.y_axis.y,
139 self.y_axis.z,
140 self.z_axis.x,
141 self.z_axis.y,
142 self.z_axis.z,
143 ]
144 }
145
146 #[inline]
150 #[must_use]
151 pub const fn from_cols_array_2d(m: &[[f64; 3]; 3]) -> Self {
152 Self::from_cols(
153 DVec3::from_array(m[0]),
154 DVec3::from_array(m[1]),
155 DVec3::from_array(m[2]),
156 )
157 }
158
159 #[inline]
163 #[must_use]
164 pub const fn to_cols_array_2d(&self) -> [[f64; 3]; 3] {
165 [
166 self.x_axis.to_array(),
167 self.y_axis.to_array(),
168 self.z_axis.to_array(),
169 ]
170 }
171
172 #[inline]
178 #[must_use]
179 pub const fn from_rows_array(m: &[f64; 9]) -> Self {
180 Self::new(m[0], m[3], m[6], m[1], m[4], m[7], m[2], m[5], m[8])
181 }
182
183 #[inline]
189 #[must_use]
190 pub const fn to_rows_array(&self) -> [f64; 9] {
191 let m = self.to_cols_array();
192 [m[0], m[3], m[6], m[1], m[4], m[7], m[2], m[5], m[8]]
193 }
194
195 #[doc(alias = "scale")]
197 #[inline]
198 #[must_use]
199 pub const fn from_diagonal(diagonal: DVec3) -> Self {
200 Self::new(
201 diagonal.x, 0.0, 0.0, 0.0, diagonal.y, 0.0, 0.0, 0.0, diagonal.z,
202 )
203 }
204
205 #[inline]
207 #[must_use]
208 pub fn from_mat4(m: DMat4) -> Self {
209 Self::from_cols(
210 DVec3::from_vec4(m.x_axis),
211 DVec3::from_vec4(m.y_axis),
212 DVec3::from_vec4(m.z_axis),
213 )
214 }
215
216 #[inline]
223 #[must_use]
224 #[track_caller]
225 pub fn from_mat4_minor(m: DMat4, i: usize, j: usize) -> Self {
226 match (i, j) {
227 (0, 0) => Self::from_cols(m.y_axis.yzw(), m.z_axis.yzw(), m.w_axis.yzw()),
228 (0, 1) => Self::from_cols(m.y_axis.xzw(), m.z_axis.xzw(), m.w_axis.xzw()),
229 (0, 2) => Self::from_cols(m.y_axis.xyw(), m.z_axis.xyw(), m.w_axis.xyw()),
230 (0, 3) => Self::from_cols(m.y_axis.xyz(), m.z_axis.xyz(), m.w_axis.xyz()),
231 (1, 0) => Self::from_cols(m.x_axis.yzw(), m.z_axis.yzw(), m.w_axis.yzw()),
232 (1, 1) => Self::from_cols(m.x_axis.xzw(), m.z_axis.xzw(), m.w_axis.xzw()),
233 (1, 2) => Self::from_cols(m.x_axis.xyw(), m.z_axis.xyw(), m.w_axis.xyw()),
234 (1, 3) => Self::from_cols(m.x_axis.xyz(), m.z_axis.xyz(), m.w_axis.xyz()),
235 (2, 0) => Self::from_cols(m.x_axis.yzw(), m.y_axis.yzw(), m.w_axis.yzw()),
236 (2, 1) => Self::from_cols(m.x_axis.xzw(), m.y_axis.xzw(), m.w_axis.xzw()),
237 (2, 2) => Self::from_cols(m.x_axis.xyw(), m.y_axis.xyw(), m.w_axis.xyw()),
238 (2, 3) => Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.w_axis.xyz()),
239 (3, 0) => Self::from_cols(m.x_axis.yzw(), m.y_axis.yzw(), m.z_axis.yzw()),
240 (3, 1) => Self::from_cols(m.x_axis.xzw(), m.y_axis.xzw(), m.z_axis.xzw()),
241 (3, 2) => Self::from_cols(m.x_axis.xyw(), m.y_axis.xyw(), m.z_axis.xyw()),
242 (3, 3) => Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.z_axis.xyz()),
243 _ => panic!("index out of bounds"),
244 }
245 }
246
247 #[inline]
253 #[must_use]
254 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
255 pub fn from_quat(rotation: DQuat) -> Self {
256 glam_assert!(rotation.is_normalized());
257
258 let x2 = rotation.x + rotation.x;
259 let y2 = rotation.y + rotation.y;
260 let z2 = rotation.z + rotation.z;
261 let xx = rotation.x * x2;
262 let xy = rotation.x * y2;
263 let xz = rotation.x * z2;
264 let yy = rotation.y * y2;
265 let yz = rotation.y * z2;
266 let zz = rotation.z * z2;
267 let wx = rotation.w * x2;
268 let wy = rotation.w * y2;
269 let wz = rotation.w * z2;
270
271 Self::from_cols(
272 DVec3::new(1.0 - (yy + zz), xy + wz, xz - wy),
273 DVec3::new(xy - wz, 1.0 - (xx + zz), yz + wx),
274 DVec3::new(xz + wy, yz - wx, 1.0 - (xx + yy)),
275 )
276 }
277
278 #[inline]
285 #[must_use]
286 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
287 pub fn from_axis_angle(axis: DVec3, angle: f64) -> Self {
288 glam_assert!(axis.is_normalized());
289
290 let (sin, cos) = math::sin_cos(angle);
291 let (xsin, ysin, zsin) = axis.mul(sin).into();
292 let (x, y, z) = axis.into();
293 let (x2, y2, z2) = axis.mul(axis).into();
294 let omc = 1.0 - cos;
295 let xyomc = x * y * omc;
296 let xzomc = x * z * omc;
297 let yzomc = y * z * omc;
298 Self::from_cols(
299 DVec3::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
300 DVec3::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
301 DVec3::new(xzomc + ysin, yzomc - xsin, z2 * omc + cos),
302 )
303 }
304
305 #[inline]
308 #[must_use]
309 pub fn from_euler(order: EulerRot, a: f64, b: f64, c: f64) -> Self {
310 Self::from_euler_angles(order, a, b, c)
311 }
312
313 #[inline]
322 #[must_use]
323 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
324 pub fn to_euler(&self, order: EulerRot) -> (f64, f64, f64) {
325 glam_assert!(
326 self.x_axis.is_normalized()
327 && self.y_axis.is_normalized()
328 && self.z_axis.is_normalized()
329 );
330 self.to_euler_angles(order)
331 }
332
333 #[inline]
335 #[must_use]
336 pub fn from_rotation_x(angle: f64) -> Self {
337 let (sina, cosa) = math::sin_cos(angle);
338 Self::from_cols(
339 DVec3::X,
340 DVec3::new(0.0, cosa, sina),
341 DVec3::new(0.0, -sina, cosa),
342 )
343 }
344
345 #[inline]
347 #[must_use]
348 pub fn from_rotation_y(angle: f64) -> Self {
349 let (sina, cosa) = math::sin_cos(angle);
350 Self::from_cols(
351 DVec3::new(cosa, 0.0, -sina),
352 DVec3::Y,
353 DVec3::new(sina, 0.0, cosa),
354 )
355 }
356
357 #[inline]
359 #[must_use]
360 pub fn from_rotation_z(angle: f64) -> Self {
361 let (sina, cosa) = math::sin_cos(angle);
362 Self::from_cols(
363 DVec3::new(cosa, sina, 0.0),
364 DVec3::new(-sina, cosa, 0.0),
365 DVec3::Z,
366 )
367 }
368
369 #[inline]
374 #[must_use]
375 pub fn from_translation(translation: DVec2) -> Self {
376 Self::from_cols(
377 DVec3::X,
378 DVec3::Y,
379 DVec3::new(translation.x, translation.y, 1.0),
380 )
381 }
382
383 #[inline]
389 #[must_use]
390 pub fn from_angle(angle: f64) -> Self {
391 let (sin, cos) = math::sin_cos(angle);
392 Self::from_cols(
393 DVec3::new(cos, sin, 0.0),
394 DVec3::new(-sin, cos, 0.0),
395 DVec3::Z,
396 )
397 }
398
399 #[inline]
405 #[must_use]
406 pub fn from_scale_angle_translation(scale: DVec2, angle: f64, translation: DVec2) -> Self {
407 let (sin, cos) = math::sin_cos(angle);
408 Self::from_cols(
409 DVec3::new(cos * scale.x, sin * scale.x, 0.0),
410 DVec3::new(-sin * scale.y, cos * scale.y, 0.0),
411 DVec3::new(translation.x, translation.y, 1.0),
412 )
413 }
414
415 #[inline]
424 #[must_use]
425 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
426 pub fn from_scale(scale: DVec2) -> Self {
427 glam_assert!(scale.cmpne(DVec2::ZERO).any());
429
430 Self::from_cols(
431 DVec3::new(scale.x, 0.0, 0.0),
432 DVec3::new(0.0, scale.y, 0.0),
433 DVec3::Z,
434 )
435 }
436
437 #[inline]
442 pub fn from_mat2(m: DMat2) -> Self {
443 Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), DVec3::Z)
444 }
445
446 #[inline]
454 #[must_use]
455 #[track_caller]
456 pub const fn from_cols_slice(slice: &[f64]) -> Self {
457 Self::new(
458 slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
459 slice[8],
460 )
461 }
462
463 #[inline]
469 #[track_caller]
470 pub fn write_cols_to_slice(&self, slice: &mut [f64]) {
471 slice[0] = self.x_axis.x;
472 slice[1] = self.x_axis.y;
473 slice[2] = self.x_axis.z;
474 slice[3] = self.y_axis.x;
475 slice[4] = self.y_axis.y;
476 slice[5] = self.y_axis.z;
477 slice[6] = self.z_axis.x;
478 slice[7] = self.z_axis.y;
479 slice[8] = self.z_axis.z;
480 }
481
482 #[inline]
493 #[must_use]
494 #[track_caller]
495 pub const fn from_rows_slice(slice: &[f64]) -> Self {
496 Self::new(
497 slice[0], slice[3], slice[6], slice[1], slice[4], slice[7], slice[2], slice[5],
498 slice[8],
499 )
500 }
501
502 #[inline]
508 #[must_use]
509 #[track_caller]
510 pub fn col(&self, index: usize) -> DVec3 {
511 match index {
512 0 => self.x_axis,
513 1 => self.y_axis,
514 2 => self.z_axis,
515 _ => panic!("index out of bounds"),
516 }
517 }
518
519 #[inline]
525 #[track_caller]
526 pub fn col_mut(&mut self, index: usize) -> &mut DVec3 {
527 match index {
528 0 => &mut self.x_axis,
529 1 => &mut self.y_axis,
530 2 => &mut self.z_axis,
531 _ => panic!("index out of bounds"),
532 }
533 }
534
535 #[inline]
543 #[must_use]
544 #[track_caller]
545 pub fn row(&self, index: usize) -> DVec3 {
546 match index {
547 0 => DVec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
548 1 => DVec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
549 2 => DVec3::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
550 _ => panic!("index out of bounds"),
551 }
552 }
553
554 #[inline]
564 #[track_caller]
565 pub fn set_row(&mut self, index: usize, row: DVec3) {
566 match index {
567 0 => {
568 self.x_axis.x = row.x;
569 self.y_axis.x = row.y;
570 self.z_axis.x = row.z;
571 }
572 1 => {
573 self.x_axis.y = row.x;
574 self.y_axis.y = row.y;
575 self.z_axis.y = row.z;
576 }
577 2 => {
578 self.x_axis.z = row.x;
579 self.y_axis.z = row.y;
580 self.z_axis.z = row.z;
581 }
582 _ => panic!("index out of bounds"),
583 }
584 }
585
586 #[inline]
589 #[must_use]
590 pub fn is_finite(&self) -> bool {
591 self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
592 }
593
594 #[inline]
596 #[must_use]
597 pub fn is_nan(&self) -> bool {
598 self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
599 }
600
601 #[inline]
603 #[must_use]
604 pub fn transpose(&self) -> Self {
605 Self {
606 x_axis: DVec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
607 y_axis: DVec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
608 z_axis: DVec3::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
609 }
610 }
611
612 #[inline]
614 #[must_use]
615 pub fn diagonal(&self) -> DVec3 {
616 DVec3::new(self.x_axis.x, self.y_axis.y, self.z_axis.z)
617 }
618
619 #[inline]
621 #[must_use]
622 pub fn determinant(&self) -> f64 {
623 self.x_axis.dot(self.y_axis.cross(self.z_axis))
624 }
625
626 #[inline(always)]
638 #[must_use]
639 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
640 fn inverse_checked<const CHECKED: bool>(&self) -> (Self, bool) {
641 let tmp0 = self.y_axis.cross(self.z_axis);
642 let tmp1 = self.z_axis.cross(self.x_axis);
643 let tmp2 = self.x_axis.cross(self.y_axis);
644 let inv_det = DVec3::splat(1.0 / self.x_axis.dot(tmp0));
645 let m =
646 Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose();
647 if CHECKED {
648 if !m.is_finite() {
649 return (Self::ZERO, false);
650 }
651 } else {
652 glam_assert!(m.is_finite());
653 }
654 (m, true)
655 }
656
657 #[inline]
669 #[must_use]
670 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
671 pub fn inverse(&self) -> Self {
672 self.inverse_checked::<false>().0
673 }
674
675 #[inline]
678 #[must_use]
679 pub fn try_inverse(&self) -> Option<Self> {
680 let (m, is_valid) = self.inverse_checked::<true>();
681 if is_valid {
682 Some(m)
683 } else {
684 None
685 }
686 }
687
688 #[inline]
691 #[must_use]
692 pub fn inverse_or_zero(&self) -> Self {
693 self.inverse_checked::<true>().0
694 }
695
696 #[inline]
706 #[must_use]
707 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
708 pub fn transform_point2(&self, rhs: DVec2) -> DVec2 {
709 glam_assert!(self.row(2).abs_diff_eq(DVec3::Z, 1e-6));
710 DMat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
711 }
712
713 #[inline]
723 #[must_use]
724 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
725 pub fn transform_vector2(&self, rhs: DVec2) -> DVec2 {
726 glam_assert!(self.row(2).abs_diff_eq(DVec3::Z, 1e-6));
727 DMat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
728 }
729
730 #[deprecated(
739 since = "0.33.1",
740 note = "use the `glam::dcamera::lh::view::look_to_mat3` function instead"
741 )]
742 #[inline]
743 #[must_use]
744 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
745 pub fn look_to_lh(dir: DVec3, up: DVec3) -> Self {
746 #[allow(deprecated)]
747 Self::look_to_rh(-dir, up)
748 }
749
750 #[deprecated(
759 since = "0.33.1",
760 note = "use the `glam::dcamera::rh::view::look_to_mat3` function instead"
761 )]
762 #[inline]
763 #[must_use]
764 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
765 pub fn look_to_rh(dir: DVec3, up: DVec3) -> Self {
766 glam_assert!(dir.is_normalized());
767 glam_assert!(up.is_normalized());
768 let f = dir;
769 let s = f.cross(up).normalize();
770 let u = s.cross(f);
771
772 Self::from_cols(
773 DVec3::new(s.x, u.x, -f.x),
774 DVec3::new(s.y, u.y, -f.y),
775 DVec3::new(s.z, u.z, -f.z),
776 )
777 }
778
779 #[deprecated(
789 since = "0.33.1",
790 note = "use the `glam::dcamera::lh::view::look_at_mat3` function instead"
791 )]
792 #[inline]
793 #[must_use]
794 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
795 pub fn look_at_lh(eye: DVec3, center: DVec3, up: DVec3) -> Self {
796 #[allow(deprecated)]
797 Self::look_to_lh(center.sub(eye).normalize(), up)
798 }
799
800 #[deprecated(
810 since = "0.33.1",
811 note = "use the `glam::dcamera::rh::view::look_at_mat3` function instead"
812 )]
813 #[inline]
814 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
815 pub fn look_at_rh(eye: DVec3, center: DVec3, up: DVec3) -> Self {
816 #[allow(deprecated)]
817 Self::look_to_rh(center.sub(eye).normalize(), up)
818 }
819
820 #[inline]
822 #[must_use]
823 pub fn mul_vec3(&self, rhs: DVec3) -> DVec3 {
824 let mut res = self.x_axis.mul(rhs.x);
825 res = res.add(self.y_axis.mul(rhs.y));
826 res = res.add(self.z_axis.mul(rhs.z));
827 res
828 }
829
830 #[inline]
832 #[must_use]
833 pub fn mul_transpose_vec3(&self, rhs: DVec3) -> DVec3 {
834 DVec3::new(
835 self.x_axis.dot(rhs),
836 self.y_axis.dot(rhs),
837 self.z_axis.dot(rhs),
838 )
839 }
840
841 #[inline]
843 #[must_use]
844 pub fn mul_mat3(&self, rhs: &Self) -> Self {
845 self.mul(rhs)
846 }
847
848 #[inline]
850 #[must_use]
851 pub fn add_mat3(&self, rhs: &Self) -> Self {
852 self.add(rhs)
853 }
854
855 #[inline]
857 #[must_use]
858 pub fn sub_mat3(&self, rhs: &Self) -> Self {
859 self.sub(rhs)
860 }
861
862 #[inline]
864 #[must_use]
865 pub fn mul_scalar(&self, rhs: f64) -> Self {
866 Self::from_cols(
867 self.x_axis.mul(rhs),
868 self.y_axis.mul(rhs),
869 self.z_axis.mul(rhs),
870 )
871 }
872
873 #[inline]
877 #[must_use]
878 pub fn mul_diagonal_scale(&self, scale: DVec3) -> Self {
879 Self::from_cols(
880 self.x_axis * scale.x,
881 self.y_axis * scale.y,
882 self.z_axis * scale.z,
883 )
884 }
885
886 #[inline]
888 #[must_use]
889 pub fn div_scalar(&self, rhs: f64) -> Self {
890 let rhs = DVec3::splat(rhs);
891 Self::from_cols(
892 self.x_axis.div(rhs),
893 self.y_axis.div(rhs),
894 self.z_axis.div(rhs),
895 )
896 }
897
898 #[inline]
900 #[must_use]
901 pub fn recip(&self) -> Self {
902 Self::from_cols(
903 self.x_axis.recip(),
904 self.y_axis.recip(),
905 self.z_axis.recip(),
906 )
907 }
908
909 #[inline]
919 #[must_use]
920 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f64) -> bool {
921 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
922 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
923 && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
924 }
925
926 #[inline]
928 #[must_use]
929 pub fn abs(&self) -> Self {
930 Self::from_cols(self.x_axis.abs(), self.y_axis.abs(), self.z_axis.abs())
931 }
932
933 #[cfg(feature = "f64")]
934 #[inline]
935 #[must_use]
936 pub fn as_mat3(&self) -> Mat3 {
937 Mat3::from_cols(
938 self.x_axis.as_vec3(),
939 self.y_axis.as_vec3(),
940 self.z_axis.as_vec3(),
941 )
942 }
943}
944
945impl Default for DMat3 {
946 #[inline]
947 fn default() -> Self {
948 Self::IDENTITY
949 }
950}
951
952impl Add for DMat3 {
953 type Output = Self;
954 #[inline]
955 fn add(self, rhs: Self) -> Self {
956 Self::from_cols(
957 self.x_axis.add(rhs.x_axis),
958 self.y_axis.add(rhs.y_axis),
959 self.z_axis.add(rhs.z_axis),
960 )
961 }
962}
963
964impl Add<&Self> for DMat3 {
965 type Output = Self;
966 #[inline]
967 fn add(self, rhs: &Self) -> Self {
968 self.add(*rhs)
969 }
970}
971
972impl Add<&DMat3> for &DMat3 {
973 type Output = DMat3;
974 #[inline]
975 fn add(self, rhs: &DMat3) -> DMat3 {
976 (*self).add(*rhs)
977 }
978}
979
980impl Add<DMat3> for &DMat3 {
981 type Output = DMat3;
982 #[inline]
983 fn add(self, rhs: DMat3) -> DMat3 {
984 (*self).add(rhs)
985 }
986}
987
988impl AddAssign for DMat3 {
989 #[inline]
990 fn add_assign(&mut self, rhs: Self) {
991 *self = self.add(rhs);
992 }
993}
994
995impl AddAssign<&Self> for DMat3 {
996 #[inline]
997 fn add_assign(&mut self, rhs: &Self) {
998 self.add_assign(*rhs);
999 }
1000}
1001
1002impl Sub for DMat3 {
1003 type Output = Self;
1004 #[inline]
1005 fn sub(self, rhs: Self) -> Self {
1006 Self::from_cols(
1007 self.x_axis.sub(rhs.x_axis),
1008 self.y_axis.sub(rhs.y_axis),
1009 self.z_axis.sub(rhs.z_axis),
1010 )
1011 }
1012}
1013
1014impl Sub<&Self> for DMat3 {
1015 type Output = Self;
1016 #[inline]
1017 fn sub(self, rhs: &Self) -> Self {
1018 self.sub(*rhs)
1019 }
1020}
1021
1022impl Sub<&DMat3> for &DMat3 {
1023 type Output = DMat3;
1024 #[inline]
1025 fn sub(self, rhs: &DMat3) -> DMat3 {
1026 (*self).sub(*rhs)
1027 }
1028}
1029
1030impl Sub<DMat3> for &DMat3 {
1031 type Output = DMat3;
1032 #[inline]
1033 fn sub(self, rhs: DMat3) -> DMat3 {
1034 (*self).sub(rhs)
1035 }
1036}
1037
1038impl SubAssign for DMat3 {
1039 #[inline]
1040 fn sub_assign(&mut self, rhs: Self) {
1041 *self = self.sub(rhs);
1042 }
1043}
1044
1045impl SubAssign<&Self> for DMat3 {
1046 #[inline]
1047 fn sub_assign(&mut self, rhs: &Self) {
1048 self.sub_assign(*rhs);
1049 }
1050}
1051
1052impl Neg for DMat3 {
1053 type Output = Self;
1054 #[inline]
1055 fn neg(self) -> Self::Output {
1056 Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
1057 }
1058}
1059
1060impl Neg for &DMat3 {
1061 type Output = DMat3;
1062 #[inline]
1063 fn neg(self) -> DMat3 {
1064 (*self).neg()
1065 }
1066}
1067
1068impl Mul for DMat3 {
1069 type Output = Self;
1070 #[inline]
1071 fn mul(self, rhs: Self) -> Self {
1072 Self::from_cols(
1073 self.mul(rhs.x_axis),
1074 self.mul(rhs.y_axis),
1075 self.mul(rhs.z_axis),
1076 )
1077 }
1078}
1079
1080impl Mul<&Self> for DMat3 {
1081 type Output = Self;
1082 #[inline]
1083 fn mul(self, rhs: &Self) -> Self {
1084 self.mul(*rhs)
1085 }
1086}
1087
1088impl Mul<&DMat3> for &DMat3 {
1089 type Output = DMat3;
1090 #[inline]
1091 fn mul(self, rhs: &DMat3) -> DMat3 {
1092 (*self).mul(*rhs)
1093 }
1094}
1095
1096impl Mul<DMat3> for &DMat3 {
1097 type Output = DMat3;
1098 #[inline]
1099 fn mul(self, rhs: DMat3) -> DMat3 {
1100 (*self).mul(rhs)
1101 }
1102}
1103
1104impl MulAssign for DMat3 {
1105 #[inline]
1106 fn mul_assign(&mut self, rhs: Self) {
1107 *self = self.mul(rhs);
1108 }
1109}
1110
1111impl MulAssign<&Self> for DMat3 {
1112 #[inline]
1113 fn mul_assign(&mut self, rhs: &Self) {
1114 self.mul_assign(*rhs);
1115 }
1116}
1117
1118impl Mul<DVec3> for DMat3 {
1119 type Output = DVec3;
1120 #[inline]
1121 fn mul(self, rhs: DVec3) -> Self::Output {
1122 self.mul_vec3(rhs)
1123 }
1124}
1125
1126impl Mul<&DVec3> for DMat3 {
1127 type Output = DVec3;
1128 #[inline]
1129 fn mul(self, rhs: &DVec3) -> DVec3 {
1130 self.mul(*rhs)
1131 }
1132}
1133
1134impl Mul<&DVec3> for &DMat3 {
1135 type Output = DVec3;
1136 #[inline]
1137 fn mul(self, rhs: &DVec3) -> DVec3 {
1138 (*self).mul(*rhs)
1139 }
1140}
1141
1142impl Mul<DVec3> for &DMat3 {
1143 type Output = DVec3;
1144 #[inline]
1145 fn mul(self, rhs: DVec3) -> DVec3 {
1146 (*self).mul(rhs)
1147 }
1148}
1149
1150impl Mul<DMat3> for f64 {
1151 type Output = DMat3;
1152 #[inline]
1153 fn mul(self, rhs: DMat3) -> Self::Output {
1154 rhs.mul_scalar(self)
1155 }
1156}
1157
1158impl Mul<&DMat3> for f64 {
1159 type Output = DMat3;
1160 #[inline]
1161 fn mul(self, rhs: &DMat3) -> DMat3 {
1162 self.mul(*rhs)
1163 }
1164}
1165
1166impl Mul<&DMat3> for &f64 {
1167 type Output = DMat3;
1168 #[inline]
1169 fn mul(self, rhs: &DMat3) -> DMat3 {
1170 (*self).mul(*rhs)
1171 }
1172}
1173
1174impl Mul<DMat3> for &f64 {
1175 type Output = DMat3;
1176 #[inline]
1177 fn mul(self, rhs: DMat3) -> DMat3 {
1178 (*self).mul(rhs)
1179 }
1180}
1181
1182impl Mul<f64> for DMat3 {
1183 type Output = Self;
1184 #[inline]
1185 fn mul(self, rhs: f64) -> Self {
1186 self.mul_scalar(rhs)
1187 }
1188}
1189
1190impl Mul<&f64> for DMat3 {
1191 type Output = Self;
1192 #[inline]
1193 fn mul(self, rhs: &f64) -> Self {
1194 self.mul(*rhs)
1195 }
1196}
1197
1198impl Mul<&f64> for &DMat3 {
1199 type Output = DMat3;
1200 #[inline]
1201 fn mul(self, rhs: &f64) -> DMat3 {
1202 (*self).mul(*rhs)
1203 }
1204}
1205
1206impl Mul<f64> for &DMat3 {
1207 type Output = DMat3;
1208 #[inline]
1209 fn mul(self, rhs: f64) -> DMat3 {
1210 (*self).mul(rhs)
1211 }
1212}
1213
1214impl MulAssign<f64> for DMat3 {
1215 #[inline]
1216 fn mul_assign(&mut self, rhs: f64) {
1217 *self = self.mul(rhs);
1218 }
1219}
1220
1221impl MulAssign<&f64> for DMat3 {
1222 #[inline]
1223 fn mul_assign(&mut self, rhs: &f64) {
1224 self.mul_assign(*rhs);
1225 }
1226}
1227
1228impl Div<DMat3> for f64 {
1229 type Output = DMat3;
1230 #[inline]
1231 fn div(self, rhs: DMat3) -> Self::Output {
1232 DMat3::from_cols(
1233 self.div(rhs.x_axis),
1234 self.div(rhs.y_axis),
1235 self.div(rhs.z_axis),
1236 )
1237 }
1238}
1239
1240impl Div<&DMat3> for f64 {
1241 type Output = DMat3;
1242 #[inline]
1243 fn div(self, rhs: &DMat3) -> DMat3 {
1244 self.div(*rhs)
1245 }
1246}
1247
1248impl Div<&DMat3> for &f64 {
1249 type Output = DMat3;
1250 #[inline]
1251 fn div(self, rhs: &DMat3) -> DMat3 {
1252 (*self).div(*rhs)
1253 }
1254}
1255
1256impl Div<DMat3> for &f64 {
1257 type Output = DMat3;
1258 #[inline]
1259 fn div(self, rhs: DMat3) -> DMat3 {
1260 (*self).div(rhs)
1261 }
1262}
1263
1264impl Div<f64> for DMat3 {
1265 type Output = Self;
1266 #[inline]
1267 fn div(self, rhs: f64) -> Self {
1268 self.div_scalar(rhs)
1269 }
1270}
1271
1272impl Div<&f64> for DMat3 {
1273 type Output = Self;
1274 #[inline]
1275 fn div(self, rhs: &f64) -> Self {
1276 self.div(*rhs)
1277 }
1278}
1279
1280impl Div<&f64> for &DMat3 {
1281 type Output = DMat3;
1282 #[inline]
1283 fn div(self, rhs: &f64) -> DMat3 {
1284 (*self).div(*rhs)
1285 }
1286}
1287
1288impl Div<f64> for &DMat3 {
1289 type Output = DMat3;
1290 #[inline]
1291 fn div(self, rhs: f64) -> DMat3 {
1292 (*self).div(rhs)
1293 }
1294}
1295
1296impl DivAssign<f64> for DMat3 {
1297 #[inline]
1298 fn div_assign(&mut self, rhs: f64) {
1299 *self = self.div(rhs);
1300 }
1301}
1302
1303impl DivAssign<&f64> for DMat3 {
1304 #[inline]
1305 fn div_assign(&mut self, rhs: &f64) {
1306 self.div_assign(*rhs);
1307 }
1308}
1309
1310impl Sum<Self> for DMat3 {
1311 fn sum<I>(iter: I) -> Self
1312 where
1313 I: Iterator<Item = Self>,
1314 {
1315 iter.fold(Self::ZERO, Self::add)
1316 }
1317}
1318
1319impl<'a> Sum<&'a Self> for DMat3 {
1320 fn sum<I>(iter: I) -> Self
1321 where
1322 I: Iterator<Item = &'a Self>,
1323 {
1324 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1325 }
1326}
1327
1328impl Product for DMat3 {
1329 fn product<I>(iter: I) -> Self
1330 where
1331 I: Iterator<Item = Self>,
1332 {
1333 iter.fold(Self::IDENTITY, Self::mul)
1334 }
1335}
1336
1337impl<'a> Product<&'a Self> for DMat3 {
1338 fn product<I>(iter: I) -> Self
1339 where
1340 I: Iterator<Item = &'a Self>,
1341 {
1342 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1343 }
1344}
1345
1346impl PartialEq for DMat3 {
1347 #[inline]
1348 fn eq(&self, rhs: &Self) -> bool {
1349 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
1350 }
1351}
1352
1353impl AsRef<[f64; 9]> for DMat3 {
1354 #[inline]
1355 fn as_ref(&self) -> &[f64; 9] {
1356 unsafe { &*(self as *const Self as *const [f64; 9]) }
1357 }
1358}
1359
1360impl AsMut<[f64; 9]> for DMat3 {
1361 #[inline]
1362 fn as_mut(&mut self) -> &mut [f64; 9] {
1363 unsafe { &mut *(self as *mut Self as *mut [f64; 9]) }
1364 }
1365}
1366
1367impl fmt::Debug for DMat3 {
1368 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1369 fmt.debug_struct(stringify!(DMat3))
1370 .field("x_axis", &self.x_axis)
1371 .field("y_axis", &self.y_axis)
1372 .field("z_axis", &self.z_axis)
1373 .finish()
1374 }
1375}
1376
1377impl fmt::Display for DMat3 {
1378 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1379 if let Some(p) = f.precision() {
1380 write!(
1381 f,
1382 "[{:.*}, {:.*}, {:.*}]",
1383 p, self.x_axis, p, self.y_axis, p, self.z_axis
1384 )
1385 } else {
1386 write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
1387 }
1388 }
1389}