1use crate::{BVec3, BVec3A, FloatExt, Quat, Vec2, Vec3, Vec4, f32::math, neon::*};
4
5use core::fmt;
6use core::iter::{Product, Sum};
7use core::ops::*;
8
9use core::arch::aarch64::*;
10
11#[cfg(feature = "zerocopy-08")]
12use zerocopy_derive_08::*;
13
14#[repr(C)]
15union UnionCast {
16 a: [f32; 4],
17 v: Vec3A,
18}
19
20#[inline(always)]
22#[must_use]
23pub const fn vec3a(x: f32, y: f32, z: f32) -> Vec3A {
24 Vec3A::new(x, y, z)
25}
26
27#[derive(Clone, Copy)]
37#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
38#[cfg_attr(
39 feature = "zerocopy-08",
40 derive(FromBytes, Immutable, IntoBytes, KnownLayout)
41)]
42#[repr(transparent)]
43pub struct Vec3A(pub(crate) float32x4_t);
44
45impl Vec3A {
46 pub const ZERO: Self = Self::splat(0.0);
48
49 pub const ONE: Self = Self::splat(1.0);
51
52 pub const NEG_ONE: Self = Self::splat(-1.0);
54
55 pub const MIN: Self = Self::splat(f32::MIN);
57
58 pub const MAX: Self = Self::splat(f32::MAX);
60
61 pub const NAN: Self = Self::splat(f32::NAN);
63
64 pub const INFINITY: Self = Self::splat(f32::INFINITY);
66
67 pub const NEG_INFINITY: Self = Self::splat(f32::NEG_INFINITY);
69
70 pub const X: Self = Self::new(1.0, 0.0, 0.0);
72
73 pub const Y: Self = Self::new(0.0, 1.0, 0.0);
75
76 pub const Z: Self = Self::new(0.0, 0.0, 1.0);
78
79 pub const NEG_X: Self = Self::new(-1.0, 0.0, 0.0);
81
82 pub const NEG_Y: Self = Self::new(0.0, -1.0, 0.0);
84
85 pub const NEG_Z: Self = Self::new(0.0, 0.0, -1.0);
87
88 pub const AXES: [Self; 3] = [Self::X, Self::Y, Self::Z];
90
91 pub const USES_CORE_SIMD: bool = false;
93 pub const USES_NEON: bool = true;
95 pub const USES_SCALAR_MATH: bool = false;
97 pub const USES_SSE2: bool = false;
99 pub const USES_WASM_SIMD: bool = false;
101
102 #[inline(always)]
104 #[must_use]
105 pub const fn new(x: f32, y: f32, z: f32) -> Self {
106 unsafe { UnionCast { a: [x, y, z, z] }.v }
107 }
108
109 #[inline]
111 #[must_use]
112 pub const fn splat(v: f32) -> Self {
113 unsafe { UnionCast { a: [v; 4] }.v }
114 }
115
116 #[inline]
118 #[must_use]
119 pub fn map<F>(self, mut f: F) -> Self
120 where
121 F: FnMut(f32) -> f32,
122 {
123 Self::new(f(self.x), f(self.y), f(self.z))
124 }
125
126 #[inline]
132 #[must_use]
133 pub fn select(mask: BVec3A, if_true: Self, if_false: Self) -> Self {
134 Self(unsafe { vbslq_f32(mask.0, if_true.0, if_false.0) })
135 }
136
137 #[inline]
139 #[must_use]
140 pub const fn from_array(a: [f32; 3]) -> Self {
141 Self::new(a[0], a[1], a[2])
142 }
143
144 #[inline]
146 #[must_use]
147 pub const fn to_array(&self) -> [f32; 3] {
148 unsafe { *(self as *const Self as *const [f32; 3]) }
149 }
150
151 #[inline]
157 #[must_use]
158 #[track_caller]
159 pub const fn from_slice(slice: &[f32]) -> Self {
160 assert!(slice.len() >= 3);
161 Self::new(slice[0], slice[1], slice[2])
162 }
163
164 #[inline]
170 #[track_caller]
171 pub fn write_to_slice(self, slice: &mut [f32]) {
172 slice[..3].copy_from_slice(&self.to_array());
173 }
174
175 #[inline]
179 #[must_use]
180 pub fn from_vec4(v: Vec4) -> Self {
181 Self(v.0)
182 }
183
184 #[inline]
186 #[must_use]
187 pub fn extend(self, w: f32) -> Vec4 {
188 Vec4::new(self.x, self.y, self.z, w)
189 }
190
191 #[inline]
195 #[must_use]
196 pub fn truncate(self) -> Vec2 {
197 use crate::swizzles::Vec3Swizzles;
198 self.xy()
199 }
200
201 #[inline]
207 #[must_use]
208 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
209 pub fn from_homogeneous(v: Vec4) -> Self {
210 glam_assert!(v.w != 0.0);
211 Self::from_vec4(v) / v.w
212 }
213
214 #[inline]
216 #[must_use]
217 pub fn to_homogeneous(self) -> Vec4 {
218 self.extend(1.0)
219 }
220
221 #[inline]
223 #[must_use]
224 pub fn to_vec3(self) -> Vec3 {
225 Vec3::from(self)
226 }
227
228 #[inline]
230 #[must_use]
231 pub fn with_x(mut self, x: f32) -> Self {
232 self.x = x;
233 self
234 }
235
236 #[inline]
238 #[must_use]
239 pub fn with_y(mut self, y: f32) -> Self {
240 self.y = y;
241 self
242 }
243
244 #[inline]
246 #[must_use]
247 pub fn with_z(mut self, z: f32) -> Self {
248 self.z = z;
249 self
250 }
251
252 #[inline]
254 #[must_use]
255 pub fn dot(self, rhs: Self) -> f32 {
256 (self.x * rhs.x) + (self.y * rhs.y) + (self.z * rhs.z)
258 }
259
260 #[inline]
262 #[must_use]
263 pub fn dot_into_vec(self, rhs: Self) -> Self {
264 Self(unsafe { dot3_into_f32x4(self.0, rhs.0) })
265 }
266
267 #[inline]
269 #[must_use]
270 pub fn cross(self, rhs: Self) -> Self {
271 unsafe {
272 let lhs = self.0;
274 let rhs = rhs.0;
275 let lhs_yzwx = vextq_f32(lhs, lhs, 1);
277 let rhs_wxyz = vextq_f32(rhs, rhs, 3);
278
279 let lhs_yzx = vsetq_lane_f32(vgetq_lane_f32(lhs, 0), lhs_yzwx, 2);
280 let rhs_zxy = vsetq_lane_f32(vgetq_lane_f32(rhs, 2), rhs_wxyz, 0);
281
282 let part_a = vmulq_f32(lhs_yzx, rhs_zxy);
284
285 let lhs_wxyz = vextq_f32(lhs, lhs, 3);
286 let rhs_yzwx = vextq_f32(rhs, rhs, 1);
287 let lhs_zxy = vsetq_lane_f32(vgetq_lane_f32(lhs, 2), lhs_wxyz, 0);
288 let rhs_yzx = vsetq_lane_f32(vgetq_lane_f32(rhs, 0), rhs_yzwx, 2);
289
290 let result = vfmsq_f32(part_a, lhs_zxy, rhs_yzx);
292 Self(result)
293 }
294 }
295
296 #[inline]
303 #[must_use]
304 pub fn min(self, rhs: Self) -> Self {
305 Self(unsafe { vminq_f32(self.0, rhs.0) })
306 }
307
308 #[inline]
315 #[must_use]
316 pub fn max(self, rhs: Self) -> Self {
317 Self(unsafe { vmaxq_f32(self.0, rhs.0) })
318 }
319
320 #[inline]
331 #[must_use]
332 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
333 pub fn clamp(self, min: Self, max: Self) -> Self {
334 glam_assert!(min.cmple(max).all(), "clamp: expected min <= max");
335 self.max(min).min(max)
336 }
337
338 #[inline]
345 #[must_use]
346 pub fn min_element(self) -> f32 {
347 self.x.min(self.y.min(self.z))
348 }
349
350 #[inline]
357 #[must_use]
358 pub fn max_element(self) -> f32 {
359 self.x.max(self.y.max(self.z))
360 }
361
362 #[doc(alias = "argmin")]
364 #[inline]
365 #[must_use]
366 pub fn min_position(self) -> usize {
367 let mut min = self.x;
368 let mut index = 0;
369 if self.y < min {
370 min = self.y;
371 index = 1;
372 }
373 if self.z < min {
374 index = 2;
375 }
376 index
377 }
378
379 #[doc(alias = "argmax")]
381 #[inline]
382 #[must_use]
383 pub fn max_position(self) -> usize {
384 let mut max = self.x;
385 let mut index = 0;
386 if self.y > max {
387 max = self.y;
388 index = 1;
389 }
390 if self.z > max {
391 index = 2;
392 }
393 index
394 }
395
396 #[inline]
400 #[must_use]
401 pub fn element_sum(self) -> f32 {
402 unsafe { vaddvq_f32(vsetq_lane_f32(0.0, self.0, 3)) }
403 }
404
405 #[inline]
409 #[must_use]
410 pub fn element_product(self) -> f32 {
411 unsafe {
412 let s = vmuls_laneq_f32(vgetq_lane_f32(self.0, 0), self.0, 1);
413 vmuls_laneq_f32(s, self.0, 2)
414 }
415 }
416
417 #[inline]
423 #[must_use]
424 pub fn cmpeq(self, rhs: Self) -> BVec3A {
425 BVec3A(unsafe { vceqq_f32(self.0, rhs.0) })
426 }
427
428 #[inline]
434 #[must_use]
435 pub fn cmpne(self, rhs: Self) -> BVec3A {
436 BVec3A(unsafe { vmvnq_u32(vceqq_f32(self.0, rhs.0)) })
437 }
438
439 #[inline]
445 #[must_use]
446 pub fn cmpge(self, rhs: Self) -> BVec3A {
447 BVec3A(unsafe { vcgeq_f32(self.0, rhs.0) })
448 }
449
450 #[inline]
456 #[must_use]
457 pub fn cmpgt(self, rhs: Self) -> BVec3A {
458 BVec3A(unsafe { vcgtq_f32(self.0, rhs.0) })
459 }
460
461 #[inline]
467 #[must_use]
468 pub fn cmple(self, rhs: Self) -> BVec3A {
469 BVec3A(unsafe { vcleq_f32(self.0, rhs.0) })
470 }
471
472 #[inline]
478 #[must_use]
479 pub fn cmplt(self, rhs: Self) -> BVec3A {
480 BVec3A(unsafe { vcltq_f32(self.0, rhs.0) })
481 }
482
483 #[inline]
485 #[must_use]
486 pub fn abs(self) -> Self {
487 Self(unsafe { vabsq_f32(self.0) })
488 }
489
490 #[inline]
496 #[must_use]
497 pub fn signum(self) -> Self {
498 let result = Self(unsafe {
499 vreinterpretq_f32_u32(vorrq_u32(
500 vandq_u32(
501 vreinterpretq_u32_f32(self.0),
502 vreinterpretq_u32_f32(Self::NEG_ONE.0),
503 ),
504 vreinterpretq_u32_f32(Self::ONE.0),
505 ))
506 });
507 let mask = self.is_nan_mask();
508 Self::select(mask, self, result)
509 }
510
511 #[inline]
513 #[must_use]
514 pub fn copysign(self, rhs: Self) -> Self {
515 let mask = Self::splat(-0.0);
516 Self(unsafe {
517 vreinterpretq_f32_u32(vorrq_u32(
518 vandq_u32(vreinterpretq_u32_f32(rhs.0), vreinterpretq_u32_f32(mask.0)),
519 vandq_u32(
520 vreinterpretq_u32_f32(self.0),
521 vmvnq_u32(vreinterpretq_u32_f32(mask.0)),
522 ),
523 ))
524 })
525 }
526
527 #[inline]
535 #[must_use]
536 pub fn is_negative_bitmask(self) -> u32 {
537 unsafe {
538 let nmask = vreinterpretq_u32_f32(vdupq_n_f32(-0.0));
539 let m = vandq_u32(vreinterpretq_u32_f32(self.0), nmask);
540 let x = vgetq_lane_u32(m, 0) >> 31;
541 let y = vgetq_lane_u32(m, 1) >> 31;
542 let z = vgetq_lane_u32(m, 2) >> 31;
543
544 x | y << 1 | z << 2
545 }
546 }
547
548 #[inline]
553 #[must_use]
554 pub fn is_negative_mask(self) -> BVec3A {
555 BVec3A(unsafe { vcltq_s32(vreinterpretq_s32_f32(self.0), vdupq_n_s32(0)) })
556 }
557
558 #[inline]
561 #[must_use]
562 pub fn is_finite(self) -> bool {
563 self.is_finite_mask().all()
564 }
565
566 #[inline]
570 #[must_use]
571 pub fn is_finite_mask(self) -> BVec3A {
572 BVec3A(unsafe { vcltq_f32(vabsq_f32(self.0), Self::INFINITY.0) })
573 }
574
575 #[inline]
577 #[must_use]
578 pub fn is_nan(self) -> bool {
579 self.is_nan_mask().any()
580 }
581
582 #[inline]
586 #[must_use]
587 pub fn is_nan_mask(self) -> BVec3A {
588 BVec3A(unsafe { vmvnq_u32(vceqq_f32(self.0, self.0)) })
589 }
590
591 #[doc(alias = "magnitude")]
593 #[inline]
594 #[must_use]
595 pub fn length(self) -> f32 {
596 math::sqrt(self.dot(self))
597 }
598
599 #[allow(dead_code)]
601 fn is_non_zero(self) -> bool {
602 self.length_squared() > 0.0
603 }
604
605 #[doc(alias = "magnitude2")]
609 #[inline]
610 #[must_use]
611 pub fn length_squared(self) -> f32 {
612 self.dot(self)
613 }
614
615 #[inline]
619 #[must_use]
620 pub fn length_recip(self) -> f32 {
621 1.0 / self.length()
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 #[allow(clippy::let_and_return)]
676 let normalized = self.mul(self.length_recip());
677 glam_assert!(normalized.is_finite());
678 normalized
679 }
680
681 #[inline]
688 #[must_use]
689 pub fn try_normalize(self) -> Option<Self> {
690 let rcp = self.length_recip();
691 if rcp.is_finite() && rcp > 0.0 {
692 Some(self * rcp)
693 } else {
694 None
695 }
696 }
697
698 #[inline]
706 #[must_use]
707 pub fn normalize_or(self, fallback: Self) -> Self {
708 let rcp = self.length_recip();
709 if rcp.is_finite() && rcp > 0.0 {
710 self * rcp
711 } else {
712 fallback
713 }
714 }
715
716 #[inline]
723 #[must_use]
724 pub fn normalize_or_zero(self) -> Self {
725 self.normalize_or(Self::ZERO)
726 }
727
728 #[inline]
732 #[must_use]
733 pub fn normalize_and_length(self) -> (Self, f32) {
734 let length = self.length();
735 let rcp = 1.0 / length;
736 if rcp.is_finite() && rcp > 0.0 {
737 (self * rcp, length)
738 } else {
739 (Self::X, 0.0)
740 }
741 }
742
743 #[inline]
747 #[must_use]
748 pub fn is_normalized(self) -> bool {
749 (self.length_squared() - 1.0).abs() <= 2e-4
750 }
751
752 #[inline]
760 #[must_use]
761 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
762 pub fn project_onto(self, rhs: Self) -> Self {
763 let rhs_len_sq = rhs.dot(rhs);
764 glam_assert!(rhs_len_sq != 0.0);
765 rhs * (self.dot(rhs) / rhs_len_sq)
766 }
767
768 #[doc(alias("plane"))]
779 #[inline]
780 #[must_use]
781 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
782 pub fn reject_from(self, rhs: Self) -> Self {
783 self - self.project_onto(rhs)
784 }
785
786 #[inline]
794 #[must_use]
795 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
796 pub fn project_onto_normalized(self, rhs: Self) -> Self {
797 glam_assert!(rhs.is_normalized());
798 rhs * self.dot(rhs)
799 }
800
801 #[doc(alias("plane"))]
812 #[inline]
813 #[must_use]
814 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
815 pub fn reject_from_normalized(self, rhs: Self) -> Self {
816 self - self.project_onto_normalized(rhs)
817 }
818
819 #[inline]
822 #[must_use]
823 pub fn round(self) -> Self {
824 Self(unsafe { vrndaq_f32(self.0) })
825 }
826
827 #[inline]
830 #[must_use]
831 pub fn floor(self) -> Self {
832 Self(unsafe { vrndmq_f32(self.0) })
833 }
834
835 #[inline]
838 #[must_use]
839 pub fn ceil(self) -> Self {
840 Self(unsafe { vrndpq_f32(self.0) })
841 }
842
843 #[inline]
846 #[must_use]
847 pub fn trunc(self) -> Self {
848 Self(unsafe { vrndq_f32(self.0) })
849 }
850
851 #[inline]
855 #[must_use]
856 pub fn step(self, rhs: Self) -> Self {
857 Self::select(rhs.cmplt(self), Self::ZERO, Self::ONE)
858 }
859
860 #[inline]
871 #[must_use]
872 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
873 pub fn smoothstep(self, edge0: Self, edge1: Self) -> Self {
874 glam_assert!(edge0.cmplt(edge1).all());
875 let t = ((self - edge0) / (edge1 - edge0)).saturate();
876 t * t * (Self::splat(3.0) - Self::splat(2.0) * t)
877 }
878
879 #[inline]
881 #[must_use]
882 pub fn saturate(self) -> Self {
883 self.clamp(Self::ZERO, Self::ONE)
884 }
885
886 #[inline]
893 #[must_use]
894 pub fn fract(self) -> Self {
895 self - self.trunc()
896 }
897
898 #[inline]
905 #[must_use]
906 pub fn fract_gl(self) -> Self {
907 self - self.floor()
908 }
909
910 #[inline]
913 #[must_use]
914 pub fn exp(self) -> Self {
915 Self::new(math::exp(self.x), math::exp(self.y), math::exp(self.z))
916 }
917
918 #[inline]
920 #[must_use]
921 pub fn exp2(self) -> Self {
922 Self::new(math::exp2(self.x), math::exp2(self.y), math::exp2(self.z))
923 }
924
925 #[inline]
928 #[must_use]
929 pub fn ln(self) -> Self {
930 Self::new(math::ln(self.x), math::ln(self.y), math::ln(self.z))
931 }
932
933 #[inline]
936 #[must_use]
937 pub fn log2(self) -> Self {
938 Self::new(math::log2(self.x), math::log2(self.y), math::log2(self.z))
939 }
940
941 #[inline]
943 #[must_use]
944 pub fn powf(self, n: f32) -> Self {
945 Self::new(
946 math::powf(self.x, n),
947 math::powf(self.y, n),
948 math::powf(self.z, n),
949 )
950 }
951
952 #[inline]
955 #[must_use]
956 pub fn sqrt(self) -> Self {
957 Self::new(math::sqrt(self.x), math::sqrt(self.y), math::sqrt(self.z))
958 }
959
960 #[inline]
962 #[must_use]
963 pub fn cos(self) -> Self {
964 Self::new(math::cos(self.x), math::cos(self.y), math::cos(self.z))
965 }
966
967 #[inline]
969 #[must_use]
970 pub fn sin(self) -> Self {
971 Self::new(math::sin(self.x), math::sin(self.y), math::sin(self.z))
972 }
973
974 #[inline]
976 #[must_use]
977 pub fn sin_cos(self) -> (Self, Self) {
978 let (sin_x, cos_x) = math::sin_cos(self.x);
979 let (sin_y, cos_y) = math::sin_cos(self.y);
980 let (sin_z, cos_z) = math::sin_cos(self.z);
981
982 (
983 Self::new(sin_x, sin_y, sin_z),
984 Self::new(cos_x, cos_y, cos_z),
985 )
986 }
987
988 #[inline]
990 #[must_use]
991 pub fn recip(self) -> Self {
992 Self(unsafe { vdivq_f32(Self::ONE.0, self.0) })
993 }
994
995 #[doc(alias = "mix")]
1007 #[inline]
1008 #[must_use]
1009 pub fn lerp(self, rhs: Self, s: f32) -> Self {
1010 self * (1.0 - s) + rhs * s
1011 }
1012
1013 #[doc(alias = "mix")]
1030 #[inline]
1031 #[must_use]
1032 pub fn lerp_monotonic(self, rhs: Self, s: f32) -> Self {
1033 Self(unsafe { vfmaq_f32(self.0, vsubq_f32(rhs.0, self.0), vdupq_n_f32(s)) })
1034 }
1035
1036 #[inline]
1041 #[must_use]
1042 pub fn move_towards(self, rhs: Self, d: f32) -> Self {
1043 let a = rhs - self;
1044 let len = a.length();
1045 if len <= d || len <= 1e-4 {
1046 return rhs;
1047 }
1048 self + a / len * d
1049 }
1050
1051 #[inline]
1057 pub fn midpoint(self, rhs: Self) -> Self {
1058 (self + rhs) * 0.5
1059 }
1060
1061 #[inline]
1071 #[must_use]
1072 pub fn abs_diff_eq(self, rhs: Self, max_abs_diff: f32) -> bool {
1073 self.sub(rhs).abs().cmple(Self::splat(max_abs_diff)).all()
1074 }
1075
1076 #[inline]
1082 #[must_use]
1083 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1084 pub fn clamp_length(self, min: f32, max: f32) -> Self {
1085 glam_assert!(0.0 <= min);
1086 glam_assert!(min <= max);
1087 let length_sq = self.length_squared();
1088 if length_sq < min * min {
1089 min * (self / math::sqrt(length_sq))
1090 } else if length_sq > max * max {
1091 max * (self / math::sqrt(length_sq))
1092 } else {
1093 self
1094 }
1095 }
1096
1097 #[inline]
1103 #[must_use]
1104 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1105 pub fn clamp_length_max(self, max: f32) -> Self {
1106 glam_assert!(0.0 <= max);
1107 let length_sq = self.length_squared();
1108 if length_sq > max * max {
1109 max * (self / math::sqrt(length_sq))
1110 } else {
1111 self
1112 }
1113 }
1114
1115 #[inline]
1121 #[must_use]
1122 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1123 pub fn clamp_length_min(self, min: f32) -> Self {
1124 glam_assert!(0.0 <= min);
1125 let length_sq = self.length_squared();
1126 if length_sq < min * min {
1127 min * (self / math::sqrt(length_sq))
1128 } else {
1129 self
1130 }
1131 }
1132
1133 #[inline]
1141 #[must_use]
1142 pub fn mul_add(self, a: Self, b: Self) -> Self {
1143 Self(unsafe { vfmaq_f32(b.0, self.0, a.0) })
1144 }
1145
1146 #[inline]
1155 #[must_use]
1156 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1157 pub fn reflect(self, normal: Self) -> Self {
1158 glam_assert!(normal.is_normalized());
1159 self - 2.0 * self.dot(normal) * normal
1160 }
1161
1162 #[inline]
1172 #[must_use]
1173 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1174 pub fn refract(self, normal: Self, eta: f32) -> Self {
1175 glam_assert!(self.is_normalized());
1176 glam_assert!(normal.is_normalized());
1177 let n_dot_i = normal.dot(self);
1178 let k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i);
1179 if k >= 0.0 {
1180 eta * self - (eta * n_dot_i + math::sqrt(k)) * normal
1181 } else {
1182 Self::ZERO
1183 }
1184 }
1185
1186 #[inline]
1197 #[must_use]
1198 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1199 pub fn angle_between(self, rhs: Self) -> f32 {
1200 glam_assert!(self.is_non_zero());
1201 glam_assert!(rhs.is_non_zero());
1202 math::acos_approx(
1203 self.dot(rhs)
1204 .div(math::sqrt(self.length_squared().mul(rhs.length_squared()))),
1205 )
1206 }
1207
1208 #[doc(alias = "signed_angle")]
1224 #[inline]
1225 #[must_use]
1226 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1227 pub fn angle_to(self, rhs: Self, axis: Self) -> f32 {
1228 glam_assert!(axis.is_normalized());
1229 glam_assert!(self.is_non_zero());
1230 glam_assert!(rhs.is_non_zero());
1231 math::atan2(self.cross(rhs).dot(axis), self.dot(rhs))
1232 }
1233
1234 #[inline]
1236 #[must_use]
1237 pub fn rotate_x(self, angle: f32) -> Self {
1238 let (sina, cosa) = math::sin_cos(angle);
1239 Self::new(
1240 self.x,
1241 self.y * cosa - self.z * sina,
1242 self.y * sina + self.z * cosa,
1243 )
1244 }
1245
1246 #[inline]
1248 #[must_use]
1249 pub fn rotate_y(self, angle: f32) -> Self {
1250 let (sina, cosa) = math::sin_cos(angle);
1251 Self::new(
1252 self.x * cosa + self.z * sina,
1253 self.y,
1254 self.x * -sina + self.z * cosa,
1255 )
1256 }
1257
1258 #[inline]
1260 #[must_use]
1261 pub fn rotate_z(self, angle: f32) -> Self {
1262 let (sina, cosa) = math::sin_cos(angle);
1263 Self::new(
1264 self.x * cosa - self.y * sina,
1265 self.x * sina + self.y * cosa,
1266 self.z,
1267 )
1268 }
1269
1270 #[inline]
1278 #[must_use]
1279 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1280 pub fn rotate_axis(self, axis: Self, angle: f32) -> Self {
1281 Quat::from_axis_angle(axis.into(), angle) * self
1282 }
1283
1284 #[inline]
1294 #[must_use]
1295 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1296 pub fn rotate_towards(self, rhs: Self, max_angle: f32) -> Self {
1297 let angle_between = self.angle_between(rhs);
1298 let angle = max_angle.clamp(angle_between - core::f32::consts::PI, angle_between);
1300 let axis = self
1301 .cross(rhs)
1302 .try_normalize()
1303 .unwrap_or_else(|| self.any_orthogonal_vector().normalize());
1304 Quat::from_axis_angle(axis.into(), angle) * self
1305 }
1306
1307 #[inline]
1314 #[must_use]
1315 pub fn any_orthogonal_vector(self) -> Self {
1316 if self.x.abs() > self.y.abs() {
1318 Self::new(-self.z, 0.0, self.x) } else {
1320 Self::new(0.0, self.z, -self.y) }
1322 }
1323
1324 #[inline]
1332 #[must_use]
1333 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1334 pub fn any_orthonormal_vector(self) -> Self {
1335 glam_assert!(self.is_normalized());
1336 let sign = self.z.signum();
1338 let a = -1.0 / (sign + self.z);
1339 let b = self.x * self.y * a;
1340 Self::new(b, sign + self.y * self.y * a, -self.y)
1341 }
1342
1343 #[inline]
1350 #[must_use]
1351 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1352 pub fn any_orthonormal_pair(self) -> (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 (
1359 Self::new(1.0 + sign * self.x * self.x * a, sign * b, -sign * self.x),
1360 Self::new(b, sign + self.y * self.y * a, -self.y),
1361 )
1362 }
1363
1364 #[inline]
1374 #[must_use]
1375 #[cfg_attr(any(debug_assertions, feature = "glam-assert"), track_caller)]
1376 pub fn slerp(self, rhs: Self, s: f32) -> Self {
1377 glam_assert!(self.is_non_zero());
1378 glam_assert!(rhs.is_non_zero());
1379 let self_length = self.length();
1380 let rhs_length = rhs.length();
1381 let dot = self.dot(rhs) / (self_length * rhs_length);
1383 if dot.abs() < 1.0 - 3e-7 {
1385 let theta = math::acos_approx(dot);
1387 let coefs = [1.0 - s, s, 1.0, 0.0];
1389 let (sin_theta, t1, t2) = unsafe {
1390 let tmp = vmulq_f32(vdupq_n_f32(theta), vld1q_f32(coefs.as_ptr()));
1391 let tmp = f32x4_sin(tmp);
1392 (
1393 vgetq_lane_f32(tmp, 2), vgetq_lane_f32(tmp, 0), vgetq_lane_f32(tmp, 1), )
1397 };
1398
1399 let result_length = self_length.lerp_monotonic(rhs_length, s);
1401 return (self * (result_length / self_length) * t1
1403 + rhs * (result_length / rhs_length) * t2)
1404 * (1.0 / sin_theta);
1405 }
1406 if dot < 0.0 {
1407 let axis = self.any_orthogonal_vector().normalize().into();
1411 let rotation = Quat::from_axis_angle(axis, core::f32::consts::PI * s);
1412 let result_length = self_length.lerp_monotonic(rhs_length, s);
1414 rotation * self * (result_length / self_length)
1415 } else {
1416 self.lerp(rhs, s)
1418 }
1419 }
1420
1421 #[cfg(feature = "f64")]
1423 #[inline]
1424 #[must_use]
1425 pub fn as_dvec3(self) -> crate::DVec3 {
1426 crate::DVec3::new(self.x as f64, self.y as f64, self.z as f64)
1427 }
1428
1429 #[cfg(feature = "i8")]
1431 #[inline]
1432 #[must_use]
1433 pub fn as_i8vec3(self) -> crate::I8Vec3 {
1434 crate::I8Vec3::new(self.x as i8, self.y as i8, self.z as i8)
1435 }
1436
1437 #[cfg(feature = "u8")]
1439 #[inline]
1440 #[must_use]
1441 pub fn as_u8vec3(self) -> crate::U8Vec3 {
1442 crate::U8Vec3::new(self.x as u8, self.y as u8, self.z as u8)
1443 }
1444
1445 #[cfg(feature = "i16")]
1447 #[inline]
1448 #[must_use]
1449 pub fn as_i16vec3(self) -> crate::I16Vec3 {
1450 crate::I16Vec3::new(self.x as i16, self.y as i16, self.z as i16)
1451 }
1452
1453 #[cfg(feature = "u16")]
1455 #[inline]
1456 #[must_use]
1457 pub fn as_u16vec3(self) -> crate::U16Vec3 {
1458 crate::U16Vec3::new(self.x as u16, self.y as u16, self.z as u16)
1459 }
1460
1461 #[cfg(feature = "i32")]
1463 #[inline]
1464 #[must_use]
1465 pub fn as_ivec3(self) -> crate::IVec3 {
1466 crate::IVec3::new(self.x as i32, self.y as i32, self.z as i32)
1467 }
1468
1469 #[cfg(feature = "u32")]
1471 #[inline]
1472 #[must_use]
1473 pub fn as_uvec3(self) -> crate::UVec3 {
1474 crate::UVec3::new(self.x as u32, self.y as u32, self.z as u32)
1475 }
1476
1477 #[cfg(feature = "i64")]
1479 #[inline]
1480 #[must_use]
1481 pub fn as_i64vec3(self) -> crate::I64Vec3 {
1482 crate::I64Vec3::new(self.x as i64, self.y as i64, self.z as i64)
1483 }
1484
1485 #[cfg(feature = "u64")]
1487 #[inline]
1488 #[must_use]
1489 pub fn as_u64vec3(self) -> crate::U64Vec3 {
1490 crate::U64Vec3::new(self.x as u64, self.y as u64, self.z as u64)
1491 }
1492
1493 #[cfg(feature = "isize")]
1495 #[inline]
1496 #[must_use]
1497 pub fn as_isizevec3(self) -> crate::ISizeVec3 {
1498 crate::ISizeVec3::new(self.x as isize, self.y as isize, self.z as isize)
1499 }
1500
1501 #[cfg(feature = "usize")]
1503 #[inline]
1504 #[must_use]
1505 pub fn as_usizevec3(self) -> crate::USizeVec3 {
1506 crate::USizeVec3::new(self.x as usize, self.y as usize, self.z as usize)
1507 }
1508}
1509
1510impl Default for Vec3A {
1511 #[inline(always)]
1512 fn default() -> Self {
1513 Self::ZERO
1514 }
1515}
1516
1517impl PartialEq for Vec3A {
1518 #[inline]
1519 fn eq(&self, rhs: &Self) -> bool {
1520 self.cmpeq(*rhs).all()
1521 }
1522}
1523
1524impl Div for Vec3A {
1525 type Output = Self;
1526 #[inline]
1527 fn div(self, rhs: Self) -> Self {
1528 Self(unsafe { vdivq_f32(self.0, rhs.0) })
1529 }
1530}
1531
1532impl Div<&Self> for Vec3A {
1533 type Output = Self;
1534 #[inline]
1535 fn div(self, rhs: &Self) -> Self {
1536 self.div(*rhs)
1537 }
1538}
1539
1540impl Div<&Vec3A> for &Vec3A {
1541 type Output = Vec3A;
1542 #[inline]
1543 fn div(self, rhs: &Vec3A) -> Vec3A {
1544 (*self).div(*rhs)
1545 }
1546}
1547
1548impl Div<Vec3A> for &Vec3A {
1549 type Output = Vec3A;
1550 #[inline]
1551 fn div(self, rhs: Vec3A) -> Vec3A {
1552 (*self).div(rhs)
1553 }
1554}
1555
1556impl DivAssign for Vec3A {
1557 #[inline]
1558 fn div_assign(&mut self, rhs: Self) {
1559 self.0 = unsafe { vdivq_f32(self.0, rhs.0) };
1560 }
1561}
1562
1563impl DivAssign<&Self> for Vec3A {
1564 #[inline]
1565 fn div_assign(&mut self, rhs: &Self) {
1566 self.div_assign(*rhs);
1567 }
1568}
1569
1570impl Div<f32> for Vec3A {
1571 type Output = Self;
1572 #[inline]
1573 fn div(self, rhs: f32) -> Self {
1574 Self(unsafe { vdivq_f32(self.0, vld1q_dup_f32(&rhs)) })
1575 }
1576}
1577
1578impl Div<&f32> for Vec3A {
1579 type Output = Self;
1580 #[inline]
1581 fn div(self, rhs: &f32) -> Self {
1582 self.div(*rhs)
1583 }
1584}
1585
1586impl Div<&f32> for &Vec3A {
1587 type Output = Vec3A;
1588 #[inline]
1589 fn div(self, rhs: &f32) -> Vec3A {
1590 (*self).div(*rhs)
1591 }
1592}
1593
1594impl Div<f32> for &Vec3A {
1595 type Output = Vec3A;
1596 #[inline]
1597 fn div(self, rhs: f32) -> Vec3A {
1598 (*self).div(rhs)
1599 }
1600}
1601
1602impl DivAssign<f32> for Vec3A {
1603 #[inline]
1604 fn div_assign(&mut self, rhs: f32) {
1605 self.0 = unsafe { vdivq_f32(self.0, vld1q_dup_f32(&rhs)) };
1606 }
1607}
1608
1609impl DivAssign<&f32> for Vec3A {
1610 #[inline]
1611 fn div_assign(&mut self, rhs: &f32) {
1612 self.div_assign(*rhs);
1613 }
1614}
1615
1616impl Div<Vec3A> for f32 {
1617 type Output = Vec3A;
1618 #[inline]
1619 fn div(self, rhs: Vec3A) -> Vec3A {
1620 Vec3A(unsafe { vdivq_f32(vld1q_dup_f32(&self), rhs.0) })
1621 }
1622}
1623
1624impl Div<&Vec3A> for f32 {
1625 type Output = Vec3A;
1626 #[inline]
1627 fn div(self, rhs: &Vec3A) -> Vec3A {
1628 self.div(*rhs)
1629 }
1630}
1631
1632impl Div<&Vec3A> for &f32 {
1633 type Output = Vec3A;
1634 #[inline]
1635 fn div(self, rhs: &Vec3A) -> Vec3A {
1636 (*self).div(*rhs)
1637 }
1638}
1639
1640impl Div<Vec3A> for &f32 {
1641 type Output = Vec3A;
1642 #[inline]
1643 fn div(self, rhs: Vec3A) -> Vec3A {
1644 (*self).div(rhs)
1645 }
1646}
1647
1648impl Mul for Vec3A {
1649 type Output = Self;
1650 #[inline]
1651 fn mul(self, rhs: Self) -> Self {
1652 Self(unsafe { vmulq_f32(self.0, rhs.0) })
1653 }
1654}
1655
1656impl Mul<&Self> for Vec3A {
1657 type Output = Self;
1658 #[inline]
1659 fn mul(self, rhs: &Self) -> Self {
1660 self.mul(*rhs)
1661 }
1662}
1663
1664impl Mul<&Vec3A> for &Vec3A {
1665 type Output = Vec3A;
1666 #[inline]
1667 fn mul(self, rhs: &Vec3A) -> Vec3A {
1668 (*self).mul(*rhs)
1669 }
1670}
1671
1672impl Mul<Vec3A> for &Vec3A {
1673 type Output = Vec3A;
1674 #[inline]
1675 fn mul(self, rhs: Vec3A) -> Vec3A {
1676 (*self).mul(rhs)
1677 }
1678}
1679
1680impl MulAssign for Vec3A {
1681 #[inline]
1682 fn mul_assign(&mut self, rhs: Self) {
1683 self.0 = unsafe { vmulq_f32(self.0, rhs.0) };
1684 }
1685}
1686
1687impl MulAssign<&Self> for Vec3A {
1688 #[inline]
1689 fn mul_assign(&mut self, rhs: &Self) {
1690 self.mul_assign(*rhs);
1691 }
1692}
1693
1694impl Mul<f32> for Vec3A {
1695 type Output = Self;
1696 #[inline]
1697 fn mul(self, rhs: f32) -> Self {
1698 Self(unsafe { vmulq_n_f32(self.0, rhs) })
1699 }
1700}
1701
1702impl Mul<&f32> for Vec3A {
1703 type Output = Self;
1704 #[inline]
1705 fn mul(self, rhs: &f32) -> Self {
1706 self.mul(*rhs)
1707 }
1708}
1709
1710impl Mul<&f32> for &Vec3A {
1711 type Output = Vec3A;
1712 #[inline]
1713 fn mul(self, rhs: &f32) -> Vec3A {
1714 (*self).mul(*rhs)
1715 }
1716}
1717
1718impl Mul<f32> for &Vec3A {
1719 type Output = Vec3A;
1720 #[inline]
1721 fn mul(self, rhs: f32) -> Vec3A {
1722 (*self).mul(rhs)
1723 }
1724}
1725
1726impl MulAssign<f32> for Vec3A {
1727 #[inline]
1728 fn mul_assign(&mut self, rhs: f32) {
1729 self.0 = unsafe { vmulq_n_f32(self.0, rhs) };
1730 }
1731}
1732
1733impl MulAssign<&f32> for Vec3A {
1734 #[inline]
1735 fn mul_assign(&mut self, rhs: &f32) {
1736 self.mul_assign(*rhs);
1737 }
1738}
1739
1740impl Mul<Vec3A> for f32 {
1741 type Output = Vec3A;
1742 #[inline]
1743 fn mul(self, rhs: Vec3A) -> Vec3A {
1744 Vec3A(unsafe { vmulq_n_f32(rhs.0, self) })
1745 }
1746}
1747
1748impl Mul<&Vec3A> for f32 {
1749 type Output = Vec3A;
1750 #[inline]
1751 fn mul(self, rhs: &Vec3A) -> Vec3A {
1752 self.mul(*rhs)
1753 }
1754}
1755
1756impl Mul<&Vec3A> for &f32 {
1757 type Output = Vec3A;
1758 #[inline]
1759 fn mul(self, rhs: &Vec3A) -> Vec3A {
1760 (*self).mul(*rhs)
1761 }
1762}
1763
1764impl Mul<Vec3A> for &f32 {
1765 type Output = Vec3A;
1766 #[inline]
1767 fn mul(self, rhs: Vec3A) -> Vec3A {
1768 (*self).mul(rhs)
1769 }
1770}
1771
1772impl Add for Vec3A {
1773 type Output = Self;
1774 #[inline]
1775 fn add(self, rhs: Self) -> Self {
1776 Self(unsafe { vaddq_f32(self.0, rhs.0) })
1777 }
1778}
1779
1780impl Add<&Self> for Vec3A {
1781 type Output = Self;
1782 #[inline]
1783 fn add(self, rhs: &Self) -> Self {
1784 self.add(*rhs)
1785 }
1786}
1787
1788impl Add<&Vec3A> for &Vec3A {
1789 type Output = Vec3A;
1790 #[inline]
1791 fn add(self, rhs: &Vec3A) -> Vec3A {
1792 (*self).add(*rhs)
1793 }
1794}
1795
1796impl Add<Vec3A> for &Vec3A {
1797 type Output = Vec3A;
1798 #[inline]
1799 fn add(self, rhs: Vec3A) -> Vec3A {
1800 (*self).add(rhs)
1801 }
1802}
1803
1804impl AddAssign for Vec3A {
1805 #[inline]
1806 fn add_assign(&mut self, rhs: Self) {
1807 self.0 = unsafe { vaddq_f32(self.0, rhs.0) };
1808 }
1809}
1810
1811impl AddAssign<&Self> for Vec3A {
1812 #[inline]
1813 fn add_assign(&mut self, rhs: &Self) {
1814 self.add_assign(*rhs);
1815 }
1816}
1817
1818impl Add<f32> for Vec3A {
1819 type Output = Self;
1820 #[inline]
1821 fn add(self, rhs: f32) -> Self {
1822 Self(unsafe { vaddq_f32(self.0, vld1q_dup_f32(&rhs)) })
1823 }
1824}
1825
1826impl Add<&f32> for Vec3A {
1827 type Output = Self;
1828 #[inline]
1829 fn add(self, rhs: &f32) -> Self {
1830 self.add(*rhs)
1831 }
1832}
1833
1834impl Add<&f32> for &Vec3A {
1835 type Output = Vec3A;
1836 #[inline]
1837 fn add(self, rhs: &f32) -> Vec3A {
1838 (*self).add(*rhs)
1839 }
1840}
1841
1842impl Add<f32> for &Vec3A {
1843 type Output = Vec3A;
1844 #[inline]
1845 fn add(self, rhs: f32) -> Vec3A {
1846 (*self).add(rhs)
1847 }
1848}
1849
1850impl AddAssign<f32> for Vec3A {
1851 #[inline]
1852 fn add_assign(&mut self, rhs: f32) {
1853 self.0 = unsafe { vaddq_f32(self.0, vld1q_dup_f32(&rhs)) };
1854 }
1855}
1856
1857impl AddAssign<&f32> for Vec3A {
1858 #[inline]
1859 fn add_assign(&mut self, rhs: &f32) {
1860 self.add_assign(*rhs);
1861 }
1862}
1863
1864impl Add<Vec3A> for f32 {
1865 type Output = Vec3A;
1866 #[inline]
1867 fn add(self, rhs: Vec3A) -> Vec3A {
1868 Vec3A(unsafe { vaddq_f32(vld1q_dup_f32(&self), rhs.0) })
1869 }
1870}
1871
1872impl Add<&Vec3A> for f32 {
1873 type Output = Vec3A;
1874 #[inline]
1875 fn add(self, rhs: &Vec3A) -> Vec3A {
1876 self.add(*rhs)
1877 }
1878}
1879
1880impl Add<&Vec3A> for &f32 {
1881 type Output = Vec3A;
1882 #[inline]
1883 fn add(self, rhs: &Vec3A) -> Vec3A {
1884 (*self).add(*rhs)
1885 }
1886}
1887
1888impl Add<Vec3A> for &f32 {
1889 type Output = Vec3A;
1890 #[inline]
1891 fn add(self, rhs: Vec3A) -> Vec3A {
1892 (*self).add(rhs)
1893 }
1894}
1895
1896impl Sub for Vec3A {
1897 type Output = Self;
1898 #[inline]
1899 fn sub(self, rhs: Self) -> Self {
1900 Self(unsafe { vsubq_f32(self.0, rhs.0) })
1901 }
1902}
1903
1904impl Sub<&Self> for Vec3A {
1905 type Output = Self;
1906 #[inline]
1907 fn sub(self, rhs: &Self) -> Self {
1908 self.sub(*rhs)
1909 }
1910}
1911
1912impl Sub<&Vec3A> for &Vec3A {
1913 type Output = Vec3A;
1914 #[inline]
1915 fn sub(self, rhs: &Vec3A) -> Vec3A {
1916 (*self).sub(*rhs)
1917 }
1918}
1919
1920impl Sub<Vec3A> for &Vec3A {
1921 type Output = Vec3A;
1922 #[inline]
1923 fn sub(self, rhs: Vec3A) -> Vec3A {
1924 (*self).sub(rhs)
1925 }
1926}
1927
1928impl SubAssign for Vec3A {
1929 #[inline]
1930 fn sub_assign(&mut self, rhs: Self) {
1931 self.0 = unsafe { vsubq_f32(self.0, rhs.0) };
1932 }
1933}
1934
1935impl SubAssign<&Self> for Vec3A {
1936 #[inline]
1937 fn sub_assign(&mut self, rhs: &Self) {
1938 self.sub_assign(*rhs);
1939 }
1940}
1941
1942impl Sub<f32> for Vec3A {
1943 type Output = Self;
1944 #[inline]
1945 fn sub(self, rhs: f32) -> Self {
1946 Self(unsafe { vsubq_f32(self.0, vld1q_dup_f32(&rhs)) })
1947 }
1948}
1949
1950impl Sub<&f32> for Vec3A {
1951 type Output = Self;
1952 #[inline]
1953 fn sub(self, rhs: &f32) -> Self {
1954 self.sub(*rhs)
1955 }
1956}
1957
1958impl Sub<&f32> for &Vec3A {
1959 type Output = Vec3A;
1960 #[inline]
1961 fn sub(self, rhs: &f32) -> Vec3A {
1962 (*self).sub(*rhs)
1963 }
1964}
1965
1966impl Sub<f32> for &Vec3A {
1967 type Output = Vec3A;
1968 #[inline]
1969 fn sub(self, rhs: f32) -> Vec3A {
1970 (*self).sub(rhs)
1971 }
1972}
1973
1974impl SubAssign<f32> for Vec3A {
1975 #[inline]
1976 fn sub_assign(&mut self, rhs: f32) {
1977 self.0 = unsafe { vsubq_f32(self.0, vld1q_dup_f32(&rhs)) };
1978 }
1979}
1980
1981impl SubAssign<&f32> for Vec3A {
1982 #[inline]
1983 fn sub_assign(&mut self, rhs: &f32) {
1984 self.sub_assign(*rhs);
1985 }
1986}
1987
1988impl Sub<Vec3A> for f32 {
1989 type Output = Vec3A;
1990 #[inline]
1991 fn sub(self, rhs: Vec3A) -> Vec3A {
1992 Vec3A(unsafe { vsubq_f32(vld1q_dup_f32(&self), rhs.0) })
1993 }
1994}
1995
1996impl Sub<&Vec3A> for f32 {
1997 type Output = Vec3A;
1998 #[inline]
1999 fn sub(self, rhs: &Vec3A) -> Vec3A {
2000 self.sub(*rhs)
2001 }
2002}
2003
2004impl Sub<&Vec3A> for &f32 {
2005 type Output = Vec3A;
2006 #[inline]
2007 fn sub(self, rhs: &Vec3A) -> Vec3A {
2008 (*self).sub(*rhs)
2009 }
2010}
2011
2012impl Sub<Vec3A> for &f32 {
2013 type Output = Vec3A;
2014 #[inline]
2015 fn sub(self, rhs: Vec3A) -> Vec3A {
2016 (*self).sub(rhs)
2017 }
2018}
2019
2020impl Rem for Vec3A {
2021 type Output = Self;
2022 #[inline]
2023 fn rem(self, rhs: Self) -> Self {
2024 unsafe {
2025 let n = vrndmq_f32(vdivq_f32(self.0, rhs.0));
2026 Self(vsubq_f32(self.0, vmulq_f32(n, rhs.0)))
2027 }
2028 }
2029}
2030
2031impl Rem<&Self> for Vec3A {
2032 type Output = Self;
2033 #[inline]
2034 fn rem(self, rhs: &Self) -> Self {
2035 self.rem(*rhs)
2036 }
2037}
2038
2039impl Rem<&Vec3A> for &Vec3A {
2040 type Output = Vec3A;
2041 #[inline]
2042 fn rem(self, rhs: &Vec3A) -> Vec3A {
2043 (*self).rem(*rhs)
2044 }
2045}
2046
2047impl Rem<Vec3A> for &Vec3A {
2048 type Output = Vec3A;
2049 #[inline]
2050 fn rem(self, rhs: Vec3A) -> Vec3A {
2051 (*self).rem(rhs)
2052 }
2053}
2054
2055impl RemAssign for Vec3A {
2056 #[inline]
2057 fn rem_assign(&mut self, rhs: Self) {
2058 *self = self.rem(rhs);
2059 }
2060}
2061
2062impl RemAssign<&Self> for Vec3A {
2063 #[inline]
2064 fn rem_assign(&mut self, rhs: &Self) {
2065 self.rem_assign(*rhs);
2066 }
2067}
2068
2069impl Rem<f32> for Vec3A {
2070 type Output = Self;
2071 #[inline]
2072 fn rem(self, rhs: f32) -> Self {
2073 self.rem(Self::splat(rhs))
2074 }
2075}
2076
2077impl Rem<&f32> for Vec3A {
2078 type Output = Self;
2079 #[inline]
2080 fn rem(self, rhs: &f32) -> Self {
2081 self.rem(*rhs)
2082 }
2083}
2084
2085impl Rem<&f32> for &Vec3A {
2086 type Output = Vec3A;
2087 #[inline]
2088 fn rem(self, rhs: &f32) -> Vec3A {
2089 (*self).rem(*rhs)
2090 }
2091}
2092
2093impl Rem<f32> for &Vec3A {
2094 type Output = Vec3A;
2095 #[inline]
2096 fn rem(self, rhs: f32) -> Vec3A {
2097 (*self).rem(rhs)
2098 }
2099}
2100
2101impl RemAssign<f32> for Vec3A {
2102 #[inline]
2103 fn rem_assign(&mut self, rhs: f32) {
2104 *self = self.rem(Self::splat(rhs));
2105 }
2106}
2107
2108impl RemAssign<&f32> for Vec3A {
2109 #[inline]
2110 fn rem_assign(&mut self, rhs: &f32) {
2111 self.rem_assign(*rhs);
2112 }
2113}
2114
2115impl Rem<Vec3A> for f32 {
2116 type Output = Vec3A;
2117 #[inline]
2118 fn rem(self, rhs: Vec3A) -> Vec3A {
2119 Vec3A::splat(self).rem(rhs)
2120 }
2121}
2122
2123impl Rem<&Vec3A> for f32 {
2124 type Output = Vec3A;
2125 #[inline]
2126 fn rem(self, rhs: &Vec3A) -> Vec3A {
2127 self.rem(*rhs)
2128 }
2129}
2130
2131impl Rem<&Vec3A> for &f32 {
2132 type Output = Vec3A;
2133 #[inline]
2134 fn rem(self, rhs: &Vec3A) -> Vec3A {
2135 (*self).rem(*rhs)
2136 }
2137}
2138
2139impl Rem<Vec3A> for &f32 {
2140 type Output = Vec3A;
2141 #[inline]
2142 fn rem(self, rhs: Vec3A) -> Vec3A {
2143 (*self).rem(rhs)
2144 }
2145}
2146
2147impl AsRef<[f32; 3]> for Vec3A {
2148 #[inline]
2149 fn as_ref(&self) -> &[f32; 3] {
2150 unsafe { &*(self as *const Self as *const [f32; 3]) }
2151 }
2152}
2153
2154impl AsMut<[f32; 3]> for Vec3A {
2155 #[inline]
2156 fn as_mut(&mut self) -> &mut [f32; 3] {
2157 unsafe { &mut *(self as *mut Self as *mut [f32; 3]) }
2158 }
2159}
2160
2161impl Sum for Vec3A {
2162 #[inline]
2163 fn sum<I>(iter: I) -> Self
2164 where
2165 I: Iterator<Item = Self>,
2166 {
2167 iter.fold(Self::ZERO, Self::add)
2168 }
2169}
2170
2171impl<'a> Sum<&'a Self> for Vec3A {
2172 #[inline]
2173 fn sum<I>(iter: I) -> Self
2174 where
2175 I: Iterator<Item = &'a Self>,
2176 {
2177 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
2178 }
2179}
2180
2181impl Product for Vec3A {
2182 #[inline]
2183 fn product<I>(iter: I) -> Self
2184 where
2185 I: Iterator<Item = Self>,
2186 {
2187 iter.fold(Self::ONE, Self::mul)
2188 }
2189}
2190
2191impl<'a> Product<&'a Self> for Vec3A {
2192 #[inline]
2193 fn product<I>(iter: I) -> Self
2194 where
2195 I: Iterator<Item = &'a Self>,
2196 {
2197 iter.fold(Self::ONE, |a, &b| Self::mul(a, b))
2198 }
2199}
2200
2201impl Neg for Vec3A {
2202 type Output = Self;
2203 #[inline]
2204 fn neg(self) -> Self {
2205 Self(unsafe { vnegq_f32(self.0) })
2206 }
2207}
2208
2209impl Neg for &Vec3A {
2210 type Output = Vec3A;
2211 #[inline]
2212 fn neg(self) -> Vec3A {
2213 (*self).neg()
2214 }
2215}
2216
2217impl Index<usize> for Vec3A {
2218 type Output = f32;
2219 #[inline]
2220 #[track_caller]
2221 fn index(&self, index: usize) -> &Self::Output {
2222 match index {
2223 0 => &self.x,
2224 1 => &self.y,
2225 2 => &self.z,
2226 _ => panic!("index out of bounds"),
2227 }
2228 }
2229}
2230
2231impl IndexMut<usize> for Vec3A {
2232 #[inline]
2233 #[track_caller]
2234 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
2235 match index {
2236 0 => &mut self.x,
2237 1 => &mut self.y,
2238 2 => &mut self.z,
2239 _ => panic!("index out of bounds"),
2240 }
2241 }
2242}
2243
2244impl fmt::Display for Vec3A {
2245 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2246 if let Some(p) = f.precision() {
2247 write!(f, "[{:.*}, {:.*}, {:.*}]", p, self.x, p, self.y, p, self.z)
2248 } else {
2249 write!(f, "[{}, {}, {}]", self.x, self.y, self.z)
2250 }
2251 }
2252}
2253
2254impl fmt::Debug for Vec3A {
2255 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
2256 fmt.debug_tuple(stringify!(Vec3A))
2257 .field(&self.x)
2258 .field(&self.y)
2259 .field(&self.z)
2260 .finish()
2261 }
2262}
2263
2264impl From<Vec3A> for float32x4_t {
2265 #[inline(always)]
2266 fn from(t: Vec3A) -> Self {
2267 t.0
2268 }
2269}
2270
2271impl From<float32x4_t> for Vec3A {
2272 #[inline(always)]
2273 fn from(t: float32x4_t) -> Self {
2274 Self(t)
2275 }
2276}
2277
2278impl From<[f32; 3]> for Vec3A {
2279 #[inline]
2280 fn from(a: [f32; 3]) -> Self {
2281 Self::new(a[0], a[1], a[2])
2282 }
2283}
2284
2285impl From<Vec3A> for [f32; 3] {
2286 #[inline]
2287 fn from(v: Vec3A) -> Self {
2288 use crate::align16::Align16;
2289 use core::mem::MaybeUninit;
2290 let mut out: MaybeUninit<Align16<Self>> = MaybeUninit::uninit();
2291 unsafe {
2292 vst1q_f32(out.as_mut_ptr().cast(), v.0);
2293 out.assume_init().0
2294 }
2295 }
2296}
2297
2298impl From<(f32, f32, f32)> for Vec3A {
2299 #[inline]
2300 fn from(t: (f32, f32, f32)) -> Self {
2301 Self::new(t.0, t.1, t.2)
2302 }
2303}
2304
2305impl From<Vec3A> for (f32, f32, f32) {
2306 #[inline]
2307 fn from(v: Vec3A) -> Self {
2308 (v.x, v.y, v.z)
2309 }
2310}
2311
2312impl From<Vec3> for Vec3A {
2313 #[inline]
2314 fn from(v: Vec3) -> Self {
2315 Self::new(v.x, v.y, v.z)
2316 }
2317}
2318
2319impl From<Vec3A> for Vec3 {
2320 #[inline]
2321 fn from(v: Vec3A) -> Self {
2322 use crate::align16::Align16;
2323 use core::mem::MaybeUninit;
2324 let mut out: MaybeUninit<Align16<Self>> = MaybeUninit::uninit();
2325 unsafe {
2326 vst1q_f32(out.as_mut_ptr().cast(), v.0);
2327 out.assume_init().0
2328 }
2329 }
2330}
2331
2332impl From<(Vec2, f32)> for Vec3A {
2333 #[inline]
2334 fn from((v, z): (Vec2, f32)) -> Self {
2335 Self::new(v.x, v.y, z)
2336 }
2337}
2338
2339impl Deref for Vec3A {
2340 type Target = crate::deref::Vec3<f32>;
2341 #[inline]
2342 fn deref(&self) -> &Self::Target {
2343 unsafe { &*(self as *const Self).cast() }
2344 }
2345}
2346
2347impl DerefMut for Vec3A {
2348 #[inline]
2349 fn deref_mut(&mut self) -> &mut Self::Target {
2350 unsafe { &mut *(self as *mut Self).cast() }
2351 }
2352}
2353
2354impl From<BVec3> for Vec3A {
2355 #[inline]
2356 fn from(v: BVec3) -> Self {
2357 Self::new(f32::from(v.x), f32::from(v.y), f32::from(v.z))
2358 }
2359}
2360
2361impl From<BVec3A> for Vec3A {
2362 #[inline]
2363 fn from(v: BVec3A) -> Self {
2364 let bool_array: [bool; 3] = v.into();
2365 Self::new(
2366 f32::from(bool_array[0]),
2367 f32::from(bool_array[1]),
2368 f32::from(bool_array[2]),
2369 )
2370 }
2371}