glam/f64/
dvec4.rs

1// Generated from vec.rs.tera template. Edit the template, not the generated file.
2
3use crate::{f64::math, BVec4, DVec2, DVec3, IVec4, UVec4, Vec4};
4
5#[cfg(not(target_arch = "spirv"))]
6use core::fmt;
7use core::iter::{Product, Sum};
8use core::{f32, ops::*};
9
10/// Creates a 4-dimensional vector.
11#[inline(always)]
12#[must_use]
13pub const fn dvec4(x: f64, y: f64, z: f64, w: f64) -> DVec4 {
14    DVec4::new(x, y, z, w)
15}
16
17/// A 4-dimensional vector.
18#[derive(Clone, Copy, PartialEq)]
19#[cfg_attr(feature = "cuda", repr(align(16)))]
20#[cfg_attr(not(target_arch = "spirv"), repr(C))]
21#[cfg_attr(target_arch = "spirv", repr(simd))]
22pub struct DVec4 {
23    pub x: f64,
24    pub y: f64,
25    pub z: f64,
26    pub w: f64,
27}
28
29impl DVec4 {
30    /// All zeroes.
31    pub const ZERO: Self = Self::splat(0.0);
32
33    /// All ones.
34    pub const ONE: Self = Self::splat(1.0);
35
36    /// All negative ones.
37    pub const NEG_ONE: Self = Self::splat(-1.0);
38
39    /// All `f64::MIN`.
40    pub const MIN: Self = Self::splat(f64::MIN);
41
42    /// All `f64::MAX`.
43    pub const MAX: Self = Self::splat(f64::MAX);
44
45    /// All `f64::NAN`.
46    pub const NAN: Self = Self::splat(f64::NAN);
47
48    /// All `f64::INFINITY`.
49    pub const INFINITY: Self = Self::splat(f64::INFINITY);
50
51    /// All `f64::NEG_INFINITY`.
52    pub const NEG_INFINITY: Self = Self::splat(f64::NEG_INFINITY);
53
54    /// A unit vector pointing along the positive X axis.
55    pub const X: Self = Self::new(1.0, 0.0, 0.0, 0.0);
56
57    /// A unit vector pointing along the positive Y axis.
58    pub const Y: Self = Self::new(0.0, 1.0, 0.0, 0.0);
59
60    /// A unit vector pointing along the positive Z axis.
61    pub const Z: Self = Self::new(0.0, 0.0, 1.0, 0.0);
62
63    /// A unit vector pointing along the positive W axis.
64    pub const W: Self = Self::new(0.0, 0.0, 0.0, 1.0);
65
66    /// A unit vector pointing along the negative X axis.
67    pub const NEG_X: Self = Self::new(-1.0, 0.0, 0.0, 0.0);
68
69    /// A unit vector pointing along the negative Y axis.
70    pub const NEG_Y: Self = Self::new(0.0, -1.0, 0.0, 0.0);
71
72    /// A unit vector pointing along the negative Z axis.
73    pub const NEG_Z: Self = Self::new(0.0, 0.0, -1.0, 0.0);
74
75    /// A unit vector pointing along the negative W axis.
76    pub const NEG_W: Self = Self::new(0.0, 0.0, 0.0, -1.0);
77
78    /// The unit axes.
79    pub const AXES: [Self; 4] = [Self::X, Self::Y, Self::Z, Self::W];
80
81    /// Creates a new vector.
82    #[inline(always)]
83    #[must_use]
84    pub const fn new(x: f64, y: f64, z: f64, w: f64) -> Self {
85        Self { x, y, z, w }
86    }
87
88    /// Creates a vector with all elements set to `v`.
89    #[inline]
90    #[must_use]
91    pub const fn splat(v: f64) -> Self {
92        Self {
93            x: v,
94
95            y: v,
96
97            z: v,
98
99            w: v,
100        }
101    }
102
103    /// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use
104    /// for each element of `self`.
105    ///
106    /// A true element in the mask uses the corresponding element from `if_true`, and false
107    /// uses the element from `if_false`.
108    #[inline]
109    #[must_use]
110    pub fn select(mask: BVec4, if_true: Self, if_false: Self) -> Self {
111        Self {
112            x: if mask.test(0) { if_true.x } else { if_false.x },
113            y: if mask.test(1) { if_true.y } else { if_false.y },
114            z: if mask.test(2) { if_true.z } else { if_false.z },
115            w: if mask.test(3) { if_true.w } else { if_false.w },
116        }
117    }
118
119    /// Creates a new vector from an array.
120    #[inline]
121    #[must_use]
122    pub const fn from_array(a: [f64; 4]) -> Self {
123        Self::new(a[0], a[1], a[2], a[3])
124    }
125
126    /// `[x, y, z, w]`
127    #[inline]
128    #[must_use]
129    pub const fn to_array(&self) -> [f64; 4] {
130        [self.x, self.y, self.z, self.w]
131    }
132
133    /// Creates a vector from the first 4 values in `slice`.
134    ///
135    /// # Panics
136    ///
137    /// Panics if `slice` is less than 4 elements long.
138    #[inline]
139    #[must_use]
140    pub const fn from_slice(slice: &[f64]) -> Self {
141        Self::new(slice[0], slice[1], slice[2], slice[3])
142    }
143
144    /// Writes the elements of `self` to the first 4 elements in `slice`.
145    ///
146    /// # Panics
147    ///
148    /// Panics if `slice` is less than 4 elements long.
149    #[inline]
150    pub fn write_to_slice(self, slice: &mut [f64]) {
151        slice[0] = self.x;
152        slice[1] = self.y;
153        slice[2] = self.z;
154        slice[3] = self.w;
155    }
156
157    /// Creates a 3D vector from the `x`, `y` and `z` elements of `self`, discarding `w`.
158    ///
159    /// Truncation to [`DVec3`] may also be performed by using [`self.xyz()`][crate::swizzles::Vec4Swizzles::xyz()].
160    #[inline]
161    #[must_use]
162    pub fn truncate(self) -> DVec3 {
163        use crate::swizzles::Vec4Swizzles;
164        self.xyz()
165    }
166
167    /// Computes the dot product of `self` and `rhs`.
168    #[inline]
169    #[must_use]
170    pub fn dot(self, rhs: Self) -> f64 {
171        (self.x * rhs.x) + (self.y * rhs.y) + (self.z * rhs.z) + (self.w * rhs.w)
172    }
173
174    /// Returns a vector where every component is the dot product of `self` and `rhs`.
175    #[inline]
176    #[must_use]
177    pub fn dot_into_vec(self, rhs: Self) -> Self {
178        Self::splat(self.dot(rhs))
179    }
180
181    /// Returns a vector containing the minimum values for each element of `self` and `rhs`.
182    ///
183    /// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`.
184    #[inline]
185    #[must_use]
186    pub fn min(self, rhs: Self) -> Self {
187        Self {
188            x: self.x.min(rhs.x),
189            y: self.y.min(rhs.y),
190            z: self.z.min(rhs.z),
191            w: self.w.min(rhs.w),
192        }
193    }
194
195    /// Returns a vector containing the maximum values for each element of `self` and `rhs`.
196    ///
197    /// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`.
198    #[inline]
199    #[must_use]
200    pub fn max(self, rhs: Self) -> Self {
201        Self {
202            x: self.x.max(rhs.x),
203            y: self.y.max(rhs.y),
204            z: self.z.max(rhs.z),
205            w: self.w.max(rhs.w),
206        }
207    }
208
209    /// Component-wise clamping of values, similar to [`f64::clamp`].
210    ///
211    /// Each element in `min` must be less-or-equal to the corresponding element in `max`.
212    ///
213    /// # Panics
214    ///
215    /// Will panic if `min` is greater than `max` when `glam_assert` is enabled.
216    #[inline]
217    #[must_use]
218    pub fn clamp(self, min: Self, max: Self) -> Self {
219        glam_assert!(min.cmple(max).all(), "clamp: expected min <= max");
220        self.max(min).min(max)
221    }
222
223    /// Returns the horizontal minimum of `self`.
224    ///
225    /// In other words this computes `min(x, y, ..)`.
226    #[inline]
227    #[must_use]
228    pub fn min_element(self) -> f64 {
229        self.x.min(self.y.min(self.z.min(self.w)))
230    }
231
232    /// Returns the horizontal maximum of `self`.
233    ///
234    /// In other words this computes `max(x, y, ..)`.
235    #[inline]
236    #[must_use]
237    pub fn max_element(self) -> f64 {
238        self.x.max(self.y.max(self.z.max(self.w)))
239    }
240
241    /// Returns a vector mask containing the result of a `==` comparison for each element of
242    /// `self` and `rhs`.
243    ///
244    /// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all
245    /// elements.
246    #[inline]
247    #[must_use]
248    pub fn cmpeq(self, rhs: Self) -> BVec4 {
249        BVec4::new(
250            self.x.eq(&rhs.x),
251            self.y.eq(&rhs.y),
252            self.z.eq(&rhs.z),
253            self.w.eq(&rhs.w),
254        )
255    }
256
257    /// Returns a vector mask containing the result of a `!=` comparison for each element of
258    /// `self` and `rhs`.
259    ///
260    /// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all
261    /// elements.
262    #[inline]
263    #[must_use]
264    pub fn cmpne(self, rhs: Self) -> BVec4 {
265        BVec4::new(
266            self.x.ne(&rhs.x),
267            self.y.ne(&rhs.y),
268            self.z.ne(&rhs.z),
269            self.w.ne(&rhs.w),
270        )
271    }
272
273    /// Returns a vector mask containing the result of a `>=` comparison for each element of
274    /// `self` and `rhs`.
275    ///
276    /// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all
277    /// elements.
278    #[inline]
279    #[must_use]
280    pub fn cmpge(self, rhs: Self) -> BVec4 {
281        BVec4::new(
282            self.x.ge(&rhs.x),
283            self.y.ge(&rhs.y),
284            self.z.ge(&rhs.z),
285            self.w.ge(&rhs.w),
286        )
287    }
288
289    /// Returns a vector mask containing the result of a `>` comparison for each element of
290    /// `self` and `rhs`.
291    ///
292    /// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all
293    /// elements.
294    #[inline]
295    #[must_use]
296    pub fn cmpgt(self, rhs: Self) -> BVec4 {
297        BVec4::new(
298            self.x.gt(&rhs.x),
299            self.y.gt(&rhs.y),
300            self.z.gt(&rhs.z),
301            self.w.gt(&rhs.w),
302        )
303    }
304
305    /// Returns a vector mask containing the result of a `<=` comparison for each element of
306    /// `self` and `rhs`.
307    ///
308    /// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all
309    /// elements.
310    #[inline]
311    #[must_use]
312    pub fn cmple(self, rhs: Self) -> BVec4 {
313        BVec4::new(
314            self.x.le(&rhs.x),
315            self.y.le(&rhs.y),
316            self.z.le(&rhs.z),
317            self.w.le(&rhs.w),
318        )
319    }
320
321    /// Returns a vector mask containing the result of a `<` comparison for each element of
322    /// `self` and `rhs`.
323    ///
324    /// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all
325    /// elements.
326    #[inline]
327    #[must_use]
328    pub fn cmplt(self, rhs: Self) -> BVec4 {
329        BVec4::new(
330            self.x.lt(&rhs.x),
331            self.y.lt(&rhs.y),
332            self.z.lt(&rhs.z),
333            self.w.lt(&rhs.w),
334        )
335    }
336
337    /// Returns a vector containing the absolute value of each element of `self`.
338    #[inline]
339    #[must_use]
340    pub fn abs(self) -> Self {
341        Self {
342            x: math::abs(self.x),
343            y: math::abs(self.y),
344            z: math::abs(self.z),
345            w: math::abs(self.w),
346        }
347    }
348
349    /// Returns a vector with elements representing the sign of `self`.
350    ///
351    /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
352    /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
353    /// - `NAN` if the number is `NAN`
354    #[inline]
355    #[must_use]
356    pub fn signum(self) -> Self {
357        Self {
358            x: math::signum(self.x),
359            y: math::signum(self.y),
360            z: math::signum(self.z),
361            w: math::signum(self.w),
362        }
363    }
364
365    /// Returns a vector with signs of `rhs` and the magnitudes of `self`.
366    #[inline]
367    #[must_use]
368    pub fn copysign(self, rhs: Self) -> Self {
369        Self {
370            x: math::copysign(self.x, rhs.x),
371            y: math::copysign(self.y, rhs.y),
372            z: math::copysign(self.z, rhs.z),
373            w: math::copysign(self.w, rhs.w),
374        }
375    }
376
377    /// Returns a bitmask with the lowest 4 bits set to the sign bits from the elements of `self`.
378    ///
379    /// A negative element results in a `1` bit and a positive element in a `0` bit.  Element `x` goes
380    /// into the first lowest bit, element `y` into the second, etc.
381    #[inline]
382    #[must_use]
383    pub fn is_negative_bitmask(self) -> u32 {
384        (self.x.is_sign_negative() as u32)
385            | (self.y.is_sign_negative() as u32) << 1
386            | (self.z.is_sign_negative() as u32) << 2
387            | (self.w.is_sign_negative() as u32) << 3
388    }
389
390    /// Returns `true` if, and only if, all elements are finite.  If any element is either
391    /// `NaN`, positive or negative infinity, this will return `false`.
392    #[inline]
393    #[must_use]
394    pub fn is_finite(self) -> bool {
395        self.x.is_finite() && self.y.is_finite() && self.z.is_finite() && self.w.is_finite()
396    }
397
398    /// Returns `true` if any elements are `NaN`.
399    #[inline]
400    #[must_use]
401    pub fn is_nan(self) -> bool {
402        self.x.is_nan() || self.y.is_nan() || self.z.is_nan() || self.w.is_nan()
403    }
404
405    /// Performs `is_nan` on each element of self, returning a vector mask of the results.
406    ///
407    /// In other words, this computes `[x.is_nan(), y.is_nan(), z.is_nan(), w.is_nan()]`.
408    #[inline]
409    #[must_use]
410    pub fn is_nan_mask(self) -> BVec4 {
411        BVec4::new(
412            self.x.is_nan(),
413            self.y.is_nan(),
414            self.z.is_nan(),
415            self.w.is_nan(),
416        )
417    }
418
419    /// Computes the length of `self`.
420    #[doc(alias = "magnitude")]
421    #[inline]
422    #[must_use]
423    pub fn length(self) -> f64 {
424        math::sqrt(self.dot(self))
425    }
426
427    /// Computes the squared length of `self`.
428    ///
429    /// This is faster than `length()` as it avoids a square root operation.
430    #[doc(alias = "magnitude2")]
431    #[inline]
432    #[must_use]
433    pub fn length_squared(self) -> f64 {
434        self.dot(self)
435    }
436
437    /// Computes `1.0 / length()`.
438    ///
439    /// For valid results, `self` must _not_ be of length zero.
440    #[inline]
441    #[must_use]
442    pub fn length_recip(self) -> f64 {
443        self.length().recip()
444    }
445
446    /// Computes the Euclidean distance between two points in space.
447    #[inline]
448    #[must_use]
449    pub fn distance(self, rhs: Self) -> f64 {
450        (self - rhs).length()
451    }
452
453    /// Compute the squared euclidean distance between two points in space.
454    #[inline]
455    #[must_use]
456    pub fn distance_squared(self, rhs: Self) -> f64 {
457        (self - rhs).length_squared()
458    }
459
460    /// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`.
461    #[inline]
462    #[must_use]
463    pub fn div_euclid(self, rhs: Self) -> Self {
464        Self::new(
465            math::div_euclid(self.x, rhs.x),
466            math::div_euclid(self.y, rhs.y),
467            math::div_euclid(self.z, rhs.z),
468            math::div_euclid(self.w, rhs.w),
469        )
470    }
471
472    /// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`.
473    ///
474    /// [Euclidean division]: f64::rem_euclid
475    #[inline]
476    #[must_use]
477    pub fn rem_euclid(self, rhs: Self) -> Self {
478        Self::new(
479            math::rem_euclid(self.x, rhs.x),
480            math::rem_euclid(self.y, rhs.y),
481            math::rem_euclid(self.z, rhs.z),
482            math::rem_euclid(self.w, rhs.w),
483        )
484    }
485
486    /// Returns `self` normalized to length 1.0.
487    ///
488    /// For valid results, `self` must _not_ be of length zero, nor very close to zero.
489    ///
490    /// See also [`Self::try_normalize()`] and [`Self::normalize_or_zero()`].
491    ///
492    /// Panics
493    ///
494    /// Will panic if `self` is zero length when `glam_assert` is enabled.
495    #[inline]
496    #[must_use]
497    pub fn normalize(self) -> Self {
498        #[allow(clippy::let_and_return)]
499        let normalized = self.mul(self.length_recip());
500        glam_assert!(normalized.is_finite());
501        normalized
502    }
503
504    /// Returns `self` normalized to length 1.0 if possible, else returns `None`.
505    ///
506    /// In particular, if the input is zero (or very close to zero), or non-finite,
507    /// the result of this operation will be `None`.
508    ///
509    /// See also [`Self::normalize_or_zero()`].
510    #[inline]
511    #[must_use]
512    pub fn try_normalize(self) -> Option<Self> {
513        let rcp = self.length_recip();
514        if rcp.is_finite() && rcp > 0.0 {
515            Some(self * rcp)
516        } else {
517            None
518        }
519    }
520
521    /// Returns `self` normalized to length 1.0 if possible, else returns zero.
522    ///
523    /// In particular, if the input is zero (or very close to zero), or non-finite,
524    /// the result of this operation will be zero.
525    ///
526    /// See also [`Self::try_normalize()`].
527    #[inline]
528    #[must_use]
529    pub fn normalize_or_zero(self) -> Self {
530        let rcp = self.length_recip();
531        if rcp.is_finite() && rcp > 0.0 {
532            self * rcp
533        } else {
534            Self::ZERO
535        }
536    }
537
538    /// Returns whether `self` is length `1.0` or not.
539    ///
540    /// Uses a precision threshold of `1e-6`.
541    #[inline]
542    #[must_use]
543    pub fn is_normalized(self) -> bool {
544        // TODO: do something with epsilon
545        math::abs(self.length_squared() - 1.0) <= 1e-4
546    }
547
548    /// Returns the vector projection of `self` onto `rhs`.
549    ///
550    /// `rhs` must be of non-zero length.
551    ///
552    /// # Panics
553    ///
554    /// Will panic if `rhs` is zero length when `glam_assert` is enabled.
555    #[inline]
556    #[must_use]
557    pub fn project_onto(self, rhs: Self) -> Self {
558        let other_len_sq_rcp = rhs.dot(rhs).recip();
559        glam_assert!(other_len_sq_rcp.is_finite());
560        rhs * self.dot(rhs) * other_len_sq_rcp
561    }
562
563    /// Returns the vector rejection of `self` from `rhs`.
564    ///
565    /// The vector rejection is the vector perpendicular to the projection of `self` onto
566    /// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`.
567    ///
568    /// `rhs` must be of non-zero length.
569    ///
570    /// # Panics
571    ///
572    /// Will panic if `rhs` has a length of zero when `glam_assert` is enabled.
573    #[inline]
574    #[must_use]
575    pub fn reject_from(self, rhs: Self) -> Self {
576        self - self.project_onto(rhs)
577    }
578
579    /// Returns the vector projection of `self` onto `rhs`.
580    ///
581    /// `rhs` must be normalized.
582    ///
583    /// # Panics
584    ///
585    /// Will panic if `rhs` is not normalized when `glam_assert` is enabled.
586    #[inline]
587    #[must_use]
588    pub fn project_onto_normalized(self, rhs: Self) -> Self {
589        glam_assert!(rhs.is_normalized());
590        rhs * self.dot(rhs)
591    }
592
593    /// Returns the vector rejection of `self` from `rhs`.
594    ///
595    /// The vector rejection is the vector perpendicular to the projection of `self` onto
596    /// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`.
597    ///
598    /// `rhs` must be normalized.
599    ///
600    /// # Panics
601    ///
602    /// Will panic if `rhs` is not normalized when `glam_assert` is enabled.
603    #[inline]
604    #[must_use]
605    pub fn reject_from_normalized(self, rhs: Self) -> Self {
606        self - self.project_onto_normalized(rhs)
607    }
608
609    /// Returns a vector containing the nearest integer to a number for each element of `self`.
610    /// Round half-way cases away from 0.0.
611    #[inline]
612    #[must_use]
613    pub fn round(self) -> Self {
614        Self {
615            x: math::round(self.x),
616            y: math::round(self.y),
617            z: math::round(self.z),
618            w: math::round(self.w),
619        }
620    }
621
622    /// Returns a vector containing the largest integer less than or equal to a number for each
623    /// element of `self`.
624    #[inline]
625    #[must_use]
626    pub fn floor(self) -> Self {
627        Self {
628            x: math::floor(self.x),
629            y: math::floor(self.y),
630            z: math::floor(self.z),
631            w: math::floor(self.w),
632        }
633    }
634
635    /// Returns a vector containing the smallest integer greater than or equal to a number for
636    /// each element of `self`.
637    #[inline]
638    #[must_use]
639    pub fn ceil(self) -> Self {
640        Self {
641            x: math::ceil(self.x),
642            y: math::ceil(self.y),
643            z: math::ceil(self.z),
644            w: math::ceil(self.w),
645        }
646    }
647
648    /// Returns a vector containing the integer part each element of `self`. This means numbers are
649    /// always truncated towards zero.
650    #[inline]
651    #[must_use]
652    pub fn trunc(self) -> Self {
653        Self {
654            x: math::trunc(self.x),
655            y: math::trunc(self.y),
656            z: math::trunc(self.z),
657            w: math::trunc(self.w),
658        }
659    }
660
661    /// Returns a vector containing the fractional part of the vector, e.g. `self -
662    /// self.floor()`.
663    ///
664    /// Note that this is fast but not precise for large numbers.
665    #[inline]
666    #[must_use]
667    pub fn fract(self) -> Self {
668        self - self.floor()
669    }
670
671    /// Returns a vector containing `e^self` (the exponential function) for each element of
672    /// `self`.
673    #[inline]
674    #[must_use]
675    pub fn exp(self) -> Self {
676        Self::new(
677            math::exp(self.x),
678            math::exp(self.y),
679            math::exp(self.z),
680            math::exp(self.w),
681        )
682    }
683
684    /// Returns a vector containing each element of `self` raised to the power of `n`.
685    #[inline]
686    #[must_use]
687    pub fn powf(self, n: f64) -> Self {
688        Self::new(
689            math::powf(self.x, n),
690            math::powf(self.y, n),
691            math::powf(self.z, n),
692            math::powf(self.w, n),
693        )
694    }
695
696    /// Returns a vector containing the reciprocal `1.0/n` of each element of `self`.
697    #[inline]
698    #[must_use]
699    pub fn recip(self) -> Self {
700        Self {
701            x: 1.0 / self.x,
702            y: 1.0 / self.y,
703            z: 1.0 / self.z,
704            w: 1.0 / self.w,
705        }
706    }
707
708    /// Performs a linear interpolation between `self` and `rhs` based on the value `s`.
709    ///
710    /// When `s` is `0.0`, the result will be equal to `self`.  When `s` is `1.0`, the result
711    /// will be equal to `rhs`. When `s` is outside of range `[0, 1]`, the result is linearly
712    /// extrapolated.
713    #[doc(alias = "mix")]
714    #[inline]
715    #[must_use]
716    pub fn lerp(self, rhs: Self, s: f64) -> Self {
717        self + ((rhs - self) * s)
718    }
719
720    /// Returns true if the absolute difference of all elements between `self` and `rhs` is
721    /// less than or equal to `max_abs_diff`.
722    ///
723    /// This can be used to compare if two vectors contain similar elements. It works best when
724    /// comparing with a known value. The `max_abs_diff` that should be used used depends on
725    /// the values being compared against.
726    ///
727    /// For more see
728    /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
729    #[inline]
730    #[must_use]
731    pub fn abs_diff_eq(self, rhs: Self, max_abs_diff: f64) -> bool {
732        self.sub(rhs).abs().cmple(Self::splat(max_abs_diff)).all()
733    }
734
735    /// Returns a vector with a length no less than `min` and no more than `max`
736    ///
737    /// # Panics
738    ///
739    /// Will panic if `min` is greater than `max` when `glam_assert` is enabled.
740    #[inline]
741    #[must_use]
742    pub fn clamp_length(self, min: f64, max: f64) -> Self {
743        glam_assert!(min <= max);
744        let length_sq = self.length_squared();
745        if length_sq < min * min {
746            min * (self / math::sqrt(length_sq))
747        } else if length_sq > max * max {
748            max * (self / math::sqrt(length_sq))
749        } else {
750            self
751        }
752    }
753
754    /// Returns a vector with a length no more than `max`
755    #[inline]
756    #[must_use]
757    pub fn clamp_length_max(self, max: f64) -> Self {
758        let length_sq = self.length_squared();
759        if length_sq > max * max {
760            max * (self / math::sqrt(length_sq))
761        } else {
762            self
763        }
764    }
765
766    /// Returns a vector with a length no less than `min`
767    #[inline]
768    #[must_use]
769    pub fn clamp_length_min(self, min: f64) -> Self {
770        let length_sq = self.length_squared();
771        if length_sq < min * min {
772            min * (self / math::sqrt(length_sq))
773        } else {
774            self
775        }
776    }
777
778    /// Fused multiply-add. Computes `(self * a) + b` element-wise with only one rounding
779    /// error, yielding a more accurate result than an unfused multiply-add.
780    ///
781    /// Using `mul_add` *may* be more performant than an unfused multiply-add if the target
782    /// architecture has a dedicated fma CPU instruction. However, this is not always true,
783    /// and will be heavily dependant on designing algorithms with specific target hardware in
784    /// mind.
785    #[inline]
786    #[must_use]
787    pub fn mul_add(self, a: Self, b: Self) -> Self {
788        Self::new(
789            math::mul_add(self.x, a.x, b.x),
790            math::mul_add(self.y, a.y, b.y),
791            math::mul_add(self.z, a.z, b.z),
792            math::mul_add(self.w, a.w, b.w),
793        )
794    }
795
796    /// Casts all elements of `self` to `f32`.
797    #[inline]
798    #[must_use]
799    pub fn as_vec4(&self) -> crate::Vec4 {
800        crate::Vec4::new(self.x as f32, self.y as f32, self.z as f32, self.w as f32)
801    }
802
803    /// Casts all elements of `self` to `i16`.
804    #[inline]
805    #[must_use]
806    pub fn as_i16vec4(&self) -> crate::I16Vec4 {
807        crate::I16Vec4::new(self.x as i16, self.y as i16, self.z as i16, self.w as i16)
808    }
809
810    /// Casts all elements of `self` to `u16`.
811    #[inline]
812    #[must_use]
813    pub fn as_u16vec4(&self) -> crate::U16Vec4 {
814        crate::U16Vec4::new(self.x as u16, self.y as u16, self.z as u16, self.w as u16)
815    }
816
817    /// Casts all elements of `self` to `i32`.
818    #[inline]
819    #[must_use]
820    pub fn as_ivec4(&self) -> crate::IVec4 {
821        crate::IVec4::new(self.x as i32, self.y as i32, self.z as i32, self.w as i32)
822    }
823
824    /// Casts all elements of `self` to `u32`.
825    #[inline]
826    #[must_use]
827    pub fn as_uvec4(&self) -> crate::UVec4 {
828        crate::UVec4::new(self.x as u32, self.y as u32, self.z as u32, self.w as u32)
829    }
830
831    /// Casts all elements of `self` to `i64`.
832    #[inline]
833    #[must_use]
834    pub fn as_i64vec4(&self) -> crate::I64Vec4 {
835        crate::I64Vec4::new(self.x as i64, self.y as i64, self.z as i64, self.w as i64)
836    }
837
838    /// Casts all elements of `self` to `u64`.
839    #[inline]
840    #[must_use]
841    pub fn as_u64vec4(&self) -> crate::U64Vec4 {
842        crate::U64Vec4::new(self.x as u64, self.y as u64, self.z as u64, self.w as u64)
843    }
844}
845
846impl Default for DVec4 {
847    #[inline(always)]
848    fn default() -> Self {
849        Self::ZERO
850    }
851}
852
853impl Div<DVec4> for DVec4 {
854    type Output = Self;
855    #[inline]
856    fn div(self, rhs: Self) -> Self {
857        Self {
858            x: self.x.div(rhs.x),
859            y: self.y.div(rhs.y),
860            z: self.z.div(rhs.z),
861            w: self.w.div(rhs.w),
862        }
863    }
864}
865
866impl DivAssign<DVec4> for DVec4 {
867    #[inline]
868    fn div_assign(&mut self, rhs: Self) {
869        self.x.div_assign(rhs.x);
870        self.y.div_assign(rhs.y);
871        self.z.div_assign(rhs.z);
872        self.w.div_assign(rhs.w);
873    }
874}
875
876impl Div<f64> for DVec4 {
877    type Output = Self;
878    #[inline]
879    fn div(self, rhs: f64) -> Self {
880        Self {
881            x: self.x.div(rhs),
882            y: self.y.div(rhs),
883            z: self.z.div(rhs),
884            w: self.w.div(rhs),
885        }
886    }
887}
888
889impl DivAssign<f64> for DVec4 {
890    #[inline]
891    fn div_assign(&mut self, rhs: f64) {
892        self.x.div_assign(rhs);
893        self.y.div_assign(rhs);
894        self.z.div_assign(rhs);
895        self.w.div_assign(rhs);
896    }
897}
898
899impl Div<DVec4> for f64 {
900    type Output = DVec4;
901    #[inline]
902    fn div(self, rhs: DVec4) -> DVec4 {
903        DVec4 {
904            x: self.div(rhs.x),
905            y: self.div(rhs.y),
906            z: self.div(rhs.z),
907            w: self.div(rhs.w),
908        }
909    }
910}
911
912impl Mul<DVec4> for DVec4 {
913    type Output = Self;
914    #[inline]
915    fn mul(self, rhs: Self) -> Self {
916        Self {
917            x: self.x.mul(rhs.x),
918            y: self.y.mul(rhs.y),
919            z: self.z.mul(rhs.z),
920            w: self.w.mul(rhs.w),
921        }
922    }
923}
924
925impl MulAssign<DVec4> for DVec4 {
926    #[inline]
927    fn mul_assign(&mut self, rhs: Self) {
928        self.x.mul_assign(rhs.x);
929        self.y.mul_assign(rhs.y);
930        self.z.mul_assign(rhs.z);
931        self.w.mul_assign(rhs.w);
932    }
933}
934
935impl Mul<f64> for DVec4 {
936    type Output = Self;
937    #[inline]
938    fn mul(self, rhs: f64) -> Self {
939        Self {
940            x: self.x.mul(rhs),
941            y: self.y.mul(rhs),
942            z: self.z.mul(rhs),
943            w: self.w.mul(rhs),
944        }
945    }
946}
947
948impl MulAssign<f64> for DVec4 {
949    #[inline]
950    fn mul_assign(&mut self, rhs: f64) {
951        self.x.mul_assign(rhs);
952        self.y.mul_assign(rhs);
953        self.z.mul_assign(rhs);
954        self.w.mul_assign(rhs);
955    }
956}
957
958impl Mul<DVec4> for f64 {
959    type Output = DVec4;
960    #[inline]
961    fn mul(self, rhs: DVec4) -> DVec4 {
962        DVec4 {
963            x: self.mul(rhs.x),
964            y: self.mul(rhs.y),
965            z: self.mul(rhs.z),
966            w: self.mul(rhs.w),
967        }
968    }
969}
970
971impl Add<DVec4> for DVec4 {
972    type Output = Self;
973    #[inline]
974    fn add(self, rhs: Self) -> Self {
975        Self {
976            x: self.x.add(rhs.x),
977            y: self.y.add(rhs.y),
978            z: self.z.add(rhs.z),
979            w: self.w.add(rhs.w),
980        }
981    }
982}
983
984impl AddAssign<DVec4> for DVec4 {
985    #[inline]
986    fn add_assign(&mut self, rhs: Self) {
987        self.x.add_assign(rhs.x);
988        self.y.add_assign(rhs.y);
989        self.z.add_assign(rhs.z);
990        self.w.add_assign(rhs.w);
991    }
992}
993
994impl Add<f64> for DVec4 {
995    type Output = Self;
996    #[inline]
997    fn add(self, rhs: f64) -> Self {
998        Self {
999            x: self.x.add(rhs),
1000            y: self.y.add(rhs),
1001            z: self.z.add(rhs),
1002            w: self.w.add(rhs),
1003        }
1004    }
1005}
1006
1007impl AddAssign<f64> for DVec4 {
1008    #[inline]
1009    fn add_assign(&mut self, rhs: f64) {
1010        self.x.add_assign(rhs);
1011        self.y.add_assign(rhs);
1012        self.z.add_assign(rhs);
1013        self.w.add_assign(rhs);
1014    }
1015}
1016
1017impl Add<DVec4> for f64 {
1018    type Output = DVec4;
1019    #[inline]
1020    fn add(self, rhs: DVec4) -> DVec4 {
1021        DVec4 {
1022            x: self.add(rhs.x),
1023            y: self.add(rhs.y),
1024            z: self.add(rhs.z),
1025            w: self.add(rhs.w),
1026        }
1027    }
1028}
1029
1030impl Sub<DVec4> for DVec4 {
1031    type Output = Self;
1032    #[inline]
1033    fn sub(self, rhs: Self) -> Self {
1034        Self {
1035            x: self.x.sub(rhs.x),
1036            y: self.y.sub(rhs.y),
1037            z: self.z.sub(rhs.z),
1038            w: self.w.sub(rhs.w),
1039        }
1040    }
1041}
1042
1043impl SubAssign<DVec4> for DVec4 {
1044    #[inline]
1045    fn sub_assign(&mut self, rhs: DVec4) {
1046        self.x.sub_assign(rhs.x);
1047        self.y.sub_assign(rhs.y);
1048        self.z.sub_assign(rhs.z);
1049        self.w.sub_assign(rhs.w);
1050    }
1051}
1052
1053impl Sub<f64> for DVec4 {
1054    type Output = Self;
1055    #[inline]
1056    fn sub(self, rhs: f64) -> Self {
1057        Self {
1058            x: self.x.sub(rhs),
1059            y: self.y.sub(rhs),
1060            z: self.z.sub(rhs),
1061            w: self.w.sub(rhs),
1062        }
1063    }
1064}
1065
1066impl SubAssign<f64> for DVec4 {
1067    #[inline]
1068    fn sub_assign(&mut self, rhs: f64) {
1069        self.x.sub_assign(rhs);
1070        self.y.sub_assign(rhs);
1071        self.z.sub_assign(rhs);
1072        self.w.sub_assign(rhs);
1073    }
1074}
1075
1076impl Sub<DVec4> for f64 {
1077    type Output = DVec4;
1078    #[inline]
1079    fn sub(self, rhs: DVec4) -> DVec4 {
1080        DVec4 {
1081            x: self.sub(rhs.x),
1082            y: self.sub(rhs.y),
1083            z: self.sub(rhs.z),
1084            w: self.sub(rhs.w),
1085        }
1086    }
1087}
1088
1089impl Rem<DVec4> for DVec4 {
1090    type Output = Self;
1091    #[inline]
1092    fn rem(self, rhs: Self) -> Self {
1093        Self {
1094            x: self.x.rem(rhs.x),
1095            y: self.y.rem(rhs.y),
1096            z: self.z.rem(rhs.z),
1097            w: self.w.rem(rhs.w),
1098        }
1099    }
1100}
1101
1102impl RemAssign<DVec4> for DVec4 {
1103    #[inline]
1104    fn rem_assign(&mut self, rhs: Self) {
1105        self.x.rem_assign(rhs.x);
1106        self.y.rem_assign(rhs.y);
1107        self.z.rem_assign(rhs.z);
1108        self.w.rem_assign(rhs.w);
1109    }
1110}
1111
1112impl Rem<f64> for DVec4 {
1113    type Output = Self;
1114    #[inline]
1115    fn rem(self, rhs: f64) -> Self {
1116        Self {
1117            x: self.x.rem(rhs),
1118            y: self.y.rem(rhs),
1119            z: self.z.rem(rhs),
1120            w: self.w.rem(rhs),
1121        }
1122    }
1123}
1124
1125impl RemAssign<f64> for DVec4 {
1126    #[inline]
1127    fn rem_assign(&mut self, rhs: f64) {
1128        self.x.rem_assign(rhs);
1129        self.y.rem_assign(rhs);
1130        self.z.rem_assign(rhs);
1131        self.w.rem_assign(rhs);
1132    }
1133}
1134
1135impl Rem<DVec4> for f64 {
1136    type Output = DVec4;
1137    #[inline]
1138    fn rem(self, rhs: DVec4) -> DVec4 {
1139        DVec4 {
1140            x: self.rem(rhs.x),
1141            y: self.rem(rhs.y),
1142            z: self.rem(rhs.z),
1143            w: self.rem(rhs.w),
1144        }
1145    }
1146}
1147
1148#[cfg(not(target_arch = "spirv"))]
1149impl AsRef<[f64; 4]> for DVec4 {
1150    #[inline]
1151    fn as_ref(&self) -> &[f64; 4] {
1152        unsafe { &*(self as *const DVec4 as *const [f64; 4]) }
1153    }
1154}
1155
1156#[cfg(not(target_arch = "spirv"))]
1157impl AsMut<[f64; 4]> for DVec4 {
1158    #[inline]
1159    fn as_mut(&mut self) -> &mut [f64; 4] {
1160        unsafe { &mut *(self as *mut DVec4 as *mut [f64; 4]) }
1161    }
1162}
1163
1164impl Sum for DVec4 {
1165    #[inline]
1166    fn sum<I>(iter: I) -> Self
1167    where
1168        I: Iterator<Item = Self>,
1169    {
1170        iter.fold(Self::ZERO, Self::add)
1171    }
1172}
1173
1174impl<'a> Sum<&'a Self> for DVec4 {
1175    #[inline]
1176    fn sum<I>(iter: I) -> Self
1177    where
1178        I: Iterator<Item = &'a Self>,
1179    {
1180        iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
1181    }
1182}
1183
1184impl Product for DVec4 {
1185    #[inline]
1186    fn product<I>(iter: I) -> Self
1187    where
1188        I: Iterator<Item = Self>,
1189    {
1190        iter.fold(Self::ONE, Self::mul)
1191    }
1192}
1193
1194impl<'a> Product<&'a Self> for DVec4 {
1195    #[inline]
1196    fn product<I>(iter: I) -> Self
1197    where
1198        I: Iterator<Item = &'a Self>,
1199    {
1200        iter.fold(Self::ONE, |a, &b| Self::mul(a, b))
1201    }
1202}
1203
1204impl Neg for DVec4 {
1205    type Output = Self;
1206    #[inline]
1207    fn neg(self) -> Self {
1208        Self {
1209            x: self.x.neg(),
1210            y: self.y.neg(),
1211            z: self.z.neg(),
1212            w: self.w.neg(),
1213        }
1214    }
1215}
1216
1217impl Index<usize> for DVec4 {
1218    type Output = f64;
1219    #[inline]
1220    fn index(&self, index: usize) -> &Self::Output {
1221        match index {
1222            0 => &self.x,
1223            1 => &self.y,
1224            2 => &self.z,
1225            3 => &self.w,
1226            _ => panic!("index out of bounds"),
1227        }
1228    }
1229}
1230
1231impl IndexMut<usize> for DVec4 {
1232    #[inline]
1233    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1234        match index {
1235            0 => &mut self.x,
1236            1 => &mut self.y,
1237            2 => &mut self.z,
1238            3 => &mut self.w,
1239            _ => panic!("index out of bounds"),
1240        }
1241    }
1242}
1243
1244#[cfg(not(target_arch = "spirv"))]
1245impl fmt::Display for DVec4 {
1246    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1247        write!(f, "[{}, {}, {}, {}]", self.x, self.y, self.z, self.w)
1248    }
1249}
1250
1251#[cfg(not(target_arch = "spirv"))]
1252impl fmt::Debug for DVec4 {
1253    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1254        fmt.debug_tuple(stringify!(DVec4))
1255            .field(&self.x)
1256            .field(&self.y)
1257            .field(&self.z)
1258            .field(&self.w)
1259            .finish()
1260    }
1261}
1262
1263impl From<[f64; 4]> for DVec4 {
1264    #[inline]
1265    fn from(a: [f64; 4]) -> Self {
1266        Self::new(a[0], a[1], a[2], a[3])
1267    }
1268}
1269
1270impl From<DVec4> for [f64; 4] {
1271    #[inline]
1272    fn from(v: DVec4) -> Self {
1273        [v.x, v.y, v.z, v.w]
1274    }
1275}
1276
1277impl From<(f64, f64, f64, f64)> for DVec4 {
1278    #[inline]
1279    fn from(t: (f64, f64, f64, f64)) -> Self {
1280        Self::new(t.0, t.1, t.2, t.3)
1281    }
1282}
1283
1284impl From<DVec4> for (f64, f64, f64, f64) {
1285    #[inline]
1286    fn from(v: DVec4) -> Self {
1287        (v.x, v.y, v.z, v.w)
1288    }
1289}
1290
1291impl From<(DVec3, f64)> for DVec4 {
1292    #[inline]
1293    fn from((v, w): (DVec3, f64)) -> Self {
1294        Self::new(v.x, v.y, v.z, w)
1295    }
1296}
1297
1298impl From<(f64, DVec3)> for DVec4 {
1299    #[inline]
1300    fn from((x, v): (f64, DVec3)) -> Self {
1301        Self::new(x, v.x, v.y, v.z)
1302    }
1303}
1304
1305impl From<(DVec2, f64, f64)> for DVec4 {
1306    #[inline]
1307    fn from((v, z, w): (DVec2, f64, f64)) -> Self {
1308        Self::new(v.x, v.y, z, w)
1309    }
1310}
1311
1312impl From<(DVec2, DVec2)> for DVec4 {
1313    #[inline]
1314    fn from((v, u): (DVec2, DVec2)) -> Self {
1315        Self::new(v.x, v.y, u.x, u.y)
1316    }
1317}
1318
1319impl From<Vec4> for DVec4 {
1320    #[inline]
1321    fn from(v: Vec4) -> Self {
1322        Self::new(
1323            f64::from(v.x),
1324            f64::from(v.y),
1325            f64::from(v.z),
1326            f64::from(v.w),
1327        )
1328    }
1329}
1330
1331impl From<IVec4> for DVec4 {
1332    #[inline]
1333    fn from(v: IVec4) -> Self {
1334        Self::new(
1335            f64::from(v.x),
1336            f64::from(v.y),
1337            f64::from(v.z),
1338            f64::from(v.w),
1339        )
1340    }
1341}
1342
1343impl From<UVec4> for DVec4 {
1344    #[inline]
1345    fn from(v: UVec4) -> Self {
1346        Self::new(
1347            f64::from(v.x),
1348            f64::from(v.y),
1349            f64::from(v.z),
1350            f64::from(v.w),
1351        )
1352    }
1353}