Skip to main content

glam/f32/neon/
vec3a.rs

1// Generated from vec.rs.tera template. Edit the template, not the generated file.
2
3use crate::{f32::math, neon::*, BVec3, BVec3A, FloatExt, Quat, Vec2, Vec3, Vec4};
4
5use core::fmt;
6use core::iter::{Product, Sum};
7use core::{f32, ops::*};
8
9use core::arch::aarch64::*;
10
11#[cfg(feature = "zerocopy")]
12use zerocopy_derive::*;
13
14#[repr(C)]
15union UnionCast {
16    a: [f32; 4],
17    v: Vec3A,
18}
19
20/// Creates a 3-dimensional vector.
21#[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/// A 3-dimensional vector.
28///
29/// SIMD vector types are used for storage on supported platforms for better
30/// performance than the [`Vec3`] type.
31///
32/// It is possible to convert between [`Vec3`] and [`Vec3A`] types using [`From`]
33/// or [`Into`] trait implementations.
34///
35/// This type is 16 byte aligned.
36#[derive(Clone, Copy)]
37#[cfg_attr(feature = "bytemuck", derive(bytemuck::Pod, bytemuck::Zeroable))]
38#[cfg_attr(
39    feature = "zerocopy",
40    derive(FromBytes, Immutable, IntoBytes, KnownLayout)
41)]
42#[repr(transparent)]
43pub struct Vec3A(pub(crate) float32x4_t);
44
45impl Vec3A {
46    /// All zeroes.
47    pub const ZERO: Self = Self::splat(0.0);
48
49    /// All ones.
50    pub const ONE: Self = Self::splat(1.0);
51
52    /// All negative ones.
53    pub const NEG_ONE: Self = Self::splat(-1.0);
54
55    /// All `f32::MIN`.
56    pub const MIN: Self = Self::splat(f32::MIN);
57
58    /// All `f32::MAX`.
59    pub const MAX: Self = Self::splat(f32::MAX);
60
61    /// All `f32::NAN`.
62    pub const NAN: Self = Self::splat(f32::NAN);
63
64    /// All `f32::INFINITY`.
65    pub const INFINITY: Self = Self::splat(f32::INFINITY);
66
67    /// All `f32::NEG_INFINITY`.
68    pub const NEG_INFINITY: Self = Self::splat(f32::NEG_INFINITY);
69
70    /// A unit vector pointing along the positive X axis.
71    pub const X: Self = Self::new(1.0, 0.0, 0.0);
72
73    /// A unit vector pointing along the positive Y axis.
74    pub const Y: Self = Self::new(0.0, 1.0, 0.0);
75
76    /// A unit vector pointing along the positive Z axis.
77    pub const Z: Self = Self::new(0.0, 0.0, 1.0);
78
79    /// A unit vector pointing along the negative X axis.
80    pub const NEG_X: Self = Self::new(-1.0, 0.0, 0.0);
81
82    /// A unit vector pointing along the negative Y axis.
83    pub const NEG_Y: Self = Self::new(0.0, -1.0, 0.0);
84
85    /// A unit vector pointing along the negative Z axis.
86    pub const NEG_Z: Self = Self::new(0.0, 0.0, -1.0);
87
88    /// The unit axes.
89    pub const AXES: [Self; 3] = [Self::X, Self::Y, Self::Z];
90
91    /// Vec3A uses Rust Portable SIMD
92    pub const USES_CORE_SIMD: bool = false;
93    /// Vec3A uses Arm NEON
94    pub const USES_NEON: bool = true;
95    /// Vec3A uses scalar math
96    pub const USES_SCALAR_MATH: bool = false;
97    /// Vec3A uses Intel SSE2
98    pub const USES_SSE2: bool = false;
99    /// Vec3A uses WebAssembly 128-bit SIMD
100    pub const USES_WASM_SIMD: bool = false;
101    #[deprecated(since = "0.31.0", note = "Renamed to USES_WASM_SIMD")]
102    pub const USES_WASM32_SIMD: bool = false;
103
104    /// Creates a new vector.
105    #[inline(always)]
106    #[must_use]
107    pub const fn new(x: f32, y: f32, z: f32) -> Self {
108        unsafe { UnionCast { a: [x, y, z, z] }.v }
109    }
110
111    /// Creates a vector with all elements set to `v`.
112    #[inline]
113    #[must_use]
114    pub const fn splat(v: f32) -> Self {
115        unsafe { UnionCast { a: [v; 4] }.v }
116    }
117
118    /// Returns a vector containing each element of `self` modified by a mapping function `f`.
119    #[inline]
120    #[must_use]
121    pub fn map<F>(self, mut f: F) -> Self
122    where
123        F: FnMut(f32) -> f32,
124    {
125        Self::new(f(self.x), f(self.y), f(self.z))
126    }
127
128    /// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use
129    /// for each element of `self`.
130    ///
131    /// A true element in the mask uses the corresponding element from `if_true`, and false
132    /// uses the element from `if_false`.
133    #[inline]
134    #[must_use]
135    pub fn select(mask: BVec3A, if_true: Self, if_false: Self) -> Self {
136        Self(unsafe { vbslq_f32(mask.0, if_true.0, if_false.0) })
137    }
138
139    /// Creates a new vector from an array.
140    #[inline]
141    #[must_use]
142    pub const fn from_array(a: [f32; 3]) -> Self {
143        Self::new(a[0], a[1], a[2])
144    }
145
146    /// Converts `self` to `[x, y, z]`
147    #[inline]
148    #[must_use]
149    pub const fn to_array(&self) -> [f32; 3] {
150        unsafe { *(self as *const Self as *const [f32; 3]) }
151    }
152
153    /// Creates a vector from the first 3 values in `slice`.
154    ///
155    /// # Panics
156    ///
157    /// Panics if `slice` is less than 3 elements long.
158    #[inline]
159    #[must_use]
160    pub const fn from_slice(slice: &[f32]) -> Self {
161        assert!(slice.len() >= 3);
162        Self::new(slice[0], slice[1], slice[2])
163    }
164
165    /// Writes the elements of `self` to the first 3 elements in `slice`.
166    ///
167    /// # Panics
168    ///
169    /// Panics if `slice` is less than 3 elements long.
170    #[inline]
171    pub fn write_to_slice(self, slice: &mut [f32]) {
172        slice[..3].copy_from_slice(&self.to_array());
173    }
174
175    /// Creates a [`Vec3A`] from the `x`, `y` and `z` elements of `self` discarding `w`.
176    ///
177    /// On architectures where SIMD is supported such as SSE2 on `x86_64` this conversion is a noop.
178    #[inline]
179    #[must_use]
180    pub fn from_vec4(v: Vec4) -> Self {
181        Self(v.0)
182    }
183
184    /// Creates a 4D vector from `self` and the given `w` value.
185    #[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    /// Creates a 2D vector from the `x` and `y` elements of `self`, discarding `z`.
192    ///
193    /// Truncation may also be performed by using [`self.xy()`][crate::swizzles::Vec3Swizzles::xy()].
194    #[inline]
195    #[must_use]
196    pub fn truncate(self) -> Vec2 {
197        use crate::swizzles::Vec3Swizzles;
198        self.xy()
199    }
200
201    /// Projects a homogeneous coordinate to 3D space by performing perspective divide.
202    ///
203    /// # Panics
204    ///
205    /// Will panic if `v.w` is `0` when `glam_assert` is enabled.
206    #[inline]
207    #[must_use]
208    pub fn from_homogeneous(v: Vec4) -> Self {
209        glam_assert!(v.w != 0.0);
210        Self::from_vec4(v) / v.w
211    }
212
213    /// Creates a homogeneous coordinate from `self`, equivalent to `self.extend(1.0)`.
214    #[inline]
215    #[must_use]
216    pub fn to_homogeneous(self) -> Vec4 {
217        self.extend(1.0)
218    }
219
220    // Converts `self` to a `Vec3`.
221    #[inline]
222    #[must_use]
223    pub fn to_vec3(self) -> Vec3 {
224        Vec3::from(self)
225    }
226
227    /// Creates a 3D vector from `self` with the given value of `x`.
228    #[inline]
229    #[must_use]
230    pub fn with_x(mut self, x: f32) -> Self {
231        self.x = x;
232        self
233    }
234
235    /// Creates a 3D vector from `self` with the given value of `y`.
236    #[inline]
237    #[must_use]
238    pub fn with_y(mut self, y: f32) -> Self {
239        self.y = y;
240        self
241    }
242
243    /// Creates a 3D vector from `self` with the given value of `z`.
244    #[inline]
245    #[must_use]
246    pub fn with_z(mut self, z: f32) -> Self {
247        self.z = z;
248        self
249    }
250
251    /// Computes the dot product of `self` and `rhs`.
252    #[inline]
253    #[must_use]
254    pub fn dot(self, rhs: Self) -> f32 {
255        // this was faster than intrinsics in testing
256        (self.x * rhs.x) + (self.y * rhs.y) + (self.z * rhs.z)
257    }
258
259    /// Returns a vector where every component is the dot product of `self` and `rhs`.
260    #[inline]
261    #[must_use]
262    pub fn dot_into_vec(self, rhs: Self) -> Self {
263        Self(unsafe { dot3_into_f32x4(self.0, rhs.0) })
264    }
265
266    /// Computes the cross product of `self` and `rhs`.
267    #[inline]
268    #[must_use]
269    pub fn cross(self, rhs: Self) -> Self {
270        unsafe {
271            // Implementation taken from Realtime Math
272            let lhs = self.0;
273            let rhs = rhs.0;
274            // cross(a, b) = (a.yzx * b.zxy) - (a.zxy * b.yzx)
275            let lhs_yzwx = vextq_f32(lhs, lhs, 1);
276            let rhs_wxyz = vextq_f32(rhs, rhs, 3);
277
278            let lhs_yzx = vsetq_lane_f32(vgetq_lane_f32(lhs, 0), lhs_yzwx, 2);
279            let rhs_zxy = vsetq_lane_f32(vgetq_lane_f32(rhs, 2), rhs_wxyz, 0);
280
281            // part_a = (a.yzx * b.zxy)
282            let part_a = vmulq_f32(lhs_yzx, rhs_zxy);
283
284            let lhs_wxyz = vextq_f32(lhs, lhs, 3);
285            let rhs_yzwx = vextq_f32(rhs, rhs, 1);
286            let lhs_zxy = vsetq_lane_f32(vgetq_lane_f32(lhs, 2), lhs_wxyz, 0);
287            let rhs_yzx = vsetq_lane_f32(vgetq_lane_f32(rhs, 0), rhs_yzwx, 2);
288
289            // result = part_a - (a.zxy * b.yzx)
290            let result = vmlsq_f32(part_a, lhs_zxy, rhs_yzx);
291            Self(result)
292        }
293    }
294
295    /// Returns a vector containing the minimum values for each element of `self` and `rhs`.
296    ///
297    /// In other words this computes `[min(x, rhs.x), min(self.y, rhs.y), ..]`.
298    ///
299    /// NaN propogation does not follow IEEE 754-2008 semantics for minNum and may differ on
300    /// different SIMD architectures.
301    #[inline]
302    #[must_use]
303    pub fn min(self, rhs: Self) -> Self {
304        Self(unsafe { vminq_f32(self.0, rhs.0) })
305    }
306
307    /// Returns a vector containing the maximum values for each element of `self` and `rhs`.
308    ///
309    /// In other words this computes `[max(self.x, rhs.x), max(self.y, rhs.y), ..]`.
310    ///
311    /// NaN propogation does not follow IEEE 754-2008 semantics for maxNum and may differ on
312    /// different SIMD architectures.
313    #[inline]
314    #[must_use]
315    pub fn max(self, rhs: Self) -> Self {
316        Self(unsafe { vmaxq_f32(self.0, rhs.0) })
317    }
318
319    /// Component-wise clamping of values, similar to [`f32::clamp`].
320    ///
321    /// Each element in `min` must be less-or-equal to the corresponding element in `max`.
322    ///
323    /// NaN propogation does not follow IEEE 754-2008 semantics and may differ on
324    /// different SIMD architectures.
325    ///
326    /// # Panics
327    ///
328    /// Will panic if `min` is greater than `max` when `glam_assert` is enabled.
329    #[inline]
330    #[must_use]
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    /// Returns the horizontal minimum of `self`.
337    ///
338    /// In other words this computes `min(x, y, ..)`.
339    ///
340    /// NaN propogation does not follow IEEE 754-2008 semantics and may differ on
341    /// different SIMD architectures.
342    #[inline]
343    #[must_use]
344    pub fn min_element(self) -> f32 {
345        self.x.min(self.y.min(self.z))
346    }
347
348    /// Returns the horizontal maximum of `self`.
349    ///
350    /// In other words this computes `max(x, y, ..)`.
351    ///
352    /// NaN propogation does not follow IEEE 754-2008 semantics and may differ on
353    /// different SIMD architectures.
354    #[inline]
355    #[must_use]
356    pub fn max_element(self) -> f32 {
357        self.x.max(self.y.max(self.z))
358    }
359
360    /// Returns the index of the first minimum element of `self`.
361    #[doc(alias = "argmin")]
362    #[inline]
363    #[must_use]
364    pub fn min_position(self) -> usize {
365        let mut min = self.x;
366        let mut index = 0;
367        if self.y < min {
368            min = self.y;
369            index = 1;
370        }
371        if self.z < min {
372            index = 2;
373        }
374        index
375    }
376
377    /// Returns the index of the first maximum element of `self`.
378    #[doc(alias = "argmax")]
379    #[inline]
380    #[must_use]
381    pub fn max_position(self) -> usize {
382        let mut max = self.x;
383        let mut index = 0;
384        if self.y > max {
385            max = self.y;
386            index = 1;
387        }
388        if self.z > max {
389            index = 2;
390        }
391        index
392    }
393
394    /// Returns the sum of all elements of `self`.
395    ///
396    /// In other words, this computes `self.x + self.y + ..`.
397    #[inline]
398    #[must_use]
399    pub fn element_sum(self) -> f32 {
400        unsafe { vaddvq_f32(vsetq_lane_f32(0.0, self.0, 3)) }
401    }
402
403    /// Returns the product of all elements of `self`.
404    ///
405    /// In other words, this computes `self.x * self.y * ..`.
406    #[inline]
407    #[must_use]
408    pub fn element_product(self) -> f32 {
409        unsafe {
410            let s = vmuls_laneq_f32(vgetq_lane_f32(self.0, 0), self.0, 1);
411            vmuls_laneq_f32(s, self.0, 2)
412        }
413    }
414
415    /// Returns a vector mask containing the result of a `==` comparison for each element of
416    /// `self` and `rhs`.
417    ///
418    /// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all
419    /// elements.
420    #[inline]
421    #[must_use]
422    pub fn cmpeq(self, rhs: Self) -> BVec3A {
423        BVec3A(unsafe { vceqq_f32(self.0, rhs.0) })
424    }
425
426    /// Returns a vector mask containing the result of a `!=` comparison for each element of
427    /// `self` and `rhs`.
428    ///
429    /// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all
430    /// elements.
431    #[inline]
432    #[must_use]
433    pub fn cmpne(self, rhs: Self) -> BVec3A {
434        BVec3A(unsafe { vmvnq_u32(vceqq_f32(self.0, rhs.0)) })
435    }
436
437    /// Returns a vector mask containing the result of a `>=` comparison for each element of
438    /// `self` and `rhs`.
439    ///
440    /// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all
441    /// elements.
442    #[inline]
443    #[must_use]
444    pub fn cmpge(self, rhs: Self) -> BVec3A {
445        BVec3A(unsafe { vcgeq_f32(self.0, rhs.0) })
446    }
447
448    /// Returns a vector mask containing the result of a `>` comparison for each element of
449    /// `self` and `rhs`.
450    ///
451    /// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all
452    /// elements.
453    #[inline]
454    #[must_use]
455    pub fn cmpgt(self, rhs: Self) -> BVec3A {
456        BVec3A(unsafe { vcgtq_f32(self.0, rhs.0) })
457    }
458
459    /// Returns a vector mask containing the result of a `<=` comparison for each element of
460    /// `self` and `rhs`.
461    ///
462    /// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all
463    /// elements.
464    #[inline]
465    #[must_use]
466    pub fn cmple(self, rhs: Self) -> BVec3A {
467        BVec3A(unsafe { vcleq_f32(self.0, rhs.0) })
468    }
469
470    /// Returns a vector mask containing the result of a `<` comparison for each element of
471    /// `self` and `rhs`.
472    ///
473    /// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all
474    /// elements.
475    #[inline]
476    #[must_use]
477    pub fn cmplt(self, rhs: Self) -> BVec3A {
478        BVec3A(unsafe { vcltq_f32(self.0, rhs.0) })
479    }
480
481    /// Returns a vector containing the absolute value of each element of `self`.
482    #[inline]
483    #[must_use]
484    pub fn abs(self) -> Self {
485        Self(unsafe { vabsq_f32(self.0) })
486    }
487
488    /// Returns a vector with elements representing the sign of `self`.
489    ///
490    /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
491    /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
492    /// - `NAN` if the number is `NAN`
493    #[inline]
494    #[must_use]
495    pub fn signum(self) -> Self {
496        let result = Self(unsafe {
497            vreinterpretq_f32_u32(vorrq_u32(
498                vandq_u32(
499                    vreinterpretq_u32_f32(self.0),
500                    vreinterpretq_u32_f32(Self::NEG_ONE.0),
501                ),
502                vreinterpretq_u32_f32(Self::ONE.0),
503            ))
504        });
505        let mask = self.is_nan_mask();
506        Self::select(mask, self, result)
507    }
508
509    /// Returns a vector with signs of `rhs` and the magnitudes of `self`.
510    #[inline]
511    #[must_use]
512    pub fn copysign(self, rhs: Self) -> Self {
513        let mask = Self::splat(-0.0);
514        Self(unsafe {
515            vreinterpretq_f32_u32(vorrq_u32(
516                vandq_u32(vreinterpretq_u32_f32(rhs.0), vreinterpretq_u32_f32(mask.0)),
517                vandq_u32(
518                    vreinterpretq_u32_f32(self.0),
519                    vmvnq_u32(vreinterpretq_u32_f32(mask.0)),
520                ),
521            ))
522        })
523    }
524
525    /// Returns a bitmask with the lowest 3 bits set to the sign bits from the elements of `self`.
526    ///
527    /// A negative element results in a `1` bit and a positive element in a `0` bit.  Element `x` goes
528    /// into the first lowest bit, element `y` into the second, etc.
529    ///
530    /// An element is negative if it has a negative sign, including -0.0, NaNs with negative sign
531    /// bit and negative infinity.
532    #[inline]
533    #[must_use]
534    pub fn is_negative_bitmask(self) -> u32 {
535        unsafe {
536            let nmask = vreinterpretq_u32_f32(vdupq_n_f32(-0.0));
537            let m = vandq_u32(vreinterpretq_u32_f32(self.0), nmask);
538            let x = vgetq_lane_u32(m, 0) >> 31;
539            let y = vgetq_lane_u32(m, 1) >> 31;
540            let z = vgetq_lane_u32(m, 2) >> 31;
541
542            x | y << 1 | z << 2
543        }
544    }
545
546    /// Returns a mask indicating which components are negative.
547    ///
548    /// An element is negative if it has a negative sign, including -0.0, NaNs with negative sign
549    /// bit and negative infinity.
550    #[inline]
551    #[must_use]
552    pub fn is_negative_mask(self) -> BVec3A {
553        BVec3A(unsafe { vcltq_s32(vreinterpretq_s32_f32(self.0), vdupq_n_s32(0)) })
554    }
555
556    /// Returns `true` if, and only if, all elements are finite.  If any element is either
557    /// `NaN`, positive or negative infinity, this will return `false`.
558    #[inline]
559    #[must_use]
560    pub fn is_finite(self) -> bool {
561        self.is_finite_mask().all()
562    }
563
564    /// Performs `is_finite` on each element of self, returning a vector mask of the results.
565    ///
566    /// In other words, this computes `[x.is_finite(), y.is_finite(), ...]`.
567    #[inline]
568    #[must_use]
569    pub fn is_finite_mask(self) -> BVec3A {
570        BVec3A(unsafe { vcltq_f32(vabsq_f32(self.0), Self::INFINITY.0) })
571    }
572
573    /// Returns `true` if any elements are `NaN`.
574    #[inline]
575    #[must_use]
576    pub fn is_nan(self) -> bool {
577        self.is_nan_mask().any()
578    }
579
580    /// Performs `is_nan` on each element of self, returning a vector mask of the results.
581    ///
582    /// In other words, this computes `[x.is_nan(), y.is_nan(), ...]`.
583    #[inline]
584    #[must_use]
585    pub fn is_nan_mask(self) -> BVec3A {
586        BVec3A(unsafe { vmvnq_u32(vceqq_f32(self.0, self.0)) })
587    }
588
589    /// Computes the length of `self`.
590    #[doc(alias = "magnitude")]
591    #[inline]
592    #[must_use]
593    pub fn length(self) -> f32 {
594        math::sqrt(self.dot(self))
595    }
596
597    /// Returns `true` if the vector is not the zero vector (also rejects NaN).
598    #[allow(dead_code)]
599    fn is_non_zero(self) -> bool {
600        self.length_squared() > 0.0
601    }
602
603    /// Computes the squared length of `self`.
604    ///
605    /// This is faster than `length()` as it avoids a square root operation.
606    #[doc(alias = "magnitude2")]
607    #[inline]
608    #[must_use]
609    pub fn length_squared(self) -> f32 {
610        self.dot(self)
611    }
612
613    /// Computes `1.0 / length()`.
614    ///
615    /// For valid results, `self` must _not_ be of length zero.
616    #[inline]
617    #[must_use]
618    pub fn length_recip(self) -> f32 {
619        self.length().recip()
620    }
621
622    /// Computes the Euclidean distance between two points in space.
623    #[inline]
624    #[must_use]
625    pub fn distance(self, rhs: Self) -> f32 {
626        (self - rhs).length()
627    }
628
629    /// Compute the squared euclidean distance between two points in space.
630    #[inline]
631    #[must_use]
632    pub fn distance_squared(self, rhs: Self) -> f32 {
633        (self - rhs).length_squared()
634    }
635
636    /// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`.
637    #[inline]
638    #[must_use]
639    pub fn div_euclid(self, rhs: Self) -> Self {
640        Self::new(
641            math::div_euclid(self.x, rhs.x),
642            math::div_euclid(self.y, rhs.y),
643            math::div_euclid(self.z, rhs.z),
644        )
645    }
646
647    /// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`.
648    ///
649    /// [Euclidean division]: f32::rem_euclid
650    #[inline]
651    #[must_use]
652    pub fn rem_euclid(self, rhs: Self) -> Self {
653        Self::new(
654            math::rem_euclid(self.x, rhs.x),
655            math::rem_euclid(self.y, rhs.y),
656            math::rem_euclid(self.z, rhs.z),
657        )
658    }
659
660    /// Returns `self` normalized to length 1.0.
661    ///
662    /// For valid results, `self` must be finite and _not_ of length zero, nor very close to zero.
663    ///
664    /// See also [`Self::try_normalize()`] and [`Self::normalize_or_zero()`].
665    ///
666    /// # Panics
667    ///
668    /// Will panic if the resulting normalized vector is not finite when `glam_assert` is enabled.
669    #[inline]
670    #[must_use]
671    pub fn normalize(self) -> Self {
672        #[allow(clippy::let_and_return)]
673        let normalized = self.mul(self.length_recip());
674        glam_assert!(normalized.is_finite());
675        normalized
676    }
677
678    /// Returns `self` normalized to length 1.0 if possible, else returns `None`.
679    ///
680    /// In particular, if the input is zero (or very close to zero), or non-finite,
681    /// the result of this operation will be `None`.
682    ///
683    /// See also [`Self::normalize_or_zero()`].
684    #[inline]
685    #[must_use]
686    pub fn try_normalize(self) -> Option<Self> {
687        let rcp = self.length_recip();
688        if rcp.is_finite() && rcp > 0.0 {
689            Some(self * rcp)
690        } else {
691            None
692        }
693    }
694
695    /// Returns `self` normalized to length 1.0 if possible, else returns a
696    /// fallback value.
697    ///
698    /// In particular, if the input is zero (or very close to zero), or non-finite,
699    /// the result of this operation will be the fallback value.
700    ///
701    /// See also [`Self::try_normalize()`].
702    #[inline]
703    #[must_use]
704    pub fn normalize_or(self, fallback: Self) -> Self {
705        let rcp = self.length_recip();
706        if rcp.is_finite() && rcp > 0.0 {
707            self * rcp
708        } else {
709            fallback
710        }
711    }
712
713    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
714    ///
715    /// In particular, if the input is zero (or very close to zero), or non-finite,
716    /// the result of this operation will be zero.
717    ///
718    /// See also [`Self::try_normalize()`].
719    #[inline]
720    #[must_use]
721    pub fn normalize_or_zero(self) -> Self {
722        self.normalize_or(Self::ZERO)
723    }
724
725    /// Returns `self` normalized to length 1.0 and the length of `self`.
726    ///
727    /// If `self` is zero length then `(Self::X, 0.0)` is returned.
728    #[inline]
729    #[must_use]
730    pub fn normalize_and_length(self) -> (Self, f32) {
731        let length = self.length();
732        let rcp = 1.0 / length;
733        if rcp.is_finite() && rcp > 0.0 {
734            (self * rcp, length)
735        } else {
736            (Self::X, 0.0)
737        }
738    }
739
740    /// Returns whether `self` is length `1.0` or not.
741    ///
742    /// Uses a precision threshold of approximately `1e-4`.
743    #[inline]
744    #[must_use]
745    pub fn is_normalized(self) -> bool {
746        math::abs(self.length_squared() - 1.0) <= 2e-4
747    }
748
749    /// Returns the vector projection of `self` onto `rhs`.
750    ///
751    /// `rhs` must be of non-zero length.
752    ///
753    /// # Panics
754    ///
755    /// Will panic if `rhs` is zero length when `glam_assert` is enabled.
756    #[inline]
757    #[must_use]
758    pub fn project_onto(self, rhs: Self) -> Self {
759        let other_len_sq_rcp = rhs.dot(rhs).recip();
760        glam_assert!(other_len_sq_rcp.is_finite());
761        rhs * self.dot(rhs) * other_len_sq_rcp
762    }
763
764    /// Returns the vector rejection of `self` from `rhs`.
765    ///
766    /// The vector rejection is the vector perpendicular to the projection of `self` onto
767    /// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`.
768    ///
769    /// `rhs` must be of non-zero length.
770    ///
771    /// # Panics
772    ///
773    /// Will panic if `rhs` has a length of zero when `glam_assert` is enabled.
774    #[doc(alias("plane"))]
775    #[inline]
776    #[must_use]
777    pub fn reject_from(self, rhs: Self) -> Self {
778        self - self.project_onto(rhs)
779    }
780
781    /// Returns the vector projection of `self` onto `rhs`.
782    ///
783    /// `rhs` must be normalized.
784    ///
785    /// # Panics
786    ///
787    /// Will panic if `rhs` is not normalized when `glam_assert` is enabled.
788    #[inline]
789    #[must_use]
790    pub fn project_onto_normalized(self, rhs: Self) -> Self {
791        glam_assert!(rhs.is_normalized());
792        rhs * self.dot(rhs)
793    }
794
795    /// Returns the vector rejection of `self` from `rhs`.
796    ///
797    /// The vector rejection is the vector perpendicular to the projection of `self` onto
798    /// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`.
799    ///
800    /// `rhs` must be normalized.
801    ///
802    /// # Panics
803    ///
804    /// Will panic if `rhs` is not normalized when `glam_assert` is enabled.
805    #[doc(alias("plane"))]
806    #[inline]
807    #[must_use]
808    pub fn reject_from_normalized(self, rhs: Self) -> Self {
809        self - self.project_onto_normalized(rhs)
810    }
811
812    /// Returns a vector containing the nearest integer to a number for each element of `self`.
813    /// Round half-way cases away from 0.0.
814    #[inline]
815    #[must_use]
816    pub fn round(self) -> Self {
817        Self(unsafe { vrndnq_f32(self.0) })
818    }
819
820    /// Returns a vector containing the largest integer less than or equal to a number for each
821    /// element of `self`.
822    #[inline]
823    #[must_use]
824    pub fn floor(self) -> Self {
825        Self(unsafe { vrndmq_f32(self.0) })
826    }
827
828    /// Returns a vector containing the smallest integer greater than or equal to a number for
829    /// each element of `self`.
830    #[inline]
831    #[must_use]
832    pub fn ceil(self) -> Self {
833        Self(unsafe { vrndpq_f32(self.0) })
834    }
835
836    /// Returns a vector containing the integer part each element of `self`. This means numbers are
837    /// always truncated towards zero.
838    #[inline]
839    #[must_use]
840    pub fn trunc(self) -> Self {
841        Self(unsafe { vrndq_f32(self.0) })
842    }
843
844    /// Returns a vector containing `0.0` if `rhs < self` and 1.0 otherwise.
845    ///
846    /// Similar to glsl's step(edge, x), which translates into edge.step(x)
847    #[inline]
848    #[must_use]
849    pub fn step(self, rhs: Self) -> Self {
850        Self::select(rhs.cmplt(self), Self::ZERO, Self::ONE)
851    }
852
853    /// Returns a vector containing all elements of `self` clamped to the range of `[0, 1]`.
854    #[inline]
855    #[must_use]
856    pub fn saturate(self) -> Self {
857        self.clamp(Self::ZERO, Self::ONE)
858    }
859
860    /// Returns a vector containing the fractional part of the vector as `self - self.trunc()`.
861    ///
862    /// Note that this differs from the GLSL implementation of `fract` which returns
863    /// `self - self.floor()`.
864    ///
865    /// Note that this is fast but not precise for large numbers.
866    #[inline]
867    #[must_use]
868    pub fn fract(self) -> Self {
869        self - self.trunc()
870    }
871
872    /// Returns a vector containing the fractional part of the vector as `self - self.floor()`.
873    ///
874    /// Note that this differs from the Rust implementation of `fract` which returns
875    /// `self - self.trunc()`.
876    ///
877    /// Note that this is fast but not precise for large numbers.
878    #[inline]
879    #[must_use]
880    pub fn fract_gl(self) -> Self {
881        self - self.floor()
882    }
883
884    /// Returns a vector containing `e^self` (the exponential function) for each element of
885    /// `self`.
886    #[inline]
887    #[must_use]
888    pub fn exp(self) -> Self {
889        Self::new(math::exp(self.x), math::exp(self.y), math::exp(self.z))
890    }
891
892    /// Returns a vector containing `2^self` for each element of `self`.
893    #[inline]
894    #[must_use]
895    pub fn exp2(self) -> Self {
896        Self::new(math::exp2(self.x), math::exp2(self.y), math::exp2(self.z))
897    }
898
899    /// Returns a vector containing the natural logarithm for each element of `self`.
900    /// This returns NaN when the element is negative and negative infinity when the element is zero.
901    #[inline]
902    #[must_use]
903    pub fn ln(self) -> Self {
904        Self::new(math::ln(self.x), math::ln(self.y), math::ln(self.z))
905    }
906
907    /// Returns a vector containing the base 2 logarithm for each element of `self`.
908    /// This returns NaN when the element is negative and negative infinity when the element is zero.
909    #[inline]
910    #[must_use]
911    pub fn log2(self) -> Self {
912        Self::new(math::log2(self.x), math::log2(self.y), math::log2(self.z))
913    }
914
915    /// Returns a vector containing each element of `self` raised to the power of `n`.
916    #[inline]
917    #[must_use]
918    pub fn powf(self, n: f32) -> Self {
919        Self::new(
920            math::powf(self.x, n),
921            math::powf(self.y, n),
922            math::powf(self.z, n),
923        )
924    }
925
926    /// Returns a vector containing the square root for each element of `self`.
927    /// This returns NaN when the element is negative.
928    #[inline]
929    #[must_use]
930    pub fn sqrt(self) -> Self {
931        Self::new(math::sqrt(self.x), math::sqrt(self.y), math::sqrt(self.z))
932    }
933
934    /// Returns a vector containing the cosine for each element of `self`.
935    #[inline]
936    #[must_use]
937    pub fn cos(self) -> Self {
938        Self::new(math::cos(self.x), math::cos(self.y), math::cos(self.z))
939    }
940
941    /// Returns a vector containing the sine for each element of `self`.
942    #[inline]
943    #[must_use]
944    pub fn sin(self) -> Self {
945        Self::new(math::sin(self.x), math::sin(self.y), math::sin(self.z))
946    }
947
948    /// Returns a tuple of two vectors containing the sine and cosine for each element of `self`.
949    #[inline]
950    #[must_use]
951    pub fn sin_cos(self) -> (Self, Self) {
952        let (sin_x, cos_x) = math::sin_cos(self.x);
953        let (sin_y, cos_y) = math::sin_cos(self.y);
954        let (sin_z, cos_z) = math::sin_cos(self.z);
955
956        (
957            Self::new(sin_x, sin_y, sin_z),
958            Self::new(cos_x, cos_y, cos_z),
959        )
960    }
961
962    /// Returns a vector containing the reciprocal `1.0/n` of each element of `self`.
963    #[inline]
964    #[must_use]
965    pub fn recip(self) -> Self {
966        Self(unsafe { vdivq_f32(Self::ONE.0, self.0) })
967    }
968
969    /// Performs a linear interpolation between `self` and `rhs` based on the value `s`.
970    ///
971    /// When `s` is `0.0`, the result will be equal to `self`.  When `s` is `1.0`, the result
972    /// will be equal to `rhs`. When `s` is outside of range `[0, 1]`, the result is linearly
973    /// extrapolated.
974    #[doc(alias = "mix")]
975    #[inline]
976    #[must_use]
977    pub fn lerp(self, rhs: Self, s: f32) -> Self {
978        self * (1.0 - s) + rhs * s
979    }
980
981    /// Moves towards `rhs` based on the value `d`.
982    ///
983    /// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to
984    /// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`.
985    #[inline]
986    #[must_use]
987    pub fn move_towards(self, rhs: Self, d: f32) -> Self {
988        let a = rhs - self;
989        let len = a.length();
990        if len <= d || len <= 1e-4 {
991            return rhs;
992        }
993        self + a / len * d
994    }
995
996    /// Calculates the midpoint between `self` and `rhs`.
997    ///
998    /// The midpoint is the average of, or halfway point between, two vectors.
999    /// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)`
1000    /// while being slightly cheaper to compute.
1001    #[inline]
1002    pub fn midpoint(self, rhs: Self) -> Self {
1003        (self + rhs) * 0.5
1004    }
1005
1006    /// Returns true if the absolute difference of all elements between `self` and `rhs` is
1007    /// less than or equal to `max_abs_diff`.
1008    ///
1009    /// This can be used to compare if two vectors contain similar elements. It works best when
1010    /// comparing with a known value. The `max_abs_diff` that should be used used depends on
1011    /// the values being compared against.
1012    ///
1013    /// For more see
1014    /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
1015    #[inline]
1016    #[must_use]
1017    pub fn abs_diff_eq(self, rhs: Self, max_abs_diff: f32) -> bool {
1018        self.sub(rhs).abs().cmple(Self::splat(max_abs_diff)).all()
1019    }
1020
1021    /// Returns a vector with a length no less than `min` and no more than `max`.
1022    ///
1023    /// # Panics
1024    ///
1025    /// Will panic if `min` is greater than `max`, or if either `min` or `max` is negative, when `glam_assert` is enabled.
1026    #[inline]
1027    #[must_use]
1028    pub fn clamp_length(self, min: f32, max: f32) -> Self {
1029        glam_assert!(0.0 <= min);
1030        glam_assert!(min <= max);
1031        let length_sq = self.length_squared();
1032        if length_sq < min * min {
1033            min * (self / math::sqrt(length_sq))
1034        } else if length_sq > max * max {
1035            max * (self / math::sqrt(length_sq))
1036        } else {
1037            self
1038        }
1039    }
1040
1041    /// Returns a vector with a length no more than `max`.
1042    ///
1043    /// # Panics
1044    ///
1045    /// Will panic if `max` is negative when `glam_assert` is enabled.
1046    #[inline]
1047    #[must_use]
1048    pub fn clamp_length_max(self, max: f32) -> Self {
1049        glam_assert!(0.0 <= max);
1050        let length_sq = self.length_squared();
1051        if length_sq > max * max {
1052            max * (self / math::sqrt(length_sq))
1053        } else {
1054            self
1055        }
1056    }
1057
1058    /// Returns a vector with a length no less than `min`.
1059    ///
1060    /// # Panics
1061    ///
1062    /// Will panic if `min` is negative when `glam_assert` is enabled.
1063    #[inline]
1064    #[must_use]
1065    pub fn clamp_length_min(self, min: f32) -> Self {
1066        glam_assert!(0.0 <= min);
1067        let length_sq = self.length_squared();
1068        if length_sq < min * min {
1069            min * (self / math::sqrt(length_sq))
1070        } else {
1071            self
1072        }
1073    }
1074
1075    /// Fused multiply-add. Computes `(self * a) + b` element-wise with only one rounding
1076    /// error, yielding a more accurate result than an unfused multiply-add.
1077    ///
1078    /// Using `mul_add` *may* be more performant than an unfused multiply-add if the target
1079    /// architecture has a dedicated fma CPU instruction. However, this is not always true,
1080    /// and will be heavily dependant on designing algorithms with specific target hardware in
1081    /// mind.
1082    #[inline]
1083    #[must_use]
1084    pub fn mul_add(self, a: Self, b: Self) -> Self {
1085        Self(unsafe { vfmaq_f32(b.0, self.0, a.0) })
1086    }
1087
1088    /// Returns the reflection vector for a given incident vector `self` and surface normal
1089    /// `normal`.
1090    ///
1091    /// `normal` must be normalized.
1092    ///
1093    /// # Panics
1094    ///
1095    /// Will panic if `normal` is not normalized when `glam_assert` is enabled.
1096    #[inline]
1097    #[must_use]
1098    pub fn reflect(self, normal: Self) -> Self {
1099        glam_assert!(normal.is_normalized());
1100        self - 2.0 * self.dot(normal) * normal
1101    }
1102
1103    /// Returns the refraction direction for a given incident vector `self`, surface normal
1104    /// `normal` and ratio of indices of refraction, `eta`. When total internal reflection occurs,
1105    /// a zero vector will be returned.
1106    ///
1107    /// `self` and `normal` must be normalized.
1108    ///
1109    /// # Panics
1110    ///
1111    /// Will panic if `self` or `normal` is not normalized when `glam_assert` is enabled.
1112    #[inline]
1113    #[must_use]
1114    pub fn refract(self, normal: Self, eta: f32) -> Self {
1115        glam_assert!(self.is_normalized());
1116        glam_assert!(normal.is_normalized());
1117        let n_dot_i = normal.dot(self);
1118        let k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i);
1119        if k >= 0.0 {
1120            eta * self - (eta * n_dot_i + math::sqrt(k)) * normal
1121        } else {
1122            Self::ZERO
1123        }
1124    }
1125
1126    /// Returns the angle (in radians) between two vectors in the range `[0, +Ï€]`.
1127    ///
1128    /// For the full rotation between two vectors as a quaternion, see
1129    /// [`Quat::from_rotation_arc`].
1130    ///
1131    /// The inputs do not need to be unit vectors however they must be non-zero.
1132    ///
1133    /// # Panics
1134    ///
1135    /// Will panic if `self` or `rhs` has zero length when `glam_assert` is enabled.
1136    #[inline]
1137    #[must_use]
1138    pub fn angle_between(self, rhs: Self) -> f32 {
1139        glam_assert!(self.is_non_zero());
1140        glam_assert!(rhs.is_non_zero());
1141        math::acos_approx(
1142            self.dot(rhs)
1143                .div(math::sqrt(self.length_squared().mul(rhs.length_squared()))),
1144        )
1145    }
1146
1147    /// Returns the signed angle (in radians) from `self` to `rhs` around `axis`
1148    /// in the range `[-Ï€, +Ï€]`.
1149    ///
1150    /// The `axis` must be a unit vector. The angle follows the right-hand rule
1151    /// around `axis` and can be used with [`Self::rotate_axis`], e.g.
1152    /// `self.rotate_axis(axis, self.angle_to(rhs, axis))` will be equal to `rhs`.
1153    ///
1154    /// For the unsigned angle without a reference axis, see [`Self::angle_between`].
1155    ///
1156    /// The inputs do not need to be unit vectors however they must be non-zero.
1157    ///
1158    /// # Panics
1159    ///
1160    /// Will panic if `axis` is not normalized when `glam_assert` is enabled.
1161    /// Will panic if `self` or `rhs` has zero length when `glam_assert` is enabled.
1162    #[doc(alias = "signed_angle")]
1163    #[inline]
1164    #[must_use]
1165    pub fn angle_to(self, rhs: Self, axis: Self) -> f32 {
1166        glam_assert!(axis.is_normalized());
1167        glam_assert!(self.is_non_zero());
1168        glam_assert!(rhs.is_non_zero());
1169        math::atan2(self.cross(rhs).dot(axis), self.dot(rhs))
1170    }
1171
1172    /// Rotates around the x axis by `angle` (in radians).
1173    #[inline]
1174    #[must_use]
1175    pub fn rotate_x(self, angle: f32) -> Self {
1176        let (sina, cosa) = math::sin_cos(angle);
1177        Self::new(
1178            self.x,
1179            self.y * cosa - self.z * sina,
1180            self.y * sina + self.z * cosa,
1181        )
1182    }
1183
1184    /// Rotates around the y axis by `angle` (in radians).
1185    #[inline]
1186    #[must_use]
1187    pub fn rotate_y(self, angle: f32) -> Self {
1188        let (sina, cosa) = math::sin_cos(angle);
1189        Self::new(
1190            self.x * cosa + self.z * sina,
1191            self.y,
1192            self.x * -sina + self.z * cosa,
1193        )
1194    }
1195
1196    /// Rotates around the z axis by `angle` (in radians).
1197    #[inline]
1198    #[must_use]
1199    pub fn rotate_z(self, angle: f32) -> Self {
1200        let (sina, cosa) = math::sin_cos(angle);
1201        Self::new(
1202            self.x * cosa - self.y * sina,
1203            self.x * sina + self.y * cosa,
1204            self.z,
1205        )
1206    }
1207
1208    /// Rotates around `axis` by `angle` (in radians).
1209    ///
1210    /// The axis must be a unit vector.
1211    ///
1212    /// # Panics
1213    ///
1214    /// Will panic if `axis` is not normalized when `glam_assert` is enabled.
1215    #[inline]
1216    #[must_use]
1217    pub fn rotate_axis(self, axis: Self, angle: f32) -> Self {
1218        Quat::from_axis_angle(axis.into(), angle) * self
1219    }
1220
1221    /// Rotates towards `rhs` up to `max_angle` (in radians).
1222    ///
1223    /// When `max_angle` is `0.0`, the result will be equal to `self`. When `max_angle` is equal to
1224    /// `self.angle_between(rhs)`, the result will be parallel to `rhs`. If `max_angle` is negative,
1225    /// rotates towards the exact opposite of `rhs`. Will not go past the target.
1226    #[inline]
1227    #[must_use]
1228    pub fn rotate_towards(self, rhs: Self, max_angle: f32) -> Self {
1229        let angle_between = self.angle_between(rhs);
1230        // When `max_angle < 0`, rotate no further than `PI` radians away
1231        let angle = max_angle.clamp(angle_between - core::f32::consts::PI, angle_between);
1232        let axis = self
1233            .cross(rhs)
1234            .try_normalize()
1235            .unwrap_or_else(|| self.any_orthogonal_vector().normalize());
1236        Quat::from_axis_angle(axis.into(), angle) * self
1237    }
1238
1239    /// Returns some vector that is orthogonal to the given one.
1240    ///
1241    /// The input vector must be finite and non-zero.
1242    ///
1243    /// The output vector is not necessarily unit length. For that use
1244    /// [`Self::any_orthonormal_vector()`] instead.
1245    #[inline]
1246    #[must_use]
1247    pub fn any_orthogonal_vector(self) -> Self {
1248        // This can probably be optimized
1249        if math::abs(self.x) > math::abs(self.y) {
1250            Self::new(-self.z, 0.0, self.x) // self.cross(Self::Y)
1251        } else {
1252            Self::new(0.0, self.z, -self.y) // self.cross(Self::X)
1253        }
1254    }
1255
1256    /// Returns any unit vector that is orthogonal to the given one.
1257    ///
1258    /// The input vector must be unit length.
1259    ///
1260    /// # Panics
1261    ///
1262    /// Will panic if `self` is not normalized when `glam_assert` is enabled.
1263    #[inline]
1264    #[must_use]
1265    pub fn any_orthonormal_vector(self) -> Self {
1266        glam_assert!(self.is_normalized());
1267        // From https://graphics.pixar.com/library/OrthonormalB/paper.pdf
1268        let sign = math::signum(self.z);
1269        let a = -1.0 / (sign + self.z);
1270        let b = self.x * self.y * a;
1271        Self::new(b, sign + self.y * self.y * a, -self.y)
1272    }
1273
1274    /// Given a unit vector return two other vectors that together form a right-handed orthonormal
1275    /// basis. That is, all three vectors are orthogonal to each other and are normalized.
1276    ///
1277    /// # Panics
1278    ///
1279    /// Will panic if `self` is not normalized when `glam_assert` is enabled.
1280    #[inline]
1281    #[must_use]
1282    pub fn any_orthonormal_pair(self) -> (Self, Self) {
1283        glam_assert!(self.is_normalized());
1284        // From https://graphics.pixar.com/library/OrthonormalB/paper.pdf
1285        let sign = math::signum(self.z);
1286        let a = -1.0 / (sign + self.z);
1287        let b = self.x * self.y * a;
1288        (
1289            Self::new(1.0 + sign * self.x * self.x * a, sign * b, -sign * self.x),
1290            Self::new(b, sign + self.y * self.y * a, -self.y),
1291        )
1292    }
1293
1294    /// Performs a spherical linear interpolation between `self` and `rhs` based on the value `s`.
1295    ///
1296    /// When `s` is `0.0`, the result will be equal to `self`.  When `s` is `1.0`, the result
1297    /// will be equal to `rhs`. When `s` is outside of range `[0, 1]`, the result is linearly
1298    /// extrapolated.
1299    #[inline]
1300    #[must_use]
1301    pub fn slerp(self, rhs: Self, s: f32) -> Self {
1302        let self_length = self.length();
1303        let rhs_length = rhs.length();
1304        // Cosine of the angle between the vectors [-1, 1], or NaN if either vector has a zero length
1305        let dot = self.dot(rhs) / (self_length * rhs_length);
1306        // If dot is close to 1 or -1, or is NaN the calculations for t1 and t2 break down
1307        if math::abs(dot) < 1.0 - 3e-7 {
1308            // Angle between the vectors [0, +Ï€]
1309            let theta = math::acos_approx(dot);
1310            // Sine of the angle between vectors [0, 1]
1311            let sin_theta = math::sin(theta);
1312            let t1 = math::sin(theta * (1.0 - s));
1313            let t2 = math::sin(theta * s);
1314
1315            // Interpolate vector lengths
1316            let result_length = self_length.lerp(rhs_length, s);
1317            // Scale the vectors to the target length and interpolate them
1318            return (self * (result_length / self_length) * t1
1319                + rhs * (result_length / rhs_length) * t2)
1320                * sin_theta.recip();
1321        }
1322        if dot < 0.0 {
1323            // Vectors are almost parallel in opposing directions
1324
1325            // Create a rotation from self to rhs along some axis
1326            let axis = self.any_orthogonal_vector().normalize().into();
1327            let rotation = Quat::from_axis_angle(axis, core::f32::consts::PI * s);
1328            // Interpolate vector lengths
1329            let result_length = self_length.lerp(rhs_length, s);
1330            rotation * self * (result_length / self_length)
1331        } else {
1332            // Vectors are almost parallel in the same direction, or dot was NaN
1333            self.lerp(rhs, s)
1334        }
1335    }
1336
1337    /// Casts all elements of `self` to `f64`.
1338    #[cfg(feature = "f64")]
1339    #[inline]
1340    #[must_use]
1341    pub fn as_dvec3(self) -> crate::DVec3 {
1342        crate::DVec3::new(self.x as f64, self.y as f64, self.z as f64)
1343    }
1344
1345    /// Casts all elements of `self` to `i8`.
1346    #[cfg(feature = "i8")]
1347    #[inline]
1348    #[must_use]
1349    pub fn as_i8vec3(self) -> crate::I8Vec3 {
1350        crate::I8Vec3::new(self.x as i8, self.y as i8, self.z as i8)
1351    }
1352
1353    /// Casts all elements of `self` to `u8`.
1354    #[cfg(feature = "u8")]
1355    #[inline]
1356    #[must_use]
1357    pub fn as_u8vec3(self) -> crate::U8Vec3 {
1358        crate::U8Vec3::new(self.x as u8, self.y as u8, self.z as u8)
1359    }
1360
1361    /// Casts all elements of `self` to `i16`.
1362    #[cfg(feature = "i16")]
1363    #[inline]
1364    #[must_use]
1365    pub fn as_i16vec3(self) -> crate::I16Vec3 {
1366        crate::I16Vec3::new(self.x as i16, self.y as i16, self.z as i16)
1367    }
1368
1369    /// Casts all elements of `self` to `u16`.
1370    #[cfg(feature = "u16")]
1371    #[inline]
1372    #[must_use]
1373    pub fn as_u16vec3(self) -> crate::U16Vec3 {
1374        crate::U16Vec3::new(self.x as u16, self.y as u16, self.z as u16)
1375    }
1376
1377    /// Casts all elements of `self` to `i32`.
1378    #[cfg(feature = "i32")]
1379    #[inline]
1380    #[must_use]
1381    pub fn as_ivec3(self) -> crate::IVec3 {
1382        crate::IVec3::new(self.x as i32, self.y as i32, self.z as i32)
1383    }
1384
1385    /// Casts all elements of `self` to `u32`.
1386    #[cfg(feature = "u32")]
1387    #[inline]
1388    #[must_use]
1389    pub fn as_uvec3(self) -> crate::UVec3 {
1390        crate::UVec3::new(self.x as u32, self.y as u32, self.z as u32)
1391    }
1392
1393    /// Casts all elements of `self` to `i64`.
1394    #[cfg(feature = "i64")]
1395    #[inline]
1396    #[must_use]
1397    pub fn as_i64vec3(self) -> crate::I64Vec3 {
1398        crate::I64Vec3::new(self.x as i64, self.y as i64, self.z as i64)
1399    }
1400
1401    /// Casts all elements of `self` to `u64`.
1402    #[cfg(feature = "u64")]
1403    #[inline]
1404    #[must_use]
1405    pub fn as_u64vec3(self) -> crate::U64Vec3 {
1406        crate::U64Vec3::new(self.x as u64, self.y as u64, self.z as u64)
1407    }
1408
1409    /// Casts all elements of `self` to `isize`.
1410    #[cfg(feature = "isize")]
1411    #[inline]
1412    #[must_use]
1413    pub fn as_isizevec3(self) -> crate::ISizeVec3 {
1414        crate::ISizeVec3::new(self.x as isize, self.y as isize, self.z as isize)
1415    }
1416
1417    /// Casts all elements of `self` to `usize`.
1418    #[cfg(feature = "usize")]
1419    #[inline]
1420    #[must_use]
1421    pub fn as_usizevec3(self) -> crate::USizeVec3 {
1422        crate::USizeVec3::new(self.x as usize, self.y as usize, self.z as usize)
1423    }
1424}
1425
1426impl Default for Vec3A {
1427    #[inline(always)]
1428    fn default() -> Self {
1429        Self::ZERO
1430    }
1431}
1432
1433impl PartialEq for Vec3A {
1434    #[inline]
1435    fn eq(&self, rhs: &Self) -> bool {
1436        self.cmpeq(*rhs).all()
1437    }
1438}
1439
1440impl Div for Vec3A {
1441    type Output = Self;
1442    #[inline]
1443    fn div(self, rhs: Self) -> Self {
1444        Self(unsafe { vdivq_f32(self.0, rhs.0) })
1445    }
1446}
1447
1448impl Div<&Self> for Vec3A {
1449    type Output = Self;
1450    #[inline]
1451    fn div(self, rhs: &Self) -> Self {
1452        self.div(*rhs)
1453    }
1454}
1455
1456impl Div<&Vec3A> for &Vec3A {
1457    type Output = Vec3A;
1458    #[inline]
1459    fn div(self, rhs: &Vec3A) -> Vec3A {
1460        (*self).div(*rhs)
1461    }
1462}
1463
1464impl Div<Vec3A> for &Vec3A {
1465    type Output = Vec3A;
1466    #[inline]
1467    fn div(self, rhs: Vec3A) -> Vec3A {
1468        (*self).div(rhs)
1469    }
1470}
1471
1472impl DivAssign for Vec3A {
1473    #[inline]
1474    fn div_assign(&mut self, rhs: Self) {
1475        self.0 = unsafe { vdivq_f32(self.0, rhs.0) };
1476    }
1477}
1478
1479impl DivAssign<&Self> for Vec3A {
1480    #[inline]
1481    fn div_assign(&mut self, rhs: &Self) {
1482        self.div_assign(*rhs);
1483    }
1484}
1485
1486impl Div<f32> for Vec3A {
1487    type Output = Self;
1488    #[inline]
1489    fn div(self, rhs: f32) -> Self {
1490        Self(unsafe { vdivq_f32(self.0, vld1q_dup_f32(&rhs)) })
1491    }
1492}
1493
1494impl Div<&f32> for Vec3A {
1495    type Output = Self;
1496    #[inline]
1497    fn div(self, rhs: &f32) -> Self {
1498        self.div(*rhs)
1499    }
1500}
1501
1502impl Div<&f32> for &Vec3A {
1503    type Output = Vec3A;
1504    #[inline]
1505    fn div(self, rhs: &f32) -> Vec3A {
1506        (*self).div(*rhs)
1507    }
1508}
1509
1510impl Div<f32> for &Vec3A {
1511    type Output = Vec3A;
1512    #[inline]
1513    fn div(self, rhs: f32) -> Vec3A {
1514        (*self).div(rhs)
1515    }
1516}
1517
1518impl DivAssign<f32> for Vec3A {
1519    #[inline]
1520    fn div_assign(&mut self, rhs: f32) {
1521        self.0 = unsafe { vdivq_f32(self.0, vld1q_dup_f32(&rhs)) };
1522    }
1523}
1524
1525impl DivAssign<&f32> for Vec3A {
1526    #[inline]
1527    fn div_assign(&mut self, rhs: &f32) {
1528        self.div_assign(*rhs);
1529    }
1530}
1531
1532impl Div<Vec3A> for f32 {
1533    type Output = Vec3A;
1534    #[inline]
1535    fn div(self, rhs: Vec3A) -> Vec3A {
1536        Vec3A(unsafe { vdivq_f32(vld1q_dup_f32(&self), rhs.0) })
1537    }
1538}
1539
1540impl Div<&Vec3A> for f32 {
1541    type Output = Vec3A;
1542    #[inline]
1543    fn div(self, rhs: &Vec3A) -> Vec3A {
1544        self.div(*rhs)
1545    }
1546}
1547
1548impl Div<&Vec3A> for &f32 {
1549    type Output = Vec3A;
1550    #[inline]
1551    fn div(self, rhs: &Vec3A) -> Vec3A {
1552        (*self).div(*rhs)
1553    }
1554}
1555
1556impl Div<Vec3A> for &f32 {
1557    type Output = Vec3A;
1558    #[inline]
1559    fn div(self, rhs: Vec3A) -> Vec3A {
1560        (*self).div(rhs)
1561    }
1562}
1563
1564impl Mul for Vec3A {
1565    type Output = Self;
1566    #[inline]
1567    fn mul(self, rhs: Self) -> Self {
1568        Self(unsafe { vmulq_f32(self.0, rhs.0) })
1569    }
1570}
1571
1572impl Mul<&Self> for Vec3A {
1573    type Output = Self;
1574    #[inline]
1575    fn mul(self, rhs: &Self) -> Self {
1576        self.mul(*rhs)
1577    }
1578}
1579
1580impl Mul<&Vec3A> for &Vec3A {
1581    type Output = Vec3A;
1582    #[inline]
1583    fn mul(self, rhs: &Vec3A) -> Vec3A {
1584        (*self).mul(*rhs)
1585    }
1586}
1587
1588impl Mul<Vec3A> for &Vec3A {
1589    type Output = Vec3A;
1590    #[inline]
1591    fn mul(self, rhs: Vec3A) -> Vec3A {
1592        (*self).mul(rhs)
1593    }
1594}
1595
1596impl MulAssign for Vec3A {
1597    #[inline]
1598    fn mul_assign(&mut self, rhs: Self) {
1599        self.0 = unsafe { vmulq_f32(self.0, rhs.0) };
1600    }
1601}
1602
1603impl MulAssign<&Self> for Vec3A {
1604    #[inline]
1605    fn mul_assign(&mut self, rhs: &Self) {
1606        self.mul_assign(*rhs);
1607    }
1608}
1609
1610impl Mul<f32> for Vec3A {
1611    type Output = Self;
1612    #[inline]
1613    fn mul(self, rhs: f32) -> Self {
1614        Self(unsafe { vmulq_n_f32(self.0, rhs) })
1615    }
1616}
1617
1618impl Mul<&f32> for Vec3A {
1619    type Output = Self;
1620    #[inline]
1621    fn mul(self, rhs: &f32) -> Self {
1622        self.mul(*rhs)
1623    }
1624}
1625
1626impl Mul<&f32> for &Vec3A {
1627    type Output = Vec3A;
1628    #[inline]
1629    fn mul(self, rhs: &f32) -> Vec3A {
1630        (*self).mul(*rhs)
1631    }
1632}
1633
1634impl Mul<f32> for &Vec3A {
1635    type Output = Vec3A;
1636    #[inline]
1637    fn mul(self, rhs: f32) -> Vec3A {
1638        (*self).mul(rhs)
1639    }
1640}
1641
1642impl MulAssign<f32> for Vec3A {
1643    #[inline]
1644    fn mul_assign(&mut self, rhs: f32) {
1645        self.0 = unsafe { vmulq_n_f32(self.0, rhs) };
1646    }
1647}
1648
1649impl MulAssign<&f32> for Vec3A {
1650    #[inline]
1651    fn mul_assign(&mut self, rhs: &f32) {
1652        self.mul_assign(*rhs);
1653    }
1654}
1655
1656impl Mul<Vec3A> for f32 {
1657    type Output = Vec3A;
1658    #[inline]
1659    fn mul(self, rhs: Vec3A) -> Vec3A {
1660        Vec3A(unsafe { vmulq_n_f32(rhs.0, self) })
1661    }
1662}
1663
1664impl Mul<&Vec3A> for f32 {
1665    type Output = Vec3A;
1666    #[inline]
1667    fn mul(self, rhs: &Vec3A) -> Vec3A {
1668        self.mul(*rhs)
1669    }
1670}
1671
1672impl Mul<&Vec3A> for &f32 {
1673    type Output = Vec3A;
1674    #[inline]
1675    fn mul(self, rhs: &Vec3A) -> Vec3A {
1676        (*self).mul(*rhs)
1677    }
1678}
1679
1680impl Mul<Vec3A> for &f32 {
1681    type Output = Vec3A;
1682    #[inline]
1683    fn mul(self, rhs: Vec3A) -> Vec3A {
1684        (*self).mul(rhs)
1685    }
1686}
1687
1688impl Add for Vec3A {
1689    type Output = Self;
1690    #[inline]
1691    fn add(self, rhs: Self) -> Self {
1692        Self(unsafe { vaddq_f32(self.0, rhs.0) })
1693    }
1694}
1695
1696impl Add<&Self> for Vec3A {
1697    type Output = Self;
1698    #[inline]
1699    fn add(self, rhs: &Self) -> Self {
1700        self.add(*rhs)
1701    }
1702}
1703
1704impl Add<&Vec3A> for &Vec3A {
1705    type Output = Vec3A;
1706    #[inline]
1707    fn add(self, rhs: &Vec3A) -> Vec3A {
1708        (*self).add(*rhs)
1709    }
1710}
1711
1712impl Add<Vec3A> for &Vec3A {
1713    type Output = Vec3A;
1714    #[inline]
1715    fn add(self, rhs: Vec3A) -> Vec3A {
1716        (*self).add(rhs)
1717    }
1718}
1719
1720impl AddAssign for Vec3A {
1721    #[inline]
1722    fn add_assign(&mut self, rhs: Self) {
1723        self.0 = unsafe { vaddq_f32(self.0, rhs.0) };
1724    }
1725}
1726
1727impl AddAssign<&Self> for Vec3A {
1728    #[inline]
1729    fn add_assign(&mut self, rhs: &Self) {
1730        self.add_assign(*rhs);
1731    }
1732}
1733
1734impl Add<f32> for Vec3A {
1735    type Output = Self;
1736    #[inline]
1737    fn add(self, rhs: f32) -> Self {
1738        Self(unsafe { vaddq_f32(self.0, vld1q_dup_f32(&rhs)) })
1739    }
1740}
1741
1742impl Add<&f32> for Vec3A {
1743    type Output = Self;
1744    #[inline]
1745    fn add(self, rhs: &f32) -> Self {
1746        self.add(*rhs)
1747    }
1748}
1749
1750impl Add<&f32> for &Vec3A {
1751    type Output = Vec3A;
1752    #[inline]
1753    fn add(self, rhs: &f32) -> Vec3A {
1754        (*self).add(*rhs)
1755    }
1756}
1757
1758impl Add<f32> for &Vec3A {
1759    type Output = Vec3A;
1760    #[inline]
1761    fn add(self, rhs: f32) -> Vec3A {
1762        (*self).add(rhs)
1763    }
1764}
1765
1766impl AddAssign<f32> for Vec3A {
1767    #[inline]
1768    fn add_assign(&mut self, rhs: f32) {
1769        self.0 = unsafe { vaddq_f32(self.0, vld1q_dup_f32(&rhs)) };
1770    }
1771}
1772
1773impl AddAssign<&f32> for Vec3A {
1774    #[inline]
1775    fn add_assign(&mut self, rhs: &f32) {
1776        self.add_assign(*rhs);
1777    }
1778}
1779
1780impl Add<Vec3A> for f32 {
1781    type Output = Vec3A;
1782    #[inline]
1783    fn add(self, rhs: Vec3A) -> Vec3A {
1784        Vec3A(unsafe { vaddq_f32(vld1q_dup_f32(&self), rhs.0) })
1785    }
1786}
1787
1788impl Add<&Vec3A> for f32 {
1789    type Output = Vec3A;
1790    #[inline]
1791    fn add(self, rhs: &Vec3A) -> Vec3A {
1792        self.add(*rhs)
1793    }
1794}
1795
1796impl Add<&Vec3A> for &f32 {
1797    type Output = Vec3A;
1798    #[inline]
1799    fn add(self, rhs: &Vec3A) -> Vec3A {
1800        (*self).add(*rhs)
1801    }
1802}
1803
1804impl Add<Vec3A> for &f32 {
1805    type Output = Vec3A;
1806    #[inline]
1807    fn add(self, rhs: Vec3A) -> Vec3A {
1808        (*self).add(rhs)
1809    }
1810}
1811
1812impl Sub for Vec3A {
1813    type Output = Self;
1814    #[inline]
1815    fn sub(self, rhs: Self) -> Self {
1816        Self(unsafe { vsubq_f32(self.0, rhs.0) })
1817    }
1818}
1819
1820impl Sub<&Self> for Vec3A {
1821    type Output = Self;
1822    #[inline]
1823    fn sub(self, rhs: &Self) -> Self {
1824        self.sub(*rhs)
1825    }
1826}
1827
1828impl Sub<&Vec3A> for &Vec3A {
1829    type Output = Vec3A;
1830    #[inline]
1831    fn sub(self, rhs: &Vec3A) -> Vec3A {
1832        (*self).sub(*rhs)
1833    }
1834}
1835
1836impl Sub<Vec3A> for &Vec3A {
1837    type Output = Vec3A;
1838    #[inline]
1839    fn sub(self, rhs: Vec3A) -> Vec3A {
1840        (*self).sub(rhs)
1841    }
1842}
1843
1844impl SubAssign for Vec3A {
1845    #[inline]
1846    fn sub_assign(&mut self, rhs: Self) {
1847        self.0 = unsafe { vsubq_f32(self.0, rhs.0) };
1848    }
1849}
1850
1851impl SubAssign<&Self> for Vec3A {
1852    #[inline]
1853    fn sub_assign(&mut self, rhs: &Self) {
1854        self.sub_assign(*rhs);
1855    }
1856}
1857
1858impl Sub<f32> for Vec3A {
1859    type Output = Self;
1860    #[inline]
1861    fn sub(self, rhs: f32) -> Self {
1862        Self(unsafe { vsubq_f32(self.0, vld1q_dup_f32(&rhs)) })
1863    }
1864}
1865
1866impl Sub<&f32> for Vec3A {
1867    type Output = Self;
1868    #[inline]
1869    fn sub(self, rhs: &f32) -> Self {
1870        self.sub(*rhs)
1871    }
1872}
1873
1874impl Sub<&f32> for &Vec3A {
1875    type Output = Vec3A;
1876    #[inline]
1877    fn sub(self, rhs: &f32) -> Vec3A {
1878        (*self).sub(*rhs)
1879    }
1880}
1881
1882impl Sub<f32> for &Vec3A {
1883    type Output = Vec3A;
1884    #[inline]
1885    fn sub(self, rhs: f32) -> Vec3A {
1886        (*self).sub(rhs)
1887    }
1888}
1889
1890impl SubAssign<f32> for Vec3A {
1891    #[inline]
1892    fn sub_assign(&mut self, rhs: f32) {
1893        self.0 = unsafe { vsubq_f32(self.0, vld1q_dup_f32(&rhs)) };
1894    }
1895}
1896
1897impl SubAssign<&f32> for Vec3A {
1898    #[inline]
1899    fn sub_assign(&mut self, rhs: &f32) {
1900        self.sub_assign(*rhs);
1901    }
1902}
1903
1904impl Sub<Vec3A> for f32 {
1905    type Output = Vec3A;
1906    #[inline]
1907    fn sub(self, rhs: Vec3A) -> Vec3A {
1908        Vec3A(unsafe { vsubq_f32(vld1q_dup_f32(&self), rhs.0) })
1909    }
1910}
1911
1912impl Sub<&Vec3A> for f32 {
1913    type Output = Vec3A;
1914    #[inline]
1915    fn sub(self, rhs: &Vec3A) -> Vec3A {
1916        self.sub(*rhs)
1917    }
1918}
1919
1920impl Sub<&Vec3A> for &f32 {
1921    type Output = Vec3A;
1922    #[inline]
1923    fn sub(self, rhs: &Vec3A) -> Vec3A {
1924        (*self).sub(*rhs)
1925    }
1926}
1927
1928impl Sub<Vec3A> for &f32 {
1929    type Output = Vec3A;
1930    #[inline]
1931    fn sub(self, rhs: Vec3A) -> Vec3A {
1932        (*self).sub(rhs)
1933    }
1934}
1935
1936impl Rem for Vec3A {
1937    type Output = Self;
1938    #[inline]
1939    fn rem(self, rhs: Self) -> Self {
1940        unsafe {
1941            let n = vrndmq_f32(vdivq_f32(self.0, rhs.0));
1942            Self(vsubq_f32(self.0, vmulq_f32(n, rhs.0)))
1943        }
1944    }
1945}
1946
1947impl Rem<&Self> for Vec3A {
1948    type Output = Self;
1949    #[inline]
1950    fn rem(self, rhs: &Self) -> Self {
1951        self.rem(*rhs)
1952    }
1953}
1954
1955impl Rem<&Vec3A> for &Vec3A {
1956    type Output = Vec3A;
1957    #[inline]
1958    fn rem(self, rhs: &Vec3A) -> Vec3A {
1959        (*self).rem(*rhs)
1960    }
1961}
1962
1963impl Rem<Vec3A> for &Vec3A {
1964    type Output = Vec3A;
1965    #[inline]
1966    fn rem(self, rhs: Vec3A) -> Vec3A {
1967        (*self).rem(rhs)
1968    }
1969}
1970
1971impl RemAssign for Vec3A {
1972    #[inline]
1973    fn rem_assign(&mut self, rhs: Self) {
1974        *self = self.rem(rhs);
1975    }
1976}
1977
1978impl RemAssign<&Self> for Vec3A {
1979    #[inline]
1980    fn rem_assign(&mut self, rhs: &Self) {
1981        self.rem_assign(*rhs);
1982    }
1983}
1984
1985impl Rem<f32> for Vec3A {
1986    type Output = Self;
1987    #[inline]
1988    fn rem(self, rhs: f32) -> Self {
1989        self.rem(Self::splat(rhs))
1990    }
1991}
1992
1993impl Rem<&f32> for Vec3A {
1994    type Output = Self;
1995    #[inline]
1996    fn rem(self, rhs: &f32) -> Self {
1997        self.rem(*rhs)
1998    }
1999}
2000
2001impl Rem<&f32> for &Vec3A {
2002    type Output = Vec3A;
2003    #[inline]
2004    fn rem(self, rhs: &f32) -> Vec3A {
2005        (*self).rem(*rhs)
2006    }
2007}
2008
2009impl Rem<f32> for &Vec3A {
2010    type Output = Vec3A;
2011    #[inline]
2012    fn rem(self, rhs: f32) -> Vec3A {
2013        (*self).rem(rhs)
2014    }
2015}
2016
2017impl RemAssign<f32> for Vec3A {
2018    #[inline]
2019    fn rem_assign(&mut self, rhs: f32) {
2020        *self = self.rem(Self::splat(rhs));
2021    }
2022}
2023
2024impl RemAssign<&f32> for Vec3A {
2025    #[inline]
2026    fn rem_assign(&mut self, rhs: &f32) {
2027        self.rem_assign(*rhs);
2028    }
2029}
2030
2031impl Rem<Vec3A> for f32 {
2032    type Output = Vec3A;
2033    #[inline]
2034    fn rem(self, rhs: Vec3A) -> Vec3A {
2035        Vec3A::splat(self).rem(rhs)
2036    }
2037}
2038
2039impl Rem<&Vec3A> for f32 {
2040    type Output = Vec3A;
2041    #[inline]
2042    fn rem(self, rhs: &Vec3A) -> Vec3A {
2043        self.rem(*rhs)
2044    }
2045}
2046
2047impl Rem<&Vec3A> for &f32 {
2048    type Output = Vec3A;
2049    #[inline]
2050    fn rem(self, rhs: &Vec3A) -> Vec3A {
2051        (*self).rem(*rhs)
2052    }
2053}
2054
2055impl Rem<Vec3A> for &f32 {
2056    type Output = Vec3A;
2057    #[inline]
2058    fn rem(self, rhs: Vec3A) -> Vec3A {
2059        (*self).rem(rhs)
2060    }
2061}
2062
2063impl AsRef<[f32; 3]> for Vec3A {
2064    #[inline]
2065    fn as_ref(&self) -> &[f32; 3] {
2066        unsafe { &*(self as *const Self as *const [f32; 3]) }
2067    }
2068}
2069
2070impl AsMut<[f32; 3]> for Vec3A {
2071    #[inline]
2072    fn as_mut(&mut self) -> &mut [f32; 3] {
2073        unsafe { &mut *(self as *mut Self as *mut [f32; 3]) }
2074    }
2075}
2076
2077impl Sum for Vec3A {
2078    #[inline]
2079    fn sum<I>(iter: I) -> Self
2080    where
2081        I: Iterator<Item = Self>,
2082    {
2083        iter.fold(Self::ZERO, Self::add)
2084    }
2085}
2086
2087impl<'a> Sum<&'a Self> for Vec3A {
2088    #[inline]
2089    fn sum<I>(iter: I) -> Self
2090    where
2091        I: Iterator<Item = &'a Self>,
2092    {
2093        iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
2094    }
2095}
2096
2097impl Product for Vec3A {
2098    #[inline]
2099    fn product<I>(iter: I) -> Self
2100    where
2101        I: Iterator<Item = Self>,
2102    {
2103        iter.fold(Self::ONE, Self::mul)
2104    }
2105}
2106
2107impl<'a> Product<&'a Self> for Vec3A {
2108    #[inline]
2109    fn product<I>(iter: I) -> Self
2110    where
2111        I: Iterator<Item = &'a Self>,
2112    {
2113        iter.fold(Self::ONE, |a, &b| Self::mul(a, b))
2114    }
2115}
2116
2117impl Neg for Vec3A {
2118    type Output = Self;
2119    #[inline]
2120    fn neg(self) -> Self {
2121        Self(unsafe { vnegq_f32(self.0) })
2122    }
2123}
2124
2125impl Neg for &Vec3A {
2126    type Output = Vec3A;
2127    #[inline]
2128    fn neg(self) -> Vec3A {
2129        (*self).neg()
2130    }
2131}
2132
2133impl Index<usize> for Vec3A {
2134    type Output = f32;
2135    #[inline]
2136    fn index(&self, index: usize) -> &Self::Output {
2137        match index {
2138            0 => &self.x,
2139            1 => &self.y,
2140            2 => &self.z,
2141            _ => panic!("index out of bounds"),
2142        }
2143    }
2144}
2145
2146impl IndexMut<usize> for Vec3A {
2147    #[inline]
2148    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
2149        match index {
2150            0 => &mut self.x,
2151            1 => &mut self.y,
2152            2 => &mut self.z,
2153            _ => panic!("index out of bounds"),
2154        }
2155    }
2156}
2157
2158impl fmt::Display for Vec3A {
2159    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2160        if let Some(p) = f.precision() {
2161            write!(f, "[{:.*}, {:.*}, {:.*}]", p, self.x, p, self.y, p, self.z)
2162        } else {
2163            write!(f, "[{}, {}, {}]", self.x, self.y, self.z)
2164        }
2165    }
2166}
2167
2168impl fmt::Debug for Vec3A {
2169    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
2170        fmt.debug_tuple(stringify!(Vec3A))
2171            .field(&self.x)
2172            .field(&self.y)
2173            .field(&self.z)
2174            .finish()
2175    }
2176}
2177
2178impl From<Vec3A> for float32x4_t {
2179    #[inline(always)]
2180    fn from(t: Vec3A) -> Self {
2181        t.0
2182    }
2183}
2184
2185impl From<float32x4_t> for Vec3A {
2186    #[inline(always)]
2187    fn from(t: float32x4_t) -> Self {
2188        Self(t)
2189    }
2190}
2191
2192impl From<[f32; 3]> for Vec3A {
2193    #[inline]
2194    fn from(a: [f32; 3]) -> Self {
2195        Self::new(a[0], a[1], a[2])
2196    }
2197}
2198
2199impl From<Vec3A> for [f32; 3] {
2200    #[inline]
2201    fn from(v: Vec3A) -> Self {
2202        use crate::align16::Align16;
2203        use core::mem::MaybeUninit;
2204        let mut out: MaybeUninit<Align16<Self>> = MaybeUninit::uninit();
2205        unsafe {
2206            vst1q_f32(out.as_mut_ptr().cast(), v.0);
2207            out.assume_init().0
2208        }
2209    }
2210}
2211
2212impl From<(f32, f32, f32)> for Vec3A {
2213    #[inline]
2214    fn from(t: (f32, f32, f32)) -> Self {
2215        Self::new(t.0, t.1, t.2)
2216    }
2217}
2218
2219impl From<Vec3A> for (f32, f32, f32) {
2220    #[inline]
2221    fn from(v: Vec3A) -> Self {
2222        (v.x, v.y, v.z)
2223    }
2224}
2225
2226impl From<Vec3> for Vec3A {
2227    #[inline]
2228    fn from(v: Vec3) -> Self {
2229        Self::new(v.x, v.y, v.z)
2230    }
2231}
2232
2233impl From<Vec3A> for Vec3 {
2234    #[inline]
2235    fn from(v: Vec3A) -> Self {
2236        use crate::align16::Align16;
2237        use core::mem::MaybeUninit;
2238        let mut out: MaybeUninit<Align16<Self>> = MaybeUninit::uninit();
2239        unsafe {
2240            vst1q_f32(out.as_mut_ptr().cast(), v.0);
2241            out.assume_init().0
2242        }
2243    }
2244}
2245
2246impl From<(Vec2, f32)> for Vec3A {
2247    #[inline]
2248    fn from((v, z): (Vec2, f32)) -> Self {
2249        Self::new(v.x, v.y, z)
2250    }
2251}
2252
2253impl Deref for Vec3A {
2254    type Target = crate::deref::Vec3<f32>;
2255    #[inline]
2256    fn deref(&self) -> &Self::Target {
2257        unsafe { &*(self as *const Self).cast() }
2258    }
2259}
2260
2261impl DerefMut for Vec3A {
2262    #[inline]
2263    fn deref_mut(&mut self) -> &mut Self::Target {
2264        unsafe { &mut *(self as *mut Self).cast() }
2265    }
2266}
2267
2268impl From<BVec3> for Vec3A {
2269    #[inline]
2270    fn from(v: BVec3) -> Self {
2271        Self::new(f32::from(v.x), f32::from(v.y), f32::from(v.z))
2272    }
2273}
2274
2275impl From<BVec3A> for Vec3A {
2276    #[inline]
2277    fn from(v: BVec3A) -> Self {
2278        let bool_array: [bool; 3] = v.into();
2279        Self::new(
2280            f32::from(bool_array[0]),
2281            f32::from(bool_array[1]),
2282            f32::from(bool_array[2]),
2283        )
2284    }
2285}