1use core::{cmp, ops};
2use num_traits::ConstZero;
3
4#[cfg(not(feature = "std"))]
8#[cfg_attr(test, allow(unused_imports))]
9use num_traits::float::Float as _;
10
11#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd)]
29#[repr(transparent)]
30pub struct Scalar<T>(pub T);
31
32#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
33#[repr(C)]
34pub struct Vec2<T> {
35 pub x: T,
36 pub y: T,
37}
38
39#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
40#[repr(C)]
41pub struct Vec3<T> {
42 pub x: T,
43 pub y: T,
44 pub z: T,
45}
46
47#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
48#[repr(C)]
49pub struct Vec4<T> {
50 pub x: T,
51 pub y: T,
52 pub z: T,
53 pub w: T,
54}
55
56macro_rules! delegate_unary_method_elementwise {
60 (const $name:ident ($($component:tt)*)) => {
61 #[inline]
62 pub const fn $name(self) -> Self {
63 Self { $( $component: self.$component.$name() ),* }
64 }
65 };
66 ($name:ident ($($component:tt)*)) => {
67 #[inline]
68 pub fn $name(self) -> Self {
69 Self { $( $component: self.$component.$name() ),* }
70 }
71 };
72}
73
74macro_rules! delegate_unary_methods_elementwise {
75 (const { $($name:ident),* } $components:tt) => {
76 $( delegate_unary_method_elementwise!(const $name $components ); )*
77 };
78 ({ $($name:ident),* } $components:tt) => {
79 $( delegate_unary_method_elementwise!($name $components ); )*
80 };
81}
82
83macro_rules! delegate_binary_method_elementwise {
84 (const $name:ident ($($component:tt)*)) => {
85 #[inline]
86 pub const fn $name(self, rhs: Self) -> Self {
87 Self { $( $component: self.$component.$name(rhs.$component) ),* }
88 }
89 };
90 ($name:ident ($($component:tt)*)) => {
91 #[inline]
92 pub fn $name(self, rhs: Self) -> Self {
93 Self { $( $component: self.$component.$name(rhs.$component) ),* }
94 }
95 };
96}
97
98macro_rules! delegate_binary_methods_elementwise {
99 (const { $($name:ident),* } $components:tt) => {
100 $( delegate_binary_method_elementwise!(const $name $components ); )*
101 };
102 ({ $($name:ident),* } $components:tt) => {
103 $( delegate_binary_method_elementwise!($name $components ); )*
104 };
105}
106
107macro_rules! impl_vector_integer_arithmetic {
113 ($vec:ident, $int:ty, $( $component:tt )*) => {
114 impl ops::Add for $vec<$int> {
115 type Output = Self;
116 #[inline]
118 fn add(self, rhs: Self) -> Self::Output {
119 $vec { $( $component: self.$component.wrapping_add(rhs.$component), )* }
120 }
121 }
122 impl ops::Sub for $vec<$int> {
123 type Output = Self;
124 #[inline]
126 fn sub(self, rhs: Self) -> Self::Output {
127 $vec { $( $component: self.$component.wrapping_sub(rhs.$component), )* }
128 }
129 }
130 impl ops::Mul for $vec<$int> {
131 type Output = Self;
132 #[inline]
134 fn mul(self, rhs: Self) -> Self::Output {
135 $vec { $( $component: self.$component.wrapping_mul(rhs.$component), )* }
136 }
137 }
138 impl ops::Div for $vec<$int> {
139 type Output = Self;
140 #[inline]
143 fn div(self, rhs: Self) -> Self::Output {
144 $vec { $(
146 $component:
147 self.$component.checked_div(rhs.$component)
148 .unwrap_or(self.$component),
149 )* }
150 }
151 }
152 impl ops::Rem for $vec<$int> {
153 type Output = Self;
154 #[inline]
155 fn rem(self, rhs: Self) -> Self::Output {
156 $vec { $( $component: self.$component.wrapping_rem(rhs.$component), )* }
157 }
158 }
159
160 impl ops::Add<$int> for $vec<$int> {
162 type Output = Self;
163 #[inline]
165 fn add(self, rhs: $int) -> Self::Output {
166 $vec { $( $component: self.$component.wrapping_add(rhs), )* }
167 }
168 }
169 impl ops::Sub<$int> for $vec<$int> {
170 type Output = Self;
171 #[inline]
173 fn sub(self, rhs: $int) -> Self::Output {
174 $vec { $( $component: self.$component.wrapping_sub(rhs), )* }
175 }
176 }
177 impl ops::Mul<$int> for $vec<$int> {
178 type Output = Self;
179 #[inline]
181 fn mul(self, rhs: $int) -> Self::Output {
182 $vec { $( $component: self.$component.wrapping_mul(rhs), )* }
183 }
184 }
185 impl ops::Div<$int> for $vec<$int> {
186 type Output = Self;
187 #[inline]
188 fn div(self, rhs: $int) -> Self::Output {
191 $vec { $(
193 $component:
194 self.$component.checked_div(rhs)
195 .unwrap_or(self.$component),
196 )* }
197 }
198 }
199 impl ops::Rem<$int> for $vec<$int> {
200 type Output = Self;
201 #[inline]
202 fn rem(self, rhs: $int) -> Self::Output {
203 $vec { $( $component: self.$component.wrapping_rem(rhs), )* }
204 }
205 }
206
207 impl $vec<$int> {
208 delegate_binary_methods_elementwise!({
209 max, min
210 } ($($component)*));
211 }
212 }
213}
214
215macro_rules! impl_vector_float_arithmetic {
218 ($vec:ident, $float:ty, $( $component:tt )*) => {
219 impl ops::Add for $vec<$float> {
221 type Output = Self;
222 #[inline]
223 fn add(self, rhs: Self) -> Self::Output {
224 $vec { $( $component: self.$component + rhs.$component, )* }
225 }
226 }
227 impl ops::Sub for $vec<$float> {
228 type Output = Self;
229 #[inline]
230 fn sub(self, rhs: Self) -> Self::Output {
231 $vec { $( $component: self.$component - rhs.$component, )* }
232 }
233 }
234 impl ops::Mul for $vec<$float> {
235 type Output = Self;
236 #[inline]
237 fn mul(self, rhs: Self) -> Self::Output {
238 $vec { $( $component: self.$component * rhs.$component, )* }
239 }
240 }
241 impl ops::Div for $vec<$float> {
242 type Output = Self;
243 #[inline]
244 fn div(self, rhs: Self) -> Self::Output {
245 $vec { $( $component: self.$component / rhs.$component, )* }
246 }
247 }
248 impl ops::Rem for $vec<$float> {
249 type Output = Self;
250 #[inline]
251 fn rem(self, rhs: Self) -> Self::Output {
252 $vec { $( $component: self.$component % rhs.$component, )* }
253 }
254 }
255
256 impl ops::Add<$float> for $vec<$float> {
258 type Output = Self;
259 #[inline]
260 fn add(self, rhs: $float) -> Self::Output {
261 $vec { $( $component: self.$component + rhs, )* }
262 }
263 }
264 impl ops::Sub<$float> for $vec<$float> {
265 type Output = Self;
266 #[inline]
267 fn sub(self, rhs: $float) -> Self::Output {
268 $vec { $( $component: self.$component - rhs, )* }
269 }
270 }
271 impl ops::Mul<$float> for $vec<$float> {
272 type Output = Self;
273 #[inline]
274 fn mul(self, rhs: $float) -> Self::Output {
275 $vec { $( $component: self.$component * rhs, )* }
276 }
277 }
278 impl ops::Div<$float> for $vec<$float> {
279 type Output = Self;
280 #[inline]
281 fn div(self, rhs: $float) -> Self::Output {
282 $vec { $( $component: self.$component / rhs, )* }
283 }
284 }
285 impl ops::Rem<$float> for $vec<$float> {
286 type Output = Self;
287 #[inline]
288 fn rem(self, rhs: $float) -> Self::Output {
289 $vec { $( $component: self.$component % rhs, )* }
290 }
291 }
292
293 impl $vec<$float> {
295 #[inline]
297 pub const fn clamp(self, low: Self, high: Self) -> Self {
298 $vec { $( $component: self.$component.clamp(low.$component, high.$component) ),* }
301 }
302 #[inline]
304 pub fn distance(self, rhs: Self) -> $float {
305 (self - rhs).length()
306 }
307 #[inline]
309 pub const fn dot(self, rhs: Self) -> $float {
310 $( self.$component * rhs.$component + )* 0.0
311 }
312 #[inline]
314 pub fn face_forward(self, e2: Self, e3: Self) -> Self {
315 self * -e2.dot(e3).signum()
317 }
318 #[inline]
320 pub fn length(self) -> $float {
321 self.dot(self).sqrt()
322 }
323 #[inline]
325 pub const fn mix(self, rhs: Self, blend: $float) -> Self {
326 $vec { $( $component: self.$component * (1.0 - blend) + rhs.$component * blend ),* }
327 }
328 #[inline]
330 pub fn mul_add(self, b: Self, c: Self) -> Self {
331 $vec { $( $component: self.$component.mul_add(b.$component, c.$component) ),* }
332 }
333 #[inline]
335 pub fn normalize(self) -> Self {
336 self * self.length().recip()
337 }
338 #[inline]
340 pub fn reflect(self, rhs: Self) -> Self {
341 self - rhs * (2.0 * rhs.dot(self))
342 }
343 #[inline]
345 pub const fn saturate(self) -> Self {
346 $vec { $( $component: self.$component.clamp(0.0, 1.0) ),* }
347 }
348 #[inline]
350 pub const fn sign(self) -> Self {
351 $vec { $(
352 $component: if self.$component == 0.0 {
354 0.0
355 } else {
356 self.$component.signum()
357 }
358 ),* }
359 }
360
361 delegate_unary_methods_elementwise!(const {
363 abs
364 } ($($component)*));
365 delegate_unary_methods_elementwise!({
366 acos, acosh, asin, asinh, atan, atanh, ceil, cos, cosh, exp, exp2, floor, fract, log2, round,
367 sin, sinh, tan, tanh, trunc, to_degrees, to_radians
368 } ($($component)*));
369 delegate_binary_methods_elementwise!({
370 atan2, max, min, powf
371 } ($($component)*));
372
373 }
376 }
377}
378
379macro_rules! impl_vector_bitwise {
380 ($vec:ident, $int:ty, $( $component:tt )*) => {
381 impl ops::BitAnd for $vec<$int> {
382 type Output = Self;
383 fn bitand(self, rhs: Self) -> Self::Output {
384 $vec { $( $component: self.$component & rhs.$component, )* }
385 }
386 }
387 impl ops::BitOr for $vec<$int> {
388 type Output = Self;
389 fn bitor(self, rhs: Self) -> Self::Output {
390 $vec { $( $component: self.$component | rhs.$component, )* }
391 }
392 }
393 impl ops::BitXor for $vec<$int> {
394 type Output = Self;
395 fn bitxor(self, rhs: Self) -> Self::Output {
396 $vec { $( $component: self.$component ^ rhs.$component, )* }
397 }
398 }
399 impl ops::Not for $vec<$int> {
400 type Output = Self;
401 fn not(self) -> Self::Output {
402 $vec { $( $component: !self.$component, )* }
403 }
404 }
405
406 }
407}
408
409macro_rules! impl_element_casts {
410 ($ty:ident) => {
411 pub fn cast_elem_as_u32(self) -> $ty<u32> {
414 self.map(|component| component as u32)
415 }
416 pub fn cast_elem_as_i32(self) -> $ty<i32> {
417 self.map(|component| component as i32)
418 }
419 pub fn cast_elem_as_f32(self) -> $ty<f32> {
420 self.map(|component| component as f32)
421 }
422 pub fn cast_elem_as_f64(self) -> $ty<f64> {
423 self.map(|component| component as f64)
424 }
425 };
426}
427
428macro_rules! impl_vector_regular_fns {
429 ( $ty:ident $component_count:literal : $( $component:tt )* ) => {
430 impl<T> $ty<T> {
431 pub fn splat(value: T) -> Self
432 where
433 T: Copy
434 {
435 Self { $( $component: value, )* }
436 }
437 pub fn splat_from_scalar(value: Scalar<T>) -> Self
438 where
439 T: Copy
440 {
441 Self { $( $component: value.0, )* }
442 }
443
444 pub const fn select(self, trues: Self, mask: $ty<bool>) -> Self
447 where
448 T: Copy
449 {
450 Self {
451 $(
452 $component: if mask.$component {
453 trues.$component
454 } else {
455 self.$component
456 },
457 )*
458 }
459 }
460
461 pub fn map<U, F>(self, mut f: F) -> $ty<U>
462 where
463 F: FnMut(T) -> U,
464 {
465 $ty {
466 $(
467 $component: f(self.$component),
468 )*
469 }
470 }
471 }
472
473 impl_vector_integer_arithmetic!($ty, i32, $($component)*);
474 impl_vector_integer_arithmetic!($ty, u32, $($component)*);
475 impl_vector_float_arithmetic!($ty, f32, $($component)*);
476 impl_vector_float_arithmetic!($ty, f64, $($component)*);
477
478 impl_vector_bitwise!($ty, bool, $($component)*);
479 impl_vector_bitwise!($ty, i32, $($component)*);
480 impl_vector_bitwise!($ty, u32, $($component)*);
481
482 impl $ty<i32> {
483 impl_element_casts!($ty);
484 }
485 impl $ty<u32> {
486 impl_element_casts!($ty);
487 }
488 impl $ty<f32> {
489 impl_element_casts!($ty);
490 }
491 impl $ty<f64> {
492 impl_element_casts!($ty);
493 }
494
495 impl<T: ConstZero> $ty<T> {
497 pub const ZERO: Self = Self { $( $component: T::ZERO, )* };
499 }
500 impl<T: ConstZero> ConstZero for $ty<T>
501 where
502 Self: ops::Add<Output = Self>
503 {
504 const ZERO: Self = Self { $( $component: T::ZERO, )* };
505 }
506 impl<T: ConstZero> num_traits::Zero for $ty<T>
507 where
508 Self: ops::Add<Output = Self>
509 {
510 fn zero() -> Self {
511 Self::ZERO
512 }
513 fn is_zero(&self) -> bool {
514 $(T::is_zero(&self.$component) & )* true
515 }
516 }
517
518 impl<T: PartialOrd> $ty<T> {
520 pub fn elementwise_eq(self, rhs: Self) -> $ty<bool> {
521 self.partial_cmp(rhs).map(|cmp| matches!(cmp, Some(cmp::Ordering::Equal)))
522 }
523 pub fn elementwise_ne(self, rhs: Self) -> $ty<bool> {
524 self.partial_cmp(rhs).map(|cmp| !matches!(cmp, Some(cmp::Ordering::Equal)))
525 }
526 pub fn elementwise_lt(self, rhs: Self) -> $ty<bool> {
527 self.partial_cmp(rhs).map(|cmp| matches!(cmp, Some(cmp::Ordering::Less)))
528 }
529 pub fn elementwise_le(self, rhs: Self) -> $ty<bool> {
530 self.partial_cmp(rhs).map(|cmp| {
531 matches!(cmp, Some(cmp::Ordering::Less | cmp::Ordering::Equal))
532 })
533 }
534 pub fn elementwise_gt(self, rhs: Self) -> $ty<bool> {
535 self.partial_cmp(rhs).map(|cmp| matches!(cmp, Some(cmp::Ordering::Greater)))
536 }
537 pub fn elementwise_ge(self, rhs: Self) -> $ty<bool> {
538 self.partial_cmp(rhs).map(|cmp| {
539 matches!(cmp, Some(cmp::Ordering::Greater | cmp::Ordering::Equal))
540 })
541 }
542
543 fn partial_cmp(self, rhs: Self) -> $ty<Option<cmp::Ordering>> {
545 $ty {
546 $(
547 $component: self.$component.partial_cmp(&rhs.$component),
548 )*
549 }
550 }
551 }
552
553 impl<T> From<$ty<T>> for [T; $component_count] {
555 fn from(value: $ty<T>) -> Self {
556 [$( value.$component ),*]
557 }
558 }
559
560 impl $ty<i32> {
563 delegate_unary_methods_elementwise!(const { abs } ($($component)*));
564 }
565 impl $ty<u32> {
566 pub fn abs(self) -> Self { self }
567 }
568 }
569}
570
571impl_vector_regular_fns!(Scalar 1 : 0);
572impl_vector_regular_fns!(Vec2 2 : x y);
573impl_vector_regular_fns!(Vec3 3 : x y z);
574impl_vector_regular_fns!(Vec4 4 : x y z w);
575
576macro_rules! impl_vector_not_scalar_fns {
581 ( $ty:ident $component_count:literal : $( $component:tt )* ) => {
582 impl<T> $ty<T> {
583 pub const fn new($( $component: T, )*) -> Self {
585 Self { $( $component, )* }
586 }
587
588 pub const fn from_scalars($( $component: Scalar<T>, )*) -> Self
589 where
590 T: Copy
591 {
592 Self { $( $component: $component.0, )* }
593 }
594 }
595
596 impl<T> From<[T; $component_count]> for $ty<T> {
597 fn from(value: [T; $component_count]) -> Self {
598 let [$( $component ),*] = value;
599 Self::new($( $component ),*)
600 }
601 }
602
603 impl<T> ops::Add<$ty<T>> for Scalar<T>
605 where
606 $ty<T>: ops::Add<Scalar<T>>
607 {
608 type Output = <$ty<T> as ops::Add<Scalar<T>>>::Output;
609 fn add(self, rhs: $ty<T>) -> Self::Output {
610 rhs + self
611 }
612 }
613 impl<T> ops::Mul<$ty<T>> for Scalar<T>
614 where
615 $ty<T>: ops::Mul<Scalar<T>>
616 {
617 type Output = <$ty<T> as ops::Mul<Scalar<T>>>::Output;
618 fn mul(self, rhs: $ty<T>) -> Self::Output {
619 rhs * self
620 }
621 }
622
623 }
624}
625
626impl_vector_not_scalar_fns!(Vec2 2 : x y);
627impl_vector_not_scalar_fns!(Vec3 3 : x y z);
628impl_vector_not_scalar_fns!(Vec4 4 : x y z w);
629
630impl<T> Scalar<T> {
631 pub fn new(value: T) -> Self {
632 Self(value)
633 }
634}
635impl<T> From<[T; 1]> for Scalar<T> {
636 fn from([value]: [T; 1]) -> Self {
637 Self(value)
638 }
639}
640
641impl<T> From<T> for Scalar<T> {
645 fn from(value: T) -> Self {
646 Self(value)
647 }
648}
649
650impl<T: Default> Default for Scalar<T> {
651 fn default() -> Self {
652 Self(Default::default())
653 }
654}
655
656macro_rules! impl_flattening_ctor {
659 (fn $fn_name:ident ( $($param:tt)* ) => ( $($arg:tt)* )) => {
660 pub const fn $fn_name ($($param)*) -> Self {
661 Self::new($($arg)*)
662 }
663 }
664}
665impl<T: Copy> Vec3<T> {
667 impl_flattening_ctor!(fn new_12(x: T, yz: Vec2<T>) => (x, yz.x, yz.y));
668 impl_flattening_ctor!(fn new_21(xy: Vec2<T>, z: T) => (xy.x, xy.y, z));
669}
670impl<T: Copy> Vec4<T> {
671 impl_flattening_ctor!(fn new_112(x: T, y: T, zw: Vec2<T>) => (x, y, zw.x, zw.y));
672 impl_flattening_ctor!(fn new_121(x: T, yz: Vec2<T>, w: T) => (x, yz.x, yz.y, w));
673 impl_flattening_ctor!(fn new_211(xy: Vec2<T>, z: T, w: T) => (xy.x, xy.y, z, w));
674 impl_flattening_ctor!(fn new_22(xy: Vec2<T>, zw: Vec2<T>) => (xy.x, xy.y, zw.x, zw.y));
675 impl_flattening_ctor!(fn new_13(x: T, yzw: Vec3<T>) => (x, yzw.x, yzw.y, yzw.z));
676 impl_flattening_ctor!(fn new_31(xyz: Vec3<T>, w: T) => (xyz.x, xyz.y, xyz.z, w));
677}
678
679macro_rules! swizzle_fn {
683 ($name:ident $output:ident ($($cin:ident)*) ) => {
684 #[doc = stringify!($($cin),*)]
686 pub fn $name(self) -> $output<T> {
688 $output::new($(self.$cin,)*)
689 }
690 }
691}
692
693impl<T: Copy> Vec2<T> {
694 swizzle_fn!(xy Vec2(x y));
695 swizzle_fn!(yx Vec2(y x));
696}
697impl<T: Copy> Vec3<T> {
698 swizzle_fn!(xy Vec2(x y));
699 swizzle_fn!(yx Vec2(y x));
700 swizzle_fn!(xyz Vec3(x y z));
701 swizzle_fn!(xzy Vec3(x z y));
702 swizzle_fn!(yxz Vec3(y x z));
703 swizzle_fn!(yzx Vec3(y z x));
704 swizzle_fn!(zxy Vec3(z x y));
705 swizzle_fn!(zyx Vec3(z y x));
706}
707impl<T: Copy> Vec4<T> {
708 swizzle_fn!(xy Vec2(x y));
709 swizzle_fn!(yx Vec2(y x));
710 swizzle_fn!(xyz Vec3(x y z));
711 swizzle_fn!(xzy Vec3(x z y));
712 swizzle_fn!(yxz Vec3(y x z));
713 swizzle_fn!(yzx Vec3(y z x));
714 swizzle_fn!(zxy Vec3(z x y));
715 swizzle_fn!(zyx Vec3(z y x));
716 swizzle_fn!(xyzw Vec4(x y z w));
717 swizzle_fn!(xywz Vec4(x y w z));
718 swizzle_fn!(xzwy Vec4(x z w y));
719 swizzle_fn!(xzyw Vec4(x z y w));
720 swizzle_fn!(xwyz Vec4(x w y z));
721 swizzle_fn!(xwzy Vec4(x w z y));
722 swizzle_fn!(yxzw Vec4(y x z w));
723 swizzle_fn!(yxwz Vec4(y x w z));
724 swizzle_fn!(yzxw Vec4(y z x w));
725 swizzle_fn!(yzwx Vec4(y z w x));
726 swizzle_fn!(ywzx Vec4(y w z x));
727 swizzle_fn!(ywxz Vec4(y w x z));
728 swizzle_fn!(zxyw Vec4(z x y w));
729 swizzle_fn!(zxwy Vec4(z x w y));
730 swizzle_fn!(zyxw Vec4(z y x w));
731 swizzle_fn!(zywx Vec4(z y w x));
732 swizzle_fn!(zwxy Vec4(z w x y));
733 swizzle_fn!(zwyx Vec4(z w y x));
734 swizzle_fn!(wxyz Vec4(w x y z));
735 swizzle_fn!(wxzy Vec4(w x z y));
736 swizzle_fn!(wyxz Vec4(w y x z));
737 swizzle_fn!(wyzx Vec4(w y z x));
738 swizzle_fn!(wzxy Vec4(w z x y));
739 swizzle_fn!(wzyx Vec4(w z y x));
740}