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