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(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
45#[repr(transparent)]
46pub struct Quat(pub(crate) float32x4_t);
47
48impl Quat {
49 const ZERO: Self = Self::from_array([0.0; 4]);
51
52 pub const IDENTITY: Self = Self::from_xyzw(0.0, 0.0, 0.0, 1.0);
54
55 pub const NAN: Self = Self::from_array([f32::NAN; 4]);
57
58 #[inline(always)]
70 #[must_use]
71 pub const fn from_xyzw(x: f32, y: f32, z: f32, w: f32) -> Self {
72 unsafe { UnionCast { a: [x, y, z, w] }.v }
73 }
74
75 #[inline]
82 #[must_use]
83 pub const fn from_array(a: [f32; 4]) -> Self {
84 Self::from_xyzw(a[0], a[1], a[2], a[3])
85 }
86
87 #[inline]
94 #[must_use]
95 pub const fn from_vec4(v: Vec4) -> Self {
96 Self(v.0)
97 }
98
99 #[inline]
110 #[must_use]
111 pub fn from_slice(slice: &[f32]) -> Self {
112 assert!(slice.len() >= 4);
113 Self(unsafe { vld1q_f32(slice.as_ptr()) })
114 }
115
116 #[inline]
122 pub fn write_to_slice(self, slice: &mut [f32]) {
123 assert!(slice.len() >= 4);
124 unsafe { vst1q_f32(slice.as_mut_ptr(), self.0) }
125 }
126
127 #[inline]
135 #[must_use]
136 pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
137 glam_assert!(axis.is_normalized());
138 let (s, c) = math::sin_cos(angle * 0.5);
139 let v = axis * s;
140 Self::from_xyzw(v.x, v.y, v.z, c)
141 }
142
143 #[inline]
147 #[must_use]
148 pub fn from_scaled_axis(v: Vec3) -> Self {
149 let length = v.length();
150 if length == 0.0 {
151 Self::IDENTITY
152 } else {
153 Self::from_axis_angle(v / length, length)
154 }
155 }
156
157 #[inline]
159 #[must_use]
160 pub fn from_rotation_x(angle: f32) -> Self {
161 let (s, c) = math::sin_cos(angle * 0.5);
162 Self::from_xyzw(s, 0.0, 0.0, c)
163 }
164
165 #[inline]
167 #[must_use]
168 pub fn from_rotation_y(angle: f32) -> Self {
169 let (s, c) = math::sin_cos(angle * 0.5);
170 Self::from_xyzw(0.0, s, 0.0, c)
171 }
172
173 #[inline]
175 #[must_use]
176 pub fn from_rotation_z(angle: f32) -> Self {
177 let (s, c) = math::sin_cos(angle * 0.5);
178 Self::from_xyzw(0.0, 0.0, s, c)
179 }
180
181 #[inline]
183 #[must_use]
184 pub fn from_euler(euler: EulerRot, a: f32, b: f32, c: f32) -> Self {
185 Self::from_euler_angles(euler, a, b, c)
186 }
187
188 #[inline]
197 #[must_use]
198 pub(crate) fn from_rotation_axes(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Self {
199 glam_assert!(x_axis.is_normalized() && y_axis.is_normalized() && z_axis.is_normalized());
200 let (m00, m01, m02) = x_axis.into();
202 let (m10, m11, m12) = y_axis.into();
203 let (m20, m21, m22) = z_axis.into();
204 if m22 <= 0.0 {
205 let dif10 = m11 - m00;
207 let omm22 = 1.0 - m22;
208 if dif10 <= 0.0 {
209 let four_xsq = omm22 - dif10;
211 let inv4x = 0.5 / math::sqrt(four_xsq);
212 Self::from_xyzw(
213 four_xsq * inv4x,
214 (m01 + m10) * inv4x,
215 (m02 + m20) * inv4x,
216 (m12 - m21) * inv4x,
217 )
218 } else {
219 let four_ysq = omm22 + dif10;
221 let inv4y = 0.5 / math::sqrt(four_ysq);
222 Self::from_xyzw(
223 (m01 + m10) * inv4y,
224 four_ysq * inv4y,
225 (m12 + m21) * inv4y,
226 (m20 - m02) * inv4y,
227 )
228 }
229 } else {
230 let sum10 = m11 + m00;
232 let opm22 = 1.0 + m22;
233 if sum10 <= 0.0 {
234 let four_zsq = opm22 - sum10;
236 let inv4z = 0.5 / math::sqrt(four_zsq);
237 Self::from_xyzw(
238 (m02 + m20) * inv4z,
239 (m12 + m21) * inv4z,
240 four_zsq * inv4z,
241 (m01 - m10) * inv4z,
242 )
243 } else {
244 let four_wsq = opm22 + sum10;
246 let inv4w = 0.5 / math::sqrt(four_wsq);
247 Self::from_xyzw(
248 (m12 - m21) * inv4w,
249 (m20 - m02) * inv4w,
250 (m01 - m10) * inv4w,
251 four_wsq * inv4w,
252 )
253 }
254 }
255 }
256
257 #[inline]
266 #[must_use]
267 pub fn from_mat3(mat: &Mat3) -> Self {
268 Self::from_rotation_axes(mat.x_axis, mat.y_axis, mat.z_axis)
269 }
270
271 #[inline]
280 #[must_use]
281 pub fn from_mat3a(mat: &Mat3A) -> Self {
282 Self::from_rotation_axes(mat.x_axis.into(), mat.y_axis.into(), mat.z_axis.into())
283 }
284
285 #[inline]
295 #[must_use]
296 pub fn from_mat4(mat: &Mat4) -> Self {
297 Self::from_rotation_axes(
298 mat.x_axis.truncate(),
299 mat.y_axis.truncate(),
300 mat.z_axis.truncate(),
301 )
302 }
303
304 #[must_use]
318 pub fn from_rotation_arc(from: Vec3, to: Vec3) -> Self {
319 glam_assert!(from.is_normalized());
320 glam_assert!(to.is_normalized());
321
322 const ONE_MINUS_EPS: f32 = 1.0 - 2.0 * f32::EPSILON;
323 let dot = from.dot(to);
324 if dot > ONE_MINUS_EPS {
325 Self::IDENTITY
327 } else if dot < -ONE_MINUS_EPS {
328 use core::f32::consts::PI; Self::from_axis_angle(from.any_orthonormal_vector(), PI)
331 } else {
332 let c = from.cross(to);
333 Self::from_xyzw(c.x, c.y, c.z, 1.0 + dot).normalize()
334 }
335 }
336
337 #[inline]
351 #[must_use]
352 pub fn from_rotation_arc_colinear(from: Vec3, to: Vec3) -> Self {
353 if from.dot(to) < 0.0 {
354 Self::from_rotation_arc(from, -to)
355 } else {
356 Self::from_rotation_arc(from, to)
357 }
358 }
359
360 #[must_use]
374 pub fn from_rotation_arc_2d(from: Vec2, to: Vec2) -> Self {
375 glam_assert!(from.is_normalized());
376 glam_assert!(to.is_normalized());
377
378 const ONE_MINUS_EPSILON: f32 = 1.0 - 2.0 * f32::EPSILON;
379 let dot = from.dot(to);
380 if dot > ONE_MINUS_EPSILON {
381 Self::IDENTITY
383 } else if dot < -ONE_MINUS_EPSILON {
384 const COS_FRAC_PI_2: f32 = 0.0;
386 const SIN_FRAC_PI_2: f32 = 1.0;
387 Self::from_xyzw(0.0, 0.0, SIN_FRAC_PI_2, COS_FRAC_PI_2)
389 } else {
390 let z = from.x * to.y - to.x * from.y;
392 let w = 1.0 + dot;
393 let len_rcp = 1.0 / math::sqrt(z * z + w * w);
395 Self::from_xyzw(0.0, 0.0, z * len_rcp, w * len_rcp)
396 }
397 }
398
399 #[inline]
407 #[must_use]
408 pub fn look_to_lh(dir: Vec3, up: Vec3) -> Self {
409 Self::look_to_rh(-dir, up)
410 }
411
412 #[inline]
420 #[must_use]
421 pub fn look_to_rh(dir: Vec3, up: Vec3) -> Self {
422 glam_assert!(dir.is_normalized());
423 glam_assert!(up.is_normalized());
424 let f = dir;
425 let s = f.cross(up).normalize();
426 let u = s.cross(f);
427
428 Self::from_rotation_axes(
429 Vec3::new(s.x, u.x, -f.x),
430 Vec3::new(s.y, u.y, -f.y),
431 Vec3::new(s.z, u.z, -f.z),
432 )
433 }
434
435 #[inline]
444 #[must_use]
445 pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
446 Self::look_to_lh(center.sub(eye).normalize(), up)
447 }
448
449 #[inline]
458 #[must_use]
459 pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
460 Self::look_to_rh(center.sub(eye).normalize(), up)
461 }
462
463 #[inline]
465 #[must_use]
466 pub fn to_axis_angle(self) -> (Vec3, f32) {
467 const EPSILON: f32 = 1.0e-8;
468 let v = Vec3::new(self.x, self.y, self.z);
469 let length = v.length();
470 if length >= EPSILON {
471 let angle = 2.0 * math::atan2(length, self.w);
472 let axis = v / length;
473 (axis, angle)
474 } else {
475 (Vec3::X, 0.0)
476 }
477 }
478
479 #[inline]
481 #[must_use]
482 pub fn to_scaled_axis(self) -> Vec3 {
483 let (axis, angle) = self.to_axis_angle();
484 axis * angle
485 }
486
487 #[inline]
489 #[must_use]
490 pub fn to_euler(self, order: EulerRot) -> (f32, f32, f32) {
491 self.to_euler_angles(order)
492 }
493
494 #[inline]
496 #[must_use]
497 pub fn to_array(&self) -> [f32; 4] {
498 [self.x, self.y, self.z, self.w]
499 }
500
501 #[inline]
503 #[must_use]
504 pub fn xyz(self) -> Vec3 {
505 Vec3::new(self.x, self.y, self.z)
506 }
507
508 #[inline]
511 #[must_use]
512 pub fn conjugate(self) -> Self {
513 const SIGN: float32x4_t = f32x4_from_array([-1.0, -1.0, -1.0, 1.0]);
514 Self(unsafe { vmulq_f32(self.0, SIGN) })
515 }
516
517 #[inline]
527 #[must_use]
528 pub fn inverse(self) -> Self {
529 glam_assert!(self.is_normalized());
530 self.conjugate()
531 }
532
533 #[inline]
536 #[must_use]
537 pub fn dot(self, rhs: Self) -> f32 {
538 Vec4::from(self).dot(Vec4::from(rhs))
539 }
540
541 #[doc(alias = "magnitude")]
543 #[inline]
544 #[must_use]
545 pub fn length(self) -> f32 {
546 Vec4::from(self).length()
547 }
548
549 #[doc(alias = "magnitude2")]
554 #[inline]
555 #[must_use]
556 pub fn length_squared(self) -> f32 {
557 Vec4::from(self).length_squared()
558 }
559
560 #[inline]
564 #[must_use]
565 pub fn length_recip(self) -> f32 {
566 Vec4::from(self).length_recip()
567 }
568
569 #[inline]
577 #[must_use]
578 pub fn normalize(self) -> Self {
579 Self::from_vec4(Vec4::from(self).normalize())
580 }
581
582 #[inline]
585 #[must_use]
586 pub fn is_finite(self) -> bool {
587 Vec4::from(self).is_finite()
588 }
589
590 #[inline]
592 #[must_use]
593 pub fn is_nan(self) -> bool {
594 Vec4::from(self).is_nan()
595 }
596
597 #[inline]
601 #[must_use]
602 pub fn is_normalized(self) -> bool {
603 Vec4::from(self).is_normalized()
604 }
605
606 #[inline]
607 #[must_use]
608 pub fn is_near_identity(self) -> bool {
609 let threshold_angle = 0.002_847_144_6;
611 let positive_w_angle = math::acos_approx(math::abs(self.w)) * 2.0;
625 positive_w_angle < threshold_angle
626 }
627
628 #[inline]
637 #[must_use]
638 pub fn angle_between(self, rhs: Self) -> f32 {
639 glam_assert!(self.is_normalized() && rhs.is_normalized());
640 math::acos_approx(math::abs(self.dot(rhs))) * 2.0
641 }
642
643 #[inline]
655 #[must_use]
656 pub fn rotate_towards(&self, rhs: Self, max_angle: f32) -> Self {
657 glam_assert!(self.is_normalized() && rhs.is_normalized());
658 let angle = self.angle_between(rhs);
659 if angle <= 1e-4 {
660 return rhs;
661 }
662 let s = (max_angle / angle).clamp(-1.0, 1.0);
663 self.slerp(rhs, s)
664 }
665
666 #[inline]
676 #[must_use]
677 pub fn abs_diff_eq(self, rhs: Self, max_abs_diff: f32) -> bool {
678 Vec4::from(self).abs_diff_eq(Vec4::from(rhs), max_abs_diff)
679 }
680
681 #[inline(always)]
682 #[must_use]
683 fn lerp_impl(self, end: Self, s: f32) -> Self {
684 (self * (1.0 - s) + end * s).normalize()
685 }
686
687 #[doc(alias = "mix")]
697 #[inline]
698 #[must_use]
699 pub fn lerp(self, end: Self, s: f32) -> Self {
700 glam_assert!(self.is_normalized());
701 glam_assert!(end.is_normalized());
702
703 const NEG_ZERO: float32x4_t = f32x4_from_array([-0.0; 4]);
704 unsafe {
705 let dot = dot4_into_f32x4(self.0, end.0);
706 let bias = vandq_u32(vreinterpretq_u32_f32(dot), vreinterpretq_u32_f32(NEG_ZERO));
709 self.lerp_impl(
710 Self(vreinterpretq_f32_u32(veorq_u32(
711 vreinterpretq_u32_f32(end.0),
712 bias,
713 ))),
714 s,
715 )
716 }
717 }
718
719 #[inline]
729 #[must_use]
730 pub fn slerp(self, mut end: Self, s: f32) -> Self {
731 glam_assert!(self.is_normalized());
733 glam_assert!(end.is_normalized());
734
735 let mut dot = self.dot(end);
742 if dot < 0.0 {
743 end = -end;
744 dot = -dot;
745 }
746
747 const DOT_THRESHOLD: f32 = 1.0 - f32::EPSILON;
748 if dot > DOT_THRESHOLD {
749 self.lerp_impl(end, s)
751 } else {
752 let theta = math::acos_approx(dot);
753
754 let scale1 = math::sin(theta * (1.0 - s));
755 let scale2 = math::sin(theta * s);
756 let theta_sin = math::sin(theta);
757 ((self * scale1) + (end * scale2)) * (1.0 / theta_sin)
758 }
759 }
760
761 #[inline]
767 #[must_use]
768 pub fn mul_vec3(self, rhs: Vec3) -> Vec3 {
769 glam_assert!(self.is_normalized());
770
771 self.mul_vec3a(rhs.into()).into()
772 }
773
774 #[inline]
783 #[must_use]
784 pub fn mul_quat(self, rhs: Self) -> Self {
785 unsafe {
786 let lhs = self.0;
787 let rhs = rhs.0;
788
789 const CONTROL_WZYX: float32x4_t = f32x4_from_array([1.0, -1.0, 1.0, -1.0]);
790 const CONTROL_ZWXY: float32x4_t = f32x4_from_array([1.0, 1.0, -1.0, -1.0]);
791 const CONTROL_YXWZ: float32x4_t = f32x4_from_array([-1.0, 1.0, 1.0, -1.0]);
792
793 let r_xxxx = vdupq_laneq_f32(lhs, 0);
794 let r_yyyy = vdupq_laneq_f32(lhs, 1);
795 let r_zzzz = vdupq_laneq_f32(lhs, 2);
796 let r_wwww = vdupq_laneq_f32(lhs, 3);
797
798 let lxrw_lyrw_lzrw_lwrw = vmulq_f32(r_wwww, rhs);
799 let l_wzyx = vrev64q_f32(rhs);
801 let l_wzyx = vextq_f32(l_wzyx, l_wzyx, 2);
802
803 let lwrx_lzrx_lyrx_lxrx = vmulq_f32(r_xxxx, l_wzyx);
804 let l_zwxy = vrev64q_f32(l_wzyx);
806
807 let lwrx_nlzrx_lyrx_nlxrx = vmulq_f32(lwrx_lzrx_lyrx_lxrx, CONTROL_WZYX);
808
809 let lzry_lwry_lxry_lyry = vmulq_f32(r_yyyy, l_zwxy);
810 let l_yxwz = vrev64q_f32(l_zwxy);
812 let l_yxwz = vextq_f32(l_yxwz, l_yxwz, 2);
813
814 let lzry_lwry_nlxry_nlyry = vmulq_f32(lzry_lwry_lxry_lyry, CONTROL_ZWXY);
815
816 let lyrz_lxrz_lwrz_lzrz = vmulq_f32(r_zzzz, l_yxwz);
817 let result0 = vaddq_f32(lxrw_lyrw_lzrw_lwrw, lwrx_nlzrx_lyrx_nlxrx);
818
819 let nlyrz_lxrz_lwrz_wlzrz = vmulq_f32(lyrz_lxrz_lwrz_lzrz, CONTROL_YXWZ);
820 let result1 = vaddq_f32(lzry_lwry_nlxry_nlyry, nlyrz_lxrz_lwrz_wlzrz);
821 Self(vaddq_f32(result0, result1))
822 }
823 }
824
825 #[inline]
835 #[must_use]
836 pub fn from_affine3(a: &crate::Affine3A) -> Self {
837 #[allow(clippy::useless_conversion)]
838 Self::from_rotation_axes(
839 a.matrix3.x_axis.into(),
840 a.matrix3.y_axis.into(),
841 a.matrix3.z_axis.into(),
842 )
843 }
844
845 #[inline]
847 #[must_use]
848 pub fn mul_vec3a(self, rhs: Vec3A) -> Vec3A {
849 unsafe {
850 let w = self.w;
851 let b = Vec3A::from(self.0);
852 let b2 = b.length_squared();
853 Vec3A(vaddq_f32(
854 vaddq_f32(
855 vmulq_n_f32(rhs.0, (w * w) - b2),
856 vmulq_n_f32(b.0, rhs.dot(b) * 2.0),
857 ),
858 vmulq_n_f32(b.cross(rhs).0, w * 2.0),
859 ))
860 }
861 }
862
863 #[inline]
864 #[must_use]
865 pub fn as_dquat(self) -> DQuat {
866 DQuat::from_xyzw(self.x as f64, self.y as f64, self.z as f64, self.w as f64)
867 }
868}
869
870impl fmt::Debug for Quat {
871 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
872 fmt.debug_tuple(stringify!(Quat))
873 .field(&self.x)
874 .field(&self.y)
875 .field(&self.z)
876 .field(&self.w)
877 .finish()
878 }
879}
880
881impl fmt::Display for Quat {
882 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
883 if let Some(p) = f.precision() {
884 write!(
885 f,
886 "[{:.*}, {:.*}, {:.*}, {:.*}]",
887 p, self.x, p, self.y, p, self.z, p, self.w
888 )
889 } else {
890 write!(f, "[{}, {}, {}, {}]", self.x, self.y, self.z, self.w)
891 }
892 }
893}
894
895impl Add for Quat {
896 type Output = Self;
897 #[inline]
904 fn add(self, rhs: Self) -> Self {
905 Self::from_vec4(Vec4::from(self) + Vec4::from(rhs))
906 }
907}
908
909impl Add<&Self> for Quat {
910 type Output = Self;
911 #[inline]
912 fn add(self, rhs: &Self) -> Self {
913 self.add(*rhs)
914 }
915}
916
917impl Add<&Quat> for &Quat {
918 type Output = Quat;
919 #[inline]
920 fn add(self, rhs: &Quat) -> Quat {
921 (*self).add(*rhs)
922 }
923}
924
925impl Add<Quat> for &Quat {
926 type Output = Quat;
927 #[inline]
928 fn add(self, rhs: Quat) -> Quat {
929 (*self).add(rhs)
930 }
931}
932
933impl AddAssign for Quat {
934 #[inline]
935 fn add_assign(&mut self, rhs: Self) {
936 *self = self.add(rhs);
937 }
938}
939
940impl AddAssign<&Self> for Quat {
941 #[inline]
942 fn add_assign(&mut self, rhs: &Self) {
943 self.add_assign(*rhs);
944 }
945}
946
947impl Sub for Quat {
948 type Output = Self;
949 #[inline]
953 fn sub(self, rhs: Self) -> Self {
954 Self::from_vec4(Vec4::from(self) - Vec4::from(rhs))
955 }
956}
957
958impl Sub<&Self> for Quat {
959 type Output = Self;
960 #[inline]
961 fn sub(self, rhs: &Self) -> Self {
962 self.sub(*rhs)
963 }
964}
965
966impl Sub<&Quat> for &Quat {
967 type Output = Quat;
968 #[inline]
969 fn sub(self, rhs: &Quat) -> Quat {
970 (*self).sub(*rhs)
971 }
972}
973
974impl Sub<Quat> for &Quat {
975 type Output = Quat;
976 #[inline]
977 fn sub(self, rhs: Quat) -> Quat {
978 (*self).sub(rhs)
979 }
980}
981
982impl SubAssign for Quat {
983 #[inline]
984 fn sub_assign(&mut self, rhs: Self) {
985 *self = self.sub(rhs);
986 }
987}
988
989impl SubAssign<&Self> for Quat {
990 #[inline]
991 fn sub_assign(&mut self, rhs: &Self) {
992 self.sub_assign(*rhs);
993 }
994}
995
996impl Mul<f32> for Quat {
997 type Output = Self;
998 #[inline]
1002 fn mul(self, rhs: f32) -> Self {
1003 Self::from_vec4(Vec4::from(self) * rhs)
1004 }
1005}
1006
1007impl Mul<&f32> for Quat {
1008 type Output = Self;
1009 #[inline]
1010 fn mul(self, rhs: &f32) -> Self {
1011 self.mul(*rhs)
1012 }
1013}
1014
1015impl Mul<&f32> for &Quat {
1016 type Output = Quat;
1017 #[inline]
1018 fn mul(self, rhs: &f32) -> Quat {
1019 (*self).mul(*rhs)
1020 }
1021}
1022
1023impl Mul<f32> for &Quat {
1024 type Output = Quat;
1025 #[inline]
1026 fn mul(self, rhs: f32) -> Quat {
1027 (*self).mul(rhs)
1028 }
1029}
1030
1031impl MulAssign<f32> for Quat {
1032 #[inline]
1033 fn mul_assign(&mut self, rhs: f32) {
1034 *self = self.mul(rhs);
1035 }
1036}
1037
1038impl MulAssign<&f32> for Quat {
1039 #[inline]
1040 fn mul_assign(&mut self, rhs: &f32) {
1041 self.mul_assign(*rhs);
1042 }
1043}
1044
1045impl Div<f32> for Quat {
1046 type Output = Self;
1047 #[inline]
1050 fn div(self, rhs: f32) -> Self {
1051 Self::from_vec4(Vec4::from(self) / rhs)
1052 }
1053}
1054
1055impl Div<&f32> for Quat {
1056 type Output = Self;
1057 #[inline]
1058 fn div(self, rhs: &f32) -> Self {
1059 self.div(*rhs)
1060 }
1061}
1062
1063impl Div<&f32> for &Quat {
1064 type Output = Quat;
1065 #[inline]
1066 fn div(self, rhs: &f32) -> Quat {
1067 (*self).div(*rhs)
1068 }
1069}
1070
1071impl Div<f32> for &Quat {
1072 type Output = Quat;
1073 #[inline]
1074 fn div(self, rhs: f32) -> Quat {
1075 (*self).div(rhs)
1076 }
1077}
1078
1079impl DivAssign<f32> for Quat {
1080 #[inline]
1081 fn div_assign(&mut self, rhs: f32) {
1082 *self = self.div(rhs);
1083 }
1084}
1085
1086impl DivAssign<&f32> for Quat {
1087 #[inline]
1088 fn div_assign(&mut self, rhs: &f32) {
1089 self.div_assign(*rhs);
1090 }
1091}
1092
1093impl Mul for Quat {
1094 type Output = Self;
1095 #[inline]
1105 fn mul(self, rhs: Self) -> Self {
1106 self.mul_quat(rhs)
1107 }
1108}
1109
1110impl Mul<&Self> for Quat {
1111 type Output = Self;
1112 #[inline]
1113 fn mul(self, rhs: &Self) -> Self {
1114 self.mul(*rhs)
1115 }
1116}
1117
1118impl Mul<&Quat> for &Quat {
1119 type Output = Quat;
1120 #[inline]
1121 fn mul(self, rhs: &Quat) -> Quat {
1122 (*self).mul(*rhs)
1123 }
1124}
1125
1126impl Mul<Quat> for &Quat {
1127 type Output = Quat;
1128 #[inline]
1129 fn mul(self, rhs: Quat) -> Quat {
1130 (*self).mul(rhs)
1131 }
1132}
1133
1134impl MulAssign for Quat {
1135 #[inline]
1136 fn mul_assign(&mut self, rhs: Self) {
1137 *self = self.mul(rhs);
1138 }
1139}
1140
1141impl MulAssign<&Self> for Quat {
1142 #[inline]
1143 fn mul_assign(&mut self, rhs: &Self) {
1144 self.mul_assign(*rhs);
1145 }
1146}
1147
1148impl Mul<Vec3> for Quat {
1149 type Output = Vec3;
1150 #[inline]
1156 fn mul(self, rhs: Vec3) -> Self::Output {
1157 self.mul_vec3(rhs)
1158 }
1159}
1160
1161impl Mul<&Vec3> for Quat {
1162 type Output = Vec3;
1163 #[inline]
1164 fn mul(self, rhs: &Vec3) -> Vec3 {
1165 self.mul(*rhs)
1166 }
1167}
1168
1169impl Mul<&Vec3> for &Quat {
1170 type Output = Vec3;
1171 #[inline]
1172 fn mul(self, rhs: &Vec3) -> Vec3 {
1173 (*self).mul(*rhs)
1174 }
1175}
1176
1177impl Mul<Vec3> for &Quat {
1178 type Output = Vec3;
1179 #[inline]
1180 fn mul(self, rhs: Vec3) -> Vec3 {
1181 (*self).mul(rhs)
1182 }
1183}
1184
1185impl Mul<Vec3A> for Quat {
1186 type Output = Vec3A;
1187 #[inline]
1188 fn mul(self, rhs: Vec3A) -> Self::Output {
1189 self.mul_vec3a(rhs)
1190 }
1191}
1192
1193impl Mul<&Vec3A> for Quat {
1194 type Output = Vec3A;
1195 #[inline]
1196 fn mul(self, rhs: &Vec3A) -> Vec3A {
1197 self.mul(*rhs)
1198 }
1199}
1200
1201impl Mul<&Vec3A> for &Quat {
1202 type Output = Vec3A;
1203 #[inline]
1204 fn mul(self, rhs: &Vec3A) -> Vec3A {
1205 (*self).mul(*rhs)
1206 }
1207}
1208
1209impl Mul<Vec3A> for &Quat {
1210 type Output = Vec3A;
1211 #[inline]
1212 fn mul(self, rhs: Vec3A) -> Vec3A {
1213 (*self).mul(rhs)
1214 }
1215}
1216
1217impl Neg for Quat {
1218 type Output = Self;
1219 #[inline]
1220 fn neg(self) -> Self {
1221 self * -1.0
1222 }
1223}
1224
1225impl Neg for &Quat {
1226 type Output = Quat;
1227 #[inline]
1228 fn neg(self) -> Quat {
1229 (*self).neg()
1230 }
1231}
1232
1233impl Default for Quat {
1234 #[inline]
1235 fn default() -> Self {
1236 Self::IDENTITY
1237 }
1238}
1239
1240impl PartialEq for Quat {
1241 #[inline]
1242 fn eq(&self, rhs: &Self) -> bool {
1243 Vec4::from(*self).eq(&Vec4::from(*rhs))
1244 }
1245}
1246
1247impl AsRef<[f32; 4]> for Quat {
1248 #[inline]
1249 fn as_ref(&self) -> &[f32; 4] {
1250 unsafe { &*(self as *const Self as *const [f32; 4]) }
1251 }
1252}
1253
1254impl Sum<Self> for Quat {
1255 fn sum<I>(iter: I) -> Self
1256 where
1257 I: Iterator<Item = Self>,
1258 {
1259 iter.fold(Self::ZERO, Self::add)
1260 }
1261}
1262
1263impl<'a> Sum<&'a Self> for Quat {
1264 fn sum<I>(iter: I) -> Self
1265 where
1266 I: Iterator<Item = &'a Self>,
1267 {
1268 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1269 }
1270}
1271
1272impl Product for Quat {
1273 fn product<I>(iter: I) -> Self
1274 where
1275 I: Iterator<Item = Self>,
1276 {
1277 iter.fold(Self::IDENTITY, Self::mul)
1278 }
1279}
1280
1281impl<'a> Product<&'a Self> for Quat {
1282 fn product<I>(iter: I) -> Self
1283 where
1284 I: Iterator<Item = &'a Self>,
1285 {
1286 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1287 }
1288}
1289
1290impl From<Quat> for Vec4 {
1291 #[inline]
1292 fn from(q: Quat) -> Self {
1293 Self(q.0)
1294 }
1295}
1296
1297impl From<Quat> for (f32, f32, f32, f32) {
1298 #[inline]
1299 fn from(q: Quat) -> Self {
1300 Vec4::from(q).into()
1301 }
1302}
1303
1304impl From<Quat> for [f32; 4] {
1305 #[inline]
1306 fn from(q: Quat) -> Self {
1307 Vec4::from(q).into()
1308 }
1309}
1310
1311impl From<Quat> for float32x4_t {
1312 #[inline]
1313 fn from(q: Quat) -> Self {
1314 q.0
1315 }
1316}
1317
1318impl Deref for Quat {
1319 type Target = crate::deref::Vec4<f32>;
1320 #[inline]
1321 fn deref(&self) -> &Self::Target {
1322 unsafe { &*(self as *const Self).cast() }
1323 }
1324}
1325
1326impl DerefMut for Quat {
1327 #[inline]
1328 fn deref_mut(&mut self) -> &mut Self::Target {
1329 unsafe { &mut *(self as *mut Self).cast() }
1330 }
1331}