1use crate::{f64::math, BVec3, BVec3A, DVec2, DVec4, IVec3, UVec3, Vec3};
4
5#[cfg(not(target_arch = "spirv"))]
6use core::fmt;
7use core::iter::{Product, Sum};
8use core::{f32, ops::*};
9
10#[inline(always)]
12#[must_use]
13pub const fn dvec3(x: f64, y: f64, z: f64) -> DVec3 {
14 DVec3::new(x, y, z)
15}
16
17#[derive(Clone, Copy, PartialEq)]
19#[cfg_attr(not(target_arch = "spirv"), repr(C))]
20#[cfg_attr(target_arch = "spirv", repr(simd))]
21pub struct DVec3 {
22 pub x: f64,
23 pub y: f64,
24 pub z: f64,
25}
26
27impl DVec3 {
28 pub const ZERO: Self = Self::splat(0.0);
30
31 pub const ONE: Self = Self::splat(1.0);
33
34 pub const NEG_ONE: Self = Self::splat(-1.0);
36
37 pub const MIN: Self = Self::splat(f64::MIN);
39
40 pub const MAX: Self = Self::splat(f64::MAX);
42
43 pub const NAN: Self = Self::splat(f64::NAN);
45
46 pub const INFINITY: Self = Self::splat(f64::INFINITY);
48
49 pub const NEG_INFINITY: Self = Self::splat(f64::NEG_INFINITY);
51
52 pub const X: Self = Self::new(1.0, 0.0, 0.0);
54
55 pub const Y: Self = Self::new(0.0, 1.0, 0.0);
57
58 pub const Z: Self = Self::new(0.0, 0.0, 1.0);
60
61 pub const NEG_X: Self = Self::new(-1.0, 0.0, 0.0);
63
64 pub const NEG_Y: Self = Self::new(0.0, -1.0, 0.0);
66
67 pub const NEG_Z: Self = Self::new(0.0, 0.0, -1.0);
69
70 pub const AXES: [Self; 3] = [Self::X, Self::Y, Self::Z];
72
73 #[inline(always)]
75 #[must_use]
76 pub const fn new(x: f64, y: f64, z: f64) -> Self {
77 Self { x, y, z }
78 }
79
80 #[inline]
82 #[must_use]
83 pub const fn splat(v: f64) -> Self {
84 Self { x: v, y: v, z: v }
85 }
86
87 #[inline]
93 #[must_use]
94 pub fn select(mask: BVec3, if_true: Self, if_false: Self) -> Self {
95 Self {
96 x: if mask.test(0) { if_true.x } else { if_false.x },
97 y: if mask.test(1) { if_true.y } else { if_false.y },
98 z: if mask.test(2) { if_true.z } else { if_false.z },
99 }
100 }
101
102 #[inline]
104 #[must_use]
105 pub const fn from_array(a: [f64; 3]) -> Self {
106 Self::new(a[0], a[1], a[2])
107 }
108
109 #[inline]
111 #[must_use]
112 pub const fn to_array(&self) -> [f64; 3] {
113 [self.x, self.y, self.z]
114 }
115
116 #[inline]
122 #[must_use]
123 pub const fn from_slice(slice: &[f64]) -> Self {
124 Self::new(slice[0], slice[1], slice[2])
125 }
126
127 #[inline]
133 pub fn write_to_slice(self, slice: &mut [f64]) {
134 slice[0] = self.x;
135 slice[1] = self.y;
136 slice[2] = self.z;
137 }
138
139 #[allow(dead_code)]
141 #[inline]
142 #[must_use]
143 pub(crate) fn from_vec4(v: DVec4) -> Self {
144 Self {
145 x: v.x,
146 y: v.y,
147 z: v.z,
148 }
149 }
150
151 #[inline]
153 #[must_use]
154 pub fn extend(self, w: f64) -> DVec4 {
155 DVec4::new(self.x, self.y, self.z, w)
156 }
157
158 #[inline]
162 #[must_use]
163 pub fn truncate(self) -> DVec2 {
164 use crate::swizzles::Vec3Swizzles;
165 self.xy()
166 }
167
168 #[inline]
170 #[must_use]
171 pub fn with_x(mut self, x: f64) -> Self {
172 self.x = x;
173 self
174 }
175
176 #[inline]
178 #[must_use]
179 pub fn with_y(mut self, y: f64) -> Self {
180 self.y = y;
181 self
182 }
183
184 #[inline]
186 #[must_use]
187 pub fn with_z(mut self, z: f64) -> Self {
188 self.z = z;
189 self
190 }
191
192 #[inline]
194 #[must_use]
195 pub fn dot(self, rhs: Self) -> f64 {
196 (self.x * rhs.x) + (self.y * rhs.y) + (self.z * rhs.z)
197 }
198
199 #[inline]
201 #[must_use]
202 pub fn dot_into_vec(self, rhs: Self) -> Self {
203 Self::splat(self.dot(rhs))
204 }
205
206 #[inline]
208 #[must_use]
209 pub fn cross(self, rhs: Self) -> Self {
210 Self {
211 x: self.y * rhs.z - rhs.y * self.z,
212 y: self.z * rhs.x - rhs.z * self.x,
213 z: self.x * rhs.y - rhs.x * self.y,
214 }
215 }
216
217 #[inline]
221 #[must_use]
222 pub fn min(self, rhs: Self) -> Self {
223 Self {
224 x: self.x.min(rhs.x),
225 y: self.y.min(rhs.y),
226 z: self.z.min(rhs.z),
227 }
228 }
229
230 #[inline]
234 #[must_use]
235 pub fn max(self, rhs: Self) -> Self {
236 Self {
237 x: self.x.max(rhs.x),
238 y: self.y.max(rhs.y),
239 z: self.z.max(rhs.z),
240 }
241 }
242
243 #[inline]
251 #[must_use]
252 pub fn clamp(self, min: Self, max: Self) -> Self {
253 glam_assert!(min.cmple(max).all(), "clamp: expected min <= max");
254 self.max(min).min(max)
255 }
256
257 #[inline]
261 #[must_use]
262 pub fn min_element(self) -> f64 {
263 self.x.min(self.y.min(self.z))
264 }
265
266 #[inline]
270 #[must_use]
271 pub fn max_element(self) -> f64 {
272 self.x.max(self.y.max(self.z))
273 }
274
275 #[inline]
279 #[must_use]
280 pub fn element_sum(self) -> f64 {
281 self.x + self.y + self.z
282 }
283
284 #[inline]
288 #[must_use]
289 pub fn element_product(self) -> f64 {
290 self.x * self.y * self.z
291 }
292
293 #[inline]
299 #[must_use]
300 pub fn cmpeq(self, rhs: Self) -> BVec3 {
301 BVec3::new(self.x.eq(&rhs.x), self.y.eq(&rhs.y), self.z.eq(&rhs.z))
302 }
303
304 #[inline]
310 #[must_use]
311 pub fn cmpne(self, rhs: Self) -> BVec3 {
312 BVec3::new(self.x.ne(&rhs.x), self.y.ne(&rhs.y), self.z.ne(&rhs.z))
313 }
314
315 #[inline]
321 #[must_use]
322 pub fn cmpge(self, rhs: Self) -> BVec3 {
323 BVec3::new(self.x.ge(&rhs.x), self.y.ge(&rhs.y), self.z.ge(&rhs.z))
324 }
325
326 #[inline]
332 #[must_use]
333 pub fn cmpgt(self, rhs: Self) -> BVec3 {
334 BVec3::new(self.x.gt(&rhs.x), self.y.gt(&rhs.y), self.z.gt(&rhs.z))
335 }
336
337 #[inline]
343 #[must_use]
344 pub fn cmple(self, rhs: Self) -> BVec3 {
345 BVec3::new(self.x.le(&rhs.x), self.y.le(&rhs.y), self.z.le(&rhs.z))
346 }
347
348 #[inline]
354 #[must_use]
355 pub fn cmplt(self, rhs: Self) -> BVec3 {
356 BVec3::new(self.x.lt(&rhs.x), self.y.lt(&rhs.y), self.z.lt(&rhs.z))
357 }
358
359 #[inline]
361 #[must_use]
362 pub fn abs(self) -> Self {
363 Self {
364 x: math::abs(self.x),
365 y: math::abs(self.y),
366 z: math::abs(self.z),
367 }
368 }
369
370 #[inline]
376 #[must_use]
377 pub fn signum(self) -> Self {
378 Self {
379 x: math::signum(self.x),
380 y: math::signum(self.y),
381 z: math::signum(self.z),
382 }
383 }
384
385 #[inline]
387 #[must_use]
388 pub fn copysign(self, rhs: Self) -> Self {
389 Self {
390 x: math::copysign(self.x, rhs.x),
391 y: math::copysign(self.y, rhs.y),
392 z: math::copysign(self.z, rhs.z),
393 }
394 }
395
396 #[inline]
401 #[must_use]
402 pub fn is_negative_bitmask(self) -> u32 {
403 (self.x.is_sign_negative() as u32)
404 | (self.y.is_sign_negative() as u32) << 1
405 | (self.z.is_sign_negative() as u32) << 2
406 }
407
408 #[inline]
411 #[must_use]
412 pub fn is_finite(self) -> bool {
413 self.x.is_finite() && self.y.is_finite() && self.z.is_finite()
414 }
415
416 #[inline]
418 #[must_use]
419 pub fn is_nan(self) -> bool {
420 self.x.is_nan() || self.y.is_nan() || self.z.is_nan()
421 }
422
423 #[inline]
427 #[must_use]
428 pub fn is_nan_mask(self) -> BVec3 {
429 BVec3::new(self.x.is_nan(), self.y.is_nan(), self.z.is_nan())
430 }
431
432 #[doc(alias = "magnitude")]
434 #[inline]
435 #[must_use]
436 pub fn length(self) -> f64 {
437 math::sqrt(self.dot(self))
438 }
439
440 #[doc(alias = "magnitude2")]
444 #[inline]
445 #[must_use]
446 pub fn length_squared(self) -> f64 {
447 self.dot(self)
448 }
449
450 #[inline]
454 #[must_use]
455 pub fn length_recip(self) -> f64 {
456 self.length().recip()
457 }
458
459 #[inline]
461 #[must_use]
462 pub fn distance(self, rhs: Self) -> f64 {
463 (self - rhs).length()
464 }
465
466 #[inline]
468 #[must_use]
469 pub fn distance_squared(self, rhs: Self) -> f64 {
470 (self - rhs).length_squared()
471 }
472
473 #[inline]
475 #[must_use]
476 pub fn div_euclid(self, rhs: Self) -> Self {
477 Self::new(
478 math::div_euclid(self.x, rhs.x),
479 math::div_euclid(self.y, rhs.y),
480 math::div_euclid(self.z, rhs.z),
481 )
482 }
483
484 #[inline]
488 #[must_use]
489 pub fn rem_euclid(self, rhs: Self) -> Self {
490 Self::new(
491 math::rem_euclid(self.x, rhs.x),
492 math::rem_euclid(self.y, rhs.y),
493 math::rem_euclid(self.z, rhs.z),
494 )
495 }
496
497 #[inline]
507 #[must_use]
508 pub fn normalize(self) -> Self {
509 #[allow(clippy::let_and_return)]
510 let normalized = self.mul(self.length_recip());
511 glam_assert!(normalized.is_finite());
512 normalized
513 }
514
515 #[inline]
522 #[must_use]
523 pub fn try_normalize(self) -> Option<Self> {
524 let rcp = self.length_recip();
525 if rcp.is_finite() && rcp > 0.0 {
526 Some(self * rcp)
527 } else {
528 None
529 }
530 }
531
532 #[inline]
540 #[must_use]
541 pub fn normalize_or(self, fallback: Self) -> Self {
542 let rcp = self.length_recip();
543 if rcp.is_finite() && rcp > 0.0 {
544 self * rcp
545 } else {
546 fallback
547 }
548 }
549
550 #[inline]
557 #[must_use]
558 pub fn normalize_or_zero(self) -> Self {
559 self.normalize_or(Self::ZERO)
560 }
561
562 #[inline]
566 #[must_use]
567 pub fn is_normalized(self) -> bool {
568 math::abs(self.length_squared() - 1.0) <= 2e-4
569 }
570
571 #[inline]
579 #[must_use]
580 pub fn project_onto(self, rhs: Self) -> Self {
581 let other_len_sq_rcp = rhs.dot(rhs).recip();
582 glam_assert!(other_len_sq_rcp.is_finite());
583 rhs * self.dot(rhs) * other_len_sq_rcp
584 }
585
586 #[inline]
597 #[must_use]
598 pub fn reject_from(self, rhs: Self) -> Self {
599 self - self.project_onto(rhs)
600 }
601
602 #[inline]
610 #[must_use]
611 pub fn project_onto_normalized(self, rhs: Self) -> Self {
612 glam_assert!(rhs.is_normalized());
613 rhs * self.dot(rhs)
614 }
615
616 #[inline]
627 #[must_use]
628 pub fn reject_from_normalized(self, rhs: Self) -> Self {
629 self - self.project_onto_normalized(rhs)
630 }
631
632 #[inline]
635 #[must_use]
636 pub fn round(self) -> Self {
637 Self {
638 x: math::round(self.x),
639 y: math::round(self.y),
640 z: math::round(self.z),
641 }
642 }
643
644 #[inline]
647 #[must_use]
648 pub fn floor(self) -> Self {
649 Self {
650 x: math::floor(self.x),
651 y: math::floor(self.y),
652 z: math::floor(self.z),
653 }
654 }
655
656 #[inline]
659 #[must_use]
660 pub fn ceil(self) -> Self {
661 Self {
662 x: math::ceil(self.x),
663 y: math::ceil(self.y),
664 z: math::ceil(self.z),
665 }
666 }
667
668 #[inline]
671 #[must_use]
672 pub fn trunc(self) -> Self {
673 Self {
674 x: math::trunc(self.x),
675 y: math::trunc(self.y),
676 z: math::trunc(self.z),
677 }
678 }
679
680 #[inline]
687 #[must_use]
688 pub fn fract(self) -> Self {
689 self - self.trunc()
690 }
691
692 #[inline]
699 #[must_use]
700 pub fn fract_gl(self) -> Self {
701 self - self.floor()
702 }
703
704 #[inline]
707 #[must_use]
708 pub fn exp(self) -> Self {
709 Self::new(math::exp(self.x), math::exp(self.y), math::exp(self.z))
710 }
711
712 #[inline]
714 #[must_use]
715 pub fn powf(self, n: f64) -> Self {
716 Self::new(
717 math::powf(self.x, n),
718 math::powf(self.y, n),
719 math::powf(self.z, n),
720 )
721 }
722
723 #[inline]
725 #[must_use]
726 pub fn recip(self) -> Self {
727 Self {
728 x: 1.0 / self.x,
729 y: 1.0 / self.y,
730 z: 1.0 / self.z,
731 }
732 }
733
734 #[doc(alias = "mix")]
740 #[inline]
741 #[must_use]
742 pub fn lerp(self, rhs: Self, s: f64) -> Self {
743 self + ((rhs - self) * s)
744 }
745
746 #[inline]
751 #[must_use]
752 pub fn move_towards(&self, rhs: Self, d: f64) -> Self {
753 let a = rhs - *self;
754 let len = a.length();
755 if len <= d || len <= 1e-4 {
756 return rhs;
757 }
758 *self + a / len * d
759 }
760
761 #[inline]
767 pub fn midpoint(self, rhs: Self) -> Self {
768 (self + rhs) * 0.5
769 }
770
771 #[inline]
781 #[must_use]
782 pub fn abs_diff_eq(self, rhs: Self, max_abs_diff: f64) -> bool {
783 self.sub(rhs).abs().cmple(Self::splat(max_abs_diff)).all()
784 }
785
786 #[inline]
792 #[must_use]
793 pub fn clamp_length(self, min: f64, max: f64) -> Self {
794 glam_assert!(min <= max);
795 let length_sq = self.length_squared();
796 if length_sq < min * min {
797 min * (self / math::sqrt(length_sq))
798 } else if length_sq > max * max {
799 max * (self / math::sqrt(length_sq))
800 } else {
801 self
802 }
803 }
804
805 #[inline]
807 #[must_use]
808 pub fn clamp_length_max(self, max: f64) -> Self {
809 let length_sq = self.length_squared();
810 if length_sq > max * max {
811 max * (self / math::sqrt(length_sq))
812 } else {
813 self
814 }
815 }
816
817 #[inline]
819 #[must_use]
820 pub fn clamp_length_min(self, min: f64) -> Self {
821 let length_sq = self.length_squared();
822 if length_sq < min * min {
823 min * (self / math::sqrt(length_sq))
824 } else {
825 self
826 }
827 }
828
829 #[inline]
837 #[must_use]
838 pub fn mul_add(self, a: Self, b: Self) -> Self {
839 Self::new(
840 math::mul_add(self.x, a.x, b.x),
841 math::mul_add(self.y, a.y, b.y),
842 math::mul_add(self.z, a.z, b.z),
843 )
844 }
845
846 #[inline]
850 #[must_use]
851 pub fn angle_between(self, rhs: Self) -> f64 {
852 math::acos_approx(
853 self.dot(rhs)
854 .div(math::sqrt(self.length_squared().mul(rhs.length_squared()))),
855 )
856 }
857
858 #[inline]
865 #[must_use]
866 pub fn any_orthogonal_vector(&self) -> Self {
867 if math::abs(self.x) > math::abs(self.y) {
869 Self::new(-self.z, 0.0, self.x) } else {
871 Self::new(0.0, self.z, -self.y) }
873 }
874
875 #[inline]
883 #[must_use]
884 pub fn any_orthonormal_vector(&self) -> Self {
885 glam_assert!(self.is_normalized());
886 let sign = math::signum(self.z);
888 let a = -1.0 / (sign + self.z);
889 let b = self.x * self.y * a;
890 Self::new(b, sign + self.y * self.y * a, -self.y)
891 }
892
893 #[inline]
900 #[must_use]
901 pub fn any_orthonormal_pair(&self) -> (Self, Self) {
902 glam_assert!(self.is_normalized());
903 let sign = math::signum(self.z);
905 let a = -1.0 / (sign + self.z);
906 let b = self.x * self.y * a;
907 (
908 Self::new(1.0 + sign * self.x * self.x * a, sign * b, -sign * self.x),
909 Self::new(b, sign + self.y * self.y * a, -self.y),
910 )
911 }
912
913 #[inline]
915 #[must_use]
916 pub fn as_vec3(&self) -> crate::Vec3 {
917 crate::Vec3::new(self.x as f32, self.y as f32, self.z as f32)
918 }
919
920 #[inline]
922 #[must_use]
923 pub fn as_vec3a(&self) -> crate::Vec3A {
924 crate::Vec3A::new(self.x as f32, self.y as f32, self.z as f32)
925 }
926
927 #[inline]
929 #[must_use]
930 pub fn as_i16vec3(&self) -> crate::I16Vec3 {
931 crate::I16Vec3::new(self.x as i16, self.y as i16, self.z as i16)
932 }
933
934 #[inline]
936 #[must_use]
937 pub fn as_u16vec3(&self) -> crate::U16Vec3 {
938 crate::U16Vec3::new(self.x as u16, self.y as u16, self.z as u16)
939 }
940
941 #[inline]
943 #[must_use]
944 pub fn as_ivec3(&self) -> crate::IVec3 {
945 crate::IVec3::new(self.x as i32, self.y as i32, self.z as i32)
946 }
947
948 #[inline]
950 #[must_use]
951 pub fn as_uvec3(&self) -> crate::UVec3 {
952 crate::UVec3::new(self.x as u32, self.y as u32, self.z as u32)
953 }
954
955 #[inline]
957 #[must_use]
958 pub fn as_i64vec3(&self) -> crate::I64Vec3 {
959 crate::I64Vec3::new(self.x as i64, self.y as i64, self.z as i64)
960 }
961
962 #[inline]
964 #[must_use]
965 pub fn as_u64vec3(&self) -> crate::U64Vec3 {
966 crate::U64Vec3::new(self.x as u64, self.y as u64, self.z as u64)
967 }
968}
969
970impl Default for DVec3 {
971 #[inline(always)]
972 fn default() -> Self {
973 Self::ZERO
974 }
975}
976
977impl Div<DVec3> for DVec3 {
978 type Output = Self;
979 #[inline]
980 fn div(self, rhs: Self) -> Self {
981 Self {
982 x: self.x.div(rhs.x),
983 y: self.y.div(rhs.y),
984 z: self.z.div(rhs.z),
985 }
986 }
987}
988
989impl DivAssign<DVec3> for DVec3 {
990 #[inline]
991 fn div_assign(&mut self, rhs: Self) {
992 self.x.div_assign(rhs.x);
993 self.y.div_assign(rhs.y);
994 self.z.div_assign(rhs.z);
995 }
996}
997
998impl Div<f64> for DVec3 {
999 type Output = Self;
1000 #[inline]
1001 fn div(self, rhs: f64) -> Self {
1002 Self {
1003 x: self.x.div(rhs),
1004 y: self.y.div(rhs),
1005 z: self.z.div(rhs),
1006 }
1007 }
1008}
1009
1010impl DivAssign<f64> for DVec3 {
1011 #[inline]
1012 fn div_assign(&mut self, rhs: f64) {
1013 self.x.div_assign(rhs);
1014 self.y.div_assign(rhs);
1015 self.z.div_assign(rhs);
1016 }
1017}
1018
1019impl Div<DVec3> for f64 {
1020 type Output = DVec3;
1021 #[inline]
1022 fn div(self, rhs: DVec3) -> DVec3 {
1023 DVec3 {
1024 x: self.div(rhs.x),
1025 y: self.div(rhs.y),
1026 z: self.div(rhs.z),
1027 }
1028 }
1029}
1030
1031impl Mul<DVec3> for DVec3 {
1032 type Output = Self;
1033 #[inline]
1034 fn mul(self, rhs: Self) -> Self {
1035 Self {
1036 x: self.x.mul(rhs.x),
1037 y: self.y.mul(rhs.y),
1038 z: self.z.mul(rhs.z),
1039 }
1040 }
1041}
1042
1043impl MulAssign<DVec3> for DVec3 {
1044 #[inline]
1045 fn mul_assign(&mut self, rhs: Self) {
1046 self.x.mul_assign(rhs.x);
1047 self.y.mul_assign(rhs.y);
1048 self.z.mul_assign(rhs.z);
1049 }
1050}
1051
1052impl Mul<f64> for DVec3 {
1053 type Output = Self;
1054 #[inline]
1055 fn mul(self, rhs: f64) -> Self {
1056 Self {
1057 x: self.x.mul(rhs),
1058 y: self.y.mul(rhs),
1059 z: self.z.mul(rhs),
1060 }
1061 }
1062}
1063
1064impl MulAssign<f64> for DVec3 {
1065 #[inline]
1066 fn mul_assign(&mut self, rhs: f64) {
1067 self.x.mul_assign(rhs);
1068 self.y.mul_assign(rhs);
1069 self.z.mul_assign(rhs);
1070 }
1071}
1072
1073impl Mul<DVec3> for f64 {
1074 type Output = DVec3;
1075 #[inline]
1076 fn mul(self, rhs: DVec3) -> DVec3 {
1077 DVec3 {
1078 x: self.mul(rhs.x),
1079 y: self.mul(rhs.y),
1080 z: self.mul(rhs.z),
1081 }
1082 }
1083}
1084
1085impl Add<DVec3> for DVec3 {
1086 type Output = Self;
1087 #[inline]
1088 fn add(self, rhs: Self) -> Self {
1089 Self {
1090 x: self.x.add(rhs.x),
1091 y: self.y.add(rhs.y),
1092 z: self.z.add(rhs.z),
1093 }
1094 }
1095}
1096
1097impl AddAssign<DVec3> for DVec3 {
1098 #[inline]
1099 fn add_assign(&mut self, rhs: Self) {
1100 self.x.add_assign(rhs.x);
1101 self.y.add_assign(rhs.y);
1102 self.z.add_assign(rhs.z);
1103 }
1104}
1105
1106impl Add<f64> for DVec3 {
1107 type Output = Self;
1108 #[inline]
1109 fn add(self, rhs: f64) -> Self {
1110 Self {
1111 x: self.x.add(rhs),
1112 y: self.y.add(rhs),
1113 z: self.z.add(rhs),
1114 }
1115 }
1116}
1117
1118impl AddAssign<f64> for DVec3 {
1119 #[inline]
1120 fn add_assign(&mut self, rhs: f64) {
1121 self.x.add_assign(rhs);
1122 self.y.add_assign(rhs);
1123 self.z.add_assign(rhs);
1124 }
1125}
1126
1127impl Add<DVec3> for f64 {
1128 type Output = DVec3;
1129 #[inline]
1130 fn add(self, rhs: DVec3) -> DVec3 {
1131 DVec3 {
1132 x: self.add(rhs.x),
1133 y: self.add(rhs.y),
1134 z: self.add(rhs.z),
1135 }
1136 }
1137}
1138
1139impl Sub<DVec3> for DVec3 {
1140 type Output = Self;
1141 #[inline]
1142 fn sub(self, rhs: Self) -> Self {
1143 Self {
1144 x: self.x.sub(rhs.x),
1145 y: self.y.sub(rhs.y),
1146 z: self.z.sub(rhs.z),
1147 }
1148 }
1149}
1150
1151impl SubAssign<DVec3> for DVec3 {
1152 #[inline]
1153 fn sub_assign(&mut self, rhs: DVec3) {
1154 self.x.sub_assign(rhs.x);
1155 self.y.sub_assign(rhs.y);
1156 self.z.sub_assign(rhs.z);
1157 }
1158}
1159
1160impl Sub<f64> for DVec3 {
1161 type Output = Self;
1162 #[inline]
1163 fn sub(self, rhs: f64) -> Self {
1164 Self {
1165 x: self.x.sub(rhs),
1166 y: self.y.sub(rhs),
1167 z: self.z.sub(rhs),
1168 }
1169 }
1170}
1171
1172impl SubAssign<f64> for DVec3 {
1173 #[inline]
1174 fn sub_assign(&mut self, rhs: f64) {
1175 self.x.sub_assign(rhs);
1176 self.y.sub_assign(rhs);
1177 self.z.sub_assign(rhs);
1178 }
1179}
1180
1181impl Sub<DVec3> for f64 {
1182 type Output = DVec3;
1183 #[inline]
1184 fn sub(self, rhs: DVec3) -> DVec3 {
1185 DVec3 {
1186 x: self.sub(rhs.x),
1187 y: self.sub(rhs.y),
1188 z: self.sub(rhs.z),
1189 }
1190 }
1191}
1192
1193impl Rem<DVec3> for DVec3 {
1194 type Output = Self;
1195 #[inline]
1196 fn rem(self, rhs: Self) -> Self {
1197 Self {
1198 x: self.x.rem(rhs.x),
1199 y: self.y.rem(rhs.y),
1200 z: self.z.rem(rhs.z),
1201 }
1202 }
1203}
1204
1205impl RemAssign<DVec3> for DVec3 {
1206 #[inline]
1207 fn rem_assign(&mut self, rhs: Self) {
1208 self.x.rem_assign(rhs.x);
1209 self.y.rem_assign(rhs.y);
1210 self.z.rem_assign(rhs.z);
1211 }
1212}
1213
1214impl Rem<f64> for DVec3 {
1215 type Output = Self;
1216 #[inline]
1217 fn rem(self, rhs: f64) -> Self {
1218 Self {
1219 x: self.x.rem(rhs),
1220 y: self.y.rem(rhs),
1221 z: self.z.rem(rhs),
1222 }
1223 }
1224}
1225
1226impl RemAssign<f64> for DVec3 {
1227 #[inline]
1228 fn rem_assign(&mut self, rhs: f64) {
1229 self.x.rem_assign(rhs);
1230 self.y.rem_assign(rhs);
1231 self.z.rem_assign(rhs);
1232 }
1233}
1234
1235impl Rem<DVec3> for f64 {
1236 type Output = DVec3;
1237 #[inline]
1238 fn rem(self, rhs: DVec3) -> DVec3 {
1239 DVec3 {
1240 x: self.rem(rhs.x),
1241 y: self.rem(rhs.y),
1242 z: self.rem(rhs.z),
1243 }
1244 }
1245}
1246
1247#[cfg(not(target_arch = "spirv"))]
1248impl AsRef<[f64; 3]> for DVec3 {
1249 #[inline]
1250 fn as_ref(&self) -> &[f64; 3] {
1251 unsafe { &*(self as *const DVec3 as *const [f64; 3]) }
1252 }
1253}
1254
1255#[cfg(not(target_arch = "spirv"))]
1256impl AsMut<[f64; 3]> for DVec3 {
1257 #[inline]
1258 fn as_mut(&mut self) -> &mut [f64; 3] {
1259 unsafe { &mut *(self as *mut DVec3 as *mut [f64; 3]) }
1260 }
1261}
1262
1263impl Sum for DVec3 {
1264 #[inline]
1265 fn sum<I>(iter: I) -> Self
1266 where
1267 I: Iterator<Item = Self>,
1268 {
1269 iter.fold(Self::ZERO, Self::add)
1270 }
1271}
1272
1273impl<'a> Sum<&'a Self> for DVec3 {
1274 #[inline]
1275 fn sum<I>(iter: I) -> Self
1276 where
1277 I: Iterator<Item = &'a Self>,
1278 {
1279 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1280 }
1281}
1282
1283impl Product for DVec3 {
1284 #[inline]
1285 fn product<I>(iter: I) -> Self
1286 where
1287 I: Iterator<Item = Self>,
1288 {
1289 iter.fold(Self::ONE, Self::mul)
1290 }
1291}
1292
1293impl<'a> Product<&'a Self> for DVec3 {
1294 #[inline]
1295 fn product<I>(iter: I) -> Self
1296 where
1297 I: Iterator<Item = &'a Self>,
1298 {
1299 iter.fold(Self::ONE, |a, &b| Self::mul(a, b))
1300 }
1301}
1302
1303impl Neg for DVec3 {
1304 type Output = Self;
1305 #[inline]
1306 fn neg(self) -> Self {
1307 Self {
1308 x: self.x.neg(),
1309 y: self.y.neg(),
1310 z: self.z.neg(),
1311 }
1312 }
1313}
1314
1315impl Index<usize> for DVec3 {
1316 type Output = f64;
1317 #[inline]
1318 fn index(&self, index: usize) -> &Self::Output {
1319 match index {
1320 0 => &self.x,
1321 1 => &self.y,
1322 2 => &self.z,
1323 _ => panic!("index out of bounds"),
1324 }
1325 }
1326}
1327
1328impl IndexMut<usize> for DVec3 {
1329 #[inline]
1330 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1331 match index {
1332 0 => &mut self.x,
1333 1 => &mut self.y,
1334 2 => &mut self.z,
1335 _ => panic!("index out of bounds"),
1336 }
1337 }
1338}
1339
1340#[cfg(not(target_arch = "spirv"))]
1341impl fmt::Display for DVec3 {
1342 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1343 if let Some(p) = f.precision() {
1344 write!(f, "[{:.*}, {:.*}, {:.*}]", p, self.x, p, self.y, p, self.z)
1345 } else {
1346 write!(f, "[{}, {}, {}]", self.x, self.y, self.z)
1347 }
1348 }
1349}
1350
1351#[cfg(not(target_arch = "spirv"))]
1352impl fmt::Debug for DVec3 {
1353 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1354 fmt.debug_tuple(stringify!(DVec3))
1355 .field(&self.x)
1356 .field(&self.y)
1357 .field(&self.z)
1358 .finish()
1359 }
1360}
1361
1362impl From<[f64; 3]> for DVec3 {
1363 #[inline]
1364 fn from(a: [f64; 3]) -> Self {
1365 Self::new(a[0], a[1], a[2])
1366 }
1367}
1368
1369impl From<DVec3> for [f64; 3] {
1370 #[inline]
1371 fn from(v: DVec3) -> Self {
1372 [v.x, v.y, v.z]
1373 }
1374}
1375
1376impl From<(f64, f64, f64)> for DVec3 {
1377 #[inline]
1378 fn from(t: (f64, f64, f64)) -> Self {
1379 Self::new(t.0, t.1, t.2)
1380 }
1381}
1382
1383impl From<DVec3> for (f64, f64, f64) {
1384 #[inline]
1385 fn from(v: DVec3) -> Self {
1386 (v.x, v.y, v.z)
1387 }
1388}
1389
1390impl From<(DVec2, f64)> for DVec3 {
1391 #[inline]
1392 fn from((v, z): (DVec2, f64)) -> Self {
1393 Self::new(v.x, v.y, z)
1394 }
1395}
1396
1397impl From<Vec3> for DVec3 {
1398 #[inline]
1399 fn from(v: Vec3) -> Self {
1400 Self::new(f64::from(v.x), f64::from(v.y), f64::from(v.z))
1401 }
1402}
1403
1404impl From<IVec3> for DVec3 {
1405 #[inline]
1406 fn from(v: IVec3) -> Self {
1407 Self::new(f64::from(v.x), f64::from(v.y), f64::from(v.z))
1408 }
1409}
1410
1411impl From<UVec3> for DVec3 {
1412 #[inline]
1413 fn from(v: UVec3) -> Self {
1414 Self::new(f64::from(v.x), f64::from(v.y), f64::from(v.z))
1415 }
1416}
1417
1418impl From<BVec3> for DVec3 {
1419 #[inline]
1420 fn from(v: BVec3) -> Self {
1421 Self::new(f64::from(v.x), f64::from(v.y), f64::from(v.z))
1422 }
1423}
1424
1425impl From<BVec3A> for DVec3 {
1426 #[inline]
1427 fn from(v: BVec3A) -> Self {
1428 let bool_array: [bool; 3] = v.into();
1429 Self::new(
1430 f64::from(bool_array[0]),
1431 f64::from(bool_array[1]),
1432 f64::from(bool_array[2]),
1433 )
1434 }
1435}