Skip to main content

glam/f32/sse2/
vec3a.rs

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