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