Skip to main content

glam/f32/neon/
vec4.rs

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