1use crate::{f32::math, sse2::*, BVec3, BVec3A, FloatExt, Quat, Vec2, Vec3, Vec4};
4
5use core::fmt;
6use core::iter::{Product, Sum};
7use core::{f32, 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")]
15use zerocopy_derive::*;
16
17#[repr(C)]
18union UnionCast {
19 a: [f32; 4],
20 v: Vec3A,
21}
22
23#[inline(always)]
25#[must_use]
26pub const fn vec3a(x: f32, y: f32, z: f32) -> Vec3A {
27 Vec3A::new(x, y, z)
28}
29
30#[derive(Clone, Copy)]
40#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
41#[cfg_attr(
42 feature = "zerocopy",
43 derive(FromBytes, Immutable, IntoBytes, KnownLayout)
44)]
45#[repr(transparent)]
46pub struct Vec3A(pub(crate) __m128);
47
48impl Vec3A {
49 pub const ZERO: Self = Self::splat(0.0);
51
52 pub const ONE: Self = Self::splat(1.0);
54
55 pub const NEG_ONE: Self = Self::splat(-1.0);
57
58 pub const MIN: Self = Self::splat(f32::MIN);
60
61 pub const MAX: Self = Self::splat(f32::MAX);
63
64 pub const NAN: Self = Self::splat(f32::NAN);
66
67 pub const INFINITY: Self = Self::splat(f32::INFINITY);
69
70 pub const NEG_INFINITY: Self = Self::splat(f32::NEG_INFINITY);
72
73 pub const X: Self = Self::new(1.0, 0.0, 0.0);
75
76 pub const Y: Self = Self::new(0.0, 1.0, 0.0);
78
79 pub const Z: Self = Self::new(0.0, 0.0, 1.0);
81
82 pub const NEG_X: Self = Self::new(-1.0, 0.0, 0.0);
84
85 pub const NEG_Y: Self = Self::new(0.0, -1.0, 0.0);
87
88 pub const NEG_Z: Self = Self::new(0.0, 0.0, -1.0);
90
91 pub const AXES: [Self; 3] = [Self::X, Self::Y, Self::Z];
93
94 pub const USES_CORE_SIMD: bool = false;
96 pub const USES_NEON: bool = false;
98 pub const USES_SCALAR_MATH: bool = false;
100 pub const USES_SSE2: bool = true;
102 pub const USES_WASM32_SIMD: bool = false;
104
105 #[inline(always)]
107 #[must_use]
108 pub const fn new(x: f32, y: f32, z: f32) -> Self {
109 unsafe { UnionCast { a: [x, y, z, z] }.v }
110 }
111
112 #[inline]
114 #[must_use]
115 pub const fn splat(v: f32) -> Self {
116 unsafe { UnionCast { a: [v; 4] }.v }
117 }
118
119 #[inline]
121 #[must_use]
122 pub fn map<F>(self, f: F) -> Self
123 where
124 F: Fn(f32) -> f32,
125 {
126 Self::new(f(self.x), f(self.y), f(self.z))
127 }
128
129 #[inline]
135 #[must_use]
136 pub fn select(mask: BVec3A, if_true: Self, if_false: Self) -> Self {
137 Self(unsafe {
138 _mm_or_ps(
139 _mm_andnot_ps(mask.0, if_false.0),
140 _mm_and_ps(if_true.0, mask.0),
141 )
142 })
143 }
144
145 #[inline]
147 #[must_use]
148 pub const fn from_array(a: [f32; 3]) -> Self {
149 Self::new(a[0], a[1], a[2])
150 }
151
152 #[inline]
154 #[must_use]
155 pub const fn to_array(&self) -> [f32; 3] {
156 unsafe { *(self as *const Self as *const [f32; 3]) }
157 }
158
159 #[inline]
165 #[must_use]
166 pub const fn from_slice(slice: &[f32]) -> Self {
167 assert!(slice.len() >= 3);
168 Self::new(slice[0], slice[1], slice[2])
169 }
170
171 #[inline]
177 pub fn write_to_slice(self, slice: &mut [f32]) {
178 slice[..3].copy_from_slice(&self.to_array());
179 }
180
181 #[inline]
185 #[must_use]
186 pub fn from_vec4(v: Vec4) -> Self {
187 Self(v.0)
188 }
189
190 #[inline]
192 #[must_use]
193 pub fn extend(self, w: f32) -> Vec4 {
194 Vec4::new(self.x, self.y, self.z, w)
195 }
196
197 #[inline]
201 #[must_use]
202 pub fn truncate(self) -> Vec2 {
203 use crate::swizzles::Vec3Swizzles;
204 self.xy()
205 }
206
207 #[inline]
213 #[must_use]
214 pub fn from_homogeneous(v: Vec4) -> Self {
215 glam_assert!(v.w != 0.0);
216 Self::from_vec4(v) / v.w
217 }
218
219 #[inline]
221 #[must_use]
222 pub fn to_homogeneous(self) -> Vec4 {
223 self.extend(1.0)
224 }
225
226 #[inline]
228 #[must_use]
229 pub fn to_vec3(self) -> Vec3 {
230 Vec3::from(self)
231 }
232
233 #[inline]
235 #[must_use]
236 pub fn with_x(mut self, x: f32) -> Self {
237 self.x = x;
238 self
239 }
240
241 #[inline]
243 #[must_use]
244 pub fn with_y(mut self, y: f32) -> Self {
245 self.y = y;
246 self
247 }
248
249 #[inline]
251 #[must_use]
252 pub fn with_z(mut self, z: f32) -> Self {
253 self.z = z;
254 self
255 }
256
257 #[inline]
259 #[must_use]
260 pub fn dot(self, rhs: Self) -> f32 {
261 unsafe { dot3(self.0, rhs.0) }
262 }
263
264 #[inline]
266 #[must_use]
267 pub fn dot_into_vec(self, rhs: Self) -> Self {
268 Self(unsafe { dot3_into_m128(self.0, rhs.0) })
269 }
270
271 #[inline]
273 #[must_use]
274 pub fn cross(self, rhs: Self) -> Self {
275 unsafe {
276 let lhszxy = _mm_shuffle_ps(self.0, self.0, 0b01_01_00_10);
282 let rhszxy = _mm_shuffle_ps(rhs.0, rhs.0, 0b01_01_00_10);
283 let lhszxy_rhs = _mm_mul_ps(lhszxy, rhs.0);
284 let rhszxy_lhs = _mm_mul_ps(rhszxy, self.0);
285 let sub = _mm_sub_ps(lhszxy_rhs, rhszxy_lhs);
286 Self(_mm_shuffle_ps(sub, sub, 0b01_01_00_10))
287 }
288 }
289
290 #[inline]
297 #[must_use]
298 pub fn min(self, rhs: Self) -> Self {
299 Self(unsafe { _mm_min_ps(self.0, rhs.0) })
300 }
301
302 #[inline]
309 #[must_use]
310 pub fn max(self, rhs: Self) -> Self {
311 Self(unsafe { _mm_max_ps(self.0, rhs.0) })
312 }
313
314 #[inline]
325 #[must_use]
326 pub fn clamp(self, min: Self, max: Self) -> Self {
327 glam_assert!(min.cmple(max).all(), "clamp: expected min <= max");
328 self.max(min).min(max)
329 }
330
331 #[inline]
338 #[must_use]
339 pub fn min_element(self) -> f32 {
340 unsafe {
341 let v = self.0;
342 let v = _mm_min_ps(v, _mm_shuffle_ps(v, v, 0b01_01_10_10));
343 let v = _mm_min_ps(v, _mm_shuffle_ps(v, v, 0b00_00_00_01));
344 _mm_cvtss_f32(v)
345 }
346 }
347
348 #[inline]
355 #[must_use]
356 pub fn max_element(self) -> f32 {
357 unsafe {
358 let v = self.0;
359 let v = _mm_max_ps(v, _mm_shuffle_ps(v, v, 0b00_00_10_10));
360 let v = _mm_max_ps(v, _mm_shuffle_ps(v, v, 0b00_00_00_01));
361 _mm_cvtss_f32(v)
362 }
363 }
364
365 #[doc(alias = "argmin")]
367 #[inline]
368 #[must_use]
369 pub fn min_position(self) -> usize {
370 let mut min = self.x;
371 let mut index = 0;
372 if self.y < min {
373 min = self.y;
374 index = 1;
375 }
376 if self.z < min {
377 index = 2;
378 }
379 index
380 }
381
382 #[doc(alias = "argmax")]
384 #[inline]
385 #[must_use]
386 pub fn max_position(self) -> usize {
387 let mut max = self.x;
388 let mut index = 0;
389 if self.y > max {
390 max = self.y;
391 index = 1;
392 }
393 if self.z > max {
394 index = 2;
395 }
396 index
397 }
398
399 #[inline]
403 #[must_use]
404 pub fn element_sum(self) -> f32 {
405 unsafe {
406 let v = self.0;
407 let v = _mm_add_ps(v, _mm_shuffle_ps(v, Self::ZERO.0, 0b00_11_00_01));
408 let v = _mm_add_ps(v, _mm_shuffle_ps(v, v, 0b00_00_00_10));
409 _mm_cvtss_f32(v)
410 }
411 }
412
413 #[inline]
417 #[must_use]
418 pub fn element_product(self) -> f32 {
419 unsafe {
420 let v = self.0;
421 let v = _mm_mul_ps(v, _mm_shuffle_ps(v, Self::ONE.0, 0b00_11_00_01));
422 let v = _mm_mul_ps(v, _mm_shuffle_ps(v, v, 0b00_00_00_10));
423 _mm_cvtss_f32(v)
424 }
425 }
426
427 #[inline]
433 #[must_use]
434 pub fn cmpeq(self, rhs: Self) -> BVec3A {
435 BVec3A(unsafe { _mm_cmpeq_ps(self.0, rhs.0) })
436 }
437
438 #[inline]
444 #[must_use]
445 pub fn cmpne(self, rhs: Self) -> BVec3A {
446 BVec3A(unsafe { _mm_cmpneq_ps(self.0, rhs.0) })
447 }
448
449 #[inline]
455 #[must_use]
456 pub fn cmpge(self, rhs: Self) -> BVec3A {
457 BVec3A(unsafe { _mm_cmpge_ps(self.0, rhs.0) })
458 }
459
460 #[inline]
466 #[must_use]
467 pub fn cmpgt(self, rhs: Self) -> BVec3A {
468 BVec3A(unsafe { _mm_cmpgt_ps(self.0, rhs.0) })
469 }
470
471 #[inline]
477 #[must_use]
478 pub fn cmple(self, rhs: Self) -> BVec3A {
479 BVec3A(unsafe { _mm_cmple_ps(self.0, rhs.0) })
480 }
481
482 #[inline]
488 #[must_use]
489 pub fn cmplt(self, rhs: Self) -> BVec3A {
490 BVec3A(unsafe { _mm_cmplt_ps(self.0, rhs.0) })
491 }
492
493 #[inline]
495 #[must_use]
496 pub fn abs(self) -> Self {
497 Self(unsafe { crate::sse2::m128_abs(self.0) })
498 }
499
500 #[inline]
506 #[must_use]
507 pub fn signum(self) -> Self {
508 let result = Self(unsafe { _mm_or_ps(_mm_and_ps(self.0, Self::NEG_ONE.0), Self::ONE.0) });
509 let mask = self.is_nan_mask();
510 Self::select(mask, self, result)
511 }
512
513 #[inline]
515 #[must_use]
516 pub fn copysign(self, rhs: Self) -> Self {
517 let mask = Self::splat(-0.0);
518 Self(unsafe { _mm_or_ps(_mm_and_ps(rhs.0, mask.0), _mm_andnot_ps(mask.0, self.0)) })
519 }
520
521 #[inline]
529 #[must_use]
530 pub fn is_negative_bitmask(self) -> u32 {
531 unsafe { (_mm_movemask_ps(self.0) as u32) & 0x7 }
532 }
533
534 #[inline]
537 #[must_use]
538 pub fn is_finite(self) -> bool {
539 self.is_finite_mask().all()
540 }
541
542 #[inline]
546 #[must_use]
547 pub fn is_finite_mask(self) -> BVec3A {
548 BVec3A(unsafe { _mm_cmplt_ps(crate::sse2::m128_abs(self.0), Self::INFINITY.0) })
549 }
550
551 #[inline]
553 #[must_use]
554 pub fn is_nan(self) -> bool {
555 self.is_nan_mask().any()
556 }
557
558 #[inline]
562 #[must_use]
563 pub fn is_nan_mask(self) -> BVec3A {
564 BVec3A(unsafe { _mm_cmpunord_ps(self.0, self.0) })
565 }
566
567 #[doc(alias = "magnitude")]
569 #[inline]
570 #[must_use]
571 pub fn length(self) -> f32 {
572 unsafe {
573 let dot = dot3_in_x(self.0, self.0);
574 _mm_cvtss_f32(_mm_sqrt_ps(dot))
575 }
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 = dot3_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 )
623 }
624
625 #[inline]
629 #[must_use]
630 pub fn rem_euclid(self, rhs: Self) -> Self {
631 Self::new(
632 math::rem_euclid(self.x, rhs.x),
633 math::rem_euclid(self.y, rhs.y),
634 math::rem_euclid(self.z, rhs.z),
635 )
636 }
637
638 #[inline]
648 #[must_use]
649 pub fn normalize(self) -> Self {
650 unsafe {
651 let length = _mm_sqrt_ps(dot3_into_m128(self.0, self.0));
652 #[allow(clippy::let_and_return)]
653 let normalized = Self(_mm_div_ps(self.0, length));
654 glam_assert!(normalized.is_finite());
655 normalized
656 }
657 }
658
659 #[inline]
666 #[must_use]
667 pub fn try_normalize(self) -> Option<Self> {
668 let rcp = self.length_recip();
669 if rcp.is_finite() && rcp > 0.0 {
670 Some(self * rcp)
671 } else {
672 None
673 }
674 }
675
676 #[inline]
684 #[must_use]
685 pub fn normalize_or(self, fallback: Self) -> Self {
686 let rcp = self.length_recip();
687 if rcp.is_finite() && rcp > 0.0 {
688 self * rcp
689 } else {
690 fallback
691 }
692 }
693
694 #[inline]
701 #[must_use]
702 pub fn normalize_or_zero(self) -> Self {
703 self.normalize_or(Self::ZERO)
704 }
705
706 #[inline]
710 #[must_use]
711 pub fn normalize_and_length(self) -> (Self, f32) {
712 let length = self.length();
713 let rcp = 1.0 / length;
714 if rcp.is_finite() && rcp > 0.0 {
715 (self * rcp, length)
716 } else {
717 (Self::X, 0.0)
718 }
719 }
720
721 #[inline]
725 #[must_use]
726 pub fn is_normalized(self) -> bool {
727 math::abs(self.length_squared() - 1.0) <= 2e-4
728 }
729
730 #[inline]
738 #[must_use]
739 pub fn project_onto(self, rhs: Self) -> Self {
740 let other_len_sq_rcp = rhs.dot(rhs).recip();
741 glam_assert!(other_len_sq_rcp.is_finite());
742 rhs * self.dot(rhs) * other_len_sq_rcp
743 }
744
745 #[doc(alias("plane"))]
756 #[inline]
757 #[must_use]
758 pub fn reject_from(self, rhs: Self) -> Self {
759 self - self.project_onto(rhs)
760 }
761
762 #[inline]
770 #[must_use]
771 pub fn project_onto_normalized(self, rhs: Self) -> Self {
772 glam_assert!(rhs.is_normalized());
773 rhs * self.dot(rhs)
774 }
775
776 #[doc(alias("plane"))]
787 #[inline]
788 #[must_use]
789 pub fn reject_from_normalized(self, rhs: Self) -> Self {
790 self - self.project_onto_normalized(rhs)
791 }
792
793 #[inline]
796 #[must_use]
797 pub fn round(self) -> Self {
798 Self(unsafe { m128_round(self.0) })
799 }
800
801 #[inline]
804 #[must_use]
805 pub fn floor(self) -> Self {
806 Self(unsafe { m128_floor(self.0) })
807 }
808
809 #[inline]
812 #[must_use]
813 pub fn ceil(self) -> Self {
814 Self(unsafe { m128_ceil(self.0) })
815 }
816
817 #[inline]
820 #[must_use]
821 pub fn trunc(self) -> Self {
822 Self(unsafe { m128_trunc(self.0) })
823 }
824
825 #[inline]
832 #[must_use]
833 pub fn fract(self) -> Self {
834 self - self.trunc()
835 }
836
837 #[inline]
844 #[must_use]
845 pub fn fract_gl(self) -> Self {
846 self - self.floor()
847 }
848
849 #[inline]
852 #[must_use]
853 pub fn exp(self) -> Self {
854 Self::new(math::exp(self.x), math::exp(self.y), math::exp(self.z))
855 }
856
857 #[inline]
859 #[must_use]
860 pub fn exp2(self) -> Self {
861 Self::new(math::exp2(self.x), math::exp2(self.y), math::exp2(self.z))
862 }
863
864 #[inline]
867 #[must_use]
868 pub fn ln(self) -> Self {
869 Self::new(math::ln(self.x), math::ln(self.y), math::ln(self.z))
870 }
871
872 #[inline]
875 #[must_use]
876 pub fn log2(self) -> Self {
877 Self::new(math::log2(self.x), math::log2(self.y), math::log2(self.z))
878 }
879
880 #[inline]
882 #[must_use]
883 pub fn powf(self, n: f32) -> Self {
884 Self::new(
885 math::powf(self.x, n),
886 math::powf(self.y, n),
887 math::powf(self.z, n),
888 )
889 }
890
891 #[inline]
893 #[must_use]
894 pub fn recip(self) -> Self {
895 Self(unsafe { _mm_div_ps(Self::ONE.0, self.0) })
896 }
897
898 #[doc(alias = "mix")]
904 #[inline]
905 #[must_use]
906 pub fn lerp(self, rhs: Self, s: f32) -> Self {
907 self * (1.0 - s) + rhs * s
908 }
909
910 #[inline]
915 #[must_use]
916 pub fn move_towards(&self, rhs: Self, d: f32) -> Self {
917 let a = rhs - *self;
918 let len = a.length();
919 if len <= d || len <= 1e-4 {
920 return rhs;
921 }
922 *self + a / len * d
923 }
924
925 #[inline]
931 pub fn midpoint(self, rhs: Self) -> Self {
932 (self + rhs) * 0.5
933 }
934
935 #[inline]
945 #[must_use]
946 pub fn abs_diff_eq(self, rhs: Self, max_abs_diff: f32) -> bool {
947 self.sub(rhs).abs().cmple(Self::splat(max_abs_diff)).all()
948 }
949
950 #[inline]
956 #[must_use]
957 pub fn clamp_length(self, min: f32, max: f32) -> Self {
958 glam_assert!(0.0 <= min);
959 glam_assert!(min <= max);
960 let length_sq = self.length_squared();
961 if length_sq < min * min {
962 min * (self / math::sqrt(length_sq))
963 } else if length_sq > max * max {
964 max * (self / math::sqrt(length_sq))
965 } else {
966 self
967 }
968 }
969
970 #[inline]
976 #[must_use]
977 pub fn clamp_length_max(self, max: f32) -> Self {
978 glam_assert!(0.0 <= max);
979 let length_sq = self.length_squared();
980 if length_sq > max * max {
981 max * (self / math::sqrt(length_sq))
982 } else {
983 self
984 }
985 }
986
987 #[inline]
993 #[must_use]
994 pub fn clamp_length_min(self, min: f32) -> Self {
995 glam_assert!(0.0 <= min);
996 let length_sq = self.length_squared();
997 if length_sq < min * min {
998 min * (self / math::sqrt(length_sq))
999 } else {
1000 self
1001 }
1002 }
1003
1004 #[inline]
1012 #[must_use]
1013 pub fn mul_add(self, a: Self, b: Self) -> Self {
1014 #[cfg(target_feature = "fma")]
1015 unsafe {
1016 Self(_mm_fmadd_ps(self.0, a.0, b.0))
1017 }
1018 #[cfg(not(target_feature = "fma"))]
1019 Self::new(
1020 math::mul_add(self.x, a.x, b.x),
1021 math::mul_add(self.y, a.y, b.y),
1022 math::mul_add(self.z, a.z, b.z),
1023 )
1024 }
1025
1026 #[inline]
1035 #[must_use]
1036 pub fn reflect(self, normal: Self) -> Self {
1037 glam_assert!(normal.is_normalized());
1038 self - 2.0 * self.dot(normal) * normal
1039 }
1040
1041 #[inline]
1051 #[must_use]
1052 pub fn refract(self, normal: Self, eta: f32) -> Self {
1053 glam_assert!(self.is_normalized());
1054 glam_assert!(normal.is_normalized());
1055 let n_dot_i = normal.dot(self);
1056 let k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i);
1057 if k >= 0.0 {
1058 eta * self - (eta * n_dot_i + math::sqrt(k)) * normal
1059 } else {
1060 Self::ZERO
1061 }
1062 }
1063
1064 #[inline]
1068 #[must_use]
1069 pub fn angle_between(self, rhs: Self) -> f32 {
1070 math::acos_approx(
1071 self.dot(rhs)
1072 .div(math::sqrt(self.length_squared().mul(rhs.length_squared()))),
1073 )
1074 }
1075
1076 #[inline]
1078 #[must_use]
1079 pub fn rotate_x(self, angle: f32) -> Self {
1080 let (sina, cosa) = math::sin_cos(angle);
1081 Self::new(
1082 self.x,
1083 self.y * cosa - self.z * sina,
1084 self.y * sina + self.z * cosa,
1085 )
1086 }
1087
1088 #[inline]
1090 #[must_use]
1091 pub fn rotate_y(self, angle: f32) -> Self {
1092 let (sina, cosa) = math::sin_cos(angle);
1093 Self::new(
1094 self.x * cosa + self.z * sina,
1095 self.y,
1096 self.x * -sina + self.z * cosa,
1097 )
1098 }
1099
1100 #[inline]
1102 #[must_use]
1103 pub fn rotate_z(self, angle: f32) -> Self {
1104 let (sina, cosa) = math::sin_cos(angle);
1105 Self::new(
1106 self.x * cosa - self.y * sina,
1107 self.x * sina + self.y * cosa,
1108 self.z,
1109 )
1110 }
1111
1112 #[inline]
1120 #[must_use]
1121 pub fn rotate_axis(self, axis: Self, angle: f32) -> Self {
1122 Quat::from_axis_angle(axis.into(), angle) * self
1123 }
1124
1125 #[inline]
1131 #[must_use]
1132 pub fn rotate_towards(self, rhs: Self, max_angle: f32) -> Self {
1133 let angle_between = self.angle_between(rhs);
1134 let angle = max_angle.clamp(angle_between - core::f32::consts::PI, angle_between);
1136 let axis = self
1137 .cross(rhs)
1138 .try_normalize()
1139 .unwrap_or_else(|| self.any_orthogonal_vector().normalize());
1140 Quat::from_axis_angle(axis.into(), angle) * self
1141 }
1142
1143 #[inline]
1150 #[must_use]
1151 pub fn any_orthogonal_vector(&self) -> Self {
1152 if math::abs(self.x) > math::abs(self.y) {
1154 Self::new(-self.z, 0.0, self.x) } else {
1156 Self::new(0.0, self.z, -self.y) }
1158 }
1159
1160 #[inline]
1168 #[must_use]
1169 pub fn any_orthonormal_vector(&self) -> Self {
1170 glam_assert!(self.is_normalized());
1171 let sign = math::signum(self.z);
1173 let a = -1.0 / (sign + self.z);
1174 let b = self.x * self.y * a;
1175 Self::new(b, sign + self.y * self.y * a, -self.y)
1176 }
1177
1178 #[inline]
1185 #[must_use]
1186 pub fn any_orthonormal_pair(&self) -> (Self, Self) {
1187 glam_assert!(self.is_normalized());
1188 let sign = math::signum(self.z);
1190 let a = -1.0 / (sign + self.z);
1191 let b = self.x * self.y * a;
1192 (
1193 Self::new(1.0 + sign * self.x * self.x * a, sign * b, -sign * self.x),
1194 Self::new(b, sign + self.y * self.y * a, -self.y),
1195 )
1196 }
1197
1198 #[inline]
1204 #[must_use]
1205 pub fn slerp(self, rhs: Self, s: f32) -> Self {
1206 let self_length = self.length();
1207 let rhs_length = rhs.length();
1208 let dot = self.dot(rhs) / (self_length * rhs_length);
1210 if math::abs(dot) < 1.0 - 3e-7 {
1212 let theta = math::acos_approx(dot);
1214 let sin_theta = math::sin(theta);
1216 let t1 = math::sin(theta * (1. - s));
1217 let t2 = math::sin(theta * s);
1218
1219 let result_length = self_length.lerp(rhs_length, s);
1221 return (self * (result_length / self_length) * t1
1223 + rhs * (result_length / rhs_length) * t2)
1224 * sin_theta.recip();
1225 }
1226 if dot < 0.0 {
1227 let axis = self.any_orthogonal_vector().normalize().into();
1231 let rotation = Quat::from_axis_angle(axis, core::f32::consts::PI * s);
1232 let result_length = self_length.lerp(rhs_length, s);
1234 rotation * self * (result_length / self_length)
1235 } else {
1236 self.lerp(rhs, s)
1238 }
1239 }
1240
1241 #[inline]
1243 #[must_use]
1244 pub fn as_dvec3(&self) -> crate::DVec3 {
1245 crate::DVec3::new(self.x as f64, self.y as f64, self.z as f64)
1246 }
1247
1248 #[inline]
1250 #[must_use]
1251 pub fn as_i8vec3(&self) -> crate::I8Vec3 {
1252 crate::I8Vec3::new(self.x as i8, self.y as i8, self.z as i8)
1253 }
1254
1255 #[inline]
1257 #[must_use]
1258 pub fn as_u8vec3(&self) -> crate::U8Vec3 {
1259 crate::U8Vec3::new(self.x as u8, self.y as u8, self.z as u8)
1260 }
1261
1262 #[inline]
1264 #[must_use]
1265 pub fn as_i16vec3(&self) -> crate::I16Vec3 {
1266 crate::I16Vec3::new(self.x as i16, self.y as i16, self.z as i16)
1267 }
1268
1269 #[inline]
1271 #[must_use]
1272 pub fn as_u16vec3(&self) -> crate::U16Vec3 {
1273 crate::U16Vec3::new(self.x as u16, self.y as u16, self.z as u16)
1274 }
1275
1276 #[inline]
1278 #[must_use]
1279 pub fn as_ivec3(&self) -> crate::IVec3 {
1280 crate::IVec3::new(self.x as i32, self.y as i32, self.z as i32)
1281 }
1282
1283 #[inline]
1285 #[must_use]
1286 pub fn as_uvec3(&self) -> crate::UVec3 {
1287 crate::UVec3::new(self.x as u32, self.y as u32, self.z as u32)
1288 }
1289
1290 #[inline]
1292 #[must_use]
1293 pub fn as_i64vec3(&self) -> crate::I64Vec3 {
1294 crate::I64Vec3::new(self.x as i64, self.y as i64, self.z as i64)
1295 }
1296
1297 #[inline]
1299 #[must_use]
1300 pub fn as_u64vec3(&self) -> crate::U64Vec3 {
1301 crate::U64Vec3::new(self.x as u64, self.y as u64, self.z as u64)
1302 }
1303
1304 #[inline]
1306 #[must_use]
1307 pub fn as_usizevec3(&self) -> crate::USizeVec3 {
1308 crate::USizeVec3::new(self.x as usize, self.y as usize, self.z as usize)
1309 }
1310}
1311
1312impl Default for Vec3A {
1313 #[inline(always)]
1314 fn default() -> Self {
1315 Self::ZERO
1316 }
1317}
1318
1319impl PartialEq for Vec3A {
1320 #[inline]
1321 fn eq(&self, rhs: &Self) -> bool {
1322 self.cmpeq(*rhs).all()
1323 }
1324}
1325
1326impl Div for Vec3A {
1327 type Output = Self;
1328 #[inline]
1329 fn div(self, rhs: Self) -> Self {
1330 Self(unsafe { _mm_div_ps(self.0, rhs.0) })
1331 }
1332}
1333
1334impl Div<&Self> for Vec3A {
1335 type Output = Self;
1336 #[inline]
1337 fn div(self, rhs: &Self) -> Self {
1338 self.div(*rhs)
1339 }
1340}
1341
1342impl Div<&Vec3A> for &Vec3A {
1343 type Output = Vec3A;
1344 #[inline]
1345 fn div(self, rhs: &Vec3A) -> Vec3A {
1346 (*self).div(*rhs)
1347 }
1348}
1349
1350impl Div<Vec3A> for &Vec3A {
1351 type Output = Vec3A;
1352 #[inline]
1353 fn div(self, rhs: Vec3A) -> Vec3A {
1354 (*self).div(rhs)
1355 }
1356}
1357
1358impl DivAssign for Vec3A {
1359 #[inline]
1360 fn div_assign(&mut self, rhs: Self) {
1361 self.0 = unsafe { _mm_div_ps(self.0, rhs.0) };
1362 }
1363}
1364
1365impl DivAssign<&Self> for Vec3A {
1366 #[inline]
1367 fn div_assign(&mut self, rhs: &Self) {
1368 self.div_assign(*rhs);
1369 }
1370}
1371
1372impl Div<f32> for Vec3A {
1373 type Output = Self;
1374 #[inline]
1375 fn div(self, rhs: f32) -> Self {
1376 Self(unsafe { _mm_div_ps(self.0, _mm_set1_ps(rhs)) })
1377 }
1378}
1379
1380impl Div<&f32> for Vec3A {
1381 type Output = Self;
1382 #[inline]
1383 fn div(self, rhs: &f32) -> Self {
1384 self.div(*rhs)
1385 }
1386}
1387
1388impl Div<&f32> for &Vec3A {
1389 type Output = Vec3A;
1390 #[inline]
1391 fn div(self, rhs: &f32) -> Vec3A {
1392 (*self).div(*rhs)
1393 }
1394}
1395
1396impl Div<f32> for &Vec3A {
1397 type Output = Vec3A;
1398 #[inline]
1399 fn div(self, rhs: f32) -> Vec3A {
1400 (*self).div(rhs)
1401 }
1402}
1403
1404impl DivAssign<f32> for Vec3A {
1405 #[inline]
1406 fn div_assign(&mut self, rhs: f32) {
1407 self.0 = unsafe { _mm_div_ps(self.0, _mm_set1_ps(rhs)) };
1408 }
1409}
1410
1411impl DivAssign<&f32> for Vec3A {
1412 #[inline]
1413 fn div_assign(&mut self, rhs: &f32) {
1414 self.div_assign(*rhs);
1415 }
1416}
1417
1418impl Div<Vec3A> for f32 {
1419 type Output = Vec3A;
1420 #[inline]
1421 fn div(self, rhs: Vec3A) -> Vec3A {
1422 Vec3A(unsafe { _mm_div_ps(_mm_set1_ps(self), rhs.0) })
1423 }
1424}
1425
1426impl Div<&Vec3A> for f32 {
1427 type Output = Vec3A;
1428 #[inline]
1429 fn div(self, rhs: &Vec3A) -> Vec3A {
1430 self.div(*rhs)
1431 }
1432}
1433
1434impl Div<&Vec3A> for &f32 {
1435 type Output = Vec3A;
1436 #[inline]
1437 fn div(self, rhs: &Vec3A) -> Vec3A {
1438 (*self).div(*rhs)
1439 }
1440}
1441
1442impl Div<Vec3A> for &f32 {
1443 type Output = Vec3A;
1444 #[inline]
1445 fn div(self, rhs: Vec3A) -> Vec3A {
1446 (*self).div(rhs)
1447 }
1448}
1449
1450impl Mul for Vec3A {
1451 type Output = Self;
1452 #[inline]
1453 fn mul(self, rhs: Self) -> Self {
1454 Self(unsafe { _mm_mul_ps(self.0, rhs.0) })
1455 }
1456}
1457
1458impl Mul<&Self> for Vec3A {
1459 type Output = Self;
1460 #[inline]
1461 fn mul(self, rhs: &Self) -> Self {
1462 self.mul(*rhs)
1463 }
1464}
1465
1466impl Mul<&Vec3A> for &Vec3A {
1467 type Output = Vec3A;
1468 #[inline]
1469 fn mul(self, rhs: &Vec3A) -> Vec3A {
1470 (*self).mul(*rhs)
1471 }
1472}
1473
1474impl Mul<Vec3A> for &Vec3A {
1475 type Output = Vec3A;
1476 #[inline]
1477 fn mul(self, rhs: Vec3A) -> Vec3A {
1478 (*self).mul(rhs)
1479 }
1480}
1481
1482impl MulAssign for Vec3A {
1483 #[inline]
1484 fn mul_assign(&mut self, rhs: Self) {
1485 self.0 = unsafe { _mm_mul_ps(self.0, rhs.0) };
1486 }
1487}
1488
1489impl MulAssign<&Self> for Vec3A {
1490 #[inline]
1491 fn mul_assign(&mut self, rhs: &Self) {
1492 self.mul_assign(*rhs);
1493 }
1494}
1495
1496impl Mul<f32> for Vec3A {
1497 type Output = Self;
1498 #[inline]
1499 fn mul(self, rhs: f32) -> Self {
1500 Self(unsafe { _mm_mul_ps(self.0, _mm_set1_ps(rhs)) })
1501 }
1502}
1503
1504impl Mul<&f32> for Vec3A {
1505 type Output = Self;
1506 #[inline]
1507 fn mul(self, rhs: &f32) -> Self {
1508 self.mul(*rhs)
1509 }
1510}
1511
1512impl Mul<&f32> for &Vec3A {
1513 type Output = Vec3A;
1514 #[inline]
1515 fn mul(self, rhs: &f32) -> Vec3A {
1516 (*self).mul(*rhs)
1517 }
1518}
1519
1520impl Mul<f32> for &Vec3A {
1521 type Output = Vec3A;
1522 #[inline]
1523 fn mul(self, rhs: f32) -> Vec3A {
1524 (*self).mul(rhs)
1525 }
1526}
1527
1528impl MulAssign<f32> for Vec3A {
1529 #[inline]
1530 fn mul_assign(&mut self, rhs: f32) {
1531 self.0 = unsafe { _mm_mul_ps(self.0, _mm_set1_ps(rhs)) };
1532 }
1533}
1534
1535impl MulAssign<&f32> for Vec3A {
1536 #[inline]
1537 fn mul_assign(&mut self, rhs: &f32) {
1538 self.mul_assign(*rhs);
1539 }
1540}
1541
1542impl Mul<Vec3A> for f32 {
1543 type Output = Vec3A;
1544 #[inline]
1545 fn mul(self, rhs: Vec3A) -> Vec3A {
1546 Vec3A(unsafe { _mm_mul_ps(_mm_set1_ps(self), rhs.0) })
1547 }
1548}
1549
1550impl Mul<&Vec3A> for f32 {
1551 type Output = Vec3A;
1552 #[inline]
1553 fn mul(self, rhs: &Vec3A) -> Vec3A {
1554 self.mul(*rhs)
1555 }
1556}
1557
1558impl Mul<&Vec3A> for &f32 {
1559 type Output = Vec3A;
1560 #[inline]
1561 fn mul(self, rhs: &Vec3A) -> Vec3A {
1562 (*self).mul(*rhs)
1563 }
1564}
1565
1566impl Mul<Vec3A> for &f32 {
1567 type Output = Vec3A;
1568 #[inline]
1569 fn mul(self, rhs: Vec3A) -> Vec3A {
1570 (*self).mul(rhs)
1571 }
1572}
1573
1574impl Add for Vec3A {
1575 type Output = Self;
1576 #[inline]
1577 fn add(self, rhs: Self) -> Self {
1578 Self(unsafe { _mm_add_ps(self.0, rhs.0) })
1579 }
1580}
1581
1582impl Add<&Self> for Vec3A {
1583 type Output = Self;
1584 #[inline]
1585 fn add(self, rhs: &Self) -> Self {
1586 self.add(*rhs)
1587 }
1588}
1589
1590impl Add<&Vec3A> for &Vec3A {
1591 type Output = Vec3A;
1592 #[inline]
1593 fn add(self, rhs: &Vec3A) -> Vec3A {
1594 (*self).add(*rhs)
1595 }
1596}
1597
1598impl Add<Vec3A> for &Vec3A {
1599 type Output = Vec3A;
1600 #[inline]
1601 fn add(self, rhs: Vec3A) -> Vec3A {
1602 (*self).add(rhs)
1603 }
1604}
1605
1606impl AddAssign for Vec3A {
1607 #[inline]
1608 fn add_assign(&mut self, rhs: Self) {
1609 self.0 = unsafe { _mm_add_ps(self.0, rhs.0) };
1610 }
1611}
1612
1613impl AddAssign<&Self> for Vec3A {
1614 #[inline]
1615 fn add_assign(&mut self, rhs: &Self) {
1616 self.add_assign(*rhs);
1617 }
1618}
1619
1620impl Add<f32> for Vec3A {
1621 type Output = Self;
1622 #[inline]
1623 fn add(self, rhs: f32) -> Self {
1624 Self(unsafe { _mm_add_ps(self.0, _mm_set1_ps(rhs)) })
1625 }
1626}
1627
1628impl Add<&f32> for Vec3A {
1629 type Output = Self;
1630 #[inline]
1631 fn add(self, rhs: &f32) -> Self {
1632 self.add(*rhs)
1633 }
1634}
1635
1636impl Add<&f32> for &Vec3A {
1637 type Output = Vec3A;
1638 #[inline]
1639 fn add(self, rhs: &f32) -> Vec3A {
1640 (*self).add(*rhs)
1641 }
1642}
1643
1644impl Add<f32> for &Vec3A {
1645 type Output = Vec3A;
1646 #[inline]
1647 fn add(self, rhs: f32) -> Vec3A {
1648 (*self).add(rhs)
1649 }
1650}
1651
1652impl AddAssign<f32> for Vec3A {
1653 #[inline]
1654 fn add_assign(&mut self, rhs: f32) {
1655 self.0 = unsafe { _mm_add_ps(self.0, _mm_set1_ps(rhs)) };
1656 }
1657}
1658
1659impl AddAssign<&f32> for Vec3A {
1660 #[inline]
1661 fn add_assign(&mut self, rhs: &f32) {
1662 self.add_assign(*rhs);
1663 }
1664}
1665
1666impl Add<Vec3A> for f32 {
1667 type Output = Vec3A;
1668 #[inline]
1669 fn add(self, rhs: Vec3A) -> Vec3A {
1670 Vec3A(unsafe { _mm_add_ps(_mm_set1_ps(self), rhs.0) })
1671 }
1672}
1673
1674impl Add<&Vec3A> for f32 {
1675 type Output = Vec3A;
1676 #[inline]
1677 fn add(self, rhs: &Vec3A) -> Vec3A {
1678 self.add(*rhs)
1679 }
1680}
1681
1682impl Add<&Vec3A> for &f32 {
1683 type Output = Vec3A;
1684 #[inline]
1685 fn add(self, rhs: &Vec3A) -> Vec3A {
1686 (*self).add(*rhs)
1687 }
1688}
1689
1690impl Add<Vec3A> for &f32 {
1691 type Output = Vec3A;
1692 #[inline]
1693 fn add(self, rhs: Vec3A) -> Vec3A {
1694 (*self).add(rhs)
1695 }
1696}
1697
1698impl Sub for Vec3A {
1699 type Output = Self;
1700 #[inline]
1701 fn sub(self, rhs: Self) -> Self {
1702 Self(unsafe { _mm_sub_ps(self.0, rhs.0) })
1703 }
1704}
1705
1706impl Sub<&Self> for Vec3A {
1707 type Output = Self;
1708 #[inline]
1709 fn sub(self, rhs: &Self) -> Self {
1710 self.sub(*rhs)
1711 }
1712}
1713
1714impl Sub<&Vec3A> for &Vec3A {
1715 type Output = Vec3A;
1716 #[inline]
1717 fn sub(self, rhs: &Vec3A) -> Vec3A {
1718 (*self).sub(*rhs)
1719 }
1720}
1721
1722impl Sub<Vec3A> for &Vec3A {
1723 type Output = Vec3A;
1724 #[inline]
1725 fn sub(self, rhs: Vec3A) -> Vec3A {
1726 (*self).sub(rhs)
1727 }
1728}
1729
1730impl SubAssign for Vec3A {
1731 #[inline]
1732 fn sub_assign(&mut self, rhs: Self) {
1733 self.0 = unsafe { _mm_sub_ps(self.0, rhs.0) };
1734 }
1735}
1736
1737impl SubAssign<&Self> for Vec3A {
1738 #[inline]
1739 fn sub_assign(&mut self, rhs: &Self) {
1740 self.sub_assign(*rhs);
1741 }
1742}
1743
1744impl Sub<f32> for Vec3A {
1745 type Output = Self;
1746 #[inline]
1747 fn sub(self, rhs: f32) -> Self {
1748 Self(unsafe { _mm_sub_ps(self.0, _mm_set1_ps(rhs)) })
1749 }
1750}
1751
1752impl Sub<&f32> for Vec3A {
1753 type Output = Self;
1754 #[inline]
1755 fn sub(self, rhs: &f32) -> Self {
1756 self.sub(*rhs)
1757 }
1758}
1759
1760impl Sub<&f32> for &Vec3A {
1761 type Output = Vec3A;
1762 #[inline]
1763 fn sub(self, rhs: &f32) -> Vec3A {
1764 (*self).sub(*rhs)
1765 }
1766}
1767
1768impl Sub<f32> for &Vec3A {
1769 type Output = Vec3A;
1770 #[inline]
1771 fn sub(self, rhs: f32) -> Vec3A {
1772 (*self).sub(rhs)
1773 }
1774}
1775
1776impl SubAssign<f32> for Vec3A {
1777 #[inline]
1778 fn sub_assign(&mut self, rhs: f32) {
1779 self.0 = unsafe { _mm_sub_ps(self.0, _mm_set1_ps(rhs)) };
1780 }
1781}
1782
1783impl SubAssign<&f32> for Vec3A {
1784 #[inline]
1785 fn sub_assign(&mut self, rhs: &f32) {
1786 self.sub_assign(*rhs);
1787 }
1788}
1789
1790impl Sub<Vec3A> for f32 {
1791 type Output = Vec3A;
1792 #[inline]
1793 fn sub(self, rhs: Vec3A) -> Vec3A {
1794 Vec3A(unsafe { _mm_sub_ps(_mm_set1_ps(self), rhs.0) })
1795 }
1796}
1797
1798impl Sub<&Vec3A> for f32 {
1799 type Output = Vec3A;
1800 #[inline]
1801 fn sub(self, rhs: &Vec3A) -> Vec3A {
1802 self.sub(*rhs)
1803 }
1804}
1805
1806impl Sub<&Vec3A> for &f32 {
1807 type Output = Vec3A;
1808 #[inline]
1809 fn sub(self, rhs: &Vec3A) -> Vec3A {
1810 (*self).sub(*rhs)
1811 }
1812}
1813
1814impl Sub<Vec3A> for &f32 {
1815 type Output = Vec3A;
1816 #[inline]
1817 fn sub(self, rhs: Vec3A) -> Vec3A {
1818 (*self).sub(rhs)
1819 }
1820}
1821
1822impl Rem for Vec3A {
1823 type Output = Self;
1824 #[inline]
1825 fn rem(self, rhs: Self) -> Self {
1826 unsafe {
1827 let n = m128_floor(_mm_div_ps(self.0, rhs.0));
1828 Self(_mm_sub_ps(self.0, _mm_mul_ps(n, rhs.0)))
1829 }
1830 }
1831}
1832
1833impl Rem<&Self> for Vec3A {
1834 type Output = Self;
1835 #[inline]
1836 fn rem(self, rhs: &Self) -> Self {
1837 self.rem(*rhs)
1838 }
1839}
1840
1841impl Rem<&Vec3A> for &Vec3A {
1842 type Output = Vec3A;
1843 #[inline]
1844 fn rem(self, rhs: &Vec3A) -> Vec3A {
1845 (*self).rem(*rhs)
1846 }
1847}
1848
1849impl Rem<Vec3A> for &Vec3A {
1850 type Output = Vec3A;
1851 #[inline]
1852 fn rem(self, rhs: Vec3A) -> Vec3A {
1853 (*self).rem(rhs)
1854 }
1855}
1856
1857impl RemAssign for Vec3A {
1858 #[inline]
1859 fn rem_assign(&mut self, rhs: Self) {
1860 *self = self.rem(rhs);
1861 }
1862}
1863
1864impl RemAssign<&Self> for Vec3A {
1865 #[inline]
1866 fn rem_assign(&mut self, rhs: &Self) {
1867 self.rem_assign(*rhs);
1868 }
1869}
1870
1871impl Rem<f32> for Vec3A {
1872 type Output = Self;
1873 #[inline]
1874 fn rem(self, rhs: f32) -> Self {
1875 self.rem(Self::splat(rhs))
1876 }
1877}
1878
1879impl Rem<&f32> for Vec3A {
1880 type Output = Self;
1881 #[inline]
1882 fn rem(self, rhs: &f32) -> Self {
1883 self.rem(*rhs)
1884 }
1885}
1886
1887impl Rem<&f32> for &Vec3A {
1888 type Output = Vec3A;
1889 #[inline]
1890 fn rem(self, rhs: &f32) -> Vec3A {
1891 (*self).rem(*rhs)
1892 }
1893}
1894
1895impl Rem<f32> for &Vec3A {
1896 type Output = Vec3A;
1897 #[inline]
1898 fn rem(self, rhs: f32) -> Vec3A {
1899 (*self).rem(rhs)
1900 }
1901}
1902
1903impl RemAssign<f32> for Vec3A {
1904 #[inline]
1905 fn rem_assign(&mut self, rhs: f32) {
1906 *self = self.rem(Self::splat(rhs));
1907 }
1908}
1909
1910impl RemAssign<&f32> for Vec3A {
1911 #[inline]
1912 fn rem_assign(&mut self, rhs: &f32) {
1913 self.rem_assign(*rhs);
1914 }
1915}
1916
1917impl Rem<Vec3A> for f32 {
1918 type Output = Vec3A;
1919 #[inline]
1920 fn rem(self, rhs: Vec3A) -> Vec3A {
1921 Vec3A::splat(self).rem(rhs)
1922 }
1923}
1924
1925impl Rem<&Vec3A> for f32 {
1926 type Output = Vec3A;
1927 #[inline]
1928 fn rem(self, rhs: &Vec3A) -> Vec3A {
1929 self.rem(*rhs)
1930 }
1931}
1932
1933impl Rem<&Vec3A> for &f32 {
1934 type Output = Vec3A;
1935 #[inline]
1936 fn rem(self, rhs: &Vec3A) -> Vec3A {
1937 (*self).rem(*rhs)
1938 }
1939}
1940
1941impl Rem<Vec3A> for &f32 {
1942 type Output = Vec3A;
1943 #[inline]
1944 fn rem(self, rhs: Vec3A) -> Vec3A {
1945 (*self).rem(rhs)
1946 }
1947}
1948
1949impl AsRef<[f32; 3]> for Vec3A {
1950 #[inline]
1951 fn as_ref(&self) -> &[f32; 3] {
1952 unsafe { &*(self as *const Self as *const [f32; 3]) }
1953 }
1954}
1955
1956impl AsMut<[f32; 3]> for Vec3A {
1957 #[inline]
1958 fn as_mut(&mut self) -> &mut [f32; 3] {
1959 unsafe { &mut *(self as *mut Self as *mut [f32; 3]) }
1960 }
1961}
1962
1963impl Sum for Vec3A {
1964 #[inline]
1965 fn sum<I>(iter: I) -> Self
1966 where
1967 I: Iterator<Item = Self>,
1968 {
1969 iter.fold(Self::ZERO, Self::add)
1970 }
1971}
1972
1973impl<'a> Sum<&'a Self> for Vec3A {
1974 #[inline]
1975 fn sum<I>(iter: I) -> Self
1976 where
1977 I: Iterator<Item = &'a Self>,
1978 {
1979 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1980 }
1981}
1982
1983impl Product for Vec3A {
1984 #[inline]
1985 fn product<I>(iter: I) -> Self
1986 where
1987 I: Iterator<Item = Self>,
1988 {
1989 iter.fold(Self::ONE, Self::mul)
1990 }
1991}
1992
1993impl<'a> Product<&'a Self> for Vec3A {
1994 #[inline]
1995 fn product<I>(iter: I) -> Self
1996 where
1997 I: Iterator<Item = &'a Self>,
1998 {
1999 iter.fold(Self::ONE, |a, &b| Self::mul(a, b))
2000 }
2001}
2002
2003impl Neg for Vec3A {
2004 type Output = Self;
2005 #[inline]
2006 fn neg(self) -> Self {
2007 Self(unsafe { _mm_xor_ps(_mm_set1_ps(-0.0), self.0) })
2008 }
2009}
2010
2011impl Neg for &Vec3A {
2012 type Output = Vec3A;
2013 #[inline]
2014 fn neg(self) -> Vec3A {
2015 (*self).neg()
2016 }
2017}
2018
2019impl Index<usize> for Vec3A {
2020 type Output = f32;
2021 #[inline]
2022 fn index(&self, index: usize) -> &Self::Output {
2023 match index {
2024 0 => &self.x,
2025 1 => &self.y,
2026 2 => &self.z,
2027 _ => panic!("index out of bounds"),
2028 }
2029 }
2030}
2031
2032impl IndexMut<usize> for Vec3A {
2033 #[inline]
2034 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
2035 match index {
2036 0 => &mut self.x,
2037 1 => &mut self.y,
2038 2 => &mut self.z,
2039 _ => panic!("index out of bounds"),
2040 }
2041 }
2042}
2043
2044impl fmt::Display for Vec3A {
2045 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2046 if let Some(p) = f.precision() {
2047 write!(f, "[{:.*}, {:.*}, {:.*}]", p, self.x, p, self.y, p, self.z)
2048 } else {
2049 write!(f, "[{}, {}, {}]", self.x, self.y, self.z)
2050 }
2051 }
2052}
2053
2054impl fmt::Debug for Vec3A {
2055 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
2056 fmt.debug_tuple(stringify!(Vec3A))
2057 .field(&self.x)
2058 .field(&self.y)
2059 .field(&self.z)
2060 .finish()
2061 }
2062}
2063
2064impl From<Vec3A> for __m128 {
2065 #[inline(always)]
2066 fn from(t: Vec3A) -> Self {
2067 t.0
2068 }
2069}
2070
2071impl From<__m128> for Vec3A {
2072 #[inline(always)]
2073 fn from(t: __m128) -> Self {
2074 Self(t)
2075 }
2076}
2077
2078impl From<[f32; 3]> for Vec3A {
2079 #[inline]
2080 fn from(a: [f32; 3]) -> Self {
2081 Self::new(a[0], a[1], a[2])
2082 }
2083}
2084
2085impl From<Vec3A> for [f32; 3] {
2086 #[inline]
2087 fn from(v: Vec3A) -> Self {
2088 use crate::Align16;
2089 use core::mem::MaybeUninit;
2090 let mut out: MaybeUninit<Align16<Self>> = MaybeUninit::uninit();
2091 unsafe {
2092 _mm_store_ps(out.as_mut_ptr().cast(), v.0);
2093 out.assume_init().0
2094 }
2095 }
2096}
2097
2098impl From<(f32, f32, f32)> for Vec3A {
2099 #[inline]
2100 fn from(t: (f32, f32, f32)) -> Self {
2101 Self::new(t.0, t.1, t.2)
2102 }
2103}
2104
2105impl From<Vec3A> for (f32, f32, f32) {
2106 #[inline]
2107 fn from(v: Vec3A) -> Self {
2108 (v.x, v.y, v.z)
2109 }
2110}
2111
2112impl From<Vec3> for Vec3A {
2113 #[inline]
2114 fn from(v: Vec3) -> Self {
2115 Self::new(v.x, v.y, v.z)
2116 }
2117}
2118
2119impl From<Vec3A> for Vec3 {
2120 #[inline]
2121 fn from(v: Vec3A) -> Self {
2122 use crate::Align16;
2123 use core::mem::MaybeUninit;
2124 let mut out: MaybeUninit<Align16<Self>> = MaybeUninit::uninit();
2125 unsafe {
2126 _mm_store_ps(out.as_mut_ptr().cast(), v.0);
2127 out.assume_init().0
2128 }
2129 }
2130}
2131
2132impl From<(Vec2, f32)> for Vec3A {
2133 #[inline]
2134 fn from((v, z): (Vec2, f32)) -> Self {
2135 Self::new(v.x, v.y, z)
2136 }
2137}
2138
2139impl Deref for Vec3A {
2140 type Target = crate::deref::Vec3<f32>;
2141 #[inline]
2142 fn deref(&self) -> &Self::Target {
2143 unsafe { &*(self as *const Self).cast() }
2144 }
2145}
2146
2147impl DerefMut for Vec3A {
2148 #[inline]
2149 fn deref_mut(&mut self) -> &mut Self::Target {
2150 unsafe { &mut *(self as *mut Self).cast() }
2151 }
2152}
2153
2154impl From<BVec3> for Vec3A {
2155 #[inline]
2156 fn from(v: BVec3) -> Self {
2157 Self::new(f32::from(v.x), f32::from(v.y), f32::from(v.z))
2158 }
2159}
2160
2161impl From<BVec3A> for Vec3A {
2162 #[inline]
2163 fn from(v: BVec3A) -> Self {
2164 let bool_array: [bool; 3] = v.into();
2165 Self::new(
2166 f32::from(bool_array[0]),
2167 f32::from(bool_array[1]),
2168 f32::from(bool_array[2]),
2169 )
2170 }
2171}