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