Skip to main content

glam/f64/
dvec4.rs

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