1 // Generated from vec.rs.tera template. Edit the template, not the generated file.
2 
3 use crate::{f32::math, sse2::*, BVec3A, Vec2, Vec3, Vec4};
4 
5 #[cfg(not(target_arch = "spirv"))]
6 use core::fmt;
7 use core::iter::{Product, Sum};
8 use core::{f32, ops::*};
9 
10 #[cfg(target_arch = "x86")]
11 use core::arch::x86::*;
12 #[cfg(target_arch = "x86_64")]
13 use core::arch::x86_64::*;
14 
15 #[repr(C)]
16 union UnionCast {
17     a: [f32; 4],
18     v: Vec3A,
19 }
20 
21 /// Creates a 3-dimensional vector.
22 #[inline(always)]
23 #[must_use]
vec3a(x: f32, y: f32, z: f32) -> Vec3A24 pub const fn vec3a(x: f32, y: f32, z: f32) -> Vec3A {
25     Vec3A::new(x, y, z)
26 }
27 
28 /// A 3-dimensional vector.
29 ///
30 /// SIMD vector types are used for storage on supported platforms for better
31 /// performance than the [`Vec3`] type.
32 ///
33 /// It is possible to convert between [`Vec3`] and [`Vec3A`] types using [`From`]
34 /// or [`Into`] trait implementations.
35 ///
36 /// This type is 16 byte aligned.
37 #[derive(Clone, Copy)]
38 #[repr(transparent)]
39 pub struct Vec3A(pub(crate) __m128);
40 
41 impl Vec3A {
42     /// All zeroes.
43     pub const ZERO: Self = Self::splat(0.0);
44 
45     /// All ones.
46     pub const ONE: Self = Self::splat(1.0);
47 
48     /// All negative ones.
49     pub const NEG_ONE: Self = Self::splat(-1.0);
50 
51     /// All `f32::MIN`.
52     pub const MIN: Self = Self::splat(f32::MIN);
53 
54     /// All `f32::MAX`.
55     pub const MAX: Self = Self::splat(f32::MAX);
56 
57     /// All `f32::NAN`.
58     pub const NAN: Self = Self::splat(f32::NAN);
59 
60     /// All `f32::INFINITY`.
61     pub const INFINITY: Self = Self::splat(f32::INFINITY);
62 
63     /// All `f32::NEG_INFINITY`.
64     pub const NEG_INFINITY: Self = Self::splat(f32::NEG_INFINITY);
65 
66     /// A unit vector pointing along the positive X axis.
67     pub const X: Self = Self::new(1.0, 0.0, 0.0);
68 
69     /// A unit vector pointing along the positive Y axis.
70     pub const Y: Self = Self::new(0.0, 1.0, 0.0);
71 
72     /// A unit vector pointing along the positive Z axis.
73     pub const Z: Self = Self::new(0.0, 0.0, 1.0);
74 
75     /// A unit vector pointing along the negative X axis.
76     pub const NEG_X: Self = Self::new(-1.0, 0.0, 0.0);
77 
78     /// A unit vector pointing along the negative Y axis.
79     pub const NEG_Y: Self = Self::new(0.0, -1.0, 0.0);
80 
81     /// A unit vector pointing along the negative Z axis.
82     pub const NEG_Z: Self = Self::new(0.0, 0.0, -1.0);
83 
84     /// The unit axes.
85     pub const AXES: [Self; 3] = [Self::X, Self::Y, Self::Z];
86 
87     /// Creates a new vector.
88     #[inline(always)]
89     #[must_use]
new(x: f32, y: f32, z: f32) -> Self90     pub const fn new(x: f32, y: f32, z: f32) -> Self {
91         unsafe { UnionCast { a: [x, y, z, z] }.v }
92     }
93 
94     /// Creates a vector with all elements set to `v`.
95     #[inline]
96     #[must_use]
splat(v: f32) -> Self97     pub const fn splat(v: f32) -> Self {
98         unsafe { UnionCast { a: [v; 4] }.v }
99     }
100 
101     /// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use
102     /// for each element of `self`.
103     ///
104     /// A true element in the mask uses the corresponding element from `if_true`, and false
105     /// uses the element from `if_false`.
106     #[inline]
107     #[must_use]
select(mask: BVec3A, if_true: Self, if_false: Self) -> Self108     pub fn select(mask: BVec3A, if_true: Self, if_false: Self) -> Self {
109         Self(unsafe {
110             _mm_or_ps(
111                 _mm_andnot_ps(mask.0, if_false.0),
112                 _mm_and_ps(if_true.0, mask.0),
113             )
114         })
115     }
116 
117     /// Creates a new vector from an array.
118     #[inline]
119     #[must_use]
from_array(a: [f32; 3]) -> Self120     pub const fn from_array(a: [f32; 3]) -> Self {
121         Self::new(a[0], a[1], a[2])
122     }
123 
124     /// `[x, y, z]`
125     #[inline]
126     #[must_use]
to_array(&self) -> [f32; 3]127     pub const fn to_array(&self) -> [f32; 3] {
128         unsafe { *(self as *const Vec3A as *const [f32; 3]) }
129     }
130 
131     /// Creates a vector from the first 3 values in `slice`.
132     ///
133     /// # Panics
134     ///
135     /// Panics if `slice` is less than 3 elements long.
136     #[inline]
137     #[must_use]
from_slice(slice: &[f32]) -> Self138     pub const fn from_slice(slice: &[f32]) -> Self {
139         Self::new(slice[0], slice[1], slice[2])
140     }
141 
142     /// Writes the elements of `self` to the first 3 elements in `slice`.
143     ///
144     /// # Panics
145     ///
146     /// Panics if `slice` is less than 3 elements long.
147     #[inline]
write_to_slice(self, slice: &mut [f32])148     pub fn write_to_slice(self, slice: &mut [f32]) {
149         slice[0] = self.x;
150         slice[1] = self.y;
151         slice[2] = self.z;
152     }
153 
154     /// Internal method for creating a 3D vector from a 4D vector, discarding `w`.
155     #[allow(dead_code)]
156     #[inline]
157     #[must_use]
from_vec4(v: Vec4) -> Self158     pub(crate) fn from_vec4(v: Vec4) -> Self {
159         Self(v.0)
160     }
161 
162     /// Creates a 4D vector from `self` and the given `w` value.
163     #[inline]
164     #[must_use]
extend(self, w: f32) -> Vec4165     pub fn extend(self, w: f32) -> Vec4 {
166         Vec4::new(self.x, self.y, self.z, w)
167     }
168 
169     /// Creates a 2D vector from the `x` and `y` elements of `self`, discarding `z`.
170     ///
171     /// Truncation may also be performed by using [`self.xy()`][crate::swizzles::Vec3Swizzles::xy()].
172     #[inline]
173     #[must_use]
truncate(self) -> Vec2174     pub fn truncate(self) -> Vec2 {
175         use crate::swizzles::Vec3Swizzles;
176         self.xy()
177     }
178 
179     /// Computes the dot product of `self` and `rhs`.
180     #[inline]
181     #[must_use]
dot(self, rhs: Self) -> f32182     pub fn dot(self, rhs: Self) -> f32 {
183         unsafe { dot3(self.0, rhs.0) }
184     }
185 
186     /// Returns a vector where every component is the dot product of `self` and `rhs`.
187     #[inline]
188     #[must_use]
dot_into_vec(self, rhs: Self) -> Self189     pub fn dot_into_vec(self, rhs: Self) -> Self {
190         Self(unsafe { dot3_into_m128(self.0, rhs.0) })
191     }
192 
193     /// Computes the cross product of `self` and `rhs`.
194     #[inline]
195     #[must_use]
cross(self, rhs: Self) -> Self196     pub fn cross(self, rhs: Self) -> Self {
197         unsafe {
198             // x  <-  a.y*b.z - a.z*b.y
199             // y  <-  a.z*b.x - a.x*b.z
200             // z  <-  a.x*b.y - a.y*b.x
201             // We can save a shuffle by grouping it in this wacky order:
202             // (self.zxy() * rhs - self * rhs.zxy()).zxy()
203             let lhszxy = _mm_shuffle_ps(self.0, self.0, 0b01_01_00_10);
204             let rhszxy = _mm_shuffle_ps(rhs.0, rhs.0, 0b01_01_00_10);
205             let lhszxy_rhs = _mm_mul_ps(lhszxy, rhs.0);
206             let rhszxy_lhs = _mm_mul_ps(rhszxy, self.0);
207             let sub = _mm_sub_ps(lhszxy_rhs, rhszxy_lhs);
208             Self(_mm_shuffle_ps(sub, sub, 0b01_01_00_10))
209         }
210     }
211 
212     /// Returns a vector containing the minimum values for each element of `self` and `rhs`.
213     ///
214     /// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`.
215     #[inline]
216     #[must_use]
min(self, rhs: Self) -> Self217     pub fn min(self, rhs: Self) -> Self {
218         Self(unsafe { _mm_min_ps(self.0, rhs.0) })
219     }
220 
221     /// Returns a vector containing the maximum values for each element of `self` and `rhs`.
222     ///
223     /// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`.
224     #[inline]
225     #[must_use]
max(self, rhs: Self) -> Self226     pub fn max(self, rhs: Self) -> Self {
227         Self(unsafe { _mm_max_ps(self.0, rhs.0) })
228     }
229 
230     /// Component-wise clamping of values, similar to [`f32::clamp`].
231     ///
232     /// Each element in `min` must be less-or-equal to the corresponding element in `max`.
233     ///
234     /// # Panics
235     ///
236     /// Will panic if `min` is greater than `max` when `glam_assert` is enabled.
237     #[inline]
238     #[must_use]
clamp(self, min: Self, max: Self) -> Self239     pub fn clamp(self, min: Self, max: Self) -> Self {
240         glam_assert!(min.cmple(max).all(), "clamp: expected min <= max");
241         self.max(min).min(max)
242     }
243 
244     /// Returns the horizontal minimum of `self`.
245     ///
246     /// In other words this computes `min(x, y, ..)`.
247     #[inline]
248     #[must_use]
min_element(self) -> f32249     pub fn min_element(self) -> f32 {
250         unsafe {
251             let v = self.0;
252             let v = _mm_min_ps(v, _mm_shuffle_ps(v, v, 0b01_01_10_10));
253             let v = _mm_min_ps(v, _mm_shuffle_ps(v, v, 0b00_00_00_01));
254             _mm_cvtss_f32(v)
255         }
256     }
257 
258     /// Returns the horizontal maximum of `self`.
259     ///
260     /// In other words this computes `max(x, y, ..)`.
261     #[inline]
262     #[must_use]
max_element(self) -> f32263     pub fn max_element(self) -> f32 {
264         unsafe {
265             let v = self.0;
266             let v = _mm_max_ps(v, _mm_shuffle_ps(v, v, 0b00_00_10_10));
267             let v = _mm_max_ps(v, _mm_shuffle_ps(v, v, 0b00_00_00_01));
268             _mm_cvtss_f32(v)
269         }
270     }
271 
272     /// Returns a vector mask containing the result of a `==` comparison for each element of
273     /// `self` and `rhs`.
274     ///
275     /// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all
276     /// elements.
277     #[inline]
278     #[must_use]
cmpeq(self, rhs: Self) -> BVec3A279     pub fn cmpeq(self, rhs: Self) -> BVec3A {
280         BVec3A(unsafe { _mm_cmpeq_ps(self.0, rhs.0) })
281     }
282 
283     /// Returns a vector mask containing the result of a `!=` comparison for each element of
284     /// `self` and `rhs`.
285     ///
286     /// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all
287     /// elements.
288     #[inline]
289     #[must_use]
cmpne(self, rhs: Self) -> BVec3A290     pub fn cmpne(self, rhs: Self) -> BVec3A {
291         BVec3A(unsafe { _mm_cmpneq_ps(self.0, rhs.0) })
292     }
293 
294     /// Returns a vector mask containing the result of a `>=` comparison for each element of
295     /// `self` and `rhs`.
296     ///
297     /// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all
298     /// elements.
299     #[inline]
300     #[must_use]
cmpge(self, rhs: Self) -> BVec3A301     pub fn cmpge(self, rhs: Self) -> BVec3A {
302         BVec3A(unsafe { _mm_cmpge_ps(self.0, rhs.0) })
303     }
304 
305     /// Returns a vector mask containing the result of a `>` comparison for each element of
306     /// `self` and `rhs`.
307     ///
308     /// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all
309     /// elements.
310     #[inline]
311     #[must_use]
cmpgt(self, rhs: Self) -> BVec3A312     pub fn cmpgt(self, rhs: Self) -> BVec3A {
313         BVec3A(unsafe { _mm_cmpgt_ps(self.0, rhs.0) })
314     }
315 
316     /// Returns a vector mask containing the result of a `<=` comparison for each element of
317     /// `self` and `rhs`.
318     ///
319     /// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all
320     /// elements.
321     #[inline]
322     #[must_use]
cmple(self, rhs: Self) -> BVec3A323     pub fn cmple(self, rhs: Self) -> BVec3A {
324         BVec3A(unsafe { _mm_cmple_ps(self.0, rhs.0) })
325     }
326 
327     /// Returns a vector mask containing the result of a `<` comparison for each element of
328     /// `self` and `rhs`.
329     ///
330     /// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all
331     /// elements.
332     #[inline]
333     #[must_use]
cmplt(self, rhs: Self) -> BVec3A334     pub fn cmplt(self, rhs: Self) -> BVec3A {
335         BVec3A(unsafe { _mm_cmplt_ps(self.0, rhs.0) })
336     }
337 
338     /// Returns a vector containing the absolute value of each element of `self`.
339     #[inline]
340     #[must_use]
abs(self) -> Self341     pub fn abs(self) -> Self {
342         Self(unsafe { crate::sse2::m128_abs(self.0) })
343     }
344 
345     /// Returns a vector with elements representing the sign of `self`.
346     ///
347     /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
348     /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
349     /// - `NAN` if the number is `NAN`
350     #[inline]
351     #[must_use]
signum(self) -> Self352     pub fn signum(self) -> Self {
353         unsafe {
354             let result = Self(_mm_or_ps(_mm_and_ps(self.0, Self::NEG_ONE.0), Self::ONE.0));
355             let mask = self.is_nan_mask();
356             Self::select(mask, self, result)
357         }
358     }
359 
360     /// Returns a vector with signs of `rhs` and the magnitudes of `self`.
361     #[inline]
362     #[must_use]
copysign(self, rhs: Self) -> Self363     pub fn copysign(self, rhs: Self) -> Self {
364         unsafe {
365             let mask = Self::splat(-0.0);
366             Self(_mm_or_ps(
367                 _mm_and_ps(rhs.0, mask.0),
368                 _mm_andnot_ps(mask.0, self.0),
369             ))
370         }
371     }
372 
373     /// Returns a bitmask with the lowest 3 bits set to the sign bits from the elements of `self`.
374     ///
375     /// A negative element results in a `1` bit and a positive element in a `0` bit.  Element `x` goes
376     /// into the first lowest bit, element `y` into the second, etc.
377     #[inline]
378     #[must_use]
is_negative_bitmask(self) -> u32379     pub fn is_negative_bitmask(self) -> u32 {
380         unsafe { (_mm_movemask_ps(self.0) as u32) & 0x7 }
381     }
382 
383     /// Returns `true` if, and only if, all elements are finite.  If any element is either
384     /// `NaN`, positive or negative infinity, this will return `false`.
385     #[inline]
386     #[must_use]
is_finite(self) -> bool387     pub fn is_finite(self) -> bool {
388         self.x.is_finite() && self.y.is_finite() && self.z.is_finite()
389     }
390 
391     /// Returns `true` if any elements are `NaN`.
392     #[inline]
393     #[must_use]
is_nan(self) -> bool394     pub fn is_nan(self) -> bool {
395         self.is_nan_mask().any()
396     }
397 
398     /// Performs `is_nan` on each element of self, returning a vector mask of the results.
399     ///
400     /// In other words, this computes `[x.is_nan(), y.is_nan(), z.is_nan(), w.is_nan()]`.
401     #[inline]
402     #[must_use]
is_nan_mask(self) -> BVec3A403     pub fn is_nan_mask(self) -> BVec3A {
404         BVec3A(unsafe { _mm_cmpunord_ps(self.0, self.0) })
405     }
406 
407     /// Computes the length of `self`.
408     #[doc(alias = "magnitude")]
409     #[inline]
410     #[must_use]
length(self) -> f32411     pub fn length(self) -> f32 {
412         unsafe {
413             let dot = dot3_in_x(self.0, self.0);
414             _mm_cvtss_f32(_mm_sqrt_ps(dot))
415         }
416     }
417 
418     /// Computes the squared length of `self`.
419     ///
420     /// This is faster than `length()` as it avoids a square root operation.
421     #[doc(alias = "magnitude2")]
422     #[inline]
423     #[must_use]
length_squared(self) -> f32424     pub fn length_squared(self) -> f32 {
425         self.dot(self)
426     }
427 
428     /// Computes `1.0 / length()`.
429     ///
430     /// For valid results, `self` must _not_ be of length zero.
431     #[inline]
432     #[must_use]
length_recip(self) -> f32433     pub fn length_recip(self) -> f32 {
434         unsafe {
435             let dot = dot3_in_x(self.0, self.0);
436             _mm_cvtss_f32(_mm_div_ps(Self::ONE.0, _mm_sqrt_ps(dot)))
437         }
438     }
439 
440     /// Computes the Euclidean distance between two points in space.
441     #[inline]
442     #[must_use]
distance(self, rhs: Self) -> f32443     pub fn distance(self, rhs: Self) -> f32 {
444         (self - rhs).length()
445     }
446 
447     /// Compute the squared euclidean distance between two points in space.
448     #[inline]
449     #[must_use]
distance_squared(self, rhs: Self) -> f32450     pub fn distance_squared(self, rhs: Self) -> f32 {
451         (self - rhs).length_squared()
452     }
453 
454     /// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`.
455     #[inline]
456     #[must_use]
div_euclid(self, rhs: Self) -> Self457     pub fn div_euclid(self, rhs: Self) -> Self {
458         Self::new(
459             math::div_euclid(self.x, rhs.x),
460             math::div_euclid(self.y, rhs.y),
461             math::div_euclid(self.z, rhs.z),
462         )
463     }
464 
465     /// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`.
466     ///
467     /// [Euclidean division]: f32::rem_euclid
468     #[inline]
469     #[must_use]
rem_euclid(self, rhs: Self) -> Self470     pub fn rem_euclid(self, rhs: Self) -> Self {
471         Self::new(
472             math::rem_euclid(self.x, rhs.x),
473             math::rem_euclid(self.y, rhs.y),
474             math::rem_euclid(self.z, rhs.z),
475         )
476     }
477 
478     /// Returns `self` normalized to length 1.0.
479     ///
480     /// For valid results, `self` must _not_ be of length zero, nor very close to zero.
481     ///
482     /// See also [`Self::try_normalize()`] and [`Self::normalize_or_zero()`].
483     ///
484     /// Panics
485     ///
486     /// Will panic if `self` is zero length when `glam_assert` is enabled.
487     #[inline]
488     #[must_use]
normalize(self) -> Self489     pub fn normalize(self) -> Self {
490         unsafe {
491             let length = _mm_sqrt_ps(dot3_into_m128(self.0, self.0));
492             #[allow(clippy::let_and_return)]
493             let normalized = Self(_mm_div_ps(self.0, length));
494             glam_assert!(normalized.is_finite());
495             normalized
496         }
497     }
498 
499     /// Returns `self` normalized to length 1.0 if possible, else returns `None`.
500     ///
501     /// In particular, if the input is zero (or very close to zero), or non-finite,
502     /// the result of this operation will be `None`.
503     ///
504     /// See also [`Self::normalize_or_zero()`].
505     #[inline]
506     #[must_use]
try_normalize(self) -> Option<Self>507     pub fn try_normalize(self) -> Option<Self> {
508         let rcp = self.length_recip();
509         if rcp.is_finite() && rcp > 0.0 {
510             Some(self * rcp)
511         } else {
512             None
513         }
514     }
515 
516     /// Returns `self` normalized to length 1.0 if possible, else returns zero.
517     ///
518     /// In particular, if the input is zero (or very close to zero), or non-finite,
519     /// the result of this operation will be zero.
520     ///
521     /// See also [`Self::try_normalize()`].
522     #[inline]
523     #[must_use]
normalize_or_zero(self) -> Self524     pub fn normalize_or_zero(self) -> Self {
525         let rcp = self.length_recip();
526         if rcp.is_finite() && rcp > 0.0 {
527             self * rcp
528         } else {
529             Self::ZERO
530         }
531     }
532 
533     /// Returns whether `self` is length `1.0` or not.
534     ///
535     /// Uses a precision threshold of `1e-6`.
536     #[inline]
537     #[must_use]
is_normalized(self) -> bool538     pub fn is_normalized(self) -> bool {
539         // TODO: do something with epsilon
540         math::abs(self.length_squared() - 1.0) <= 1e-4
541     }
542 
543     /// Returns the vector projection of `self` onto `rhs`.
544     ///
545     /// `rhs` must be of non-zero length.
546     ///
547     /// # Panics
548     ///
549     /// Will panic if `rhs` is zero length when `glam_assert` is enabled.
550     #[inline]
551     #[must_use]
project_onto(self, rhs: Self) -> Self552     pub fn project_onto(self, rhs: Self) -> Self {
553         let other_len_sq_rcp = rhs.dot(rhs).recip();
554         glam_assert!(other_len_sq_rcp.is_finite());
555         rhs * self.dot(rhs) * other_len_sq_rcp
556     }
557 
558     /// Returns the vector rejection of `self` from `rhs`.
559     ///
560     /// The vector rejection is the vector perpendicular to the projection of `self` onto
561     /// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`.
562     ///
563     /// `rhs` must be of non-zero length.
564     ///
565     /// # Panics
566     ///
567     /// Will panic if `rhs` has a length of zero when `glam_assert` is enabled.
568     #[inline]
569     #[must_use]
reject_from(self, rhs: Self) -> Self570     pub fn reject_from(self, rhs: Self) -> Self {
571         self - self.project_onto(rhs)
572     }
573 
574     /// Returns the vector projection of `self` onto `rhs`.
575     ///
576     /// `rhs` must be normalized.
577     ///
578     /// # Panics
579     ///
580     /// Will panic if `rhs` is not normalized when `glam_assert` is enabled.
581     #[inline]
582     #[must_use]
project_onto_normalized(self, rhs: Self) -> Self583     pub fn project_onto_normalized(self, rhs: Self) -> Self {
584         glam_assert!(rhs.is_normalized());
585         rhs * self.dot(rhs)
586     }
587 
588     /// Returns the vector rejection of `self` from `rhs`.
589     ///
590     /// The vector rejection is the vector perpendicular to the projection of `self` onto
591     /// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`.
592     ///
593     /// `rhs` must be normalized.
594     ///
595     /// # Panics
596     ///
597     /// Will panic if `rhs` is not normalized when `glam_assert` is enabled.
598     #[inline]
599     #[must_use]
reject_from_normalized(self, rhs: Self) -> Self600     pub fn reject_from_normalized(self, rhs: Self) -> Self {
601         self - self.project_onto_normalized(rhs)
602     }
603 
604     /// Returns a vector containing the nearest integer to a number for each element of `self`.
605     /// Round half-way cases away from 0.0.
606     #[inline]
607     #[must_use]
round(self) -> Self608     pub fn round(self) -> Self {
609         Self(unsafe { m128_round(self.0) })
610     }
611 
612     /// Returns a vector containing the largest integer less than or equal to a number for each
613     /// element of `self`.
614     #[inline]
615     #[must_use]
floor(self) -> Self616     pub fn floor(self) -> Self {
617         Self(unsafe { m128_floor(self.0) })
618     }
619 
620     /// Returns a vector containing the smallest integer greater than or equal to a number for
621     /// each element of `self`.
622     #[inline]
623     #[must_use]
ceil(self) -> Self624     pub fn ceil(self) -> Self {
625         Self(unsafe { m128_ceil(self.0) })
626     }
627 
628     /// Returns a vector containing the integer part each element of `self`. This means numbers are
629     /// always truncated towards zero.
630     #[inline]
631     #[must_use]
trunc(self) -> Self632     pub fn trunc(self) -> Self {
633         Self(unsafe { m128_trunc(self.0) })
634     }
635 
636     /// Returns a vector containing the fractional part of the vector, e.g. `self -
637     /// self.floor()`.
638     ///
639     /// Note that this is fast but not precise for large numbers.
640     #[inline]
641     #[must_use]
fract(self) -> Self642     pub fn fract(self) -> Self {
643         self - self.floor()
644     }
645 
646     /// Returns a vector containing `e^self` (the exponential function) for each element of
647     /// `self`.
648     #[inline]
649     #[must_use]
exp(self) -> Self650     pub fn exp(self) -> Self {
651         Self::new(math::exp(self.x), math::exp(self.y), math::exp(self.z))
652     }
653 
654     /// Returns a vector containing each element of `self` raised to the power of `n`.
655     #[inline]
656     #[must_use]
powf(self, n: f32) -> Self657     pub fn powf(self, n: f32) -> Self {
658         Self::new(
659             math::powf(self.x, n),
660             math::powf(self.y, n),
661             math::powf(self.z, n),
662         )
663     }
664 
665     /// Returns a vector containing the reciprocal `1.0/n` of each element of `self`.
666     #[inline]
667     #[must_use]
recip(self) -> Self668     pub fn recip(self) -> Self {
669         Self(unsafe { _mm_div_ps(Self::ONE.0, self.0) })
670     }
671 
672     /// Performs a linear interpolation between `self` and `rhs` based on the value `s`.
673     ///
674     /// When `s` is `0.0`, the result will be equal to `self`.  When `s` is `1.0`, the result
675     /// will be equal to `rhs`. When `s` is outside of range `[0, 1]`, the result is linearly
676     /// extrapolated.
677     #[doc(alias = "mix")]
678     #[inline]
679     #[must_use]
lerp(self, rhs: Self, s: f32) -> Self680     pub fn lerp(self, rhs: Self, s: f32) -> Self {
681         self + ((rhs - self) * s)
682     }
683 
684     /// Returns true if the absolute difference of all elements between `self` and `rhs` is
685     /// less than or equal to `max_abs_diff`.
686     ///
687     /// This can be used to compare if two vectors contain similar elements. It works best when
688     /// comparing with a known value. The `max_abs_diff` that should be used used depends on
689     /// the values being compared against.
690     ///
691     /// For more see
692     /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
693     #[inline]
694     #[must_use]
abs_diff_eq(self, rhs: Self, max_abs_diff: f32) -> bool695     pub fn abs_diff_eq(self, rhs: Self, max_abs_diff: f32) -> bool {
696         self.sub(rhs).abs().cmple(Self::splat(max_abs_diff)).all()
697     }
698 
699     /// Returns a vector with a length no less than `min` and no more than `max`
700     ///
701     /// # Panics
702     ///
703     /// Will panic if `min` is greater than `max` when `glam_assert` is enabled.
704     #[inline]
705     #[must_use]
clamp_length(self, min: f32, max: f32) -> Self706     pub fn clamp_length(self, min: f32, max: f32) -> Self {
707         glam_assert!(min <= max);
708         let length_sq = self.length_squared();
709         if length_sq < min * min {
710             min * (self / math::sqrt(length_sq))
711         } else if length_sq > max * max {
712             max * (self / math::sqrt(length_sq))
713         } else {
714             self
715         }
716     }
717 
718     /// Returns a vector with a length no more than `max`
719     #[inline]
720     #[must_use]
clamp_length_max(self, max: f32) -> Self721     pub fn clamp_length_max(self, max: f32) -> Self {
722         let length_sq = self.length_squared();
723         if length_sq > max * max {
724             max * (self / math::sqrt(length_sq))
725         } else {
726             self
727         }
728     }
729 
730     /// Returns a vector with a length no less than `min`
731     #[inline]
732     #[must_use]
clamp_length_min(self, min: f32) -> Self733     pub fn clamp_length_min(self, min: f32) -> Self {
734         let length_sq = self.length_squared();
735         if length_sq < min * min {
736             min * (self / math::sqrt(length_sq))
737         } else {
738             self
739         }
740     }
741 
742     /// Fused multiply-add. Computes `(self * a) + b` element-wise with only one rounding
743     /// error, yielding a more accurate result than an unfused multiply-add.
744     ///
745     /// Using `mul_add` *may* be more performant than an unfused multiply-add if the target
746     /// architecture has a dedicated fma CPU instruction. However, this is not always true,
747     /// and will be heavily dependant on designing algorithms with specific target hardware in
748     /// mind.
749     #[inline]
750     #[must_use]
mul_add(self, a: Self, b: Self) -> Self751     pub fn mul_add(self, a: Self, b: Self) -> Self {
752         #[cfg(target_feature = "fma")]
753         unsafe {
754             Self(_mm_fmadd_ps(self.0, a.0, b.0))
755         }
756         #[cfg(not(target_feature = "fma"))]
757         Self::new(
758             math::mul_add(self.x, a.x, b.x),
759             math::mul_add(self.y, a.y, b.y),
760             math::mul_add(self.z, a.z, b.z),
761         )
762     }
763 
764     /// Returns the angle (in radians) between two vectors.
765     ///
766     /// The inputs do not need to be unit vectors however they must be non-zero.
767     #[inline]
768     #[must_use]
angle_between(self, rhs: Self) -> f32769     pub fn angle_between(self, rhs: Self) -> f32 {
770         math::acos_approx(
771             self.dot(rhs)
772                 .div(math::sqrt(self.length_squared().mul(rhs.length_squared()))),
773         )
774     }
775 
776     /// Returns some vector that is orthogonal to the given one.
777     ///
778     /// The input vector must be finite and non-zero.
779     ///
780     /// The output vector is not necessarily unit length. For that use
781     /// [`Self::any_orthonormal_vector()`] instead.
782     #[inline]
783     #[must_use]
any_orthogonal_vector(&self) -> Self784     pub fn any_orthogonal_vector(&self) -> Self {
785         // This can probably be optimized
786         if math::abs(self.x) > math::abs(self.y) {
787             Self::new(-self.z, 0.0, self.x) // self.cross(Self::Y)
788         } else {
789             Self::new(0.0, self.z, -self.y) // self.cross(Self::X)
790         }
791     }
792 
793     /// Returns any unit vector that is orthogonal to the given one.
794     ///
795     /// The input vector must be unit length.
796     ///
797     /// # Panics
798     ///
799     /// Will panic if `self` is not normalized when `glam_assert` is enabled.
800     #[inline]
801     #[must_use]
any_orthonormal_vector(&self) -> Self802     pub fn any_orthonormal_vector(&self) -> Self {
803         glam_assert!(self.is_normalized());
804         // From https://graphics.pixar.com/library/OrthonormalB/paper.pdf
805         let sign = math::signum(self.z);
806         let a = -1.0 / (sign + self.z);
807         let b = self.x * self.y * a;
808         Self::new(b, sign + self.y * self.y * a, -self.y)
809     }
810 
811     /// Given a unit vector return two other vectors that together form an orthonormal
812     /// basis. That is, all three vectors are orthogonal to each other and are normalized.
813     ///
814     /// # Panics
815     ///
816     /// Will panic if `self` is not normalized when `glam_assert` is enabled.
817     #[inline]
818     #[must_use]
any_orthonormal_pair(&self) -> (Self, Self)819     pub fn any_orthonormal_pair(&self) -> (Self, Self) {
820         glam_assert!(self.is_normalized());
821         // From https://graphics.pixar.com/library/OrthonormalB/paper.pdf
822         let sign = math::signum(self.z);
823         let a = -1.0 / (sign + self.z);
824         let b = self.x * self.y * a;
825         (
826             Self::new(1.0 + sign * self.x * self.x * a, sign * b, -sign * self.x),
827             Self::new(b, sign + self.y * self.y * a, -self.y),
828         )
829     }
830 
831     /// Casts all elements of `self` to `f64`.
832     #[inline]
833     #[must_use]
as_dvec3(&self) -> crate::DVec3834     pub fn as_dvec3(&self) -> crate::DVec3 {
835         crate::DVec3::new(self.x as f64, self.y as f64, self.z as f64)
836     }
837 
838     /// Casts all elements of `self` to `i16`.
839     #[inline]
840     #[must_use]
as_i16vec3(&self) -> crate::I16Vec3841     pub fn as_i16vec3(&self) -> crate::I16Vec3 {
842         crate::I16Vec3::new(self.x as i16, self.y as i16, self.z as i16)
843     }
844 
845     /// Casts all elements of `self` to `u16`.
846     #[inline]
847     #[must_use]
as_u16vec3(&self) -> crate::U16Vec3848     pub fn as_u16vec3(&self) -> crate::U16Vec3 {
849         crate::U16Vec3::new(self.x as u16, self.y as u16, self.z as u16)
850     }
851 
852     /// Casts all elements of `self` to `i32`.
853     #[inline]
854     #[must_use]
as_ivec3(&self) -> crate::IVec3855     pub fn as_ivec3(&self) -> crate::IVec3 {
856         crate::IVec3::new(self.x as i32, self.y as i32, self.z as i32)
857     }
858 
859     /// Casts all elements of `self` to `u32`.
860     #[inline]
861     #[must_use]
as_uvec3(&self) -> crate::UVec3862     pub fn as_uvec3(&self) -> crate::UVec3 {
863         crate::UVec3::new(self.x as u32, self.y as u32, self.z as u32)
864     }
865 
866     /// Casts all elements of `self` to `i64`.
867     #[inline]
868     #[must_use]
as_i64vec3(&self) -> crate::I64Vec3869     pub fn as_i64vec3(&self) -> crate::I64Vec3 {
870         crate::I64Vec3::new(self.x as i64, self.y as i64, self.z as i64)
871     }
872 
873     /// Casts all elements of `self` to `u64`.
874     #[inline]
875     #[must_use]
as_u64vec3(&self) -> crate::U64Vec3876     pub fn as_u64vec3(&self) -> crate::U64Vec3 {
877         crate::U64Vec3::new(self.x as u64, self.y as u64, self.z as u64)
878     }
879 }
880 
881 impl Default for Vec3A {
882     #[inline(always)]
default() -> Self883     fn default() -> Self {
884         Self::ZERO
885     }
886 }
887 
888 impl PartialEq for Vec3A {
889     #[inline]
eq(&self, rhs: &Self) -> bool890     fn eq(&self, rhs: &Self) -> bool {
891         self.cmpeq(*rhs).all()
892     }
893 }
894 
895 impl Div<Vec3A> for Vec3A {
896     type Output = Self;
897     #[inline]
div(self, rhs: Self) -> Self898     fn div(self, rhs: Self) -> Self {
899         Self(unsafe { _mm_div_ps(self.0, rhs.0) })
900     }
901 }
902 
903 impl DivAssign<Vec3A> for Vec3A {
904     #[inline]
div_assign(&mut self, rhs: Self)905     fn div_assign(&mut self, rhs: Self) {
906         self.0 = unsafe { _mm_div_ps(self.0, rhs.0) };
907     }
908 }
909 
910 impl Div<f32> for Vec3A {
911     type Output = Self;
912     #[inline]
div(self, rhs: f32) -> Self913     fn div(self, rhs: f32) -> Self {
914         Self(unsafe { _mm_div_ps(self.0, _mm_set1_ps(rhs)) })
915     }
916 }
917 
918 impl DivAssign<f32> for Vec3A {
919     #[inline]
div_assign(&mut self, rhs: f32)920     fn div_assign(&mut self, rhs: f32) {
921         self.0 = unsafe { _mm_div_ps(self.0, _mm_set1_ps(rhs)) };
922     }
923 }
924 
925 impl Div<Vec3A> for f32 {
926     type Output = Vec3A;
927     #[inline]
div(self, rhs: Vec3A) -> Vec3A928     fn div(self, rhs: Vec3A) -> Vec3A {
929         Vec3A(unsafe { _mm_div_ps(_mm_set1_ps(self), rhs.0) })
930     }
931 }
932 
933 impl Mul<Vec3A> for Vec3A {
934     type Output = Self;
935     #[inline]
mul(self, rhs: Self) -> Self936     fn mul(self, rhs: Self) -> Self {
937         Self(unsafe { _mm_mul_ps(self.0, rhs.0) })
938     }
939 }
940 
941 impl MulAssign<Vec3A> for Vec3A {
942     #[inline]
mul_assign(&mut self, rhs: Self)943     fn mul_assign(&mut self, rhs: Self) {
944         self.0 = unsafe { _mm_mul_ps(self.0, rhs.0) };
945     }
946 }
947 
948 impl Mul<f32> for Vec3A {
949     type Output = Self;
950     #[inline]
mul(self, rhs: f32) -> Self951     fn mul(self, rhs: f32) -> Self {
952         Self(unsafe { _mm_mul_ps(self.0, _mm_set1_ps(rhs)) })
953     }
954 }
955 
956 impl MulAssign<f32> for Vec3A {
957     #[inline]
mul_assign(&mut self, rhs: f32)958     fn mul_assign(&mut self, rhs: f32) {
959         self.0 = unsafe { _mm_mul_ps(self.0, _mm_set1_ps(rhs)) };
960     }
961 }
962 
963 impl Mul<Vec3A> for f32 {
964     type Output = Vec3A;
965     #[inline]
mul(self, rhs: Vec3A) -> Vec3A966     fn mul(self, rhs: Vec3A) -> Vec3A {
967         Vec3A(unsafe { _mm_mul_ps(_mm_set1_ps(self), rhs.0) })
968     }
969 }
970 
971 impl Add<Vec3A> for Vec3A {
972     type Output = Self;
973     #[inline]
add(self, rhs: Self) -> Self974     fn add(self, rhs: Self) -> Self {
975         Self(unsafe { _mm_add_ps(self.0, rhs.0) })
976     }
977 }
978 
979 impl AddAssign<Vec3A> for Vec3A {
980     #[inline]
add_assign(&mut self, rhs: Self)981     fn add_assign(&mut self, rhs: Self) {
982         self.0 = unsafe { _mm_add_ps(self.0, rhs.0) };
983     }
984 }
985 
986 impl Add<f32> for Vec3A {
987     type Output = Self;
988     #[inline]
add(self, rhs: f32) -> Self989     fn add(self, rhs: f32) -> Self {
990         Self(unsafe { _mm_add_ps(self.0, _mm_set1_ps(rhs)) })
991     }
992 }
993 
994 impl AddAssign<f32> for Vec3A {
995     #[inline]
add_assign(&mut self, rhs: f32)996     fn add_assign(&mut self, rhs: f32) {
997         self.0 = unsafe { _mm_add_ps(self.0, _mm_set1_ps(rhs)) };
998     }
999 }
1000 
1001 impl Add<Vec3A> for f32 {
1002     type Output = Vec3A;
1003     #[inline]
add(self, rhs: Vec3A) -> Vec3A1004     fn add(self, rhs: Vec3A) -> Vec3A {
1005         Vec3A(unsafe { _mm_add_ps(_mm_set1_ps(self), rhs.0) })
1006     }
1007 }
1008 
1009 impl Sub<Vec3A> for Vec3A {
1010     type Output = Self;
1011     #[inline]
sub(self, rhs: Self) -> Self1012     fn sub(self, rhs: Self) -> Self {
1013         Self(unsafe { _mm_sub_ps(self.0, rhs.0) })
1014     }
1015 }
1016 
1017 impl SubAssign<Vec3A> for Vec3A {
1018     #[inline]
sub_assign(&mut self, rhs: Vec3A)1019     fn sub_assign(&mut self, rhs: Vec3A) {
1020         self.0 = unsafe { _mm_sub_ps(self.0, rhs.0) };
1021     }
1022 }
1023 
1024 impl Sub<f32> for Vec3A {
1025     type Output = Self;
1026     #[inline]
sub(self, rhs: f32) -> Self1027     fn sub(self, rhs: f32) -> Self {
1028         Self(unsafe { _mm_sub_ps(self.0, _mm_set1_ps(rhs)) })
1029     }
1030 }
1031 
1032 impl SubAssign<f32> for Vec3A {
1033     #[inline]
sub_assign(&mut self, rhs: f32)1034     fn sub_assign(&mut self, rhs: f32) {
1035         self.0 = unsafe { _mm_sub_ps(self.0, _mm_set1_ps(rhs)) };
1036     }
1037 }
1038 
1039 impl Sub<Vec3A> for f32 {
1040     type Output = Vec3A;
1041     #[inline]
sub(self, rhs: Vec3A) -> Vec3A1042     fn sub(self, rhs: Vec3A) -> Vec3A {
1043         Vec3A(unsafe { _mm_sub_ps(_mm_set1_ps(self), rhs.0) })
1044     }
1045 }
1046 
1047 impl Rem<Vec3A> for Vec3A {
1048     type Output = Self;
1049     #[inline]
rem(self, rhs: Self) -> Self1050     fn rem(self, rhs: Self) -> Self {
1051         unsafe {
1052             let n = m128_floor(_mm_div_ps(self.0, rhs.0));
1053             Self(_mm_sub_ps(self.0, _mm_mul_ps(n, rhs.0)))
1054         }
1055     }
1056 }
1057 
1058 impl RemAssign<Vec3A> for Vec3A {
1059     #[inline]
rem_assign(&mut self, rhs: Self)1060     fn rem_assign(&mut self, rhs: Self) {
1061         *self = self.rem(rhs);
1062     }
1063 }
1064 
1065 impl Rem<f32> for Vec3A {
1066     type Output = Self;
1067     #[inline]
rem(self, rhs: f32) -> Self1068     fn rem(self, rhs: f32) -> Self {
1069         self.rem(Self::splat(rhs))
1070     }
1071 }
1072 
1073 impl RemAssign<f32> for Vec3A {
1074     #[inline]
rem_assign(&mut self, rhs: f32)1075     fn rem_assign(&mut self, rhs: f32) {
1076         *self = self.rem(Self::splat(rhs));
1077     }
1078 }
1079 
1080 impl Rem<Vec3A> for f32 {
1081     type Output = Vec3A;
1082     #[inline]
rem(self, rhs: Vec3A) -> Vec3A1083     fn rem(self, rhs: Vec3A) -> Vec3A {
1084         Vec3A::splat(self).rem(rhs)
1085     }
1086 }
1087 
1088 #[cfg(not(target_arch = "spirv"))]
1089 impl AsRef<[f32; 3]> for Vec3A {
1090     #[inline]
as_ref(&self) -> &[f32; 3]1091     fn as_ref(&self) -> &[f32; 3] {
1092         unsafe { &*(self as *const Vec3A as *const [f32; 3]) }
1093     }
1094 }
1095 
1096 #[cfg(not(target_arch = "spirv"))]
1097 impl AsMut<[f32; 3]> for Vec3A {
1098     #[inline]
as_mut(&mut self) -> &mut [f32; 3]1099     fn as_mut(&mut self) -> &mut [f32; 3] {
1100         unsafe { &mut *(self as *mut Vec3A as *mut [f32; 3]) }
1101     }
1102 }
1103 
1104 impl Sum for Vec3A {
1105     #[inline]
sum<I>(iter: I) -> Self where I: Iterator<Item = Self>,1106     fn sum<I>(iter: I) -> Self
1107     where
1108         I: Iterator<Item = Self>,
1109     {
1110         iter.fold(Self::ZERO, Self::add)
1111     }
1112 }
1113 
1114 impl<'a> Sum<&'a Self> for Vec3A {
1115     #[inline]
sum<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,1116     fn sum<I>(iter: I) -> Self
1117     where
1118         I: Iterator<Item = &'a Self>,
1119     {
1120         iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1121     }
1122 }
1123 
1124 impl Product for Vec3A {
1125     #[inline]
product<I>(iter: I) -> Self where I: Iterator<Item = Self>,1126     fn product<I>(iter: I) -> Self
1127     where
1128         I: Iterator<Item = Self>,
1129     {
1130         iter.fold(Self::ONE, Self::mul)
1131     }
1132 }
1133 
1134 impl<'a> Product<&'a Self> for Vec3A {
1135     #[inline]
product<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,1136     fn product<I>(iter: I) -> Self
1137     where
1138         I: Iterator<Item = &'a Self>,
1139     {
1140         iter.fold(Self::ONE, |a, &b| Self::mul(a, b))
1141     }
1142 }
1143 
1144 impl Neg for Vec3A {
1145     type Output = Self;
1146     #[inline]
neg(self) -> Self1147     fn neg(self) -> Self {
1148         Self(unsafe { _mm_xor_ps(_mm_set1_ps(-0.0), self.0) })
1149     }
1150 }
1151 
1152 impl Index<usize> for Vec3A {
1153     type Output = f32;
1154     #[inline]
index(&self, index: usize) -> &Self::Output1155     fn index(&self, index: usize) -> &Self::Output {
1156         match index {
1157             0 => &self.x,
1158             1 => &self.y,
1159             2 => &self.z,
1160             _ => panic!("index out of bounds"),
1161         }
1162     }
1163 }
1164 
1165 impl IndexMut<usize> for Vec3A {
1166     #[inline]
index_mut(&mut self, index: usize) -> &mut Self::Output1167     fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1168         match index {
1169             0 => &mut self.x,
1170             1 => &mut self.y,
1171             2 => &mut self.z,
1172             _ => panic!("index out of bounds"),
1173         }
1174     }
1175 }
1176 
1177 #[cfg(not(target_arch = "spirv"))]
1178 impl fmt::Display for Vec3A {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1179     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1180         write!(f, "[{}, {}, {}]", self.x, self.y, self.z)
1181     }
1182 }
1183 
1184 #[cfg(not(target_arch = "spirv"))]
1185 impl fmt::Debug for Vec3A {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result1186     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1187         fmt.debug_tuple(stringify!(Vec3A))
1188             .field(&self.x)
1189             .field(&self.y)
1190             .field(&self.z)
1191             .finish()
1192     }
1193 }
1194 
1195 impl From<Vec3A> for __m128 {
1196     #[inline]
from(t: Vec3A) -> Self1197     fn from(t: Vec3A) -> Self {
1198         t.0
1199     }
1200 }
1201 
1202 impl From<__m128> for Vec3A {
1203     #[inline]
from(t: __m128) -> Self1204     fn from(t: __m128) -> Self {
1205         Self(t)
1206     }
1207 }
1208 
1209 impl From<[f32; 3]> for Vec3A {
1210     #[inline]
from(a: [f32; 3]) -> Self1211     fn from(a: [f32; 3]) -> Self {
1212         Self::new(a[0], a[1], a[2])
1213     }
1214 }
1215 
1216 impl From<Vec3A> for [f32; 3] {
1217     #[inline]
from(v: Vec3A) -> Self1218     fn from(v: Vec3A) -> Self {
1219         use crate::Align16;
1220         use core::mem::MaybeUninit;
1221         let mut out: MaybeUninit<Align16<Self>> = MaybeUninit::uninit();
1222         unsafe {
1223             _mm_store_ps(out.as_mut_ptr().cast(), v.0);
1224             out.assume_init().0
1225         }
1226     }
1227 }
1228 
1229 impl From<(f32, f32, f32)> for Vec3A {
1230     #[inline]
from(t: (f32, f32, f32)) -> Self1231     fn from(t: (f32, f32, f32)) -> Self {
1232         Self::new(t.0, t.1, t.2)
1233     }
1234 }
1235 
1236 impl From<Vec3A> for (f32, f32, f32) {
1237     #[inline]
from(v: Vec3A) -> Self1238     fn from(v: Vec3A) -> Self {
1239         use crate::Align16;
1240         use core::mem::MaybeUninit;
1241         let mut out: MaybeUninit<Align16<Self>> = MaybeUninit::uninit();
1242         unsafe {
1243             _mm_store_ps(out.as_mut_ptr().cast(), v.0);
1244             out.assume_init().0
1245         }
1246     }
1247 }
1248 
1249 impl From<Vec3> for Vec3A {
1250     #[inline]
from(v: Vec3) -> Self1251     fn from(v: Vec3) -> Self {
1252         Self::new(v.x, v.y, v.z)
1253     }
1254 }
1255 
1256 impl From<Vec4> for Vec3A {
1257     /// Creates a [`Vec3A`] from the `x`, `y` and `z` elements of `self` discarding `w`.
1258     ///
1259     /// On architectures where SIMD is supported such as SSE2 on `x86_64` this conversion is a noop.
1260     #[inline]
from(v: Vec4) -> Self1261     fn from(v: Vec4) -> Self {
1262         Self(v.0)
1263     }
1264 }
1265 
1266 impl From<Vec3A> for Vec3 {
1267     #[inline]
from(v: Vec3A) -> Self1268     fn from(v: Vec3A) -> Self {
1269         use crate::Align16;
1270         use core::mem::MaybeUninit;
1271         let mut out: MaybeUninit<Align16<Self>> = MaybeUninit::uninit();
1272         unsafe {
1273             _mm_store_ps(out.as_mut_ptr().cast(), v.0);
1274             out.assume_init().0
1275         }
1276     }
1277 }
1278 
1279 impl From<(Vec2, f32)> for Vec3A {
1280     #[inline]
from((v, z): (Vec2, f32)) -> Self1281     fn from((v, z): (Vec2, f32)) -> Self {
1282         Self::new(v.x, v.y, z)
1283     }
1284 }
1285 
1286 impl Deref for Vec3A {
1287     type Target = crate::deref::Vec3<f32>;
1288     #[inline]
deref(&self) -> &Self::Target1289     fn deref(&self) -> &Self::Target {
1290         unsafe { &*(self as *const Self).cast() }
1291     }
1292 }
1293 
1294 impl DerefMut for Vec3A {
1295     #[inline]
deref_mut(&mut self) -> &mut Self::Target1296     fn deref_mut(&mut self) -> &mut Self::Target {
1297         unsafe { &mut *(self as *mut Self).cast() }
1298     }
1299 }
1300