1use crate::{
4 euler::{EulerRot, FromEuler, ToEuler},
5 f32::math,
6 sse2::*,
7 Mat3, Mat3A, Mat4, Vec2, Vec3, Vec3A, Vec4,
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 #[deprecated(
436 since = "0.33.1",
437 note = "use the `glam::camera::lh::view::look_to_quat` function instead"
438 )]
439 #[inline]
440 #[must_use]
441 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
442 pub fn look_to_lh(dir: Vec3, up: Vec3) -> Self {
443 #[allow(deprecated)]
444 Self::look_to_rh(-dir, up)
445 }
446
447 #[deprecated(
456 since = "0.33.1",
457 note = "use the `glam::camera::rh::view::look_to_quat` function instead"
458 )]
459 #[inline]
460 #[must_use]
461 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
462 pub fn look_to_rh(dir: Vec3, up: Vec3) -> Self {
463 glam_assert!(dir.is_normalized());
464 glam_assert!(up.is_normalized());
465 let f = dir;
466 let s = f.cross(up).normalize();
467 let u = s.cross(f);
468
469 Self::from_rotation_axes(
470 Vec3::new(s.x, u.x, -f.x),
471 Vec3::new(s.y, u.y, -f.y),
472 Vec3::new(s.z, u.z, -f.z),
473 )
474 }
475
476 #[deprecated(
486 since = "0.33.1",
487 note = "use the `glam::camera::lh::view::look_at_quat` function instead"
488 )]
489 #[inline]
490 #[must_use]
491 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
492 pub fn look_at_lh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
493 #[allow(deprecated)]
494 Self::look_to_lh(center.sub(eye).normalize(), up)
495 }
496
497 #[deprecated(
507 since = "0.33.1",
508 note = "use the `glam::camera::rh::view::look_at_quat` function instead"
509 )]
510 #[inline]
511 #[must_use]
512 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
513 pub fn look_at_rh(eye: Vec3, center: Vec3, up: Vec3) -> Self {
514 #[allow(deprecated)]
515 Self::look_to_rh(center.sub(eye).normalize(), up)
516 }
517
518 #[inline]
520 #[must_use]
521 pub fn to_axis_angle(self) -> (Vec3, f32) {
522 const EPSILON: f32 = 1.0e-8;
523 let v = Vec3::new(self.x, self.y, self.z);
524 let length = v.length();
525 if length >= EPSILON {
526 let angle = 2.0 * math::atan2(length, self.w);
527 let axis = v / length;
528 (axis, angle)
529 } else {
530 (Vec3::X, 0.0)
531 }
532 }
533
534 #[inline]
536 #[must_use]
537 pub fn to_scaled_axis(self) -> Vec3 {
538 let (axis, angle) = self.to_axis_angle();
539 axis * angle
540 }
541
542 #[inline]
548 #[must_use]
549 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
550 pub fn to_euler(self, order: EulerRot) -> (f32, f32, f32) {
551 Mat3::from_quat(self).to_euler_angles(order)
552 }
553
554 #[inline]
556 #[must_use]
557 pub const fn to_array(&self) -> [f32; 4] {
558 unsafe { *(self as *const Self as *const [f32; 4]) }
559 }
560
561 #[inline]
563 #[must_use]
564 pub fn xyz(self) -> Vec3 {
565 Vec3::new(self.x, self.y, self.z)
566 }
567
568 #[inline]
571 #[must_use]
572 pub fn conjugate(self) -> Self {
573 const SIGN: __m128 = m128_from_f32x4([-0.0, -0.0, -0.0, 0.0]);
574 Self(unsafe { _mm_xor_ps(self.0, SIGN) })
575 }
576
577 #[inline]
587 #[must_use]
588 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
589 pub fn inverse(self) -> Self {
590 glam_assert!(self.is_normalized());
591 self.conjugate()
592 }
593
594 #[inline]
597 #[must_use]
598 pub fn dot(self, rhs: Self) -> f32 {
599 Vec4::from(self).dot(Vec4::from(rhs))
600 }
601
602 #[doc(alias = "magnitude")]
604 #[inline]
605 #[must_use]
606 pub fn length(self) -> f32 {
607 Vec4::from(self).length()
608 }
609
610 #[doc(alias = "magnitude2")]
615 #[inline]
616 #[must_use]
617 pub fn length_squared(self) -> f32 {
618 Vec4::from(self).length_squared()
619 }
620
621 #[inline]
625 #[must_use]
626 pub fn length_recip(self) -> f32 {
627 Vec4::from(self).length_recip()
628 }
629
630 #[inline]
638 #[must_use]
639 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
640 pub fn normalize(self) -> Self {
641 Self::from_vec4(Vec4::from(self).normalize())
642 }
643
644 #[inline]
647 #[must_use]
648 pub fn is_finite(self) -> bool {
649 Vec4::from(self).is_finite()
650 }
651
652 #[inline]
654 #[must_use]
655 pub fn is_nan(self) -> bool {
656 Vec4::from(self).is_nan()
657 }
658
659 #[inline]
663 #[must_use]
664 pub fn is_normalized(self) -> bool {
665 Vec4::from(self).is_normalized()
666 }
667
668 #[inline]
670 #[must_use]
671 pub fn is_near_identity(self) -> bool {
672 const THRESHOLD: f32 = 1.0 - 1e-6;
677 math::abs(self.w) > THRESHOLD
678 }
679
680 #[inline]
689 #[must_use]
690 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
691 pub fn angle_between(self, rhs: Self) -> f32 {
692 glam_assert!(self.is_normalized() && rhs.is_normalized());
693 math::acos_approx(math::abs(self.dot(rhs))) * 2.0
694 }
695
696 #[inline]
708 #[must_use]
709 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
710 pub fn rotate_towards(self, rhs: Self, max_angle: f32) -> Self {
711 glam_assert!(self.is_normalized() && rhs.is_normalized());
712 let angle = self.angle_between(rhs);
713 if angle <= 1e-4 {
714 return rhs;
715 }
716 let s = (max_angle / angle).clamp(-1.0, 1.0);
717 self.slerp(rhs, s)
718 }
719
720 #[inline]
730 #[must_use]
731 pub fn abs_diff_eq(self, rhs: Self, max_abs_diff: f32) -> bool {
732 Vec4::from(self).abs_diff_eq(Vec4::from(rhs), max_abs_diff)
733 }
734
735 #[inline(always)]
736 #[must_use]
737 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
738 fn lerp_impl(self, end: Self, s: f32) -> Self {
739 (self * (1.0 - s) + end * s).normalize()
740 }
741
742 #[doc(alias = "mix")]
755 #[inline]
756 #[must_use]
757 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
758 pub fn lerp(self, end: Self, s: f32) -> Self {
759 glam_assert!(self.is_normalized());
760 glam_assert!(end.is_normalized());
761
762 const NEG_ZERO: __m128 = m128_from_f32x4([-0.0; 4]);
763 unsafe {
764 let dot = dot4_into_m128(self.0, end.0);
765 let bias = _mm_and_ps(dot, NEG_ZERO);
768 self.lerp_impl(Self(_mm_xor_ps(end.0, bias)), s)
769 }
770 }
771
772 #[inline(always)]
773 #[must_use]
774 fn slerp_impl(self, end: Self, dot: f32, s: f32) -> Self {
775 let theta = math::acos_approx(dot);
776
777 let x = 1.0 - s;
778 let y = s;
779 let z = 1.0;
780
781 unsafe {
782 let tmp = _mm_mul_ps(_mm_set_ps1(theta), _mm_set_ps(0.0, z, y, x));
783 let tmp = m128_sin(tmp);
784
785 let scale1 = _mm_shuffle_ps(tmp, tmp, 0b00_00_00_00);
786 let scale2 = _mm_shuffle_ps(tmp, tmp, 0b01_01_01_01);
787 let theta_sin = _mm_shuffle_ps(tmp, tmp, 0b10_10_10_10);
788
789 Self(_mm_div_ps(
790 m128_mul_add(end.0, scale2, _mm_mul_ps(self.0, scale1)),
791 theta_sin,
792 ))
793 }
794 }
795
796 #[inline]
806 #[must_use]
807 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
808 pub fn slerp(self, mut end: Self, s: f32) -> Self {
809 glam_assert!(self.is_normalized());
811 glam_assert!(end.is_normalized());
812
813 let mut dot = self.dot(end);
820 if dot < 0.0 {
821 end = -end;
822 dot = -dot;
823 }
824
825 const DOT_THRESHOLD: f32 = 1.0 - f32::EPSILON;
826 if dot > DOT_THRESHOLD {
827 self.lerp_impl(end, s)
829 } else {
830 self.slerp_impl(end, dot, s)
831 }
832 }
833
834 #[inline]
848 #[must_use]
849 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
850 pub fn slerp_long(self, end: Self, s: f32) -> Self {
851 glam_assert!(self.is_normalized());
852 glam_assert!(end.is_normalized());
853
854 let dot = self.dot(end);
855
856 const DOT_THRESHOLD: f32 = 1.0 - f32::EPSILON;
857 if math::abs(dot) > DOT_THRESHOLD {
858 self.lerp_impl(end, s)
860 } else {
861 self.slerp_impl(end, dot, s)
862 }
863 }
864
865 #[inline]
871 #[must_use]
872 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
873 pub fn mul_vec3(self, rhs: Vec3) -> Vec3 {
874 glam_assert!(self.is_normalized());
875
876 self.mul_vec3a(rhs.into()).into()
877 }
878
879 #[inline]
884 #[must_use]
885 pub fn mul_quat(self, rhs: Self) -> Self {
886 const CONTROL_WZYX: __m128 = m128_from_f32x4([1.0, -1.0, 1.0, -1.0]);
888 const CONTROL_ZWXY: __m128 = m128_from_f32x4([1.0, 1.0, -1.0, -1.0]);
889 const CONTROL_YXWZ: __m128 = m128_from_f32x4([-1.0, 1.0, 1.0, -1.0]);
890
891 let lhs = self.0;
892 let rhs = rhs.0;
893
894 unsafe {
895 let r_xxxx = _mm_shuffle_ps(lhs, lhs, 0b00_00_00_00);
896 let r_yyyy = _mm_shuffle_ps(lhs, lhs, 0b01_01_01_01);
897 let r_zzzz = _mm_shuffle_ps(lhs, lhs, 0b10_10_10_10);
898 let r_wwww = _mm_shuffle_ps(lhs, lhs, 0b11_11_11_11);
899
900 let lxrw_lyrw_lzrw_lwrw = _mm_mul_ps(r_wwww, rhs);
901 let l_wzyx = _mm_shuffle_ps(rhs, rhs, 0b00_01_10_11);
902
903 let lwrx_lzrx_lyrx_lxrx = _mm_mul_ps(r_xxxx, l_wzyx);
904 let l_zwxy = _mm_shuffle_ps(l_wzyx, l_wzyx, 0b10_11_00_01);
905
906 let lzry_lwry_lxry_lyry = _mm_mul_ps(r_yyyy, l_zwxy);
907 let l_yxwz = _mm_shuffle_ps(l_zwxy, l_zwxy, 0b00_01_10_11);
908
909 let lzry_lwry_nlxry_nlyry = _mm_mul_ps(lzry_lwry_lxry_lyry, CONTROL_ZWXY);
910
911 let lyrz_lxrz_lwrz_lzrz = _mm_mul_ps(r_zzzz, l_yxwz);
912 let result0 = m128_mul_add(lwrx_lzrx_lyrx_lxrx, CONTROL_WZYX, lxrw_lyrw_lzrw_lwrw);
913
914 let result1 = m128_mul_add(lyrz_lxrz_lwrz_lzrz, CONTROL_YXWZ, lzry_lwry_nlxry_nlyry);
915
916 Self(_mm_add_ps(result0, result1))
917 }
918 }
919
920 #[inline]
930 #[must_use]
931 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
932 pub fn from_affine3(a: &crate::Affine3) -> Self {
933 Self::from_rotation_axes(a.matrix3.x_axis, a.matrix3.y_axis, a.matrix3.z_axis)
934 }
935
936 #[inline]
946 #[must_use]
947 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
948 pub fn from_affine3a(a: &crate::Affine3A) -> Self {
949 Self::from_rotation_axes(
950 a.matrix3.x_axis.into(),
951 a.matrix3.y_axis.into(),
952 a.matrix3.z_axis.into(),
953 )
954 }
955
956 #[inline]
962 #[must_use]
963 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
964 pub fn mul_vec3a(self, rhs: Vec3A) -> Vec3A {
965 glam_assert!(self.is_normalized());
966
967 unsafe {
968 const TWO: __m128 = m128_from_f32x4([2.0; 4]);
969 let w = _mm_shuffle_ps(self.0, self.0, 0b11_11_11_11);
970 let b = self.0;
971 let b2 = dot3_into_m128(b, b);
972 Vec3A(_mm_add_ps(
973 _mm_add_ps(
974 _mm_mul_ps(rhs.0, _mm_sub_ps(_mm_mul_ps(w, w), b2)),
975 _mm_mul_ps(b, _mm_mul_ps(dot3_into_m128(rhs.0, b), TWO)),
976 ),
977 _mm_mul_ps(Vec3A(b).cross(rhs).into(), _mm_mul_ps(w, TWO)),
978 ))
979 }
980 }
981
982 #[cfg(feature = "f64")]
983 #[inline]
984 #[must_use]
985 pub fn as_dquat(self) -> DQuat {
986 DQuat::from_xyzw(self.x as f64, self.y as f64, self.z as f64, self.w as f64)
987 }
988}
989
990impl fmt::Debug for Quat {
991 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
992 fmt.debug_tuple(stringify!(Quat))
993 .field(&self.x)
994 .field(&self.y)
995 .field(&self.z)
996 .field(&self.w)
997 .finish()
998 }
999}
1000
1001impl fmt::Display for Quat {
1002 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1003 if let Some(p) = f.precision() {
1004 write!(
1005 f,
1006 "[{:.*}, {:.*}, {:.*}, {:.*}]",
1007 p, self.x, p, self.y, p, self.z, p, self.w
1008 )
1009 } else {
1010 write!(f, "[{}, {}, {}, {}]", self.x, self.y, self.z, self.w)
1011 }
1012 }
1013}
1014
1015impl Add for Quat {
1016 type Output = Self;
1017 #[inline]
1024 fn add(self, rhs: Self) -> Self {
1025 Self::from_vec4(Vec4::from(self) + Vec4::from(rhs))
1026 }
1027}
1028
1029impl Add<&Self> for Quat {
1030 type Output = Self;
1031 #[inline]
1032 fn add(self, rhs: &Self) -> Self {
1033 self.add(*rhs)
1034 }
1035}
1036
1037impl Add<&Quat> for &Quat {
1038 type Output = Quat;
1039 #[inline]
1040 fn add(self, rhs: &Quat) -> Quat {
1041 (*self).add(*rhs)
1042 }
1043}
1044
1045impl Add<Quat> for &Quat {
1046 type Output = Quat;
1047 #[inline]
1048 fn add(self, rhs: Quat) -> Quat {
1049 (*self).add(rhs)
1050 }
1051}
1052
1053impl AddAssign for Quat {
1054 #[inline]
1055 fn add_assign(&mut self, rhs: Self) {
1056 *self = self.add(rhs);
1057 }
1058}
1059
1060impl AddAssign<&Self> for Quat {
1061 #[inline]
1062 fn add_assign(&mut self, rhs: &Self) {
1063 self.add_assign(*rhs);
1064 }
1065}
1066
1067impl Sub for Quat {
1068 type Output = Self;
1069 #[inline]
1073 fn sub(self, rhs: Self) -> Self {
1074 Self::from_vec4(Vec4::from(self) - Vec4::from(rhs))
1075 }
1076}
1077
1078impl Sub<&Self> for Quat {
1079 type Output = Self;
1080 #[inline]
1081 fn sub(self, rhs: &Self) -> Self {
1082 self.sub(*rhs)
1083 }
1084}
1085
1086impl Sub<&Quat> for &Quat {
1087 type Output = Quat;
1088 #[inline]
1089 fn sub(self, rhs: &Quat) -> Quat {
1090 (*self).sub(*rhs)
1091 }
1092}
1093
1094impl Sub<Quat> for &Quat {
1095 type Output = Quat;
1096 #[inline]
1097 fn sub(self, rhs: Quat) -> Quat {
1098 (*self).sub(rhs)
1099 }
1100}
1101
1102impl SubAssign for Quat {
1103 #[inline]
1104 fn sub_assign(&mut self, rhs: Self) {
1105 *self = self.sub(rhs);
1106 }
1107}
1108
1109impl SubAssign<&Self> for Quat {
1110 #[inline]
1111 fn sub_assign(&mut self, rhs: &Self) {
1112 self.sub_assign(*rhs);
1113 }
1114}
1115
1116impl Mul<f32> for Quat {
1117 type Output = Self;
1118 #[inline]
1122 fn mul(self, rhs: f32) -> Self {
1123 Self::from_vec4(Vec4::from(self) * rhs)
1124 }
1125}
1126
1127impl Mul<&f32> for Quat {
1128 type Output = Self;
1129 #[inline]
1130 fn mul(self, rhs: &f32) -> Self {
1131 self.mul(*rhs)
1132 }
1133}
1134
1135impl Mul<&f32> for &Quat {
1136 type Output = Quat;
1137 #[inline]
1138 fn mul(self, rhs: &f32) -> Quat {
1139 (*self).mul(*rhs)
1140 }
1141}
1142
1143impl Mul<f32> for &Quat {
1144 type Output = Quat;
1145 #[inline]
1146 fn mul(self, rhs: f32) -> Quat {
1147 (*self).mul(rhs)
1148 }
1149}
1150
1151impl MulAssign<f32> for Quat {
1152 #[inline]
1153 fn mul_assign(&mut self, rhs: f32) {
1154 *self = self.mul(rhs);
1155 }
1156}
1157
1158impl MulAssign<&f32> for Quat {
1159 #[inline]
1160 fn mul_assign(&mut self, rhs: &f32) {
1161 self.mul_assign(*rhs);
1162 }
1163}
1164
1165impl Div<f32> for Quat {
1166 type Output = Self;
1167 #[inline]
1170 fn div(self, rhs: f32) -> Self {
1171 Self::from_vec4(Vec4::from(self) / rhs)
1172 }
1173}
1174
1175impl Div<&f32> for Quat {
1176 type Output = Self;
1177 #[inline]
1178 fn div(self, rhs: &f32) -> Self {
1179 self.div(*rhs)
1180 }
1181}
1182
1183impl Div<&f32> for &Quat {
1184 type Output = Quat;
1185 #[inline]
1186 fn div(self, rhs: &f32) -> Quat {
1187 (*self).div(*rhs)
1188 }
1189}
1190
1191impl Div<f32> for &Quat {
1192 type Output = Quat;
1193 #[inline]
1194 fn div(self, rhs: f32) -> Quat {
1195 (*self).div(rhs)
1196 }
1197}
1198
1199impl DivAssign<f32> for Quat {
1200 #[inline]
1201 fn div_assign(&mut self, rhs: f32) {
1202 *self = self.div(rhs);
1203 }
1204}
1205
1206impl DivAssign<&f32> for Quat {
1207 #[inline]
1208 fn div_assign(&mut self, rhs: &f32) {
1209 self.div_assign(*rhs);
1210 }
1211}
1212
1213impl Mul for Quat {
1214 type Output = Self;
1215 #[inline]
1221 fn mul(self, rhs: Self) -> Self {
1222 self.mul_quat(rhs)
1223 }
1224}
1225
1226impl Mul<&Self> for Quat {
1227 type Output = Self;
1228 #[inline]
1229 fn mul(self, rhs: &Self) -> Self {
1230 self.mul(*rhs)
1231 }
1232}
1233
1234impl Mul<&Quat> for &Quat {
1235 type Output = Quat;
1236 #[inline]
1237 fn mul(self, rhs: &Quat) -> Quat {
1238 (*self).mul(*rhs)
1239 }
1240}
1241
1242impl Mul<Quat> for &Quat {
1243 type Output = Quat;
1244 #[inline]
1245 fn mul(self, rhs: Quat) -> Quat {
1246 (*self).mul(rhs)
1247 }
1248}
1249
1250impl MulAssign for Quat {
1251 #[inline]
1252 fn mul_assign(&mut self, rhs: Self) {
1253 *self = self.mul(rhs);
1254 }
1255}
1256
1257impl MulAssign<&Self> for Quat {
1258 #[inline]
1259 fn mul_assign(&mut self, rhs: &Self) {
1260 self.mul_assign(*rhs);
1261 }
1262}
1263
1264impl Mul<Vec3> for Quat {
1265 type Output = Vec3;
1266 #[inline]
1272 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1273 fn mul(self, rhs: Vec3) -> Self::Output {
1274 self.mul_vec3(rhs)
1275 }
1276}
1277
1278impl Mul<&Vec3> for Quat {
1279 type Output = Vec3;
1280 #[inline]
1281 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1282 fn mul(self, rhs: &Vec3) -> Vec3 {
1283 self.mul(*rhs)
1284 }
1285}
1286
1287impl Mul<&Vec3> for &Quat {
1288 type Output = Vec3;
1289 #[inline]
1290 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1291 fn mul(self, rhs: &Vec3) -> Vec3 {
1292 (*self).mul(*rhs)
1293 }
1294}
1295
1296impl Mul<Vec3> for &Quat {
1297 type Output = Vec3;
1298 #[inline]
1299 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1300 fn mul(self, rhs: Vec3) -> Vec3 {
1301 (*self).mul(rhs)
1302 }
1303}
1304
1305impl Mul<Vec3A> for Quat {
1306 type Output = Vec3A;
1307 #[inline]
1313 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1314 fn mul(self, rhs: Vec3A) -> Self::Output {
1315 self.mul_vec3a(rhs)
1316 }
1317}
1318
1319impl Mul<&Vec3A> for Quat {
1320 type Output = Vec3A;
1321 #[inline]
1322 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1323 fn mul(self, rhs: &Vec3A) -> Vec3A {
1324 self.mul(*rhs)
1325 }
1326}
1327
1328impl Mul<&Vec3A> for &Quat {
1329 type Output = Vec3A;
1330 #[inline]
1331 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1332 fn mul(self, rhs: &Vec3A) -> Vec3A {
1333 (*self).mul(*rhs)
1334 }
1335}
1336
1337impl Mul<Vec3A> for &Quat {
1338 type Output = Vec3A;
1339 #[inline]
1340 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1341 fn mul(self, rhs: Vec3A) -> Vec3A {
1342 (*self).mul(rhs)
1343 }
1344}
1345
1346impl Neg for Quat {
1347 type Output = Self;
1348 #[inline]
1349 fn neg(self) -> Self {
1350 self * -1.0
1351 }
1352}
1353
1354impl Neg for &Quat {
1355 type Output = Quat;
1356 #[inline]
1357 fn neg(self) -> Quat {
1358 (*self).neg()
1359 }
1360}
1361
1362impl Default for Quat {
1363 #[inline]
1364 fn default() -> Self {
1365 Self::IDENTITY
1366 }
1367}
1368
1369impl PartialEq for Quat {
1370 #[inline]
1371 fn eq(&self, rhs: &Self) -> bool {
1372 Vec4::from(*self).eq(&Vec4::from(*rhs))
1373 }
1374}
1375
1376impl AsRef<[f32; 4]> for Quat {
1377 #[inline]
1378 fn as_ref(&self) -> &[f32; 4] {
1379 unsafe { &*(self as *const Self as *const [f32; 4]) }
1380 }
1381}
1382
1383impl Sum<Self> for Quat {
1384 fn sum<I>(iter: I) -> Self
1385 where
1386 I: Iterator<Item = Self>,
1387 {
1388 iter.fold(Self::ZERO, Self::add)
1389 }
1390}
1391
1392impl<'a> Sum<&'a Self> for Quat {
1393 fn sum<I>(iter: I) -> Self
1394 where
1395 I: Iterator<Item = &'a Self>,
1396 {
1397 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1398 }
1399}
1400
1401impl Product for Quat {
1402 fn product<I>(iter: I) -> Self
1403 where
1404 I: Iterator<Item = Self>,
1405 {
1406 iter.fold(Self::IDENTITY, Self::mul)
1407 }
1408}
1409
1410impl<'a> Product<&'a Self> for Quat {
1411 fn product<I>(iter: I) -> Self
1412 where
1413 I: Iterator<Item = &'a Self>,
1414 {
1415 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1416 }
1417}
1418
1419impl From<Quat> for Vec4 {
1420 #[inline]
1421 fn from(q: Quat) -> Self {
1422 Self(q.0)
1423 }
1424}
1425
1426impl From<Quat> for (f32, f32, f32, f32) {
1427 #[inline]
1428 fn from(q: Quat) -> Self {
1429 Vec4::from(q).into()
1430 }
1431}
1432
1433impl From<Quat> for [f32; 4] {
1434 #[inline]
1435 fn from(q: Quat) -> Self {
1436 Vec4::from(q).into()
1437 }
1438}
1439
1440impl From<Quat> for __m128 {
1441 #[inline]
1442 fn from(q: Quat) -> Self {
1443 q.0
1444 }
1445}
1446
1447impl Deref for Quat {
1448 type Target = crate::deref::Vec4<f32>;
1449 #[inline]
1450 fn deref(&self) -> &Self::Target {
1451 unsafe { &*(self as *const Self).cast() }
1452 }
1453}
1454
1455impl DerefMut for Quat {
1456 #[inline]
1457 fn deref_mut(&mut self) -> &mut Self::Target {
1458 unsafe { &mut *(self as *mut Self).cast() }
1459 }
1460}