1use crate::{f32::math, swizzles::*, DMat3, EulerRot, Mat2, Mat3A, Mat4, Quat, Vec2, Vec3, Vec3A};
4#[cfg(not(target_arch = "spirv"))]
5use core::fmt;
6use core::iter::{Product, Sum};
7use core::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
8
9#[inline(always)]
11pub const fn mat3(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Mat3 {
12 Mat3::from_cols(x_axis, y_axis, z_axis)
13}
14
15#[derive(Clone, Copy)]
40#[repr(C)]
41pub struct Mat3 {
42 pub x_axis: Vec3,
43 pub y_axis: Vec3,
44 pub z_axis: Vec3,
45}
46
47impl Mat3 {
48 pub const ZERO: Self = Self::from_cols(Vec3::ZERO, Vec3::ZERO, Vec3::ZERO);
50
51 pub const IDENTITY: Self = Self::from_cols(Vec3::X, Vec3::Y, Vec3::Z);
53
54 pub const NAN: Self = Self::from_cols(Vec3::NAN, Vec3::NAN, Vec3::NAN);
56
57 #[allow(clippy::too_many_arguments)]
58 #[inline(always)]
59 const fn new(
60 m00: f32,
61 m01: f32,
62 m02: f32,
63 m10: f32,
64 m11: f32,
65 m12: f32,
66 m20: f32,
67 m21: f32,
68 m22: f32,
69 ) -> Self {
70 Self {
71 x_axis: Vec3::new(m00, m01, m02),
72 y_axis: Vec3::new(m10, m11, m12),
73 z_axis: Vec3::new(m20, m21, m22),
74 }
75 }
76
77 #[inline(always)]
79 pub const fn from_cols(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Self {
80 Self {
81 x_axis,
82 y_axis,
83 z_axis,
84 }
85 }
86
87 #[inline]
91 pub const fn from_cols_array(m: &[f32; 9]) -> Self {
92 Self::new(m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8])
93 }
94
95 #[inline]
98 pub const fn to_cols_array(&self) -> [f32; 9] {
99 [
100 self.x_axis.x,
101 self.x_axis.y,
102 self.x_axis.z,
103 self.y_axis.x,
104 self.y_axis.y,
105 self.y_axis.z,
106 self.z_axis.x,
107 self.z_axis.y,
108 self.z_axis.z,
109 ]
110 }
111
112 #[inline]
116 pub const fn from_cols_array_2d(m: &[[f32; 3]; 3]) -> Self {
117 Self::from_cols(
118 Vec3::from_array(m[0]),
119 Vec3::from_array(m[1]),
120 Vec3::from_array(m[2]),
121 )
122 }
123
124 #[inline]
127 pub const fn to_cols_array_2d(&self) -> [[f32; 3]; 3] {
128 [
129 self.x_axis.to_array(),
130 self.y_axis.to_array(),
131 self.z_axis.to_array(),
132 ]
133 }
134
135 #[doc(alias = "scale")]
137 #[inline]
138 pub const fn from_diagonal(diagonal: Vec3) -> Self {
139 Self::new(
140 diagonal.x, 0.0, 0.0, 0.0, diagonal.y, 0.0, 0.0, 0.0, diagonal.z,
141 )
142 }
143
144 pub fn from_mat4(m: Mat4) -> Self {
146 Self::from_cols(m.x_axis.xyz(), m.y_axis.xyz(), m.z_axis.xyz())
147 }
148
149 #[inline]
155 pub fn from_quat(rotation: Quat) -> Self {
156 glam_assert!(rotation.is_normalized());
157
158 let x2 = rotation.x + rotation.x;
159 let y2 = rotation.y + rotation.y;
160 let z2 = rotation.z + rotation.z;
161 let xx = rotation.x * x2;
162 let xy = rotation.x * y2;
163 let xz = rotation.x * z2;
164 let yy = rotation.y * y2;
165 let yz = rotation.y * z2;
166 let zz = rotation.z * z2;
167 let wx = rotation.w * x2;
168 let wy = rotation.w * y2;
169 let wz = rotation.w * z2;
170
171 Self::from_cols(
172 Vec3::new(1.0 - (yy + zz), xy + wz, xz - wy),
173 Vec3::new(xy - wz, 1.0 - (xx + zz), yz + wx),
174 Vec3::new(xz + wy, yz - wx, 1.0 - (xx + yy)),
175 )
176 }
177
178 #[inline]
185 pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
186 glam_assert!(axis.is_normalized());
187
188 let (sin, cos) = math::sin_cos(angle);
189 let (xsin, ysin, zsin) = axis.mul(sin).into();
190 let (x, y, z) = axis.into();
191 let (x2, y2, z2) = axis.mul(axis).into();
192 let omc = 1.0 - cos;
193 let xyomc = x * y * omc;
194 let xzomc = x * z * omc;
195 let yzomc = y * z * omc;
196 Self::from_cols(
197 Vec3::new(x2 * omc + cos, xyomc + zsin, xzomc - ysin),
198 Vec3::new(xyomc - zsin, y2 * omc + cos, yzomc + xsin),
199 Vec3::new(xzomc + ysin, yzomc - xsin, z2 * omc + cos),
200 )
201 }
202
203 #[inline]
204 pub fn from_euler(order: EulerRot, a: f32, b: f32, c: f32) -> Self {
207 let quat = Quat::from_euler(order, a, b, c);
208 Self::from_quat(quat)
209 }
210
211 #[inline]
213 pub fn from_rotation_x(angle: f32) -> Self {
214 let (sina, cosa) = math::sin_cos(angle);
215 Self::from_cols(
216 Vec3::X,
217 Vec3::new(0.0, cosa, sina),
218 Vec3::new(0.0, -sina, cosa),
219 )
220 }
221
222 #[inline]
224 pub fn from_rotation_y(angle: f32) -> Self {
225 let (sina, cosa) = math::sin_cos(angle);
226 Self::from_cols(
227 Vec3::new(cosa, 0.0, -sina),
228 Vec3::Y,
229 Vec3::new(sina, 0.0, cosa),
230 )
231 }
232
233 #[inline]
235 pub fn from_rotation_z(angle: f32) -> Self {
236 let (sina, cosa) = math::sin_cos(angle);
237 Self::from_cols(
238 Vec3::new(cosa, sina, 0.0),
239 Vec3::new(-sina, cosa, 0.0),
240 Vec3::Z,
241 )
242 }
243
244 #[inline]
249 pub fn from_translation(translation: Vec2) -> Self {
250 Self::from_cols(
251 Vec3::X,
252 Vec3::Y,
253 Vec3::new(translation.x, translation.y, 1.0),
254 )
255 }
256
257 #[inline]
263 pub fn from_angle(angle: f32) -> Self {
264 let (sin, cos) = math::sin_cos(angle);
265 Self::from_cols(Vec3::new(cos, sin, 0.0), Vec3::new(-sin, cos, 0.0), Vec3::Z)
266 }
267
268 #[inline]
274 pub fn from_scale_angle_translation(scale: Vec2, angle: f32, translation: Vec2) -> Self {
275 let (sin, cos) = math::sin_cos(angle);
276 Self::from_cols(
277 Vec3::new(cos * scale.x, sin * scale.x, 0.0),
278 Vec3::new(-sin * scale.y, cos * scale.y, 0.0),
279 Vec3::new(translation.x, translation.y, 1.0),
280 )
281 }
282
283 #[inline]
292 pub fn from_scale(scale: Vec2) -> Self {
293 glam_assert!(scale.cmpne(Vec2::ZERO).any());
295
296 Self::from_cols(
297 Vec3::new(scale.x, 0.0, 0.0),
298 Vec3::new(0.0, scale.y, 0.0),
299 Vec3::Z,
300 )
301 }
302
303 #[inline]
308 pub fn from_mat2(m: Mat2) -> Self {
309 Self::from_cols((m.x_axis, 0.0).into(), (m.y_axis, 0.0).into(), Vec3::Z)
310 }
311
312 #[inline]
318 pub const fn from_cols_slice(slice: &[f32]) -> Self {
319 Self::new(
320 slice[0], slice[1], slice[2], slice[3], slice[4], slice[5], slice[6], slice[7],
321 slice[8],
322 )
323 }
324
325 #[inline]
331 pub fn write_cols_to_slice(self, slice: &mut [f32]) {
332 slice[0] = self.x_axis.x;
333 slice[1] = self.x_axis.y;
334 slice[2] = self.x_axis.z;
335 slice[3] = self.y_axis.x;
336 slice[4] = self.y_axis.y;
337 slice[5] = self.y_axis.z;
338 slice[6] = self.z_axis.x;
339 slice[7] = self.z_axis.y;
340 slice[8] = self.z_axis.z;
341 }
342
343 #[inline]
349 pub fn col(&self, index: usize) -> Vec3 {
350 match index {
351 0 => self.x_axis,
352 1 => self.y_axis,
353 2 => self.z_axis,
354 _ => panic!("index out of bounds"),
355 }
356 }
357
358 #[inline]
364 pub fn col_mut(&mut self, index: usize) -> &mut Vec3 {
365 match index {
366 0 => &mut self.x_axis,
367 1 => &mut self.y_axis,
368 2 => &mut self.z_axis,
369 _ => panic!("index out of bounds"),
370 }
371 }
372
373 #[inline]
379 pub fn row(&self, index: usize) -> Vec3 {
380 match index {
381 0 => Vec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
382 1 => Vec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
383 2 => Vec3::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
384 _ => panic!("index out of bounds"),
385 }
386 }
387
388 #[inline]
391 pub fn is_finite(&self) -> bool {
392 self.x_axis.is_finite() && self.y_axis.is_finite() && self.z_axis.is_finite()
393 }
394
395 #[inline]
397 pub fn is_nan(&self) -> bool {
398 self.x_axis.is_nan() || self.y_axis.is_nan() || self.z_axis.is_nan()
399 }
400
401 #[must_use]
403 #[inline]
404 pub fn transpose(&self) -> Self {
405 Self {
406 x_axis: Vec3::new(self.x_axis.x, self.y_axis.x, self.z_axis.x),
407 y_axis: Vec3::new(self.x_axis.y, self.y_axis.y, self.z_axis.y),
408 z_axis: Vec3::new(self.x_axis.z, self.y_axis.z, self.z_axis.z),
409 }
410 }
411
412 #[inline]
414 pub fn determinant(&self) -> f32 {
415 self.z_axis.dot(self.x_axis.cross(self.y_axis))
416 }
417
418 #[must_use]
426 #[inline]
427 pub fn inverse(&self) -> Self {
428 let tmp0 = self.y_axis.cross(self.z_axis);
429 let tmp1 = self.z_axis.cross(self.x_axis);
430 let tmp2 = self.x_axis.cross(self.y_axis);
431 let det = self.z_axis.dot(tmp2);
432 glam_assert!(det != 0.0);
433 let inv_det = Vec3::splat(det.recip());
434 Self::from_cols(tmp0.mul(inv_det), tmp1.mul(inv_det), tmp2.mul(inv_det)).transpose()
435 }
436
437 #[inline]
447 pub fn transform_point2(&self, rhs: Vec2) -> Vec2 {
448 glam_assert!(self.row(2).abs_diff_eq(Vec3::Z, 1e-6));
449 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs + self.z_axis.xy()
450 }
451
452 #[inline]
462 pub fn transform_vector2(&self, rhs: Vec2) -> Vec2 {
463 glam_assert!(self.row(2).abs_diff_eq(Vec3::Z, 1e-6));
464 Mat2::from_cols(self.x_axis.xy(), self.y_axis.xy()) * rhs
465 }
466
467 #[inline]
469 pub fn mul_vec3(&self, rhs: Vec3) -> Vec3 {
470 let mut res = self.x_axis.mul(rhs.x);
471 res = res.add(self.y_axis.mul(rhs.y));
472 res = res.add(self.z_axis.mul(rhs.z));
473 res
474 }
475
476 #[inline]
478 pub fn mul_vec3a(&self, rhs: Vec3A) -> Vec3A {
479 self.mul_vec3(rhs.into()).into()
480 }
481
482 #[inline]
484 pub fn mul_mat3(&self, rhs: &Self) -> Self {
485 Self::from_cols(
486 self.mul(rhs.x_axis),
487 self.mul(rhs.y_axis),
488 self.mul(rhs.z_axis),
489 )
490 }
491
492 #[inline]
494 pub fn add_mat3(&self, rhs: &Self) -> Self {
495 Self::from_cols(
496 self.x_axis.add(rhs.x_axis),
497 self.y_axis.add(rhs.y_axis),
498 self.z_axis.add(rhs.z_axis),
499 )
500 }
501
502 #[inline]
504 pub fn sub_mat3(&self, rhs: &Self) -> Self {
505 Self::from_cols(
506 self.x_axis.sub(rhs.x_axis),
507 self.y_axis.sub(rhs.y_axis),
508 self.z_axis.sub(rhs.z_axis),
509 )
510 }
511
512 #[inline]
514 pub fn mul_scalar(&self, rhs: f32) -> Self {
515 Self::from_cols(
516 self.x_axis.mul(rhs),
517 self.y_axis.mul(rhs),
518 self.z_axis.mul(rhs),
519 )
520 }
521
522 #[inline]
532 pub fn abs_diff_eq(&self, rhs: Self, max_abs_diff: f32) -> bool {
533 self.x_axis.abs_diff_eq(rhs.x_axis, max_abs_diff)
534 && self.y_axis.abs_diff_eq(rhs.y_axis, max_abs_diff)
535 && self.z_axis.abs_diff_eq(rhs.z_axis, max_abs_diff)
536 }
537
538 #[inline]
539 pub fn as_dmat3(&self) -> DMat3 {
540 DMat3::from_cols(
541 self.x_axis.as_dvec3(),
542 self.y_axis.as_dvec3(),
543 self.z_axis.as_dvec3(),
544 )
545 }
546}
547
548impl Default for Mat3 {
549 #[inline]
550 fn default() -> Self {
551 Self::IDENTITY
552 }
553}
554
555impl Add<Mat3> for Mat3 {
556 type Output = Self;
557 #[inline]
558 fn add(self, rhs: Self) -> Self::Output {
559 self.add_mat3(&rhs)
560 }
561}
562
563impl AddAssign<Mat3> for Mat3 {
564 #[inline]
565 fn add_assign(&mut self, rhs: Self) {
566 *self = self.add_mat3(&rhs);
567 }
568}
569
570impl Sub<Mat3> for Mat3 {
571 type Output = Self;
572 #[inline]
573 fn sub(self, rhs: Self) -> Self::Output {
574 self.sub_mat3(&rhs)
575 }
576}
577
578impl SubAssign<Mat3> for Mat3 {
579 #[inline]
580 fn sub_assign(&mut self, rhs: Self) {
581 *self = self.sub_mat3(&rhs);
582 }
583}
584
585impl Neg for Mat3 {
586 type Output = Self;
587 #[inline]
588 fn neg(self) -> Self::Output {
589 Self::from_cols(self.x_axis.neg(), self.y_axis.neg(), self.z_axis.neg())
590 }
591}
592
593impl Mul<Mat3> for Mat3 {
594 type Output = Self;
595 #[inline]
596 fn mul(self, rhs: Self) -> Self::Output {
597 self.mul_mat3(&rhs)
598 }
599}
600
601impl MulAssign<Mat3> for Mat3 {
602 #[inline]
603 fn mul_assign(&mut self, rhs: Self) {
604 *self = self.mul_mat3(&rhs);
605 }
606}
607
608impl Mul<Vec3> for Mat3 {
609 type Output = Vec3;
610 #[inline]
611 fn mul(self, rhs: Vec3) -> Self::Output {
612 self.mul_vec3(rhs)
613 }
614}
615
616impl Mul<Mat3> for f32 {
617 type Output = Mat3;
618 #[inline]
619 fn mul(self, rhs: Mat3) -> Self::Output {
620 rhs.mul_scalar(self)
621 }
622}
623
624impl Mul<f32> for Mat3 {
625 type Output = Self;
626 #[inline]
627 fn mul(self, rhs: f32) -> Self::Output {
628 self.mul_scalar(rhs)
629 }
630}
631
632impl MulAssign<f32> for Mat3 {
633 #[inline]
634 fn mul_assign(&mut self, rhs: f32) {
635 *self = self.mul_scalar(rhs);
636 }
637}
638
639impl Mul<Vec3A> for Mat3 {
640 type Output = Vec3A;
641 #[inline]
642 fn mul(self, rhs: Vec3A) -> Vec3A {
643 self.mul_vec3a(rhs)
644 }
645}
646
647impl From<Mat3A> for Mat3 {
648 #[inline]
649 fn from(m: Mat3A) -> Self {
650 Self {
651 x_axis: m.x_axis.into(),
652 y_axis: m.y_axis.into(),
653 z_axis: m.z_axis.into(),
654 }
655 }
656}
657
658impl Sum<Self> for Mat3 {
659 fn sum<I>(iter: I) -> Self
660 where
661 I: Iterator<Item = Self>,
662 {
663 iter.fold(Self::ZERO, Self::add)
664 }
665}
666
667impl<'a> Sum<&'a Self> for Mat3 {
668 fn sum<I>(iter: I) -> Self
669 where
670 I: Iterator<Item = &'a Self>,
671 {
672 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
673 }
674}
675
676impl Product for Mat3 {
677 fn product<I>(iter: I) -> Self
678 where
679 I: Iterator<Item = Self>,
680 {
681 iter.fold(Self::IDENTITY, Self::mul)
682 }
683}
684
685impl<'a> Product<&'a Self> for Mat3 {
686 fn product<I>(iter: I) -> Self
687 where
688 I: Iterator<Item = &'a Self>,
689 {
690 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
691 }
692}
693
694impl PartialEq for Mat3 {
695 #[inline]
696 fn eq(&self, rhs: &Self) -> bool {
697 self.x_axis.eq(&rhs.x_axis) && self.y_axis.eq(&rhs.y_axis) && self.z_axis.eq(&rhs.z_axis)
698 }
699}
700
701#[cfg(not(target_arch = "spirv"))]
702impl AsRef<[f32; 9]> for Mat3 {
703 #[inline]
704 fn as_ref(&self) -> &[f32; 9] {
705 unsafe { &*(self as *const Self as *const [f32; 9]) }
706 }
707}
708
709#[cfg(not(target_arch = "spirv"))]
710impl AsMut<[f32; 9]> for Mat3 {
711 #[inline]
712 fn as_mut(&mut self) -> &mut [f32; 9] {
713 unsafe { &mut *(self as *mut Self as *mut [f32; 9]) }
714 }
715}
716
717#[cfg(not(target_arch = "spirv"))]
718impl fmt::Debug for Mat3 {
719 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
720 fmt.debug_struct(stringify!(Mat3))
721 .field("x_axis", &self.x_axis)
722 .field("y_axis", &self.y_axis)
723 .field("z_axis", &self.z_axis)
724 .finish()
725 }
726}
727
728#[cfg(not(target_arch = "spirv"))]
729impl fmt::Display for Mat3 {
730 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
731 write!(f, "[{}, {}, {}]", self.x_axis, self.y_axis, self.z_axis)
732 }
733}