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