1use crate::{
4 Mat3, Mat3A, Mat4, Vec2, Vec3, Vec3A, Vec4,
5 euler::{EulerRot, FromEuler, ToEuler},
6 f32::math,
7 neon::*,
8};
9
10#[cfg(feature = "f64")]
11use crate::DQuat;
12
13use core::arch::aarch64::*;
14
15use core::fmt;
16use core::iter::{Product, Sum};
17use core::ops::{
18 Add, AddAssign, Deref, DerefMut, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign,
19};
20
21#[cfg(feature = "zerocopy-08")]
22use zerocopy_derive_08::*;
23
24#[repr(C)]
25union UnionCast {
26 a: [f32; 4],
27 v: Quat,
28}
29
30#[inline]
35#[must_use]
36pub const fn quat(x: f32, y: f32, z: f32, w: f32) -> Quat {
37 Quat::from_xyzw(x, y, z, w)
38}
39
40#[derive(Clone, Copy)]
50#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
51#[cfg_attr(
52 feature = "zerocopy-08",
53 derive(FromBytes, Immutable, IntoBytes, KnownLayout)
54)]
55#[repr(transparent)]
56pub struct Quat(pub(crate) float32x4_t);
57
58impl Quat {
59 const ZERO: Self = Self::from_array([0.0; 4]);
61
62 pub const IDENTITY: Self = Self::from_xyzw(0.0, 0.0, 0.0, 1.0);
64
65 pub const NAN: Self = Self::from_array([f32::NAN; 4]);
67
68 #[inline(always)]
80 #[must_use]
81 pub const fn from_xyzw(x: f32, y: f32, z: f32, w: f32) -> Self {
82 unsafe { UnionCast { a: [x, y, z, w] }.v }
83 }
84
85 #[inline]
92 #[must_use]
93 pub const fn from_array(a: [f32; 4]) -> Self {
94 Self::from_xyzw(a[0], a[1], a[2], a[3])
95 }
96
97 #[inline]
104 #[must_use]
105 pub const fn from_vec4(v: Vec4) -> Self {
106 Self(v.0)
107 }
108
109 #[inline]
120 #[must_use]
121 #[track_caller]
122 pub fn from_slice(slice: &[f32]) -> Self {
123 assert!(slice.len() >= 4);
124 Self(unsafe { vld1q_f32(slice.as_ptr()) })
125 }
126
127 #[inline]
133 #[track_caller]
134 pub fn write_to_slice(self, slice: &mut [f32]) {
135 assert!(slice.len() >= 4);
136 unsafe { vst1q_f32(slice.as_mut_ptr(), self.0) }
137 }
138
139 #[inline]
147 #[must_use]
148 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
149 pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
150 glam_assert!(axis.is_normalized());
151 let (s, c) = math::sin_cos(angle * 0.5);
152 let v = axis * s;
153 Self::from_xyzw(v.x, v.y, v.z, c)
154 }
155
156 #[inline]
164 #[must_use]
165 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
166 pub fn from_scaled_axis(v: Vec3) -> Self {
167 let length = v.length();
168 if length == 0.0 {
169 Self::IDENTITY
170 } else {
171 Self::from_axis_angle(v / length, length)
172 }
173 }
174
175 #[inline]
177 #[must_use]
178 pub fn from_rotation_x(angle: f32) -> Self {
179 let (s, c) = math::sin_cos(angle * 0.5);
180 Self::from_xyzw(s, 0.0, 0.0, c)
181 }
182
183 #[inline]
185 #[must_use]
186 pub fn from_rotation_y(angle: f32) -> Self {
187 let (s, c) = math::sin_cos(angle * 0.5);
188 Self::from_xyzw(0.0, s, 0.0, c)
189 }
190
191 #[inline]
193 #[must_use]
194 pub fn from_rotation_z(angle: f32) -> Self {
195 let (s, c) = math::sin_cos(angle * 0.5);
196 Self::from_xyzw(0.0, 0.0, s, c)
197 }
198
199 #[inline]
201 #[must_use]
202 pub fn from_euler(euler: EulerRot, a: f32, b: f32, c: f32) -> Self {
203 Self::from_euler_angles(euler, a, b, c)
204 }
205
206 #[inline]
215 #[must_use]
216 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
217 pub fn from_rotation_axes(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Self {
218 glam_assert!(x_axis.is_normalized() && y_axis.is_normalized() && z_axis.is_normalized());
219 let (m00, m01, m02) = x_axis.into();
221 let (m10, m11, m12) = y_axis.into();
222 let (m20, m21, m22) = z_axis.into();
223 if m22 <= 0.0 {
224 let dif10 = m11 - m00;
226 let omm22 = 1.0 - m22;
227 if dif10 <= 0.0 {
228 let four_xsq = omm22 - dif10;
230 let inv4x = 0.5 / math::sqrt(four_xsq);
231 Self::from_xyzw(
232 four_xsq * inv4x,
233 (m01 + m10) * inv4x,
234 (m02 + m20) * inv4x,
235 (m12 - m21) * inv4x,
236 )
237 } else {
238 let four_ysq = omm22 + dif10;
240 let inv4y = 0.5 / math::sqrt(four_ysq);
241 Self::from_xyzw(
242 (m01 + m10) * inv4y,
243 four_ysq * inv4y,
244 (m12 + m21) * inv4y,
245 (m20 - m02) * inv4y,
246 )
247 }
248 } else {
249 let sum10 = m11 + m00;
251 let opm22 = 1.0 + m22;
252 if sum10 <= 0.0 {
253 let four_zsq = opm22 - sum10;
255 let inv4z = 0.5 / math::sqrt(four_zsq);
256 Self::from_xyzw(
257 (m02 + m20) * inv4z,
258 (m12 + m21) * inv4z,
259 four_zsq * inv4z,
260 (m01 - m10) * inv4z,
261 )
262 } else {
263 let four_wsq = opm22 + sum10;
265 let inv4w = 0.5 / math::sqrt(four_wsq);
266 Self::from_xyzw(
267 (m12 - m21) * inv4w,
268 (m20 - m02) * inv4w,
269 (m01 - m10) * inv4w,
270 four_wsq * inv4w,
271 )
272 }
273 }
274 }
275
276 #[inline]
285 #[must_use]
286 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
287 pub fn from_mat3(mat: &Mat3) -> Self {
288 Self::from_rotation_axes(mat.x_axis, mat.y_axis, mat.z_axis)
289 }
290
291 #[inline]
300 #[must_use]
301 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
302 pub fn from_mat3a(mat: &Mat3A) -> Self {
303 Self::from_rotation_axes(mat.x_axis.into(), mat.y_axis.into(), mat.z_axis.into())
304 }
305
306 #[inline]
316 #[must_use]
317 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
318 pub fn from_mat4(mat: &Mat4) -> Self {
319 Self::from_rotation_axes(
320 mat.x_axis.truncate(),
321 mat.y_axis.truncate(),
322 mat.z_axis.truncate(),
323 )
324 }
325
326 #[must_use]
340 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
341 pub fn from_rotation_arc(from: Vec3, to: Vec3) -> Self {
342 glam_assert!(from.is_normalized());
343 glam_assert!(to.is_normalized());
344
345 const ONE_MINUS_EPS: f32 = 1.0 - 2.0 * f32::EPSILON;
346 let dot = from.dot(to);
347 if dot > ONE_MINUS_EPS {
348 Self::IDENTITY
350 } else if dot < -ONE_MINUS_EPS {
351 use core::f32::consts::PI; Self::from_axis_angle(from.any_orthonormal_vector(), PI)
354 } else {
355 let c = from.cross(to);
356 Self::from_xyzw(c.x, c.y, c.z, 1.0 + dot).normalize()
357 }
358 }
359
360 #[inline]
374 #[must_use]
375 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
376 pub fn from_rotation_arc_colinear(from: Vec3, to: Vec3) -> Self {
377 if from.dot(to) < 0.0 {
378 Self::from_rotation_arc(from, -to)
379 } else {
380 Self::from_rotation_arc(from, to)
381 }
382 }
383
384 #[must_use]
398 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
399 pub fn from_rotation_arc_2d(from: Vec2, to: Vec2) -> Self {
400 glam_assert!(from.is_normalized());
401 glam_assert!(to.is_normalized());
402
403 const ONE_MINUS_EPSILON: f32 = 1.0 - 2.0 * f32::EPSILON;
404 let dot = from.dot(to);
405 if dot > ONE_MINUS_EPSILON {
406 Self::IDENTITY
408 } else if dot < -ONE_MINUS_EPSILON {
409 const COS_FRAC_PI_2: f32 = 0.0;
411 const SIN_FRAC_PI_2: f32 = 1.0;
412 Self::from_xyzw(0.0, 0.0, SIN_FRAC_PI_2, COS_FRAC_PI_2)
414 } else {
415 let z = from.x * to.y - to.x * from.y;
417 let w = 1.0 + dot;
418 let len_rcp = 1.0 / math::sqrt(z * z + w * w);
420 Self::from_xyzw(0.0, 0.0, z * len_rcp, w * len_rcp)
421 }
422 }
423
424 #[inline]
426 #[must_use]
427 pub fn to_axis_angle(self) -> (Vec3, f32) {
428 const EPSILON: f32 = 1.0e-8;
429 let v = Vec3::new(self.x, self.y, self.z);
430 let length = v.length();
431 if length >= EPSILON {
432 let angle = 2.0 * math::atan2(length, self.w);
433 let axis = v / length;
434 (axis, angle)
435 } else {
436 (Vec3::X, 0.0)
437 }
438 }
439
440 #[inline]
442 #[must_use]
443 pub fn to_scaled_axis(self) -> Vec3 {
444 let (axis, angle) = self.to_axis_angle();
445 axis * angle
446 }
447
448 #[inline]
454 #[must_use]
455 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
456 pub fn to_euler(self, order: EulerRot) -> (f32, f32, f32) {
457 Mat3::from_quat(self).to_euler_angles(order)
458 }
459
460 #[inline]
462 #[must_use]
463 pub const fn to_array(&self) -> [f32; 4] {
464 unsafe { *(self as *const Self as *const [f32; 4]) }
465 }
466
467 #[inline]
469 #[must_use]
470 pub fn xyz(self) -> Vec3 {
471 Vec3::new(self.x, self.y, self.z)
472 }
473
474 #[inline]
477 #[must_use]
478 pub fn conjugate(self) -> Self {
479 const SIGN: float32x4_t = f32x4_from_array([-1.0, -1.0, -1.0, 1.0]);
480 Self(unsafe { vmulq_f32(self.0, SIGN) })
481 }
482
483 #[inline]
493 #[must_use]
494 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
495 pub fn inverse(self) -> Self {
496 glam_assert!(self.is_normalized());
497 self.conjugate()
498 }
499
500 #[inline]
503 #[must_use]
504 pub fn dot(self, rhs: Self) -> f32 {
505 Vec4::from(self).dot(Vec4::from(rhs))
506 }
507
508 #[doc(alias = "magnitude")]
510 #[inline]
511 #[must_use]
512 pub fn length(self) -> f32 {
513 Vec4::from(self).length()
514 }
515
516 #[doc(alias = "magnitude2")]
521 #[inline]
522 #[must_use]
523 pub fn length_squared(self) -> f32 {
524 Vec4::from(self).length_squared()
525 }
526
527 #[inline]
531 #[must_use]
532 pub fn length_recip(self) -> f32 {
533 Vec4::from(self).length_recip()
534 }
535
536 #[inline]
544 #[must_use]
545 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
546 pub fn normalize(self) -> Self {
547 Self::from_vec4(Vec4::from(self).normalize())
548 }
549
550 #[inline]
553 #[must_use]
554 pub fn is_finite(self) -> bool {
555 Vec4::from(self).is_finite()
556 }
557
558 #[inline]
560 #[must_use]
561 pub fn is_nan(self) -> bool {
562 Vec4::from(self).is_nan()
563 }
564
565 #[inline]
569 #[must_use]
570 pub fn is_normalized(self) -> bool {
571 Vec4::from(self).is_normalized()
572 }
573
574 #[inline]
576 #[must_use]
577 pub fn is_near_identity(self) -> bool {
578 const THRESHOLD: f32 = 1.0 - 1e-6;
583 self.w.abs() > THRESHOLD
584 }
585
586 #[inline]
595 #[must_use]
596 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
597 pub fn angle_between(self, rhs: Self) -> f32 {
598 glam_assert!(self.is_normalized() && rhs.is_normalized());
599 math::acos_approx(self.dot(rhs).abs()) * 2.0
600 }
601
602 #[inline]
614 #[must_use]
615 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
616 pub fn rotate_towards(self, rhs: Self, max_angle: f32) -> Self {
617 glam_assert!(self.is_normalized() && rhs.is_normalized());
618 let angle = self.angle_between(rhs);
619 if angle <= 1e-4 {
620 return rhs;
621 }
622 let s = (max_angle / angle).clamp(-1.0, 1.0);
623 self.slerp(rhs, s)
624 }
625
626 #[inline]
636 #[must_use]
637 pub fn abs_diff_eq(self, rhs: Self, max_abs_diff: f32) -> bool {
638 Vec4::from(self).abs_diff_eq(Vec4::from(rhs), max_abs_diff)
639 }
640
641 #[inline(always)]
642 #[must_use]
643 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
644 fn lerp_impl(self, end: Self, s: f32) -> Self {
645 (self * (1.0 - s) + end * s).normalize()
646 }
647
648 #[doc(alias = "mix")]
661 #[inline]
662 #[must_use]
663 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
664 pub fn lerp(self, end: Self, s: f32) -> Self {
665 glam_assert!(self.is_normalized());
666 glam_assert!(end.is_normalized());
667
668 const NEG_ZERO: float32x4_t = f32x4_from_array([-0.0; 4]);
669 unsafe {
670 let dot = dot4_into_f32x4(self.0, end.0);
671 let bias = vandq_u32(vreinterpretq_u32_f32(dot), vreinterpretq_u32_f32(NEG_ZERO));
674 self.lerp_impl(
675 Self(vreinterpretq_f32_u32(veorq_u32(
676 vreinterpretq_u32_f32(end.0),
677 bias,
678 ))),
679 s,
680 )
681 }
682 }
683
684 #[inline(always)]
685 #[must_use]
686 fn slerp_impl(self, end: Self, dot: f32, s: f32) -> Self {
687 let theta = math::acos_approx(dot);
688
689 let coefs = [1.0 - s, s, 1.0, 0.0];
690 unsafe {
691 let tmp = vmulq_f32(vdupq_n_f32(theta), vld1q_f32(coefs.as_ptr()));
692 let tmp = f32x4_sin(tmp);
693
694 let scale1 = vdupq_n_f32(vgetq_lane_f32(tmp, 0));
695 let scale2 = vdupq_n_f32(vgetq_lane_f32(tmp, 1));
696 let theta_sin = vdupq_n_f32(vgetq_lane_f32(tmp, 2));
697
698 Self(vdivq_f32(
699 vfmaq_f32(vmulq_f32(self.0, scale1), end.0, scale2),
700 theta_sin,
701 ))
702 }
703 }
704
705 #[inline]
715 #[must_use]
716 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
717 pub fn slerp(self, mut end: Self, s: f32) -> Self {
718 glam_assert!(self.is_normalized());
720 glam_assert!(end.is_normalized());
721
722 let mut dot = self.dot(end);
729 if dot < 0.0 {
730 end = -end;
731 dot = -dot;
732 }
733
734 const DOT_THRESHOLD: f32 = 1.0 - f32::EPSILON;
735 if dot > DOT_THRESHOLD {
736 self.lerp_impl(end, s)
738 } else {
739 self.slerp_impl(end, dot, s)
740 }
741 }
742
743 #[inline]
757 #[must_use]
758 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
759 pub fn slerp_long(self, end: Self, s: f32) -> Self {
760 glam_assert!(self.is_normalized());
761 glam_assert!(end.is_normalized());
762
763 let dot = self.dot(end);
764
765 const DOT_THRESHOLD: f32 = 1.0 - f32::EPSILON;
766 if dot.abs() > DOT_THRESHOLD {
767 self.lerp_impl(end, s)
769 } else {
770 self.slerp_impl(end, dot, s)
771 }
772 }
773
774 #[inline]
780 #[must_use]
781 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
782 pub fn mul_vec3(self, rhs: Vec3) -> Vec3 {
783 glam_assert!(self.is_normalized());
784
785 self.mul_vec3a(rhs.into()).into()
786 }
787
788 #[inline]
793 #[must_use]
794 pub fn mul_quat(self, rhs: Self) -> Self {
795 unsafe {
796 let lhs = self.0;
797 let rhs = rhs.0;
798
799 const CONTROL_WZYX: float32x4_t = f32x4_from_array([1.0, -1.0, 1.0, -1.0]);
800 const CONTROL_ZWXY: float32x4_t = f32x4_from_array([1.0, 1.0, -1.0, -1.0]);
801 const CONTROL_YXWZ: float32x4_t = f32x4_from_array([-1.0, 1.0, 1.0, -1.0]);
802
803 let r_xxxx = vdupq_laneq_f32(lhs, 0);
804 let r_yyyy = vdupq_laneq_f32(lhs, 1);
805 let r_zzzz = vdupq_laneq_f32(lhs, 2);
806 let r_wwww = vdupq_laneq_f32(lhs, 3);
807
808 let lxrw_lyrw_lzrw_lwrw = vmulq_f32(r_wwww, rhs);
809 let l_wzyx = vrev64q_f32(rhs);
811 let l_wzyx = vextq_f32(l_wzyx, l_wzyx, 2);
812
813 let lwrx_lzrx_lyrx_lxrx = vmulq_f32(r_xxxx, l_wzyx);
814 let l_zwxy = vrev64q_f32(l_wzyx);
816
817 let lzry_lwry_lxry_lyry = vmulq_f32(r_yyyy, l_zwxy);
818 let l_yxwz = vrev64q_f32(l_zwxy);
820 let l_yxwz = vextq_f32(l_yxwz, l_yxwz, 2);
821
822 let lzry_lwry_nlxry_nlyry = vmulq_f32(lzry_lwry_lxry_lyry, CONTROL_ZWXY);
823
824 let lyrz_lxrz_lwrz_lzrz = vmulq_f32(r_zzzz, l_yxwz);
825 let result0 = vfmaq_f32(lxrw_lyrw_lzrw_lwrw, lwrx_lzrx_lyrx_lxrx, CONTROL_WZYX);
826
827 let result1 = vfmaq_f32(lzry_lwry_nlxry_nlyry, lyrz_lxrz_lwrz_lzrz, CONTROL_YXWZ);
828 Self(vaddq_f32(result0, result1))
829 }
830 }
831
832 #[inline]
842 #[must_use]
843 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
844 pub fn from_affine3(a: &crate::Affine3) -> Self {
845 Self::from_rotation_axes(a.matrix3.x_axis, a.matrix3.y_axis, a.matrix3.z_axis)
846 }
847
848 #[inline]
858 #[must_use]
859 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
860 pub fn from_affine3a(a: &crate::Affine3A) -> Self {
861 Self::from_rotation_axes(
862 a.matrix3.x_axis.into(),
863 a.matrix3.y_axis.into(),
864 a.matrix3.z_axis.into(),
865 )
866 }
867
868 #[inline]
874 #[must_use]
875 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
876 pub fn mul_vec3a(self, rhs: Vec3A) -> Vec3A {
877 glam_assert!(self.is_normalized());
878
879 unsafe {
880 let w = self.w;
881 let b = Vec3A::from(self.0);
882 let b2 = b.length_squared();
883 Vec3A(vaddq_f32(
884 vaddq_f32(
885 vmulq_n_f32(rhs.0, (w * w) - b2),
886 vmulq_n_f32(b.0, rhs.dot(b) * 2.0),
887 ),
888 vmulq_n_f32(b.cross(rhs).0, w * 2.0),
889 ))
890 }
891 }
892
893 #[cfg(feature = "f64")]
894 #[inline]
895 #[must_use]
896 pub fn as_dquat(self) -> DQuat {
897 DQuat::from_xyzw(self.x as f64, self.y as f64, self.z as f64, self.w as f64)
898 }
899}
900
901impl fmt::Debug for Quat {
902 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
903 fmt.debug_tuple(stringify!(Quat))
904 .field(&self.x)
905 .field(&self.y)
906 .field(&self.z)
907 .field(&self.w)
908 .finish()
909 }
910}
911
912impl fmt::Display for Quat {
913 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
914 if let Some(p) = f.precision() {
915 write!(
916 f,
917 "[{:.*}, {:.*}, {:.*}, {:.*}]",
918 p, self.x, p, self.y, p, self.z, p, self.w
919 )
920 } else {
921 write!(f, "[{}, {}, {}, {}]", self.x, self.y, self.z, self.w)
922 }
923 }
924}
925
926impl Add for Quat {
927 type Output = Self;
928 #[inline]
935 fn add(self, rhs: Self) -> Self {
936 Self::from_vec4(Vec4::from(self) + Vec4::from(rhs))
937 }
938}
939
940impl Add<&Self> for Quat {
941 type Output = Self;
942 #[inline]
943 fn add(self, rhs: &Self) -> Self {
944 self.add(*rhs)
945 }
946}
947
948impl Add<&Quat> for &Quat {
949 type Output = Quat;
950 #[inline]
951 fn add(self, rhs: &Quat) -> Quat {
952 (*self).add(*rhs)
953 }
954}
955
956impl Add<Quat> for &Quat {
957 type Output = Quat;
958 #[inline]
959 fn add(self, rhs: Quat) -> Quat {
960 (*self).add(rhs)
961 }
962}
963
964impl AddAssign for Quat {
965 #[inline]
966 fn add_assign(&mut self, rhs: Self) {
967 *self = self.add(rhs);
968 }
969}
970
971impl AddAssign<&Self> for Quat {
972 #[inline]
973 fn add_assign(&mut self, rhs: &Self) {
974 self.add_assign(*rhs);
975 }
976}
977
978impl Sub for Quat {
979 type Output = Self;
980 #[inline]
984 fn sub(self, rhs: Self) -> Self {
985 Self::from_vec4(Vec4::from(self) - Vec4::from(rhs))
986 }
987}
988
989impl Sub<&Self> for Quat {
990 type Output = Self;
991 #[inline]
992 fn sub(self, rhs: &Self) -> Self {
993 self.sub(*rhs)
994 }
995}
996
997impl Sub<&Quat> for &Quat {
998 type Output = Quat;
999 #[inline]
1000 fn sub(self, rhs: &Quat) -> Quat {
1001 (*self).sub(*rhs)
1002 }
1003}
1004
1005impl Sub<Quat> for &Quat {
1006 type Output = Quat;
1007 #[inline]
1008 fn sub(self, rhs: Quat) -> Quat {
1009 (*self).sub(rhs)
1010 }
1011}
1012
1013impl SubAssign for Quat {
1014 #[inline]
1015 fn sub_assign(&mut self, rhs: Self) {
1016 *self = self.sub(rhs);
1017 }
1018}
1019
1020impl SubAssign<&Self> for Quat {
1021 #[inline]
1022 fn sub_assign(&mut self, rhs: &Self) {
1023 self.sub_assign(*rhs);
1024 }
1025}
1026
1027impl Mul<f32> for Quat {
1028 type Output = Self;
1029 #[inline]
1033 fn mul(self, rhs: f32) -> Self {
1034 Self::from_vec4(Vec4::from(self) * rhs)
1035 }
1036}
1037
1038impl Mul<&f32> for Quat {
1039 type Output = Self;
1040 #[inline]
1041 fn mul(self, rhs: &f32) -> Self {
1042 self.mul(*rhs)
1043 }
1044}
1045
1046impl Mul<&f32> for &Quat {
1047 type Output = Quat;
1048 #[inline]
1049 fn mul(self, rhs: &f32) -> Quat {
1050 (*self).mul(*rhs)
1051 }
1052}
1053
1054impl Mul<f32> for &Quat {
1055 type Output = Quat;
1056 #[inline]
1057 fn mul(self, rhs: f32) -> Quat {
1058 (*self).mul(rhs)
1059 }
1060}
1061
1062impl MulAssign<f32> for Quat {
1063 #[inline]
1064 fn mul_assign(&mut self, rhs: f32) {
1065 *self = self.mul(rhs);
1066 }
1067}
1068
1069impl MulAssign<&f32> for Quat {
1070 #[inline]
1071 fn mul_assign(&mut self, rhs: &f32) {
1072 self.mul_assign(*rhs);
1073 }
1074}
1075
1076impl Div<f32> for Quat {
1077 type Output = Self;
1078 #[inline]
1081 fn div(self, rhs: f32) -> Self {
1082 Self::from_vec4(Vec4::from(self) / rhs)
1083 }
1084}
1085
1086impl Div<&f32> for Quat {
1087 type Output = Self;
1088 #[inline]
1089 fn div(self, rhs: &f32) -> Self {
1090 self.div(*rhs)
1091 }
1092}
1093
1094impl Div<&f32> for &Quat {
1095 type Output = Quat;
1096 #[inline]
1097 fn div(self, rhs: &f32) -> Quat {
1098 (*self).div(*rhs)
1099 }
1100}
1101
1102impl Div<f32> for &Quat {
1103 type Output = Quat;
1104 #[inline]
1105 fn div(self, rhs: f32) -> Quat {
1106 (*self).div(rhs)
1107 }
1108}
1109
1110impl DivAssign<f32> for Quat {
1111 #[inline]
1112 fn div_assign(&mut self, rhs: f32) {
1113 *self = self.div(rhs);
1114 }
1115}
1116
1117impl DivAssign<&f32> for Quat {
1118 #[inline]
1119 fn div_assign(&mut self, rhs: &f32) {
1120 self.div_assign(*rhs);
1121 }
1122}
1123
1124impl Mul for Quat {
1125 type Output = Self;
1126 #[inline]
1132 fn mul(self, rhs: Self) -> Self {
1133 self.mul_quat(rhs)
1134 }
1135}
1136
1137impl Mul<&Self> for Quat {
1138 type Output = Self;
1139 #[inline]
1140 fn mul(self, rhs: &Self) -> Self {
1141 self.mul(*rhs)
1142 }
1143}
1144
1145impl Mul<&Quat> for &Quat {
1146 type Output = Quat;
1147 #[inline]
1148 fn mul(self, rhs: &Quat) -> Quat {
1149 (*self).mul(*rhs)
1150 }
1151}
1152
1153impl Mul<Quat> for &Quat {
1154 type Output = Quat;
1155 #[inline]
1156 fn mul(self, rhs: Quat) -> Quat {
1157 (*self).mul(rhs)
1158 }
1159}
1160
1161impl MulAssign for Quat {
1162 #[inline]
1163 fn mul_assign(&mut self, rhs: Self) {
1164 *self = self.mul(rhs);
1165 }
1166}
1167
1168impl MulAssign<&Self> for Quat {
1169 #[inline]
1170 fn mul_assign(&mut self, rhs: &Self) {
1171 self.mul_assign(*rhs);
1172 }
1173}
1174
1175impl Mul<Vec3> for Quat {
1176 type Output = Vec3;
1177 #[inline]
1183 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1184 fn mul(self, rhs: Vec3) -> Self::Output {
1185 self.mul_vec3(rhs)
1186 }
1187}
1188
1189impl Mul<&Vec3> for Quat {
1190 type Output = Vec3;
1191 #[inline]
1192 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1193 fn mul(self, rhs: &Vec3) -> Vec3 {
1194 self.mul(*rhs)
1195 }
1196}
1197
1198impl Mul<&Vec3> for &Quat {
1199 type Output = Vec3;
1200 #[inline]
1201 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1202 fn mul(self, rhs: &Vec3) -> Vec3 {
1203 (*self).mul(*rhs)
1204 }
1205}
1206
1207impl Mul<Vec3> for &Quat {
1208 type Output = Vec3;
1209 #[inline]
1210 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1211 fn mul(self, rhs: Vec3) -> Vec3 {
1212 (*self).mul(rhs)
1213 }
1214}
1215
1216impl Mul<Vec3A> for Quat {
1217 type Output = Vec3A;
1218 #[inline]
1224 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1225 fn mul(self, rhs: Vec3A) -> Self::Output {
1226 self.mul_vec3a(rhs)
1227 }
1228}
1229
1230impl Mul<&Vec3A> for Quat {
1231 type Output = Vec3A;
1232 #[inline]
1233 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1234 fn mul(self, rhs: &Vec3A) -> Vec3A {
1235 self.mul(*rhs)
1236 }
1237}
1238
1239impl Mul<&Vec3A> for &Quat {
1240 type Output = Vec3A;
1241 #[inline]
1242 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1243 fn mul(self, rhs: &Vec3A) -> Vec3A {
1244 (*self).mul(*rhs)
1245 }
1246}
1247
1248impl Mul<Vec3A> for &Quat {
1249 type Output = Vec3A;
1250 #[inline]
1251 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1252 fn mul(self, rhs: Vec3A) -> Vec3A {
1253 (*self).mul(rhs)
1254 }
1255}
1256
1257impl Neg for Quat {
1258 type Output = Self;
1259 #[inline]
1260 fn neg(self) -> Self {
1261 self * -1.0
1262 }
1263}
1264
1265impl Neg for &Quat {
1266 type Output = Quat;
1267 #[inline]
1268 fn neg(self) -> Quat {
1269 (*self).neg()
1270 }
1271}
1272
1273impl Default for Quat {
1274 #[inline]
1275 fn default() -> Self {
1276 Self::IDENTITY
1277 }
1278}
1279
1280impl PartialEq for Quat {
1281 #[inline]
1282 fn eq(&self, rhs: &Self) -> bool {
1283 Vec4::from(*self).eq(&Vec4::from(*rhs))
1284 }
1285}
1286
1287impl AsRef<[f32; 4]> for Quat {
1288 #[inline]
1289 fn as_ref(&self) -> &[f32; 4] {
1290 unsafe { &*(self as *const Self as *const [f32; 4]) }
1291 }
1292}
1293
1294impl Sum<Self> for Quat {
1295 fn sum<I>(iter: I) -> Self
1296 where
1297 I: Iterator<Item = Self>,
1298 {
1299 iter.fold(Self::ZERO, Self::add)
1300 }
1301}
1302
1303impl<'a> Sum<&'a Self> for Quat {
1304 fn sum<I>(iter: I) -> Self
1305 where
1306 I: Iterator<Item = &'a Self>,
1307 {
1308 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1309 }
1310}
1311
1312impl Product for Quat {
1313 fn product<I>(iter: I) -> Self
1314 where
1315 I: Iterator<Item = Self>,
1316 {
1317 iter.fold(Self::IDENTITY, Self::mul)
1318 }
1319}
1320
1321impl<'a> Product<&'a Self> for Quat {
1322 fn product<I>(iter: I) -> Self
1323 where
1324 I: Iterator<Item = &'a Self>,
1325 {
1326 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1327 }
1328}
1329
1330impl From<Quat> for Vec4 {
1331 #[inline]
1332 fn from(q: Quat) -> Self {
1333 Self(q.0)
1334 }
1335}
1336
1337impl From<Quat> for (f32, f32, f32, f32) {
1338 #[inline]
1339 fn from(q: Quat) -> Self {
1340 Vec4::from(q).into()
1341 }
1342}
1343
1344impl From<Quat> for [f32; 4] {
1345 #[inline]
1346 fn from(q: Quat) -> Self {
1347 Vec4::from(q).into()
1348 }
1349}
1350
1351impl From<Quat> for float32x4_t {
1352 #[inline]
1353 fn from(q: Quat) -> Self {
1354 q.0
1355 }
1356}
1357
1358impl Deref for Quat {
1359 type Target = crate::deref::Vec4<f32>;
1360 #[inline]
1361 fn deref(&self) -> &Self::Target {
1362 unsafe { &*(self as *const Self).cast() }
1363 }
1364}
1365
1366impl DerefMut for Quat {
1367 #[inline]
1368 fn deref_mut(&mut self) -> &mut Self::Target {
1369 unsafe { &mut *(self as *mut Self).cast() }
1370 }
1371}