1use crate::{f64::math, BVec4, DVec2, DVec3, IVec4, UVec4, Vec4};
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 dvec4(x: f64, y: f64, z: f64, w: f64) -> DVec4 {
14 DVec4::new(x, y, z, w)
15}
16
17#[derive(Clone, Copy, PartialEq)]
19#[cfg_attr(feature = "cuda", repr(align(16)))]
20#[cfg_attr(not(target_arch = "spirv"), repr(C))]
21#[cfg_attr(target_arch = "spirv", repr(simd))]
22pub struct DVec4 {
23 pub x: f64,
24 pub y: f64,
25 pub z: f64,
26 pub w: f64,
27}
28
29impl DVec4 {
30 pub const ZERO: Self = Self::splat(0.0);
32
33 pub const ONE: Self = Self::splat(1.0);
35
36 pub const NEG_ONE: Self = Self::splat(-1.0);
38
39 pub const MIN: Self = Self::splat(f64::MIN);
41
42 pub const MAX: Self = Self::splat(f64::MAX);
44
45 pub const NAN: Self = Self::splat(f64::NAN);
47
48 pub const INFINITY: Self = Self::splat(f64::INFINITY);
50
51 pub const NEG_INFINITY: Self = Self::splat(f64::NEG_INFINITY);
53
54 pub const X: Self = Self::new(1.0, 0.0, 0.0, 0.0);
56
57 pub const Y: Self = Self::new(0.0, 1.0, 0.0, 0.0);
59
60 pub const Z: Self = Self::new(0.0, 0.0, 1.0, 0.0);
62
63 pub const W: Self = Self::new(0.0, 0.0, 0.0, 1.0);
65
66 pub const NEG_X: Self = Self::new(-1.0, 0.0, 0.0, 0.0);
68
69 pub const NEG_Y: Self = Self::new(0.0, -1.0, 0.0, 0.0);
71
72 pub const NEG_Z: Self = Self::new(0.0, 0.0, -1.0, 0.0);
74
75 pub const NEG_W: Self = Self::new(0.0, 0.0, 0.0, -1.0);
77
78 pub const AXES: [Self; 4] = [Self::X, Self::Y, Self::Z, Self::W];
80
81 #[inline(always)]
83 #[must_use]
84 pub const fn new(x: f64, y: f64, z: f64, w: f64) -> Self {
85 Self { x, y, z, w }
86 }
87
88 #[inline]
90 #[must_use]
91 pub const fn splat(v: f64) -> Self {
92 Self {
93 x: v,
94
95 y: v,
96
97 z: v,
98
99 w: v,
100 }
101 }
102
103 #[inline]
109 #[must_use]
110 pub fn select(mask: BVec4, if_true: Self, if_false: Self) -> Self {
111 Self {
112 x: if mask.test(0) { if_true.x } else { if_false.x },
113 y: if mask.test(1) { if_true.y } else { if_false.y },
114 z: if mask.test(2) { if_true.z } else { if_false.z },
115 w: if mask.test(3) { if_true.w } else { if_false.w },
116 }
117 }
118
119 #[inline]
121 #[must_use]
122 pub const fn from_array(a: [f64; 4]) -> Self {
123 Self::new(a[0], a[1], a[2], a[3])
124 }
125
126 #[inline]
128 #[must_use]
129 pub const fn to_array(&self) -> [f64; 4] {
130 [self.x, self.y, self.z, self.w]
131 }
132
133 #[inline]
139 #[must_use]
140 pub const fn from_slice(slice: &[f64]) -> Self {
141 Self::new(slice[0], slice[1], slice[2], slice[3])
142 }
143
144 #[inline]
150 pub fn write_to_slice(self, slice: &mut [f64]) {
151 slice[0] = self.x;
152 slice[1] = self.y;
153 slice[2] = self.z;
154 slice[3] = self.w;
155 }
156
157 #[inline]
161 #[must_use]
162 pub fn truncate(self) -> DVec3 {
163 use crate::swizzles::Vec4Swizzles;
164 self.xyz()
165 }
166
167 #[inline]
169 #[must_use]
170 pub fn dot(self, rhs: Self) -> f64 {
171 (self.x * rhs.x) + (self.y * rhs.y) + (self.z * rhs.z) + (self.w * rhs.w)
172 }
173
174 #[inline]
176 #[must_use]
177 pub fn dot_into_vec(self, rhs: Self) -> Self {
178 Self::splat(self.dot(rhs))
179 }
180
181 #[inline]
185 #[must_use]
186 pub fn min(self, rhs: Self) -> Self {
187 Self {
188 x: self.x.min(rhs.x),
189 y: self.y.min(rhs.y),
190 z: self.z.min(rhs.z),
191 w: self.w.min(rhs.w),
192 }
193 }
194
195 #[inline]
199 #[must_use]
200 pub fn max(self, rhs: Self) -> Self {
201 Self {
202 x: self.x.max(rhs.x),
203 y: self.y.max(rhs.y),
204 z: self.z.max(rhs.z),
205 w: self.w.max(rhs.w),
206 }
207 }
208
209 #[inline]
217 #[must_use]
218 pub fn clamp(self, min: Self, max: Self) -> Self {
219 glam_assert!(min.cmple(max).all(), "clamp: expected min <= max");
220 self.max(min).min(max)
221 }
222
223 #[inline]
227 #[must_use]
228 pub fn min_element(self) -> f64 {
229 self.x.min(self.y.min(self.z.min(self.w)))
230 }
231
232 #[inline]
236 #[must_use]
237 pub fn max_element(self) -> f64 {
238 self.x.max(self.y.max(self.z.max(self.w)))
239 }
240
241 #[inline]
247 #[must_use]
248 pub fn cmpeq(self, rhs: Self) -> BVec4 {
249 BVec4::new(
250 self.x.eq(&rhs.x),
251 self.y.eq(&rhs.y),
252 self.z.eq(&rhs.z),
253 self.w.eq(&rhs.w),
254 )
255 }
256
257 #[inline]
263 #[must_use]
264 pub fn cmpne(self, rhs: Self) -> BVec4 {
265 BVec4::new(
266 self.x.ne(&rhs.x),
267 self.y.ne(&rhs.y),
268 self.z.ne(&rhs.z),
269 self.w.ne(&rhs.w),
270 )
271 }
272
273 #[inline]
279 #[must_use]
280 pub fn cmpge(self, rhs: Self) -> BVec4 {
281 BVec4::new(
282 self.x.ge(&rhs.x),
283 self.y.ge(&rhs.y),
284 self.z.ge(&rhs.z),
285 self.w.ge(&rhs.w),
286 )
287 }
288
289 #[inline]
295 #[must_use]
296 pub fn cmpgt(self, rhs: Self) -> BVec4 {
297 BVec4::new(
298 self.x.gt(&rhs.x),
299 self.y.gt(&rhs.y),
300 self.z.gt(&rhs.z),
301 self.w.gt(&rhs.w),
302 )
303 }
304
305 #[inline]
311 #[must_use]
312 pub fn cmple(self, rhs: Self) -> BVec4 {
313 BVec4::new(
314 self.x.le(&rhs.x),
315 self.y.le(&rhs.y),
316 self.z.le(&rhs.z),
317 self.w.le(&rhs.w),
318 )
319 }
320
321 #[inline]
327 #[must_use]
328 pub fn cmplt(self, rhs: Self) -> BVec4 {
329 BVec4::new(
330 self.x.lt(&rhs.x),
331 self.y.lt(&rhs.y),
332 self.z.lt(&rhs.z),
333 self.w.lt(&rhs.w),
334 )
335 }
336
337 #[inline]
339 #[must_use]
340 pub fn abs(self) -> Self {
341 Self {
342 x: math::abs(self.x),
343 y: math::abs(self.y),
344 z: math::abs(self.z),
345 w: math::abs(self.w),
346 }
347 }
348
349 #[inline]
355 #[must_use]
356 pub fn signum(self) -> Self {
357 Self {
358 x: math::signum(self.x),
359 y: math::signum(self.y),
360 z: math::signum(self.z),
361 w: math::signum(self.w),
362 }
363 }
364
365 #[inline]
367 #[must_use]
368 pub fn copysign(self, rhs: Self) -> Self {
369 Self {
370 x: math::copysign(self.x, rhs.x),
371 y: math::copysign(self.y, rhs.y),
372 z: math::copysign(self.z, rhs.z),
373 w: math::copysign(self.w, rhs.w),
374 }
375 }
376
377 #[inline]
382 #[must_use]
383 pub fn is_negative_bitmask(self) -> u32 {
384 (self.x.is_sign_negative() as u32)
385 | (self.y.is_sign_negative() as u32) << 1
386 | (self.z.is_sign_negative() as u32) << 2
387 | (self.w.is_sign_negative() as u32) << 3
388 }
389
390 #[inline]
393 #[must_use]
394 pub fn is_finite(self) -> bool {
395 self.x.is_finite() && self.y.is_finite() && self.z.is_finite() && self.w.is_finite()
396 }
397
398 #[inline]
400 #[must_use]
401 pub fn is_nan(self) -> bool {
402 self.x.is_nan() || self.y.is_nan() || self.z.is_nan() || self.w.is_nan()
403 }
404
405 #[inline]
409 #[must_use]
410 pub fn is_nan_mask(self) -> BVec4 {
411 BVec4::new(
412 self.x.is_nan(),
413 self.y.is_nan(),
414 self.z.is_nan(),
415 self.w.is_nan(),
416 )
417 }
418
419 #[doc(alias = "magnitude")]
421 #[inline]
422 #[must_use]
423 pub fn length(self) -> f64 {
424 math::sqrt(self.dot(self))
425 }
426
427 #[doc(alias = "magnitude2")]
431 #[inline]
432 #[must_use]
433 pub fn length_squared(self) -> f64 {
434 self.dot(self)
435 }
436
437 #[inline]
441 #[must_use]
442 pub fn length_recip(self) -> f64 {
443 self.length().recip()
444 }
445
446 #[inline]
448 #[must_use]
449 pub fn distance(self, rhs: Self) -> f64 {
450 (self - rhs).length()
451 }
452
453 #[inline]
455 #[must_use]
456 pub fn distance_squared(self, rhs: Self) -> f64 {
457 (self - rhs).length_squared()
458 }
459
460 #[inline]
462 #[must_use]
463 pub fn div_euclid(self, rhs: Self) -> Self {
464 Self::new(
465 math::div_euclid(self.x, rhs.x),
466 math::div_euclid(self.y, rhs.y),
467 math::div_euclid(self.z, rhs.z),
468 math::div_euclid(self.w, rhs.w),
469 )
470 }
471
472 #[inline]
476 #[must_use]
477 pub fn rem_euclid(self, rhs: Self) -> Self {
478 Self::new(
479 math::rem_euclid(self.x, rhs.x),
480 math::rem_euclid(self.y, rhs.y),
481 math::rem_euclid(self.z, rhs.z),
482 math::rem_euclid(self.w, rhs.w),
483 )
484 }
485
486 #[inline]
496 #[must_use]
497 pub fn normalize(self) -> Self {
498 #[allow(clippy::let_and_return)]
499 let normalized = self.mul(self.length_recip());
500 glam_assert!(normalized.is_finite());
501 normalized
502 }
503
504 #[inline]
511 #[must_use]
512 pub fn try_normalize(self) -> Option<Self> {
513 let rcp = self.length_recip();
514 if rcp.is_finite() && rcp > 0.0 {
515 Some(self * rcp)
516 } else {
517 None
518 }
519 }
520
521 #[inline]
528 #[must_use]
529 pub fn normalize_or_zero(self) -> Self {
530 let rcp = self.length_recip();
531 if rcp.is_finite() && rcp > 0.0 {
532 self * rcp
533 } else {
534 Self::ZERO
535 }
536 }
537
538 #[inline]
542 #[must_use]
543 pub fn is_normalized(self) -> bool {
544 math::abs(self.length_squared() - 1.0) <= 1e-4
546 }
547
548 #[inline]
556 #[must_use]
557 pub fn project_onto(self, rhs: Self) -> Self {
558 let other_len_sq_rcp = rhs.dot(rhs).recip();
559 glam_assert!(other_len_sq_rcp.is_finite());
560 rhs * self.dot(rhs) * other_len_sq_rcp
561 }
562
563 #[inline]
574 #[must_use]
575 pub fn reject_from(self, rhs: Self) -> Self {
576 self - self.project_onto(rhs)
577 }
578
579 #[inline]
587 #[must_use]
588 pub fn project_onto_normalized(self, rhs: Self) -> Self {
589 glam_assert!(rhs.is_normalized());
590 rhs * self.dot(rhs)
591 }
592
593 #[inline]
604 #[must_use]
605 pub fn reject_from_normalized(self, rhs: Self) -> Self {
606 self - self.project_onto_normalized(rhs)
607 }
608
609 #[inline]
612 #[must_use]
613 pub fn round(self) -> Self {
614 Self {
615 x: math::round(self.x),
616 y: math::round(self.y),
617 z: math::round(self.z),
618 w: math::round(self.w),
619 }
620 }
621
622 #[inline]
625 #[must_use]
626 pub fn floor(self) -> Self {
627 Self {
628 x: math::floor(self.x),
629 y: math::floor(self.y),
630 z: math::floor(self.z),
631 w: math::floor(self.w),
632 }
633 }
634
635 #[inline]
638 #[must_use]
639 pub fn ceil(self) -> Self {
640 Self {
641 x: math::ceil(self.x),
642 y: math::ceil(self.y),
643 z: math::ceil(self.z),
644 w: math::ceil(self.w),
645 }
646 }
647
648 #[inline]
651 #[must_use]
652 pub fn trunc(self) -> Self {
653 Self {
654 x: math::trunc(self.x),
655 y: math::trunc(self.y),
656 z: math::trunc(self.z),
657 w: math::trunc(self.w),
658 }
659 }
660
661 #[inline]
666 #[must_use]
667 pub fn fract(self) -> Self {
668 self - self.floor()
669 }
670
671 #[inline]
674 #[must_use]
675 pub fn exp(self) -> Self {
676 Self::new(
677 math::exp(self.x),
678 math::exp(self.y),
679 math::exp(self.z),
680 math::exp(self.w),
681 )
682 }
683
684 #[inline]
686 #[must_use]
687 pub fn powf(self, n: f64) -> Self {
688 Self::new(
689 math::powf(self.x, n),
690 math::powf(self.y, n),
691 math::powf(self.z, n),
692 math::powf(self.w, n),
693 )
694 }
695
696 #[inline]
698 #[must_use]
699 pub fn recip(self) -> Self {
700 Self {
701 x: 1.0 / self.x,
702 y: 1.0 / self.y,
703 z: 1.0 / self.z,
704 w: 1.0 / self.w,
705 }
706 }
707
708 #[doc(alias = "mix")]
714 #[inline]
715 #[must_use]
716 pub fn lerp(self, rhs: Self, s: f64) -> Self {
717 self + ((rhs - self) * s)
718 }
719
720 #[inline]
730 #[must_use]
731 pub fn abs_diff_eq(self, rhs: Self, max_abs_diff: f64) -> bool {
732 self.sub(rhs).abs().cmple(Self::splat(max_abs_diff)).all()
733 }
734
735 #[inline]
741 #[must_use]
742 pub fn clamp_length(self, min: f64, max: f64) -> Self {
743 glam_assert!(min <= max);
744 let length_sq = self.length_squared();
745 if length_sq < min * min {
746 min * (self / math::sqrt(length_sq))
747 } else if length_sq > max * max {
748 max * (self / math::sqrt(length_sq))
749 } else {
750 self
751 }
752 }
753
754 #[inline]
756 #[must_use]
757 pub fn clamp_length_max(self, max: f64) -> Self {
758 let length_sq = self.length_squared();
759 if length_sq > max * max {
760 max * (self / math::sqrt(length_sq))
761 } else {
762 self
763 }
764 }
765
766 #[inline]
768 #[must_use]
769 pub fn clamp_length_min(self, min: f64) -> Self {
770 let length_sq = self.length_squared();
771 if length_sq < min * min {
772 min * (self / math::sqrt(length_sq))
773 } else {
774 self
775 }
776 }
777
778 #[inline]
786 #[must_use]
787 pub fn mul_add(self, a: Self, b: Self) -> Self {
788 Self::new(
789 math::mul_add(self.x, a.x, b.x),
790 math::mul_add(self.y, a.y, b.y),
791 math::mul_add(self.z, a.z, b.z),
792 math::mul_add(self.w, a.w, b.w),
793 )
794 }
795
796 #[inline]
798 #[must_use]
799 pub fn as_vec4(&self) -> crate::Vec4 {
800 crate::Vec4::new(self.x as f32, self.y as f32, self.z as f32, self.w as f32)
801 }
802
803 #[inline]
805 #[must_use]
806 pub fn as_i16vec4(&self) -> crate::I16Vec4 {
807 crate::I16Vec4::new(self.x as i16, self.y as i16, self.z as i16, self.w as i16)
808 }
809
810 #[inline]
812 #[must_use]
813 pub fn as_u16vec4(&self) -> crate::U16Vec4 {
814 crate::U16Vec4::new(self.x as u16, self.y as u16, self.z as u16, self.w as u16)
815 }
816
817 #[inline]
819 #[must_use]
820 pub fn as_ivec4(&self) -> crate::IVec4 {
821 crate::IVec4::new(self.x as i32, self.y as i32, self.z as i32, self.w as i32)
822 }
823
824 #[inline]
826 #[must_use]
827 pub fn as_uvec4(&self) -> crate::UVec4 {
828 crate::UVec4::new(self.x as u32, self.y as u32, self.z as u32, self.w as u32)
829 }
830
831 #[inline]
833 #[must_use]
834 pub fn as_i64vec4(&self) -> crate::I64Vec4 {
835 crate::I64Vec4::new(self.x as i64, self.y as i64, self.z as i64, self.w as i64)
836 }
837
838 #[inline]
840 #[must_use]
841 pub fn as_u64vec4(&self) -> crate::U64Vec4 {
842 crate::U64Vec4::new(self.x as u64, self.y as u64, self.z as u64, self.w as u64)
843 }
844}
845
846impl Default for DVec4 {
847 #[inline(always)]
848 fn default() -> Self {
849 Self::ZERO
850 }
851}
852
853impl Div<DVec4> for DVec4 {
854 type Output = Self;
855 #[inline]
856 fn div(self, rhs: Self) -> Self {
857 Self {
858 x: self.x.div(rhs.x),
859 y: self.y.div(rhs.y),
860 z: self.z.div(rhs.z),
861 w: self.w.div(rhs.w),
862 }
863 }
864}
865
866impl DivAssign<DVec4> for DVec4 {
867 #[inline]
868 fn div_assign(&mut self, rhs: Self) {
869 self.x.div_assign(rhs.x);
870 self.y.div_assign(rhs.y);
871 self.z.div_assign(rhs.z);
872 self.w.div_assign(rhs.w);
873 }
874}
875
876impl Div<f64> for DVec4 {
877 type Output = Self;
878 #[inline]
879 fn div(self, rhs: f64) -> Self {
880 Self {
881 x: self.x.div(rhs),
882 y: self.y.div(rhs),
883 z: self.z.div(rhs),
884 w: self.w.div(rhs),
885 }
886 }
887}
888
889impl DivAssign<f64> for DVec4 {
890 #[inline]
891 fn div_assign(&mut self, rhs: f64) {
892 self.x.div_assign(rhs);
893 self.y.div_assign(rhs);
894 self.z.div_assign(rhs);
895 self.w.div_assign(rhs);
896 }
897}
898
899impl Div<DVec4> for f64 {
900 type Output = DVec4;
901 #[inline]
902 fn div(self, rhs: DVec4) -> DVec4 {
903 DVec4 {
904 x: self.div(rhs.x),
905 y: self.div(rhs.y),
906 z: self.div(rhs.z),
907 w: self.div(rhs.w),
908 }
909 }
910}
911
912impl Mul<DVec4> for DVec4 {
913 type Output = Self;
914 #[inline]
915 fn mul(self, rhs: Self) -> Self {
916 Self {
917 x: self.x.mul(rhs.x),
918 y: self.y.mul(rhs.y),
919 z: self.z.mul(rhs.z),
920 w: self.w.mul(rhs.w),
921 }
922 }
923}
924
925impl MulAssign<DVec4> for DVec4 {
926 #[inline]
927 fn mul_assign(&mut self, rhs: Self) {
928 self.x.mul_assign(rhs.x);
929 self.y.mul_assign(rhs.y);
930 self.z.mul_assign(rhs.z);
931 self.w.mul_assign(rhs.w);
932 }
933}
934
935impl Mul<f64> for DVec4 {
936 type Output = Self;
937 #[inline]
938 fn mul(self, rhs: f64) -> Self {
939 Self {
940 x: self.x.mul(rhs),
941 y: self.y.mul(rhs),
942 z: self.z.mul(rhs),
943 w: self.w.mul(rhs),
944 }
945 }
946}
947
948impl MulAssign<f64> for DVec4 {
949 #[inline]
950 fn mul_assign(&mut self, rhs: f64) {
951 self.x.mul_assign(rhs);
952 self.y.mul_assign(rhs);
953 self.z.mul_assign(rhs);
954 self.w.mul_assign(rhs);
955 }
956}
957
958impl Mul<DVec4> for f64 {
959 type Output = DVec4;
960 #[inline]
961 fn mul(self, rhs: DVec4) -> DVec4 {
962 DVec4 {
963 x: self.mul(rhs.x),
964 y: self.mul(rhs.y),
965 z: self.mul(rhs.z),
966 w: self.mul(rhs.w),
967 }
968 }
969}
970
971impl Add<DVec4> for DVec4 {
972 type Output = Self;
973 #[inline]
974 fn add(self, rhs: Self) -> Self {
975 Self {
976 x: self.x.add(rhs.x),
977 y: self.y.add(rhs.y),
978 z: self.z.add(rhs.z),
979 w: self.w.add(rhs.w),
980 }
981 }
982}
983
984impl AddAssign<DVec4> for DVec4 {
985 #[inline]
986 fn add_assign(&mut self, rhs: Self) {
987 self.x.add_assign(rhs.x);
988 self.y.add_assign(rhs.y);
989 self.z.add_assign(rhs.z);
990 self.w.add_assign(rhs.w);
991 }
992}
993
994impl Add<f64> for DVec4 {
995 type Output = Self;
996 #[inline]
997 fn add(self, rhs: f64) -> Self {
998 Self {
999 x: self.x.add(rhs),
1000 y: self.y.add(rhs),
1001 z: self.z.add(rhs),
1002 w: self.w.add(rhs),
1003 }
1004 }
1005}
1006
1007impl AddAssign<f64> for DVec4 {
1008 #[inline]
1009 fn add_assign(&mut self, rhs: f64) {
1010 self.x.add_assign(rhs);
1011 self.y.add_assign(rhs);
1012 self.z.add_assign(rhs);
1013 self.w.add_assign(rhs);
1014 }
1015}
1016
1017impl Add<DVec4> for f64 {
1018 type Output = DVec4;
1019 #[inline]
1020 fn add(self, rhs: DVec4) -> DVec4 {
1021 DVec4 {
1022 x: self.add(rhs.x),
1023 y: self.add(rhs.y),
1024 z: self.add(rhs.z),
1025 w: self.add(rhs.w),
1026 }
1027 }
1028}
1029
1030impl Sub<DVec4> for DVec4 {
1031 type Output = Self;
1032 #[inline]
1033 fn sub(self, rhs: Self) -> Self {
1034 Self {
1035 x: self.x.sub(rhs.x),
1036 y: self.y.sub(rhs.y),
1037 z: self.z.sub(rhs.z),
1038 w: self.w.sub(rhs.w),
1039 }
1040 }
1041}
1042
1043impl SubAssign<DVec4> for DVec4 {
1044 #[inline]
1045 fn sub_assign(&mut self, rhs: DVec4) {
1046 self.x.sub_assign(rhs.x);
1047 self.y.sub_assign(rhs.y);
1048 self.z.sub_assign(rhs.z);
1049 self.w.sub_assign(rhs.w);
1050 }
1051}
1052
1053impl Sub<f64> for DVec4 {
1054 type Output = Self;
1055 #[inline]
1056 fn sub(self, rhs: f64) -> Self {
1057 Self {
1058 x: self.x.sub(rhs),
1059 y: self.y.sub(rhs),
1060 z: self.z.sub(rhs),
1061 w: self.w.sub(rhs),
1062 }
1063 }
1064}
1065
1066impl SubAssign<f64> for DVec4 {
1067 #[inline]
1068 fn sub_assign(&mut self, rhs: f64) {
1069 self.x.sub_assign(rhs);
1070 self.y.sub_assign(rhs);
1071 self.z.sub_assign(rhs);
1072 self.w.sub_assign(rhs);
1073 }
1074}
1075
1076impl Sub<DVec4> for f64 {
1077 type Output = DVec4;
1078 #[inline]
1079 fn sub(self, rhs: DVec4) -> DVec4 {
1080 DVec4 {
1081 x: self.sub(rhs.x),
1082 y: self.sub(rhs.y),
1083 z: self.sub(rhs.z),
1084 w: self.sub(rhs.w),
1085 }
1086 }
1087}
1088
1089impl Rem<DVec4> for DVec4 {
1090 type Output = Self;
1091 #[inline]
1092 fn rem(self, rhs: Self) -> Self {
1093 Self {
1094 x: self.x.rem(rhs.x),
1095 y: self.y.rem(rhs.y),
1096 z: self.z.rem(rhs.z),
1097 w: self.w.rem(rhs.w),
1098 }
1099 }
1100}
1101
1102impl RemAssign<DVec4> for DVec4 {
1103 #[inline]
1104 fn rem_assign(&mut self, rhs: Self) {
1105 self.x.rem_assign(rhs.x);
1106 self.y.rem_assign(rhs.y);
1107 self.z.rem_assign(rhs.z);
1108 self.w.rem_assign(rhs.w);
1109 }
1110}
1111
1112impl Rem<f64> for DVec4 {
1113 type Output = Self;
1114 #[inline]
1115 fn rem(self, rhs: f64) -> Self {
1116 Self {
1117 x: self.x.rem(rhs),
1118 y: self.y.rem(rhs),
1119 z: self.z.rem(rhs),
1120 w: self.w.rem(rhs),
1121 }
1122 }
1123}
1124
1125impl RemAssign<f64> for DVec4 {
1126 #[inline]
1127 fn rem_assign(&mut self, rhs: f64) {
1128 self.x.rem_assign(rhs);
1129 self.y.rem_assign(rhs);
1130 self.z.rem_assign(rhs);
1131 self.w.rem_assign(rhs);
1132 }
1133}
1134
1135impl Rem<DVec4> for f64 {
1136 type Output = DVec4;
1137 #[inline]
1138 fn rem(self, rhs: DVec4) -> DVec4 {
1139 DVec4 {
1140 x: self.rem(rhs.x),
1141 y: self.rem(rhs.y),
1142 z: self.rem(rhs.z),
1143 w: self.rem(rhs.w),
1144 }
1145 }
1146}
1147
1148#[cfg(not(target_arch = "spirv"))]
1149impl AsRef<[f64; 4]> for DVec4 {
1150 #[inline]
1151 fn as_ref(&self) -> &[f64; 4] {
1152 unsafe { &*(self as *const DVec4 as *const [f64; 4]) }
1153 }
1154}
1155
1156#[cfg(not(target_arch = "spirv"))]
1157impl AsMut<[f64; 4]> for DVec4 {
1158 #[inline]
1159 fn as_mut(&mut self) -> &mut [f64; 4] {
1160 unsafe { &mut *(self as *mut DVec4 as *mut [f64; 4]) }
1161 }
1162}
1163
1164impl Sum for DVec4 {
1165 #[inline]
1166 fn sum<I>(iter: I) -> Self
1167 where
1168 I: Iterator<Item = Self>,
1169 {
1170 iter.fold(Self::ZERO, Self::add)
1171 }
1172}
1173
1174impl<'a> Sum<&'a Self> for DVec4 {
1175 #[inline]
1176 fn sum<I>(iter: I) -> Self
1177 where
1178 I: Iterator<Item = &'a Self>,
1179 {
1180 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1181 }
1182}
1183
1184impl Product for DVec4 {
1185 #[inline]
1186 fn product<I>(iter: I) -> Self
1187 where
1188 I: Iterator<Item = Self>,
1189 {
1190 iter.fold(Self::ONE, Self::mul)
1191 }
1192}
1193
1194impl<'a> Product<&'a Self> for DVec4 {
1195 #[inline]
1196 fn product<I>(iter: I) -> Self
1197 where
1198 I: Iterator<Item = &'a Self>,
1199 {
1200 iter.fold(Self::ONE, |a, &b| Self::mul(a, b))
1201 }
1202}
1203
1204impl Neg for DVec4 {
1205 type Output = Self;
1206 #[inline]
1207 fn neg(self) -> Self {
1208 Self {
1209 x: self.x.neg(),
1210 y: self.y.neg(),
1211 z: self.z.neg(),
1212 w: self.w.neg(),
1213 }
1214 }
1215}
1216
1217impl Index<usize> for DVec4 {
1218 type Output = f64;
1219 #[inline]
1220 fn index(&self, index: usize) -> &Self::Output {
1221 match index {
1222 0 => &self.x,
1223 1 => &self.y,
1224 2 => &self.z,
1225 3 => &self.w,
1226 _ => panic!("index out of bounds"),
1227 }
1228 }
1229}
1230
1231impl IndexMut<usize> for DVec4 {
1232 #[inline]
1233 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1234 match index {
1235 0 => &mut self.x,
1236 1 => &mut self.y,
1237 2 => &mut self.z,
1238 3 => &mut self.w,
1239 _ => panic!("index out of bounds"),
1240 }
1241 }
1242}
1243
1244#[cfg(not(target_arch = "spirv"))]
1245impl fmt::Display for DVec4 {
1246 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1247 write!(f, "[{}, {}, {}, {}]", self.x, self.y, self.z, self.w)
1248 }
1249}
1250
1251#[cfg(not(target_arch = "spirv"))]
1252impl fmt::Debug for DVec4 {
1253 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1254 fmt.debug_tuple(stringify!(DVec4))
1255 .field(&self.x)
1256 .field(&self.y)
1257 .field(&self.z)
1258 .field(&self.w)
1259 .finish()
1260 }
1261}
1262
1263impl From<[f64; 4]> for DVec4 {
1264 #[inline]
1265 fn from(a: [f64; 4]) -> Self {
1266 Self::new(a[0], a[1], a[2], a[3])
1267 }
1268}
1269
1270impl From<DVec4> for [f64; 4] {
1271 #[inline]
1272 fn from(v: DVec4) -> Self {
1273 [v.x, v.y, v.z, v.w]
1274 }
1275}
1276
1277impl From<(f64, f64, f64, f64)> for DVec4 {
1278 #[inline]
1279 fn from(t: (f64, f64, f64, f64)) -> Self {
1280 Self::new(t.0, t.1, t.2, t.3)
1281 }
1282}
1283
1284impl From<DVec4> for (f64, f64, f64, f64) {
1285 #[inline]
1286 fn from(v: DVec4) -> Self {
1287 (v.x, v.y, v.z, v.w)
1288 }
1289}
1290
1291impl From<(DVec3, f64)> for DVec4 {
1292 #[inline]
1293 fn from((v, w): (DVec3, f64)) -> Self {
1294 Self::new(v.x, v.y, v.z, w)
1295 }
1296}
1297
1298impl From<(f64, DVec3)> for DVec4 {
1299 #[inline]
1300 fn from((x, v): (f64, DVec3)) -> Self {
1301 Self::new(x, v.x, v.y, v.z)
1302 }
1303}
1304
1305impl From<(DVec2, f64, f64)> for DVec4 {
1306 #[inline]
1307 fn from((v, z, w): (DVec2, f64, f64)) -> Self {
1308 Self::new(v.x, v.y, z, w)
1309 }
1310}
1311
1312impl From<(DVec2, DVec2)> for DVec4 {
1313 #[inline]
1314 fn from((v, u): (DVec2, DVec2)) -> Self {
1315 Self::new(v.x, v.y, u.x, u.y)
1316 }
1317}
1318
1319impl From<Vec4> for DVec4 {
1320 #[inline]
1321 fn from(v: Vec4) -> Self {
1322 Self::new(
1323 f64::from(v.x),
1324 f64::from(v.y),
1325 f64::from(v.z),
1326 f64::from(v.w),
1327 )
1328 }
1329}
1330
1331impl From<IVec4> for DVec4 {
1332 #[inline]
1333 fn from(v: IVec4) -> Self {
1334 Self::new(
1335 f64::from(v.x),
1336 f64::from(v.y),
1337 f64::from(v.z),
1338 f64::from(v.w),
1339 )
1340 }
1341}
1342
1343impl From<UVec4> for DVec4 {
1344 #[inline]
1345 fn from(v: UVec4) -> Self {
1346 Self::new(
1347 f64::from(v.x),
1348 f64::from(v.y),
1349 f64::from(v.z),
1350 f64::from(v.w),
1351 )
1352 }
1353}