Skip to main content

glam/f32/sse2/
vec4.rs

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