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