1use crate::{f32::math, sse2::*, BVec4, BVec4A, Vec2, Vec3, Vec3A};
4
5use core::fmt;
6use core::iter::{Product, Sum};
7use core::ops::*;
8
9#[cfg(target_arch = "x86")]
10use core::arch::x86::*;
11#[cfg(target_arch = "x86_64")]
12use core::arch::x86_64::*;
13
14#[cfg(feature = "zerocopy-08")]
15use zerocopy_derive_08::*;
16
17#[repr(C)]
18union UnionCast {
19 a: [f32; 4],
20 v: Vec4,
21}
22
23#[inline(always)]
25#[must_use]
26pub const fn vec4(x: f32, y: f32, z: f32, w: f32) -> Vec4 {
27 Vec4::new(x, y, z, w)
28}
29
30#[derive(Clone, Copy)]
36#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
37#[cfg_attr(
38 feature = "zerocopy-08",
39 derive(FromBytes, Immutable, IntoBytes, KnownLayout)
40)]
41#[repr(transparent)]
42pub struct Vec4(pub(crate) __m128);
43
44impl Vec4 {
45 pub const ZERO: Self = Self::splat(0.0);
47
48 pub const ONE: Self = Self::splat(1.0);
50
51 pub const NEG_ONE: Self = Self::splat(-1.0);
53
54 pub const MIN: Self = Self::splat(f32::MIN);
56
57 pub const MAX: Self = Self::splat(f32::MAX);
59
60 pub const NAN: Self = Self::splat(f32::NAN);
62
63 pub const INFINITY: Self = Self::splat(f32::INFINITY);
65
66 pub const NEG_INFINITY: Self = Self::splat(f32::NEG_INFINITY);
68
69 pub const X: Self = Self::new(1.0, 0.0, 0.0, 0.0);
71
72 pub const Y: Self = Self::new(0.0, 1.0, 0.0, 0.0);
74
75 pub const Z: Self = Self::new(0.0, 0.0, 1.0, 0.0);
77
78 pub const W: Self = Self::new(0.0, 0.0, 0.0, 1.0);
80
81 pub const NEG_X: Self = Self::new(-1.0, 0.0, 0.0, 0.0);
83
84 pub const NEG_Y: Self = Self::new(0.0, -1.0, 0.0, 0.0);
86
87 pub const NEG_Z: Self = Self::new(0.0, 0.0, -1.0, 0.0);
89
90 pub const NEG_W: Self = Self::new(0.0, 0.0, 0.0, -1.0);
92
93 pub const AXES: [Self; 4] = [Self::X, Self::Y, Self::Z, Self::W];
95
96 pub const USES_CORE_SIMD: bool = false;
98 pub const USES_NEON: bool = false;
100 pub const USES_SCALAR_MATH: bool = false;
102 pub const USES_SSE2: bool = true;
104 pub const USES_WASM_SIMD: bool = false;
106 #[deprecated(since = "0.31.0", note = "Renamed to USES_WASM_SIMD")]
107 pub const USES_WASM32_SIMD: bool = false;
108
109 #[inline(always)]
111 #[must_use]
112 pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
113 unsafe { UnionCast { a: [x, y, z, w] }.v }
114 }
115
116 #[inline]
118 #[must_use]
119 pub const fn splat(v: f32) -> Self {
120 unsafe { UnionCast { a: [v; 4] }.v }
121 }
122
123 #[inline]
125 #[must_use]
126 pub fn map<F>(self, mut f: F) -> Self
127 where
128 F: FnMut(f32) -> f32,
129 {
130 Self::new(f(self.x), f(self.y), f(self.z), f(self.w))
131 }
132
133 #[inline]
139 #[must_use]
140 pub fn select(mask: BVec4A, if_true: Self, if_false: Self) -> Self {
141 Self(unsafe {
142 _mm_or_ps(
143 _mm_andnot_ps(mask.0, if_false.0),
144 _mm_and_ps(if_true.0, mask.0),
145 )
146 })
147 }
148
149 #[inline]
151 #[must_use]
152 pub const fn from_array(a: [f32; 4]) -> Self {
153 Self::new(a[0], a[1], a[2], a[3])
154 }
155
156 #[inline]
158 #[must_use]
159 pub const fn to_array(&self) -> [f32; 4] {
160 unsafe { *(self as *const Self as *const [f32; 4]) }
161 }
162
163 #[inline]
169 #[must_use]
170 #[track_caller]
171 pub const fn from_slice(slice: &[f32]) -> Self {
172 assert!(slice.len() >= 4);
173 Self::new(slice[0], slice[1], slice[2], slice[3])
174 }
175
176 #[inline]
182 #[track_caller]
183 pub fn write_to_slice(self, slice: &mut [f32]) {
184 assert!(slice.len() >= 4);
185 unsafe {
186 _mm_storeu_ps(slice.as_mut_ptr(), self.0);
187 }
188 }
189
190 #[inline]
196 #[must_use]
197 pub fn truncate(self) -> Vec3 {
198 use crate::swizzles::Vec4Swizzles;
199 self.xyz()
200 }
201
202 #[inline]
210 #[must_use]
211 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
212 pub fn project(self) -> Vec3 {
213 Vec3::from_homogeneous(self)
214 }
215
216 #[inline]
218 #[must_use]
219 pub fn with_x(mut self, x: f32) -> Self {
220 self.x = x;
221 self
222 }
223
224 #[inline]
226 #[must_use]
227 pub fn with_y(mut self, y: f32) -> Self {
228 self.y = y;
229 self
230 }
231
232 #[inline]
234 #[must_use]
235 pub fn with_z(mut self, z: f32) -> Self {
236 self.z = z;
237 self
238 }
239
240 #[inline]
242 #[must_use]
243 pub fn with_w(mut self, w: f32) -> Self {
244 self.w = w;
245 self
246 }
247
248 #[inline]
250 #[must_use]
251 pub fn dot(self, rhs: Self) -> f32 {
252 unsafe { dot4(self.0, rhs.0) }
253 }
254
255 #[inline]
257 #[must_use]
258 pub fn dot_into_vec(self, rhs: Self) -> Self {
259 Self(unsafe { dot4_into_m128(self.0, rhs.0) })
260 }
261
262 #[inline]
269 #[must_use]
270 pub fn min(self, rhs: Self) -> Self {
271 Self(unsafe { _mm_min_ps(self.0, rhs.0) })
272 }
273
274 #[inline]
281 #[must_use]
282 pub fn max(self, rhs: Self) -> Self {
283 Self(unsafe { _mm_max_ps(self.0, rhs.0) })
284 }
285
286 #[inline]
297 #[must_use]
298 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
299 pub fn clamp(self, min: Self, max: Self) -> Self {
300 glam_assert!(min.cmple(max).all(), "clamp: expected min <= max");
301 self.max(min).min(max)
302 }
303
304 #[inline]
311 #[must_use]
312 pub fn min_element(self) -> f32 {
313 unsafe {
314 let v = self.0;
315 let v = _mm_min_ps(v, _mm_shuffle_ps(v, v, 0b00_00_11_10));
316 let v = _mm_min_ps(v, _mm_shuffle_ps(v, v, 0b00_00_00_01));
317 _mm_cvtss_f32(v)
318 }
319 }
320
321 #[inline]
328 #[must_use]
329 pub fn max_element(self) -> f32 {
330 unsafe {
331 let v = self.0;
332 let v = _mm_max_ps(v, _mm_shuffle_ps(v, v, 0b00_00_11_10));
333 let v = _mm_max_ps(v, _mm_shuffle_ps(v, v, 0b00_00_00_01));
334 _mm_cvtss_f32(v)
335 }
336 }
337
338 #[doc(alias = "argmin")]
340 #[inline]
341 #[must_use]
342 pub fn min_position(self) -> usize {
343 let mut min = self.x;
344 let mut index = 0;
345 if self.y < min {
346 min = self.y;
347 index = 1;
348 }
349 if self.z < min {
350 min = self.z;
351 index = 2;
352 }
353 if self.w < min {
354 index = 3;
355 }
356 index
357 }
358
359 #[doc(alias = "argmax")]
361 #[inline]
362 #[must_use]
363 pub fn max_position(self) -> usize {
364 let mut max = self.x;
365 let mut index = 0;
366 if self.y > max {
367 max = self.y;
368 index = 1;
369 }
370 if self.z > max {
371 max = self.z;
372 index = 2;
373 }
374 if self.w > max {
375 index = 3;
376 }
377 index
378 }
379
380 #[inline]
384 #[must_use]
385 pub fn element_sum(self) -> f32 {
386 unsafe {
387 let v = self.0;
388 let v = _mm_add_ps(v, _mm_shuffle_ps(v, v, 0b00_11_00_01));
389 let v = _mm_add_ps(v, _mm_shuffle_ps(v, v, 0b00_00_00_10));
390 _mm_cvtss_f32(v)
391 }
392 }
393
394 #[inline]
398 #[must_use]
399 pub fn element_product(self) -> f32 {
400 unsafe {
401 let v = self.0;
402 let v = _mm_mul_ps(v, _mm_shuffle_ps(v, v, 0b00_11_00_01));
403 let v = _mm_mul_ps(v, _mm_shuffle_ps(v, v, 0b00_00_00_10));
404 _mm_cvtss_f32(v)
405 }
406 }
407
408 #[inline]
414 #[must_use]
415 pub fn cmpeq(self, rhs: Self) -> BVec4A {
416 BVec4A(unsafe { _mm_cmpeq_ps(self.0, rhs.0) })
417 }
418
419 #[inline]
425 #[must_use]
426 pub fn cmpne(self, rhs: Self) -> BVec4A {
427 BVec4A(unsafe { _mm_cmpneq_ps(self.0, rhs.0) })
428 }
429
430 #[inline]
436 #[must_use]
437 pub fn cmpge(self, rhs: Self) -> BVec4A {
438 BVec4A(unsafe { _mm_cmpge_ps(self.0, rhs.0) })
439 }
440
441 #[inline]
447 #[must_use]
448 pub fn cmpgt(self, rhs: Self) -> BVec4A {
449 BVec4A(unsafe { _mm_cmpgt_ps(self.0, rhs.0) })
450 }
451
452 #[inline]
458 #[must_use]
459 pub fn cmple(self, rhs: Self) -> BVec4A {
460 BVec4A(unsafe { _mm_cmple_ps(self.0, rhs.0) })
461 }
462
463 #[inline]
469 #[must_use]
470 pub fn cmplt(self, rhs: Self) -> BVec4A {
471 BVec4A(unsafe { _mm_cmplt_ps(self.0, rhs.0) })
472 }
473
474 #[inline]
476 #[must_use]
477 pub fn abs(self) -> Self {
478 Self(unsafe { crate::sse2::m128_abs(self.0) })
479 }
480
481 #[inline]
487 #[must_use]
488 pub fn signum(self) -> Self {
489 let result = Self(unsafe { _mm_or_ps(_mm_and_ps(self.0, Self::NEG_ONE.0), Self::ONE.0) });
490 let mask = self.is_nan_mask();
491 Self::select(mask, self, result)
492 }
493
494 #[inline]
496 #[must_use]
497 pub fn copysign(self, rhs: Self) -> Self {
498 let mask = Self::splat(-0.0);
499 Self(unsafe { _mm_or_ps(_mm_and_ps(rhs.0, mask.0), _mm_andnot_ps(mask.0, self.0)) })
500 }
501
502 #[inline]
510 #[must_use]
511 pub fn is_negative_bitmask(self) -> u32 {
512 unsafe { _mm_movemask_ps(self.0) as u32 }
513 }
514
515 #[inline]
520 #[must_use]
521 pub fn is_negative_mask(self) -> BVec4A {
522 BVec4A(unsafe {
523 _mm_castsi128_ps(_mm_cmplt_epi32(
524 _mm_castps_si128(self.0),
525 _mm_setzero_si128(),
526 ))
527 })
528 }
529
530 #[inline]
533 #[must_use]
534 pub fn is_finite(self) -> bool {
535 self.is_finite_mask().all()
536 }
537
538 #[inline]
542 #[must_use]
543 pub fn is_finite_mask(self) -> BVec4A {
544 BVec4A(unsafe { _mm_cmplt_ps(crate::sse2::m128_abs(self.0), Self::INFINITY.0) })
545 }
546
547 #[inline]
549 #[must_use]
550 pub fn is_nan(self) -> bool {
551 self.is_nan_mask().any()
552 }
553
554 #[inline]
558 #[must_use]
559 pub fn is_nan_mask(self) -> BVec4A {
560 BVec4A(unsafe { _mm_cmpunord_ps(self.0, self.0) })
561 }
562
563 #[doc(alias = "magnitude")]
565 #[inline]
566 #[must_use]
567 pub fn length(self) -> f32 {
568 unsafe {
569 let dot = dot4_in_x(self.0, self.0);
570 _mm_cvtss_f32(_mm_sqrt_ps(dot))
571 }
572 }
573
574 #[allow(dead_code)]
576 fn is_non_zero(self) -> bool {
577 self.length_squared() > 0.0
578 }
579
580 #[doc(alias = "magnitude2")]
584 #[inline]
585 #[must_use]
586 pub fn length_squared(self) -> f32 {
587 self.dot(self)
588 }
589
590 #[inline]
594 #[must_use]
595 pub fn length_recip(self) -> f32 {
596 unsafe {
597 let dot = dot4_in_x(self.0, self.0);
598 _mm_cvtss_f32(_mm_div_ps(Self::ONE.0, _mm_sqrt_ps(dot)))
599 }
600 }
601
602 #[inline]
604 #[must_use]
605 pub fn distance(self, rhs: Self) -> f32 {
606 (self - rhs).length()
607 }
608
609 #[inline]
611 #[must_use]
612 pub fn distance_squared(self, rhs: Self) -> f32 {
613 (self - rhs).length_squared()
614 }
615
616 #[inline]
618 #[must_use]
619 pub fn div_euclid(self, rhs: Self) -> Self {
620 Self::new(
621 math::div_euclid(self.x, rhs.x),
622 math::div_euclid(self.y, rhs.y),
623 math::div_euclid(self.z, rhs.z),
624 math::div_euclid(self.w, rhs.w),
625 )
626 }
627
628 #[inline]
632 #[must_use]
633 pub fn rem_euclid(self, rhs: Self) -> Self {
634 Self::new(
635 math::rem_euclid(self.x, rhs.x),
636 math::rem_euclid(self.y, rhs.y),
637 math::rem_euclid(self.z, rhs.z),
638 math::rem_euclid(self.w, rhs.w),
639 )
640 }
641
642 #[inline]
652 #[must_use]
653 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
654 pub fn normalize(self) -> Self {
655 unsafe {
656 let length = _mm_sqrt_ps(dot4_into_m128(self.0, self.0));
657 #[allow(clippy::let_and_return)]
658 let normalized = Self(_mm_div_ps(self.0, length));
659 glam_assert!(normalized.is_finite());
660 normalized
661 }
662 }
663
664 #[inline]
671 #[must_use]
672 pub fn try_normalize(self) -> Option<Self> {
673 let rcp = self.length_recip();
674 if rcp.is_finite() && rcp > 0.0 {
675 Some(self * rcp)
676 } else {
677 None
678 }
679 }
680
681 #[inline]
689 #[must_use]
690 pub fn normalize_or(self, fallback: Self) -> Self {
691 let rcp = self.length_recip();
692 if rcp.is_finite() && rcp > 0.0 {
693 self * rcp
694 } else {
695 fallback
696 }
697 }
698
699 #[inline]
706 #[must_use]
707 pub fn normalize_or_zero(self) -> Self {
708 self.normalize_or(Self::ZERO)
709 }
710
711 #[inline]
715 #[must_use]
716 pub fn normalize_and_length(self) -> (Self, f32) {
717 let length = self.length();
718 let rcp = 1.0 / length;
719 if rcp.is_finite() && rcp > 0.0 {
720 (self * rcp, length)
721 } else {
722 (Self::X, 0.0)
723 }
724 }
725
726 #[inline]
730 #[must_use]
731 pub fn is_normalized(self) -> bool {
732 math::abs(self.length_squared() - 1.0) <= 2e-4
733 }
734
735 #[inline]
743 #[must_use]
744 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
745 pub fn project_onto(self, rhs: Self) -> Self {
746 let rhs_len_sq = rhs.dot(rhs);
747 glam_assert!(rhs_len_sq != 0.0);
748 rhs * (self.dot(rhs) / rhs_len_sq)
749 }
750
751 #[doc(alias("plane"))]
762 #[inline]
763 #[must_use]
764 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
765 pub fn reject_from(self, rhs: Self) -> Self {
766 self - self.project_onto(rhs)
767 }
768
769 #[inline]
777 #[must_use]
778 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
779 pub fn project_onto_normalized(self, rhs: Self) -> Self {
780 glam_assert!(rhs.is_normalized());
781 rhs * self.dot(rhs)
782 }
783
784 #[doc(alias("plane"))]
795 #[inline]
796 #[must_use]
797 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
798 pub fn reject_from_normalized(self, rhs: Self) -> Self {
799 self - self.project_onto_normalized(rhs)
800 }
801
802 #[inline]
805 #[must_use]
806 pub fn round(self) -> Self {
807 Self(unsafe { m128_round(self.0) })
808 }
809
810 #[inline]
813 #[must_use]
814 pub fn floor(self) -> Self {
815 Self(unsafe { m128_floor(self.0) })
816 }
817
818 #[inline]
821 #[must_use]
822 pub fn ceil(self) -> Self {
823 Self(unsafe { m128_ceil(self.0) })
824 }
825
826 #[inline]
829 #[must_use]
830 pub fn trunc(self) -> Self {
831 Self(unsafe { m128_trunc(self.0) })
832 }
833
834 #[inline]
838 #[must_use]
839 pub fn step(self, rhs: Self) -> Self {
840 Self::select(rhs.cmplt(self), Self::ZERO, Self::ONE)
841 }
842
843 #[inline]
854 #[must_use]
855 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
856 pub fn smoothstep(self, edge0: Self, edge1: Self) -> Self {
857 glam_assert!(edge0.cmplt(edge1).all());
858 let t = ((self - edge0) / (edge1 - edge0)).saturate();
859 t * t * (Self::splat(3.0) - Self::splat(2.0) * t)
860 }
861
862 #[inline]
864 #[must_use]
865 pub fn saturate(self) -> Self {
866 self.clamp(Self::ZERO, Self::ONE)
867 }
868
869 #[inline]
876 #[must_use]
877 pub fn fract(self) -> Self {
878 self - self.trunc()
879 }
880
881 #[inline]
888 #[must_use]
889 pub fn fract_gl(self) -> Self {
890 self - self.floor()
891 }
892
893 #[inline]
896 #[must_use]
897 pub fn exp(self) -> Self {
898 Self::new(
899 math::exp(self.x),
900 math::exp(self.y),
901 math::exp(self.z),
902 math::exp(self.w),
903 )
904 }
905
906 #[inline]
908 #[must_use]
909 pub fn exp2(self) -> Self {
910 Self::new(
911 math::exp2(self.x),
912 math::exp2(self.y),
913 math::exp2(self.z),
914 math::exp2(self.w),
915 )
916 }
917
918 #[inline]
921 #[must_use]
922 pub fn ln(self) -> Self {
923 Self::new(
924 math::ln(self.x),
925 math::ln(self.y),
926 math::ln(self.z),
927 math::ln(self.w),
928 )
929 }
930
931 #[inline]
934 #[must_use]
935 pub fn log2(self) -> Self {
936 Self::new(
937 math::log2(self.x),
938 math::log2(self.y),
939 math::log2(self.z),
940 math::log2(self.w),
941 )
942 }
943
944 #[inline]
946 #[must_use]
947 pub fn powf(self, n: f32) -> Self {
948 Self::new(
949 math::powf(self.x, n),
950 math::powf(self.y, n),
951 math::powf(self.z, n),
952 math::powf(self.w, n),
953 )
954 }
955
956 #[inline]
959 #[must_use]
960 pub fn sqrt(self) -> Self {
961 Self::new(
962 math::sqrt(self.x),
963 math::sqrt(self.y),
964 math::sqrt(self.z),
965 math::sqrt(self.w),
966 )
967 }
968
969 #[inline]
971 #[must_use]
972 pub fn cos(self) -> Self {
973 Self::new(
974 math::cos(self.x),
975 math::cos(self.y),
976 math::cos(self.z),
977 math::cos(self.w),
978 )
979 }
980
981 #[inline]
983 #[must_use]
984 pub fn sin(self) -> Self {
985 Self::new(
986 math::sin(self.x),
987 math::sin(self.y),
988 math::sin(self.z),
989 math::sin(self.w),
990 )
991 }
992
993 #[inline]
995 #[must_use]
996 pub fn sin_cos(self) -> (Self, Self) {
997 let (sin_x, cos_x) = math::sin_cos(self.x);
998 let (sin_y, cos_y) = math::sin_cos(self.y);
999 let (sin_z, cos_z) = math::sin_cos(self.z);
1000 let (sin_w, cos_w) = math::sin_cos(self.w);
1001
1002 (
1003 Self::new(sin_x, sin_y, sin_z, sin_w),
1004 Self::new(cos_x, cos_y, cos_z, cos_w),
1005 )
1006 }
1007
1008 #[inline]
1010 #[must_use]
1011 pub fn recip(self) -> Self {
1012 Self(unsafe { _mm_div_ps(Self::ONE.0, self.0) })
1013 }
1014
1015 #[doc(alias = "mix")]
1027 #[inline]
1028 #[must_use]
1029 pub fn lerp(self, rhs: Self, s: f32) -> Self {
1030 self * (1.0 - s) + rhs * s
1031 }
1032
1033 #[doc(alias = "mix")]
1050 #[inline]
1051 #[must_use]
1052 pub fn lerp_monotonic(self, rhs: Self, s: f32) -> Self {
1053 unsafe {
1054 Self(m128_mul_add(
1055 _mm_sub_ps(rhs.0, self.0),
1056 _mm_set_ps1(s),
1057 self.0,
1058 ))
1059 }
1060 }
1061
1062 #[inline]
1067 #[must_use]
1068 pub fn move_towards(self, rhs: Self, d: f32) -> Self {
1069 let a = rhs - self;
1070 let len = a.length();
1071 if len <= d || len <= 1e-4 {
1072 return rhs;
1073 }
1074 self + a / len * d
1075 }
1076
1077 #[inline]
1083 pub fn midpoint(self, rhs: Self) -> Self {
1084 (self + rhs) * 0.5
1085 }
1086
1087 #[inline]
1097 #[must_use]
1098 pub fn abs_diff_eq(self, rhs: Self, max_abs_diff: f32) -> bool {
1099 self.sub(rhs).abs().cmple(Self::splat(max_abs_diff)).all()
1100 }
1101
1102 #[inline]
1108 #[must_use]
1109 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1110 pub fn clamp_length(self, min: f32, max: f32) -> Self {
1111 glam_assert!(0.0 <= min);
1112 glam_assert!(min <= max);
1113 let length_sq = self.length_squared();
1114 if length_sq < min * min {
1115 min * (self / math::sqrt(length_sq))
1116 } else if length_sq > max * max {
1117 max * (self / math::sqrt(length_sq))
1118 } else {
1119 self
1120 }
1121 }
1122
1123 #[inline]
1129 #[must_use]
1130 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1131 pub fn clamp_length_max(self, max: f32) -> Self {
1132 glam_assert!(0.0 <= max);
1133 let length_sq = self.length_squared();
1134 if length_sq > max * max {
1135 max * (self / math::sqrt(length_sq))
1136 } else {
1137 self
1138 }
1139 }
1140
1141 #[inline]
1147 #[must_use]
1148 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1149 pub fn clamp_length_min(self, min: f32) -> Self {
1150 glam_assert!(0.0 <= min);
1151 let length_sq = self.length_squared();
1152 if length_sq < min * min {
1153 min * (self / math::sqrt(length_sq))
1154 } else {
1155 self
1156 }
1157 }
1158
1159 #[inline]
1167 #[must_use]
1168 pub fn mul_add(self, a: Self, b: Self) -> Self {
1169 #[cfg(target_feature = "fma")]
1170 unsafe {
1171 Self(_mm_fmadd_ps(self.0, a.0, b.0))
1172 }
1173 #[cfg(not(target_feature = "fma"))]
1174 Self::new(
1175 math::mul_add(self.x, a.x, b.x),
1176 math::mul_add(self.y, a.y, b.y),
1177 math::mul_add(self.z, a.z, b.z),
1178 math::mul_add(self.w, a.w, b.w),
1179 )
1180 }
1181
1182 #[inline]
1191 #[must_use]
1192 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1193 pub fn reflect(self, normal: Self) -> Self {
1194 glam_assert!(normal.is_normalized());
1195 self - 2.0 * self.dot(normal) * normal
1196 }
1197
1198 #[inline]
1208 #[must_use]
1209 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1210 pub fn refract(self, normal: Self, eta: f32) -> Self {
1211 glam_assert!(self.is_normalized());
1212 glam_assert!(normal.is_normalized());
1213 let n_dot_i = normal.dot(self);
1214 let k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i);
1215 if k >= 0.0 {
1216 eta * self - (eta * n_dot_i + math::sqrt(k)) * normal
1217 } else {
1218 Self::ZERO
1219 }
1220 }
1221
1222 #[cfg(feature = "f64")]
1224 #[inline]
1225 #[must_use]
1226 pub fn as_dvec4(self) -> crate::DVec4 {
1227 crate::DVec4::new(self.x as f64, self.y as f64, self.z as f64, self.w as f64)
1228 }
1229
1230 #[cfg(feature = "i8")]
1232 #[inline]
1233 #[must_use]
1234 pub fn as_i8vec4(self) -> crate::I8Vec4 {
1235 crate::I8Vec4::new(self.x as i8, self.y as i8, self.z as i8, self.w as i8)
1236 }
1237
1238 #[cfg(feature = "u8")]
1240 #[inline]
1241 #[must_use]
1242 pub fn as_u8vec4(self) -> crate::U8Vec4 {
1243 crate::U8Vec4::new(self.x as u8, self.y as u8, self.z as u8, self.w as u8)
1244 }
1245
1246 #[cfg(feature = "i16")]
1248 #[inline]
1249 #[must_use]
1250 pub fn as_i16vec4(self) -> crate::I16Vec4 {
1251 crate::I16Vec4::new(self.x as i16, self.y as i16, self.z as i16, self.w as i16)
1252 }
1253
1254 #[cfg(feature = "u16")]
1256 #[inline]
1257 #[must_use]
1258 pub fn as_u16vec4(self) -> crate::U16Vec4 {
1259 crate::U16Vec4::new(self.x as u16, self.y as u16, self.z as u16, self.w as u16)
1260 }
1261
1262 #[cfg(feature = "i32")]
1264 #[inline]
1265 #[must_use]
1266 pub fn as_ivec4(self) -> crate::IVec4 {
1267 crate::IVec4::new(self.x as i32, self.y as i32, self.z as i32, self.w as i32)
1268 }
1269
1270 #[cfg(feature = "u32")]
1272 #[inline]
1273 #[must_use]
1274 pub fn as_uvec4(self) -> crate::UVec4 {
1275 crate::UVec4::new(self.x as u32, self.y as u32, self.z as u32, self.w as u32)
1276 }
1277
1278 #[cfg(feature = "i64")]
1280 #[inline]
1281 #[must_use]
1282 pub fn as_i64vec4(self) -> crate::I64Vec4 {
1283 crate::I64Vec4::new(self.x as i64, self.y as i64, self.z as i64, self.w as i64)
1284 }
1285
1286 #[cfg(feature = "u64")]
1288 #[inline]
1289 #[must_use]
1290 pub fn as_u64vec4(self) -> crate::U64Vec4 {
1291 crate::U64Vec4::new(self.x as u64, self.y as u64, self.z as u64, self.w as u64)
1292 }
1293
1294 #[cfg(feature = "isize")]
1296 #[inline]
1297 #[must_use]
1298 pub fn as_isizevec4(self) -> crate::ISizeVec4 {
1299 crate::ISizeVec4::new(
1300 self.x as isize,
1301 self.y as isize,
1302 self.z as isize,
1303 self.w as isize,
1304 )
1305 }
1306
1307 #[cfg(feature = "usize")]
1309 #[inline]
1310 #[must_use]
1311 pub fn as_usizevec4(self) -> crate::USizeVec4 {
1312 crate::USizeVec4::new(
1313 self.x as usize,
1314 self.y as usize,
1315 self.z as usize,
1316 self.w as usize,
1317 )
1318 }
1319}
1320
1321impl Default for Vec4 {
1322 #[inline(always)]
1323 fn default() -> Self {
1324 Self::ZERO
1325 }
1326}
1327
1328impl PartialEq for Vec4 {
1329 #[inline]
1330 fn eq(&self, rhs: &Self) -> bool {
1331 self.cmpeq(*rhs).all()
1332 }
1333}
1334
1335impl Div for Vec4 {
1336 type Output = Self;
1337 #[inline]
1338 fn div(self, rhs: Self) -> Self {
1339 Self(unsafe { _mm_div_ps(self.0, rhs.0) })
1340 }
1341}
1342
1343impl Div<&Self> for Vec4 {
1344 type Output = Self;
1345 #[inline]
1346 fn div(self, rhs: &Self) -> Self {
1347 self.div(*rhs)
1348 }
1349}
1350
1351impl Div<&Vec4> for &Vec4 {
1352 type Output = Vec4;
1353 #[inline]
1354 fn div(self, rhs: &Vec4) -> Vec4 {
1355 (*self).div(*rhs)
1356 }
1357}
1358
1359impl Div<Vec4> for &Vec4 {
1360 type Output = Vec4;
1361 #[inline]
1362 fn div(self, rhs: Vec4) -> Vec4 {
1363 (*self).div(rhs)
1364 }
1365}
1366
1367impl DivAssign for Vec4 {
1368 #[inline]
1369 fn div_assign(&mut self, rhs: Self) {
1370 self.0 = unsafe { _mm_div_ps(self.0, rhs.0) };
1371 }
1372}
1373
1374impl DivAssign<&Self> for Vec4 {
1375 #[inline]
1376 fn div_assign(&mut self, rhs: &Self) {
1377 self.div_assign(*rhs);
1378 }
1379}
1380
1381impl Div<f32> for Vec4 {
1382 type Output = Self;
1383 #[inline]
1384 fn div(self, rhs: f32) -> Self {
1385 Self(unsafe { _mm_div_ps(self.0, _mm_set1_ps(rhs)) })
1386 }
1387}
1388
1389impl Div<&f32> for Vec4 {
1390 type Output = Self;
1391 #[inline]
1392 fn div(self, rhs: &f32) -> Self {
1393 self.div(*rhs)
1394 }
1395}
1396
1397impl Div<&f32> for &Vec4 {
1398 type Output = Vec4;
1399 #[inline]
1400 fn div(self, rhs: &f32) -> Vec4 {
1401 (*self).div(*rhs)
1402 }
1403}
1404
1405impl Div<f32> for &Vec4 {
1406 type Output = Vec4;
1407 #[inline]
1408 fn div(self, rhs: f32) -> Vec4 {
1409 (*self).div(rhs)
1410 }
1411}
1412
1413impl DivAssign<f32> for Vec4 {
1414 #[inline]
1415 fn div_assign(&mut self, rhs: f32) {
1416 self.0 = unsafe { _mm_div_ps(self.0, _mm_set1_ps(rhs)) };
1417 }
1418}
1419
1420impl DivAssign<&f32> for Vec4 {
1421 #[inline]
1422 fn div_assign(&mut self, rhs: &f32) {
1423 self.div_assign(*rhs);
1424 }
1425}
1426
1427impl Div<Vec4> for f32 {
1428 type Output = Vec4;
1429 #[inline]
1430 fn div(self, rhs: Vec4) -> Vec4 {
1431 Vec4(unsafe { _mm_div_ps(_mm_set1_ps(self), rhs.0) })
1432 }
1433}
1434
1435impl Div<&Vec4> for f32 {
1436 type Output = Vec4;
1437 #[inline]
1438 fn div(self, rhs: &Vec4) -> Vec4 {
1439 self.div(*rhs)
1440 }
1441}
1442
1443impl Div<&Vec4> for &f32 {
1444 type Output = Vec4;
1445 #[inline]
1446 fn div(self, rhs: &Vec4) -> Vec4 {
1447 (*self).div(*rhs)
1448 }
1449}
1450
1451impl Div<Vec4> for &f32 {
1452 type Output = Vec4;
1453 #[inline]
1454 fn div(self, rhs: Vec4) -> Vec4 {
1455 (*self).div(rhs)
1456 }
1457}
1458
1459impl Mul for Vec4 {
1460 type Output = Self;
1461 #[inline]
1462 fn mul(self, rhs: Self) -> Self {
1463 Self(unsafe { _mm_mul_ps(self.0, rhs.0) })
1464 }
1465}
1466
1467impl Mul<&Self> for Vec4 {
1468 type Output = Self;
1469 #[inline]
1470 fn mul(self, rhs: &Self) -> Self {
1471 self.mul(*rhs)
1472 }
1473}
1474
1475impl Mul<&Vec4> for &Vec4 {
1476 type Output = Vec4;
1477 #[inline]
1478 fn mul(self, rhs: &Vec4) -> Vec4 {
1479 (*self).mul(*rhs)
1480 }
1481}
1482
1483impl Mul<Vec4> for &Vec4 {
1484 type Output = Vec4;
1485 #[inline]
1486 fn mul(self, rhs: Vec4) -> Vec4 {
1487 (*self).mul(rhs)
1488 }
1489}
1490
1491impl MulAssign for Vec4 {
1492 #[inline]
1493 fn mul_assign(&mut self, rhs: Self) {
1494 self.0 = unsafe { _mm_mul_ps(self.0, rhs.0) };
1495 }
1496}
1497
1498impl MulAssign<&Self> for Vec4 {
1499 #[inline]
1500 fn mul_assign(&mut self, rhs: &Self) {
1501 self.mul_assign(*rhs);
1502 }
1503}
1504
1505impl Mul<f32> for Vec4 {
1506 type Output = Self;
1507 #[inline]
1508 fn mul(self, rhs: f32) -> Self {
1509 Self(unsafe { _mm_mul_ps(self.0, _mm_set1_ps(rhs)) })
1510 }
1511}
1512
1513impl Mul<&f32> for Vec4 {
1514 type Output = Self;
1515 #[inline]
1516 fn mul(self, rhs: &f32) -> Self {
1517 self.mul(*rhs)
1518 }
1519}
1520
1521impl Mul<&f32> for &Vec4 {
1522 type Output = Vec4;
1523 #[inline]
1524 fn mul(self, rhs: &f32) -> Vec4 {
1525 (*self).mul(*rhs)
1526 }
1527}
1528
1529impl Mul<f32> for &Vec4 {
1530 type Output = Vec4;
1531 #[inline]
1532 fn mul(self, rhs: f32) -> Vec4 {
1533 (*self).mul(rhs)
1534 }
1535}
1536
1537impl MulAssign<f32> for Vec4 {
1538 #[inline]
1539 fn mul_assign(&mut self, rhs: f32) {
1540 self.0 = unsafe { _mm_mul_ps(self.0, _mm_set1_ps(rhs)) };
1541 }
1542}
1543
1544impl MulAssign<&f32> for Vec4 {
1545 #[inline]
1546 fn mul_assign(&mut self, rhs: &f32) {
1547 self.mul_assign(*rhs);
1548 }
1549}
1550
1551impl Mul<Vec4> for f32 {
1552 type Output = Vec4;
1553 #[inline]
1554 fn mul(self, rhs: Vec4) -> Vec4 {
1555 Vec4(unsafe { _mm_mul_ps(_mm_set1_ps(self), rhs.0) })
1556 }
1557}
1558
1559impl Mul<&Vec4> for f32 {
1560 type Output = Vec4;
1561 #[inline]
1562 fn mul(self, rhs: &Vec4) -> Vec4 {
1563 self.mul(*rhs)
1564 }
1565}
1566
1567impl Mul<&Vec4> for &f32 {
1568 type Output = Vec4;
1569 #[inline]
1570 fn mul(self, rhs: &Vec4) -> Vec4 {
1571 (*self).mul(*rhs)
1572 }
1573}
1574
1575impl Mul<Vec4> for &f32 {
1576 type Output = Vec4;
1577 #[inline]
1578 fn mul(self, rhs: Vec4) -> Vec4 {
1579 (*self).mul(rhs)
1580 }
1581}
1582
1583impl Add for Vec4 {
1584 type Output = Self;
1585 #[inline]
1586 fn add(self, rhs: Self) -> Self {
1587 Self(unsafe { _mm_add_ps(self.0, rhs.0) })
1588 }
1589}
1590
1591impl Add<&Self> for Vec4 {
1592 type Output = Self;
1593 #[inline]
1594 fn add(self, rhs: &Self) -> Self {
1595 self.add(*rhs)
1596 }
1597}
1598
1599impl Add<&Vec4> for &Vec4 {
1600 type Output = Vec4;
1601 #[inline]
1602 fn add(self, rhs: &Vec4) -> Vec4 {
1603 (*self).add(*rhs)
1604 }
1605}
1606
1607impl Add<Vec4> for &Vec4 {
1608 type Output = Vec4;
1609 #[inline]
1610 fn add(self, rhs: Vec4) -> Vec4 {
1611 (*self).add(rhs)
1612 }
1613}
1614
1615impl AddAssign for Vec4 {
1616 #[inline]
1617 fn add_assign(&mut self, rhs: Self) {
1618 self.0 = unsafe { _mm_add_ps(self.0, rhs.0) };
1619 }
1620}
1621
1622impl AddAssign<&Self> for Vec4 {
1623 #[inline]
1624 fn add_assign(&mut self, rhs: &Self) {
1625 self.add_assign(*rhs);
1626 }
1627}
1628
1629impl Add<f32> for Vec4 {
1630 type Output = Self;
1631 #[inline]
1632 fn add(self, rhs: f32) -> Self {
1633 Self(unsafe { _mm_add_ps(self.0, _mm_set1_ps(rhs)) })
1634 }
1635}
1636
1637impl Add<&f32> for Vec4 {
1638 type Output = Self;
1639 #[inline]
1640 fn add(self, rhs: &f32) -> Self {
1641 self.add(*rhs)
1642 }
1643}
1644
1645impl Add<&f32> for &Vec4 {
1646 type Output = Vec4;
1647 #[inline]
1648 fn add(self, rhs: &f32) -> Vec4 {
1649 (*self).add(*rhs)
1650 }
1651}
1652
1653impl Add<f32> for &Vec4 {
1654 type Output = Vec4;
1655 #[inline]
1656 fn add(self, rhs: f32) -> Vec4 {
1657 (*self).add(rhs)
1658 }
1659}
1660
1661impl AddAssign<f32> for Vec4 {
1662 #[inline]
1663 fn add_assign(&mut self, rhs: f32) {
1664 self.0 = unsafe { _mm_add_ps(self.0, _mm_set1_ps(rhs)) };
1665 }
1666}
1667
1668impl AddAssign<&f32> for Vec4 {
1669 #[inline]
1670 fn add_assign(&mut self, rhs: &f32) {
1671 self.add_assign(*rhs);
1672 }
1673}
1674
1675impl Add<Vec4> for f32 {
1676 type Output = Vec4;
1677 #[inline]
1678 fn add(self, rhs: Vec4) -> Vec4 {
1679 Vec4(unsafe { _mm_add_ps(_mm_set1_ps(self), rhs.0) })
1680 }
1681}
1682
1683impl Add<&Vec4> for f32 {
1684 type Output = Vec4;
1685 #[inline]
1686 fn add(self, rhs: &Vec4) -> Vec4 {
1687 self.add(*rhs)
1688 }
1689}
1690
1691impl Add<&Vec4> for &f32 {
1692 type Output = Vec4;
1693 #[inline]
1694 fn add(self, rhs: &Vec4) -> Vec4 {
1695 (*self).add(*rhs)
1696 }
1697}
1698
1699impl Add<Vec4> for &f32 {
1700 type Output = Vec4;
1701 #[inline]
1702 fn add(self, rhs: Vec4) -> Vec4 {
1703 (*self).add(rhs)
1704 }
1705}
1706
1707impl Sub for Vec4 {
1708 type Output = Self;
1709 #[inline]
1710 fn sub(self, rhs: Self) -> Self {
1711 Self(unsafe { _mm_sub_ps(self.0, rhs.0) })
1712 }
1713}
1714
1715impl Sub<&Self> for Vec4 {
1716 type Output = Self;
1717 #[inline]
1718 fn sub(self, rhs: &Self) -> Self {
1719 self.sub(*rhs)
1720 }
1721}
1722
1723impl Sub<&Vec4> for &Vec4 {
1724 type Output = Vec4;
1725 #[inline]
1726 fn sub(self, rhs: &Vec4) -> Vec4 {
1727 (*self).sub(*rhs)
1728 }
1729}
1730
1731impl Sub<Vec4> for &Vec4 {
1732 type Output = Vec4;
1733 #[inline]
1734 fn sub(self, rhs: Vec4) -> Vec4 {
1735 (*self).sub(rhs)
1736 }
1737}
1738
1739impl SubAssign for Vec4 {
1740 #[inline]
1741 fn sub_assign(&mut self, rhs: Self) {
1742 self.0 = unsafe { _mm_sub_ps(self.0, rhs.0) };
1743 }
1744}
1745
1746impl SubAssign<&Self> for Vec4 {
1747 #[inline]
1748 fn sub_assign(&mut self, rhs: &Self) {
1749 self.sub_assign(*rhs);
1750 }
1751}
1752
1753impl Sub<f32> for Vec4 {
1754 type Output = Self;
1755 #[inline]
1756 fn sub(self, rhs: f32) -> Self {
1757 Self(unsafe { _mm_sub_ps(self.0, _mm_set1_ps(rhs)) })
1758 }
1759}
1760
1761impl Sub<&f32> for Vec4 {
1762 type Output = Self;
1763 #[inline]
1764 fn sub(self, rhs: &f32) -> Self {
1765 self.sub(*rhs)
1766 }
1767}
1768
1769impl Sub<&f32> for &Vec4 {
1770 type Output = Vec4;
1771 #[inline]
1772 fn sub(self, rhs: &f32) -> Vec4 {
1773 (*self).sub(*rhs)
1774 }
1775}
1776
1777impl Sub<f32> for &Vec4 {
1778 type Output = Vec4;
1779 #[inline]
1780 fn sub(self, rhs: f32) -> Vec4 {
1781 (*self).sub(rhs)
1782 }
1783}
1784
1785impl SubAssign<f32> for Vec4 {
1786 #[inline]
1787 fn sub_assign(&mut self, rhs: f32) {
1788 self.0 = unsafe { _mm_sub_ps(self.0, _mm_set1_ps(rhs)) };
1789 }
1790}
1791
1792impl SubAssign<&f32> for Vec4 {
1793 #[inline]
1794 fn sub_assign(&mut self, rhs: &f32) {
1795 self.sub_assign(*rhs);
1796 }
1797}
1798
1799impl Sub<Vec4> for f32 {
1800 type Output = Vec4;
1801 #[inline]
1802 fn sub(self, rhs: Vec4) -> Vec4 {
1803 Vec4(unsafe { _mm_sub_ps(_mm_set1_ps(self), rhs.0) })
1804 }
1805}
1806
1807impl Sub<&Vec4> for f32 {
1808 type Output = Vec4;
1809 #[inline]
1810 fn sub(self, rhs: &Vec4) -> Vec4 {
1811 self.sub(*rhs)
1812 }
1813}
1814
1815impl Sub<&Vec4> for &f32 {
1816 type Output = Vec4;
1817 #[inline]
1818 fn sub(self, rhs: &Vec4) -> Vec4 {
1819 (*self).sub(*rhs)
1820 }
1821}
1822
1823impl Sub<Vec4> for &f32 {
1824 type Output = Vec4;
1825 #[inline]
1826 fn sub(self, rhs: Vec4) -> Vec4 {
1827 (*self).sub(rhs)
1828 }
1829}
1830
1831impl Rem for Vec4 {
1832 type Output = Self;
1833 #[inline]
1834 fn rem(self, rhs: Self) -> Self {
1835 unsafe {
1836 let n = m128_floor(_mm_div_ps(self.0, rhs.0));
1837 Self(_mm_sub_ps(self.0, _mm_mul_ps(n, rhs.0)))
1838 }
1839 }
1840}
1841
1842impl Rem<&Self> for Vec4 {
1843 type Output = Self;
1844 #[inline]
1845 fn rem(self, rhs: &Self) -> Self {
1846 self.rem(*rhs)
1847 }
1848}
1849
1850impl Rem<&Vec4> for &Vec4 {
1851 type Output = Vec4;
1852 #[inline]
1853 fn rem(self, rhs: &Vec4) -> Vec4 {
1854 (*self).rem(*rhs)
1855 }
1856}
1857
1858impl Rem<Vec4> for &Vec4 {
1859 type Output = Vec4;
1860 #[inline]
1861 fn rem(self, rhs: Vec4) -> Vec4 {
1862 (*self).rem(rhs)
1863 }
1864}
1865
1866impl RemAssign for Vec4 {
1867 #[inline]
1868 fn rem_assign(&mut self, rhs: Self) {
1869 *self = self.rem(rhs);
1870 }
1871}
1872
1873impl RemAssign<&Self> for Vec4 {
1874 #[inline]
1875 fn rem_assign(&mut self, rhs: &Self) {
1876 self.rem_assign(*rhs);
1877 }
1878}
1879
1880impl Rem<f32> for Vec4 {
1881 type Output = Self;
1882 #[inline]
1883 fn rem(self, rhs: f32) -> Self {
1884 self.rem(Self::splat(rhs))
1885 }
1886}
1887
1888impl Rem<&f32> for Vec4 {
1889 type Output = Self;
1890 #[inline]
1891 fn rem(self, rhs: &f32) -> Self {
1892 self.rem(*rhs)
1893 }
1894}
1895
1896impl Rem<&f32> for &Vec4 {
1897 type Output = Vec4;
1898 #[inline]
1899 fn rem(self, rhs: &f32) -> Vec4 {
1900 (*self).rem(*rhs)
1901 }
1902}
1903
1904impl Rem<f32> for &Vec4 {
1905 type Output = Vec4;
1906 #[inline]
1907 fn rem(self, rhs: f32) -> Vec4 {
1908 (*self).rem(rhs)
1909 }
1910}
1911
1912impl RemAssign<f32> for Vec4 {
1913 #[inline]
1914 fn rem_assign(&mut self, rhs: f32) {
1915 *self = self.rem(Self::splat(rhs));
1916 }
1917}
1918
1919impl RemAssign<&f32> for Vec4 {
1920 #[inline]
1921 fn rem_assign(&mut self, rhs: &f32) {
1922 self.rem_assign(*rhs);
1923 }
1924}
1925
1926impl Rem<Vec4> for f32 {
1927 type Output = Vec4;
1928 #[inline]
1929 fn rem(self, rhs: Vec4) -> Vec4 {
1930 Vec4::splat(self).rem(rhs)
1931 }
1932}
1933
1934impl Rem<&Vec4> for f32 {
1935 type Output = Vec4;
1936 #[inline]
1937 fn rem(self, rhs: &Vec4) -> Vec4 {
1938 self.rem(*rhs)
1939 }
1940}
1941
1942impl Rem<&Vec4> for &f32 {
1943 type Output = Vec4;
1944 #[inline]
1945 fn rem(self, rhs: &Vec4) -> Vec4 {
1946 (*self).rem(*rhs)
1947 }
1948}
1949
1950impl Rem<Vec4> for &f32 {
1951 type Output = Vec4;
1952 #[inline]
1953 fn rem(self, rhs: Vec4) -> Vec4 {
1954 (*self).rem(rhs)
1955 }
1956}
1957
1958impl AsRef<[f32; 4]> for Vec4 {
1959 #[inline]
1960 fn as_ref(&self) -> &[f32; 4] {
1961 unsafe { &*(self as *const Self as *const [f32; 4]) }
1962 }
1963}
1964
1965impl AsMut<[f32; 4]> for Vec4 {
1966 #[inline]
1967 fn as_mut(&mut self) -> &mut [f32; 4] {
1968 unsafe { &mut *(self as *mut Self as *mut [f32; 4]) }
1969 }
1970}
1971
1972impl Sum for Vec4 {
1973 #[inline]
1974 fn sum<I>(iter: I) -> Self
1975 where
1976 I: Iterator<Item = Self>,
1977 {
1978 iter.fold(Self::ZERO, Self::add)
1979 }
1980}
1981
1982impl<'a> Sum<&'a Self> for Vec4 {
1983 #[inline]
1984 fn sum<I>(iter: I) -> Self
1985 where
1986 I: Iterator<Item = &'a Self>,
1987 {
1988 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1989 }
1990}
1991
1992impl Product for Vec4 {
1993 #[inline]
1994 fn product<I>(iter: I) -> Self
1995 where
1996 I: Iterator<Item = Self>,
1997 {
1998 iter.fold(Self::ONE, Self::mul)
1999 }
2000}
2001
2002impl<'a> Product<&'a Self> for Vec4 {
2003 #[inline]
2004 fn product<I>(iter: I) -> Self
2005 where
2006 I: Iterator<Item = &'a Self>,
2007 {
2008 iter.fold(Self::ONE, |a, &b| Self::mul(a, b))
2009 }
2010}
2011
2012impl Neg for Vec4 {
2013 type Output = Self;
2014 #[inline]
2015 fn neg(self) -> Self {
2016 Self(unsafe { _mm_xor_ps(_mm_set1_ps(-0.0), self.0) })
2017 }
2018}
2019
2020impl Neg for &Vec4 {
2021 type Output = Vec4;
2022 #[inline]
2023 fn neg(self) -> Vec4 {
2024 (*self).neg()
2025 }
2026}
2027
2028impl Index<usize> for Vec4 {
2029 type Output = f32;
2030 #[inline]
2031 #[track_caller]
2032 fn index(&self, index: usize) -> &Self::Output {
2033 match index {
2034 0 => &self.x,
2035 1 => &self.y,
2036 2 => &self.z,
2037 3 => &self.w,
2038 _ => panic!("index out of bounds"),
2039 }
2040 }
2041}
2042
2043impl IndexMut<usize> for Vec4 {
2044 #[inline]
2045 #[track_caller]
2046 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
2047 match index {
2048 0 => &mut self.x,
2049 1 => &mut self.y,
2050 2 => &mut self.z,
2051 3 => &mut self.w,
2052 _ => panic!("index out of bounds"),
2053 }
2054 }
2055}
2056
2057impl fmt::Display for Vec4 {
2058 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2059 if let Some(p) = f.precision() {
2060 write!(
2061 f,
2062 "[{:.*}, {:.*}, {:.*}, {:.*}]",
2063 p, self.x, p, self.y, p, self.z, p, self.w
2064 )
2065 } else {
2066 write!(f, "[{}, {}, {}, {}]", self.x, self.y, self.z, self.w)
2067 }
2068 }
2069}
2070
2071impl fmt::Debug for Vec4 {
2072 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
2073 fmt.debug_tuple(stringify!(Vec4))
2074 .field(&self.x)
2075 .field(&self.y)
2076 .field(&self.z)
2077 .field(&self.w)
2078 .finish()
2079 }
2080}
2081
2082impl From<Vec4> for __m128 {
2083 #[inline(always)]
2084 fn from(t: Vec4) -> Self {
2085 t.0
2086 }
2087}
2088
2089impl From<__m128> for Vec4 {
2090 #[inline(always)]
2091 fn from(t: __m128) -> Self {
2092 Self(t)
2093 }
2094}
2095
2096impl From<[f32; 4]> for Vec4 {
2097 #[inline]
2098 fn from(a: [f32; 4]) -> Self {
2099 Self(unsafe { _mm_loadu_ps(a.as_ptr()) })
2100 }
2101}
2102
2103impl From<Vec4> for [f32; 4] {
2104 #[inline]
2105 fn from(v: Vec4) -> Self {
2106 use crate::Align16;
2107 use core::mem::MaybeUninit;
2108 let mut out: MaybeUninit<Align16<Self>> = MaybeUninit::uninit();
2109 unsafe {
2110 _mm_store_ps(out.as_mut_ptr().cast(), v.0);
2111 out.assume_init().0
2112 }
2113 }
2114}
2115
2116impl From<(f32, f32, f32, f32)> for Vec4 {
2117 #[inline]
2118 fn from(t: (f32, f32, f32, f32)) -> Self {
2119 Self::new(t.0, t.1, t.2, t.3)
2120 }
2121}
2122
2123impl From<Vec4> for (f32, f32, f32, f32) {
2124 #[inline]
2125 fn from(v: Vec4) -> Self {
2126 (v.x, v.y, v.z, v.w)
2127 }
2128}
2129
2130impl From<(Vec3A, f32)> for Vec4 {
2131 #[inline]
2132 fn from((v, w): (Vec3A, f32)) -> Self {
2133 v.extend(w)
2134 }
2135}
2136
2137impl From<(f32, Vec3A)> for Vec4 {
2138 #[inline]
2139 fn from((x, v): (f32, Vec3A)) -> Self {
2140 Self::new(x, v.x, v.y, v.z)
2141 }
2142}
2143
2144impl From<(Vec3, f32)> for Vec4 {
2145 #[inline]
2146 fn from((v, w): (Vec3, f32)) -> Self {
2147 Self::new(v.x, v.y, v.z, w)
2148 }
2149}
2150
2151impl From<(f32, Vec3)> for Vec4 {
2152 #[inline]
2153 fn from((x, v): (f32, Vec3)) -> Self {
2154 Self::new(x, v.x, v.y, v.z)
2155 }
2156}
2157
2158impl From<(Vec2, f32, f32)> for Vec4 {
2159 #[inline]
2160 fn from((v, z, w): (Vec2, f32, f32)) -> Self {
2161 Self::new(v.x, v.y, z, w)
2162 }
2163}
2164
2165impl From<(Vec2, Vec2)> for Vec4 {
2166 #[inline]
2167 fn from((v, u): (Vec2, Vec2)) -> Self {
2168 Self::new(v.x, v.y, u.x, u.y)
2169 }
2170}
2171
2172impl Deref for Vec4 {
2173 type Target = crate::deref::Vec4<f32>;
2174 #[inline]
2175 fn deref(&self) -> &Self::Target {
2176 unsafe { &*(self as *const Self).cast() }
2177 }
2178}
2179
2180impl DerefMut for Vec4 {
2181 #[inline]
2182 fn deref_mut(&mut self) -> &mut Self::Target {
2183 unsafe { &mut *(self as *mut Self).cast() }
2184 }
2185}
2186
2187impl From<BVec4> for Vec4 {
2188 #[inline]
2189 fn from(v: BVec4) -> Self {
2190 Self::new(
2191 f32::from(v.x),
2192 f32::from(v.y),
2193 f32::from(v.z),
2194 f32::from(v.w),
2195 )
2196 }
2197}
2198
2199#[cfg(not(feature = "scalar-math"))]
2200impl From<BVec4A> for Vec4 {
2201 #[inline]
2202 fn from(v: BVec4A) -> Self {
2203 let bool_array: [bool; 4] = v.into();
2204 Self::new(
2205 f32::from(bool_array[0]),
2206 f32::from(bool_array[1]),
2207 f32::from(bool_array[2]),
2208 f32::from(bool_array[3]),
2209 )
2210 }
2211}