1use crate::{
4 euler::{EulerRot, FromEuler, ToEuler},
5 f32::math,
6 neon::*,
7 DQuat, Mat3, Mat3A, Mat4, Vec2, Vec3, Vec3A, Vec4,
8};
9
10use core::arch::aarch64::*;
11
12use core::fmt;
13use core::iter::{Product, Sum};
14use core::ops::{
15 Add, AddAssign, Deref, DerefMut, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign,
16};
17
18#[repr(C)]
19union UnionCast {
20 a: [f32; 4],
21 v: Quat,
22}
23
24#[inline]
29#[must_use]
30pub const fn quat(x: f32, y: f32, z: f32, w: f32) -> Quat {
31 Quat::from_xyzw(x, y, z, w)
32}
33
34#[derive(Clone, Copy)]
44#[cfg_attr(
45 all(feature = "bytemuck", not(target_arch = "spirv")),
46 derive(bytemuck::Pod, bytemuck::Zeroable)
47)]
48#[repr(transparent)]
49pub struct Quat(pub(crate) float32x4_t);
50
51impl Quat {
52 const ZERO: Self = Self::from_array([0.0; 4]);
54
55 pub const IDENTITY: Self = Self::from_xyzw(0.0, 0.0, 0.0, 1.0);
57
58 pub const NAN: Self = Self::from_array([f32::NAN; 4]);
60
61 #[inline(always)]
73 #[must_use]
74 pub const fn from_xyzw(x: f32, y: f32, z: f32, w: f32) -> Self {
75 unsafe { UnionCast { a: [x, y, z, w] }.v }
76 }
77
78 #[inline]
85 #[must_use]
86 pub const fn from_array(a: [f32; 4]) -> Self {
87 Self::from_xyzw(a[0], a[1], a[2], a[3])
88 }
89
90 #[inline]
97 #[must_use]
98 pub const fn from_vec4(v: Vec4) -> Self {
99 Self(v.0)
100 }
101
102 #[inline]
113 #[must_use]
114 pub fn from_slice(slice: &[f32]) -> Self {
115 assert!(slice.len() >= 4);
116 Self(unsafe { vld1q_f32(slice.as_ptr()) })
117 }
118
119 #[inline]
125 pub fn write_to_slice(self, slice: &mut [f32]) {
126 assert!(slice.len() >= 4);
127 unsafe { vst1q_f32(slice.as_mut_ptr(), self.0) }
128 }
129
130 #[inline]
138 #[must_use]
139 pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
140 glam_assert!(axis.is_normalized());
141 let (s, c) = math::sin_cos(angle * 0.5);
142 let v = axis * s;
143 Self::from_xyzw(v.x, v.y, v.z, c)
144 }
145
146 #[inline]
150 #[must_use]
151 pub fn from_scaled_axis(v: Vec3) -> Self {
152 let length = v.length();
153 if length == 0.0 {
154 Self::IDENTITY
155 } else {
156 Self::from_axis_angle(v / length, length)
157 }
158 }
159
160 #[inline]
162 #[must_use]
163 pub fn from_rotation_x(angle: f32) -> Self {
164 let (s, c) = math::sin_cos(angle * 0.5);
165 Self::from_xyzw(s, 0.0, 0.0, c)
166 }
167
168 #[inline]
170 #[must_use]
171 pub fn from_rotation_y(angle: f32) -> Self {
172 let (s, c) = math::sin_cos(angle * 0.5);
173 Self::from_xyzw(0.0, s, 0.0, c)
174 }
175
176 #[inline]
178 #[must_use]
179 pub fn from_rotation_z(angle: f32) -> Self {
180 let (s, c) = math::sin_cos(angle * 0.5);
181 Self::from_xyzw(0.0, 0.0, s, c)
182 }
183
184 #[inline]
186 #[must_use]
187 pub fn from_euler(euler: EulerRot, a: f32, b: f32, c: f32) -> Self {
188 Self::from_euler_angles(euler, a, b, c)
189 }
190
191 #[inline]
200 #[must_use]
201 pub(crate) fn from_rotation_axes(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Self {
202 glam_assert!(x_axis.is_normalized() && y_axis.is_normalized() && z_axis.is_normalized());
203 let (m00, m01, m02) = x_axis.into();
205 let (m10, m11, m12) = y_axis.into();
206 let (m20, m21, m22) = z_axis.into();
207 if m22 <= 0.0 {
208 let dif10 = m11 - m00;
210 let omm22 = 1.0 - m22;
211 if dif10 <= 0.0 {
212 let four_xsq = omm22 - dif10;
214 let inv4x = 0.5 / math::sqrt(four_xsq);
215 Self::from_xyzw(
216 four_xsq * inv4x,
217 (m01 + m10) * inv4x,
218 (m02 + m20) * inv4x,
219 (m12 - m21) * inv4x,
220 )
221 } else {
222 let four_ysq = omm22 + dif10;
224 let inv4y = 0.5 / math::sqrt(four_ysq);
225 Self::from_xyzw(
226 (m01 + m10) * inv4y,
227 four_ysq * inv4y,
228 (m12 + m21) * inv4y,
229 (m20 - m02) * inv4y,
230 )
231 }
232 } else {
233 let sum10 = m11 + m00;
235 let opm22 = 1.0 + m22;
236 if sum10 <= 0.0 {
237 let four_zsq = opm22 - sum10;
239 let inv4z = 0.5 / math::sqrt(four_zsq);
240 Self::from_xyzw(
241 (m02 + m20) * inv4z,
242 (m12 + m21) * inv4z,
243 four_zsq * inv4z,
244 (m01 - m10) * inv4z,
245 )
246 } else {
247 let four_wsq = opm22 + sum10;
249 let inv4w = 0.5 / math::sqrt(four_wsq);
250 Self::from_xyzw(
251 (m12 - m21) * inv4w,
252 (m20 - m02) * inv4w,
253 (m01 - m10) * inv4w,
254 four_wsq * inv4w,
255 )
256 }
257 }
258 }
259
260 #[inline]
269 #[must_use]
270 pub fn from_mat3(mat: &Mat3) -> Self {
271 Self::from_rotation_axes(mat.x_axis, mat.y_axis, mat.z_axis)
272 }
273
274 #[inline]
283 #[must_use]
284 pub fn from_mat3a(mat: &Mat3A) -> Self {
285 Self::from_rotation_axes(mat.x_axis.into(), mat.y_axis.into(), mat.z_axis.into())
286 }
287
288 #[inline]
298 #[must_use]
299 pub fn from_mat4(mat: &Mat4) -> Self {
300 Self::from_rotation_axes(
301 mat.x_axis.truncate(),
302 mat.y_axis.truncate(),
303 mat.z_axis.truncate(),
304 )
305 }
306
307 #[must_use]
321 pub fn from_rotation_arc(from: Vec3, to: Vec3) -> Self {
322 glam_assert!(from.is_normalized());
323 glam_assert!(to.is_normalized());
324
325 const ONE_MINUS_EPS: f32 = 1.0 - 2.0 * f32::EPSILON;
326 let dot = from.dot(to);
327 if dot > ONE_MINUS_EPS {
328 Self::IDENTITY
330 } else if dot < -ONE_MINUS_EPS {
331 use core::f32::consts::PI; Self::from_axis_angle(from.any_orthonormal_vector(), PI)
334 } else {
335 let c = from.cross(to);
336 Self::from_xyzw(c.x, c.y, c.z, 1.0 + dot).normalize()
337 }
338 }
339
340 #[inline]
354 #[must_use]
355 pub fn from_rotation_arc_colinear(from: Vec3, to: Vec3) -> Self {
356 if from.dot(to) < 0.0 {
357 Self::from_rotation_arc(from, -to)
358 } else {
359 Self::from_rotation_arc(from, to)
360 }
361 }
362
363 #[must_use]
377 pub fn from_rotation_arc_2d(from: Vec2, to: Vec2) -> Self {
378 glam_assert!(from.is_normalized());
379 glam_assert!(to.is_normalized());
380
381 const ONE_MINUS_EPSILON: f32 = 1.0 - 2.0 * f32::EPSILON;
382 let dot = from.dot(to);
383 if dot > ONE_MINUS_EPSILON {
384 Self::IDENTITY
386 } else if dot < -ONE_MINUS_EPSILON {
387 const COS_FRAC_PI_2: f32 = 0.0;
389 const SIN_FRAC_PI_2: f32 = 1.0;
390 Self::from_xyzw(0.0, 0.0, SIN_FRAC_PI_2, COS_FRAC_PI_2)
392 } else {
393 let z = from.x * to.y - to.x * from.y;
395 let w = 1.0 + dot;
396 let len_rcp = 1.0 / math::sqrt(z * z + w * w);
398 Self::from_xyzw(0.0, 0.0, z * len_rcp, w * len_rcp)
399 }
400 }
401
402 #[inline]
410 #[must_use]
411 pub fn look_to_lh(dir: Vec3, up: Vec3) -> Self {
412 Self::look_to_rh(-dir, up)
413 }
414
415 #[inline]
423 #[must_use]
424 pub fn look_to_rh(dir: Vec3, up: Vec3) -> Self {
425 glam_assert!(dir.is_normalized());
426 glam_assert!(up.is_normalized());
427 let f = dir;
428 let s = f.cross(up).normalize();
429 let u = s.cross(f);
430
431 Self::from_rotation_axes(
432 Vec3::new(s.x, u.x, -f.x),
433 Vec3::new(s.y, u.y, -f.y),
434 Vec3::new(s.z, u.z, -f.z),
435 )
436 }
437
438 #[inline]
447 #[must_use]
448 pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
449 Self::look_to_lh(center.sub(eye).normalize(), up)
450 }
451
452 #[inline]
461 #[must_use]
462 pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
463 Self::look_to_rh(center.sub(eye).normalize(), up)
464 }
465
466 #[inline]
468 #[must_use]
469 pub fn to_axis_angle(self) -> (Vec3, f32) {
470 const EPSILON: f32 = 1.0e-8;
471 let v = Vec3::new(self.x, self.y, self.z);
472 let length = v.length();
473 if length >= EPSILON {
474 let angle = 2.0 * math::atan2(length, self.w);
475 let axis = v / length;
476 (axis, angle)
477 } else {
478 (Vec3::X, 0.0)
479 }
480 }
481
482 #[inline]
484 #[must_use]
485 pub fn to_scaled_axis(self) -> Vec3 {
486 let (axis, angle) = self.to_axis_angle();
487 axis * angle
488 }
489
490 #[inline]
492 #[must_use]
493 pub fn to_euler(self, order: EulerRot) -> (f32, f32, f32) {
494 self.to_euler_angles(order)
495 }
496
497 #[inline]
499 #[must_use]
500 pub fn to_array(&self) -> [f32; 4] {
501 [self.x, self.y, self.z, self.w]
502 }
503
504 #[inline]
506 #[must_use]
507 pub fn xyz(self) -> Vec3 {
508 Vec3::new(self.x, self.y, self.z)
509 }
510
511 #[inline]
514 #[must_use]
515 pub fn conjugate(self) -> Self {
516 const SIGN: float32x4_t = f32x4_from_array([-1.0, -1.0, -1.0, 1.0]);
517 Self(unsafe { vmulq_f32(self.0, SIGN) })
518 }
519
520 #[inline]
530 #[must_use]
531 pub fn inverse(self) -> Self {
532 glam_assert!(self.is_normalized());
533 self.conjugate()
534 }
535
536 #[inline]
539 #[must_use]
540 pub fn dot(self, rhs: Self) -> f32 {
541 Vec4::from(self).dot(Vec4::from(rhs))
542 }
543
544 #[doc(alias = "magnitude")]
546 #[inline]
547 #[must_use]
548 pub fn length(self) -> f32 {
549 Vec4::from(self).length()
550 }
551
552 #[doc(alias = "magnitude2")]
557 #[inline]
558 #[must_use]
559 pub fn length_squared(self) -> f32 {
560 Vec4::from(self).length_squared()
561 }
562
563 #[inline]
567 #[must_use]
568 pub fn length_recip(self) -> f32 {
569 Vec4::from(self).length_recip()
570 }
571
572 #[inline]
580 #[must_use]
581 pub fn normalize(self) -> Self {
582 Self::from_vec4(Vec4::from(self).normalize())
583 }
584
585 #[inline]
588 #[must_use]
589 pub fn is_finite(self) -> bool {
590 Vec4::from(self).is_finite()
591 }
592
593 #[inline]
595 #[must_use]
596 pub fn is_nan(self) -> bool {
597 Vec4::from(self).is_nan()
598 }
599
600 #[inline]
604 #[must_use]
605 pub fn is_normalized(self) -> bool {
606 Vec4::from(self).is_normalized()
607 }
608
609 #[inline]
610 #[must_use]
611 pub fn is_near_identity(self) -> bool {
612 let threshold_angle = 0.002_847_144_6;
614 let positive_w_angle = math::acos_approx(math::abs(self.w)) * 2.0;
628 positive_w_angle < threshold_angle
629 }
630
631 #[inline]
640 #[must_use]
641 pub fn angle_between(self, rhs: Self) -> f32 {
642 glam_assert!(self.is_normalized() && rhs.is_normalized());
643 math::acos_approx(math::abs(self.dot(rhs))) * 2.0
644 }
645
646 #[inline]
658 #[must_use]
659 pub fn rotate_towards(&self, rhs: Self, max_angle: f32) -> Self {
660 glam_assert!(self.is_normalized() && rhs.is_normalized());
661 let angle = self.angle_between(rhs);
662 if angle <= 1e-4 {
663 return rhs;
664 }
665 let s = (max_angle / angle).clamp(-1.0, 1.0);
666 self.slerp(rhs, s)
667 }
668
669 #[inline]
679 #[must_use]
680 pub fn abs_diff_eq(self, rhs: Self, max_abs_diff: f32) -> bool {
681 Vec4::from(self).abs_diff_eq(Vec4::from(rhs), max_abs_diff)
682 }
683
684 #[inline(always)]
685 #[must_use]
686 fn lerp_impl(self, end: Self, s: f32) -> Self {
687 (self * (1.0 - s) + end * s).normalize()
688 }
689
690 #[doc(alias = "mix")]
700 #[inline]
701 #[must_use]
702 pub fn lerp(self, end: Self, s: f32) -> Self {
703 glam_assert!(self.is_normalized());
704 glam_assert!(end.is_normalized());
705
706 const NEG_ZERO: float32x4_t = f32x4_from_array([-0.0; 4]);
707 unsafe {
708 let dot = dot4_into_f32x4(self.0, end.0);
709 let bias = vandq_u32(vreinterpretq_u32_f32(dot), vreinterpretq_u32_f32(NEG_ZERO));
712 self.lerp_impl(
713 Self(vreinterpretq_f32_u32(veorq_u32(
714 vreinterpretq_u32_f32(end.0),
715 bias,
716 ))),
717 s,
718 )
719 }
720 }
721
722 #[inline]
732 #[must_use]
733 pub fn slerp(self, mut end: Self, s: f32) -> Self {
734 glam_assert!(self.is_normalized());
736 glam_assert!(end.is_normalized());
737
738 let mut dot = self.dot(end);
745 if dot < 0.0 {
746 end = -end;
747 dot = -dot;
748 }
749
750 const DOT_THRESHOLD: f32 = 1.0 - f32::EPSILON;
751 if dot > DOT_THRESHOLD {
752 self.lerp_impl(end, s)
754 } else {
755 let theta = math::acos_approx(dot);
756
757 let scale1 = math::sin(theta * (1.0 - s));
758 let scale2 = math::sin(theta * s);
759 let theta_sin = math::sin(theta);
760 ((self * scale1) + (end * scale2)) * (1.0 / theta_sin)
761 }
762 }
763
764 #[inline]
770 #[must_use]
771 pub fn mul_vec3(self, rhs: Vec3) -> Vec3 {
772 glam_assert!(self.is_normalized());
773
774 self.mul_vec3a(rhs.into()).into()
775 }
776
777 #[inline]
786 #[must_use]
787 pub fn mul_quat(self, rhs: Self) -> Self {
788 unsafe {
789 let lhs = self.0;
790 let rhs = rhs.0;
791
792 const CONTROL_WZYX: float32x4_t = f32x4_from_array([1.0, -1.0, 1.0, -1.0]);
793 const CONTROL_ZWXY: float32x4_t = f32x4_from_array([1.0, 1.0, -1.0, -1.0]);
794 const CONTROL_YXWZ: float32x4_t = f32x4_from_array([-1.0, 1.0, 1.0, -1.0]);
795
796 let r_xxxx = vdupq_laneq_f32(lhs, 0);
797 let r_yyyy = vdupq_laneq_f32(lhs, 1);
798 let r_zzzz = vdupq_laneq_f32(lhs, 2);
799 let r_wwww = vdupq_laneq_f32(lhs, 3);
800
801 let lxrw_lyrw_lzrw_lwrw = vmulq_f32(r_wwww, rhs);
802 let l_wzyx = vrev64q_f32(rhs);
804 let l_wzyx = vextq_f32(l_wzyx, l_wzyx, 2);
805
806 let lwrx_lzrx_lyrx_lxrx = vmulq_f32(r_xxxx, l_wzyx);
807 let l_zwxy = vrev64q_f32(l_wzyx);
809
810 let lwrx_nlzrx_lyrx_nlxrx = vmulq_f32(lwrx_lzrx_lyrx_lxrx, CONTROL_WZYX);
811
812 let lzry_lwry_lxry_lyry = vmulq_f32(r_yyyy, l_zwxy);
813 let l_yxwz = vrev64q_f32(l_zwxy);
815 let l_yxwz = vextq_f32(l_yxwz, l_yxwz, 2);
816
817 let lzry_lwry_nlxry_nlyry = vmulq_f32(lzry_lwry_lxry_lyry, CONTROL_ZWXY);
818
819 let lyrz_lxrz_lwrz_lzrz = vmulq_f32(r_zzzz, l_yxwz);
820 let result0 = vaddq_f32(lxrw_lyrw_lzrw_lwrw, lwrx_nlzrx_lyrx_nlxrx);
821
822 let nlyrz_lxrz_lwrz_wlzrz = vmulq_f32(lyrz_lxrz_lwrz_lzrz, CONTROL_YXWZ);
823 let result1 = vaddq_f32(lzry_lwry_nlxry_nlyry, nlyrz_lxrz_lwrz_wlzrz);
824 Self(vaddq_f32(result0, result1))
825 }
826 }
827
828 #[inline]
838 #[must_use]
839 pub fn from_affine3(a: &crate::Affine3A) -> Self {
840 #[allow(clippy::useless_conversion)]
841 Self::from_rotation_axes(
842 a.matrix3.x_axis.into(),
843 a.matrix3.y_axis.into(),
844 a.matrix3.z_axis.into(),
845 )
846 }
847
848 #[inline]
850 #[must_use]
851 pub fn mul_vec3a(self, rhs: Vec3A) -> Vec3A {
852 unsafe {
853 let w = self.w;
854 let b = Vec3A::from(self.0);
855 let b2 = b.length_squared();
856 Vec3A(vaddq_f32(
857 vaddq_f32(
858 vmulq_n_f32(rhs.0, (w * w) - b2),
859 vmulq_n_f32(b.0, rhs.dot(b) * 2.0),
860 ),
861 vmulq_n_f32(b.cross(rhs).0, w * 2.0),
862 ))
863 }
864 }
865
866 #[inline]
867 #[must_use]
868 pub fn as_dquat(self) -> DQuat {
869 DQuat::from_xyzw(self.x as f64, self.y as f64, self.z as f64, self.w as f64)
870 }
871}
872
873impl fmt::Debug for Quat {
874 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
875 fmt.debug_tuple(stringify!(Quat))
876 .field(&self.x)
877 .field(&self.y)
878 .field(&self.z)
879 .field(&self.w)
880 .finish()
881 }
882}
883
884impl fmt::Display for Quat {
885 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
886 if let Some(p) = f.precision() {
887 write!(
888 f,
889 "[{:.*}, {:.*}, {:.*}, {:.*}]",
890 p, self.x, p, self.y, p, self.z, p, self.w
891 )
892 } else {
893 write!(f, "[{}, {}, {}, {}]", self.x, self.y, self.z, self.w)
894 }
895 }
896}
897
898impl Add for Quat {
899 type Output = Self;
900 #[inline]
907 fn add(self, rhs: Self) -> Self {
908 Self::from_vec4(Vec4::from(self) + Vec4::from(rhs))
909 }
910}
911
912impl Add<&Self> for Quat {
913 type Output = Self;
914 #[inline]
915 fn add(self, rhs: &Self) -> Self {
916 self.add(*rhs)
917 }
918}
919
920impl Add<&Quat> for &Quat {
921 type Output = Quat;
922 #[inline]
923 fn add(self, rhs: &Quat) -> Quat {
924 (*self).add(*rhs)
925 }
926}
927
928impl Add<Quat> for &Quat {
929 type Output = Quat;
930 #[inline]
931 fn add(self, rhs: Quat) -> Quat {
932 (*self).add(rhs)
933 }
934}
935
936impl AddAssign for Quat {
937 #[inline]
938 fn add_assign(&mut self, rhs: Self) {
939 *self = self.add(rhs);
940 }
941}
942
943impl AddAssign<&Self> for Quat {
944 #[inline]
945 fn add_assign(&mut self, rhs: &Self) {
946 self.add_assign(*rhs);
947 }
948}
949
950impl Sub for Quat {
951 type Output = Self;
952 #[inline]
956 fn sub(self, rhs: Self) -> Self {
957 Self::from_vec4(Vec4::from(self) - Vec4::from(rhs))
958 }
959}
960
961impl Sub<&Self> for Quat {
962 type Output = Self;
963 #[inline]
964 fn sub(self, rhs: &Self) -> Self {
965 self.sub(*rhs)
966 }
967}
968
969impl Sub<&Quat> for &Quat {
970 type Output = Quat;
971 #[inline]
972 fn sub(self, rhs: &Quat) -> Quat {
973 (*self).sub(*rhs)
974 }
975}
976
977impl Sub<Quat> for &Quat {
978 type Output = Quat;
979 #[inline]
980 fn sub(self, rhs: Quat) -> Quat {
981 (*self).sub(rhs)
982 }
983}
984
985impl SubAssign for Quat {
986 #[inline]
987 fn sub_assign(&mut self, rhs: Self) {
988 *self = self.sub(rhs);
989 }
990}
991
992impl SubAssign<&Self> for Quat {
993 #[inline]
994 fn sub_assign(&mut self, rhs: &Self) {
995 self.sub_assign(*rhs);
996 }
997}
998
999impl Mul<f32> for Quat {
1000 type Output = Self;
1001 #[inline]
1005 fn mul(self, rhs: f32) -> Self {
1006 Self::from_vec4(Vec4::from(self) * rhs)
1007 }
1008}
1009
1010impl Mul<&f32> for Quat {
1011 type Output = Self;
1012 #[inline]
1013 fn mul(self, rhs: &f32) -> Self {
1014 self.mul(*rhs)
1015 }
1016}
1017
1018impl Mul<&f32> for &Quat {
1019 type Output = Quat;
1020 #[inline]
1021 fn mul(self, rhs: &f32) -> Quat {
1022 (*self).mul(*rhs)
1023 }
1024}
1025
1026impl Mul<f32> for &Quat {
1027 type Output = Quat;
1028 #[inline]
1029 fn mul(self, rhs: f32) -> Quat {
1030 (*self).mul(rhs)
1031 }
1032}
1033
1034impl MulAssign<f32> for Quat {
1035 #[inline]
1036 fn mul_assign(&mut self, rhs: f32) {
1037 *self = self.mul(rhs);
1038 }
1039}
1040
1041impl MulAssign<&f32> for Quat {
1042 #[inline]
1043 fn mul_assign(&mut self, rhs: &f32) {
1044 self.mul_assign(*rhs);
1045 }
1046}
1047
1048impl Div<f32> for Quat {
1049 type Output = Self;
1050 #[inline]
1053 fn div(self, rhs: f32) -> Self {
1054 Self::from_vec4(Vec4::from(self) / rhs)
1055 }
1056}
1057
1058impl Div<&f32> for Quat {
1059 type Output = Self;
1060 #[inline]
1061 fn div(self, rhs: &f32) -> Self {
1062 self.div(*rhs)
1063 }
1064}
1065
1066impl Div<&f32> for &Quat {
1067 type Output = Quat;
1068 #[inline]
1069 fn div(self, rhs: &f32) -> Quat {
1070 (*self).div(*rhs)
1071 }
1072}
1073
1074impl Div<f32> for &Quat {
1075 type Output = Quat;
1076 #[inline]
1077 fn div(self, rhs: f32) -> Quat {
1078 (*self).div(rhs)
1079 }
1080}
1081
1082impl DivAssign<f32> for Quat {
1083 #[inline]
1084 fn div_assign(&mut self, rhs: f32) {
1085 *self = self.div(rhs);
1086 }
1087}
1088
1089impl DivAssign<&f32> for Quat {
1090 #[inline]
1091 fn div_assign(&mut self, rhs: &f32) {
1092 self.div_assign(*rhs);
1093 }
1094}
1095
1096impl Mul for Quat {
1097 type Output = Self;
1098 #[inline]
1108 fn mul(self, rhs: Self) -> Self {
1109 self.mul_quat(rhs)
1110 }
1111}
1112
1113impl Mul<&Self> for Quat {
1114 type Output = Self;
1115 #[inline]
1116 fn mul(self, rhs: &Self) -> Self {
1117 self.mul(*rhs)
1118 }
1119}
1120
1121impl Mul<&Quat> for &Quat {
1122 type Output = Quat;
1123 #[inline]
1124 fn mul(self, rhs: &Quat) -> Quat {
1125 (*self).mul(*rhs)
1126 }
1127}
1128
1129impl Mul<Quat> for &Quat {
1130 type Output = Quat;
1131 #[inline]
1132 fn mul(self, rhs: Quat) -> Quat {
1133 (*self).mul(rhs)
1134 }
1135}
1136
1137impl MulAssign for Quat {
1138 #[inline]
1139 fn mul_assign(&mut self, rhs: Self) {
1140 *self = self.mul(rhs);
1141 }
1142}
1143
1144impl MulAssign<&Self> for Quat {
1145 #[inline]
1146 fn mul_assign(&mut self, rhs: &Self) {
1147 self.mul_assign(*rhs);
1148 }
1149}
1150
1151impl Mul<Vec3> for Quat {
1152 type Output = Vec3;
1153 #[inline]
1159 fn mul(self, rhs: Vec3) -> Self::Output {
1160 self.mul_vec3(rhs)
1161 }
1162}
1163
1164impl Mul<&Vec3> for Quat {
1165 type Output = Vec3;
1166 #[inline]
1167 fn mul(self, rhs: &Vec3) -> Vec3 {
1168 self.mul(*rhs)
1169 }
1170}
1171
1172impl Mul<&Vec3> for &Quat {
1173 type Output = Vec3;
1174 #[inline]
1175 fn mul(self, rhs: &Vec3) -> Vec3 {
1176 (*self).mul(*rhs)
1177 }
1178}
1179
1180impl Mul<Vec3> for &Quat {
1181 type Output = Vec3;
1182 #[inline]
1183 fn mul(self, rhs: Vec3) -> Vec3 {
1184 (*self).mul(rhs)
1185 }
1186}
1187
1188impl Mul<Vec3A> for Quat {
1189 type Output = Vec3A;
1190 #[inline]
1191 fn mul(self, rhs: Vec3A) -> Self::Output {
1192 self.mul_vec3a(rhs)
1193 }
1194}
1195
1196impl Mul<&Vec3A> for Quat {
1197 type Output = Vec3A;
1198 #[inline]
1199 fn mul(self, rhs: &Vec3A) -> Vec3A {
1200 self.mul(*rhs)
1201 }
1202}
1203
1204impl Mul<&Vec3A> for &Quat {
1205 type Output = Vec3A;
1206 #[inline]
1207 fn mul(self, rhs: &Vec3A) -> Vec3A {
1208 (*self).mul(*rhs)
1209 }
1210}
1211
1212impl Mul<Vec3A> for &Quat {
1213 type Output = Vec3A;
1214 #[inline]
1215 fn mul(self, rhs: Vec3A) -> Vec3A {
1216 (*self).mul(rhs)
1217 }
1218}
1219
1220impl Neg for Quat {
1221 type Output = Self;
1222 #[inline]
1223 fn neg(self) -> Self {
1224 self * -1.0
1225 }
1226}
1227
1228impl Neg for &Quat {
1229 type Output = Quat;
1230 #[inline]
1231 fn neg(self) -> Quat {
1232 (*self).neg()
1233 }
1234}
1235
1236impl Default for Quat {
1237 #[inline]
1238 fn default() -> Self {
1239 Self::IDENTITY
1240 }
1241}
1242
1243impl PartialEq for Quat {
1244 #[inline]
1245 fn eq(&self, rhs: &Self) -> bool {
1246 Vec4::from(*self).eq(&Vec4::from(*rhs))
1247 }
1248}
1249
1250#[cfg(not(target_arch = "spirv"))]
1251impl AsRef<[f32; 4]> for Quat {
1252 #[inline]
1253 fn as_ref(&self) -> &[f32; 4] {
1254 unsafe { &*(self as *const Self as *const [f32; 4]) }
1255 }
1256}
1257
1258impl Sum<Self> for Quat {
1259 fn sum<I>(iter: I) -> Self
1260 where
1261 I: Iterator<Item = Self>,
1262 {
1263 iter.fold(Self::ZERO, Self::add)
1264 }
1265}
1266
1267impl<'a> Sum<&'a Self> for Quat {
1268 fn sum<I>(iter: I) -> Self
1269 where
1270 I: Iterator<Item = &'a Self>,
1271 {
1272 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1273 }
1274}
1275
1276impl Product for Quat {
1277 fn product<I>(iter: I) -> Self
1278 where
1279 I: Iterator<Item = Self>,
1280 {
1281 iter.fold(Self::IDENTITY, Self::mul)
1282 }
1283}
1284
1285impl<'a> Product<&'a Self> for Quat {
1286 fn product<I>(iter: I) -> Self
1287 where
1288 I: Iterator<Item = &'a Self>,
1289 {
1290 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1291 }
1292}
1293
1294impl From<Quat> for Vec4 {
1295 #[inline]
1296 fn from(q: Quat) -> Self {
1297 Self(q.0)
1298 }
1299}
1300
1301impl From<Quat> for (f32, f32, f32, f32) {
1302 #[inline]
1303 fn from(q: Quat) -> Self {
1304 Vec4::from(q).into()
1305 }
1306}
1307
1308impl From<Quat> for [f32; 4] {
1309 #[inline]
1310 fn from(q: Quat) -> Self {
1311 Vec4::from(q).into()
1312 }
1313}
1314
1315impl From<Quat> for float32x4_t {
1316 #[inline]
1317 fn from(q: Quat) -> Self {
1318 q.0
1319 }
1320}
1321
1322impl Deref for Quat {
1323 type Target = crate::deref::Vec4<f32>;
1324 #[inline]
1325 fn deref(&self) -> &Self::Target {
1326 unsafe { &*(self as *const Self).cast() }
1327 }
1328}
1329
1330impl DerefMut for Quat {
1331 #[inline]
1332 fn deref_mut(&mut self) -> &mut Self::Target {
1333 unsafe { &mut *(self as *mut Self).cast() }
1334 }
1335}