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