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::{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/// 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-08",
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
102    /// Creates a new vector.
103    #[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    /// Creates a vector with all elements set to `v`.
110    #[inline]
111    #[must_use]
112    pub const fn splat(v: f32) -> Self {
113        unsafe { UnionCast { a: [v; 4] }.v }
114    }
115
116    /// Returns a vector containing each element of `self` modified by a mapping function `f`.
117    #[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    /// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use
127    /// for each element of `self`.
128    ///
129    /// A true element in the mask uses the corresponding element from `if_true`, and false
130    /// uses the element from `if_false`.
131    #[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    /// Creates a new vector from an array.
138    #[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    /// Converts `self` to `[x, y, z]`
145    #[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    /// Creates a vector from the first 3 values in `slice`.
152    ///
153    /// # Panics
154    ///
155    /// Panics if `slice` is less than 3 elements long.
156    #[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    /// Writes the elements of `self` to the first 3 elements in `slice`.
165    ///
166    /// # Panics
167    ///
168    /// Panics if `slice` is less than 3 elements long.
169    #[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    /// 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    #[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    /// Creates a homogeneous coordinate from `self`, equivalent to `self.extend(1.0)`.
215    #[inline]
216    #[must_use]
217    pub fn to_homogeneous(self) -> Vec4 {
218        self.extend(1.0)
219    }
220
221    // Converts `self` to a `Vec3`.
222    #[inline]
223    #[must_use]
224    pub fn to_vec3(self) -> Vec3 {
225        Vec3::from(self)
226    }
227
228    /// Creates a 3D vector from `self` with the given value of `x`.
229    #[inline]
230    #[must_use]
231    pub fn with_x(mut self, x: f32) -> Self {
232        self.x = x;
233        self
234    }
235
236    /// Creates a 3D vector from `self` with the given value of `y`.
237    #[inline]
238    #[must_use]
239    pub fn with_y(mut self, y: f32) -> Self {
240        self.y = y;
241        self
242    }
243
244    /// Creates a 3D vector from `self` with the given value of `z`.
245    #[inline]
246    #[must_use]
247    pub fn with_z(mut self, z: f32) -> Self {
248        self.z = z;
249        self
250    }
251
252    /// Computes the dot product of `self` and `rhs`.
253    #[inline]
254    #[must_use]
255    pub fn dot(self, rhs: Self) -> f32 {
256        // this was faster than intrinsics in testing
257        (self.x * rhs.x) + (self.y * rhs.y) + (self.z * rhs.z)
258    }
259
260    /// Returns a vector where every component is the dot product of `self` and `rhs`.
261    #[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    /// Computes the cross product of `self` and `rhs`.
268    #[inline]
269    #[must_use]
270    pub fn cross(self, rhs: Self) -> Self {
271        unsafe {
272            // Implementation taken from Realtime Math
273            let lhs = self.0;
274            let rhs = rhs.0;
275            // cross(a, b) = (a.yzx * b.zxy) - (a.zxy * b.yzx)
276            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            // part_a = (a.yzx * b.zxy)
283            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            // result = part_a - (a.zxy * b.yzx)
291            let result = vfmsq_f32(part_a, lhs_zxy, rhs_yzx);
292            Self(result)
293        }
294    }
295
296    /// Returns a vector containing the minimum values for each element of `self` and `rhs`.
297    ///
298    /// In other words this computes `[min(x, rhs.x), min(self.y, rhs.y), ..]`.
299    ///
300    /// NaN propogation does not follow IEEE 754-2008 semantics for minNum and may differ on
301    /// different SIMD architectures.
302    #[inline]
303    #[must_use]
304    pub fn min(self, rhs: Self) -> Self {
305        Self(unsafe { vminq_f32(self.0, rhs.0) })
306    }
307
308    /// Returns a vector containing the maximum values for each element of `self` and `rhs`.
309    ///
310    /// In other words this computes `[max(self.x, rhs.x), max(self.y, rhs.y), ..]`.
311    ///
312    /// NaN propogation does not follow IEEE 754-2008 semantics for maxNum and may differ on
313    /// different SIMD architectures.
314    #[inline]
315    #[must_use]
316    pub fn max(self, rhs: Self) -> Self {
317        Self(unsafe { vmaxq_f32(self.0, rhs.0) })
318    }
319
320    /// Component-wise clamping of values, similar to [`f32::clamp`].
321    ///
322    /// Each element in `min` must be less-or-equal to the corresponding element in `max`.
323    ///
324    /// NaN propogation does not follow IEEE 754-2008 semantics and may differ on
325    /// different SIMD architectures.
326    ///
327    /// # Panics
328    ///
329    /// Will panic if `min` is greater than `max` when `glam_assert` is enabled.
330    #[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    /// Returns the horizontal minimum of `self`.
339    ///
340    /// In other words this computes `min(x, y, ..)`.
341    ///
342    /// NaN propogation does not follow IEEE 754-2008 semantics and may differ on
343    /// different SIMD architectures.
344    #[inline]
345    #[must_use]
346    pub fn min_element(self) -> f32 {
347        self.x.min(self.y.min(self.z))
348    }
349
350    /// Returns the horizontal maximum of `self`.
351    ///
352    /// In other words this computes `max(x, y, ..)`.
353    ///
354    /// NaN propogation does not follow IEEE 754-2008 semantics and may differ on
355    /// different SIMD architectures.
356    #[inline]
357    #[must_use]
358    pub fn max_element(self) -> f32 {
359        self.x.max(self.y.max(self.z))
360    }
361
362    /// Returns the index of the first minimum element of `self`.
363    #[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    /// Returns the index of the first maximum element of `self`.
380    #[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    /// Returns the sum of all elements of `self`.
397    ///
398    /// In other words, this computes `self.x + self.y + ..`.
399    #[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    /// Returns the product of all elements of `self`.
406    ///
407    /// In other words, this computes `self.x * self.y * ..`.
408    #[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    /// Returns a vector mask containing the result of a `==` comparison for each element of
418    /// `self` and `rhs`.
419    ///
420    /// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all
421    /// elements.
422    #[inline]
423    #[must_use]
424    pub fn cmpeq(self, rhs: Self) -> BVec3A {
425        BVec3A(unsafe { vceqq_f32(self.0, rhs.0) })
426    }
427
428    /// Returns a vector mask containing the result of a `!=` comparison for each element of
429    /// `self` and `rhs`.
430    ///
431    /// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all
432    /// elements.
433    #[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    /// Returns a vector mask containing the result of a `>=` comparison for each element of
440    /// `self` and `rhs`.
441    ///
442    /// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all
443    /// elements.
444    #[inline]
445    #[must_use]
446    pub fn cmpge(self, rhs: Self) -> BVec3A {
447        BVec3A(unsafe { vcgeq_f32(self.0, rhs.0) })
448    }
449
450    /// Returns a vector mask containing the result of a `>` comparison for each element of
451    /// `self` and `rhs`.
452    ///
453    /// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all
454    /// elements.
455    #[inline]
456    #[must_use]
457    pub fn cmpgt(self, rhs: Self) -> BVec3A {
458        BVec3A(unsafe { vcgtq_f32(self.0, rhs.0) })
459    }
460
461    /// Returns a vector mask containing the result of a `<=` comparison for each element of
462    /// `self` and `rhs`.
463    ///
464    /// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all
465    /// elements.
466    #[inline]
467    #[must_use]
468    pub fn cmple(self, rhs: Self) -> BVec3A {
469        BVec3A(unsafe { vcleq_f32(self.0, rhs.0) })
470    }
471
472    /// Returns a vector mask containing the result of a `<` comparison for each element of
473    /// `self` and `rhs`.
474    ///
475    /// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all
476    /// elements.
477    #[inline]
478    #[must_use]
479    pub fn cmplt(self, rhs: Self) -> BVec3A {
480        BVec3A(unsafe { vcltq_f32(self.0, rhs.0) })
481    }
482
483    /// Returns a vector containing the absolute value of each element of `self`.
484    #[inline]
485    #[must_use]
486    pub fn abs(self) -> Self {
487        Self(unsafe { vabsq_f32(self.0) })
488    }
489
490    /// Returns a vector with elements representing the sign of `self`.
491    ///
492    /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
493    /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
494    /// - `NAN` if the number is `NAN`
495    #[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    /// Returns a vector with signs of `rhs` and the magnitudes of `self`.
512    #[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    /// Returns a bitmask with the lowest 3 bits set to the sign bits from the elements of `self`.
528    ///
529    /// A negative element results in a `1` bit and a positive element in a `0` bit.  Element `x` goes
530    /// into the first lowest bit, element `y` into the second, etc.
531    ///
532    /// An element is negative if it has a negative sign, including -0.0, NaNs with negative sign
533    /// bit and negative infinity.
534    #[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    /// Returns a mask indicating which components are negative.
549    ///
550    /// An element is negative if it has a negative sign, including -0.0, NaNs with negative sign
551    /// bit and negative infinity.
552    #[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    /// Returns `true` if, and only if, all elements are finite.  If any element is either
559    /// `NaN`, positive or negative infinity, this will return `false`.
560    #[inline]
561    #[must_use]
562    pub fn is_finite(self) -> bool {
563        self.is_finite_mask().all()
564    }
565
566    /// Performs `is_finite` on each element of self, returning a vector mask of the results.
567    ///
568    /// In other words, this computes `[x.is_finite(), y.is_finite(), ...]`.
569    #[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    /// Returns `true` if any elements are `NaN`.
576    #[inline]
577    #[must_use]
578    pub fn is_nan(self) -> bool {
579        self.is_nan_mask().any()
580    }
581
582    /// Performs `is_nan` on each element of self, returning a vector mask of the results.
583    ///
584    /// In other words, this computes `[x.is_nan(), y.is_nan(), ...]`.
585    #[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    /// Computes the length of `self`.
592    #[doc(alias = "magnitude")]
593    #[inline]
594    #[must_use]
595    pub fn length(self) -> f32 {
596        math::sqrt(self.dot(self))
597    }
598
599    /// Returns `true` if the vector is not the zero vector (also rejects NaN).
600    #[allow(dead_code)]
601    fn is_non_zero(self) -> bool {
602        self.length_squared() > 0.0
603    }
604
605    /// Computes the squared length of `self`.
606    ///
607    /// This is faster than `length()` as it avoids a square root operation.
608    #[doc(alias = "magnitude2")]
609    #[inline]
610    #[must_use]
611    pub fn length_squared(self) -> f32 {
612        self.dot(self)
613    }
614
615    /// Computes `1.0 / length()`.
616    ///
617    /// For valid results, `self` must _not_ be of length zero.
618    #[inline]
619    #[must_use]
620    pub fn length_recip(self) -> f32 {
621        1.0 / self.length()
622    }
623
624    /// Computes the Euclidean distance between two points in space.
625    #[inline]
626    #[must_use]
627    pub fn distance(self, rhs: Self) -> f32 {
628        (self - rhs).length()
629    }
630
631    /// Compute the squared euclidean distance between two points in space.
632    #[inline]
633    #[must_use]
634    pub fn distance_squared(self, rhs: Self) -> f32 {
635        (self - rhs).length_squared()
636    }
637
638    /// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`.
639    #[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    /// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`.
650    ///
651    /// [Euclidean division]: f32::rem_euclid
652    #[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    /// Returns `self` normalized to length 1.0.
663    ///
664    /// For valid results, `self` must be finite and _not_ of length zero, nor very close to zero.
665    ///
666    /// See also [`Self::try_normalize()`] and [`Self::normalize_or_zero()`].
667    ///
668    /// # Panics
669    ///
670    /// Will panic if the resulting normalized vector is not finite when `glam_assert` is enabled.
671    #[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    /// Returns `self` normalized to length 1.0 if possible, else returns `None`.
682    ///
683    /// In particular, if the input is zero (or very close to zero), or non-finite,
684    /// the result of this operation will be `None`.
685    ///
686    /// See also [`Self::normalize_or_zero()`].
687    #[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    /// Returns `self` normalized to length 1.0 if possible, else returns a
699    /// fallback value.
700    ///
701    /// In particular, if the input is zero (or very close to zero), or non-finite,
702    /// the result of this operation will be the fallback value.
703    ///
704    /// See also [`Self::try_normalize()`].
705    #[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    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
717    ///
718    /// In particular, if the input is zero (or very close to zero), or non-finite,
719    /// the result of this operation will be zero.
720    ///
721    /// See also [`Self::try_normalize()`].
722    #[inline]
723    #[must_use]
724    pub fn normalize_or_zero(self) -> Self {
725        self.normalize_or(Self::ZERO)
726    }
727
728    /// Returns `self` normalized to length 1.0 and the length of `self`.
729    ///
730    /// If `self` is zero length then `(Self::X, 0.0)` is returned.
731    #[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    /// Returns whether `self` is length `1.0` or not.
744    ///
745    /// Uses a precision threshold of approximately `1e-4`.
746    #[inline]
747    #[must_use]
748    pub fn is_normalized(self) -> bool {
749        (self.length_squared() - 1.0).abs() <= 2e-4
750    }
751
752    /// Returns the vector projection of `self` onto `rhs`.
753    ///
754    /// `rhs` must be of non-zero length.
755    ///
756    /// # Panics
757    ///
758    /// Will panic if `rhs` is zero length when `glam_assert` is enabled.
759    #[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    /// Returns the vector rejection of `self` from `rhs`.
769    ///
770    /// The vector rejection is the vector perpendicular to the projection of `self` onto
771    /// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`.
772    ///
773    /// `rhs` must be of non-zero length.
774    ///
775    /// # Panics
776    ///
777    /// Will panic if `rhs` has a length of zero when `glam_assert` is enabled.
778    #[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    /// Returns the vector projection of `self` onto `rhs`.
787    ///
788    /// `rhs` must be normalized.
789    ///
790    /// # Panics
791    ///
792    /// Will panic if `rhs` is not normalized when `glam_assert` is enabled.
793    #[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    /// Returns the vector rejection of `self` from `rhs`.
802    ///
803    /// The vector rejection is the vector perpendicular to the projection of `self` onto
804    /// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`.
805    ///
806    /// `rhs` must be normalized.
807    ///
808    /// # Panics
809    ///
810    /// Will panic if `rhs` is not normalized when `glam_assert` is enabled.
811    #[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    /// Returns a vector containing the nearest integer to a number for each element of `self`.
820    /// Round half-way cases away from 0.0.
821    #[inline]
822    #[must_use]
823    pub fn round(self) -> Self {
824        Self(unsafe { vrndaq_f32(self.0) })
825    }
826
827    /// Returns a vector containing the largest integer less than or equal to a number for each
828    /// element of `self`.
829    #[inline]
830    #[must_use]
831    pub fn floor(self) -> Self {
832        Self(unsafe { vrndmq_f32(self.0) })
833    }
834
835    /// Returns a vector containing the smallest integer greater than or equal to a number for
836    /// each element of `self`.
837    #[inline]
838    #[must_use]
839    pub fn ceil(self) -> Self {
840        Self(unsafe { vrndpq_f32(self.0) })
841    }
842
843    /// Returns a vector containing the integer part each element of `self`. This means numbers are
844    /// always truncated towards zero.
845    #[inline]
846    #[must_use]
847    pub fn trunc(self) -> Self {
848        Self(unsafe { vrndq_f32(self.0) })
849    }
850
851    /// Returns a vector containing `0.0` if `rhs < self` and 1.0 otherwise.
852    ///
853    /// Similar to glsl's step(edge, x), which translates into edge.step(x)
854    #[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    /// Performs Hermite interpolation between `0.0` and `1.0` using `x` normalized to `[edge0, edge1]`.
861    ///
862    /// This is equivalent to `t * t * (3.0 - 2.0 * t)`, where `t` is clamped to `[0.0, 1.0]`.
863    /// Results are undefined if any element of `edge0` is greater than or equal to the corresponding
864    /// element of `edge1`.
865    ///
866    /// # Panics
867    ///
868    /// Will panic if any element of `edge0` is greater than or equal to the corresponding element
869    /// of `edge1`, when `glam_assert` is enabled.
870    #[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    /// Returns a vector containing all elements of `self` clamped to the range of `[0, 1]`.
880    #[inline]
881    #[must_use]
882    pub fn saturate(self) -> Self {
883        self.clamp(Self::ZERO, Self::ONE)
884    }
885
886    /// Returns a vector containing the fractional part of the vector as `self - self.trunc()`.
887    ///
888    /// Note that this differs from the GLSL implementation of `fract` which returns
889    /// `self - self.floor()`.
890    ///
891    /// Note that this is fast but not precise for large numbers.
892    #[inline]
893    #[must_use]
894    pub fn fract(self) -> Self {
895        self - self.trunc()
896    }
897
898    /// Returns a vector containing the fractional part of the vector as `self - self.floor()`.
899    ///
900    /// Note that this differs from the Rust implementation of `fract` which returns
901    /// `self - self.trunc()`.
902    ///
903    /// Note that this is fast but not precise for large numbers.
904    #[inline]
905    #[must_use]
906    pub fn fract_gl(self) -> Self {
907        self - self.floor()
908    }
909
910    /// Returns a vector containing `e^self` (the exponential function) for each element of
911    /// `self`.
912    #[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    /// Returns a vector containing `2^self` for each element of `self`.
919    #[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    /// Returns a vector containing the natural logarithm for each element of `self`.
926    /// This returns NaN when the element is negative and negative infinity when the element is zero.
927    #[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    /// Returns a vector containing the base 2 logarithm for each element of `self`.
934    /// This returns NaN when the element is negative and negative infinity when the element is zero.
935    #[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    /// Returns a vector containing each element of `self` raised to the power of `n`.
942    #[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    /// Returns a vector containing the square root for each element of `self`.
953    /// This returns NaN when the element is negative.
954    #[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    /// Returns a vector containing the cosine for each element of `self`.
961    #[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    /// Returns a vector containing the sine for each element of `self`.
968    #[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    /// Returns a tuple of two vectors containing the sine and cosine for each element of `self`.
975    #[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    /// Returns a vector containing the reciprocal `1.0/n` of each element of `self`.
989    #[inline]
990    #[must_use]
991    pub fn recip(self) -> Self {
992        Self(unsafe { vdivq_f32(Self::ONE.0, self.0) })
993    }
994
995    /// Performs a linear interpolation between `self` and `rhs` based on the value `s`, using the
996    /// form `self * (1.0 - s) + rhs * s`.
997    ///
998    /// When `s` is `0.0`, the result will be equal to `self`. When `s` is `1.0`, the result will
999    /// be equal to `rhs`. When `s` is outside of the range `[0, 1]`, the result is linearly
1000    /// extrapolated.
1001    ///
1002    /// The result is guaranteed to be `self` at `s == 0.0` and `rhs` at `s == 1.0`, even when the
1003    /// values differ greatly in magnitude, but it is not monotonic in `s` for nearly equal inputs
1004    /// and may not preserve equal inputs exactly. Consider [`lerp_monotonic`](Self::lerp_monotonic)
1005    /// instead when interpolating between values that may be equal or nearly equal.
1006    #[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    /// Performs a linear interpolation between `self` and `rhs` based on the value `s`, using the
1014    /// monotonic form `self + (rhs - self) * s`.
1015    ///
1016    /// When `s` is `0.0`, the result will be equal to `self`. When `s` is `1.0`, the result will
1017    /// be equal to `rhs`. When `s` is outside of the range `[0, 1]`, the result is linearly
1018    /// extrapolated.
1019    ///
1020    /// Prefer this over [`lerp`](Self::lerp) when interpolating between values that may be equal or
1021    /// nearly equal: the result is monotonic in `s` and equal inputs are preserved exactly, avoiding
1022    /// the rounding jitter that [`lerp`](Self::lerp) can introduce. The tradeoff is that
1023    /// `rhs - self` is evaluated first, so this is less accurate than [`lerp`](Self::lerp) when
1024    /// `self` and `rhs` differ greatly in magnitude, and overflows to infinity when they have
1025    /// opposite signs and large magnitudes.
1026    ///
1027    /// On SIMD back-ends the multiply and add are fused when the target supports it, which has a
1028    /// single rounding step and can be more accurate than a separate multiply and add.
1029    #[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    /// Moves towards `rhs` based on the value `d`.
1037    ///
1038    /// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to
1039    /// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`.
1040    #[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    /// Calculates the midpoint between `self` and `rhs`.
1052    ///
1053    /// The midpoint is the average of, or halfway point between, two vectors.
1054    /// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)`
1055    /// while being slightly cheaper to compute.
1056    #[inline]
1057    pub fn midpoint(self, rhs: Self) -> Self {
1058        (self + rhs) * 0.5
1059    }
1060
1061    /// Returns true if the absolute difference of all elements between `self` and `rhs` is
1062    /// less than or equal to `max_abs_diff`.
1063    ///
1064    /// This can be used to compare if two vectors contain similar elements. It works best when
1065    /// comparing with a known value. The `max_abs_diff` that should be used used depends on
1066    /// the values being compared against.
1067    ///
1068    /// For more see
1069    /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
1070    #[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    /// Returns a vector with a length no less than `min` and no more than `max`.
1077    ///
1078    /// # Panics
1079    ///
1080    /// Will panic if `min` is greater than `max`, or if either `min` or `max` is negative, when `glam_assert` is enabled.
1081    #[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    /// Returns a vector with a length no more than `max`.
1098    ///
1099    /// # Panics
1100    ///
1101    /// Will panic if `max` is negative when `glam_assert` is enabled.
1102    #[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    /// Returns a vector with a length no less than `min`.
1116    ///
1117    /// # Panics
1118    ///
1119    /// Will panic if `min` is negative when `glam_assert` is enabled.
1120    #[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    /// Fused multiply-add. Computes `(self * a) + b` element-wise with only one rounding
1134    /// error, yielding a more accurate result than an unfused multiply-add.
1135    ///
1136    /// Using `mul_add` *may* be more performant than an unfused multiply-add if the target
1137    /// architecture has a dedicated fma CPU instruction. However, this is not always true,
1138    /// and will be heavily dependant on designing algorithms with specific target hardware in
1139    /// mind.
1140    #[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    /// Returns the reflection vector for a given incident vector `self` and surface normal
1147    /// `normal`.
1148    ///
1149    /// `normal` must be normalized.
1150    ///
1151    /// # Panics
1152    ///
1153    /// Will panic if `normal` is not normalized when `glam_assert` is enabled.
1154    #[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    /// Returns the refraction direction for a given incident vector `self`, surface normal
1163    /// `normal` and ratio of indices of refraction, `eta`. When total internal reflection occurs,
1164    /// a zero vector will be returned.
1165    ///
1166    /// `self` and `normal` must be normalized.
1167    ///
1168    /// # Panics
1169    ///
1170    /// Will panic if `self` or `normal` is not normalized when `glam_assert` is enabled.
1171    #[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    /// Returns the angle (in radians) between two vectors in the range `[0, +Ï€]`.
1187    ///
1188    /// For the full rotation between two vectors as a quaternion, see
1189    /// [`Quat::from_rotation_arc`].
1190    ///
1191    /// The inputs do not need to be unit vectors however they must be non-zero.
1192    ///
1193    /// # Panics
1194    ///
1195    /// Will panic if `self` or `rhs` has zero length when `glam_assert` is enabled.
1196    #[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    /// Returns the signed angle (in radians) from `self` to `rhs` around `axis`
1209    /// in the range `[-Ï€, +Ï€]`.
1210    ///
1211    /// The `axis` must be a unit vector. The angle follows the right-hand rule
1212    /// around `axis` and can be used with [`Self::rotate_axis`], e.g.
1213    /// `self.rotate_axis(axis, self.angle_to(rhs, axis))` will be equal to `rhs`.
1214    ///
1215    /// For the unsigned angle without a reference axis, see [`Self::angle_between`].
1216    ///
1217    /// The inputs do not need to be unit vectors however they must be non-zero.
1218    ///
1219    /// # Panics
1220    ///
1221    /// Will panic if `axis` is not normalized when `glam_assert` is enabled.
1222    /// Will panic if `self` or `rhs` has zero length when `glam_assert` is enabled.
1223    #[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    /// Rotates around the x axis by `angle` (in radians).
1235    #[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    /// Rotates around the y axis by `angle` (in radians).
1247    #[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    /// Rotates around the z axis by `angle` (in radians).
1259    #[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    /// Rotates around `axis` by `angle` (in radians).
1271    ///
1272    /// The axis must be a unit vector.
1273    ///
1274    /// # Panics
1275    ///
1276    /// Will panic if `axis` is not normalized when `glam_assert` is enabled.
1277    #[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    /// Rotates towards `rhs` up to `max_angle` (in radians).
1285    ///
1286    /// When `max_angle` is `0.0`, the result will be equal to `self`. When `max_angle` is equal to
1287    /// `self.angle_between(rhs)`, the result will be parallel to `rhs`. If `max_angle` is negative,
1288    /// rotates towards the exact opposite of `rhs`. Will not go past the target.
1289    ///
1290    /// # Panics
1291    ///
1292    /// Will panic if `self` or `rhs` are zero length when `glam_assert` is enabled.
1293    #[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        // When `max_angle < 0`, rotate no further than `PI` radians away
1299        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    /// Returns some vector that is orthogonal to the given one.
1308    ///
1309    /// The input vector must be finite and non-zero.
1310    ///
1311    /// The output vector is not necessarily unit length. For that use
1312    /// [`Self::any_orthonormal_vector()`] instead.
1313    #[inline]
1314    #[must_use]
1315    pub fn any_orthogonal_vector(self) -> Self {
1316        // This can probably be optimized
1317        if self.x.abs() > self.y.abs() {
1318            Self::new(-self.z, 0.0, self.x) // self.cross(Self::Y)
1319        } else {
1320            Self::new(0.0, self.z, -self.y) // self.cross(Self::X)
1321        }
1322    }
1323
1324    /// Returns any unit vector that is orthogonal to the given one.
1325    ///
1326    /// The input vector must be unit length.
1327    ///
1328    /// # Panics
1329    ///
1330    /// Will panic if `self` is not normalized when `glam_assert` is enabled.
1331    #[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        // From https://graphics.pixar.com/library/OrthonormalB/paper.pdf
1337        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    /// Given a unit vector return two other vectors that together form a right-handed orthonormal
1344    /// basis. That is, all three vectors are orthogonal to each other and are normalized.
1345    ///
1346    /// # Panics
1347    ///
1348    /// Will panic if `self` is not normalized when `glam_assert` is enabled.
1349    #[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        // From https://graphics.pixar.com/library/OrthonormalB/paper.pdf
1355        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    /// Performs a spherical linear interpolation between `self` and `rhs` based on the value `s`.
1365    ///
1366    /// When `s` is `0.0`, the result will be equal to `self`.  When `s` is `1.0`, the result
1367    /// will be equal to `rhs`. When `s` is outside of range `[0, 1]`, the result is linearly
1368    /// extrapolated.
1369    ///
1370    /// # Panics
1371    ///
1372    /// Will panic if `self` or `rhs` has zero length when `glam_assert` is enabled.
1373    #[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        // Cosine of the angle between the vectors [-1, 1], or NaN if either vector has a zero length
1382        let dot = self.dot(rhs) / (self_length * rhs_length);
1383        // If dot is close to 1 or -1, or is NaN the calculations for t1 and t2 break down
1384        if dot.abs() < 1.0 - 3e-7 {
1385            // Angle between the vectors [0, +Ï€]
1386            let theta = math::acos_approx(dot);
1387            // Sine of the angle between vectors [0, 1]
1388            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), // sin(theta)
1394                    vgetq_lane_f32(tmp, 0), // sin(theta * (1.0 - s))
1395                    vgetq_lane_f32(tmp, 1), // sin(theta * s)
1396                )
1397            };
1398
1399            // Interpolate vector lengths. The monotonic form keeps equal lengths exact.
1400            let result_length = self_length.lerp_monotonic(rhs_length, s);
1401            // Scale the vectors to the target length and interpolate them
1402            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            // Vectors are almost parallel in opposing directions
1408
1409            // Create a rotation from self to rhs along some axis
1410            let axis = self.any_orthogonal_vector().normalize().into();
1411            let rotation = Quat::from_axis_angle(axis, core::f32::consts::PI * s);
1412            // Interpolate vector lengths. The monotonic form keeps equal lengths exact.
1413            let result_length = self_length.lerp_monotonic(rhs_length, s);
1414            rotation * self * (result_length / self_length)
1415        } else {
1416            // Vectors are almost parallel in the same direction, or dot was NaN
1417            self.lerp(rhs, s)
1418        }
1419    }
1420
1421    /// Casts all elements of `self` to `f64`.
1422    #[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    /// Casts all elements of `self` to `i8`.
1430    #[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    /// Casts all elements of `self` to `u8`.
1438    #[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    /// Casts all elements of `self` to `i16`.
1446    #[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    /// Casts all elements of `self` to `u16`.
1454    #[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    /// Casts all elements of `self` to `i32`.
1462    #[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    /// Casts all elements of `self` to `u32`.
1470    #[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    /// Casts all elements of `self` to `i64`.
1478    #[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    /// Casts all elements of `self` to `u64`.
1486    #[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    /// Casts all elements of `self` to `isize`.
1494    #[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    /// Casts all elements of `self` to `usize`.
1502    #[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}