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 pub fn from_slice(slice: &[f64]) -> Self {
115 Self::from_xyzw(slice[0], slice[1], slice[2], slice[3])
116 }
117
118 #[inline]
124 pub fn write_to_slice(self, slice: &mut [f64]) {
125 slice[0] = self.x;
126 slice[1] = self.y;
127 slice[2] = self.z;
128 slice[3] = self.w;
129 }
130
131 #[inline]
139 #[must_use]
140 pub fn from_axis_angle(axis: DVec3, angle: f64) -> Self {
141 glam_assert!(axis.is_normalized());
142 let (s, c) = math::sin_cos(angle * 0.5);
143 let v = axis * s;
144 Self::from_xyzw(v.x, v.y, v.z, c)
145 }
146
147 #[inline]
151 #[must_use]
152 pub fn from_scaled_axis(v: DVec3) -> Self {
153 let length = v.length();
154 if length == 0.0 {
155 Self::IDENTITY
156 } else {
157 Self::from_axis_angle(v / length, length)
158 }
159 }
160
161 #[inline]
163 #[must_use]
164 pub fn from_rotation_x(angle: f64) -> Self {
165 let (s, c) = math::sin_cos(angle * 0.5);
166 Self::from_xyzw(s, 0.0, 0.0, c)
167 }
168
169 #[inline]
171 #[must_use]
172 pub fn from_rotation_y(angle: f64) -> Self {
173 let (s, c) = math::sin_cos(angle * 0.5);
174 Self::from_xyzw(0.0, s, 0.0, c)
175 }
176
177 #[inline]
179 #[must_use]
180 pub fn from_rotation_z(angle: f64) -> Self {
181 let (s, c) = math::sin_cos(angle * 0.5);
182 Self::from_xyzw(0.0, 0.0, s, c)
183 }
184
185 #[inline]
187 #[must_use]
188 pub fn from_euler(euler: EulerRot, a: f64, b: f64, c: f64) -> Self {
189 Self::from_euler_angles(euler, a, b, c)
190 }
191
192 #[inline]
201 #[must_use]
202 pub fn from_rotation_axes(x_axis: DVec3, y_axis: DVec3, z_axis: DVec3) -> Self {
203 glam_assert!(x_axis.is_normalized() && y_axis.is_normalized() && z_axis.is_normalized());
204 let (m00, m01, m02) = x_axis.into();
206 let (m10, m11, m12) = y_axis.into();
207 let (m20, m21, m22) = z_axis.into();
208 if m22 <= 0.0 {
209 let dif10 = m11 - m00;
211 let omm22 = 1.0 - m22;
212 if dif10 <= 0.0 {
213 let four_xsq = omm22 - dif10;
215 let inv4x = 0.5 / math::sqrt(four_xsq);
216 Self::from_xyzw(
217 four_xsq * inv4x,
218 (m01 + m10) * inv4x,
219 (m02 + m20) * inv4x,
220 (m12 - m21) * inv4x,
221 )
222 } else {
223 let four_ysq = omm22 + dif10;
225 let inv4y = 0.5 / math::sqrt(four_ysq);
226 Self::from_xyzw(
227 (m01 + m10) * inv4y,
228 four_ysq * inv4y,
229 (m12 + m21) * inv4y,
230 (m20 - m02) * inv4y,
231 )
232 }
233 } else {
234 let sum10 = m11 + m00;
236 let opm22 = 1.0 + m22;
237 if sum10 <= 0.0 {
238 let four_zsq = opm22 - sum10;
240 let inv4z = 0.5 / math::sqrt(four_zsq);
241 Self::from_xyzw(
242 (m02 + m20) * inv4z,
243 (m12 + m21) * inv4z,
244 four_zsq * inv4z,
245 (m01 - m10) * inv4z,
246 )
247 } else {
248 let four_wsq = opm22 + sum10;
250 let inv4w = 0.5 / math::sqrt(four_wsq);
251 Self::from_xyzw(
252 (m12 - m21) * inv4w,
253 (m20 - m02) * inv4w,
254 (m01 - m10) * inv4w,
255 four_wsq * inv4w,
256 )
257 }
258 }
259 }
260
261 #[inline]
270 #[must_use]
271 pub fn from_mat3(mat: &DMat3) -> Self {
272 Self::from_rotation_axes(mat.x_axis, mat.y_axis, mat.z_axis)
273 }
274
275 #[inline]
285 #[must_use]
286 pub fn from_mat4(mat: &DMat4) -> Self {
287 Self::from_rotation_axes(
288 mat.x_axis.truncate(),
289 mat.y_axis.truncate(),
290 mat.z_axis.truncate(),
291 )
292 }
293
294 #[must_use]
308 pub fn from_rotation_arc(from: DVec3, to: DVec3) -> Self {
309 glam_assert!(from.is_normalized());
310 glam_assert!(to.is_normalized());
311
312 const ONE_MINUS_EPS: f64 = 1.0 - 2.0 * f64::EPSILON;
313 let dot = from.dot(to);
314 if dot > ONE_MINUS_EPS {
315 Self::IDENTITY
317 } else if dot < -ONE_MINUS_EPS {
318 use core::f64::consts::PI; Self::from_axis_angle(from.any_orthonormal_vector(), PI)
321 } else {
322 let c = from.cross(to);
323 Self::from_xyzw(c.x, c.y, c.z, 1.0 + dot).normalize()
324 }
325 }
326
327 #[inline]
341 #[must_use]
342 pub fn from_rotation_arc_colinear(from: DVec3, to: DVec3) -> Self {
343 if from.dot(to) < 0.0 {
344 Self::from_rotation_arc(from, -to)
345 } else {
346 Self::from_rotation_arc(from, to)
347 }
348 }
349
350 #[must_use]
364 pub fn from_rotation_arc_2d(from: DVec2, to: DVec2) -> Self {
365 glam_assert!(from.is_normalized());
366 glam_assert!(to.is_normalized());
367
368 const ONE_MINUS_EPSILON: f64 = 1.0 - 2.0 * f64::EPSILON;
369 let dot = from.dot(to);
370 if dot > ONE_MINUS_EPSILON {
371 Self::IDENTITY
373 } else if dot < -ONE_MINUS_EPSILON {
374 const COS_FRAC_PI_2: f64 = 0.0;
376 const SIN_FRAC_PI_2: f64 = 1.0;
377 Self::from_xyzw(0.0, 0.0, SIN_FRAC_PI_2, COS_FRAC_PI_2)
379 } else {
380 let z = from.x * to.y - to.x * from.y;
382 let w = 1.0 + dot;
383 let len_rcp = 1.0 / math::sqrt(z * z + w * w);
385 Self::from_xyzw(0.0, 0.0, z * len_rcp, w * len_rcp)
386 }
387 }
388
389 #[deprecated(
397 since = "0.33.1",
398 note = "use the `glam::dcamera::lh::view::look_to_quat` function instead"
399 )]
400 #[inline]
401 #[must_use]
402 pub fn look_to_lh(dir: DVec3, up: DVec3) -> Self {
403 #[allow(deprecated)]
404 Self::look_to_rh(-dir, up)
405 }
406
407 #[deprecated(
415 since = "0.33.1",
416 note = "use the `glam::dcamera::rh::view::look_to_quat` function instead"
417 )]
418 #[inline]
419 #[must_use]
420 pub fn look_to_rh(dir: DVec3, up: DVec3) -> Self {
421 glam_assert!(dir.is_normalized());
422 glam_assert!(up.is_normalized());
423 let f = dir;
424 let s = f.cross(up).normalize();
425 let u = s.cross(f);
426
427 Self::from_rotation_axes(
428 DVec3::new(s.x, u.x, -f.x),
429 DVec3::new(s.y, u.y, -f.y),
430 DVec3::new(s.z, u.z, -f.z),
431 )
432 }
433
434 #[deprecated(
443 since = "0.33.1",
444 note = "use the `glam::dcamera::lh::view::look_at_quat` function instead"
445 )]
446 #[inline]
447 #[must_use]
448 pub fn look_at_lh(eye: DVec3, center: DVec3, up: DVec3) -> Self {
449 #[allow(deprecated)]
450 Self::look_to_lh(center.sub(eye).normalize(), up)
451 }
452
453 #[deprecated(
462 since = "0.33.1",
463 note = "use the `glam::dcamera::rh::view::look_at_quat` function instead"
464 )]
465 #[inline]
466 #[must_use]
467 pub fn look_at_rh(eye: DVec3, center: DVec3, up: DVec3) -> Self {
468 #[allow(deprecated)]
469 Self::look_to_rh(center.sub(eye).normalize(), up)
470 }
471
472 #[inline]
474 #[must_use]
475 pub fn to_axis_angle(self) -> (DVec3, f64) {
476 const EPSILON: f64 = 1.0e-8;
477 let v = DVec3::new(self.x, self.y, self.z);
478 let length = v.length();
479 if length >= EPSILON {
480 let angle = 2.0 * math::atan2(length, self.w);
481 let axis = v / length;
482 (axis, angle)
483 } else {
484 (DVec3::X, 0.0)
485 }
486 }
487
488 #[inline]
490 #[must_use]
491 pub fn to_scaled_axis(self) -> DVec3 {
492 let (axis, angle) = self.to_axis_angle();
493 axis * angle
494 }
495
496 #[inline]
498 #[must_use]
499 pub fn to_euler(self, order: EulerRot) -> (f64, f64, f64) {
500 self.to_euler_angles(order)
501 }
502
503 #[inline]
505 #[must_use]
506 pub const fn to_array(&self) -> [f64; 4] {
507 [self.x, self.y, self.z, self.w]
508 }
509
510 #[inline]
512 #[must_use]
513 pub fn xyz(self) -> DVec3 {
514 DVec3::new(self.x, self.y, self.z)
515 }
516
517 #[inline]
520 #[must_use]
521 pub fn conjugate(self) -> Self {
522 Self {
523 x: -self.x,
524 y: -self.y,
525 z: -self.z,
526 w: self.w,
527 }
528 }
529
530 #[inline]
540 #[must_use]
541 pub fn inverse(self) -> Self {
542 glam_assert!(self.is_normalized());
543 self.conjugate()
544 }
545
546 #[inline]
549 #[must_use]
550 pub fn dot(self, rhs: Self) -> f64 {
551 DVec4::from(self).dot(DVec4::from(rhs))
552 }
553
554 #[doc(alias = "magnitude")]
556 #[inline]
557 #[must_use]
558 pub fn length(self) -> f64 {
559 DVec4::from(self).length()
560 }
561
562 #[doc(alias = "magnitude2")]
567 #[inline]
568 #[must_use]
569 pub fn length_squared(self) -> f64 {
570 DVec4::from(self).length_squared()
571 }
572
573 #[inline]
577 #[must_use]
578 pub fn length_recip(self) -> f64 {
579 DVec4::from(self).length_recip()
580 }
581
582 #[inline]
590 #[must_use]
591 pub fn normalize(self) -> Self {
592 Self::from_vec4(DVec4::from(self).normalize())
593 }
594
595 #[inline]
598 #[must_use]
599 pub fn is_finite(self) -> bool {
600 DVec4::from(self).is_finite()
601 }
602
603 #[inline]
605 #[must_use]
606 pub fn is_nan(self) -> bool {
607 DVec4::from(self).is_nan()
608 }
609
610 #[inline]
614 #[must_use]
615 pub fn is_normalized(self) -> bool {
616 DVec4::from(self).is_normalized()
617 }
618
619 #[inline]
621 #[must_use]
622 pub fn is_near_identity(self) -> bool {
623 const THRESHOLD: f64 = 1.0 - 1e-14;
628 math::abs(self.w) > THRESHOLD
629 }
630
631 #[inline]
640 #[must_use]
641 pub fn angle_between(self, rhs: Self) -> f64 {
642 glam_assert!(self.is_normalized() && rhs.is_normalized());
643 math::acos_approx(math::abs(self.dot(rhs))) * 2.0
644 }
645
646 #[inline]
658 #[must_use]
659 pub fn rotate_towards(self, rhs: Self, max_angle: f64) -> Self {
660 glam_assert!(self.is_normalized() && rhs.is_normalized());
661 let angle = self.angle_between(rhs);
662 if angle <= 1e-4 {
663 return rhs;
664 }
665 let s = (max_angle / angle).clamp(-1.0, 1.0);
666 self.slerp(rhs, s)
667 }
668
669 #[inline]
679 #[must_use]
680 pub fn abs_diff_eq(self, rhs: Self, max_abs_diff: f64) -> bool {
681 DVec4::from(self).abs_diff_eq(DVec4::from(rhs), max_abs_diff)
682 }
683
684 #[inline(always)]
685 #[must_use]
686 fn lerp_impl(self, end: Self, s: f64) -> Self {
687 (self * (1.0 - s) + end * s).normalize()
688 }
689
690 #[doc(alias = "mix")]
703 #[inline]
704 #[must_use]
705 pub fn lerp(self, end: Self, s: f64) -> Self {
706 glam_assert!(self.is_normalized());
707 glam_assert!(end.is_normalized());
708
709 let dot = self.dot(end);
710 let bias = if dot >= 0.0 { 1.0 } else { -1.0 };
711 self.lerp_impl(end * bias, s)
712 }
713
714 #[inline(always)]
715 #[must_use]
716 fn slerp_impl(self, end: Self, dot: f64, s: f64) -> Self {
717 let theta = math::acos_approx(dot);
718
719 let scale1 = math::sin(theta * (1.0 - s));
720 let scale2 = math::sin(theta * s);
721 let theta_sin = math::sin(theta);
722 ((self * scale1) + (end * scale2)) * (1.0 / theta_sin)
723 }
724
725 #[inline]
735 #[must_use]
736 pub fn slerp(self, mut end: Self, s: f64) -> Self {
737 glam_assert!(self.is_normalized());
739 glam_assert!(end.is_normalized());
740
741 let mut dot = self.dot(end);
748 if dot < 0.0 {
749 end = -end;
750 dot = -dot;
751 }
752
753 const DOT_THRESHOLD: f64 = 1.0 - f64::EPSILON;
754 if dot > DOT_THRESHOLD {
755 self.lerp_impl(end, s)
757 } else {
758 self.slerp_impl(end, dot, s)
759 }
760 }
761
762 #[inline]
776 #[must_use]
777 pub fn slerp_long(self, end: Self, s: f64) -> Self {
778 glam_assert!(self.is_normalized());
779 glam_assert!(end.is_normalized());
780
781 let dot = self.dot(end);
782
783 const DOT_THRESHOLD: f64 = 1.0 - f64::EPSILON;
784 if dot.abs() > DOT_THRESHOLD {
785 self.lerp_impl(end, s)
787 } else {
788 self.slerp_impl(end, dot, s)
789 }
790 }
791
792 #[inline]
798 #[must_use]
799 pub fn mul_vec3(self, rhs: DVec3) -> DVec3 {
800 glam_assert!(self.is_normalized());
801
802 let w = self.w;
803 let b = DVec3::new(self.x, self.y, self.z);
804 let b2 = b.dot(b);
805 rhs.mul(w * w - b2)
806 .add(b.mul(rhs.dot(b) * 2.0))
807 .add(b.cross(rhs).mul(w * 2.0))
808 }
809
810 #[inline]
819 #[must_use]
820 pub fn mul_quat(self, rhs: Self) -> Self {
821 let (x0, y0, z0, w0) = self.into();
822 let (x1, y1, z1, w1) = rhs.into();
823 Self::from_xyzw(
824 w0 * x1 + x0 * w1 + y0 * z1 - z0 * y1,
825 w0 * y1 - x0 * z1 + y0 * w1 + z0 * x1,
826 w0 * z1 + x0 * y1 - y0 * x1 + z0 * w1,
827 w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1,
828 )
829 }
830
831 #[inline]
841 #[must_use]
842 pub fn from_affine3(a: &crate::DAffine3) -> Self {
843 Self::from_rotation_axes(a.matrix3.x_axis, a.matrix3.y_axis, a.matrix3.z_axis)
844 }
845
846 #[inline]
847 #[must_use]
848 pub fn as_quat(self) -> Quat {
849 Quat::from_xyzw(self.x as f32, self.y as f32, self.z as f32, self.w as f32)
850 }
851}
852
853impl fmt::Debug for DQuat {
854 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
855 fmt.debug_tuple(stringify!(DQuat))
856 .field(&self.x)
857 .field(&self.y)
858 .field(&self.z)
859 .field(&self.w)
860 .finish()
861 }
862}
863
864impl fmt::Display for DQuat {
865 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
866 if let Some(p) = f.precision() {
867 write!(
868 f,
869 "[{:.*}, {:.*}, {:.*}, {:.*}]",
870 p, self.x, p, self.y, p, self.z, p, self.w
871 )
872 } else {
873 write!(f, "[{}, {}, {}, {}]", self.x, self.y, self.z, self.w)
874 }
875 }
876}
877
878impl Add for DQuat {
879 type Output = Self;
880 #[inline]
887 fn add(self, rhs: Self) -> Self {
888 Self::from_vec4(DVec4::from(self) + DVec4::from(rhs))
889 }
890}
891
892impl Add<&Self> for DQuat {
893 type Output = Self;
894 #[inline]
895 fn add(self, rhs: &Self) -> Self {
896 self.add(*rhs)
897 }
898}
899
900impl Add<&DQuat> for &DQuat {
901 type Output = DQuat;
902 #[inline]
903 fn add(self, rhs: &DQuat) -> DQuat {
904 (*self).add(*rhs)
905 }
906}
907
908impl Add<DQuat> for &DQuat {
909 type Output = DQuat;
910 #[inline]
911 fn add(self, rhs: DQuat) -> DQuat {
912 (*self).add(rhs)
913 }
914}
915
916impl AddAssign for DQuat {
917 #[inline]
918 fn add_assign(&mut self, rhs: Self) {
919 *self = self.add(rhs);
920 }
921}
922
923impl AddAssign<&Self> for DQuat {
924 #[inline]
925 fn add_assign(&mut self, rhs: &Self) {
926 self.add_assign(*rhs);
927 }
928}
929
930impl Sub for DQuat {
931 type Output = Self;
932 #[inline]
936 fn sub(self, rhs: Self) -> Self {
937 Self::from_vec4(DVec4::from(self) - DVec4::from(rhs))
938 }
939}
940
941impl Sub<&Self> for DQuat {
942 type Output = Self;
943 #[inline]
944 fn sub(self, rhs: &Self) -> Self {
945 self.sub(*rhs)
946 }
947}
948
949impl Sub<&DQuat> for &DQuat {
950 type Output = DQuat;
951 #[inline]
952 fn sub(self, rhs: &DQuat) -> DQuat {
953 (*self).sub(*rhs)
954 }
955}
956
957impl Sub<DQuat> for &DQuat {
958 type Output = DQuat;
959 #[inline]
960 fn sub(self, rhs: DQuat) -> DQuat {
961 (*self).sub(rhs)
962 }
963}
964
965impl SubAssign for DQuat {
966 #[inline]
967 fn sub_assign(&mut self, rhs: Self) {
968 *self = self.sub(rhs);
969 }
970}
971
972impl SubAssign<&Self> for DQuat {
973 #[inline]
974 fn sub_assign(&mut self, rhs: &Self) {
975 self.sub_assign(*rhs);
976 }
977}
978
979impl Mul<f64> for DQuat {
980 type Output = Self;
981 #[inline]
985 fn mul(self, rhs: f64) -> Self {
986 Self::from_vec4(DVec4::from(self) * rhs)
987 }
988}
989
990impl Mul<&f64> for DQuat {
991 type Output = Self;
992 #[inline]
993 fn mul(self, rhs: &f64) -> Self {
994 self.mul(*rhs)
995 }
996}
997
998impl Mul<&f64> for &DQuat {
999 type Output = DQuat;
1000 #[inline]
1001 fn mul(self, rhs: &f64) -> DQuat {
1002 (*self).mul(*rhs)
1003 }
1004}
1005
1006impl Mul<f64> for &DQuat {
1007 type Output = DQuat;
1008 #[inline]
1009 fn mul(self, rhs: f64) -> DQuat {
1010 (*self).mul(rhs)
1011 }
1012}
1013
1014impl MulAssign<f64> for DQuat {
1015 #[inline]
1016 fn mul_assign(&mut self, rhs: f64) {
1017 *self = self.mul(rhs);
1018 }
1019}
1020
1021impl MulAssign<&f64> for DQuat {
1022 #[inline]
1023 fn mul_assign(&mut self, rhs: &f64) {
1024 self.mul_assign(*rhs);
1025 }
1026}
1027
1028impl Div<f64> for DQuat {
1029 type Output = Self;
1030 #[inline]
1033 fn div(self, rhs: f64) -> Self {
1034 Self::from_vec4(DVec4::from(self) / rhs)
1035 }
1036}
1037
1038impl Div<&f64> for DQuat {
1039 type Output = Self;
1040 #[inline]
1041 fn div(self, rhs: &f64) -> Self {
1042 self.div(*rhs)
1043 }
1044}
1045
1046impl Div<&f64> for &DQuat {
1047 type Output = DQuat;
1048 #[inline]
1049 fn div(self, rhs: &f64) -> DQuat {
1050 (*self).div(*rhs)
1051 }
1052}
1053
1054impl Div<f64> for &DQuat {
1055 type Output = DQuat;
1056 #[inline]
1057 fn div(self, rhs: f64) -> DQuat {
1058 (*self).div(rhs)
1059 }
1060}
1061
1062impl DivAssign<f64> for DQuat {
1063 #[inline]
1064 fn div_assign(&mut self, rhs: f64) {
1065 *self = self.div(rhs);
1066 }
1067}
1068
1069impl DivAssign<&f64> for DQuat {
1070 #[inline]
1071 fn div_assign(&mut self, rhs: &f64) {
1072 self.div_assign(*rhs);
1073 }
1074}
1075
1076impl Mul for DQuat {
1077 type Output = Self;
1078 #[inline]
1088 fn mul(self, rhs: Self) -> Self {
1089 self.mul_quat(rhs)
1090 }
1091}
1092
1093impl Mul<&Self> for DQuat {
1094 type Output = Self;
1095 #[inline]
1096 fn mul(self, rhs: &Self) -> Self {
1097 self.mul(*rhs)
1098 }
1099}
1100
1101impl Mul<&DQuat> for &DQuat {
1102 type Output = DQuat;
1103 #[inline]
1104 fn mul(self, rhs: &DQuat) -> DQuat {
1105 (*self).mul(*rhs)
1106 }
1107}
1108
1109impl Mul<DQuat> for &DQuat {
1110 type Output = DQuat;
1111 #[inline]
1112 fn mul(self, rhs: DQuat) -> DQuat {
1113 (*self).mul(rhs)
1114 }
1115}
1116
1117impl MulAssign for DQuat {
1118 #[inline]
1119 fn mul_assign(&mut self, rhs: Self) {
1120 *self = self.mul(rhs);
1121 }
1122}
1123
1124impl MulAssign<&Self> for DQuat {
1125 #[inline]
1126 fn mul_assign(&mut self, rhs: &Self) {
1127 self.mul_assign(*rhs);
1128 }
1129}
1130
1131impl Mul<DVec3> for DQuat {
1132 type Output = DVec3;
1133 #[inline]
1139 fn mul(self, rhs: DVec3) -> Self::Output {
1140 self.mul_vec3(rhs)
1141 }
1142}
1143
1144impl Mul<&DVec3> for DQuat {
1145 type Output = DVec3;
1146 #[inline]
1147 fn mul(self, rhs: &DVec3) -> DVec3 {
1148 self.mul(*rhs)
1149 }
1150}
1151
1152impl Mul<&DVec3> for &DQuat {
1153 type Output = DVec3;
1154 #[inline]
1155 fn mul(self, rhs: &DVec3) -> DVec3 {
1156 (*self).mul(*rhs)
1157 }
1158}
1159
1160impl Mul<DVec3> for &DQuat {
1161 type Output = DVec3;
1162 #[inline]
1163 fn mul(self, rhs: DVec3) -> DVec3 {
1164 (*self).mul(rhs)
1165 }
1166}
1167
1168impl Neg for DQuat {
1169 type Output = Self;
1170 #[inline]
1171 fn neg(self) -> Self {
1172 self * -1.0
1173 }
1174}
1175
1176impl Neg for &DQuat {
1177 type Output = DQuat;
1178 #[inline]
1179 fn neg(self) -> DQuat {
1180 (*self).neg()
1181 }
1182}
1183
1184impl Default for DQuat {
1185 #[inline]
1186 fn default() -> Self {
1187 Self::IDENTITY
1188 }
1189}
1190
1191impl PartialEq for DQuat {
1192 #[inline]
1193 fn eq(&self, rhs: &Self) -> bool {
1194 DVec4::from(*self).eq(&DVec4::from(*rhs))
1195 }
1196}
1197
1198impl AsRef<[f64; 4]> for DQuat {
1199 #[inline]
1200 fn as_ref(&self) -> &[f64; 4] {
1201 unsafe { &*(self as *const Self as *const [f64; 4]) }
1202 }
1203}
1204
1205impl Sum<Self> for DQuat {
1206 fn sum<I>(iter: I) -> Self
1207 where
1208 I: Iterator<Item = Self>,
1209 {
1210 iter.fold(Self::ZERO, Self::add)
1211 }
1212}
1213
1214impl<'a> Sum<&'a Self> for DQuat {
1215 fn sum<I>(iter: I) -> Self
1216 where
1217 I: Iterator<Item = &'a Self>,
1218 {
1219 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1220 }
1221}
1222
1223impl Product for DQuat {
1224 fn product<I>(iter: I) -> Self
1225 where
1226 I: Iterator<Item = Self>,
1227 {
1228 iter.fold(Self::IDENTITY, Self::mul)
1229 }
1230}
1231
1232impl<'a> Product<&'a Self> for DQuat {
1233 fn product<I>(iter: I) -> Self
1234 where
1235 I: Iterator<Item = &'a Self>,
1236 {
1237 iter.fold(Self::IDENTITY, |a, &b| Self::mul(a, b))
1238 }
1239}
1240
1241impl From<DQuat> for DVec4 {
1242 #[inline]
1243 fn from(q: DQuat) -> Self {
1244 Self::new(q.x, q.y, q.z, q.w)
1245 }
1246}
1247
1248impl From<DQuat> for (f64, f64, f64, f64) {
1249 #[inline]
1250 fn from(q: DQuat) -> Self {
1251 (q.x, q.y, q.z, q.w)
1252 }
1253}
1254
1255impl From<DQuat> for [f64; 4] {
1256 #[inline]
1257 fn from(q: DQuat) -> Self {
1258 [q.x, q.y, q.z, q.w]
1259 }
1260}