1 // Generated from vec.rs.tera template. Edit the template, not the generated file.
2
3 use crate::{coresimd::*, f32::math, BVec4A, Vec2, Vec3, Vec3A};
4
5 #[cfg(not(target_arch = "spirv"))]
6 use core::fmt;
7 use core::iter::{Product, Sum};
8 use core::{f32, ops::*};
9
10 use core::simd::{cmp::SimdPartialEq, cmp::SimdPartialOrd, num::SimdFloat, *};
11 use std::simd::StdFloat;
12
13 /// Creates a 4-dimensional vector.
14 #[inline(always)]
15 #[must_use]
vec4(x: f32, y: f32, z: f32, w: f32) -> Vec416 pub const fn vec4(x: f32, y: f32, z: f32, w: f32) -> Vec4 {
17 Vec4::new(x, y, z, w)
18 }
19
20 /// A 4-dimensional vector.
21 ///
22 /// SIMD vector types are used for storage on supported platforms.
23 ///
24 /// This type is 16 byte aligned.
25 #[derive(Clone, Copy)]
26 #[repr(transparent)]
27 pub struct Vec4(pub(crate) f32x4);
28
29 impl Vec4 {
30 /// All zeroes.
31 pub const ZERO: Self = Self::splat(0.0);
32
33 /// All ones.
34 pub const ONE: Self = Self::splat(1.0);
35
36 /// All negative ones.
37 pub const NEG_ONE: Self = Self::splat(-1.0);
38
39 /// All `f32::MIN`.
40 pub const MIN: Self = Self::splat(f32::MIN);
41
42 /// All `f32::MAX`.
43 pub const MAX: Self = Self::splat(f32::MAX);
44
45 /// All `f32::NAN`.
46 pub const NAN: Self = Self::splat(f32::NAN);
47
48 /// All `f32::INFINITY`.
49 pub const INFINITY: Self = Self::splat(f32::INFINITY);
50
51 /// All `f32::NEG_INFINITY`.
52 pub const NEG_INFINITY: Self = Self::splat(f32::NEG_INFINITY);
53
54 /// A unit vector pointing along the positive X axis.
55 pub const X: Self = Self::new(1.0, 0.0, 0.0, 0.0);
56
57 /// A unit vector pointing along the positive Y axis.
58 pub const Y: Self = Self::new(0.0, 1.0, 0.0, 0.0);
59
60 /// A unit vector pointing along the positive Z axis.
61 pub const Z: Self = Self::new(0.0, 0.0, 1.0, 0.0);
62
63 /// A unit vector pointing along the positive W axis.
64 pub const W: Self = Self::new(0.0, 0.0, 0.0, 1.0);
65
66 /// A unit vector pointing along the negative X axis.
67 pub const NEG_X: Self = Self::new(-1.0, 0.0, 0.0, 0.0);
68
69 /// A unit vector pointing along the negative Y axis.
70 pub const NEG_Y: Self = Self::new(0.0, -1.0, 0.0, 0.0);
71
72 /// A unit vector pointing along the negative Z axis.
73 pub const NEG_Z: Self = Self::new(0.0, 0.0, -1.0, 0.0);
74
75 /// A unit vector pointing along the negative W axis.
76 pub const NEG_W: Self = Self::new(0.0, 0.0, 0.0, -1.0);
77
78 /// The unit axes.
79 pub const AXES: [Self; 4] = [Self::X, Self::Y, Self::Z, Self::W];
80
81 /// Creates a new vector.
82 #[inline(always)]
83 #[must_use]
new(x: f32, y: f32, z: f32, w: f32) -> Self84 pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
85 Self(f32x4::from_array([x, y, z, w]))
86 }
87
88 /// Creates a vector with all elements set to `v`.
89 #[inline]
90 #[must_use]
splat(v: f32) -> Self91 pub const fn splat(v: f32) -> Self {
92 Self(Simd::from_array([v; 4]))
93 }
94
95 /// Creates a vector from the elements in `if_true` and `if_false`, selecting which to use
96 /// for each element of `self`.
97 ///
98 /// A true element in the mask uses the corresponding element from `if_true`, and false
99 /// uses the element from `if_false`.
100 #[inline]
101 #[must_use]
select(mask: BVec4A, if_true: Self, if_false: Self) -> Self102 pub fn select(mask: BVec4A, if_true: Self, if_false: Self) -> Self {
103 Self(mask.0.select(if_true.0, if_false.0))
104 }
105
106 /// Creates a new vector from an array.
107 #[inline]
108 #[must_use]
from_array(a: [f32; 4]) -> Self109 pub const fn from_array(a: [f32; 4]) -> Self {
110 Self::new(a[0], a[1], a[2], a[3])
111 }
112
113 /// `[x, y, z, w]`
114 #[inline]
115 #[must_use]
to_array(&self) -> [f32; 4]116 pub const fn to_array(&self) -> [f32; 4] {
117 unsafe { *(self as *const Vec4 as *const [f32; 4]) }
118 }
119
120 /// Creates a vector from the first 4 values in `slice`.
121 ///
122 /// # Panics
123 ///
124 /// Panics if `slice` is less than 4 elements long.
125 #[inline]
126 #[must_use]
from_slice(slice: &[f32]) -> Self127 pub const fn from_slice(slice: &[f32]) -> Self {
128 Self::new(slice[0], slice[1], slice[2], slice[3])
129 }
130
131 /// Writes the elements of `self` to the first 4 elements in `slice`.
132 ///
133 /// # Panics
134 ///
135 /// Panics if `slice` is less than 4 elements long.
136 #[inline]
write_to_slice(self, slice: &mut [f32])137 pub fn write_to_slice(self, slice: &mut [f32]) {
138 slice[0] = self.x;
139 slice[1] = self.y;
140 slice[2] = self.z;
141 slice[3] = self.w;
142 }
143
144 /// Creates a 3D vector from the `x`, `y` and `z` elements of `self`, discarding `w`.
145 ///
146 /// Truncation to [`Vec3`] may also be performed by using [`self.xyz()`][crate::swizzles::Vec4Swizzles::xyz()].
147 ///
148 /// To truncate to [`Vec3A`] use [`Vec3A::from()`].
149 #[inline]
150 #[must_use]
truncate(self) -> Vec3151 pub fn truncate(self) -> Vec3 {
152 use crate::swizzles::Vec4Swizzles;
153 self.xyz()
154 }
155
156 /// Computes the dot product of `self` and `rhs`.
157 #[inline]
158 #[must_use]
dot(self, rhs: Self) -> f32159 pub fn dot(self, rhs: Self) -> f32 {
160 dot4(self.0, rhs.0)
161 }
162
163 /// Returns a vector where every component is the dot product of `self` and `rhs`.
164 #[inline]
165 #[must_use]
dot_into_vec(self, rhs: Self) -> Self166 pub fn dot_into_vec(self, rhs: Self) -> Self {
167 Self(dot4_into_f32x4(self.0, rhs.0))
168 }
169
170 /// Returns a vector containing the minimum values for each element of `self` and `rhs`.
171 ///
172 /// In other words this computes `[self.x.min(rhs.x), self.y.min(rhs.y), ..]`.
173 #[inline]
174 #[must_use]
min(self, rhs: Self) -> Self175 pub fn min(self, rhs: Self) -> Self {
176 Self(self.0.simd_min(rhs.0))
177 }
178
179 /// Returns a vector containing the maximum values for each element of `self` and `rhs`.
180 ///
181 /// In other words this computes `[self.x.max(rhs.x), self.y.max(rhs.y), ..]`.
182 #[inline]
183 #[must_use]
max(self, rhs: Self) -> Self184 pub fn max(self, rhs: Self) -> Self {
185 Self(self.0.simd_max(rhs.0))
186 }
187
188 /// Component-wise clamping of values, similar to [`f32::clamp`].
189 ///
190 /// Each element in `min` must be less-or-equal to the corresponding element in `max`.
191 ///
192 /// # Panics
193 ///
194 /// Will panic if `min` is greater than `max` when `glam_assert` is enabled.
195 #[inline]
196 #[must_use]
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]
206 #[must_use]
min_element(self) -> f32207 pub fn min_element(self) -> f32 {
208 self.0.reduce_min()
209 }
210
211 /// Returns the horizontal maximum of `self`.
212 ///
213 /// In other words this computes `max(x, y, ..)`.
214 #[inline]
215 #[must_use]
max_element(self) -> f32216 pub fn max_element(self) -> f32 {
217 self.0.reduce_max()
218 }
219
220 /// Returns a vector mask containing the result of a `==` comparison for each element of
221 /// `self` and `rhs`.
222 ///
223 /// In other words, this computes `[self.x == rhs.x, self.y == rhs.y, ..]` for all
224 /// elements.
225 #[inline]
226 #[must_use]
cmpeq(self, rhs: Self) -> BVec4A227 pub fn cmpeq(self, rhs: Self) -> BVec4A {
228 BVec4A(f32x4::simd_eq(self.0, rhs.0))
229 }
230
231 /// Returns a vector mask containing the result of a `!=` comparison for each element of
232 /// `self` and `rhs`.
233 ///
234 /// In other words this computes `[self.x != rhs.x, self.y != rhs.y, ..]` for all
235 /// elements.
236 #[inline]
237 #[must_use]
cmpne(self, rhs: Self) -> BVec4A238 pub fn cmpne(self, rhs: Self) -> BVec4A {
239 BVec4A(f32x4::simd_ne(self.0, rhs.0))
240 }
241
242 /// Returns a vector mask containing the result of a `>=` comparison for each element of
243 /// `self` and `rhs`.
244 ///
245 /// In other words this computes `[self.x >= rhs.x, self.y >= rhs.y, ..]` for all
246 /// elements.
247 #[inline]
248 #[must_use]
cmpge(self, rhs: Self) -> BVec4A249 pub fn cmpge(self, rhs: Self) -> BVec4A {
250 BVec4A(f32x4::simd_ge(self.0, rhs.0))
251 }
252
253 /// Returns a vector mask containing the result of a `>` comparison for each element of
254 /// `self` and `rhs`.
255 ///
256 /// In other words this computes `[self.x > rhs.x, self.y > rhs.y, ..]` for all
257 /// elements.
258 #[inline]
259 #[must_use]
cmpgt(self, rhs: Self) -> BVec4A260 pub fn cmpgt(self, rhs: Self) -> BVec4A {
261 BVec4A(f32x4::simd_gt(self.0, rhs.0))
262 }
263
264 /// Returns a vector mask containing the result of a `<=` comparison for each element of
265 /// `self` and `rhs`.
266 ///
267 /// In other words this computes `[self.x <= rhs.x, self.y <= rhs.y, ..]` for all
268 /// elements.
269 #[inline]
270 #[must_use]
cmple(self, rhs: Self) -> BVec4A271 pub fn cmple(self, rhs: Self) -> BVec4A {
272 BVec4A(f32x4::simd_le(self.0, rhs.0))
273 }
274
275 /// Returns a vector mask containing the result of a `<` comparison for each element of
276 /// `self` and `rhs`.
277 ///
278 /// In other words this computes `[self.x < rhs.x, self.y < rhs.y, ..]` for all
279 /// elements.
280 #[inline]
281 #[must_use]
cmplt(self, rhs: Self) -> BVec4A282 pub fn cmplt(self, rhs: Self) -> BVec4A {
283 BVec4A(f32x4::simd_lt(self.0, rhs.0))
284 }
285
286 /// Returns a vector containing the absolute value of each element of `self`.
287 #[inline]
288 #[must_use]
abs(self) -> Self289 pub fn abs(self) -> Self {
290 Self(self.0.abs())
291 }
292
293 /// Returns a vector with elements representing the sign of `self`.
294 ///
295 /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
296 /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
297 /// - `NAN` if the number is `NAN`
298 #[inline]
299 #[must_use]
signum(self) -> Self300 pub fn signum(self) -> Self {
301 Self(self.0.signum())
302 }
303
304 /// Returns a vector with signs of `rhs` and the magnitudes of `self`.
305 #[inline]
306 #[must_use]
copysign(self, rhs: Self) -> Self307 pub fn copysign(self, rhs: Self) -> Self {
308 Self(self.0.copysign(rhs.0))
309 }
310
311 /// Returns a bitmask with the lowest 4 bits set to the sign bits from the elements of `self`.
312 ///
313 /// A negative element results in a `1` bit and a positive element in a `0` bit. Element `x` goes
314 /// into the first lowest bit, element `y` into the second, etc.
315 #[inline]
316 #[must_use]
is_negative_bitmask(self) -> u32317 pub fn is_negative_bitmask(self) -> u32 {
318 self.0.is_sign_negative().to_bitmask() as u32
319 }
320
321 /// Returns `true` if, and only if, all elements are finite. If any element is either
322 /// `NaN`, positive or negative infinity, this will return `false`.
323 #[inline]
324 #[must_use]
is_finite(self) -> bool325 pub fn is_finite(self) -> bool {
326 f32x4::is_finite(self.0).all()
327 }
328
329 /// Returns `true` if any elements are `NaN`.
330 #[inline]
331 #[must_use]
is_nan(self) -> bool332 pub fn is_nan(self) -> bool {
333 self.is_nan_mask().any()
334 }
335
336 /// Performs `is_nan` on each element of self, returning a vector mask of the results.
337 ///
338 /// In other words, this computes `[x.is_nan(), y.is_nan(), z.is_nan(), w.is_nan()]`.
339 #[inline]
340 #[must_use]
is_nan_mask(self) -> BVec4A341 pub fn is_nan_mask(self) -> BVec4A {
342 BVec4A(f32x4::is_nan(self.0))
343 }
344
345 /// Computes the length of `self`.
346 #[doc(alias = "magnitude")]
347 #[inline]
348 #[must_use]
length(self) -> f32349 pub fn length(self) -> f32 {
350 let dot = dot4_in_x(self.0, self.0);
351 dot.sqrt()[0]
352 }
353
354 /// Computes the squared length of `self`.
355 ///
356 /// This is faster than `length()` as it avoids a square root operation.
357 #[doc(alias = "magnitude2")]
358 #[inline]
359 #[must_use]
length_squared(self) -> f32360 pub fn length_squared(self) -> f32 {
361 self.dot(self)
362 }
363
364 /// Computes `1.0 / length()`.
365 ///
366 /// For valid results, `self` must _not_ be of length zero.
367 #[inline]
368 #[must_use]
length_recip(self) -> f32369 pub fn length_recip(self) -> f32 {
370 let dot = dot4_in_x(self.0, self.0);
371 dot.sqrt().recip()[0]
372 }
373
374 /// Computes the Euclidean distance between two points in space.
375 #[inline]
376 #[must_use]
distance(self, rhs: Self) -> f32377 pub fn distance(self, rhs: Self) -> f32 {
378 (self - rhs).length()
379 }
380
381 /// Compute the squared euclidean distance between two points in space.
382 #[inline]
383 #[must_use]
distance_squared(self, rhs: Self) -> f32384 pub fn distance_squared(self, rhs: Self) -> f32 {
385 (self - rhs).length_squared()
386 }
387
388 /// Returns the element-wise quotient of [Euclidean division] of `self` by `rhs`.
389 #[inline]
390 #[must_use]
div_euclid(self, rhs: Self) -> Self391 pub fn div_euclid(self, rhs: Self) -> Self {
392 Self::new(
393 math::div_euclid(self.x, rhs.x),
394 math::div_euclid(self.y, rhs.y),
395 math::div_euclid(self.z, rhs.z),
396 math::div_euclid(self.w, rhs.w),
397 )
398 }
399
400 /// Returns the element-wise remainder of [Euclidean division] of `self` by `rhs`.
401 ///
402 /// [Euclidean division]: f32::rem_euclid
403 #[inline]
404 #[must_use]
rem_euclid(self, rhs: Self) -> Self405 pub fn rem_euclid(self, rhs: Self) -> Self {
406 Self::new(
407 math::rem_euclid(self.x, rhs.x),
408 math::rem_euclid(self.y, rhs.y),
409 math::rem_euclid(self.z, rhs.z),
410 math::rem_euclid(self.w, rhs.w),
411 )
412 }
413
414 /// Returns `self` normalized to length 1.0.
415 ///
416 /// For valid results, `self` must _not_ be of length zero, nor very close to zero.
417 ///
418 /// See also [`Self::try_normalize()`] and [`Self::normalize_or_zero()`].
419 ///
420 /// Panics
421 ///
422 /// Will panic if `self` is zero length when `glam_assert` is enabled.
423 #[inline]
424 #[must_use]
normalize(self) -> Self425 pub fn normalize(self) -> Self {
426 let length = dot4_into_f32x4(self.0, self.0).sqrt();
427 #[allow(clippy::let_and_return)]
428 let normalized = Self(self.0 / length);
429 glam_assert!(normalized.is_finite());
430 normalized
431 }
432
433 /// Returns `self` normalized to length 1.0 if possible, else returns `None`.
434 ///
435 /// In particular, if the input is zero (or very close to zero), or non-finite,
436 /// the result of this operation will be `None`.
437 ///
438 /// See also [`Self::normalize_or_zero()`].
439 #[inline]
440 #[must_use]
try_normalize(self) -> Option<Self>441 pub fn try_normalize(self) -> Option<Self> {
442 let rcp = self.length_recip();
443 if rcp.is_finite() && rcp > 0.0 {
444 Some(self * rcp)
445 } else {
446 None
447 }
448 }
449
450 /// Returns `self` normalized to length 1.0 if possible, else returns zero.
451 ///
452 /// In particular, if the input is zero (or very close to zero), or non-finite,
453 /// the result of this operation will be zero.
454 ///
455 /// See also [`Self::try_normalize()`].
456 #[inline]
457 #[must_use]
normalize_or_zero(self) -> Self458 pub fn normalize_or_zero(self) -> Self {
459 let rcp = self.length_recip();
460 if rcp.is_finite() && rcp > 0.0 {
461 self * rcp
462 } else {
463 Self::ZERO
464 }
465 }
466
467 /// Returns whether `self` is length `1.0` or not.
468 ///
469 /// Uses a precision threshold of `1e-6`.
470 #[inline]
471 #[must_use]
is_normalized(self) -> bool472 pub fn is_normalized(self) -> bool {
473 // TODO: do something with epsilon
474 math::abs(self.length_squared() - 1.0) <= 1e-4
475 }
476
477 /// Returns the vector projection of `self` onto `rhs`.
478 ///
479 /// `rhs` must be of non-zero length.
480 ///
481 /// # Panics
482 ///
483 /// Will panic if `rhs` is zero length when `glam_assert` is enabled.
484 #[inline]
485 #[must_use]
project_onto(self, rhs: Self) -> Self486 pub fn project_onto(self, rhs: Self) -> Self {
487 let other_len_sq_rcp = rhs.dot(rhs).recip();
488 glam_assert!(other_len_sq_rcp.is_finite());
489 rhs * self.dot(rhs) * other_len_sq_rcp
490 }
491
492 /// Returns the vector rejection of `self` from `rhs`.
493 ///
494 /// The vector rejection is the vector perpendicular to the projection of `self` onto
495 /// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`.
496 ///
497 /// `rhs` must be of non-zero length.
498 ///
499 /// # Panics
500 ///
501 /// Will panic if `rhs` has a length of zero when `glam_assert` is enabled.
502 #[inline]
503 #[must_use]
reject_from(self, rhs: Self) -> Self504 pub fn reject_from(self, rhs: Self) -> Self {
505 self - self.project_onto(rhs)
506 }
507
508 /// Returns the vector projection of `self` onto `rhs`.
509 ///
510 /// `rhs` must be normalized.
511 ///
512 /// # Panics
513 ///
514 /// Will panic if `rhs` is not normalized when `glam_assert` is enabled.
515 #[inline]
516 #[must_use]
project_onto_normalized(self, rhs: Self) -> Self517 pub fn project_onto_normalized(self, rhs: Self) -> Self {
518 glam_assert!(rhs.is_normalized());
519 rhs * self.dot(rhs)
520 }
521
522 /// Returns the vector rejection of `self` from `rhs`.
523 ///
524 /// The vector rejection is the vector perpendicular to the projection of `self` onto
525 /// `rhs`, in rhs words the result of `self - self.project_onto(rhs)`.
526 ///
527 /// `rhs` must be normalized.
528 ///
529 /// # Panics
530 ///
531 /// Will panic if `rhs` is not normalized when `glam_assert` is enabled.
532 #[inline]
533 #[must_use]
reject_from_normalized(self, rhs: Self) -> Self534 pub fn reject_from_normalized(self, rhs: Self) -> Self {
535 self - self.project_onto_normalized(rhs)
536 }
537
538 /// Returns a vector containing the nearest integer to a number for each element of `self`.
539 /// Round half-way cases away from 0.0.
540 #[inline]
541 #[must_use]
round(self) -> Self542 pub fn round(self) -> Self {
543 Self(self.0.round())
544 }
545
546 /// Returns a vector containing the largest integer less than or equal to a number for each
547 /// element of `self`.
548 #[inline]
549 #[must_use]
floor(self) -> Self550 pub fn floor(self) -> Self {
551 Self(self.0.floor())
552 }
553
554 /// Returns a vector containing the smallest integer greater than or equal to a number for
555 /// each element of `self`.
556 #[inline]
557 #[must_use]
ceil(self) -> Self558 pub fn ceil(self) -> Self {
559 Self(self.0.ceil())
560 }
561
562 /// Returns a vector containing the integer part each element of `self`. This means numbers are
563 /// always truncated towards zero.
564 #[inline]
565 #[must_use]
trunc(self) -> Self566 pub fn trunc(self) -> Self {
567 Self(self.0.trunc())
568 }
569
570 /// Returns a vector containing the fractional part of the vector, e.g. `self -
571 /// self.floor()`.
572 ///
573 /// Note that this is fast but not precise for large numbers.
574 #[inline]
575 #[must_use]
fract(self) -> Self576 pub fn fract(self) -> Self {
577 self - self.floor()
578 }
579
580 /// Returns a vector containing `e^self` (the exponential function) for each element of
581 /// `self`.
582 #[inline]
583 #[must_use]
exp(self) -> Self584 pub fn exp(self) -> Self {
585 Self::new(
586 math::exp(self.x),
587 math::exp(self.y),
588 math::exp(self.z),
589 math::exp(self.w),
590 )
591 }
592
593 /// Returns a vector containing each element of `self` raised to the power of `n`.
594 #[inline]
595 #[must_use]
powf(self, n: f32) -> Self596 pub fn powf(self, n: f32) -> Self {
597 Self::new(
598 math::powf(self.x, n),
599 math::powf(self.y, n),
600 math::powf(self.z, n),
601 math::powf(self.w, n),
602 )
603 }
604
605 /// Returns a vector containing the reciprocal `1.0/n` of each element of `self`.
606 #[inline]
607 #[must_use]
recip(self) -> Self608 pub fn recip(self) -> Self {
609 Self(self.0.recip())
610 }
611
612 /// Performs a linear interpolation between `self` and `rhs` based on the value `s`.
613 ///
614 /// When `s` is `0.0`, the result will be equal to `self`. When `s` is `1.0`, the result
615 /// will be equal to `rhs`. When `s` is outside of range `[0, 1]`, the result is linearly
616 /// extrapolated.
617 #[doc(alias = "mix")]
618 #[inline]
619 #[must_use]
lerp(self, rhs: Self, s: f32) -> Self620 pub fn lerp(self, rhs: Self, s: f32) -> Self {
621 self + ((rhs - self) * s)
622 }
623
624 /// Returns true if the absolute difference of all elements between `self` and `rhs` is
625 /// less than or equal to `max_abs_diff`.
626 ///
627 /// This can be used to compare if two vectors contain similar elements. It works best when
628 /// comparing with a known value. The `max_abs_diff` that should be used used depends on
629 /// the values being compared against.
630 ///
631 /// For more see
632 /// [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
633 #[inline]
634 #[must_use]
abs_diff_eq(self, rhs: Self, max_abs_diff: f32) -> bool635 pub fn abs_diff_eq(self, rhs: Self, max_abs_diff: f32) -> bool {
636 self.sub(rhs).abs().cmple(Self::splat(max_abs_diff)).all()
637 }
638
639 /// Returns a vector with a length no less than `min` and no more than `max`
640 ///
641 /// # Panics
642 ///
643 /// Will panic if `min` is greater than `max` when `glam_assert` is enabled.
644 #[inline]
645 #[must_use]
clamp_length(self, min: f32, max: f32) -> Self646 pub fn clamp_length(self, min: f32, max: f32) -> Self {
647 glam_assert!(min <= max);
648 let length_sq = self.length_squared();
649 if length_sq < min * min {
650 min * (self / math::sqrt(length_sq))
651 } else if length_sq > max * max {
652 max * (self / math::sqrt(length_sq))
653 } else {
654 self
655 }
656 }
657
658 /// Returns a vector with a length no more than `max`
659 #[inline]
660 #[must_use]
clamp_length_max(self, max: f32) -> Self661 pub fn clamp_length_max(self, max: f32) -> Self {
662 let length_sq = self.length_squared();
663 if length_sq > max * max {
664 max * (self / math::sqrt(length_sq))
665 } else {
666 self
667 }
668 }
669
670 /// Returns a vector with a length no less than `min`
671 #[inline]
672 #[must_use]
clamp_length_min(self, min: f32) -> Self673 pub fn clamp_length_min(self, min: f32) -> Self {
674 let length_sq = self.length_squared();
675 if length_sq < min * min {
676 min * (self / math::sqrt(length_sq))
677 } else {
678 self
679 }
680 }
681
682 /// Fused multiply-add. Computes `(self * a) + b` element-wise with only one rounding
683 /// error, yielding a more accurate result than an unfused multiply-add.
684 ///
685 /// Using `mul_add` *may* be more performant than an unfused multiply-add if the target
686 /// architecture has a dedicated fma CPU instruction. However, this is not always true,
687 /// and will be heavily dependant on designing algorithms with specific target hardware in
688 /// mind.
689 #[inline]
690 #[must_use]
mul_add(self, a: Self, b: Self) -> Self691 pub fn mul_add(self, a: Self, b: Self) -> Self {
692 Self(self.0.mul_add(a.0, b.0))
693 }
694
695 /// Casts all elements of `self` to `f64`.
696 #[inline]
697 #[must_use]
as_dvec4(&self) -> crate::DVec4698 pub fn as_dvec4(&self) -> crate::DVec4 {
699 crate::DVec4::new(self.x as f64, self.y as f64, self.z as f64, self.w as f64)
700 }
701
702 /// Casts all elements of `self` to `i16`.
703 #[inline]
704 #[must_use]
as_i16vec4(&self) -> crate::I16Vec4705 pub fn as_i16vec4(&self) -> crate::I16Vec4 {
706 crate::I16Vec4::new(self.x as i16, self.y as i16, self.z as i16, self.w as i16)
707 }
708
709 /// Casts all elements of `self` to `u16`.
710 #[inline]
711 #[must_use]
as_u16vec4(&self) -> crate::U16Vec4712 pub fn as_u16vec4(&self) -> crate::U16Vec4 {
713 crate::U16Vec4::new(self.x as u16, self.y as u16, self.z as u16, self.w as u16)
714 }
715
716 /// Casts all elements of `self` to `i32`.
717 #[inline]
718 #[must_use]
as_ivec4(&self) -> crate::IVec4719 pub fn as_ivec4(&self) -> crate::IVec4 {
720 crate::IVec4::new(self.x as i32, self.y as i32, self.z as i32, self.w as i32)
721 }
722
723 /// Casts all elements of `self` to `u32`.
724 #[inline]
725 #[must_use]
as_uvec4(&self) -> crate::UVec4726 pub fn as_uvec4(&self) -> crate::UVec4 {
727 crate::UVec4::new(self.x as u32, self.y as u32, self.z as u32, self.w as u32)
728 }
729
730 /// Casts all elements of `self` to `i64`.
731 #[inline]
732 #[must_use]
as_i64vec4(&self) -> crate::I64Vec4733 pub fn as_i64vec4(&self) -> crate::I64Vec4 {
734 crate::I64Vec4::new(self.x as i64, self.y as i64, self.z as i64, self.w as i64)
735 }
736
737 /// Casts all elements of `self` to `u64`.
738 #[inline]
739 #[must_use]
as_u64vec4(&self) -> crate::U64Vec4740 pub fn as_u64vec4(&self) -> crate::U64Vec4 {
741 crate::U64Vec4::new(self.x as u64, self.y as u64, self.z as u64, self.w as u64)
742 }
743 }
744
745 impl Default for Vec4 {
746 #[inline(always)]
default() -> Self747 fn default() -> Self {
748 Self::ZERO
749 }
750 }
751
752 impl PartialEq for Vec4 {
753 #[inline]
eq(&self, rhs: &Self) -> bool754 fn eq(&self, rhs: &Self) -> bool {
755 self.cmpeq(*rhs).all()
756 }
757 }
758
759 impl Div<Vec4> for Vec4 {
760 type Output = Self;
761 #[inline]
div(self, rhs: Self) -> Self762 fn div(self, rhs: Self) -> Self {
763 Self(self.0 / rhs.0)
764 }
765 }
766
767 impl DivAssign<Vec4> for Vec4 {
768 #[inline]
div_assign(&mut self, rhs: Self)769 fn div_assign(&mut self, rhs: Self) {
770 self.0 /= rhs.0;
771 }
772 }
773
774 impl Div<f32> for Vec4 {
775 type Output = Self;
776 #[inline]
div(self, rhs: f32) -> Self777 fn div(self, rhs: f32) -> Self {
778 Self(self.0 / f32x4::splat(rhs))
779 }
780 }
781
782 impl DivAssign<f32> for Vec4 {
783 #[inline]
div_assign(&mut self, rhs: f32)784 fn div_assign(&mut self, rhs: f32) {
785 self.0 /= f32x4::splat(rhs);
786 }
787 }
788
789 impl Div<Vec4> for f32 {
790 type Output = Vec4;
791 #[inline]
div(self, rhs: Vec4) -> Vec4792 fn div(self, rhs: Vec4) -> Vec4 {
793 Vec4(f32x4::splat(self) / rhs.0)
794 }
795 }
796
797 impl Mul<Vec4> for Vec4 {
798 type Output = Self;
799 #[inline]
mul(self, rhs: Self) -> Self800 fn mul(self, rhs: Self) -> Self {
801 Self(self.0 * rhs.0)
802 }
803 }
804
805 impl MulAssign<Vec4> for Vec4 {
806 #[inline]
mul_assign(&mut self, rhs: Self)807 fn mul_assign(&mut self, rhs: Self) {
808 self.0 *= rhs.0;
809 }
810 }
811
812 impl Mul<f32> for Vec4 {
813 type Output = Self;
814 #[inline]
mul(self, rhs: f32) -> Self815 fn mul(self, rhs: f32) -> Self {
816 Self(self.0 * f32x4::splat(rhs))
817 }
818 }
819
820 impl MulAssign<f32> for Vec4 {
821 #[inline]
mul_assign(&mut self, rhs: f32)822 fn mul_assign(&mut self, rhs: f32) {
823 self.0 *= f32x4::splat(rhs);
824 }
825 }
826
827 impl Mul<Vec4> for f32 {
828 type Output = Vec4;
829 #[inline]
mul(self, rhs: Vec4) -> Vec4830 fn mul(self, rhs: Vec4) -> Vec4 {
831 Vec4(f32x4::splat(self) * rhs.0)
832 }
833 }
834
835 impl Add<Vec4> for Vec4 {
836 type Output = Self;
837 #[inline]
add(self, rhs: Self) -> Self838 fn add(self, rhs: Self) -> Self {
839 Self(self.0 + rhs.0)
840 }
841 }
842
843 impl AddAssign<Vec4> for Vec4 {
844 #[inline]
add_assign(&mut self, rhs: Self)845 fn add_assign(&mut self, rhs: Self) {
846 self.0 += rhs.0;
847 }
848 }
849
850 impl Add<f32> for Vec4 {
851 type Output = Self;
852 #[inline]
add(self, rhs: f32) -> Self853 fn add(self, rhs: f32) -> Self {
854 Self(self.0 + f32x4::splat(rhs))
855 }
856 }
857
858 impl AddAssign<f32> for Vec4 {
859 #[inline]
add_assign(&mut self, rhs: f32)860 fn add_assign(&mut self, rhs: f32) {
861 self.0 += f32x4::splat(rhs);
862 }
863 }
864
865 impl Add<Vec4> for f32 {
866 type Output = Vec4;
867 #[inline]
add(self, rhs: Vec4) -> Vec4868 fn add(self, rhs: Vec4) -> Vec4 {
869 Vec4(f32x4::splat(self) + rhs.0)
870 }
871 }
872
873 impl Sub<Vec4> for Vec4 {
874 type Output = Self;
875 #[inline]
sub(self, rhs: Self) -> Self876 fn sub(self, rhs: Self) -> Self {
877 Self(self.0 - rhs.0)
878 }
879 }
880
881 impl SubAssign<Vec4> for Vec4 {
882 #[inline]
sub_assign(&mut self, rhs: Vec4)883 fn sub_assign(&mut self, rhs: Vec4) {
884 self.0 -= rhs.0;
885 }
886 }
887
888 impl Sub<f32> for Vec4 {
889 type Output = Self;
890 #[inline]
sub(self, rhs: f32) -> Self891 fn sub(self, rhs: f32) -> Self {
892 Self(self.0 - f32x4::splat(rhs))
893 }
894 }
895
896 impl SubAssign<f32> for Vec4 {
897 #[inline]
sub_assign(&mut self, rhs: f32)898 fn sub_assign(&mut self, rhs: f32) {
899 self.0 -= f32x4::splat(rhs);
900 }
901 }
902
903 impl Sub<Vec4> for f32 {
904 type Output = Vec4;
905 #[inline]
sub(self, rhs: Vec4) -> Vec4906 fn sub(self, rhs: Vec4) -> Vec4 {
907 Vec4(f32x4::splat(self) - rhs.0)
908 }
909 }
910
911 impl Rem<Vec4> for Vec4 {
912 type Output = Self;
913 #[inline]
rem(self, rhs: Self) -> Self914 fn rem(self, rhs: Self) -> Self {
915 Self(self.0 % rhs.0)
916 }
917 }
918
919 impl RemAssign<Vec4> for Vec4 {
920 #[inline]
rem_assign(&mut self, rhs: Self)921 fn rem_assign(&mut self, rhs: Self) {
922 self.0 %= rhs.0;
923 }
924 }
925
926 impl Rem<f32> for Vec4 {
927 type Output = Self;
928 #[inline]
rem(self, rhs: f32) -> Self929 fn rem(self, rhs: f32) -> Self {
930 self.rem(Self::splat(rhs))
931 }
932 }
933
934 impl RemAssign<f32> for Vec4 {
935 #[inline]
rem_assign(&mut self, rhs: f32)936 fn rem_assign(&mut self, rhs: f32) {
937 self.0 %= f32x4::splat(rhs);
938 }
939 }
940
941 impl Rem<Vec4> for f32 {
942 type Output = Vec4;
943 #[inline]
rem(self, rhs: Vec4) -> Vec4944 fn rem(self, rhs: Vec4) -> Vec4 {
945 Vec4::splat(self).rem(rhs)
946 }
947 }
948
949 #[cfg(not(target_arch = "spirv"))]
950 impl AsRef<[f32; 4]> for Vec4 {
951 #[inline]
as_ref(&self) -> &[f32; 4]952 fn as_ref(&self) -> &[f32; 4] {
953 unsafe { &*(self as *const Vec4 as *const [f32; 4]) }
954 }
955 }
956
957 #[cfg(not(target_arch = "spirv"))]
958 impl AsMut<[f32; 4]> for Vec4 {
959 #[inline]
as_mut(&mut self) -> &mut [f32; 4]960 fn as_mut(&mut self) -> &mut [f32; 4] {
961 unsafe { &mut *(self as *mut Vec4 as *mut [f32; 4]) }
962 }
963 }
964
965 impl Sum for Vec4 {
966 #[inline]
sum<I>(iter: I) -> Self where I: Iterator<Item = Self>,967 fn sum<I>(iter: I) -> Self
968 where
969 I: Iterator<Item = Self>,
970 {
971 iter.fold(Self::ZERO, Self::add)
972 }
973 }
974
975 impl<'a> Sum<&'a Self> for Vec4 {
976 #[inline]
sum<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,977 fn sum<I>(iter: I) -> Self
978 where
979 I: Iterator<Item = &'a Self>,
980 {
981 iter.fold(Self::ZERO, |a, &b| Self::add(a, b))
982 }
983 }
984
985 impl Product for Vec4 {
986 #[inline]
product<I>(iter: I) -> Self where I: Iterator<Item = Self>,987 fn product<I>(iter: I) -> Self
988 where
989 I: Iterator<Item = Self>,
990 {
991 iter.fold(Self::ONE, Self::mul)
992 }
993 }
994
995 impl<'a> Product<&'a Self> for Vec4 {
996 #[inline]
product<I>(iter: I) -> Self where I: Iterator<Item = &'a Self>,997 fn product<I>(iter: I) -> Self
998 where
999 I: Iterator<Item = &'a Self>,
1000 {
1001 iter.fold(Self::ONE, |a, &b| Self::mul(a, b))
1002 }
1003 }
1004
1005 impl Neg for Vec4 {
1006 type Output = Self;
1007 #[inline]
neg(self) -> Self1008 fn neg(self) -> Self {
1009 Self(-self.0)
1010 }
1011 }
1012
1013 impl Index<usize> for Vec4 {
1014 type Output = f32;
1015 #[inline]
index(&self, index: usize) -> &Self::Output1016 fn index(&self, index: usize) -> &Self::Output {
1017 &self.0[index]
1018 }
1019 }
1020
1021 impl IndexMut<usize> for Vec4 {
1022 #[inline]
index_mut(&mut self, index: usize) -> &mut Self::Output1023 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1024 &mut self.0[index]
1025 }
1026 }
1027
1028 #[cfg(not(target_arch = "spirv"))]
1029 impl fmt::Display for Vec4 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1030 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1031 write!(f, "[{}, {}, {}, {}]", self.x, self.y, self.z, self.w)
1032 }
1033 }
1034
1035 #[cfg(not(target_arch = "spirv"))]
1036 impl fmt::Debug for Vec4 {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result1037 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1038 fmt.debug_tuple(stringify!(Vec4))
1039 .field(&self.x)
1040 .field(&self.y)
1041 .field(&self.z)
1042 .field(&self.w)
1043 .finish()
1044 }
1045 }
1046
1047 impl From<Vec4> for f32x4 {
1048 #[inline]
from(t: Vec4) -> Self1049 fn from(t: Vec4) -> Self {
1050 t.0
1051 }
1052 }
1053
1054 impl From<f32x4> for Vec4 {
1055 #[inline]
from(t: f32x4) -> Self1056 fn from(t: f32x4) -> Self {
1057 Self(t)
1058 }
1059 }
1060
1061 impl From<[f32; 4]> for Vec4 {
1062 #[inline]
from(a: [f32; 4]) -> Self1063 fn from(a: [f32; 4]) -> Self {
1064 Self(f32x4::from_array(a))
1065 }
1066 }
1067
1068 impl From<Vec4> for [f32; 4] {
1069 #[inline]
from(v: Vec4) -> Self1070 fn from(v: Vec4) -> Self {
1071 v.0.to_array()
1072 }
1073 }
1074
1075 impl From<(f32, f32, f32, f32)> for Vec4 {
1076 #[inline]
from(t: (f32, f32, f32, f32)) -> Self1077 fn from(t: (f32, f32, f32, f32)) -> Self {
1078 Self::new(t.0, t.1, t.2, t.3)
1079 }
1080 }
1081
1082 impl From<Vec4> for (f32, f32, f32, f32) {
1083 #[inline]
from(v: Vec4) -> Self1084 fn from(v: Vec4) -> Self {
1085 unsafe { *(v.0.to_array().as_ptr() as *const Self) }
1086 }
1087 }
1088
1089 impl From<(Vec3A, f32)> for Vec4 {
1090 #[inline]
from((v, w): (Vec3A, f32)) -> Self1091 fn from((v, w): (Vec3A, f32)) -> Self {
1092 v.extend(w)
1093 }
1094 }
1095
1096 impl From<(f32, Vec3A)> for Vec4 {
1097 #[inline]
from((x, v): (f32, Vec3A)) -> Self1098 fn from((x, v): (f32, Vec3A)) -> Self {
1099 Self::new(x, v.x, v.y, v.z)
1100 }
1101 }
1102
1103 impl From<(Vec3, f32)> for Vec4 {
1104 #[inline]
from((v, w): (Vec3, f32)) -> Self1105 fn from((v, w): (Vec3, f32)) -> Self {
1106 Self::new(v.x, v.y, v.z, w)
1107 }
1108 }
1109
1110 impl From<(f32, Vec3)> for Vec4 {
1111 #[inline]
from((x, v): (f32, Vec3)) -> Self1112 fn from((x, v): (f32, Vec3)) -> Self {
1113 Self::new(x, v.x, v.y, v.z)
1114 }
1115 }
1116
1117 impl From<(Vec2, f32, f32)> for Vec4 {
1118 #[inline]
from((v, z, w): (Vec2, f32, f32)) -> Self1119 fn from((v, z, w): (Vec2, f32, f32)) -> Self {
1120 Self::new(v.x, v.y, z, w)
1121 }
1122 }
1123
1124 impl From<(Vec2, Vec2)> for Vec4 {
1125 #[inline]
from((v, u): (Vec2, Vec2)) -> Self1126 fn from((v, u): (Vec2, Vec2)) -> Self {
1127 Self::new(v.x, v.y, u.x, u.y)
1128 }
1129 }
1130
1131 impl Deref for Vec4 {
1132 type Target = crate::deref::Vec4<f32>;
1133 #[inline]
deref(&self) -> &Self::Target1134 fn deref(&self) -> &Self::Target {
1135 unsafe { &*(self as *const Self).cast() }
1136 }
1137 }
1138
1139 impl DerefMut for Vec4 {
1140 #[inline]
deref_mut(&mut self) -> &mut Self::Target1141 fn deref_mut(&mut self) -> &mut Self::Target {
1142 unsafe { &mut *(self as *mut Self).cast() }
1143 }
1144 }
1145