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