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    /// Computes the squared length of `self`.
598    ///
599    /// This is faster than `length()` as it avoids a square root operation.
600    #[doc(alias = "magnitude2")]
601    #[inline]
602    #[must_use]
603    pub fn length_squared(self) -> f32 {
604        self.dot(self)
605    }
606
607    /// Computes `1.0 / length()`.
608    ///
609    /// For valid results, `self` must _not_ be of length zero.
610    #[inline]
611    #[must_use]
612    pub fn length_recip(self) -> f32 {
613        self.length().recip()
614    }
615
616    /// Computes the Euclidean distance between two points in space.
617    #[inline]
618    #[must_use]
619    pub fn distance(self, rhs: Self) -> f32 {
620        (self - rhs).length()
621    }
622
623    /// Compute the squared euclidean distance between two points in space.
624    #[inline]
625    #[must_use]
626    pub fn distance_squared(self, rhs: Self) -> f32 {
627        (self - rhs).length_squared()
628    }
629
630    /// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`.
631    #[inline]
632    #[must_use]
633    pub fn div_euclid(self, rhs: Self) -> Self {
634        Self::new(
635            math::div_euclid(self.x, rhs.x),
636            math::div_euclid(self.y, rhs.y),
637            math::div_euclid(self.z, rhs.z),
638        )
639    }
640
641    /// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`.
642    ///
643    /// [Euclidean division]: f32::rem_euclid
644    #[inline]
645    #[must_use]
646    pub fn rem_euclid(self, rhs: Self) -> Self {
647        Self::new(
648            math::rem_euclid(self.x, rhs.x),
649            math::rem_euclid(self.y, rhs.y),
650            math::rem_euclid(self.z, rhs.z),
651        )
652    }
653
654    /// Returns `self` normalized to length 1.0.
655    ///
656    /// For valid results, `self` must be finite and _not_ of length zero, nor very close to zero.
657    ///
658    /// See also [`Self::try_normalize()`] and [`Self::normalize_or_zero()`].
659    ///
660    /// # Panics
661    ///
662    /// Will panic if the resulting normalized vector is not finite when `glam_assert` is enabled.
663    #[inline]
664    #[must_use]
665    pub fn normalize(self) -> Self {
666        #[allow(clippy::let_and_return)]
667        let normalized = self.mul(self.length_recip());
668        glam_assert!(normalized.is_finite());
669        normalized
670    }
671
672    /// Returns `self` normalized to length 1.0 if possible, else returns `None`.
673    ///
674    /// In particular, if the input is zero (or very close to zero), or non-finite,
675    /// the result of this operation will be `None`.
676    ///
677    /// See also [`Self::normalize_or_zero()`].
678    #[inline]
679    #[must_use]
680    pub fn try_normalize(self) -> Option<Self> {
681        let rcp = self.length_recip();
682        if rcp.is_finite() && rcp > 0.0 {
683            Some(self * rcp)
684        } else {
685            None
686        }
687    }
688
689    /// Returns `self` normalized to length 1.0 if possible, else returns a
690    /// fallback value.
691    ///
692    /// In particular, if the input is zero (or very close to zero), or non-finite,
693    /// the result of this operation will be the fallback value.
694    ///
695    /// See also [`Self::try_normalize()`].
696    #[inline]
697    #[must_use]
698    pub fn normalize_or(self, fallback: Self) -> Self {
699        let rcp = self.length_recip();
700        if rcp.is_finite() && rcp > 0.0 {
701            self * rcp
702        } else {
703            fallback
704        }
705    }
706
707    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
708    ///
709    /// In particular, if the input is zero (or very close to zero), or non-finite,
710    /// the result of this operation will be zero.
711    ///
712    /// See also [`Self::try_normalize()`].
713    #[inline]
714    #[must_use]
715    pub fn normalize_or_zero(self) -> Self {
716        self.normalize_or(Self::ZERO)
717    }
718
719    /// Returns `self` normalized to length 1.0 and the length of `self`.
720    ///
721    /// If `self` is zero length then `(Self::X, 0.0)` is returned.
722    #[inline]
723    #[must_use]
724    pub fn normalize_and_length(self) -> (Self, f32) {
725        let length = self.length();
726        let rcp = 1.0 / length;
727        if rcp.is_finite() && rcp > 0.0 {
728            (self * rcp, length)
729        } else {
730            (Self::X, 0.0)
731        }
732    }
733
734    /// Returns whether `self` is length `1.0` or not.
735    ///
736    /// Uses a precision threshold of approximately `1e-4`.
737    #[inline]
738    #[must_use]
739    pub fn is_normalized(self) -> bool {
740        math::abs(self.length_squared() - 1.0) <= 2e-4
741    }
742
743    /// Returns the vector projection of `self` onto `rhs`.
744    ///
745    /// `rhs` must be of non-zero length.
746    ///
747    /// # Panics
748    ///
749    /// Will panic if `rhs` is zero length when `glam_assert` is enabled.
750    #[inline]
751    #[must_use]
752    pub fn project_onto(self, rhs: Self) -> Self {
753        let other_len_sq_rcp = rhs.dot(rhs).recip();
754        glam_assert!(other_len_sq_rcp.is_finite());
755        rhs * self.dot(rhs) * other_len_sq_rcp
756    }
757
758    /// Returns the vector rejection of `self` from `rhs`.
759    ///
760    /// The vector rejection is the vector perpendicular to the projection of `self` onto
761    /// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`.
762    ///
763    /// `rhs` must be of non-zero length.
764    ///
765    /// # Panics
766    ///
767    /// Will panic if `rhs` has a length of zero when `glam_assert` is enabled.
768    #[doc(alias("plane"))]
769    #[inline]
770    #[must_use]
771    pub fn reject_from(self, rhs: Self) -> Self {
772        self - self.project_onto(rhs)
773    }
774
775    /// Returns the vector projection of `self` onto `rhs`.
776    ///
777    /// `rhs` must be normalized.
778    ///
779    /// # Panics
780    ///
781    /// Will panic if `rhs` is not normalized when `glam_assert` is enabled.
782    #[inline]
783    #[must_use]
784    pub fn project_onto_normalized(self, rhs: Self) -> Self {
785        glam_assert!(rhs.is_normalized());
786        rhs * self.dot(rhs)
787    }
788
789    /// Returns the vector rejection of `self` from `rhs`.
790    ///
791    /// The vector rejection is the vector perpendicular to the projection of `self` onto
792    /// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`.
793    ///
794    /// `rhs` must be normalized.
795    ///
796    /// # Panics
797    ///
798    /// Will panic if `rhs` is not normalized when `glam_assert` is enabled.
799    #[doc(alias("plane"))]
800    #[inline]
801    #[must_use]
802    pub fn reject_from_normalized(self, rhs: Self) -> Self {
803        self - self.project_onto_normalized(rhs)
804    }
805
806    /// Returns a vector containing the nearest integer to a number for each element of `self`.
807    /// Round half-way cases away from 0.0.
808    #[inline]
809    #[must_use]
810    pub fn round(self) -> Self {
811        Self(unsafe { vrndnq_f32(self.0) })
812    }
813
814    /// Returns a vector containing the largest integer less than or equal to a number for each
815    /// element of `self`.
816    #[inline]
817    #[must_use]
818    pub fn floor(self) -> Self {
819        Self(unsafe { vrndmq_f32(self.0) })
820    }
821
822    /// Returns a vector containing the smallest integer greater than or equal to a number for
823    /// each element of `self`.
824    #[inline]
825    #[must_use]
826    pub fn ceil(self) -> Self {
827        Self(unsafe { vrndpq_f32(self.0) })
828    }
829
830    /// Returns a vector containing the integer part each element of `self`. This means numbers are
831    /// always truncated towards zero.
832    #[inline]
833    #[must_use]
834    pub fn trunc(self) -> Self {
835        Self(unsafe { vrndq_f32(self.0) })
836    }
837
838    /// Returns a vector containing `0.0` if `rhs < self` and 1.0 otherwise.
839    ///
840    /// Similar to glsl's step(edge, x), which translates into edge.step(x)
841    #[inline]
842    #[must_use]
843    pub fn step(self, rhs: Self) -> Self {
844        Self::select(rhs.cmplt(self), Self::ZERO, Self::ONE)
845    }
846
847    /// Returns a vector containing all elements of `self` clamped to the range of `[0, 1]`.
848    #[inline]
849    #[must_use]
850    pub fn saturate(self) -> Self {
851        self.clamp(Self::ZERO, Self::ONE)
852    }
853
854    /// Returns a vector containing the fractional part of the vector as `self - self.trunc()`.
855    ///
856    /// Note that this differs from the GLSL implementation of `fract` which returns
857    /// `self - self.floor()`.
858    ///
859    /// Note that this is fast but not precise for large numbers.
860    #[inline]
861    #[must_use]
862    pub fn fract(self) -> Self {
863        self - self.trunc()
864    }
865
866    /// Returns a vector containing the fractional part of the vector as `self - self.floor()`.
867    ///
868    /// Note that this differs from the Rust implementation of `fract` which returns
869    /// `self - self.trunc()`.
870    ///
871    /// Note that this is fast but not precise for large numbers.
872    #[inline]
873    #[must_use]
874    pub fn fract_gl(self) -> Self {
875        self - self.floor()
876    }
877
878    /// Returns a vector containing `e^self` (the exponential function) for each element of
879    /// `self`.
880    #[inline]
881    #[must_use]
882    pub fn exp(self) -> Self {
883        Self::new(math::exp(self.x), math::exp(self.y), math::exp(self.z))
884    }
885
886    /// Returns a vector containing `2^self` for each element of `self`.
887    #[inline]
888    #[must_use]
889    pub fn exp2(self) -> Self {
890        Self::new(math::exp2(self.x), math::exp2(self.y), math::exp2(self.z))
891    }
892
893    /// Returns a vector containing the natural logarithm for each element of `self`.
894    /// This returns NaN when the element is negative and negative infinity when the element is zero.
895    #[inline]
896    #[must_use]
897    pub fn ln(self) -> Self {
898        Self::new(math::ln(self.x), math::ln(self.y), math::ln(self.z))
899    }
900
901    /// Returns a vector containing the base 2 logarithm for each element of `self`.
902    /// This returns NaN when the element is negative and negative infinity when the element is zero.
903    #[inline]
904    #[must_use]
905    pub fn log2(self) -> Self {
906        Self::new(math::log2(self.x), math::log2(self.y), math::log2(self.z))
907    }
908
909    /// Returns a vector containing each element of `self` raised to the power of `n`.
910    #[inline]
911    #[must_use]
912    pub fn powf(self, n: f32) -> Self {
913        Self::new(
914            math::powf(self.x, n),
915            math::powf(self.y, n),
916            math::powf(self.z, n),
917        )
918    }
919
920    /// Returns a vector containing the square root for each element of `self`.
921    /// This returns NaN when the element is negative.
922    #[inline]
923    #[must_use]
924    pub fn sqrt(self) -> Self {
925        Self::new(math::sqrt(self.x), math::sqrt(self.y), math::sqrt(self.z))
926    }
927
928    /// Returns a vector containing the cosine for each element of `self`.
929    #[inline]
930    #[must_use]
931    pub fn cos(self) -> Self {
932        Self::new(math::cos(self.x), math::cos(self.y), math::cos(self.z))
933    }
934
935    /// Returns a vector containing the sine for each element of `self`.
936    #[inline]
937    #[must_use]
938    pub fn sin(self) -> Self {
939        Self::new(math::sin(self.x), math::sin(self.y), math::sin(self.z))
940    }
941
942    /// Returns a tuple of two vectors containing the sine and cosine for each element of `self`.
943    #[inline]
944    #[must_use]
945    pub fn sin_cos(self) -> (Self, Self) {
946        let (sin_x, cos_x) = math::sin_cos(self.x);
947        let (sin_y, cos_y) = math::sin_cos(self.y);
948        let (sin_z, cos_z) = math::sin_cos(self.z);
949
950        (
951            Self::new(sin_x, sin_y, sin_z),
952            Self::new(cos_x, cos_y, cos_z),
953        )
954    }
955
956    /// Returns a vector containing the reciprocal `1.0/n` of each element of `self`.
957    #[inline]
958    #[must_use]
959    pub fn recip(self) -> Self {
960        Self(unsafe { vdivq_f32(Self::ONE.0, self.0) })
961    }
962
963    /// Performs a linear interpolation between `self` and `rhs` based on the value `s`.
964    ///
965    /// When `s` is `0.0`, the result will be equal to `self`.  When `s` is `1.0`, the result
966    /// will be equal to `rhs`. When `s` is outside of range `[0, 1]`, the result is linearly
967    /// extrapolated.
968    #[doc(alias = "mix")]
969    #[inline]
970    #[must_use]
971    pub fn lerp(self, rhs: Self, s: f32) -> Self {
972        self * (1.0 - s) + rhs * s
973    }
974
975    /// Moves towards `rhs` based on the value `d`.
976    ///
977    /// When `d` is `0.0`, the result will be equal to `self`. When `d` is equal to
978    /// `self.distance(rhs)`, the result will be equal to `rhs`. Will not go past `rhs`.
979    #[inline]
980    #[must_use]
981    pub fn move_towards(self, rhs: Self, d: f32) -> Self {
982        let a = rhs - self;
983        let len = a.length();
984        if len <= d || len <= 1e-4 {
985            return rhs;
986        }
987        self + a / len * d
988    }
989
990    /// Calculates the midpoint between `self` and `rhs`.
991    ///
992    /// The midpoint is the average of, or halfway point between, two vectors.
993    /// `a.midpoint(b)` should yield the same result as `a.lerp(b, 0.5)`
994    /// while being slightly cheaper to compute.
995    #[inline]
996    pub fn midpoint(self, rhs: Self) -> Self {
997        (self + rhs) * 0.5
998    }
999
1000    /// Returns true if the absolute difference of all elements between `self` and `rhs` is
1001    /// less than or equal to `max_abs_diff`.
1002    ///
1003    /// This can be used to compare if two vectors contain similar elements. It works best when
1004    /// comparing with a known value. The `max_abs_diff` that should be used used depends on
1005    /// the values being compared against.
1006    ///
1007    /// For more see
1008    /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
1009    #[inline]
1010    #[must_use]
1011    pub fn abs_diff_eq(self, rhs: Self, max_abs_diff: f32) -> bool {
1012        self.sub(rhs).abs().cmple(Self::splat(max_abs_diff)).all()
1013    }
1014
1015    /// Returns a vector with a length no less than `min` and no more than `max`.
1016    ///
1017    /// # Panics
1018    ///
1019    /// Will panic if `min` is greater than `max`, or if either `min` or `max` is negative, when `glam_assert` is enabled.
1020    #[inline]
1021    #[must_use]
1022    pub fn clamp_length(self, min: f32, max: f32) -> Self {
1023        glam_assert!(0.0 <= min);
1024        glam_assert!(min <= max);
1025        let length_sq = self.length_squared();
1026        if length_sq < min * min {
1027            min * (self / math::sqrt(length_sq))
1028        } else if length_sq > max * max {
1029            max * (self / math::sqrt(length_sq))
1030        } else {
1031            self
1032        }
1033    }
1034
1035    /// Returns a vector with a length no more than `max`.
1036    ///
1037    /// # Panics
1038    ///
1039    /// Will panic if `max` is negative when `glam_assert` is enabled.
1040    #[inline]
1041    #[must_use]
1042    pub fn clamp_length_max(self, max: f32) -> Self {
1043        glam_assert!(0.0 <= max);
1044        let length_sq = self.length_squared();
1045        if length_sq > max * max {
1046            max * (self / math::sqrt(length_sq))
1047        } else {
1048            self
1049        }
1050    }
1051
1052    /// Returns a vector with a length no less than `min`.
1053    ///
1054    /// # Panics
1055    ///
1056    /// Will panic if `min` is negative when `glam_assert` is enabled.
1057    #[inline]
1058    #[must_use]
1059    pub fn clamp_length_min(self, min: f32) -> Self {
1060        glam_assert!(0.0 <= min);
1061        let length_sq = self.length_squared();
1062        if length_sq < min * min {
1063            min * (self / math::sqrt(length_sq))
1064        } else {
1065            self
1066        }
1067    }
1068
1069    /// Fused multiply-add. Computes `(self * a) + b` element-wise with only one rounding
1070    /// error, yielding a more accurate result than an unfused multiply-add.
1071    ///
1072    /// Using `mul_add` *may* be more performant than an unfused multiply-add if the target
1073    /// architecture has a dedicated fma CPU instruction. However, this is not always true,
1074    /// and will be heavily dependant on designing algorithms with specific target hardware in
1075    /// mind.
1076    #[inline]
1077    #[must_use]
1078    pub fn mul_add(self, a: Self, b: Self) -> Self {
1079        Self(unsafe { vfmaq_f32(b.0, self.0, a.0) })
1080    }
1081
1082    /// Returns the reflection vector for a given incident vector `self` and surface normal
1083    /// `normal`.
1084    ///
1085    /// `normal` must be normalized.
1086    ///
1087    /// # Panics
1088    ///
1089    /// Will panic if `normal` is not normalized when `glam_assert` is enabled.
1090    #[inline]
1091    #[must_use]
1092    pub fn reflect(self, normal: Self) -> Self {
1093        glam_assert!(normal.is_normalized());
1094        self - 2.0 * self.dot(normal) * normal
1095    }
1096
1097    /// Returns the refraction direction for a given incident vector `self`, surface normal
1098    /// `normal` and ratio of indices of refraction, `eta`. When total internal reflection occurs,
1099    /// a zero vector will be returned.
1100    ///
1101    /// `self` and `normal` must be normalized.
1102    ///
1103    /// # Panics
1104    ///
1105    /// Will panic if `self` or `normal` is not normalized when `glam_assert` is enabled.
1106    #[inline]
1107    #[must_use]
1108    pub fn refract(self, normal: Self, eta: f32) -> Self {
1109        glam_assert!(self.is_normalized());
1110        glam_assert!(normal.is_normalized());
1111        let n_dot_i = normal.dot(self);
1112        let k = 1.0 - eta * eta * (1.0 - n_dot_i * n_dot_i);
1113        if k >= 0.0 {
1114            eta * self - (eta * n_dot_i + math::sqrt(k)) * normal
1115        } else {
1116            Self::ZERO
1117        }
1118    }
1119
1120    /// Returns the angle (in radians) between two vectors in the range `[0, +Ï€]`.
1121    ///
1122    /// The inputs do not need to be unit vectors however they must be non-zero.
1123    #[inline]
1124    #[must_use]
1125    pub fn angle_between(self, rhs: Self) -> f32 {
1126        math::acos_approx(
1127            self.dot(rhs)
1128                .div(math::sqrt(self.length_squared().mul(rhs.length_squared()))),
1129        )
1130    }
1131
1132    /// Rotates around the x axis by `angle` (in radians).
1133    #[inline]
1134    #[must_use]
1135    pub fn rotate_x(self, angle: f32) -> Self {
1136        let (sina, cosa) = math::sin_cos(angle);
1137        Self::new(
1138            self.x,
1139            self.y * cosa - self.z * sina,
1140            self.y * sina + self.z * cosa,
1141        )
1142    }
1143
1144    /// Rotates around the y axis by `angle` (in radians).
1145    #[inline]
1146    #[must_use]
1147    pub fn rotate_y(self, angle: f32) -> Self {
1148        let (sina, cosa) = math::sin_cos(angle);
1149        Self::new(
1150            self.x * cosa + self.z * sina,
1151            self.y,
1152            self.x * -sina + self.z * cosa,
1153        )
1154    }
1155
1156    /// Rotates around the z axis by `angle` (in radians).
1157    #[inline]
1158    #[must_use]
1159    pub fn rotate_z(self, angle: f32) -> Self {
1160        let (sina, cosa) = math::sin_cos(angle);
1161        Self::new(
1162            self.x * cosa - self.y * sina,
1163            self.x * sina + self.y * cosa,
1164            self.z,
1165        )
1166    }
1167
1168    /// Rotates around `axis` by `angle` (in radians).
1169    ///
1170    /// The axis must be a unit vector.
1171    ///
1172    /// # Panics
1173    ///
1174    /// Will panic if `axis` is not normalized when `glam_assert` is enabled.
1175    #[inline]
1176    #[must_use]
1177    pub fn rotate_axis(self, axis: Self, angle: f32) -> Self {
1178        Quat::from_axis_angle(axis.into(), angle) * self
1179    }
1180
1181    /// Rotates towards `rhs` up to `max_angle` (in radians).
1182    ///
1183    /// When `max_angle` is `0.0`, the result will be equal to `self`. When `max_angle` is equal to
1184    /// `self.angle_between(rhs)`, the result will be parallel to `rhs`. If `max_angle` is negative,
1185    /// rotates towards the exact opposite of `rhs`. Will not go past the target.
1186    #[inline]
1187    #[must_use]
1188    pub fn rotate_towards(self, rhs: Self, max_angle: f32) -> Self {
1189        let angle_between = self.angle_between(rhs);
1190        // When `max_angle < 0`, rotate no further than `PI` radians away
1191        let angle = max_angle.clamp(angle_between - core::f32::consts::PI, angle_between);
1192        let axis = self
1193            .cross(rhs)
1194            .try_normalize()
1195            .unwrap_or_else(|| self.any_orthogonal_vector().normalize());
1196        Quat::from_axis_angle(axis.into(), angle) * self
1197    }
1198
1199    /// Returns some vector that is orthogonal to the given one.
1200    ///
1201    /// The input vector must be finite and non-zero.
1202    ///
1203    /// The output vector is not necessarily unit length. For that use
1204    /// [`Self::any_orthonormal_vector()`] instead.
1205    #[inline]
1206    #[must_use]
1207    pub fn any_orthogonal_vector(self) -> Self {
1208        // This can probably be optimized
1209        if math::abs(self.x) > math::abs(self.y) {
1210            Self::new(-self.z, 0.0, self.x) // self.cross(Self::Y)
1211        } else {
1212            Self::new(0.0, self.z, -self.y) // self.cross(Self::X)
1213        }
1214    }
1215
1216    /// Returns any unit vector that is orthogonal to the given one.
1217    ///
1218    /// The input vector must be unit length.
1219    ///
1220    /// # Panics
1221    ///
1222    /// Will panic if `self` is not normalized when `glam_assert` is enabled.
1223    #[inline]
1224    #[must_use]
1225    pub fn any_orthonormal_vector(self) -> Self {
1226        glam_assert!(self.is_normalized());
1227        // From https://graphics.pixar.com/library/OrthonormalB/paper.pdf
1228        let sign = math::signum(self.z);
1229        let a = -1.0 / (sign + self.z);
1230        let b = self.x * self.y * a;
1231        Self::new(b, sign + self.y * self.y * a, -self.y)
1232    }
1233
1234    /// Given a unit vector return two other vectors that together form a right-handed orthonormal
1235    /// basis. That is, all three vectors are orthogonal to each other and are normalized.
1236    ///
1237    /// # Panics
1238    ///
1239    /// Will panic if `self` is not normalized when `glam_assert` is enabled.
1240    #[inline]
1241    #[must_use]
1242    pub fn any_orthonormal_pair(self) -> (Self, Self) {
1243        glam_assert!(self.is_normalized());
1244        // From https://graphics.pixar.com/library/OrthonormalB/paper.pdf
1245        let sign = math::signum(self.z);
1246        let a = -1.0 / (sign + self.z);
1247        let b = self.x * self.y * a;
1248        (
1249            Self::new(1.0 + sign * self.x * self.x * a, sign * b, -sign * self.x),
1250            Self::new(b, sign + self.y * self.y * a, -self.y),
1251        )
1252    }
1253
1254    /// Performs a spherical linear interpolation between `self` and `rhs` based on the value `s`.
1255    ///
1256    /// When `s` is `0.0`, the result will be equal to `self`.  When `s` is `1.0`, the result
1257    /// will be equal to `rhs`. When `s` is outside of range `[0, 1]`, the result is linearly
1258    /// extrapolated.
1259    #[inline]
1260    #[must_use]
1261    pub fn slerp(self, rhs: Self, s: f32) -> Self {
1262        let self_length = self.length();
1263        let rhs_length = rhs.length();
1264        // Cosine of the angle between the vectors [-1, 1], or NaN if either vector has a zero length
1265        let dot = self.dot(rhs) / (self_length * rhs_length);
1266        // If dot is close to 1 or -1, or is NaN the calculations for t1 and t2 break down
1267        if math::abs(dot) < 1.0 - 3e-7 {
1268            // Angle between the vectors [0, +Ï€]
1269            let theta = math::acos_approx(dot);
1270            // Sine of the angle between vectors [0, 1]
1271            let sin_theta = math::sin(theta);
1272            let t1 = math::sin(theta * (1. - s));
1273            let t2 = math::sin(theta * s);
1274
1275            // Interpolate vector lengths
1276            let result_length = self_length.lerp(rhs_length, s);
1277            // Scale the vectors to the target length and interpolate them
1278            return (self * (result_length / self_length) * t1
1279                + rhs * (result_length / rhs_length) * t2)
1280                * sin_theta.recip();
1281        }
1282        if dot < 0.0 {
1283            // Vectors are almost parallel in opposing directions
1284
1285            // Create a rotation from self to rhs along some axis
1286            let axis = self.any_orthogonal_vector().normalize().into();
1287            let rotation = Quat::from_axis_angle(axis, core::f32::consts::PI * s);
1288            // Interpolate vector lengths
1289            let result_length = self_length.lerp(rhs_length, s);
1290            rotation * self * (result_length / self_length)
1291        } else {
1292            // Vectors are almost parallel in the same direction, or dot was NaN
1293            self.lerp(rhs, s)
1294        }
1295    }
1296
1297    /// Casts all elements of `self` to `f64`.
1298    #[cfg(feature = "f64")]
1299    #[inline]
1300    #[must_use]
1301    pub fn as_dvec3(self) -> crate::DVec3 {
1302        crate::DVec3::new(self.x as f64, self.y as f64, self.z as f64)
1303    }
1304
1305    /// Casts all elements of `self` to `i8`.
1306    #[cfg(feature = "i8")]
1307    #[inline]
1308    #[must_use]
1309    pub fn as_i8vec3(self) -> crate::I8Vec3 {
1310        crate::I8Vec3::new(self.x as i8, self.y as i8, self.z as i8)
1311    }
1312
1313    /// Casts all elements of `self` to `u8`.
1314    #[cfg(feature = "u8")]
1315    #[inline]
1316    #[must_use]
1317    pub fn as_u8vec3(self) -> crate::U8Vec3 {
1318        crate::U8Vec3::new(self.x as u8, self.y as u8, self.z as u8)
1319    }
1320
1321    /// Casts all elements of `self` to `i16`.
1322    #[cfg(feature = "i16")]
1323    #[inline]
1324    #[must_use]
1325    pub fn as_i16vec3(self) -> crate::I16Vec3 {
1326        crate::I16Vec3::new(self.x as i16, self.y as i16, self.z as i16)
1327    }
1328
1329    /// Casts all elements of `self` to `u16`.
1330    #[cfg(feature = "u16")]
1331    #[inline]
1332    #[must_use]
1333    pub fn as_u16vec3(self) -> crate::U16Vec3 {
1334        crate::U16Vec3::new(self.x as u16, self.y as u16, self.z as u16)
1335    }
1336
1337    /// Casts all elements of `self` to `i32`.
1338    #[cfg(feature = "i32")]
1339    #[inline]
1340    #[must_use]
1341    pub fn as_ivec3(self) -> crate::IVec3 {
1342        crate::IVec3::new(self.x as i32, self.y as i32, self.z as i32)
1343    }
1344
1345    /// Casts all elements of `self` to `u32`.
1346    #[cfg(feature = "u32")]
1347    #[inline]
1348    #[must_use]
1349    pub fn as_uvec3(self) -> crate::UVec3 {
1350        crate::UVec3::new(self.x as u32, self.y as u32, self.z as u32)
1351    }
1352
1353    /// Casts all elements of `self` to `i64`.
1354    #[cfg(feature = "i64")]
1355    #[inline]
1356    #[must_use]
1357    pub fn as_i64vec3(self) -> crate::I64Vec3 {
1358        crate::I64Vec3::new(self.x as i64, self.y as i64, self.z as i64)
1359    }
1360
1361    /// Casts all elements of `self` to `u64`.
1362    #[cfg(feature = "u64")]
1363    #[inline]
1364    #[must_use]
1365    pub fn as_u64vec3(self) -> crate::U64Vec3 {
1366        crate::U64Vec3::new(self.x as u64, self.y as u64, self.z as u64)
1367    }
1368
1369    /// Casts all elements of `self` to `isize`.
1370    #[cfg(feature = "isize")]
1371    #[inline]
1372    #[must_use]
1373    pub fn as_isizevec3(self) -> crate::ISizeVec3 {
1374        crate::ISizeVec3::new(self.x as isize, self.y as isize, self.z as isize)
1375    }
1376
1377    /// Casts all elements of `self` to `usize`.
1378    #[cfg(feature = "usize")]
1379    #[inline]
1380    #[must_use]
1381    pub fn as_usizevec3(self) -> crate::USizeVec3 {
1382        crate::USizeVec3::new(self.x as usize, self.y as usize, self.z as usize)
1383    }
1384}
1385
1386impl Default for Vec3A {
1387    #[inline(always)]
1388    fn default() -> Self {
1389        Self::ZERO
1390    }
1391}
1392
1393impl PartialEq for Vec3A {
1394    #[inline]
1395    fn eq(&self, rhs: &Self) -> bool {
1396        self.cmpeq(*rhs).all()
1397    }
1398}
1399
1400impl Div for Vec3A {
1401    type Output = Self;
1402    #[inline]
1403    fn div(self, rhs: Self) -> Self {
1404        Self(unsafe { vdivq_f32(self.0, rhs.0) })
1405    }
1406}
1407
1408impl Div<&Self> for Vec3A {
1409    type Output = Self;
1410    #[inline]
1411    fn div(self, rhs: &Self) -> Self {
1412        self.div(*rhs)
1413    }
1414}
1415
1416impl Div<&Vec3A> for &Vec3A {
1417    type Output = Vec3A;
1418    #[inline]
1419    fn div(self, rhs: &Vec3A) -> Vec3A {
1420        (*self).div(*rhs)
1421    }
1422}
1423
1424impl Div<Vec3A> for &Vec3A {
1425    type Output = Vec3A;
1426    #[inline]
1427    fn div(self, rhs: Vec3A) -> Vec3A {
1428        (*self).div(rhs)
1429    }
1430}
1431
1432impl DivAssign for Vec3A {
1433    #[inline]
1434    fn div_assign(&mut self, rhs: Self) {
1435        self.0 = unsafe { vdivq_f32(self.0, rhs.0) };
1436    }
1437}
1438
1439impl DivAssign<&Self> for Vec3A {
1440    #[inline]
1441    fn div_assign(&mut self, rhs: &Self) {
1442        self.div_assign(*rhs);
1443    }
1444}
1445
1446impl Div<f32> for Vec3A {
1447    type Output = Self;
1448    #[inline]
1449    fn div(self, rhs: f32) -> Self {
1450        Self(unsafe { vdivq_f32(self.0, vld1q_dup_f32(&rhs)) })
1451    }
1452}
1453
1454impl Div<&f32> for Vec3A {
1455    type Output = Self;
1456    #[inline]
1457    fn div(self, rhs: &f32) -> Self {
1458        self.div(*rhs)
1459    }
1460}
1461
1462impl Div<&f32> for &Vec3A {
1463    type Output = Vec3A;
1464    #[inline]
1465    fn div(self, rhs: &f32) -> Vec3A {
1466        (*self).div(*rhs)
1467    }
1468}
1469
1470impl Div<f32> for &Vec3A {
1471    type Output = Vec3A;
1472    #[inline]
1473    fn div(self, rhs: f32) -> Vec3A {
1474        (*self).div(rhs)
1475    }
1476}
1477
1478impl DivAssign<f32> for Vec3A {
1479    #[inline]
1480    fn div_assign(&mut self, rhs: f32) {
1481        self.0 = unsafe { vdivq_f32(self.0, vld1q_dup_f32(&rhs)) };
1482    }
1483}
1484
1485impl DivAssign<&f32> for Vec3A {
1486    #[inline]
1487    fn div_assign(&mut self, rhs: &f32) {
1488        self.div_assign(*rhs);
1489    }
1490}
1491
1492impl Div<Vec3A> for f32 {
1493    type Output = Vec3A;
1494    #[inline]
1495    fn div(self, rhs: Vec3A) -> Vec3A {
1496        Vec3A(unsafe { vdivq_f32(vld1q_dup_f32(&self), rhs.0) })
1497    }
1498}
1499
1500impl Div<&Vec3A> for f32 {
1501    type Output = Vec3A;
1502    #[inline]
1503    fn div(self, rhs: &Vec3A) -> Vec3A {
1504        self.div(*rhs)
1505    }
1506}
1507
1508impl Div<&Vec3A> for &f32 {
1509    type Output = Vec3A;
1510    #[inline]
1511    fn div(self, rhs: &Vec3A) -> Vec3A {
1512        (*self).div(*rhs)
1513    }
1514}
1515
1516impl Div<Vec3A> for &f32 {
1517    type Output = Vec3A;
1518    #[inline]
1519    fn div(self, rhs: Vec3A) -> Vec3A {
1520        (*self).div(rhs)
1521    }
1522}
1523
1524impl Mul for Vec3A {
1525    type Output = Self;
1526    #[inline]
1527    fn mul(self, rhs: Self) -> Self {
1528        Self(unsafe { vmulq_f32(self.0, rhs.0) })
1529    }
1530}
1531
1532impl Mul<&Self> for Vec3A {
1533    type Output = Self;
1534    #[inline]
1535    fn mul(self, rhs: &Self) -> Self {
1536        self.mul(*rhs)
1537    }
1538}
1539
1540impl Mul<&Vec3A> for &Vec3A {
1541    type Output = Vec3A;
1542    #[inline]
1543    fn mul(self, rhs: &Vec3A) -> Vec3A {
1544        (*self).mul(*rhs)
1545    }
1546}
1547
1548impl Mul<Vec3A> for &Vec3A {
1549    type Output = Vec3A;
1550    #[inline]
1551    fn mul(self, rhs: Vec3A) -> Vec3A {
1552        (*self).mul(rhs)
1553    }
1554}
1555
1556impl MulAssign for Vec3A {
1557    #[inline]
1558    fn mul_assign(&mut self, rhs: Self) {
1559        self.0 = unsafe { vmulq_f32(self.0, rhs.0) };
1560    }
1561}
1562
1563impl MulAssign<&Self> for Vec3A {
1564    #[inline]
1565    fn mul_assign(&mut self, rhs: &Self) {
1566        self.mul_assign(*rhs);
1567    }
1568}
1569
1570impl Mul<f32> for Vec3A {
1571    type Output = Self;
1572    #[inline]
1573    fn mul(self, rhs: f32) -> Self {
1574        Self(unsafe { vmulq_n_f32(self.0, rhs) })
1575    }
1576}
1577
1578impl Mul<&f32> for Vec3A {
1579    type Output = Self;
1580    #[inline]
1581    fn mul(self, rhs: &f32) -> Self {
1582        self.mul(*rhs)
1583    }
1584}
1585
1586impl Mul<&f32> for &Vec3A {
1587    type Output = Vec3A;
1588    #[inline]
1589    fn mul(self, rhs: &f32) -> Vec3A {
1590        (*self).mul(*rhs)
1591    }
1592}
1593
1594impl Mul<f32> for &Vec3A {
1595    type Output = Vec3A;
1596    #[inline]
1597    fn mul(self, rhs: f32) -> Vec3A {
1598        (*self).mul(rhs)
1599    }
1600}
1601
1602impl MulAssign<f32> for Vec3A {
1603    #[inline]
1604    fn mul_assign(&mut self, rhs: f32) {
1605        self.0 = unsafe { vmulq_n_f32(self.0, rhs) };
1606    }
1607}
1608
1609impl MulAssign<&f32> for Vec3A {
1610    #[inline]
1611    fn mul_assign(&mut self, rhs: &f32) {
1612        self.mul_assign(*rhs);
1613    }
1614}
1615
1616impl Mul<Vec3A> for f32 {
1617    type Output = Vec3A;
1618    #[inline]
1619    fn mul(self, rhs: Vec3A) -> Vec3A {
1620        Vec3A(unsafe { vmulq_n_f32(rhs.0, self) })
1621    }
1622}
1623
1624impl Mul<&Vec3A> for f32 {
1625    type Output = Vec3A;
1626    #[inline]
1627    fn mul(self, rhs: &Vec3A) -> Vec3A {
1628        self.mul(*rhs)
1629    }
1630}
1631
1632impl Mul<&Vec3A> for &f32 {
1633    type Output = Vec3A;
1634    #[inline]
1635    fn mul(self, rhs: &Vec3A) -> Vec3A {
1636        (*self).mul(*rhs)
1637    }
1638}
1639
1640impl Mul<Vec3A> for &f32 {
1641    type Output = Vec3A;
1642    #[inline]
1643    fn mul(self, rhs: Vec3A) -> Vec3A {
1644        (*self).mul(rhs)
1645    }
1646}
1647
1648impl Add for Vec3A {
1649    type Output = Self;
1650    #[inline]
1651    fn add(self, rhs: Self) -> Self {
1652        Self(unsafe { vaddq_f32(self.0, rhs.0) })
1653    }
1654}
1655
1656impl Add<&Self> for Vec3A {
1657    type Output = Self;
1658    #[inline]
1659    fn add(self, rhs: &Self) -> Self {
1660        self.add(*rhs)
1661    }
1662}
1663
1664impl Add<&Vec3A> for &Vec3A {
1665    type Output = Vec3A;
1666    #[inline]
1667    fn add(self, rhs: &Vec3A) -> Vec3A {
1668        (*self).add(*rhs)
1669    }
1670}
1671
1672impl Add<Vec3A> for &Vec3A {
1673    type Output = Vec3A;
1674    #[inline]
1675    fn add(self, rhs: Vec3A) -> Vec3A {
1676        (*self).add(rhs)
1677    }
1678}
1679
1680impl AddAssign for Vec3A {
1681    #[inline]
1682    fn add_assign(&mut self, rhs: Self) {
1683        self.0 = unsafe { vaddq_f32(self.0, rhs.0) };
1684    }
1685}
1686
1687impl AddAssign<&Self> for Vec3A {
1688    #[inline]
1689    fn add_assign(&mut self, rhs: &Self) {
1690        self.add_assign(*rhs);
1691    }
1692}
1693
1694impl Add<f32> for Vec3A {
1695    type Output = Self;
1696    #[inline]
1697    fn add(self, rhs: f32) -> Self {
1698        Self(unsafe { vaddq_f32(self.0, vld1q_dup_f32(&rhs)) })
1699    }
1700}
1701
1702impl Add<&f32> for Vec3A {
1703    type Output = Self;
1704    #[inline]
1705    fn add(self, rhs: &f32) -> Self {
1706        self.add(*rhs)
1707    }
1708}
1709
1710impl Add<&f32> for &Vec3A {
1711    type Output = Vec3A;
1712    #[inline]
1713    fn add(self, rhs: &f32) -> Vec3A {
1714        (*self).add(*rhs)
1715    }
1716}
1717
1718impl Add<f32> for &Vec3A {
1719    type Output = Vec3A;
1720    #[inline]
1721    fn add(self, rhs: f32) -> Vec3A {
1722        (*self).add(rhs)
1723    }
1724}
1725
1726impl AddAssign<f32> for Vec3A {
1727    #[inline]
1728    fn add_assign(&mut self, rhs: f32) {
1729        self.0 = unsafe { vaddq_f32(self.0, vld1q_dup_f32(&rhs)) };
1730    }
1731}
1732
1733impl AddAssign<&f32> for Vec3A {
1734    #[inline]
1735    fn add_assign(&mut self, rhs: &f32) {
1736        self.add_assign(*rhs);
1737    }
1738}
1739
1740impl Add<Vec3A> for f32 {
1741    type Output = Vec3A;
1742    #[inline]
1743    fn add(self, rhs: Vec3A) -> Vec3A {
1744        Vec3A(unsafe { vaddq_f32(vld1q_dup_f32(&self), rhs.0) })
1745    }
1746}
1747
1748impl Add<&Vec3A> for f32 {
1749    type Output = Vec3A;
1750    #[inline]
1751    fn add(self, rhs: &Vec3A) -> Vec3A {
1752        self.add(*rhs)
1753    }
1754}
1755
1756impl Add<&Vec3A> for &f32 {
1757    type Output = Vec3A;
1758    #[inline]
1759    fn add(self, rhs: &Vec3A) -> Vec3A {
1760        (*self).add(*rhs)
1761    }
1762}
1763
1764impl Add<Vec3A> for &f32 {
1765    type Output = Vec3A;
1766    #[inline]
1767    fn add(self, rhs: Vec3A) -> Vec3A {
1768        (*self).add(rhs)
1769    }
1770}
1771
1772impl Sub for Vec3A {
1773    type Output = Self;
1774    #[inline]
1775    fn sub(self, rhs: Self) -> Self {
1776        Self(unsafe { vsubq_f32(self.0, rhs.0) })
1777    }
1778}
1779
1780impl Sub<&Self> for Vec3A {
1781    type Output = Self;
1782    #[inline]
1783    fn sub(self, rhs: &Self) -> Self {
1784        self.sub(*rhs)
1785    }
1786}
1787
1788impl Sub<&Vec3A> for &Vec3A {
1789    type Output = Vec3A;
1790    #[inline]
1791    fn sub(self, rhs: &Vec3A) -> Vec3A {
1792        (*self).sub(*rhs)
1793    }
1794}
1795
1796impl Sub<Vec3A> for &Vec3A {
1797    type Output = Vec3A;
1798    #[inline]
1799    fn sub(self, rhs: Vec3A) -> Vec3A {
1800        (*self).sub(rhs)
1801    }
1802}
1803
1804impl SubAssign for Vec3A {
1805    #[inline]
1806    fn sub_assign(&mut self, rhs: Self) {
1807        self.0 = unsafe { vsubq_f32(self.0, rhs.0) };
1808    }
1809}
1810
1811impl SubAssign<&Self> for Vec3A {
1812    #[inline]
1813    fn sub_assign(&mut self, rhs: &Self) {
1814        self.sub_assign(*rhs);
1815    }
1816}
1817
1818impl Sub<f32> for Vec3A {
1819    type Output = Self;
1820    #[inline]
1821    fn sub(self, rhs: f32) -> Self {
1822        Self(unsafe { vsubq_f32(self.0, vld1q_dup_f32(&rhs)) })
1823    }
1824}
1825
1826impl Sub<&f32> for Vec3A {
1827    type Output = Self;
1828    #[inline]
1829    fn sub(self, rhs: &f32) -> Self {
1830        self.sub(*rhs)
1831    }
1832}
1833
1834impl Sub<&f32> for &Vec3A {
1835    type Output = Vec3A;
1836    #[inline]
1837    fn sub(self, rhs: &f32) -> Vec3A {
1838        (*self).sub(*rhs)
1839    }
1840}
1841
1842impl Sub<f32> for &Vec3A {
1843    type Output = Vec3A;
1844    #[inline]
1845    fn sub(self, rhs: f32) -> Vec3A {
1846        (*self).sub(rhs)
1847    }
1848}
1849
1850impl SubAssign<f32> for Vec3A {
1851    #[inline]
1852    fn sub_assign(&mut self, rhs: f32) {
1853        self.0 = unsafe { vsubq_f32(self.0, vld1q_dup_f32(&rhs)) };
1854    }
1855}
1856
1857impl SubAssign<&f32> for Vec3A {
1858    #[inline]
1859    fn sub_assign(&mut self, rhs: &f32) {
1860        self.sub_assign(*rhs);
1861    }
1862}
1863
1864impl Sub<Vec3A> for f32 {
1865    type Output = Vec3A;
1866    #[inline]
1867    fn sub(self, rhs: Vec3A) -> Vec3A {
1868        Vec3A(unsafe { vsubq_f32(vld1q_dup_f32(&self), rhs.0) })
1869    }
1870}
1871
1872impl Sub<&Vec3A> for f32 {
1873    type Output = Vec3A;
1874    #[inline]
1875    fn sub(self, rhs: &Vec3A) -> Vec3A {
1876        self.sub(*rhs)
1877    }
1878}
1879
1880impl Sub<&Vec3A> for &f32 {
1881    type Output = Vec3A;
1882    #[inline]
1883    fn sub(self, rhs: &Vec3A) -> Vec3A {
1884        (*self).sub(*rhs)
1885    }
1886}
1887
1888impl Sub<Vec3A> for &f32 {
1889    type Output = Vec3A;
1890    #[inline]
1891    fn sub(self, rhs: Vec3A) -> Vec3A {
1892        (*self).sub(rhs)
1893    }
1894}
1895
1896impl Rem for Vec3A {
1897    type Output = Self;
1898    #[inline]
1899    fn rem(self, rhs: Self) -> Self {
1900        unsafe {
1901            let n = vrndmq_f32(vdivq_f32(self.0, rhs.0));
1902            Self(vsubq_f32(self.0, vmulq_f32(n, rhs.0)))
1903        }
1904    }
1905}
1906
1907impl Rem<&Self> for Vec3A {
1908    type Output = Self;
1909    #[inline]
1910    fn rem(self, rhs: &Self) -> Self {
1911        self.rem(*rhs)
1912    }
1913}
1914
1915impl Rem<&Vec3A> for &Vec3A {
1916    type Output = Vec3A;
1917    #[inline]
1918    fn rem(self, rhs: &Vec3A) -> Vec3A {
1919        (*self).rem(*rhs)
1920    }
1921}
1922
1923impl Rem<Vec3A> for &Vec3A {
1924    type Output = Vec3A;
1925    #[inline]
1926    fn rem(self, rhs: Vec3A) -> Vec3A {
1927        (*self).rem(rhs)
1928    }
1929}
1930
1931impl RemAssign for Vec3A {
1932    #[inline]
1933    fn rem_assign(&mut self, rhs: Self) {
1934        *self = self.rem(rhs);
1935    }
1936}
1937
1938impl RemAssign<&Self> for Vec3A {
1939    #[inline]
1940    fn rem_assign(&mut self, rhs: &Self) {
1941        self.rem_assign(*rhs);
1942    }
1943}
1944
1945impl Rem<f32> for Vec3A {
1946    type Output = Self;
1947    #[inline]
1948    fn rem(self, rhs: f32) -> Self {
1949        self.rem(Self::splat(rhs))
1950    }
1951}
1952
1953impl Rem<&f32> for Vec3A {
1954    type Output = Self;
1955    #[inline]
1956    fn rem(self, rhs: &f32) -> Self {
1957        self.rem(*rhs)
1958    }
1959}
1960
1961impl Rem<&f32> for &Vec3A {
1962    type Output = Vec3A;
1963    #[inline]
1964    fn rem(self, rhs: &f32) -> Vec3A {
1965        (*self).rem(*rhs)
1966    }
1967}
1968
1969impl Rem<f32> for &Vec3A {
1970    type Output = Vec3A;
1971    #[inline]
1972    fn rem(self, rhs: f32) -> Vec3A {
1973        (*self).rem(rhs)
1974    }
1975}
1976
1977impl RemAssign<f32> for Vec3A {
1978    #[inline]
1979    fn rem_assign(&mut self, rhs: f32) {
1980        *self = self.rem(Self::splat(rhs));
1981    }
1982}
1983
1984impl RemAssign<&f32> for Vec3A {
1985    #[inline]
1986    fn rem_assign(&mut self, rhs: &f32) {
1987        self.rem_assign(*rhs);
1988    }
1989}
1990
1991impl Rem<Vec3A> for f32 {
1992    type Output = Vec3A;
1993    #[inline]
1994    fn rem(self, rhs: Vec3A) -> Vec3A {
1995        Vec3A::splat(self).rem(rhs)
1996    }
1997}
1998
1999impl Rem<&Vec3A> for f32 {
2000    type Output = Vec3A;
2001    #[inline]
2002    fn rem(self, rhs: &Vec3A) -> Vec3A {
2003        self.rem(*rhs)
2004    }
2005}
2006
2007impl Rem<&Vec3A> for &f32 {
2008    type Output = Vec3A;
2009    #[inline]
2010    fn rem(self, rhs: &Vec3A) -> Vec3A {
2011        (*self).rem(*rhs)
2012    }
2013}
2014
2015impl Rem<Vec3A> for &f32 {
2016    type Output = Vec3A;
2017    #[inline]
2018    fn rem(self, rhs: Vec3A) -> Vec3A {
2019        (*self).rem(rhs)
2020    }
2021}
2022
2023impl AsRef<[f32; 3]> for Vec3A {
2024    #[inline]
2025    fn as_ref(&self) -> &[f32; 3] {
2026        unsafe { &*(self as *const Self as *const [f32; 3]) }
2027    }
2028}
2029
2030impl AsMut<[f32; 3]> for Vec3A {
2031    #[inline]
2032    fn as_mut(&mut self) -> &mut [f32; 3] {
2033        unsafe { &mut *(self as *mut Self as *mut [f32; 3]) }
2034    }
2035}
2036
2037impl Sum for Vec3A {
2038    #[inline]
2039    fn sum<I>(iter: I) -> Self
2040    where
2041        I: Iterator<Item = Self>,
2042    {
2043        iter.fold(Self::ZERO, Self::add)
2044    }
2045}
2046
2047impl<'a> Sum<&'a Self> for Vec3A {
2048    #[inline]
2049    fn sum<I>(iter: I) -> Self
2050    where
2051        I: Iterator<Item = &'a Self>,
2052    {
2053        iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
2054    }
2055}
2056
2057impl Product for Vec3A {
2058    #[inline]
2059    fn product<I>(iter: I) -> Self
2060    where
2061        I: Iterator<Item = Self>,
2062    {
2063        iter.fold(Self::ONE, Self::mul)
2064    }
2065}
2066
2067impl<'a> Product<&'a Self> for Vec3A {
2068    #[inline]
2069    fn product<I>(iter: I) -> Self
2070    where
2071        I: Iterator<Item = &'a Self>,
2072    {
2073        iter.fold(Self::ONE, |a, &b| Self::mul(a, b))
2074    }
2075}
2076
2077impl Neg for Vec3A {
2078    type Output = Self;
2079    #[inline]
2080    fn neg(self) -> Self {
2081        Self(unsafe { vnegq_f32(self.0) })
2082    }
2083}
2084
2085impl Neg for &Vec3A {
2086    type Output = Vec3A;
2087    #[inline]
2088    fn neg(self) -> Vec3A {
2089        (*self).neg()
2090    }
2091}
2092
2093impl Index<usize> for Vec3A {
2094    type Output = f32;
2095    #[inline]
2096    fn index(&self, index: usize) -> &Self::Output {
2097        match index {
2098            0 => &self.x,
2099            1 => &self.y,
2100            2 => &self.z,
2101            _ => panic!("index out of bounds"),
2102        }
2103    }
2104}
2105
2106impl IndexMut<usize> for Vec3A {
2107    #[inline]
2108    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
2109        match index {
2110            0 => &mut self.x,
2111            1 => &mut self.y,
2112            2 => &mut self.z,
2113            _ => panic!("index out of bounds"),
2114        }
2115    }
2116}
2117
2118impl fmt::Display for Vec3A {
2119    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2120        if let Some(p) = f.precision() {
2121            write!(f, "[{:.*}, {:.*}, {:.*}]", p, self.x, p, self.y, p, self.z)
2122        } else {
2123            write!(f, "[{}, {}, {}]", self.x, self.y, self.z)
2124        }
2125    }
2126}
2127
2128impl fmt::Debug for Vec3A {
2129    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
2130        fmt.debug_tuple(stringify!(Vec3A))
2131            .field(&self.x)
2132            .field(&self.y)
2133            .field(&self.z)
2134            .finish()
2135    }
2136}
2137
2138impl From<Vec3A> for float32x4_t {
2139    #[inline(always)]
2140    fn from(t: Vec3A) -> Self {
2141        t.0
2142    }
2143}
2144
2145impl From<float32x4_t> for Vec3A {
2146    #[inline(always)]
2147    fn from(t: float32x4_t) -> Self {
2148        Self(t)
2149    }
2150}
2151
2152impl From<[f32; 3]> for Vec3A {
2153    #[inline]
2154    fn from(a: [f32; 3]) -> Self {
2155        Self::new(a[0], a[1], a[2])
2156    }
2157}
2158
2159impl From<Vec3A> for [f32; 3] {
2160    #[inline]
2161    fn from(v: Vec3A) -> Self {
2162        use crate::align16::Align16;
2163        use core::mem::MaybeUninit;
2164        let mut out: MaybeUninit<Align16<Self>> = MaybeUninit::uninit();
2165        unsafe {
2166            vst1q_f32(out.as_mut_ptr().cast(), v.0);
2167            out.assume_init().0
2168        }
2169    }
2170}
2171
2172impl From<(f32, f32, f32)> for Vec3A {
2173    #[inline]
2174    fn from(t: (f32, f32, f32)) -> Self {
2175        Self::new(t.0, t.1, t.2)
2176    }
2177}
2178
2179impl From<Vec3A> for (f32, f32, f32) {
2180    #[inline]
2181    fn from(v: Vec3A) -> Self {
2182        (v.x, v.y, v.z)
2183    }
2184}
2185
2186impl From<Vec3> for Vec3A {
2187    #[inline]
2188    fn from(v: Vec3) -> Self {
2189        Self::new(v.x, v.y, v.z)
2190    }
2191}
2192
2193impl From<Vec3A> for Vec3 {
2194    #[inline]
2195    fn from(v: Vec3A) -> Self {
2196        use crate::align16::Align16;
2197        use core::mem::MaybeUninit;
2198        let mut out: MaybeUninit<Align16<Self>> = MaybeUninit::uninit();
2199        unsafe {
2200            vst1q_f32(out.as_mut_ptr().cast(), v.0);
2201            out.assume_init().0
2202        }
2203    }
2204}
2205
2206impl From<(Vec2, f32)> for Vec3A {
2207    #[inline]
2208    fn from((v, z): (Vec2, f32)) -> Self {
2209        Self::new(v.x, v.y, z)
2210    }
2211}
2212
2213impl Deref for Vec3A {
2214    type Target = crate::deref::Vec3<f32>;
2215    #[inline]
2216    fn deref(&self) -> &Self::Target {
2217        unsafe { &*(self as *const Self).cast() }
2218    }
2219}
2220
2221impl DerefMut for Vec3A {
2222    #[inline]
2223    fn deref_mut(&mut self) -> &mut Self::Target {
2224        unsafe { &mut *(self as *mut Self).cast() }
2225    }
2226}
2227
2228impl From<BVec3> for Vec3A {
2229    #[inline]
2230    fn from(v: BVec3) -> Self {
2231        Self::new(f32::from(v.x), f32::from(v.y), f32::from(v.z))
2232    }
2233}
2234
2235impl From<BVec3A> for Vec3A {
2236    #[inline]
2237    fn from(v: BVec3A) -> Self {
2238        let bool_array: [bool; 3] = v.into();
2239        Self::new(
2240            f32::from(bool_array[0]),
2241            f32::from(bool_array[1]),
2242            f32::from(bool_array[2]),
2243        )
2244    }
2245}