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