1use crate::{BVec3, BVec3A, FloatExt, Quat, Vec2, Vec3, Vec4, 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: 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-08",
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_WASM_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, mut f: F) -> Self
123 where
124 F: FnMut(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 #[track_caller]
167 pub const fn from_slice(slice: &[f32]) -> Self {
168 assert!(slice.len() >= 3);
169 Self::new(slice[0], slice[1], slice[2])
170 }
171
172 #[inline]
178 #[track_caller]
179 pub fn write_to_slice(self, slice: &mut [f32]) {
180 slice[..3].copy_from_slice(&self.to_array());
181 }
182
183 #[inline]
187 #[must_use]
188 pub fn from_vec4(v: Vec4) -> Self {
189 Self(v.0)
190 }
191
192 #[inline]
194 #[must_use]
195 pub fn extend(self, w: f32) -> Vec4 {
196 Vec4::new(self.x, self.y, self.z, w)
197 }
198
199 #[inline]
203 #[must_use]
204 pub fn truncate(self) -> Vec2 {
205 use crate::swizzles::Vec3Swizzles;
206 self.xy()
207 }
208
209 #[inline]
215 #[must_use]
216 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
217 pub fn from_homogeneous(v: Vec4) -> Self {
218 glam_assert!(v.w != 0.0);
219 Self::from_vec4(v) / v.w
220 }
221
222 #[inline]
224 #[must_use]
225 pub fn to_homogeneous(self) -> Vec4 {
226 self.extend(1.0)
227 }
228
229 #[inline]
231 #[must_use]
232 pub fn to_vec3(self) -> Vec3 {
233 Vec3::from(self)
234 }
235
236 #[inline]
238 #[must_use]
239 pub fn with_x(mut self, x: f32) -> Self {
240 self.x = x;
241 self
242 }
243
244 #[inline]
246 #[must_use]
247 pub fn with_y(mut self, y: f32) -> Self {
248 self.y = y;
249 self
250 }
251
252 #[inline]
254 #[must_use]
255 pub fn with_z(mut self, z: f32) -> Self {
256 self.z = z;
257 self
258 }
259
260 #[inline]
262 #[must_use]
263 pub fn dot(self, rhs: Self) -> f32 {
264 unsafe { dot3(self.0, rhs.0) }
265 }
266
267 #[inline]
269 #[must_use]
270 pub fn dot_into_vec(self, rhs: Self) -> Self {
271 Self(unsafe { dot3_into_m128(self.0, rhs.0) })
272 }
273
274 #[inline]
276 #[must_use]
277 pub fn cross(self, rhs: Self) -> Self {
278 unsafe {
279 let lhszxy = _mm_shuffle_ps(self.0, self.0, 0b01_01_00_10);
285 let rhszxy = _mm_shuffle_ps(rhs.0, rhs.0, 0b01_01_00_10);
286 let lhszxy_rhs = _mm_mul_ps(lhszxy, rhs.0);
287 let sub = m128_neg_mul_sub(rhszxy, self.0, lhszxy_rhs);
288 Self(_mm_shuffle_ps(sub, sub, 0b01_01_00_10))
289 }
290 }
291
292 #[inline]
299 #[must_use]
300 pub fn min(self, rhs: Self) -> Self {
301 Self(unsafe { _mm_min_ps(self.0, rhs.0) })
302 }
303
304 #[inline]
311 #[must_use]
312 pub fn max(self, rhs: Self) -> Self {
313 Self(unsafe { _mm_max_ps(self.0, rhs.0) })
314 }
315
316 #[inline]
327 #[must_use]
328 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
329 pub fn clamp(self, min: Self, max: Self) -> Self {
330 glam_assert!(min.cmple(max).all(), "clamp: expected min <= max");
331 self.max(min).min(max)
332 }
333
334 #[inline]
341 #[must_use]
342 pub fn min_element(self) -> f32 {
343 unsafe {
344 let v = self.0;
345 let v = _mm_min_ps(v, _mm_shuffle_ps(v, v, 0b01_01_10_10));
346 let v = _mm_min_ps(v, _mm_shuffle_ps(v, v, 0b00_00_00_01));
347 _mm_cvtss_f32(v)
348 }
349 }
350
351 #[inline]
358 #[must_use]
359 pub fn max_element(self) -> f32 {
360 unsafe {
361 let v = self.0;
362 let v = _mm_max_ps(v, _mm_shuffle_ps(v, v, 0b00_00_10_10));
363 let v = _mm_max_ps(v, _mm_shuffle_ps(v, v, 0b00_00_00_01));
364 _mm_cvtss_f32(v)
365 }
366 }
367
368 #[doc(alias = "argmin")]
370 #[inline]
371 #[must_use]
372 pub fn min_position(self) -> usize {
373 let mut min = self.x;
374 let mut index = 0;
375 if self.y < min {
376 min = self.y;
377 index = 1;
378 }
379 if self.z < min {
380 index = 2;
381 }
382 index
383 }
384
385 #[doc(alias = "argmax")]
387 #[inline]
388 #[must_use]
389 pub fn max_position(self) -> usize {
390 let mut max = self.x;
391 let mut index = 0;
392 if self.y > max {
393 max = self.y;
394 index = 1;
395 }
396 if self.z > max {
397 index = 2;
398 }
399 index
400 }
401
402 #[inline]
406 #[must_use]
407 pub fn element_sum(self) -> f32 {
408 unsafe {
409 let v = self.0;
410 let v = _mm_add_ps(v, _mm_shuffle_ps(v, Self::ZERO.0, 0b00_11_00_01));
411 let v = _mm_add_ps(v, _mm_shuffle_ps(v, v, 0b00_00_00_10));
412 _mm_cvtss_f32(v)
413 }
414 }
415
416 #[inline]
420 #[must_use]
421 pub fn element_product(self) -> f32 {
422 unsafe {
423 let v = self.0;
424 let v = _mm_mul_ps(v, _mm_shuffle_ps(v, Self::ONE.0, 0b00_11_00_01));
425 let v = _mm_mul_ps(v, _mm_shuffle_ps(v, v, 0b00_00_00_10));
426 _mm_cvtss_f32(v)
427 }
428 }
429
430 #[inline]
436 #[must_use]
437 pub fn cmpeq(self, rhs: Self) -> BVec3A {
438 BVec3A(unsafe { _mm_cmpeq_ps(self.0, rhs.0) })
439 }
440
441 #[inline]
447 #[must_use]
448 pub fn cmpne(self, rhs: Self) -> BVec3A {
449 BVec3A(unsafe { _mm_cmpneq_ps(self.0, rhs.0) })
450 }
451
452 #[inline]
458 #[must_use]
459 pub fn cmpge(self, rhs: Self) -> BVec3A {
460 BVec3A(unsafe { _mm_cmpge_ps(self.0, rhs.0) })
461 }
462
463 #[inline]
469 #[must_use]
470 pub fn cmpgt(self, rhs: Self) -> BVec3A {
471 BVec3A(unsafe { _mm_cmpgt_ps(self.0, rhs.0) })
472 }
473
474 #[inline]
480 #[must_use]
481 pub fn cmple(self, rhs: Self) -> BVec3A {
482 BVec3A(unsafe { _mm_cmple_ps(self.0, rhs.0) })
483 }
484
485 #[inline]
491 #[must_use]
492 pub fn cmplt(self, rhs: Self) -> BVec3A {
493 BVec3A(unsafe { _mm_cmplt_ps(self.0, rhs.0) })
494 }
495
496 #[inline]
498 #[must_use]
499 pub fn abs(self) -> Self {
500 Self(unsafe { crate::sse2::m128_abs(self.0) })
501 }
502
503 #[inline]
509 #[must_use]
510 pub fn signum(self) -> Self {
511 let result = Self(unsafe { _mm_or_ps(_mm_and_ps(self.0, Self::NEG_ONE.0), Self::ONE.0) });
512 let mask = self.is_nan_mask();
513 Self::select(mask, self, result)
514 }
515
516 #[inline]
518 #[must_use]
519 pub fn copysign(self, rhs: Self) -> Self {
520 let mask = Self::splat(-0.0);
521 Self(unsafe { _mm_or_ps(_mm_and_ps(rhs.0, mask.0), _mm_andnot_ps(mask.0, self.0)) })
522 }
523
524 #[inline]
532 #[must_use]
533 pub fn is_negative_bitmask(self) -> u32 {
534 unsafe { (_mm_movemask_ps(self.0) as u32) & 0x7 }
535 }
536
537 #[inline]
542 #[must_use]
543 pub fn is_negative_mask(self) -> BVec3A {
544 BVec3A(unsafe {
545 _mm_castsi128_ps(_mm_cmplt_epi32(
546 _mm_castps_si128(self.0),
547 _mm_setzero_si128(),
548 ))
549 })
550 }
551
552 #[inline]
555 #[must_use]
556 pub fn is_finite(self) -> bool {
557 self.is_finite_mask().all()
558 }
559
560 #[inline]
564 #[must_use]
565 pub fn is_finite_mask(self) -> BVec3A {
566 BVec3A(unsafe { _mm_cmplt_ps(crate::sse2::m128_abs(self.0), Self::INFINITY.0) })
567 }
568
569 #[inline]
571 #[must_use]
572 pub fn is_nan(self) -> bool {
573 self.is_nan_mask().any()
574 }
575
576 #[inline]
580 #[must_use]
581 pub fn is_nan_mask(self) -> BVec3A {
582 BVec3A(unsafe { _mm_cmpunord_ps(self.0, self.0) })
583 }
584
585 #[doc(alias = "magnitude")]
587 #[inline]
588 #[must_use]
589 pub fn length(self) -> f32 {
590 unsafe {
591 let dot = dot3_in_x(self.0, self.0);
592 _mm_cvtss_f32(_mm_sqrt_ps(dot))
593 }
594 }
595
596 #[allow(dead_code)]
598 fn is_non_zero(self) -> bool {
599 self.length_squared() > 0.0
600 }
601
602 #[doc(alias = "magnitude2")]
606 #[inline]
607 #[must_use]
608 pub fn length_squared(self) -> f32 {
609 self.dot(self)
610 }
611
612 #[inline]
616 #[must_use]
617 pub fn length_recip(self) -> f32 {
618 unsafe {
619 let dot = dot3_in_x(self.0, self.0);
620 _mm_cvtss_f32(_mm_div_ps(Self::ONE.0, _mm_sqrt_ps(dot)))
621 }
622 }
623
624 #[inline]
626 #[must_use]
627 pub fn distance(self, rhs: Self) -> f32 {
628 (self - rhs).length()
629 }
630
631 #[inline]
633 #[must_use]
634 pub fn distance_squared(self, rhs: Self) -> f32 {
635 (self - rhs).length_squared()
636 }
637
638 #[inline]
640 #[must_use]
641 pub fn div_euclid(self, rhs: Self) -> Self {
642 Self::new(
643 math::div_euclid(self.x, rhs.x),
644 math::div_euclid(self.y, rhs.y),
645 math::div_euclid(self.z, rhs.z),
646 )
647 }
648
649 #[inline]
653 #[must_use]
654 pub fn rem_euclid(self, rhs: Self) -> Self {
655 Self::new(
656 math::rem_euclid(self.x, rhs.x),
657 math::rem_euclid(self.y, rhs.y),
658 math::rem_euclid(self.z, rhs.z),
659 )
660 }
661
662 #[inline]
672 #[must_use]
673 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
674 pub fn normalize(self) -> Self {
675 unsafe {
676 let length = _mm_sqrt_ps(dot3_into_m128(self.0, self.0));
677 #[allow(clippy::let_and_return)]
678 let normalized = Self(_mm_div_ps(self.0, length));
679 glam_assert!(normalized.is_finite());
680 normalized
681 }
682 }
683
684 #[inline]
691 #[must_use]
692 pub fn try_normalize(self) -> Option<Self> {
693 let rcp = self.length_recip();
694 if rcp.is_finite() && rcp > 0.0 {
695 Some(self * rcp)
696 } else {
697 None
698 }
699 }
700
701 #[inline]
709 #[must_use]
710 pub fn normalize_or(self, fallback: Self) -> Self {
711 let rcp = self.length_recip();
712 if rcp.is_finite() && rcp > 0.0 {
713 self * rcp
714 } else {
715 fallback
716 }
717 }
718
719 #[inline]
726 #[must_use]
727 pub fn normalize_or_zero(self) -> Self {
728 self.normalize_or(Self::ZERO)
729 }
730
731 #[inline]
735 #[must_use]
736 pub fn normalize_and_length(self) -> (Self, f32) {
737 let length = self.length();
738 let rcp = 1.0 / length;
739 if rcp.is_finite() && rcp > 0.0 {
740 (self * rcp, length)
741 } else {
742 (Self::X, 0.0)
743 }
744 }
745
746 #[inline]
750 #[must_use]
751 pub fn is_normalized(self) -> bool {
752 (self.length_squared() - 1.0).abs() <= 2e-4
753 }
754
755 #[inline]
763 #[must_use]
764 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
765 pub fn project_onto(self, rhs: Self) -> Self {
766 let rhs_len_sq = rhs.dot(rhs);
767 glam_assert!(rhs_len_sq != 0.0);
768 rhs * (self.dot(rhs) / rhs_len_sq)
769 }
770
771 #[doc(alias("plane"))]
782 #[inline]
783 #[must_use]
784 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
785 pub fn reject_from(self, rhs: Self) -> Self {
786 self - self.project_onto(rhs)
787 }
788
789 #[inline]
797 #[must_use]
798 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
799 pub fn project_onto_normalized(self, rhs: Self) -> Self {
800 glam_assert!(rhs.is_normalized());
801 rhs * self.dot(rhs)
802 }
803
804 #[doc(alias("plane"))]
815 #[inline]
816 #[must_use]
817 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
818 pub fn reject_from_normalized(self, rhs: Self) -> Self {
819 self - self.project_onto_normalized(rhs)
820 }
821
822 #[inline]
825 #[must_use]
826 pub fn round(self) -> Self {
827 Self(unsafe { m128_round(self.0) })
828 }
829
830 #[inline]
833 #[must_use]
834 pub fn floor(self) -> Self {
835 Self(unsafe { m128_floor(self.0) })
836 }
837
838 #[inline]
841 #[must_use]
842 pub fn ceil(self) -> Self {
843 Self(unsafe { m128_ceil(self.0) })
844 }
845
846 #[inline]
849 #[must_use]
850 pub fn trunc(self) -> Self {
851 Self(unsafe { m128_trunc(self.0) })
852 }
853
854 #[inline]
858 #[must_use]
859 pub fn step(self, rhs: Self) -> Self {
860 Self::select(rhs.cmplt(self), Self::ZERO, Self::ONE)
861 }
862
863 #[inline]
874 #[must_use]
875 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
876 pub fn smoothstep(self, edge0: Self, edge1: Self) -> Self {
877 glam_assert!(edge0.cmplt(edge1).all());
878 let t = ((self - edge0) / (edge1 - edge0)).saturate();
879 t * t * (Self::splat(3.0) - Self::splat(2.0) * t)
880 }
881
882 #[inline]
884 #[must_use]
885 pub fn saturate(self) -> Self {
886 self.clamp(Self::ZERO, Self::ONE)
887 }
888
889 #[inline]
896 #[must_use]
897 pub fn fract(self) -> Self {
898 self - self.trunc()
899 }
900
901 #[inline]
908 #[must_use]
909 pub fn fract_gl(self) -> Self {
910 self - self.floor()
911 }
912
913 #[inline]
916 #[must_use]
917 pub fn exp(self) -> Self {
918 Self::new(math::exp(self.x), math::exp(self.y), math::exp(self.z))
919 }
920
921 #[inline]
923 #[must_use]
924 pub fn exp2(self) -> Self {
925 Self::new(math::exp2(self.x), math::exp2(self.y), math::exp2(self.z))
926 }
927
928 #[inline]
931 #[must_use]
932 pub fn ln(self) -> Self {
933 Self::new(math::ln(self.x), math::ln(self.y), math::ln(self.z))
934 }
935
936 #[inline]
939 #[must_use]
940 pub fn log2(self) -> Self {
941 Self::new(math::log2(self.x), math::log2(self.y), math::log2(self.z))
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 )
953 }
954
955 #[inline]
958 #[must_use]
959 pub fn sqrt(self) -> Self {
960 Self::new(math::sqrt(self.x), math::sqrt(self.y), math::sqrt(self.z))
961 }
962
963 #[inline]
965 #[must_use]
966 pub fn cos(self) -> Self {
967 Self::new(math::cos(self.x), math::cos(self.y), math::cos(self.z))
968 }
969
970 #[inline]
972 #[must_use]
973 pub fn sin(self) -> Self {
974 Self::new(math::sin(self.x), math::sin(self.y), math::sin(self.z))
975 }
976
977 #[inline]
979 #[must_use]
980 pub fn sin_cos(self) -> (Self, Self) {
981 let (sin_x, cos_x) = math::sin_cos(self.x);
982 let (sin_y, cos_y) = math::sin_cos(self.y);
983 let (sin_z, cos_z) = math::sin_cos(self.z);
984
985 (
986 Self::new(sin_x, sin_y, sin_z),
987 Self::new(cos_x, cos_y, cos_z),
988 )
989 }
990
991 #[inline]
993 #[must_use]
994 pub fn recip(self) -> Self {
995 Self(unsafe { _mm_div_ps(Self::ONE.0, self.0) })
996 }
997
998 #[doc(alias = "mix")]
1010 #[inline]
1011 #[must_use]
1012 pub fn lerp(self, rhs: Self, s: f32) -> Self {
1013 self * (1.0 - s) + rhs * s
1014 }
1015
1016 #[doc(alias = "mix")]
1033 #[inline]
1034 #[must_use]
1035 pub fn lerp_monotonic(self, rhs: Self, s: f32) -> Self {
1036 unsafe {
1037 Self(m128_mul_add(
1038 _mm_sub_ps(rhs.0, self.0),
1039 _mm_set_ps1(s),
1040 self.0,
1041 ))
1042 }
1043 }
1044
1045 #[inline]
1050 #[must_use]
1051 pub fn move_towards(self, rhs: Self, d: f32) -> Self {
1052 let a = rhs - self;
1053 let len = a.length();
1054 if len <= d || len <= 1e-4 {
1055 return rhs;
1056 }
1057 self + a / len * d
1058 }
1059
1060 #[inline]
1066 pub fn midpoint(self, rhs: Self) -> Self {
1067 (self + rhs) * 0.5
1068 }
1069
1070 #[inline]
1080 #[must_use]
1081 pub fn abs_diff_eq(self, rhs: Self, max_abs_diff: f32) -> bool {
1082 self.sub(rhs).abs().cmple(Self::splat(max_abs_diff)).all()
1083 }
1084
1085 #[inline]
1091 #[must_use]
1092 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1093 pub fn clamp_length(self, min: f32, max: f32) -> Self {
1094 glam_assert!(0.0 <= min);
1095 glam_assert!(min <= max);
1096 let length_sq = self.length_squared();
1097 if length_sq < min * min {
1098 min * (self / math::sqrt(length_sq))
1099 } else if length_sq > max * max {
1100 max * (self / math::sqrt(length_sq))
1101 } else {
1102 self
1103 }
1104 }
1105
1106 #[inline]
1112 #[must_use]
1113 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1114 pub fn clamp_length_max(self, max: f32) -> Self {
1115 glam_assert!(0.0 <= max);
1116 let length_sq = self.length_squared();
1117 if length_sq > max * max {
1118 max * (self / math::sqrt(length_sq))
1119 } else {
1120 self
1121 }
1122 }
1123
1124 #[inline]
1130 #[must_use]
1131 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1132 pub fn clamp_length_min(self, min: f32) -> Self {
1133 glam_assert!(0.0 <= min);
1134 let length_sq = self.length_squared();
1135 if length_sq < min * min {
1136 min * (self / math::sqrt(length_sq))
1137 } else {
1138 self
1139 }
1140 }
1141
1142 #[inline]
1150 #[must_use]
1151 pub fn mul_add(self, a: Self, b: Self) -> Self {
1152 #[cfg(target_feature = "fma")]
1153 unsafe {
1154 Self(_mm_fmadd_ps(self.0, a.0, b.0))
1155 }
1156 #[cfg(not(target_feature = "fma"))]
1157 Self::new(
1158 math::mul_add(self.x, a.x, b.x),
1159 math::mul_add(self.y, a.y, b.y),
1160 math::mul_add(self.z, a.z, b.z),
1161 )
1162 }
1163
1164 #[inline]
1173 #[must_use]
1174 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1175 pub fn reflect(self, normal: Self) -> Self {
1176 glam_assert!(normal.is_normalized());
1177 self - 2.0 * self.dot(normal) * normal
1178 }
1179
1180 #[inline]
1190 #[must_use]
1191 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1192 pub fn refract(self, normal: Self, eta: f32) -> Self {
1193 glam_assert!(self.is_normalized());
1194 glam_assert!(normal.is_normalized());
1195 let n_dot_i = normal.dot(self);
1196 let k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i);
1197 if k >= 0.0 {
1198 eta * self - (eta * n_dot_i + math::sqrt(k)) * normal
1199 } else {
1200 Self::ZERO
1201 }
1202 }
1203
1204 #[inline]
1215 #[must_use]
1216 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1217 pub fn angle_between(self, rhs: Self) -> f32 {
1218 glam_assert!(self.is_non_zero());
1219 glam_assert!(rhs.is_non_zero());
1220 math::acos_approx(
1221 self.dot(rhs)
1222 .div(math::sqrt(self.length_squared().mul(rhs.length_squared()))),
1223 )
1224 }
1225
1226 #[doc(alias = "signed_angle")]
1242 #[inline]
1243 #[must_use]
1244 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1245 pub fn angle_to(self, rhs: Self, axis: Self) -> f32 {
1246 glam_assert!(axis.is_normalized());
1247 glam_assert!(self.is_non_zero());
1248 glam_assert!(rhs.is_non_zero());
1249 math::atan2(self.cross(rhs).dot(axis), self.dot(rhs))
1250 }
1251
1252 #[inline]
1254 #[must_use]
1255 pub fn rotate_x(self, angle: f32) -> Self {
1256 let (sina, cosa) = math::sin_cos(angle);
1257 Self::new(
1258 self.x,
1259 self.y * cosa - self.z * sina,
1260 self.y * sina + self.z * cosa,
1261 )
1262 }
1263
1264 #[inline]
1266 #[must_use]
1267 pub fn rotate_y(self, angle: f32) -> Self {
1268 let (sina, cosa) = math::sin_cos(angle);
1269 Self::new(
1270 self.x * cosa + self.z * sina,
1271 self.y,
1272 self.x * -sina + self.z * cosa,
1273 )
1274 }
1275
1276 #[inline]
1278 #[must_use]
1279 pub fn rotate_z(self, angle: f32) -> Self {
1280 let (sina, cosa) = math::sin_cos(angle);
1281 Self::new(
1282 self.x * cosa - self.y * sina,
1283 self.x * sina + self.y * cosa,
1284 self.z,
1285 )
1286 }
1287
1288 #[inline]
1296 #[must_use]
1297 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1298 pub fn rotate_axis(self, axis: Self, angle: f32) -> Self {
1299 Quat::from_axis_angle(axis.into(), angle) * self
1300 }
1301
1302 #[inline]
1312 #[must_use]
1313 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1314 pub fn rotate_towards(self, rhs: Self, max_angle: f32) -> Self {
1315 let angle_between = self.angle_between(rhs);
1316 let angle = max_angle.clamp(angle_between - core::f32::consts::PI, angle_between);
1318 let axis = self
1319 .cross(rhs)
1320 .try_normalize()
1321 .unwrap_or_else(|| self.any_orthogonal_vector().normalize());
1322 Quat::from_axis_angle(axis.into(), angle) * self
1323 }
1324
1325 #[inline]
1332 #[must_use]
1333 pub fn any_orthogonal_vector(self) -> Self {
1334 if self.x.abs() > self.y.abs() {
1336 Self::new(-self.z, 0.0, self.x) } else {
1338 Self::new(0.0, self.z, -self.y) }
1340 }
1341
1342 #[inline]
1350 #[must_use]
1351 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1352 pub fn any_orthonormal_vector(self) -> Self {
1353 glam_assert!(self.is_normalized());
1354 let sign = self.z.signum();
1356 let a = -1.0 / (sign + self.z);
1357 let b = self.x * self.y * a;
1358 Self::new(b, sign + self.y * self.y * a, -self.y)
1359 }
1360
1361 #[inline]
1368 #[must_use]
1369 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1370 pub fn any_orthonormal_pair(self) -> (Self, Self) {
1371 glam_assert!(self.is_normalized());
1372 let sign = self.z.signum();
1374 let a = -1.0 / (sign + self.z);
1375 let b = self.x * self.y * a;
1376 (
1377 Self::new(1.0 + sign * self.x * self.x * a, sign * b, -sign * self.x),
1378 Self::new(b, sign + self.y * self.y * a, -self.y),
1379 )
1380 }
1381
1382 #[inline]
1392 #[must_use]
1393 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1394 pub fn slerp(self, rhs: Self, s: f32) -> Self {
1395 glam_assert!(self.is_non_zero());
1396 glam_assert!(rhs.is_non_zero());
1397 let self_length = self.length();
1398 let rhs_length = rhs.length();
1399 let dot = self.dot(rhs) / (self_length * rhs_length);
1401 if dot.abs() < 1.0 - 3e-7 {
1403 let theta = math::acos_approx(dot);
1405 let x = 1.0 - s;
1407 let y = s;
1408 let z = 1.0;
1409
1410 let (sin_theta, t1, t2) = unsafe {
1411 let tmp = _mm_mul_ps(_mm_set_ps1(theta), _mm_set_ps(0.0, z, y, x));
1412 let tmp = m128_sin(tmp);
1413 (
1414 _mm_cvtss_f32(_mm_shuffle_ps(tmp, tmp, 0b10_10_10_10)), _mm_cvtss_f32(_mm_shuffle_ps(tmp, tmp, 0b00_00_00_00)), _mm_cvtss_f32(_mm_shuffle_ps(tmp, tmp, 0b01_01_01_01)), )
1418 };
1419
1420 let result_length = self_length.lerp_monotonic(rhs_length, s);
1422 return (self * (result_length / self_length) * t1
1424 + rhs * (result_length / rhs_length) * t2)
1425 * (1.0 / sin_theta);
1426 }
1427 if dot < 0.0 {
1428 let axis = self.any_orthogonal_vector().normalize().into();
1432 let rotation = Quat::from_axis_angle(axis, core::f32::consts::PI * s);
1433 let result_length = self_length.lerp_monotonic(rhs_length, s);
1435 rotation * self * (result_length / self_length)
1436 } else {
1437 self.lerp(rhs, s)
1439 }
1440 }
1441
1442 #[cfg(feature = "f64")]
1444 #[inline]
1445 #[must_use]
1446 pub fn as_dvec3(self) -> crate::DVec3 {
1447 crate::DVec3::new(self.x as f64, self.y as f64, self.z as f64)
1448 }
1449
1450 #[cfg(feature = "i8")]
1452 #[inline]
1453 #[must_use]
1454 pub fn as_i8vec3(self) -> crate::I8Vec3 {
1455 crate::I8Vec3::new(self.x as i8, self.y as i8, self.z as i8)
1456 }
1457
1458 #[cfg(feature = "u8")]
1460 #[inline]
1461 #[must_use]
1462 pub fn as_u8vec3(self) -> crate::U8Vec3 {
1463 crate::U8Vec3::new(self.x as u8, self.y as u8, self.z as u8)
1464 }
1465
1466 #[cfg(feature = "i16")]
1468 #[inline]
1469 #[must_use]
1470 pub fn as_i16vec3(self) -> crate::I16Vec3 {
1471 crate::I16Vec3::new(self.x as i16, self.y as i16, self.z as i16)
1472 }
1473
1474 #[cfg(feature = "u16")]
1476 #[inline]
1477 #[must_use]
1478 pub fn as_u16vec3(self) -> crate::U16Vec3 {
1479 crate::U16Vec3::new(self.x as u16, self.y as u16, self.z as u16)
1480 }
1481
1482 #[cfg(feature = "i32")]
1484 #[inline]
1485 #[must_use]
1486 pub fn as_ivec3(self) -> crate::IVec3 {
1487 crate::IVec3::new(self.x as i32, self.y as i32, self.z as i32)
1488 }
1489
1490 #[cfg(feature = "u32")]
1492 #[inline]
1493 #[must_use]
1494 pub fn as_uvec3(self) -> crate::UVec3 {
1495 crate::UVec3::new(self.x as u32, self.y as u32, self.z as u32)
1496 }
1497
1498 #[cfg(feature = "i64")]
1500 #[inline]
1501 #[must_use]
1502 pub fn as_i64vec3(self) -> crate::I64Vec3 {
1503 crate::I64Vec3::new(self.x as i64, self.y as i64, self.z as i64)
1504 }
1505
1506 #[cfg(feature = "u64")]
1508 #[inline]
1509 #[must_use]
1510 pub fn as_u64vec3(self) -> crate::U64Vec3 {
1511 crate::U64Vec3::new(self.x as u64, self.y as u64, self.z as u64)
1512 }
1513
1514 #[cfg(feature = "isize")]
1516 #[inline]
1517 #[must_use]
1518 pub fn as_isizevec3(self) -> crate::ISizeVec3 {
1519 crate::ISizeVec3::new(self.x as isize, self.y as isize, self.z as isize)
1520 }
1521
1522 #[cfg(feature = "usize")]
1524 #[inline]
1525 #[must_use]
1526 pub fn as_usizevec3(self) -> crate::USizeVec3 {
1527 crate::USizeVec3::new(self.x as usize, self.y as usize, self.z as usize)
1528 }
1529}
1530
1531impl Default for Vec3A {
1532 #[inline(always)]
1533 fn default() -> Self {
1534 Self::ZERO
1535 }
1536}
1537
1538impl PartialEq for Vec3A {
1539 #[inline]
1540 fn eq(&self, rhs: &Self) -> bool {
1541 self.cmpeq(*rhs).all()
1542 }
1543}
1544
1545impl Div for Vec3A {
1546 type Output = Self;
1547 #[inline]
1548 fn div(self, rhs: Self) -> Self {
1549 Self(unsafe { _mm_div_ps(self.0, rhs.0) })
1550 }
1551}
1552
1553impl Div<&Self> for Vec3A {
1554 type Output = Self;
1555 #[inline]
1556 fn div(self, rhs: &Self) -> Self {
1557 self.div(*rhs)
1558 }
1559}
1560
1561impl Div<&Vec3A> for &Vec3A {
1562 type Output = Vec3A;
1563 #[inline]
1564 fn div(self, rhs: &Vec3A) -> Vec3A {
1565 (*self).div(*rhs)
1566 }
1567}
1568
1569impl Div<Vec3A> for &Vec3A {
1570 type Output = Vec3A;
1571 #[inline]
1572 fn div(self, rhs: Vec3A) -> Vec3A {
1573 (*self).div(rhs)
1574 }
1575}
1576
1577impl DivAssign for Vec3A {
1578 #[inline]
1579 fn div_assign(&mut self, rhs: Self) {
1580 self.0 = unsafe { _mm_div_ps(self.0, rhs.0) };
1581 }
1582}
1583
1584impl DivAssign<&Self> for Vec3A {
1585 #[inline]
1586 fn div_assign(&mut self, rhs: &Self) {
1587 self.div_assign(*rhs);
1588 }
1589}
1590
1591impl Div<f32> for Vec3A {
1592 type Output = Self;
1593 #[inline]
1594 fn div(self, rhs: f32) -> Self {
1595 Self(unsafe { _mm_div_ps(self.0, _mm_set1_ps(rhs)) })
1596 }
1597}
1598
1599impl Div<&f32> for Vec3A {
1600 type Output = Self;
1601 #[inline]
1602 fn div(self, rhs: &f32) -> Self {
1603 self.div(*rhs)
1604 }
1605}
1606
1607impl Div<&f32> for &Vec3A {
1608 type Output = Vec3A;
1609 #[inline]
1610 fn div(self, rhs: &f32) -> Vec3A {
1611 (*self).div(*rhs)
1612 }
1613}
1614
1615impl Div<f32> for &Vec3A {
1616 type Output = Vec3A;
1617 #[inline]
1618 fn div(self, rhs: f32) -> Vec3A {
1619 (*self).div(rhs)
1620 }
1621}
1622
1623impl DivAssign<f32> for Vec3A {
1624 #[inline]
1625 fn div_assign(&mut self, rhs: f32) {
1626 self.0 = unsafe { _mm_div_ps(self.0, _mm_set1_ps(rhs)) };
1627 }
1628}
1629
1630impl DivAssign<&f32> for Vec3A {
1631 #[inline]
1632 fn div_assign(&mut self, rhs: &f32) {
1633 self.div_assign(*rhs);
1634 }
1635}
1636
1637impl Div<Vec3A> for f32 {
1638 type Output = Vec3A;
1639 #[inline]
1640 fn div(self, rhs: Vec3A) -> Vec3A {
1641 Vec3A(unsafe { _mm_div_ps(_mm_set1_ps(self), rhs.0) })
1642 }
1643}
1644
1645impl Div<&Vec3A> for f32 {
1646 type Output = Vec3A;
1647 #[inline]
1648 fn div(self, rhs: &Vec3A) -> Vec3A {
1649 self.div(*rhs)
1650 }
1651}
1652
1653impl Div<&Vec3A> for &f32 {
1654 type Output = Vec3A;
1655 #[inline]
1656 fn div(self, rhs: &Vec3A) -> Vec3A {
1657 (*self).div(*rhs)
1658 }
1659}
1660
1661impl Div<Vec3A> for &f32 {
1662 type Output = Vec3A;
1663 #[inline]
1664 fn div(self, rhs: Vec3A) -> Vec3A {
1665 (*self).div(rhs)
1666 }
1667}
1668
1669impl Mul for Vec3A {
1670 type Output = Self;
1671 #[inline]
1672 fn mul(self, rhs: Self) -> Self {
1673 Self(unsafe { _mm_mul_ps(self.0, rhs.0) })
1674 }
1675}
1676
1677impl Mul<&Self> for Vec3A {
1678 type Output = Self;
1679 #[inline]
1680 fn mul(self, rhs: &Self) -> Self {
1681 self.mul(*rhs)
1682 }
1683}
1684
1685impl Mul<&Vec3A> for &Vec3A {
1686 type Output = Vec3A;
1687 #[inline]
1688 fn mul(self, rhs: &Vec3A) -> Vec3A {
1689 (*self).mul(*rhs)
1690 }
1691}
1692
1693impl Mul<Vec3A> for &Vec3A {
1694 type Output = Vec3A;
1695 #[inline]
1696 fn mul(self, rhs: Vec3A) -> Vec3A {
1697 (*self).mul(rhs)
1698 }
1699}
1700
1701impl MulAssign for Vec3A {
1702 #[inline]
1703 fn mul_assign(&mut self, rhs: Self) {
1704 self.0 = unsafe { _mm_mul_ps(self.0, rhs.0) };
1705 }
1706}
1707
1708impl MulAssign<&Self> for Vec3A {
1709 #[inline]
1710 fn mul_assign(&mut self, rhs: &Self) {
1711 self.mul_assign(*rhs);
1712 }
1713}
1714
1715impl Mul<f32> for Vec3A {
1716 type Output = Self;
1717 #[inline]
1718 fn mul(self, rhs: f32) -> Self {
1719 Self(unsafe { _mm_mul_ps(self.0, _mm_set1_ps(rhs)) })
1720 }
1721}
1722
1723impl Mul<&f32> for Vec3A {
1724 type Output = Self;
1725 #[inline]
1726 fn mul(self, rhs: &f32) -> Self {
1727 self.mul(*rhs)
1728 }
1729}
1730
1731impl Mul<&f32> for &Vec3A {
1732 type Output = Vec3A;
1733 #[inline]
1734 fn mul(self, rhs: &f32) -> Vec3A {
1735 (*self).mul(*rhs)
1736 }
1737}
1738
1739impl Mul<f32> for &Vec3A {
1740 type Output = Vec3A;
1741 #[inline]
1742 fn mul(self, rhs: f32) -> Vec3A {
1743 (*self).mul(rhs)
1744 }
1745}
1746
1747impl MulAssign<f32> for Vec3A {
1748 #[inline]
1749 fn mul_assign(&mut self, rhs: f32) {
1750 self.0 = unsafe { _mm_mul_ps(self.0, _mm_set1_ps(rhs)) };
1751 }
1752}
1753
1754impl MulAssign<&f32> for Vec3A {
1755 #[inline]
1756 fn mul_assign(&mut self, rhs: &f32) {
1757 self.mul_assign(*rhs);
1758 }
1759}
1760
1761impl Mul<Vec3A> for f32 {
1762 type Output = Vec3A;
1763 #[inline]
1764 fn mul(self, rhs: Vec3A) -> Vec3A {
1765 Vec3A(unsafe { _mm_mul_ps(_mm_set1_ps(self), rhs.0) })
1766 }
1767}
1768
1769impl Mul<&Vec3A> for f32 {
1770 type Output = Vec3A;
1771 #[inline]
1772 fn mul(self, rhs: &Vec3A) -> Vec3A {
1773 self.mul(*rhs)
1774 }
1775}
1776
1777impl Mul<&Vec3A> for &f32 {
1778 type Output = Vec3A;
1779 #[inline]
1780 fn mul(self, rhs: &Vec3A) -> Vec3A {
1781 (*self).mul(*rhs)
1782 }
1783}
1784
1785impl Mul<Vec3A> for &f32 {
1786 type Output = Vec3A;
1787 #[inline]
1788 fn mul(self, rhs: Vec3A) -> Vec3A {
1789 (*self).mul(rhs)
1790 }
1791}
1792
1793impl Add for Vec3A {
1794 type Output = Self;
1795 #[inline]
1796 fn add(self, rhs: Self) -> Self {
1797 Self(unsafe { _mm_add_ps(self.0, rhs.0) })
1798 }
1799}
1800
1801impl Add<&Self> for Vec3A {
1802 type Output = Self;
1803 #[inline]
1804 fn add(self, rhs: &Self) -> Self {
1805 self.add(*rhs)
1806 }
1807}
1808
1809impl Add<&Vec3A> for &Vec3A {
1810 type Output = Vec3A;
1811 #[inline]
1812 fn add(self, rhs: &Vec3A) -> Vec3A {
1813 (*self).add(*rhs)
1814 }
1815}
1816
1817impl Add<Vec3A> for &Vec3A {
1818 type Output = Vec3A;
1819 #[inline]
1820 fn add(self, rhs: Vec3A) -> Vec3A {
1821 (*self).add(rhs)
1822 }
1823}
1824
1825impl AddAssign for Vec3A {
1826 #[inline]
1827 fn add_assign(&mut self, rhs: Self) {
1828 self.0 = unsafe { _mm_add_ps(self.0, rhs.0) };
1829 }
1830}
1831
1832impl AddAssign<&Self> for Vec3A {
1833 #[inline]
1834 fn add_assign(&mut self, rhs: &Self) {
1835 self.add_assign(*rhs);
1836 }
1837}
1838
1839impl Add<f32> for Vec3A {
1840 type Output = Self;
1841 #[inline]
1842 fn add(self, rhs: f32) -> Self {
1843 Self(unsafe { _mm_add_ps(self.0, _mm_set1_ps(rhs)) })
1844 }
1845}
1846
1847impl Add<&f32> for Vec3A {
1848 type Output = Self;
1849 #[inline]
1850 fn add(self, rhs: &f32) -> Self {
1851 self.add(*rhs)
1852 }
1853}
1854
1855impl Add<&f32> for &Vec3A {
1856 type Output = Vec3A;
1857 #[inline]
1858 fn add(self, rhs: &f32) -> Vec3A {
1859 (*self).add(*rhs)
1860 }
1861}
1862
1863impl Add<f32> for &Vec3A {
1864 type Output = Vec3A;
1865 #[inline]
1866 fn add(self, rhs: f32) -> Vec3A {
1867 (*self).add(rhs)
1868 }
1869}
1870
1871impl AddAssign<f32> for Vec3A {
1872 #[inline]
1873 fn add_assign(&mut self, rhs: f32) {
1874 self.0 = unsafe { _mm_add_ps(self.0, _mm_set1_ps(rhs)) };
1875 }
1876}
1877
1878impl AddAssign<&f32> for Vec3A {
1879 #[inline]
1880 fn add_assign(&mut self, rhs: &f32) {
1881 self.add_assign(*rhs);
1882 }
1883}
1884
1885impl Add<Vec3A> for f32 {
1886 type Output = Vec3A;
1887 #[inline]
1888 fn add(self, rhs: Vec3A) -> Vec3A {
1889 Vec3A(unsafe { _mm_add_ps(_mm_set1_ps(self), rhs.0) })
1890 }
1891}
1892
1893impl Add<&Vec3A> for f32 {
1894 type Output = Vec3A;
1895 #[inline]
1896 fn add(self, rhs: &Vec3A) -> Vec3A {
1897 self.add(*rhs)
1898 }
1899}
1900
1901impl Add<&Vec3A> for &f32 {
1902 type Output = Vec3A;
1903 #[inline]
1904 fn add(self, rhs: &Vec3A) -> Vec3A {
1905 (*self).add(*rhs)
1906 }
1907}
1908
1909impl Add<Vec3A> for &f32 {
1910 type Output = Vec3A;
1911 #[inline]
1912 fn add(self, rhs: Vec3A) -> Vec3A {
1913 (*self).add(rhs)
1914 }
1915}
1916
1917impl Sub for Vec3A {
1918 type Output = Self;
1919 #[inline]
1920 fn sub(self, rhs: Self) -> Self {
1921 Self(unsafe { _mm_sub_ps(self.0, rhs.0) })
1922 }
1923}
1924
1925impl Sub<&Self> for Vec3A {
1926 type Output = Self;
1927 #[inline]
1928 fn sub(self, rhs: &Self) -> Self {
1929 self.sub(*rhs)
1930 }
1931}
1932
1933impl Sub<&Vec3A> for &Vec3A {
1934 type Output = Vec3A;
1935 #[inline]
1936 fn sub(self, rhs: &Vec3A) -> Vec3A {
1937 (*self).sub(*rhs)
1938 }
1939}
1940
1941impl Sub<Vec3A> for &Vec3A {
1942 type Output = Vec3A;
1943 #[inline]
1944 fn sub(self, rhs: Vec3A) -> Vec3A {
1945 (*self).sub(rhs)
1946 }
1947}
1948
1949impl SubAssign for Vec3A {
1950 #[inline]
1951 fn sub_assign(&mut self, rhs: Self) {
1952 self.0 = unsafe { _mm_sub_ps(self.0, rhs.0) };
1953 }
1954}
1955
1956impl SubAssign<&Self> for Vec3A {
1957 #[inline]
1958 fn sub_assign(&mut self, rhs: &Self) {
1959 self.sub_assign(*rhs);
1960 }
1961}
1962
1963impl Sub<f32> for Vec3A {
1964 type Output = Self;
1965 #[inline]
1966 fn sub(self, rhs: f32) -> Self {
1967 Self(unsafe { _mm_sub_ps(self.0, _mm_set1_ps(rhs)) })
1968 }
1969}
1970
1971impl Sub<&f32> for Vec3A {
1972 type Output = Self;
1973 #[inline]
1974 fn sub(self, rhs: &f32) -> Self {
1975 self.sub(*rhs)
1976 }
1977}
1978
1979impl Sub<&f32> for &Vec3A {
1980 type Output = Vec3A;
1981 #[inline]
1982 fn sub(self, rhs: &f32) -> Vec3A {
1983 (*self).sub(*rhs)
1984 }
1985}
1986
1987impl Sub<f32> for &Vec3A {
1988 type Output = Vec3A;
1989 #[inline]
1990 fn sub(self, rhs: f32) -> Vec3A {
1991 (*self).sub(rhs)
1992 }
1993}
1994
1995impl SubAssign<f32> for Vec3A {
1996 #[inline]
1997 fn sub_assign(&mut self, rhs: f32) {
1998 self.0 = unsafe { _mm_sub_ps(self.0, _mm_set1_ps(rhs)) };
1999 }
2000}
2001
2002impl SubAssign<&f32> for Vec3A {
2003 #[inline]
2004 fn sub_assign(&mut self, rhs: &f32) {
2005 self.sub_assign(*rhs);
2006 }
2007}
2008
2009impl Sub<Vec3A> for f32 {
2010 type Output = Vec3A;
2011 #[inline]
2012 fn sub(self, rhs: Vec3A) -> Vec3A {
2013 Vec3A(unsafe { _mm_sub_ps(_mm_set1_ps(self), rhs.0) })
2014 }
2015}
2016
2017impl Sub<&Vec3A> for f32 {
2018 type Output = Vec3A;
2019 #[inline]
2020 fn sub(self, rhs: &Vec3A) -> Vec3A {
2021 self.sub(*rhs)
2022 }
2023}
2024
2025impl Sub<&Vec3A> for &f32 {
2026 type Output = Vec3A;
2027 #[inline]
2028 fn sub(self, rhs: &Vec3A) -> Vec3A {
2029 (*self).sub(*rhs)
2030 }
2031}
2032
2033impl Sub<Vec3A> for &f32 {
2034 type Output = Vec3A;
2035 #[inline]
2036 fn sub(self, rhs: Vec3A) -> Vec3A {
2037 (*self).sub(rhs)
2038 }
2039}
2040
2041impl Rem for Vec3A {
2042 type Output = Self;
2043 #[inline]
2044 fn rem(self, rhs: Self) -> Self {
2045 unsafe {
2046 let n = m128_floor(_mm_div_ps(self.0, rhs.0));
2047 Self(_mm_sub_ps(self.0, _mm_mul_ps(n, rhs.0)))
2048 }
2049 }
2050}
2051
2052impl Rem<&Self> for Vec3A {
2053 type Output = Self;
2054 #[inline]
2055 fn rem(self, rhs: &Self) -> Self {
2056 self.rem(*rhs)
2057 }
2058}
2059
2060impl Rem<&Vec3A> for &Vec3A {
2061 type Output = Vec3A;
2062 #[inline]
2063 fn rem(self, rhs: &Vec3A) -> Vec3A {
2064 (*self).rem(*rhs)
2065 }
2066}
2067
2068impl Rem<Vec3A> for &Vec3A {
2069 type Output = Vec3A;
2070 #[inline]
2071 fn rem(self, rhs: Vec3A) -> Vec3A {
2072 (*self).rem(rhs)
2073 }
2074}
2075
2076impl RemAssign for Vec3A {
2077 #[inline]
2078 fn rem_assign(&mut self, rhs: Self) {
2079 *self = self.rem(rhs);
2080 }
2081}
2082
2083impl RemAssign<&Self> for Vec3A {
2084 #[inline]
2085 fn rem_assign(&mut self, rhs: &Self) {
2086 self.rem_assign(*rhs);
2087 }
2088}
2089
2090impl Rem<f32> for Vec3A {
2091 type Output = Self;
2092 #[inline]
2093 fn rem(self, rhs: f32) -> Self {
2094 self.rem(Self::splat(rhs))
2095 }
2096}
2097
2098impl Rem<&f32> for Vec3A {
2099 type Output = Self;
2100 #[inline]
2101 fn rem(self, rhs: &f32) -> Self {
2102 self.rem(*rhs)
2103 }
2104}
2105
2106impl Rem<&f32> for &Vec3A {
2107 type Output = Vec3A;
2108 #[inline]
2109 fn rem(self, rhs: &f32) -> Vec3A {
2110 (*self).rem(*rhs)
2111 }
2112}
2113
2114impl Rem<f32> for &Vec3A {
2115 type Output = Vec3A;
2116 #[inline]
2117 fn rem(self, rhs: f32) -> Vec3A {
2118 (*self).rem(rhs)
2119 }
2120}
2121
2122impl RemAssign<f32> for Vec3A {
2123 #[inline]
2124 fn rem_assign(&mut self, rhs: f32) {
2125 *self = self.rem(Self::splat(rhs));
2126 }
2127}
2128
2129impl RemAssign<&f32> for Vec3A {
2130 #[inline]
2131 fn rem_assign(&mut self, rhs: &f32) {
2132 self.rem_assign(*rhs);
2133 }
2134}
2135
2136impl Rem<Vec3A> for f32 {
2137 type Output = Vec3A;
2138 #[inline]
2139 fn rem(self, rhs: Vec3A) -> Vec3A {
2140 Vec3A::splat(self).rem(rhs)
2141 }
2142}
2143
2144impl Rem<&Vec3A> for f32 {
2145 type Output = Vec3A;
2146 #[inline]
2147 fn rem(self, rhs: &Vec3A) -> Vec3A {
2148 self.rem(*rhs)
2149 }
2150}
2151
2152impl Rem<&Vec3A> for &f32 {
2153 type Output = Vec3A;
2154 #[inline]
2155 fn rem(self, rhs: &Vec3A) -> Vec3A {
2156 (*self).rem(*rhs)
2157 }
2158}
2159
2160impl Rem<Vec3A> for &f32 {
2161 type Output = Vec3A;
2162 #[inline]
2163 fn rem(self, rhs: Vec3A) -> Vec3A {
2164 (*self).rem(rhs)
2165 }
2166}
2167
2168impl AsRef<[f32; 3]> for Vec3A {
2169 #[inline]
2170 fn as_ref(&self) -> &[f32; 3] {
2171 unsafe { &*(self as *const Self as *const [f32; 3]) }
2172 }
2173}
2174
2175impl AsMut<[f32; 3]> for Vec3A {
2176 #[inline]
2177 fn as_mut(&mut self) -> &mut [f32; 3] {
2178 unsafe { &mut *(self as *mut Self as *mut [f32; 3]) }
2179 }
2180}
2181
2182impl Sum for Vec3A {
2183 #[inline]
2184 fn sum<I>(iter: I) -> Self
2185 where
2186 I: Iterator<Item = Self>,
2187 {
2188 iter.fold(Self::ZERO, Self::add)
2189 }
2190}
2191
2192impl<'a> Sum<&'a Self> for Vec3A {
2193 #[inline]
2194 fn sum<I>(iter: I) -> Self
2195 where
2196 I: Iterator<Item = &'a Self>,
2197 {
2198 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
2199 }
2200}
2201
2202impl Product for Vec3A {
2203 #[inline]
2204 fn product<I>(iter: I) -> Self
2205 where
2206 I: Iterator<Item = Self>,
2207 {
2208 iter.fold(Self::ONE, Self::mul)
2209 }
2210}
2211
2212impl<'a> Product<&'a Self> for Vec3A {
2213 #[inline]
2214 fn product<I>(iter: I) -> Self
2215 where
2216 I: Iterator<Item = &'a Self>,
2217 {
2218 iter.fold(Self::ONE, |a, &b| Self::mul(a, b))
2219 }
2220}
2221
2222impl Neg for Vec3A {
2223 type Output = Self;
2224 #[inline]
2225 fn neg(self) -> Self {
2226 Self(unsafe { _mm_xor_ps(_mm_set1_ps(-0.0), self.0) })
2227 }
2228}
2229
2230impl Neg for &Vec3A {
2231 type Output = Vec3A;
2232 #[inline]
2233 fn neg(self) -> Vec3A {
2234 (*self).neg()
2235 }
2236}
2237
2238impl Index<usize> for Vec3A {
2239 type Output = f32;
2240 #[inline]
2241 #[track_caller]
2242 fn index(&self, index: usize) -> &Self::Output {
2243 match index {
2244 0 => &self.x,
2245 1 => &self.y,
2246 2 => &self.z,
2247 _ => panic!("index out of bounds"),
2248 }
2249 }
2250}
2251
2252impl IndexMut<usize> for Vec3A {
2253 #[inline]
2254 #[track_caller]
2255 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
2256 match index {
2257 0 => &mut self.x,
2258 1 => &mut self.y,
2259 2 => &mut self.z,
2260 _ => panic!("index out of bounds"),
2261 }
2262 }
2263}
2264
2265impl fmt::Display for Vec3A {
2266 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2267 if let Some(p) = f.precision() {
2268 write!(f, "[{:.*}, {:.*}, {:.*}]", p, self.x, p, self.y, p, self.z)
2269 } else {
2270 write!(f, "[{}, {}, {}]", self.x, self.y, self.z)
2271 }
2272 }
2273}
2274
2275impl fmt::Debug for Vec3A {
2276 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
2277 fmt.debug_tuple(stringify!(Vec3A))
2278 .field(&self.x)
2279 .field(&self.y)
2280 .field(&self.z)
2281 .finish()
2282 }
2283}
2284
2285impl From<Vec3A> for __m128 {
2286 #[inline(always)]
2287 fn from(t: Vec3A) -> Self {
2288 t.0
2289 }
2290}
2291
2292impl From<__m128> for Vec3A {
2293 #[inline(always)]
2294 fn from(t: __m128) -> Self {
2295 Self(t)
2296 }
2297}
2298
2299impl From<[f32; 3]> for Vec3A {
2300 #[inline]
2301 fn from(a: [f32; 3]) -> Self {
2302 Self::new(a[0], a[1], a[2])
2303 }
2304}
2305
2306impl From<Vec3A> for [f32; 3] {
2307 #[inline]
2308 fn from(v: Vec3A) -> Self {
2309 use crate::Align16;
2310 use core::mem::MaybeUninit;
2311 let mut out: MaybeUninit<Align16<Self>> = MaybeUninit::uninit();
2312 unsafe {
2313 _mm_store_ps(out.as_mut_ptr().cast(), v.0);
2314 out.assume_init().0
2315 }
2316 }
2317}
2318
2319impl From<(f32, f32, f32)> for Vec3A {
2320 #[inline]
2321 fn from(t: (f32, f32, f32)) -> Self {
2322 Self::new(t.0, t.1, t.2)
2323 }
2324}
2325
2326impl From<Vec3A> for (f32, f32, f32) {
2327 #[inline]
2328 fn from(v: Vec3A) -> Self {
2329 (v.x, v.y, v.z)
2330 }
2331}
2332
2333impl From<Vec3> for Vec3A {
2334 #[inline]
2335 fn from(v: Vec3) -> Self {
2336 Self::new(v.x, v.y, v.z)
2337 }
2338}
2339
2340impl From<Vec3A> for Vec3 {
2341 #[inline]
2342 fn from(v: Vec3A) -> Self {
2343 use crate::Align16;
2344 use core::mem::MaybeUninit;
2345 let mut out: MaybeUninit<Align16<Self>> = MaybeUninit::uninit();
2346 unsafe {
2347 _mm_store_ps(out.as_mut_ptr().cast(), v.0);
2348 out.assume_init().0
2349 }
2350 }
2351}
2352
2353impl From<(Vec2, f32)> for Vec3A {
2354 #[inline]
2355 fn from((v, z): (Vec2, f32)) -> Self {
2356 Self::new(v.x, v.y, z)
2357 }
2358}
2359
2360impl Deref for Vec3A {
2361 type Target = crate::deref::Vec3<f32>;
2362 #[inline]
2363 fn deref(&self) -> &Self::Target {
2364 unsafe { &*(self as *const Self).cast() }
2365 }
2366}
2367
2368impl DerefMut for Vec3A {
2369 #[inline]
2370 fn deref_mut(&mut self) -> &mut Self::Target {
2371 unsafe { &mut *(self as *mut Self).cast() }
2372 }
2373}
2374
2375impl From<BVec3> for Vec3A {
2376 #[inline]
2377 fn from(v: BVec3) -> Self {
2378 Self::new(f32::from(v.x), f32::from(v.y), f32::from(v.z))
2379 }
2380}
2381
2382impl From<BVec3A> for Vec3A {
2383 #[inline]
2384 fn from(v: BVec3A) -> Self {
2385 let bool_array: [bool; 3] = v.into();
2386 Self::new(
2387 f32::from(bool_array[0]),
2388 f32::from(bool_array[1]),
2389 f32::from(bool_array[2]),
2390 )
2391 }
2392}