1use crate::{
4 euler::{EulerRot, FromEuler, ToEuler},
5 f64::math,
6 DMat3, DMat4, DVec2, DVec3, DVec4, Quat,
7};
8
9use core::fmt;
10use core::iter::{Product, Sum};
11use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
12
13#[cfg(feature = "zerocopy-08")]
14use zerocopy_derive_08::*;
15
16#[inline]
21#[must_use]
22pub const fn dquat(x: f64, y: f64, z: f64, w: f64) -> DQuat {
23 DQuat::from_xyzw(x, y, z, w)
24}
25
26#[derive(Clone, Copy)]
32#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
33#[cfg_attr(
34 feature = "zerocopy-08",
35 derive(FromBytes, Immutable, IntoBytes, KnownLayout)
36)]
37#[repr(C)]
38#[cfg_attr(target_arch = "spirv", rust_gpu::vector::v1)]
39pub struct DQuat {
40 pub x: f64,
41 pub y: f64,
42 pub z: f64,
43 pub w: f64,
44}
45
46impl DQuat {
47 const ZERO: Self = Self::from_array([0.0; 4]);
49
50 pub const IDENTITY: Self = Self::from_xyzw(0.0, 0.0, 0.0, 1.0);
52
53 pub const NAN: Self = Self::from_array([f64::NAN; 4]);
55
56 #[inline(always)]
68 #[must_use]
69 pub const fn from_xyzw(x: f64, y: f64, z: f64, w: f64) -> Self {
70 Self { x, y, z, w }
71 }
72
73 #[inline]
80 #[must_use]
81 pub const fn from_array(a: [f64; 4]) -> Self {
82 Self::from_xyzw(a[0], a[1], a[2], a[3])
83 }
84
85 #[inline]
92 #[must_use]
93 pub const fn from_vec4(v: DVec4) -> Self {
94 Self {
95 x: v.x,
96 y: v.y,
97 z: v.z,
98 w: v.w,
99 }
100 }
101
102 #[inline]
113 #[must_use]
114 #[track_caller]
115 pub fn from_slice(slice: &[f64]) -> Self {
116 Self::from_xyzw(slice[0], slice[1], slice[2], slice[3])
117 }
118
119 #[inline]
125 #[track_caller]
126 pub fn write_to_slice(self, slice: &mut [f64]) {
127 slice[0] = self.x;
128 slice[1] = self.y;
129 slice[2] = self.z;
130 slice[3] = self.w;
131 }
132
133 #[inline]
141 #[must_use]
142 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
143 pub fn from_axis_angle(axis: DVec3, angle: f64) -> Self {
144 glam_assert!(axis.is_normalized());
145 let (s, c) = math::sin_cos(angle * 0.5);
146 let v = axis * s;
147 Self::from_xyzw(v.x, v.y, v.z, c)
148 }
149
150 #[inline]
158 #[must_use]
159 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
160 pub fn from_scaled_axis(v: DVec3) -> Self {
161 let length = v.length();
162 if length == 0.0 {
163 Self::IDENTITY
164 } else {
165 Self::from_axis_angle(v / length, length)
166 }
167 }
168
169 #[inline]
171 #[must_use]
172 pub fn from_rotation_x(angle: f64) -> Self {
173 let (s, c) = math::sin_cos(angle * 0.5);
174 Self::from_xyzw(s, 0.0, 0.0, c)
175 }
176
177 #[inline]
179 #[must_use]
180 pub fn from_rotation_y(angle: f64) -> Self {
181 let (s, c) = math::sin_cos(angle * 0.5);
182 Self::from_xyzw(0.0, s, 0.0, c)
183 }
184
185 #[inline]
187 #[must_use]
188 pub fn from_rotation_z(angle: f64) -> Self {
189 let (s, c) = math::sin_cos(angle * 0.5);
190 Self::from_xyzw(0.0, 0.0, s, c)
191 }
192
193 #[inline]
195 #[must_use]
196 pub fn from_euler(euler: EulerRot, a: f64, b: f64, c: f64) -> Self {
197 Self::from_euler_angles(euler, a, b, c)
198 }
199
200 #[inline]
209 #[must_use]
210 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
211 pub fn from_rotation_axes(x_axis: DVec3, y_axis: DVec3, z_axis: DVec3) -> Self {
212 glam_assert!(x_axis.is_normalized() && y_axis.is_normalized() && z_axis.is_normalized());
213 let (m00, m01, m02) = x_axis.into();
215 let (m10, m11, m12) = y_axis.into();
216 let (m20, m21, m22) = z_axis.into();
217 if m22 <= 0.0 {
218 let dif10 = m11 - m00;
220 let omm22 = 1.0 - m22;
221 if dif10 <= 0.0 {
222 let four_xsq = omm22 - dif10;
224 let inv4x = 0.5 / math::sqrt(four_xsq);
225 Self::from_xyzw(
226 four_xsq * inv4x,
227 (m01 + m10) * inv4x,
228 (m02 + m20) * inv4x,
229 (m12 - m21) * inv4x,
230 )
231 } else {
232 let four_ysq = omm22 + dif10;
234 let inv4y = 0.5 / math::sqrt(four_ysq);
235 Self::from_xyzw(
236 (m01 + m10) * inv4y,
237 four_ysq * inv4y,
238 (m12 + m21) * inv4y,
239 (m20 - m02) * inv4y,
240 )
241 }
242 } else {
243 let sum10 = m11 + m00;
245 let opm22 = 1.0 + m22;
246 if sum10 <= 0.0 {
247 let four_zsq = opm22 - sum10;
249 let inv4z = 0.5 / math::sqrt(four_zsq);
250 Self::from_xyzw(
251 (m02 + m20) * inv4z,
252 (m12 + m21) * inv4z,
253 four_zsq * inv4z,
254 (m01 - m10) * inv4z,
255 )
256 } else {
257 let four_wsq = opm22 + sum10;
259 let inv4w = 0.5 / math::sqrt(four_wsq);
260 Self::from_xyzw(
261 (m12 - m21) * inv4w,
262 (m20 - m02) * inv4w,
263 (m01 - m10) * inv4w,
264 four_wsq * inv4w,
265 )
266 }
267 }
268 }
269
270 #[inline]
279 #[must_use]
280 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
281 pub fn from_mat3(mat: &DMat3) -> Self {
282 Self::from_rotation_axes(mat.x_axis, mat.y_axis, mat.z_axis)
283 }
284
285 #[inline]
295 #[must_use]
296 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
297 pub fn from_mat4(mat: &DMat4) -> Self {
298 Self::from_rotation_axes(
299 mat.x_axis.truncate(),
300 mat.y_axis.truncate(),
301 mat.z_axis.truncate(),
302 )
303 }
304
305 #[must_use]
319 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
320 pub fn from_rotation_arc(from: DVec3, to: DVec3) -> Self {
321 glam_assert!(from.is_normalized());
322 glam_assert!(to.is_normalized());
323
324 const ONE_MINUS_EPS: f64 = 1.0 - 2.0 * f64::EPSILON;
325 let dot = from.dot(to);
326 if dot > ONE_MINUS_EPS {
327 Self::IDENTITY
329 } else if dot < -ONE_MINUS_EPS {
330 use core::f64::consts::PI; Self::from_axis_angle(from.any_orthonormal_vector(), PI)
333 } else {
334 let c = from.cross(to);
335 Self::from_xyzw(c.x, c.y, c.z, 1.0 + dot).normalize()
336 }
337 }
338
339 #[inline]
353 #[must_use]
354 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
355 pub fn from_rotation_arc_colinear(from: DVec3, to: DVec3) -> Self {
356 if from.dot(to) < 0.0 {
357 Self::from_rotation_arc(from, -to)
358 } else {
359 Self::from_rotation_arc(from, to)
360 }
361 }
362
363 #[must_use]
377 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
378 pub fn from_rotation_arc_2d(from: DVec2, to: DVec2) -> Self {
379 glam_assert!(from.is_normalized());
380 glam_assert!(to.is_normalized());
381
382 const ONE_MINUS_EPSILON: f64 = 1.0 - 2.0 * f64::EPSILON;
383 let dot = from.dot(to);
384 if dot > ONE_MINUS_EPSILON {
385 Self::IDENTITY
387 } else if dot < -ONE_MINUS_EPSILON {
388 const COS_FRAC_PI_2: f64 = 0.0;
390 const SIN_FRAC_PI_2: f64 = 1.0;
391 Self::from_xyzw(0.0, 0.0, SIN_FRAC_PI_2, COS_FRAC_PI_2)
393 } else {
394 let z = from.x * to.y - to.x * from.y;
396 let w = 1.0 + dot;
397 let len_rcp = 1.0 / math::sqrt(z * z + w * w);
399 Self::from_xyzw(0.0, 0.0, z * len_rcp, w * len_rcp)
400 }
401 }
402
403 #[deprecated(
412 since = "0.33.1",
413 note = "use the `glam::dcamera::lh::view::look_to_quat` function instead"
414 )]
415 #[inline]
416 #[must_use]
417 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
418 pub fn look_to_lh(dir: DVec3, up: DVec3) -> Self {
419 #[allow(deprecated)]
420 Self::look_to_rh(-dir, up)
421 }
422
423 #[deprecated(
432 since = "0.33.1",
433 note = "use the `glam::dcamera::rh::view::look_to_quat` function instead"
434 )]
435 #[inline]
436 #[must_use]
437 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
438 pub fn look_to_rh(dir: DVec3, up: DVec3) -> Self {
439 glam_assert!(dir.is_normalized());
440 glam_assert!(up.is_normalized());
441 let f = dir;
442 let s = f.cross(up).normalize();
443 let u = s.cross(f);
444
445 Self::from_rotation_axes(
446 DVec3::new(s.x, u.x, -f.x),
447 DVec3::new(s.y, u.y, -f.y),
448 DVec3::new(s.z, u.z, -f.z),
449 )
450 }
451
452 #[deprecated(
462 since = "0.33.1",
463 note = "use the `glam::dcamera::lh::view::look_at_quat` function instead"
464 )]
465 #[inline]
466 #[must_use]
467 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
468 pub fn look_at_lh(eye: DVec3, center: DVec3, up: DVec3) -> Self {
469 #[allow(deprecated)]
470 Self::look_to_lh(center.sub(eye).normalize(), up)
471 }
472
473 #[deprecated(
483 since = "0.33.1",
484 note = "use the `glam::dcamera::rh::view::look_at_quat` function instead"
485 )]
486 #[inline]
487 #[must_use]
488 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
489 pub fn look_at_rh(eye: DVec3, center: DVec3, up: DVec3) -> Self {
490 #[allow(deprecated)]
491 Self::look_to_rh(center.sub(eye).normalize(), up)
492 }
493
494 #[inline]
496 #[must_use]
497 pub fn to_axis_angle(self) -> (DVec3, f64) {
498 const EPSILON: f64 = 1.0e-8;
499 let v = DVec3::new(self.x, self.y, self.z);
500 let length = v.length();
501 if length >= EPSILON {
502 let angle = 2.0 * math::atan2(length, self.w);
503 let axis = v / length;
504 (axis, angle)
505 } else {
506 (DVec3::X, 0.0)
507 }
508 }
509
510 #[inline]
512 #[must_use]
513 pub fn to_scaled_axis(self) -> DVec3 {
514 let (axis, angle) = self.to_axis_angle();
515 axis * angle
516 }
517
518 #[inline]
524 #[must_use]
525 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
526 pub fn to_euler(self, order: EulerRot) -> (f64, f64, f64) {
527 DMat3::from_quat(self).to_euler_angles(order)
528 }
529
530 #[inline]
532 #[must_use]
533 pub const fn to_array(&self) -> [f64; 4] {
534 [self.x, self.y, self.z, self.w]
535 }
536
537 #[inline]
539 #[must_use]
540 pub fn xyz(self) -> DVec3 {
541 DVec3::new(self.x, self.y, self.z)
542 }
543
544 #[inline]
547 #[must_use]
548 pub fn conjugate(self) -> Self {
549 Self {
550 x: -self.x,
551 y: -self.y,
552 z: -self.z,
553 w: self.w,
554 }
555 }
556
557 #[inline]
567 #[must_use]
568 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
569 pub fn inverse(self) -> Self {
570 glam_assert!(self.is_normalized());
571 self.conjugate()
572 }
573
574 #[inline]
577 #[must_use]
578 pub fn dot(self, rhs: Self) -> f64 {
579 DVec4::from(self).dot(DVec4::from(rhs))
580 }
581
582 #[doc(alias = "magnitude")]
584 #[inline]
585 #[must_use]
586 pub fn length(self) -> f64 {
587 DVec4::from(self).length()
588 }
589
590 #[doc(alias = "magnitude2")]
595 #[inline]
596 #[must_use]
597 pub fn length_squared(self) -> f64 {
598 DVec4::from(self).length_squared()
599 }
600
601 #[inline]
605 #[must_use]
606 pub fn length_recip(self) -> f64 {
607 DVec4::from(self).length_recip()
608 }
609
610 #[inline]
618 #[must_use]
619 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
620 pub fn normalize(self) -> Self {
621 Self::from_vec4(DVec4::from(self).normalize())
622 }
623
624 #[inline]
627 #[must_use]
628 pub fn is_finite(self) -> bool {
629 DVec4::from(self).is_finite()
630 }
631
632 #[inline]
634 #[must_use]
635 pub fn is_nan(self) -> bool {
636 DVec4::from(self).is_nan()
637 }
638
639 #[inline]
643 #[must_use]
644 pub fn is_normalized(self) -> bool {
645 DVec4::from(self).is_normalized()
646 }
647
648 #[inline]
650 #[must_use]
651 pub fn is_near_identity(self) -> bool {
652 const THRESHOLD: f64 = 1.0 - 1e-14;
657 math::abs(self.w) > THRESHOLD
658 }
659
660 #[inline]
669 #[must_use]
670 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
671 pub fn angle_between(self, rhs: Self) -> f64 {
672 glam_assert!(self.is_normalized() && rhs.is_normalized());
673 math::acos_approx(math::abs(self.dot(rhs))) * 2.0
674 }
675
676 #[inline]
688 #[must_use]
689 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
690 pub fn rotate_towards(self, rhs: Self, max_angle: f64) -> Self {
691 glam_assert!(self.is_normalized() && rhs.is_normalized());
692 let angle = self.angle_between(rhs);
693 if angle <= 1e-4 {
694 return rhs;
695 }
696 let s = (max_angle / angle).clamp(-1.0, 1.0);
697 self.slerp(rhs, s)
698 }
699
700 #[inline]
710 #[must_use]
711 pub fn abs_diff_eq(self, rhs: Self, max_abs_diff: f64) -> bool {
712 DVec4::from(self).abs_diff_eq(DVec4::from(rhs), max_abs_diff)
713 }
714
715 #[inline(always)]
716 #[must_use]
717 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
718 fn lerp_impl(self, end: Self, s: f64) -> Self {
719 (self * (1.0 - s) + end * s).normalize()
720 }
721
722 #[doc(alias = "mix")]
735 #[inline]
736 #[must_use]
737 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
738 pub fn lerp(self, end: Self, s: f64) -> Self {
739 glam_assert!(self.is_normalized());
740 glam_assert!(end.is_normalized());
741
742 let dot = self.dot(end);
743 let bias = if dot >= 0.0 { 1.0 } else { -1.0 };
744 self.lerp_impl(end * bias, s)
745 }
746
747 #[inline(always)]
748 #[must_use]
749 fn slerp_impl(self, end: Self, dot: f64, s: f64) -> Self {
750 let theta = math::acos_approx(dot);
751
752 let scale1 = math::sin(theta * (1.0 - s));
753 let scale2 = math::sin(theta * s);
754 let theta_sin = math::sin(theta);
755 ((self * scale1) + (end * scale2)) * (1.0 / theta_sin)
756 }
757
758 #[inline]
768 #[must_use]
769 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
770 pub fn slerp(self, mut end: Self, s: f64) -> Self {
771 glam_assert!(self.is_normalized());
773 glam_assert!(end.is_normalized());
774
775 let mut dot = self.dot(end);
782 if dot < 0.0 {
783 end = -end;
784 dot = -dot;
785 }
786
787 const DOT_THRESHOLD: f64 = 1.0 - f64::EPSILON;
788 if dot > DOT_THRESHOLD {
789 self.lerp_impl(end, s)
791 } else {
792 self.slerp_impl(end, dot, s)
793 }
794 }
795
796 #[inline]
810 #[must_use]
811 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
812 pub fn slerp_long(self, end: Self, s: f64) -> Self {
813 glam_assert!(self.is_normalized());
814 glam_assert!(end.is_normalized());
815
816 let dot = self.dot(end);
817
818 const DOT_THRESHOLD: f64 = 1.0 - f64::EPSILON;
819 if math::abs(dot) > DOT_THRESHOLD {
820 self.lerp_impl(end, s)
822 } else {
823 self.slerp_impl(end, dot, s)
824 }
825 }
826
827 #[inline]
833 #[must_use]
834 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
835 pub fn mul_vec3(self, rhs: DVec3) -> DVec3 {
836 glam_assert!(self.is_normalized());
837
838 let w = self.w;
839 let b = DVec3::new(self.x, self.y, self.z);
840 let b2 = b.dot(b);
841 rhs.mul(w * w - b2)
842 .add(b.mul(rhs.dot(b) * 2.0))
843 .add(b.cross(rhs).mul(w * 2.0))
844 }
845
846 #[inline]
851 #[must_use]
852 pub fn mul_quat(self, rhs: Self) -> Self {
853 let (x0, y0, z0, w0) = self.into();
854 let (x1, y1, z1, w1) = rhs.into();
855 Self::from_xyzw(
856 w0 * x1 + x0 * w1 + y0 * z1 - z0 * y1,
857 w0 * y1 - x0 * z1 + y0 * w1 + z0 * x1,
858 w0 * z1 + x0 * y1 - y0 * x1 + z0 * w1,
859 w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1,
860 )
861 }
862
863 #[inline]
873 #[must_use]
874 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
875 pub fn from_affine3(a: &crate::DAffine3) -> Self {
876 Self::from_rotation_axes(a.matrix3.x_axis, a.matrix3.y_axis, a.matrix3.z_axis)
877 }
878
879 #[inline]
880 #[must_use]
881 pub fn as_quat(self) -> Quat {
882 Quat::from_xyzw(self.x as f32, self.y as f32, self.z as f32, self.w as f32)
883 }
884}
885
886impl fmt::Debug for DQuat {
887 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
888 fmt.debug_tuple(stringify!(DQuat))
889 .field(&self.x)
890 .field(&self.y)
891 .field(&self.z)
892 .field(&self.w)
893 .finish()
894 }
895}
896
897impl fmt::Display for DQuat {
898 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
899 if let Some(p) = f.precision() {
900 write!(
901 f,
902 "[{:.*}, {:.*}, {:.*}, {:.*}]",
903 p, self.x, p, self.y, p, self.z, p, self.w
904 )
905 } else {
906 write!(f, "[{}, {}, {}, {}]", self.x, self.y, self.z, self.w)
907 }
908 }
909}
910
911impl Add for DQuat {
912 type Output = Self;
913 #[inline]
920 fn add(self, rhs: Self) -> Self {
921 Self::from_vec4(DVec4::from(self) + DVec4::from(rhs))
922 }
923}
924
925impl Add<&Self> for DQuat {
926 type Output = Self;
927 #[inline]
928 fn add(self, rhs: &Self) -> Self {
929 self.add(*rhs)
930 }
931}
932
933impl Add<&DQuat> for &DQuat {
934 type Output = DQuat;
935 #[inline]
936 fn add(self, rhs: &DQuat) -> DQuat {
937 (*self).add(*rhs)
938 }
939}
940
941impl Add<DQuat> for &DQuat {
942 type Output = DQuat;
943 #[inline]
944 fn add(self, rhs: DQuat) -> DQuat {
945 (*self).add(rhs)
946 }
947}
948
949impl AddAssign for DQuat {
950 #[inline]
951 fn add_assign(&mut self, rhs: Self) {
952 *self = self.add(rhs);
953 }
954}
955
956impl AddAssign<&Self> for DQuat {
957 #[inline]
958 fn add_assign(&mut self, rhs: &Self) {
959 self.add_assign(*rhs);
960 }
961}
962
963impl Sub for DQuat {
964 type Output = Self;
965 #[inline]
969 fn sub(self, rhs: Self) -> Self {
970 Self::from_vec4(DVec4::from(self) - DVec4::from(rhs))
971 }
972}
973
974impl Sub<&Self> for DQuat {
975 type Output = Self;
976 #[inline]
977 fn sub(self, rhs: &Self) -> Self {
978 self.sub(*rhs)
979 }
980}
981
982impl Sub<&DQuat> for &DQuat {
983 type Output = DQuat;
984 #[inline]
985 fn sub(self, rhs: &DQuat) -> DQuat {
986 (*self).sub(*rhs)
987 }
988}
989
990impl Sub<DQuat> for &DQuat {
991 type Output = DQuat;
992 #[inline]
993 fn sub(self, rhs: DQuat) -> DQuat {
994 (*self).sub(rhs)
995 }
996}
997
998impl SubAssign for DQuat {
999 #[inline]
1000 fn sub_assign(&mut self, rhs: Self) {
1001 *self = self.sub(rhs);
1002 }
1003}
1004
1005impl SubAssign<&Self> for DQuat {
1006 #[inline]
1007 fn sub_assign(&mut self, rhs: &Self) {
1008 self.sub_assign(*rhs);
1009 }
1010}
1011
1012impl Mul<f64> for DQuat {
1013 type Output = Self;
1014 #[inline]
1018 fn mul(self, rhs: f64) -> Self {
1019 Self::from_vec4(DVec4::from(self) * rhs)
1020 }
1021}
1022
1023impl Mul<&f64> for DQuat {
1024 type Output = Self;
1025 #[inline]
1026 fn mul(self, rhs: &f64) -> Self {
1027 self.mul(*rhs)
1028 }
1029}
1030
1031impl Mul<&f64> for &DQuat {
1032 type Output = DQuat;
1033 #[inline]
1034 fn mul(self, rhs: &f64) -> DQuat {
1035 (*self).mul(*rhs)
1036 }
1037}
1038
1039impl Mul<f64> for &DQuat {
1040 type Output = DQuat;
1041 #[inline]
1042 fn mul(self, rhs: f64) -> DQuat {
1043 (*self).mul(rhs)
1044 }
1045}
1046
1047impl MulAssign<f64> for DQuat {
1048 #[inline]
1049 fn mul_assign(&mut self, rhs: f64) {
1050 *self = self.mul(rhs);
1051 }
1052}
1053
1054impl MulAssign<&f64> for DQuat {
1055 #[inline]
1056 fn mul_assign(&mut self, rhs: &f64) {
1057 self.mul_assign(*rhs);
1058 }
1059}
1060
1061impl Div<f64> for DQuat {
1062 type Output = Self;
1063 #[inline]
1066 fn div(self, rhs: f64) -> Self {
1067 Self::from_vec4(DVec4::from(self) / rhs)
1068 }
1069}
1070
1071impl Div<&f64> for DQuat {
1072 type Output = Self;
1073 #[inline]
1074 fn div(self, rhs: &f64) -> Self {
1075 self.div(*rhs)
1076 }
1077}
1078
1079impl Div<&f64> for &DQuat {
1080 type Output = DQuat;
1081 #[inline]
1082 fn div(self, rhs: &f64) -> DQuat {
1083 (*self).div(*rhs)
1084 }
1085}
1086
1087impl Div<f64> for &DQuat {
1088 type Output = DQuat;
1089 #[inline]
1090 fn div(self, rhs: f64) -> DQuat {
1091 (*self).div(rhs)
1092 }
1093}
1094
1095impl DivAssign<f64> for DQuat {
1096 #[inline]
1097 fn div_assign(&mut self, rhs: f64) {
1098 *self = self.div(rhs);
1099 }
1100}
1101
1102impl DivAssign<&f64> for DQuat {
1103 #[inline]
1104 fn div_assign(&mut self, rhs: &f64) {
1105 self.div_assign(*rhs);
1106 }
1107}
1108
1109impl Mul for DQuat {
1110 type Output = Self;
1111 #[inline]
1117 fn mul(self, rhs: Self) -> Self {
1118 self.mul_quat(rhs)
1119 }
1120}
1121
1122impl Mul<&Self> for DQuat {
1123 type Output = Self;
1124 #[inline]
1125 fn mul(self, rhs: &Self) -> Self {
1126 self.mul(*rhs)
1127 }
1128}
1129
1130impl Mul<&DQuat> for &DQuat {
1131 type Output = DQuat;
1132 #[inline]
1133 fn mul(self, rhs: &DQuat) -> DQuat {
1134 (*self).mul(*rhs)
1135 }
1136}
1137
1138impl Mul<DQuat> for &DQuat {
1139 type Output = DQuat;
1140 #[inline]
1141 fn mul(self, rhs: DQuat) -> DQuat {
1142 (*self).mul(rhs)
1143 }
1144}
1145
1146impl MulAssign for DQuat {
1147 #[inline]
1148 fn mul_assign(&mut self, rhs: Self) {
1149 *self = self.mul(rhs);
1150 }
1151}
1152
1153impl MulAssign<&Self> for DQuat {
1154 #[inline]
1155 fn mul_assign(&mut self, rhs: &Self) {
1156 self.mul_assign(*rhs);
1157 }
1158}
1159
1160impl Mul<DVec3> for DQuat {
1161 type Output = DVec3;
1162 #[inline]
1168 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1169 fn mul(self, rhs: DVec3) -> Self::Output {
1170 self.mul_vec3(rhs)
1171 }
1172}
1173
1174impl Mul<&DVec3> for DQuat {
1175 type Output = DVec3;
1176 #[inline]
1177 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1178 fn mul(self, rhs: &DVec3) -> DVec3 {
1179 self.mul(*rhs)
1180 }
1181}
1182
1183impl Mul<&DVec3> for &DQuat {
1184 type Output = DVec3;
1185 #[inline]
1186 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1187 fn mul(self, rhs: &DVec3) -> DVec3 {
1188 (*self).mul(*rhs)
1189 }
1190}
1191
1192impl Mul<DVec3> for &DQuat {
1193 type Output = DVec3;
1194 #[inline]
1195 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1196 fn mul(self, rhs: DVec3) -> DVec3 {
1197 (*self).mul(rhs)
1198 }
1199}
1200
1201impl Neg for DQuat {
1202 type Output = Self;
1203 #[inline]
1204 fn neg(self) -> Self {
1205 self * -1.0
1206 }
1207}
1208
1209impl Neg for &DQuat {
1210 type Output = DQuat;
1211 #[inline]
1212 fn neg(self) -> DQuat {
1213 (*self).neg()
1214 }
1215}
1216
1217impl Default for DQuat {
1218 #[inline]
1219 fn default() -> Self {
1220 Self::IDENTITY
1221 }
1222}
1223
1224impl PartialEq for DQuat {
1225 #[inline]
1226 fn eq(&self, rhs: &Self) -> bool {
1227 DVec4::from(*self).eq(&DVec4::from(*rhs))
1228 }
1229}
1230
1231impl AsRef<[f64; 4]> for DQuat {
1232 #[inline]
1233 fn as_ref(&self) -> &[f64; 4] {
1234 unsafe { &*(self as *const Self as *const [f64; 4]) }
1235 }
1236}
1237
1238impl Sum<Self> for DQuat {
1239 fn sum<I>(iter: I) -> Self
1240 where
1241 I: Iterator<Item = Self>,
1242 {
1243 iter.fold(Self::ZERO, Self::add)
1244 }
1245}
1246
1247impl<'a> Sum<&'a Self> for DQuat {
1248 fn sum<I>(iter: I) -> Self
1249 where
1250 I: Iterator<Item = &'a Self>,
1251 {
1252 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1253 }
1254}
1255
1256impl Product for DQuat {
1257 fn product<I>(iter: I) -> Self
1258 where
1259 I: Iterator<Item = Self>,
1260 {
1261 iter.fold(Self::IDENTITY, Self::mul)
1262 }
1263}
1264
1265impl<'a> Product<&'a Self> for DQuat {
1266 fn product<I>(iter: I) -> Self
1267 where
1268 I: Iterator<Item = &'a Self>,
1269 {
1270 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1271 }
1272}
1273
1274impl From<DQuat> for DVec4 {
1275 #[inline]
1276 fn from(q: DQuat) -> Self {
1277 Self::new(q.x, q.y, q.z, q.w)
1278 }
1279}
1280
1281impl From<DQuat> for (f64, f64, f64, f64) {
1282 #[inline]
1283 fn from(q: DQuat) -> Self {
1284 (q.x, q.y, q.z, q.w)
1285 }
1286}
1287
1288impl From<DQuat> for [f64; 4] {
1289 #[inline]
1290 fn from(q: DQuat) -> Self {
1291 [q.x, q.y, q.z, q.w]
1292 }
1293}