1#[cfg(not(feature = "scalar-math"))]
4use crate::BVec4A;
5use crate::{f64::math, BVec4, DVec2, DVec3, IVec4, UVec4, Vec4};
6
7#[cfg(not(target_arch = "spirv"))]
8use core::fmt;
9use core::iter::{Product, Sum};
10use core::{f32, ops::*};
11
12#[inline(always)]
14#[must_use]
15pub const fn dvec4(x: f64, y: f64, z: f64, w: f64) -> DVec4 {
16 DVec4::new(x, y, z, w)
17}
18
19#[derive(Clone, Copy, PartialEq)]
21#[cfg_attr(feature = "cuda", repr(align(16)))]
22#[cfg_attr(not(target_arch = "spirv"), repr(C))]
23#[cfg_attr(target_arch = "spirv", repr(simd))]
24pub struct DVec4 {
25 pub x: f64,
26 pub y: f64,
27 pub z: f64,
28 pub w: f64,
29}
30
31impl DVec4 {
32 pub const ZERO: Self = Self::splat(0.0);
34
35 pub const ONE: Self = Self::splat(1.0);
37
38 pub const NEG_ONE: Self = Self::splat(-1.0);
40
41 pub const MIN: Self = Self::splat(f64::MIN);
43
44 pub const MAX: Self = Self::splat(f64::MAX);
46
47 pub const NAN: Self = Self::splat(f64::NAN);
49
50 pub const INFINITY: Self = Self::splat(f64::INFINITY);
52
53 pub const NEG_INFINITY: Self = Self::splat(f64::NEG_INFINITY);
55
56 pub const X: Self = Self::new(1.0, 0.0, 0.0, 0.0);
58
59 pub const Y: Self = Self::new(0.0, 1.0, 0.0, 0.0);
61
62 pub const Z: Self = Self::new(0.0, 0.0, 1.0, 0.0);
64
65 pub const W: Self = Self::new(0.0, 0.0, 0.0, 1.0);
67
68 pub const NEG_X: Self = Self::new(-1.0, 0.0, 0.0, 0.0);
70
71 pub const NEG_Y: Self = Self::new(0.0, -1.0, 0.0, 0.0);
73
74 pub const NEG_Z: Self = Self::new(0.0, 0.0, -1.0, 0.0);
76
77 pub const NEG_W: Self = Self::new(0.0, 0.0, 0.0, -1.0);
79
80 pub const AXES: [Self; 4] = [Self::X, Self::Y, Self::Z, Self::W];
82
83 #[inline(always)]
85 #[must_use]
86 pub const fn new(x: f64, y: f64, z: f64, w: f64) -> Self {
87 Self { x, y, z, w }
88 }
89
90 #[inline]
92 #[must_use]
93 pub const fn splat(v: f64) -> Self {
94 Self {
95 x: v,
96
97 y: v,
98
99 z: v,
100
101 w: v,
102 }
103 }
104
105 #[inline]
111 #[must_use]
112 pub fn select(mask: BVec4, if_true: Self, if_false: Self) -> Self {
113 Self {
114 x: if mask.test(0) { if_true.x } else { if_false.x },
115 y: if mask.test(1) { if_true.y } else { if_false.y },
116 z: if mask.test(2) { if_true.z } else { if_false.z },
117 w: if mask.test(3) { if_true.w } else { if_false.w },
118 }
119 }
120
121 #[inline]
123 #[must_use]
124 pub const fn from_array(a: [f64; 4]) -> Self {
125 Self::new(a[0], a[1], a[2], a[3])
126 }
127
128 #[inline]
130 #[must_use]
131 pub const fn to_array(&self) -> [f64; 4] {
132 [self.x, self.y, self.z, self.w]
133 }
134
135 #[inline]
141 #[must_use]
142 pub const fn from_slice(slice: &[f64]) -> Self {
143 Self::new(slice[0], slice[1], slice[2], slice[3])
144 }
145
146 #[inline]
152 pub fn write_to_slice(self, slice: &mut [f64]) {
153 slice[0] = self.x;
154 slice[1] = self.y;
155 slice[2] = self.z;
156 slice[3] = self.w;
157 }
158
159 #[inline]
163 #[must_use]
164 pub fn truncate(self) -> DVec3 {
165 use crate::swizzles::Vec4Swizzles;
166 self.xyz()
167 }
168
169 #[inline]
171 #[must_use]
172 pub fn with_x(mut self, x: f64) -> Self {
173 self.x = x;
174 self
175 }
176
177 #[inline]
179 #[must_use]
180 pub fn with_y(mut self, y: f64) -> Self {
181 self.y = y;
182 self
183 }
184
185 #[inline]
187 #[must_use]
188 pub fn with_z(mut self, z: f64) -> Self {
189 self.z = z;
190 self
191 }
192
193 #[inline]
195 #[must_use]
196 pub fn with_w(mut self, w: f64) -> Self {
197 self.w = w;
198 self
199 }
200
201 #[inline]
203 #[must_use]
204 pub fn dot(self, rhs: Self) -> f64 {
205 (self.x * rhs.x) + (self.y * rhs.y) + (self.z * rhs.z) + (self.w * rhs.w)
206 }
207
208 #[inline]
210 #[must_use]
211 pub fn dot_into_vec(self, rhs: Self) -> Self {
212 Self::splat(self.dot(rhs))
213 }
214
215 #[inline]
219 #[must_use]
220 pub fn min(self, rhs: Self) -> Self {
221 Self {
222 x: self.x.min(rhs.x),
223 y: self.y.min(rhs.y),
224 z: self.z.min(rhs.z),
225 w: self.w.min(rhs.w),
226 }
227 }
228
229 #[inline]
233 #[must_use]
234 pub fn max(self, rhs: Self) -> Self {
235 Self {
236 x: self.x.max(rhs.x),
237 y: self.y.max(rhs.y),
238 z: self.z.max(rhs.z),
239 w: self.w.max(rhs.w),
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.min(self.w)))
264 }
265
266 #[inline]
270 #[must_use]
271 pub fn max_element(self) -> f64 {
272 self.x.max(self.y.max(self.z.max(self.w)))
273 }
274
275 #[inline]
279 #[must_use]
280 pub fn element_sum(self) -> f64 {
281 self.x + self.y + self.z + self.w
282 }
283
284 #[inline]
288 #[must_use]
289 pub fn element_product(self) -> f64 {
290 self.x * self.y * self.z * self.w
291 }
292
293 #[inline]
299 #[must_use]
300 pub fn cmpeq(self, rhs: Self) -> BVec4 {
301 BVec4::new(
302 self.x.eq(&rhs.x),
303 self.y.eq(&rhs.y),
304 self.z.eq(&rhs.z),
305 self.w.eq(&rhs.w),
306 )
307 }
308
309 #[inline]
315 #[must_use]
316 pub fn cmpne(self, rhs: Self) -> BVec4 {
317 BVec4::new(
318 self.x.ne(&rhs.x),
319 self.y.ne(&rhs.y),
320 self.z.ne(&rhs.z),
321 self.w.ne(&rhs.w),
322 )
323 }
324
325 #[inline]
331 #[must_use]
332 pub fn cmpge(self, rhs: Self) -> BVec4 {
333 BVec4::new(
334 self.x.ge(&rhs.x),
335 self.y.ge(&rhs.y),
336 self.z.ge(&rhs.z),
337 self.w.ge(&rhs.w),
338 )
339 }
340
341 #[inline]
347 #[must_use]
348 pub fn cmpgt(self, rhs: Self) -> BVec4 {
349 BVec4::new(
350 self.x.gt(&rhs.x),
351 self.y.gt(&rhs.y),
352 self.z.gt(&rhs.z),
353 self.w.gt(&rhs.w),
354 )
355 }
356
357 #[inline]
363 #[must_use]
364 pub fn cmple(self, rhs: Self) -> BVec4 {
365 BVec4::new(
366 self.x.le(&rhs.x),
367 self.y.le(&rhs.y),
368 self.z.le(&rhs.z),
369 self.w.le(&rhs.w),
370 )
371 }
372
373 #[inline]
379 #[must_use]
380 pub fn cmplt(self, rhs: Self) -> BVec4 {
381 BVec4::new(
382 self.x.lt(&rhs.x),
383 self.y.lt(&rhs.y),
384 self.z.lt(&rhs.z),
385 self.w.lt(&rhs.w),
386 )
387 }
388
389 #[inline]
391 #[must_use]
392 pub fn abs(self) -> Self {
393 Self {
394 x: math::abs(self.x),
395 y: math::abs(self.y),
396 z: math::abs(self.z),
397 w: math::abs(self.w),
398 }
399 }
400
401 #[inline]
407 #[must_use]
408 pub fn signum(self) -> Self {
409 Self {
410 x: math::signum(self.x),
411 y: math::signum(self.y),
412 z: math::signum(self.z),
413 w: math::signum(self.w),
414 }
415 }
416
417 #[inline]
419 #[must_use]
420 pub fn copysign(self, rhs: Self) -> Self {
421 Self {
422 x: math::copysign(self.x, rhs.x),
423 y: math::copysign(self.y, rhs.y),
424 z: math::copysign(self.z, rhs.z),
425 w: math::copysign(self.w, rhs.w),
426 }
427 }
428
429 #[inline]
434 #[must_use]
435 pub fn is_negative_bitmask(self) -> u32 {
436 (self.x.is_sign_negative() as u32)
437 | (self.y.is_sign_negative() as u32) << 1
438 | (self.z.is_sign_negative() as u32) << 2
439 | (self.w.is_sign_negative() as u32) << 3
440 }
441
442 #[inline]
445 #[must_use]
446 pub fn is_finite(self) -> bool {
447 self.x.is_finite() && self.y.is_finite() && self.z.is_finite() && self.w.is_finite()
448 }
449
450 #[inline]
452 #[must_use]
453 pub fn is_nan(self) -> bool {
454 self.x.is_nan() || self.y.is_nan() || self.z.is_nan() || self.w.is_nan()
455 }
456
457 #[inline]
461 #[must_use]
462 pub fn is_nan_mask(self) -> BVec4 {
463 BVec4::new(
464 self.x.is_nan(),
465 self.y.is_nan(),
466 self.z.is_nan(),
467 self.w.is_nan(),
468 )
469 }
470
471 #[doc(alias = "magnitude")]
473 #[inline]
474 #[must_use]
475 pub fn length(self) -> f64 {
476 math::sqrt(self.dot(self))
477 }
478
479 #[doc(alias = "magnitude2")]
483 #[inline]
484 #[must_use]
485 pub fn length_squared(self) -> f64 {
486 self.dot(self)
487 }
488
489 #[inline]
493 #[must_use]
494 pub fn length_recip(self) -> f64 {
495 self.length().recip()
496 }
497
498 #[inline]
500 #[must_use]
501 pub fn distance(self, rhs: Self) -> f64 {
502 (self - rhs).length()
503 }
504
505 #[inline]
507 #[must_use]
508 pub fn distance_squared(self, rhs: Self) -> f64 {
509 (self - rhs).length_squared()
510 }
511
512 #[inline]
514 #[must_use]
515 pub fn div_euclid(self, rhs: Self) -> Self {
516 Self::new(
517 math::div_euclid(self.x, rhs.x),
518 math::div_euclid(self.y, rhs.y),
519 math::div_euclid(self.z, rhs.z),
520 math::div_euclid(self.w, rhs.w),
521 )
522 }
523
524 #[inline]
528 #[must_use]
529 pub fn rem_euclid(self, rhs: Self) -> Self {
530 Self::new(
531 math::rem_euclid(self.x, rhs.x),
532 math::rem_euclid(self.y, rhs.y),
533 math::rem_euclid(self.z, rhs.z),
534 math::rem_euclid(self.w, rhs.w),
535 )
536 }
537
538 #[inline]
548 #[must_use]
549 pub fn normalize(self) -> Self {
550 #[allow(clippy::let_and_return)]
551 let normalized = self.mul(self.length_recip());
552 glam_assert!(normalized.is_finite());
553 normalized
554 }
555
556 #[inline]
563 #[must_use]
564 pub fn try_normalize(self) -> Option<Self> {
565 let rcp = self.length_recip();
566 if rcp.is_finite() && rcp > 0.0 {
567 Some(self * rcp)
568 } else {
569 None
570 }
571 }
572
573 #[inline]
581 #[must_use]
582 pub fn normalize_or(self, fallback: Self) -> Self {
583 let rcp = self.length_recip();
584 if rcp.is_finite() && rcp > 0.0 {
585 self * rcp
586 } else {
587 fallback
588 }
589 }
590
591 #[inline]
598 #[must_use]
599 pub fn normalize_or_zero(self) -> Self {
600 self.normalize_or(Self::ZERO)
601 }
602
603 #[inline]
607 #[must_use]
608 pub fn is_normalized(self) -> bool {
609 math::abs(self.length_squared() - 1.0) <= 2e-4
610 }
611
612 #[inline]
620 #[must_use]
621 pub fn project_onto(self, rhs: Self) -> Self {
622 let other_len_sq_rcp = rhs.dot(rhs).recip();
623 glam_assert!(other_len_sq_rcp.is_finite());
624 rhs * self.dot(rhs) * other_len_sq_rcp
625 }
626
627 #[inline]
638 #[must_use]
639 pub fn reject_from(self, rhs: Self) -> Self {
640 self - self.project_onto(rhs)
641 }
642
643 #[inline]
651 #[must_use]
652 pub fn project_onto_normalized(self, rhs: Self) -> Self {
653 glam_assert!(rhs.is_normalized());
654 rhs * self.dot(rhs)
655 }
656
657 #[inline]
668 #[must_use]
669 pub fn reject_from_normalized(self, rhs: Self) -> Self {
670 self - self.project_onto_normalized(rhs)
671 }
672
673 #[inline]
676 #[must_use]
677 pub fn round(self) -> Self {
678 Self {
679 x: math::round(self.x),
680 y: math::round(self.y),
681 z: math::round(self.z),
682 w: math::round(self.w),
683 }
684 }
685
686 #[inline]
689 #[must_use]
690 pub fn floor(self) -> Self {
691 Self {
692 x: math::floor(self.x),
693 y: math::floor(self.y),
694 z: math::floor(self.z),
695 w: math::floor(self.w),
696 }
697 }
698
699 #[inline]
702 #[must_use]
703 pub fn ceil(self) -> Self {
704 Self {
705 x: math::ceil(self.x),
706 y: math::ceil(self.y),
707 z: math::ceil(self.z),
708 w: math::ceil(self.w),
709 }
710 }
711
712 #[inline]
715 #[must_use]
716 pub fn trunc(self) -> Self {
717 Self {
718 x: math::trunc(self.x),
719 y: math::trunc(self.y),
720 z: math::trunc(self.z),
721 w: math::trunc(self.w),
722 }
723 }
724
725 #[inline]
732 #[must_use]
733 pub fn fract(self) -> Self {
734 self - self.trunc()
735 }
736
737 #[inline]
744 #[must_use]
745 pub fn fract_gl(self) -> Self {
746 self - self.floor()
747 }
748
749 #[inline]
752 #[must_use]
753 pub fn exp(self) -> Self {
754 Self::new(
755 math::exp(self.x),
756 math::exp(self.y),
757 math::exp(self.z),
758 math::exp(self.w),
759 )
760 }
761
762 #[inline]
764 #[must_use]
765 pub fn powf(self, n: f64) -> Self {
766 Self::new(
767 math::powf(self.x, n),
768 math::powf(self.y, n),
769 math::powf(self.z, n),
770 math::powf(self.w, n),
771 )
772 }
773
774 #[inline]
776 #[must_use]
777 pub fn recip(self) -> Self {
778 Self {
779 x: 1.0 / self.x,
780 y: 1.0 / self.y,
781 z: 1.0 / self.z,
782 w: 1.0 / self.w,
783 }
784 }
785
786 #[doc(alias = "mix")]
792 #[inline]
793 #[must_use]
794 pub fn lerp(self, rhs: Self, s: f64) -> Self {
795 self + ((rhs - self) * s)
796 }
797
798 #[inline]
803 #[must_use]
804 pub fn move_towards(&self, rhs: Self, d: f64) -> Self {
805 let a = rhs - *self;
806 let len = a.length();
807 if len <= d || len <= 1e-4 {
808 return rhs;
809 }
810 *self + a / len * d
811 }
812
813 #[inline]
819 pub fn midpoint(self, rhs: Self) -> Self {
820 (self + rhs) * 0.5
821 }
822
823 #[inline]
833 #[must_use]
834 pub fn abs_diff_eq(self, rhs: Self, max_abs_diff: f64) -> bool {
835 self.sub(rhs).abs().cmple(Self::splat(max_abs_diff)).all()
836 }
837
838 #[inline]
844 #[must_use]
845 pub fn clamp_length(self, min: f64, max: f64) -> Self {
846 glam_assert!(min <= max);
847 let length_sq = self.length_squared();
848 if length_sq < min * min {
849 min * (self / math::sqrt(length_sq))
850 } else if length_sq > max * max {
851 max * (self / math::sqrt(length_sq))
852 } else {
853 self
854 }
855 }
856
857 #[inline]
859 #[must_use]
860 pub fn clamp_length_max(self, max: f64) -> Self {
861 let length_sq = self.length_squared();
862 if length_sq > max * max {
863 max * (self / math::sqrt(length_sq))
864 } else {
865 self
866 }
867 }
868
869 #[inline]
871 #[must_use]
872 pub fn clamp_length_min(self, min: f64) -> Self {
873 let length_sq = self.length_squared();
874 if length_sq < min * min {
875 min * (self / math::sqrt(length_sq))
876 } else {
877 self
878 }
879 }
880
881 #[inline]
889 #[must_use]
890 pub fn mul_add(self, a: Self, b: Self) -> Self {
891 Self::new(
892 math::mul_add(self.x, a.x, b.x),
893 math::mul_add(self.y, a.y, b.y),
894 math::mul_add(self.z, a.z, b.z),
895 math::mul_add(self.w, a.w, b.w),
896 )
897 }
898
899 #[inline]
901 #[must_use]
902 pub fn as_vec4(&self) -> crate::Vec4 {
903 crate::Vec4::new(self.x as f32, self.y as f32, self.z as f32, self.w as f32)
904 }
905
906 #[inline]
908 #[must_use]
909 pub fn as_i16vec4(&self) -> crate::I16Vec4 {
910 crate::I16Vec4::new(self.x as i16, self.y as i16, self.z as i16, self.w as i16)
911 }
912
913 #[inline]
915 #[must_use]
916 pub fn as_u16vec4(&self) -> crate::U16Vec4 {
917 crate::U16Vec4::new(self.x as u16, self.y as u16, self.z as u16, self.w as u16)
918 }
919
920 #[inline]
922 #[must_use]
923 pub fn as_ivec4(&self) -> crate::IVec4 {
924 crate::IVec4::new(self.x as i32, self.y as i32, self.z as i32, self.w as i32)
925 }
926
927 #[inline]
929 #[must_use]
930 pub fn as_uvec4(&self) -> crate::UVec4 {
931 crate::UVec4::new(self.x as u32, self.y as u32, self.z as u32, self.w as u32)
932 }
933
934 #[inline]
936 #[must_use]
937 pub fn as_i64vec4(&self) -> crate::I64Vec4 {
938 crate::I64Vec4::new(self.x as i64, self.y as i64, self.z as i64, self.w as i64)
939 }
940
941 #[inline]
943 #[must_use]
944 pub fn as_u64vec4(&self) -> crate::U64Vec4 {
945 crate::U64Vec4::new(self.x as u64, self.y as u64, self.z as u64, self.w as u64)
946 }
947}
948
949impl Default for DVec4 {
950 #[inline(always)]
951 fn default() -> Self {
952 Self::ZERO
953 }
954}
955
956impl Div<DVec4> for DVec4 {
957 type Output = Self;
958 #[inline]
959 fn div(self, rhs: Self) -> Self {
960 Self {
961 x: self.x.div(rhs.x),
962 y: self.y.div(rhs.y),
963 z: self.z.div(rhs.z),
964 w: self.w.div(rhs.w),
965 }
966 }
967}
968
969impl DivAssign<DVec4> for DVec4 {
970 #[inline]
971 fn div_assign(&mut self, rhs: Self) {
972 self.x.div_assign(rhs.x);
973 self.y.div_assign(rhs.y);
974 self.z.div_assign(rhs.z);
975 self.w.div_assign(rhs.w);
976 }
977}
978
979impl Div<f64> for DVec4 {
980 type Output = Self;
981 #[inline]
982 fn div(self, rhs: f64) -> Self {
983 Self {
984 x: self.x.div(rhs),
985 y: self.y.div(rhs),
986 z: self.z.div(rhs),
987 w: self.w.div(rhs),
988 }
989 }
990}
991
992impl DivAssign<f64> for DVec4 {
993 #[inline]
994 fn div_assign(&mut self, rhs: f64) {
995 self.x.div_assign(rhs);
996 self.y.div_assign(rhs);
997 self.z.div_assign(rhs);
998 self.w.div_assign(rhs);
999 }
1000}
1001
1002impl Div<DVec4> for f64 {
1003 type Output = DVec4;
1004 #[inline]
1005 fn div(self, rhs: DVec4) -> DVec4 {
1006 DVec4 {
1007 x: self.div(rhs.x),
1008 y: self.div(rhs.y),
1009 z: self.div(rhs.z),
1010 w: self.div(rhs.w),
1011 }
1012 }
1013}
1014
1015impl Mul<DVec4> for DVec4 {
1016 type Output = Self;
1017 #[inline]
1018 fn mul(self, rhs: Self) -> Self {
1019 Self {
1020 x: self.x.mul(rhs.x),
1021 y: self.y.mul(rhs.y),
1022 z: self.z.mul(rhs.z),
1023 w: self.w.mul(rhs.w),
1024 }
1025 }
1026}
1027
1028impl MulAssign<DVec4> for DVec4 {
1029 #[inline]
1030 fn mul_assign(&mut self, rhs: Self) {
1031 self.x.mul_assign(rhs.x);
1032 self.y.mul_assign(rhs.y);
1033 self.z.mul_assign(rhs.z);
1034 self.w.mul_assign(rhs.w);
1035 }
1036}
1037
1038impl Mul<f64> for DVec4 {
1039 type Output = Self;
1040 #[inline]
1041 fn mul(self, rhs: f64) -> Self {
1042 Self {
1043 x: self.x.mul(rhs),
1044 y: self.y.mul(rhs),
1045 z: self.z.mul(rhs),
1046 w: self.w.mul(rhs),
1047 }
1048 }
1049}
1050
1051impl MulAssign<f64> for DVec4 {
1052 #[inline]
1053 fn mul_assign(&mut self, rhs: f64) {
1054 self.x.mul_assign(rhs);
1055 self.y.mul_assign(rhs);
1056 self.z.mul_assign(rhs);
1057 self.w.mul_assign(rhs);
1058 }
1059}
1060
1061impl Mul<DVec4> for f64 {
1062 type Output = DVec4;
1063 #[inline]
1064 fn mul(self, rhs: DVec4) -> DVec4 {
1065 DVec4 {
1066 x: self.mul(rhs.x),
1067 y: self.mul(rhs.y),
1068 z: self.mul(rhs.z),
1069 w: self.mul(rhs.w),
1070 }
1071 }
1072}
1073
1074impl Add<DVec4> for DVec4 {
1075 type Output = Self;
1076 #[inline]
1077 fn add(self, rhs: Self) -> Self {
1078 Self {
1079 x: self.x.add(rhs.x),
1080 y: self.y.add(rhs.y),
1081 z: self.z.add(rhs.z),
1082 w: self.w.add(rhs.w),
1083 }
1084 }
1085}
1086
1087impl AddAssign<DVec4> for DVec4 {
1088 #[inline]
1089 fn add_assign(&mut self, rhs: Self) {
1090 self.x.add_assign(rhs.x);
1091 self.y.add_assign(rhs.y);
1092 self.z.add_assign(rhs.z);
1093 self.w.add_assign(rhs.w);
1094 }
1095}
1096
1097impl Add<f64> for DVec4 {
1098 type Output = Self;
1099 #[inline]
1100 fn add(self, rhs: f64) -> Self {
1101 Self {
1102 x: self.x.add(rhs),
1103 y: self.y.add(rhs),
1104 z: self.z.add(rhs),
1105 w: self.w.add(rhs),
1106 }
1107 }
1108}
1109
1110impl AddAssign<f64> for DVec4 {
1111 #[inline]
1112 fn add_assign(&mut self, rhs: f64) {
1113 self.x.add_assign(rhs);
1114 self.y.add_assign(rhs);
1115 self.z.add_assign(rhs);
1116 self.w.add_assign(rhs);
1117 }
1118}
1119
1120impl Add<DVec4> for f64 {
1121 type Output = DVec4;
1122 #[inline]
1123 fn add(self, rhs: DVec4) -> DVec4 {
1124 DVec4 {
1125 x: self.add(rhs.x),
1126 y: self.add(rhs.y),
1127 z: self.add(rhs.z),
1128 w: self.add(rhs.w),
1129 }
1130 }
1131}
1132
1133impl Sub<DVec4> for DVec4 {
1134 type Output = Self;
1135 #[inline]
1136 fn sub(self, rhs: Self) -> Self {
1137 Self {
1138 x: self.x.sub(rhs.x),
1139 y: self.y.sub(rhs.y),
1140 z: self.z.sub(rhs.z),
1141 w: self.w.sub(rhs.w),
1142 }
1143 }
1144}
1145
1146impl SubAssign<DVec4> for DVec4 {
1147 #[inline]
1148 fn sub_assign(&mut self, rhs: DVec4) {
1149 self.x.sub_assign(rhs.x);
1150 self.y.sub_assign(rhs.y);
1151 self.z.sub_assign(rhs.z);
1152 self.w.sub_assign(rhs.w);
1153 }
1154}
1155
1156impl Sub<f64> for DVec4 {
1157 type Output = Self;
1158 #[inline]
1159 fn sub(self, rhs: f64) -> Self {
1160 Self {
1161 x: self.x.sub(rhs),
1162 y: self.y.sub(rhs),
1163 z: self.z.sub(rhs),
1164 w: self.w.sub(rhs),
1165 }
1166 }
1167}
1168
1169impl SubAssign<f64> for DVec4 {
1170 #[inline]
1171 fn sub_assign(&mut self, rhs: f64) {
1172 self.x.sub_assign(rhs);
1173 self.y.sub_assign(rhs);
1174 self.z.sub_assign(rhs);
1175 self.w.sub_assign(rhs);
1176 }
1177}
1178
1179impl Sub<DVec4> for f64 {
1180 type Output = DVec4;
1181 #[inline]
1182 fn sub(self, rhs: DVec4) -> DVec4 {
1183 DVec4 {
1184 x: self.sub(rhs.x),
1185 y: self.sub(rhs.y),
1186 z: self.sub(rhs.z),
1187 w: self.sub(rhs.w),
1188 }
1189 }
1190}
1191
1192impl Rem<DVec4> for DVec4 {
1193 type Output = Self;
1194 #[inline]
1195 fn rem(self, rhs: Self) -> Self {
1196 Self {
1197 x: self.x.rem(rhs.x),
1198 y: self.y.rem(rhs.y),
1199 z: self.z.rem(rhs.z),
1200 w: self.w.rem(rhs.w),
1201 }
1202 }
1203}
1204
1205impl RemAssign<DVec4> for DVec4 {
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 self.w.rem_assign(rhs.w);
1212 }
1213}
1214
1215impl Rem<f64> for DVec4 {
1216 type Output = Self;
1217 #[inline]
1218 fn rem(self, rhs: f64) -> Self {
1219 Self {
1220 x: self.x.rem(rhs),
1221 y: self.y.rem(rhs),
1222 z: self.z.rem(rhs),
1223 w: self.w.rem(rhs),
1224 }
1225 }
1226}
1227
1228impl RemAssign<f64> for DVec4 {
1229 #[inline]
1230 fn rem_assign(&mut self, rhs: f64) {
1231 self.x.rem_assign(rhs);
1232 self.y.rem_assign(rhs);
1233 self.z.rem_assign(rhs);
1234 self.w.rem_assign(rhs);
1235 }
1236}
1237
1238impl Rem<DVec4> for f64 {
1239 type Output = DVec4;
1240 #[inline]
1241 fn rem(self, rhs: DVec4) -> DVec4 {
1242 DVec4 {
1243 x: self.rem(rhs.x),
1244 y: self.rem(rhs.y),
1245 z: self.rem(rhs.z),
1246 w: self.rem(rhs.w),
1247 }
1248 }
1249}
1250
1251#[cfg(not(target_arch = "spirv"))]
1252impl AsRef<[f64; 4]> for DVec4 {
1253 #[inline]
1254 fn as_ref(&self) -> &[f64; 4] {
1255 unsafe { &*(self as *const DVec4 as *const [f64; 4]) }
1256 }
1257}
1258
1259#[cfg(not(target_arch = "spirv"))]
1260impl AsMut<[f64; 4]> for DVec4 {
1261 #[inline]
1262 fn as_mut(&mut self) -> &mut [f64; 4] {
1263 unsafe { &mut *(self as *mut DVec4 as *mut [f64; 4]) }
1264 }
1265}
1266
1267impl Sum for DVec4 {
1268 #[inline]
1269 fn sum<I>(iter: I) -> Self
1270 where
1271 I: Iterator<Item = Self>,
1272 {
1273 iter.fold(Self::ZERO, Self::add)
1274 }
1275}
1276
1277impl<'a> Sum<&'a Self> for DVec4 {
1278 #[inline]
1279 fn sum<I>(iter: I) -> Self
1280 where
1281 I: Iterator<Item = &'a Self>,
1282 {
1283 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1284 }
1285}
1286
1287impl Product for DVec4 {
1288 #[inline]
1289 fn product<I>(iter: I) -> Self
1290 where
1291 I: Iterator<Item = Self>,
1292 {
1293 iter.fold(Self::ONE, Self::mul)
1294 }
1295}
1296
1297impl<'a> Product<&'a Self> for DVec4 {
1298 #[inline]
1299 fn product<I>(iter: I) -> Self
1300 where
1301 I: Iterator<Item = &'a Self>,
1302 {
1303 iter.fold(Self::ONE, |a, &b| Self::mul(a, b))
1304 }
1305}
1306
1307impl Neg for DVec4 {
1308 type Output = Self;
1309 #[inline]
1310 fn neg(self) -> Self {
1311 Self {
1312 x: self.x.neg(),
1313 y: self.y.neg(),
1314 z: self.z.neg(),
1315 w: self.w.neg(),
1316 }
1317 }
1318}
1319
1320impl Index<usize> for DVec4 {
1321 type Output = f64;
1322 #[inline]
1323 fn index(&self, index: usize) -> &Self::Output {
1324 match index {
1325 0 => &self.x,
1326 1 => &self.y,
1327 2 => &self.z,
1328 3 => &self.w,
1329 _ => panic!("index out of bounds"),
1330 }
1331 }
1332}
1333
1334impl IndexMut<usize> for DVec4 {
1335 #[inline]
1336 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1337 match index {
1338 0 => &mut self.x,
1339 1 => &mut self.y,
1340 2 => &mut self.z,
1341 3 => &mut self.w,
1342 _ => panic!("index out of bounds"),
1343 }
1344 }
1345}
1346
1347#[cfg(not(target_arch = "spirv"))]
1348impl fmt::Display for DVec4 {
1349 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1350 if let Some(p) = f.precision() {
1351 write!(
1352 f,
1353 "[{:.*}, {:.*}, {:.*}, {:.*}]",
1354 p, self.x, p, self.y, p, self.z, p, self.w
1355 )
1356 } else {
1357 write!(f, "[{}, {}, {}, {}]", self.x, self.y, self.z, self.w)
1358 }
1359 }
1360}
1361
1362#[cfg(not(target_arch = "spirv"))]
1363impl fmt::Debug for DVec4 {
1364 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1365 fmt.debug_tuple(stringify!(DVec4))
1366 .field(&self.x)
1367 .field(&self.y)
1368 .field(&self.z)
1369 .field(&self.w)
1370 .finish()
1371 }
1372}
1373
1374impl From<[f64; 4]> for DVec4 {
1375 #[inline]
1376 fn from(a: [f64; 4]) -> Self {
1377 Self::new(a[0], a[1], a[2], a[3])
1378 }
1379}
1380
1381impl From<DVec4> for [f64; 4] {
1382 #[inline]
1383 fn from(v: DVec4) -> Self {
1384 [v.x, v.y, v.z, v.w]
1385 }
1386}
1387
1388impl From<(f64, f64, f64, f64)> for DVec4 {
1389 #[inline]
1390 fn from(t: (f64, f64, f64, f64)) -> Self {
1391 Self::new(t.0, t.1, t.2, t.3)
1392 }
1393}
1394
1395impl From<DVec4> for (f64, f64, f64, f64) {
1396 #[inline]
1397 fn from(v: DVec4) -> Self {
1398 (v.x, v.y, v.z, v.w)
1399 }
1400}
1401
1402impl From<(DVec3, f64)> for DVec4 {
1403 #[inline]
1404 fn from((v, w): (DVec3, f64)) -> Self {
1405 Self::new(v.x, v.y, v.z, w)
1406 }
1407}
1408
1409impl From<(f64, DVec3)> for DVec4 {
1410 #[inline]
1411 fn from((x, v): (f64, DVec3)) -> Self {
1412 Self::new(x, v.x, v.y, v.z)
1413 }
1414}
1415
1416impl From<(DVec2, f64, f64)> for DVec4 {
1417 #[inline]
1418 fn from((v, z, w): (DVec2, f64, f64)) -> Self {
1419 Self::new(v.x, v.y, z, w)
1420 }
1421}
1422
1423impl From<(DVec2, DVec2)> for DVec4 {
1424 #[inline]
1425 fn from((v, u): (DVec2, DVec2)) -> Self {
1426 Self::new(v.x, v.y, u.x, u.y)
1427 }
1428}
1429
1430impl From<Vec4> for DVec4 {
1431 #[inline]
1432 fn from(v: Vec4) -> Self {
1433 Self::new(
1434 f64::from(v.x),
1435 f64::from(v.y),
1436 f64::from(v.z),
1437 f64::from(v.w),
1438 )
1439 }
1440}
1441
1442impl From<IVec4> for DVec4 {
1443 #[inline]
1444 fn from(v: IVec4) -> Self {
1445 Self::new(
1446 f64::from(v.x),
1447 f64::from(v.y),
1448 f64::from(v.z),
1449 f64::from(v.w),
1450 )
1451 }
1452}
1453
1454impl From<UVec4> for DVec4 {
1455 #[inline]
1456 fn from(v: UVec4) -> Self {
1457 Self::new(
1458 f64::from(v.x),
1459 f64::from(v.y),
1460 f64::from(v.z),
1461 f64::from(v.w),
1462 )
1463 }
1464}
1465
1466impl From<BVec4> for DVec4 {
1467 #[inline]
1468 fn from(v: BVec4) -> Self {
1469 Self::new(
1470 f64::from(v.x),
1471 f64::from(v.y),
1472 f64::from(v.z),
1473 f64::from(v.w),
1474 )
1475 }
1476}
1477
1478#[cfg(not(feature = "scalar-math"))]
1479
1480impl From<BVec4A> for DVec4 {
1481 #[inline]
1482 fn from(v: BVec4A) -> Self {
1483 let bool_array: [bool; 4] = v.into();
1484 Self::new(
1485 f64::from(bool_array[0]),
1486 f64::from(bool_array[1]),
1487 f64::from(bool_array[2]),
1488 f64::from(bool_array[3]),
1489 )
1490 }
1491}