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