1use crate::{
4 Mat3, Mat3A, Mat4, Vec2, Vec3, Vec3A, Vec4,
5 euler::{EulerRot, FromEuler, ToEuler},
6 f32::math,
7 sse2::*,
8};
9
10#[cfg(feature = "f64")]
11use crate::DQuat;
12
13#[cfg(target_arch = "x86")]
14use core::arch::x86::*;
15#[cfg(target_arch = "x86_64")]
16use core::arch::x86_64::*;
17
18use core::fmt;
19use core::iter::{Product, Sum};
20use core::ops::{
21 Add, AddAssign, Deref, DerefMut, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign,
22};
23
24#[cfg(feature = "zerocopy-08")]
25use zerocopy_derive_08::*;
26
27#[repr(C)]
28union UnionCast {
29 a: [f32; 4],
30 v: Quat,
31}
32
33#[inline]
38#[must_use]
39pub const fn quat(x: f32, y: f32, z: f32, w: f32) -> Quat {
40 Quat::from_xyzw(x, y, z, w)
41}
42
43#[derive(Clone, Copy)]
53#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
54#[cfg_attr(
55 feature = "zerocopy-08",
56 derive(FromBytes, Immutable, IntoBytes, KnownLayout)
57)]
58#[repr(transparent)]
59pub struct Quat(pub(crate) __m128);
60
61impl Quat {
62 const ZERO: Self = Self::from_array([0.0; 4]);
64
65 pub const IDENTITY: Self = Self::from_xyzw(0.0, 0.0, 0.0, 1.0);
67
68 pub const NAN: Self = Self::from_array([f32::NAN; 4]);
70
71 #[inline(always)]
83 #[must_use]
84 pub const fn from_xyzw(x: f32, y: f32, z: f32, w: f32) -> Self {
85 unsafe { UnionCast { a: [x, y, z, w] }.v }
86 }
87
88 #[inline]
95 #[must_use]
96 pub const fn from_array(a: [f32; 4]) -> Self {
97 Self::from_xyzw(a[0], a[1], a[2], a[3])
98 }
99
100 #[inline]
107 #[must_use]
108 pub const fn from_vec4(v: Vec4) -> Self {
109 Self(v.0)
110 }
111
112 #[inline]
123 #[must_use]
124 #[track_caller]
125 pub fn from_slice(slice: &[f32]) -> Self {
126 assert!(slice.len() >= 4);
127 Self(unsafe { _mm_loadu_ps(slice.as_ptr()) })
128 }
129
130 #[inline]
136 #[track_caller]
137 pub fn write_to_slice(self, slice: &mut [f32]) {
138 assert!(slice.len() >= 4);
139 unsafe { _mm_storeu_ps(slice.as_mut_ptr(), self.0) }
140 }
141
142 #[inline]
150 #[must_use]
151 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
152 pub fn from_axis_angle(axis: Vec3, angle: f32) -> Self {
153 glam_assert!(axis.is_normalized());
154 let (s, c) = math::sin_cos(angle * 0.5);
155 let v = axis * s;
156 Self::from_xyzw(v.x, v.y, v.z, c)
157 }
158
159 #[inline]
167 #[must_use]
168 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
169 pub fn from_scaled_axis(v: Vec3) -> Self {
170 let length = v.length();
171 if length == 0.0 {
172 Self::IDENTITY
173 } else {
174 Self::from_axis_angle(v / length, length)
175 }
176 }
177
178 #[inline]
180 #[must_use]
181 pub fn from_rotation_x(angle: f32) -> Self {
182 let (s, c) = math::sin_cos(angle * 0.5);
183 Self::from_xyzw(s, 0.0, 0.0, c)
184 }
185
186 #[inline]
188 #[must_use]
189 pub fn from_rotation_y(angle: f32) -> Self {
190 let (s, c) = math::sin_cos(angle * 0.5);
191 Self::from_xyzw(0.0, s, 0.0, c)
192 }
193
194 #[inline]
196 #[must_use]
197 pub fn from_rotation_z(angle: f32) -> Self {
198 let (s, c) = math::sin_cos(angle * 0.5);
199 Self::from_xyzw(0.0, 0.0, s, c)
200 }
201
202 #[inline]
204 #[must_use]
205 pub fn from_euler(euler: EulerRot, a: f32, b: f32, c: f32) -> Self {
206 Self::from_euler_angles(euler, a, b, c)
207 }
208
209 #[inline]
218 #[must_use]
219 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
220 pub fn from_rotation_axes(x_axis: Vec3, y_axis: Vec3, z_axis: Vec3) -> Self {
221 glam_assert!(x_axis.is_normalized() && y_axis.is_normalized() && z_axis.is_normalized());
222 let (m00, m01, m02) = x_axis.into();
224 let (m10, m11, m12) = y_axis.into();
225 let (m20, m21, m22) = z_axis.into();
226 if m22 <= 0.0 {
227 let dif10 = m11 - m00;
229 let omm22 = 1.0 - m22;
230 if dif10 <= 0.0 {
231 let four_xsq = omm22 - dif10;
233 let inv4x = 0.5 / math::sqrt(four_xsq);
234 Self::from_xyzw(
235 four_xsq * inv4x,
236 (m01 + m10) * inv4x,
237 (m02 + m20) * inv4x,
238 (m12 - m21) * inv4x,
239 )
240 } else {
241 let four_ysq = omm22 + dif10;
243 let inv4y = 0.5 / math::sqrt(four_ysq);
244 Self::from_xyzw(
245 (m01 + m10) * inv4y,
246 four_ysq * inv4y,
247 (m12 + m21) * inv4y,
248 (m20 - m02) * inv4y,
249 )
250 }
251 } else {
252 let sum10 = m11 + m00;
254 let opm22 = 1.0 + m22;
255 if sum10 <= 0.0 {
256 let four_zsq = opm22 - sum10;
258 let inv4z = 0.5 / math::sqrt(four_zsq);
259 Self::from_xyzw(
260 (m02 + m20) * inv4z,
261 (m12 + m21) * inv4z,
262 four_zsq * inv4z,
263 (m01 - m10) * inv4z,
264 )
265 } else {
266 let four_wsq = opm22 + sum10;
268 let inv4w = 0.5 / math::sqrt(four_wsq);
269 Self::from_xyzw(
270 (m12 - m21) * inv4w,
271 (m20 - m02) * inv4w,
272 (m01 - m10) * inv4w,
273 four_wsq * inv4w,
274 )
275 }
276 }
277 }
278
279 #[inline]
288 #[must_use]
289 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
290 pub fn from_mat3(mat: &Mat3) -> Self {
291 Self::from_rotation_axes(mat.x_axis, mat.y_axis, mat.z_axis)
292 }
293
294 #[inline]
303 #[must_use]
304 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
305 pub fn from_mat3a(mat: &Mat3A) -> Self {
306 Self::from_rotation_axes(mat.x_axis.into(), mat.y_axis.into(), mat.z_axis.into())
307 }
308
309 #[inline]
319 #[must_use]
320 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
321 pub fn from_mat4(mat: &Mat4) -> Self {
322 Self::from_rotation_axes(
323 mat.x_axis.truncate(),
324 mat.y_axis.truncate(),
325 mat.z_axis.truncate(),
326 )
327 }
328
329 #[must_use]
343 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
344 pub fn from_rotation_arc(from: Vec3, to: Vec3) -> Self {
345 glam_assert!(from.is_normalized());
346 glam_assert!(to.is_normalized());
347
348 const ONE_MINUS_EPS: f32 = 1.0 - 2.0 * f32::EPSILON;
349 let dot = from.dot(to);
350 if dot > ONE_MINUS_EPS {
351 Self::IDENTITY
353 } else if dot < -ONE_MINUS_EPS {
354 use core::f32::consts::PI; Self::from_axis_angle(from.any_orthonormal_vector(), PI)
357 } else {
358 let c = from.cross(to);
359 Self::from_xyzw(c.x, c.y, c.z, 1.0 + dot).normalize()
360 }
361 }
362
363 #[inline]
377 #[must_use]
378 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
379 pub fn from_rotation_arc_colinear(from: Vec3, to: Vec3) -> Self {
380 if from.dot(to) < 0.0 {
381 Self::from_rotation_arc(from, -to)
382 } else {
383 Self::from_rotation_arc(from, to)
384 }
385 }
386
387 #[must_use]
401 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
402 pub fn from_rotation_arc_2d(from: Vec2, to: Vec2) -> Self {
403 glam_assert!(from.is_normalized());
404 glam_assert!(to.is_normalized());
405
406 const ONE_MINUS_EPSILON: f32 = 1.0 - 2.0 * f32::EPSILON;
407 let dot = from.dot(to);
408 if dot > ONE_MINUS_EPSILON {
409 Self::IDENTITY
411 } else if dot < -ONE_MINUS_EPSILON {
412 const COS_FRAC_PI_2: f32 = 0.0;
414 const SIN_FRAC_PI_2: f32 = 1.0;
415 Self::from_xyzw(0.0, 0.0, SIN_FRAC_PI_2, COS_FRAC_PI_2)
417 } else {
418 let z = from.x * to.y - to.x * from.y;
420 let w = 1.0 + dot;
421 let len_rcp = 1.0 / math::sqrt(z * z + w * w);
423 Self::from_xyzw(0.0, 0.0, z * len_rcp, w * len_rcp)
424 }
425 }
426
427 #[inline]
429 #[must_use]
430 pub fn to_axis_angle(self) -> (Vec3, f32) {
431 const EPSILON: f32 = 1.0e-8;
432 let v = Vec3::new(self.x, self.y, self.z);
433 let length = v.length();
434 if length >= EPSILON {
435 let angle = 2.0 * math::atan2(length, self.w);
436 let axis = v / length;
437 (axis, angle)
438 } else {
439 (Vec3::X, 0.0)
440 }
441 }
442
443 #[inline]
445 #[must_use]
446 pub fn to_scaled_axis(self) -> Vec3 {
447 let (axis, angle) = self.to_axis_angle();
448 axis * angle
449 }
450
451 #[inline]
457 #[must_use]
458 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
459 pub fn to_euler(self, order: EulerRot) -> (f32, f32, f32) {
460 Mat3::from_quat(self).to_euler_angles(order)
461 }
462
463 #[inline]
465 #[must_use]
466 pub const fn to_array(&self) -> [f32; 4] {
467 unsafe { *(self as *const Self as *const [f32; 4]) }
468 }
469
470 #[inline]
472 #[must_use]
473 pub fn xyz(self) -> Vec3 {
474 Vec3::new(self.x, self.y, self.z)
475 }
476
477 #[inline]
480 #[must_use]
481 pub fn conjugate(self) -> Self {
482 const SIGN: __m128 = m128_from_f32x4([-0.0, -0.0, -0.0, 0.0]);
483 Self(unsafe { _mm_xor_ps(self.0, SIGN) })
484 }
485
486 #[inline]
496 #[must_use]
497 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
498 pub fn inverse(self) -> Self {
499 glam_assert!(self.is_normalized());
500 self.conjugate()
501 }
502
503 #[inline]
506 #[must_use]
507 pub fn dot(self, rhs: Self) -> f32 {
508 Vec4::from(self).dot(Vec4::from(rhs))
509 }
510
511 #[doc(alias = "magnitude")]
513 #[inline]
514 #[must_use]
515 pub fn length(self) -> f32 {
516 Vec4::from(self).length()
517 }
518
519 #[doc(alias = "magnitude2")]
524 #[inline]
525 #[must_use]
526 pub fn length_squared(self) -> f32 {
527 Vec4::from(self).length_squared()
528 }
529
530 #[inline]
534 #[must_use]
535 pub fn length_recip(self) -> f32 {
536 Vec4::from(self).length_recip()
537 }
538
539 #[inline]
547 #[must_use]
548 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
549 pub fn normalize(self) -> Self {
550 Self::from_vec4(Vec4::from(self).normalize())
551 }
552
553 #[inline]
556 #[must_use]
557 pub fn is_finite(self) -> bool {
558 Vec4::from(self).is_finite()
559 }
560
561 #[inline]
563 #[must_use]
564 pub fn is_nan(self) -> bool {
565 Vec4::from(self).is_nan()
566 }
567
568 #[inline]
572 #[must_use]
573 pub fn is_normalized(self) -> bool {
574 Vec4::from(self).is_normalized()
575 }
576
577 #[inline]
579 #[must_use]
580 pub fn is_near_identity(self) -> bool {
581 const THRESHOLD: f32 = 1.0 - 1e-6;
586 self.w.abs() > THRESHOLD
587 }
588
589 #[inline]
598 #[must_use]
599 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
600 pub fn angle_between(self, rhs: Self) -> f32 {
601 glam_assert!(self.is_normalized() && rhs.is_normalized());
602 math::acos_approx(self.dot(rhs).abs()) * 2.0
603 }
604
605 #[inline]
617 #[must_use]
618 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
619 pub fn rotate_towards(self, rhs: Self, max_angle: f32) -> Self {
620 glam_assert!(self.is_normalized() && rhs.is_normalized());
621 let angle = self.angle_between(rhs);
622 if angle <= 1e-4 {
623 return rhs;
624 }
625 if max_angle < 0.0 {
626 let target = (self - rhs * self.dot(rhs)).normalize();
628 let angle = self.angle_between(target);
629 if angle <= 1e-4 {
630 return target;
631 }
632 return self.slerp(target, (-max_angle / angle).clamp(0.0, 1.0));
633 }
634 self.slerp(rhs, (max_angle / angle).clamp(0.0, 1.0))
635 }
636
637 #[inline]
647 #[must_use]
648 pub fn abs_diff_eq(self, rhs: Self, max_abs_diff: f32) -> bool {
649 Vec4::from(self).abs_diff_eq(Vec4::from(rhs), max_abs_diff)
650 }
651
652 #[inline(always)]
653 #[must_use]
654 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
655 fn lerp_impl(self, end: Self, s: f32) -> Self {
656 (self * (1.0 - s) + end * s).normalize()
657 }
658
659 #[doc(alias = "mix")]
672 #[inline]
673 #[must_use]
674 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
675 pub fn lerp(self, end: Self, s: f32) -> Self {
676 glam_assert!(self.is_normalized());
677 glam_assert!(end.is_normalized());
678
679 const NEG_ZERO: __m128 = m128_from_f32x4([-0.0; 4]);
680 unsafe {
681 let dot = dot4_into_m128(self.0, end.0);
682 let bias = _mm_and_ps(dot, NEG_ZERO);
685 self.lerp_impl(Self(_mm_xor_ps(end.0, bias)), s)
686 }
687 }
688
689 #[inline(always)]
690 #[must_use]
691 fn slerp_impl(self, end: Self, dot: f32, s: f32) -> Self {
692 let theta = math::acos_approx(dot);
693
694 let x = 1.0 - s;
695 let y = s;
696 let z = 1.0;
697
698 unsafe {
699 let tmp = _mm_mul_ps(_mm_set_ps1(theta), _mm_set_ps(0.0, z, y, x));
700 let tmp = m128_sin(tmp);
701
702 let scale1 = _mm_shuffle_ps(tmp, tmp, 0b00_00_00_00);
703 let scale2 = _mm_shuffle_ps(tmp, tmp, 0b01_01_01_01);
704 let theta_sin = _mm_shuffle_ps(tmp, tmp, 0b10_10_10_10);
705
706 Self(_mm_div_ps(
707 m128_mul_add(end.0, scale2, _mm_mul_ps(self.0, scale1)),
708 theta_sin,
709 ))
710 }
711 }
712
713 #[inline]
723 #[must_use]
724 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
725 pub fn slerp(self, mut end: Self, s: f32) -> Self {
726 glam_assert!(self.is_normalized());
728 glam_assert!(end.is_normalized());
729
730 let mut dot = self.dot(end);
737 if dot < 0.0 {
738 end = -end;
739 dot = -dot;
740 }
741
742 const DOT_THRESHOLD: f32 = 1.0 - f32::EPSILON;
743 if dot > DOT_THRESHOLD {
744 self.lerp_impl(end, s)
746 } else {
747 self.slerp_impl(end, dot, s)
748 }
749 }
750
751 #[inline]
765 #[must_use]
766 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
767 pub fn slerp_long(self, end: Self, s: f32) -> Self {
768 glam_assert!(self.is_normalized());
769 glam_assert!(end.is_normalized());
770
771 let dot = self.dot(end);
772
773 const DOT_THRESHOLD: f32 = 1.0 - f32::EPSILON;
774 if dot.abs() > DOT_THRESHOLD {
775 self.lerp_impl(end, s)
777 } else {
778 self.slerp_impl(end, dot, s)
779 }
780 }
781
782 #[inline]
788 #[must_use]
789 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
790 pub fn mul_vec3(self, rhs: Vec3) -> Vec3 {
791 glam_assert!(self.is_normalized());
792
793 self.mul_vec3a(rhs.into()).into()
794 }
795
796 #[inline]
801 #[must_use]
802 pub fn mul_quat(self, rhs: Self) -> Self {
803 const CONTROL_WZYX: __m128 = m128_from_f32x4([1.0, -1.0, 1.0, -1.0]);
805 const CONTROL_ZWXY: __m128 = m128_from_f32x4([1.0, 1.0, -1.0, -1.0]);
806 const CONTROL_YXWZ: __m128 = m128_from_f32x4([-1.0, 1.0, 1.0, -1.0]);
807
808 let lhs = self.0;
809 let rhs = rhs.0;
810
811 unsafe {
812 let r_xxxx = _mm_shuffle_ps(lhs, lhs, 0b00_00_00_00);
813 let r_yyyy = _mm_shuffle_ps(lhs, lhs, 0b01_01_01_01);
814 let r_zzzz = _mm_shuffle_ps(lhs, lhs, 0b10_10_10_10);
815 let r_wwww = _mm_shuffle_ps(lhs, lhs, 0b11_11_11_11);
816
817 let lxrw_lyrw_lzrw_lwrw = _mm_mul_ps(r_wwww, rhs);
818 let l_wzyx = _mm_shuffle_ps(rhs, rhs, 0b00_01_10_11);
819
820 let lwrx_lzrx_lyrx_lxrx = _mm_mul_ps(r_xxxx, l_wzyx);
821 let l_zwxy = _mm_shuffle_ps(l_wzyx, l_wzyx, 0b10_11_00_01);
822
823 let lzry_lwry_lxry_lyry = _mm_mul_ps(r_yyyy, l_zwxy);
824 let l_yxwz = _mm_shuffle_ps(l_zwxy, l_zwxy, 0b00_01_10_11);
825
826 let lzry_lwry_nlxry_nlyry = _mm_mul_ps(lzry_lwry_lxry_lyry, CONTROL_ZWXY);
827
828 let lyrz_lxrz_lwrz_lzrz = _mm_mul_ps(r_zzzz, l_yxwz);
829 let result0 = m128_mul_add(lwrx_lzrx_lyrx_lxrx, CONTROL_WZYX, lxrw_lyrw_lzrw_lwrw);
830
831 let result1 = m128_mul_add(lyrz_lxrz_lwrz_lzrz, CONTROL_YXWZ, lzry_lwry_nlxry_nlyry);
832
833 Self(_mm_add_ps(result0, result1))
834 }
835 }
836
837 #[inline]
847 #[must_use]
848 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
849 pub fn from_affine3(a: &crate::Affine3) -> Self {
850 Self::from_rotation_axes(a.matrix3.x_axis, a.matrix3.y_axis, a.matrix3.z_axis)
851 }
852
853 #[inline]
863 #[must_use]
864 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
865 pub fn from_affine3a(a: &crate::Affine3A) -> Self {
866 Self::from_rotation_axes(
867 a.matrix3.x_axis.into(),
868 a.matrix3.y_axis.into(),
869 a.matrix3.z_axis.into(),
870 )
871 }
872
873 #[inline]
879 #[must_use]
880 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
881 pub fn mul_vec3a(self, rhs: Vec3A) -> Vec3A {
882 glam_assert!(self.is_normalized());
883
884 unsafe {
885 const TWO: __m128 = m128_from_f32x4([2.0; 4]);
886 let w = _mm_shuffle_ps(self.0, self.0, 0b11_11_11_11);
887 let b = self.0;
888 let b2 = dot3_into_m128(b, b);
889 Vec3A(_mm_add_ps(
890 _mm_add_ps(
891 _mm_mul_ps(rhs.0, _mm_sub_ps(_mm_mul_ps(w, w), b2)),
892 _mm_mul_ps(b, _mm_mul_ps(dot3_into_m128(rhs.0, b), TWO)),
893 ),
894 _mm_mul_ps(Vec3A(b).cross(rhs).into(), _mm_mul_ps(w, TWO)),
895 ))
896 }
897 }
898
899 #[cfg(feature = "f64")]
900 #[inline]
901 #[must_use]
902 pub fn as_dquat(self) -> DQuat {
903 DQuat::from_xyzw(self.x as f64, self.y as f64, self.z as f64, self.w as f64)
904 }
905}
906
907impl fmt::Debug for Quat {
908 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
909 fmt.debug_tuple(stringify!(Quat))
910 .field(&self.x)
911 .field(&self.y)
912 .field(&self.z)
913 .field(&self.w)
914 .finish()
915 }
916}
917
918impl fmt::Display for Quat {
919 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
920 if let Some(p) = f.precision() {
921 write!(
922 f,
923 "[{:.*}, {:.*}, {:.*}, {:.*}]",
924 p, self.x, p, self.y, p, self.z, p, self.w
925 )
926 } else {
927 write!(f, "[{}, {}, {}, {}]", self.x, self.y, self.z, self.w)
928 }
929 }
930}
931
932impl Add for Quat {
933 type Output = Self;
934 #[inline]
941 fn add(self, rhs: Self) -> Self {
942 Self::from_vec4(Vec4::from(self) + Vec4::from(rhs))
943 }
944}
945
946impl Add<&Self> for Quat {
947 type Output = Self;
948 #[inline]
949 fn add(self, rhs: &Self) -> Self {
950 self.add(*rhs)
951 }
952}
953
954impl Add<&Quat> for &Quat {
955 type Output = Quat;
956 #[inline]
957 fn add(self, rhs: &Quat) -> Quat {
958 (*self).add(*rhs)
959 }
960}
961
962impl Add<Quat> for &Quat {
963 type Output = Quat;
964 #[inline]
965 fn add(self, rhs: Quat) -> Quat {
966 (*self).add(rhs)
967 }
968}
969
970impl AddAssign for Quat {
971 #[inline]
972 fn add_assign(&mut self, rhs: Self) {
973 *self = self.add(rhs);
974 }
975}
976
977impl AddAssign<&Self> for Quat {
978 #[inline]
979 fn add_assign(&mut self, rhs: &Self) {
980 self.add_assign(*rhs);
981 }
982}
983
984impl Sub for Quat {
985 type Output = Self;
986 #[inline]
990 fn sub(self, rhs: Self) -> Self {
991 Self::from_vec4(Vec4::from(self) - Vec4::from(rhs))
992 }
993}
994
995impl Sub<&Self> for Quat {
996 type Output = Self;
997 #[inline]
998 fn sub(self, rhs: &Self) -> Self {
999 self.sub(*rhs)
1000 }
1001}
1002
1003impl Sub<&Quat> for &Quat {
1004 type Output = Quat;
1005 #[inline]
1006 fn sub(self, rhs: &Quat) -> Quat {
1007 (*self).sub(*rhs)
1008 }
1009}
1010
1011impl Sub<Quat> for &Quat {
1012 type Output = Quat;
1013 #[inline]
1014 fn sub(self, rhs: Quat) -> Quat {
1015 (*self).sub(rhs)
1016 }
1017}
1018
1019impl SubAssign for Quat {
1020 #[inline]
1021 fn sub_assign(&mut self, rhs: Self) {
1022 *self = self.sub(rhs);
1023 }
1024}
1025
1026impl SubAssign<&Self> for Quat {
1027 #[inline]
1028 fn sub_assign(&mut self, rhs: &Self) {
1029 self.sub_assign(*rhs);
1030 }
1031}
1032
1033impl Mul<f32> for Quat {
1034 type Output = Self;
1035 #[inline]
1039 fn mul(self, rhs: f32) -> Self {
1040 Self::from_vec4(Vec4::from(self) * rhs)
1041 }
1042}
1043
1044impl Mul<&f32> for Quat {
1045 type Output = Self;
1046 #[inline]
1047 fn mul(self, rhs: &f32) -> Self {
1048 self.mul(*rhs)
1049 }
1050}
1051
1052impl Mul<&f32> for &Quat {
1053 type Output = Quat;
1054 #[inline]
1055 fn mul(self, rhs: &f32) -> Quat {
1056 (*self).mul(*rhs)
1057 }
1058}
1059
1060impl Mul<f32> for &Quat {
1061 type Output = Quat;
1062 #[inline]
1063 fn mul(self, rhs: f32) -> Quat {
1064 (*self).mul(rhs)
1065 }
1066}
1067
1068impl MulAssign<f32> for Quat {
1069 #[inline]
1070 fn mul_assign(&mut self, rhs: f32) {
1071 *self = self.mul(rhs);
1072 }
1073}
1074
1075impl MulAssign<&f32> for Quat {
1076 #[inline]
1077 fn mul_assign(&mut self, rhs: &f32) {
1078 self.mul_assign(*rhs);
1079 }
1080}
1081
1082impl Div<f32> for Quat {
1083 type Output = Self;
1084 #[inline]
1087 fn div(self, rhs: f32) -> Self {
1088 Self::from_vec4(Vec4::from(self) / rhs)
1089 }
1090}
1091
1092impl Div<&f32> for Quat {
1093 type Output = Self;
1094 #[inline]
1095 fn div(self, rhs: &f32) -> Self {
1096 self.div(*rhs)
1097 }
1098}
1099
1100impl Div<&f32> for &Quat {
1101 type Output = Quat;
1102 #[inline]
1103 fn div(self, rhs: &f32) -> Quat {
1104 (*self).div(*rhs)
1105 }
1106}
1107
1108impl Div<f32> for &Quat {
1109 type Output = Quat;
1110 #[inline]
1111 fn div(self, rhs: f32) -> Quat {
1112 (*self).div(rhs)
1113 }
1114}
1115
1116impl DivAssign<f32> for Quat {
1117 #[inline]
1118 fn div_assign(&mut self, rhs: f32) {
1119 *self = self.div(rhs);
1120 }
1121}
1122
1123impl DivAssign<&f32> for Quat {
1124 #[inline]
1125 fn div_assign(&mut self, rhs: &f32) {
1126 self.div_assign(*rhs);
1127 }
1128}
1129
1130impl Mul for Quat {
1131 type Output = Self;
1132 #[inline]
1138 fn mul(self, rhs: Self) -> Self {
1139 self.mul_quat(rhs)
1140 }
1141}
1142
1143impl Mul<&Self> for Quat {
1144 type Output = Self;
1145 #[inline]
1146 fn mul(self, rhs: &Self) -> Self {
1147 self.mul(*rhs)
1148 }
1149}
1150
1151impl Mul<&Quat> for &Quat {
1152 type Output = Quat;
1153 #[inline]
1154 fn mul(self, rhs: &Quat) -> Quat {
1155 (*self).mul(*rhs)
1156 }
1157}
1158
1159impl Mul<Quat> for &Quat {
1160 type Output = Quat;
1161 #[inline]
1162 fn mul(self, rhs: Quat) -> Quat {
1163 (*self).mul(rhs)
1164 }
1165}
1166
1167impl MulAssign for Quat {
1168 #[inline]
1169 fn mul_assign(&mut self, rhs: Self) {
1170 *self = self.mul(rhs);
1171 }
1172}
1173
1174impl MulAssign<&Self> for Quat {
1175 #[inline]
1176 fn mul_assign(&mut self, rhs: &Self) {
1177 self.mul_assign(*rhs);
1178 }
1179}
1180
1181impl Mul<Vec3> for Quat {
1182 type Output = Vec3;
1183 #[inline]
1189 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1190 fn mul(self, rhs: Vec3) -> Self::Output {
1191 self.mul_vec3(rhs)
1192 }
1193}
1194
1195impl Mul<&Vec3> for Quat {
1196 type Output = Vec3;
1197 #[inline]
1198 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1199 fn mul(self, rhs: &Vec3) -> Vec3 {
1200 self.mul(*rhs)
1201 }
1202}
1203
1204impl Mul<&Vec3> for &Quat {
1205 type Output = Vec3;
1206 #[inline]
1207 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1208 fn mul(self, rhs: &Vec3) -> Vec3 {
1209 (*self).mul(*rhs)
1210 }
1211}
1212
1213impl Mul<Vec3> for &Quat {
1214 type Output = Vec3;
1215 #[inline]
1216 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1217 fn mul(self, rhs: Vec3) -> Vec3 {
1218 (*self).mul(rhs)
1219 }
1220}
1221
1222impl Mul<Vec3A> for Quat {
1223 type Output = Vec3A;
1224 #[inline]
1230 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1231 fn mul(self, rhs: Vec3A) -> Self::Output {
1232 self.mul_vec3a(rhs)
1233 }
1234}
1235
1236impl Mul<&Vec3A> for Quat {
1237 type Output = Vec3A;
1238 #[inline]
1239 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1240 fn mul(self, rhs: &Vec3A) -> Vec3A {
1241 self.mul(*rhs)
1242 }
1243}
1244
1245impl Mul<&Vec3A> for &Quat {
1246 type Output = Vec3A;
1247 #[inline]
1248 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1249 fn mul(self, rhs: &Vec3A) -> Vec3A {
1250 (*self).mul(*rhs)
1251 }
1252}
1253
1254impl Mul<Vec3A> for &Quat {
1255 type Output = Vec3A;
1256 #[inline]
1257 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1258 fn mul(self, rhs: Vec3A) -> Vec3A {
1259 (*self).mul(rhs)
1260 }
1261}
1262
1263impl Neg for Quat {
1264 type Output = Self;
1265 #[inline]
1266 fn neg(self) -> Self {
1267 self * -1.0
1268 }
1269}
1270
1271impl Neg for &Quat {
1272 type Output = Quat;
1273 #[inline]
1274 fn neg(self) -> Quat {
1275 (*self).neg()
1276 }
1277}
1278
1279impl Default for Quat {
1280 #[inline]
1281 fn default() -> Self {
1282 Self::IDENTITY
1283 }
1284}
1285
1286impl PartialEq for Quat {
1287 #[inline]
1288 fn eq(&self, rhs: &Self) -> bool {
1289 Vec4::from(*self).eq(&Vec4::from(*rhs))
1290 }
1291}
1292
1293impl AsRef<[f32; 4]> for Quat {
1294 #[inline]
1295 fn as_ref(&self) -> &[f32; 4] {
1296 unsafe { &*(self as *const Self as *const [f32; 4]) }
1297 }
1298}
1299
1300impl Sum<Self> for Quat {
1301 fn sum<I>(iter: I) -> Self
1302 where
1303 I: Iterator<Item = Self>,
1304 {
1305 iter.fold(Self::ZERO, Self::add)
1306 }
1307}
1308
1309impl<'a> Sum<&'a Self> for Quat {
1310 fn sum<I>(iter: I) -> Self
1311 where
1312 I: Iterator<Item = &'a Self>,
1313 {
1314 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1315 }
1316}
1317
1318impl Product for Quat {
1319 fn product<I>(iter: I) -> Self
1320 where
1321 I: Iterator<Item = Self>,
1322 {
1323 iter.fold(Self::IDENTITY, Self::mul)
1324 }
1325}
1326
1327impl<'a> Product<&'a Self> for Quat {
1328 fn product<I>(iter: I) -> Self
1329 where
1330 I: Iterator<Item = &'a Self>,
1331 {
1332 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1333 }
1334}
1335
1336impl From<Quat> for Vec4 {
1337 #[inline]
1338 fn from(q: Quat) -> Self {
1339 Self(q.0)
1340 }
1341}
1342
1343impl From<Quat> for (f32, f32, f32, f32) {
1344 #[inline]
1345 fn from(q: Quat) -> Self {
1346 Vec4::from(q).into()
1347 }
1348}
1349
1350impl From<Quat> for [f32; 4] {
1351 #[inline]
1352 fn from(q: Quat) -> Self {
1353 Vec4::from(q).into()
1354 }
1355}
1356
1357impl From<Quat> for __m128 {
1358 #[inline]
1359 fn from(q: Quat) -> Self {
1360 q.0
1361 }
1362}
1363
1364impl Deref for Quat {
1365 type Target = crate::deref::Vec4<f32>;
1366 #[inline]
1367 fn deref(&self) -> &Self::Target {
1368 unsafe { &*(self as *const Self).cast() }
1369 }
1370}
1371
1372impl DerefMut for Quat {
1373 #[inline]
1374 fn deref_mut(&mut self) -> &mut Self::Target {
1375 unsafe { &mut *(self as *mut Self).cast() }
1376 }
1377}