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