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