1use core::{cmp, fmt, 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)]
27#[repr(transparent)]
28pub struct Scalar<T>(pub T);
29
30#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
31#[repr(C)]
32pub struct Vec2<T> {
33 pub x: T,
34 pub y: T,
35}
36
37#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
38#[repr(C)]
39pub struct Vec3<T> {
40 pub x: T,
41 pub y: T,
42 pub z: T,
43}
44
45#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
46#[repr(C)]
47pub struct Vec4<T> {
48 pub x: T,
49 pub y: T,
50 pub z: T,
51 pub w: T,
52}
53
54macro_rules! delegate_unary_method_elementwise {
58 (const $name:ident ($($component:tt)*)) => {
59 #[inline]
60 pub const fn $name(self) -> Self {
61 Self { $( $component: self.$component.$name() ),* }
62 }
63 };
64 ($name:ident ($($component:tt)*)) => {
65 #[inline]
66 pub fn $name(self) -> Self {
67 Self { $( $component: self.$component.$name() ),* }
68 }
69 };
70}
71
72macro_rules! delegate_unary_methods_elementwise {
73 (const { $($name:ident),* } $components:tt) => {
74 $( delegate_unary_method_elementwise!(const $name $components ); )*
75 };
76 ({ $($name:ident),* } $components:tt) => {
77 $( delegate_unary_method_elementwise!($name $components ); )*
78 };
79}
80
81macro_rules! delegate_binary_method_elementwise {
82 (const $name:ident ($($component:tt)*)) => {
83 #[inline]
84 pub const fn $name(self, rhs: Self) -> Self {
85 Self { $( $component: self.$component.$name(rhs.$component) ),* }
86 }
87 };
88 ($name:ident ($($component:tt)*)) => {
89 #[inline]
90 pub fn $name(self, rhs: Self) -> Self {
91 Self { $( $component: self.$component.$name(rhs.$component) ),* }
92 }
93 };
94}
95
96macro_rules! delegate_binary_methods_elementwise {
97 (const { $($name:ident),* } $components:tt) => {
98 $( delegate_binary_method_elementwise!(const $name $components ); )*
99 };
100 ({ $($name:ident),* } $components:tt) => {
101 $( delegate_binary_method_elementwise!($name $components ); )*
102 };
103}
104
105macro_rules! impl_vector_integer_arithmetic {
114 ($vec:ident, $int:ty, $( $component:tt )*) => {
115 impl ops::Add for $vec<$int> {
116 type Output = Self;
117 #[inline]
119 fn add(self, rhs: Self) -> Self::Output {
120 $vec { $( $component: self.$component.wrapping_add(rhs.$component), )* }
121 }
122 }
123 impl ops::Sub for $vec<$int> {
124 type Output = Self;
125 #[inline]
127 fn sub(self, rhs: Self) -> Self::Output {
128 $vec { $( $component: self.$component.wrapping_sub(rhs.$component), )* }
129 }
130 }
131 impl ops::Neg for $vec<$int> {
132 type Output = Self;
133 #[inline]
134 fn neg(self) -> Self::Output {
135 $vec { $( $component: self.$component.wrapping_neg(), )* }
136 }
137 }
138 impl ops::Mul for $vec<$int> {
139 type Output = Self;
140 #[inline]
142 fn mul(self, rhs: Self) -> Self::Output {
143 $vec { $( $component: self.$component.wrapping_mul(rhs.$component), )* }
144 }
145 }
146 impl ops::Div for $vec<$int> {
147 type Output = Self;
148 #[inline]
151 fn div(self, rhs: Self) -> Self::Output {
152 $vec { $(
154 $component:
155 self.$component.checked_div(rhs.$component)
156 .unwrap_or(self.$component),
157 )* }
158 }
159 }
160 impl ops::Rem for $vec<$int> {
161 type Output = Self;
162 #[inline]
163 fn rem(self, rhs: Self) -> Self::Output {
164 $vec { $( $component: self.$component.wrapping_rem(rhs.$component), )* }
165 }
166 }
167
168 impl $vec<$int> {
169 #[inline]
171 pub fn clamp(self, low: Self, high: Self) -> Self {
172 $vec { $( $component: self.$component.max(low.$component).min(high.$component) ),* }
174 }
175
176 delegate_binary_methods_elementwise!({
177 max, min
178 } ($($component)*));
179 }
180 }
181}
182
183macro_rules! impl_vector_scalar_integer_arithmetic {
186 ($vec:ident, $int:ty, $( $component:tt )*) => {
187 impl ops::Add<Scalar<$int>> for $vec<$int> {
188 type Output = Self;
189 #[inline]
191 fn add(self, Scalar(rhs): Scalar<$int>) -> Self::Output {
192 $vec { $( $component: self.$component.wrapping_add(rhs), )* }
193 }
194 }
195 impl ops::Sub<Scalar<$int>> for $vec<$int> {
196 type Output = Self;
197 #[inline]
199 fn sub(self, Scalar(rhs): Scalar<$int>) -> Self::Output {
200 $vec { $( $component: self.$component.wrapping_sub(rhs), )* }
201 }
202 }
203 impl ops::Sub<$vec<$int>> for Scalar<$int> {
205 type Output = $vec<$int>;
206 #[inline]
207 fn sub(self, rhs: $vec<$int>) -> Self::Output {
208 $vec { $( $component: self.0.wrapping_sub(rhs.$component), )* }
209 }
210 }
211 impl ops::Mul<Scalar<$int>> for $vec<$int> {
212 type Output = Self;
213 #[inline]
215 fn mul(self, Scalar(rhs): Scalar<$int>) -> Self::Output {
216 $vec { $( $component: self.$component.wrapping_mul(rhs), )* }
217 }
218 }
219 impl ops::Div<Scalar<$int>> for $vec<$int> {
220 type Output = Self;
221 #[inline]
222 fn div(self, Scalar(rhs): Scalar<$int>) -> Self::Output {
225 $vec { $(
227 $component:
228 self.$component.checked_div(rhs)
229 .unwrap_or(self.$component),
230 )* }
231 }
232 }
233 impl ops::Div<$vec<$int>> for Scalar<$int> {
234 type Output = $vec<$int>;
235 #[inline]
236 fn div(self, rhs: $vec<$int>) -> Self::Output {
237 $vec { $(
239 $component:
240 self.0.checked_div(rhs.$component)
241 .unwrap_or(self.0),
242 )* }
243 }
244 }
245 impl ops::Rem<Scalar<$int>> for $vec<$int> {
246 type Output = Self;
247 #[inline]
248 fn rem(self, Scalar(rhs): Scalar<$int>) -> Self::Output {
249 $vec { $( $component: self.$component.wrapping_rem(rhs), )* }
250 }
251 }
252 }
253}
254
255macro_rules! impl_vector_float_arithmetic {
258 ($vec:ident, $float:ty, $( $component:tt )*) => {
259 impl ops::Add for $vec<$float> {
261 type Output = Self;
262 #[inline]
263 fn add(self, rhs: Self) -> Self::Output {
264 $vec { $( $component: self.$component + rhs.$component, )* }
265 }
266 }
267 impl ops::Sub for $vec<$float> {
268 type Output = Self;
269 #[inline]
270 fn sub(self, rhs: Self) -> Self::Output {
271 $vec { $( $component: self.$component - rhs.$component, )* }
272 }
273 }
274 impl ops::Neg for $vec<$float> {
275 type Output = Self;
276 #[inline]
277 fn neg(self) -> Self::Output {
278 $vec { $( $component: -self.$component, )* }
279 }
280 }
281 impl ops::Mul for $vec<$float> {
282 type Output = Self;
283 #[inline]
284 fn mul(self, rhs: Self) -> Self::Output {
285 $vec { $( $component: self.$component * rhs.$component, )* }
286 }
287 }
288 impl ops::Div for $vec<$float> {
289 type Output = Self;
290 #[inline]
291 fn div(self, rhs: Self) -> Self::Output {
292 $vec { $( $component: self.$component / rhs.$component, )* }
293 }
294 }
295 impl ops::Rem for $vec<$float> {
296 type Output = Self;
297 #[inline]
298 fn rem(self, rhs: Self) -> Self::Output {
299 $vec { $( $component: self.$component % rhs.$component, )* }
300 }
301 }
302
303 impl $vec<$float> {
305 #[inline]
307 pub const fn clamp(self, low: Self, high: Self) -> Self {
308 $vec { $( $component: self.$component.max(low.$component).min(high.$component) ),* }
310 }
311 #[inline]
313 pub fn distance(self, rhs: Self) -> Scalar<$float> {
314 (self - rhs).length()
315 }
316 #[inline]
318 pub fn face_forward(self, e2: Self, e3: Self) -> Self {
319 self * Scalar((-e2.dot(e3)).0.signum())
321 }
322 #[inline]
324 pub fn length(self) -> Scalar<$float> {
325 Scalar(self.dot(self).0.sqrt())
326 }
327 #[inline]
329 pub const fn mix(self, rhs: Self, blend: Scalar<$float>) -> Self {
330 $vec { $( $component: self.$component * (1.0 - blend.0) + rhs.$component * blend.0 ),* }
331 }
332 #[inline]
334 pub fn mul_add(self, b: Self, c: Self) -> Self {
335 $vec { $( $component: self.$component.mul_add(b.$component, c.$component) ),* }
336 }
337 #[inline]
339 pub fn normalize(self) -> Self {
340 self / self.length()
341 }
342 #[inline]
344 pub fn reflect(self, rhs: Self) -> Self {
345 self - rhs * (Scalar(2.0) * rhs.dot(self))
346 }
347 #[inline]
349 pub const fn saturate(self) -> Self {
350 $vec { $( $component: self.$component.clamp(0.0, 1.0) ),* }
351 }
352 #[inline]
354 pub const fn sign(self) -> Self {
355 $vec { $(
356 $component: if self.$component == 0.0 {
358 0.0
359 } else {
360 self.$component.signum()
361 }
362 ),* }
363 }
364 pub fn smoothstep(self, edge0: Self, edge1: Self) -> Self {
367 let t = ((self - edge0) / (edge1 - edge0)).saturate();
368 t * t * (Scalar(3.0) - Scalar(2.0) * t)
369 }
370
371 delegate_unary_methods_elementwise!(const {
373 abs
374 } ($($component)*));
375 delegate_unary_methods_elementwise!({
376 acos, acosh, asin, asinh, atan, atanh, ceil, cos, cosh, exp, exp2, floor, fract, log2, round,
377 sin, sinh, tan, tanh, trunc, to_degrees, to_radians
378 } ($($component)*));
379 delegate_binary_methods_elementwise!({
380 atan2, max, min, powf
381 } ($($component)*));
382
383 }
386 }
387}
388
389macro_rules! impl_vector_scalar_float_arithmetic {
392 ($vec:ident, $float:ty, $( $component:tt )*) => {
393 impl ops::Add<Scalar<$float>> for $vec<$float> {
394 type Output = $vec<$float>;
395 #[inline]
396 fn add(self, rhs: Scalar<$float>) -> Self::Output {
397 $vec { $( $component: self.$component + rhs.0, )* }
398 }
399 }
400 impl ops::Sub<Scalar<$float>> for $vec<$float> {
401 type Output = $vec<$float>;
402 #[inline]
403 fn sub(self, rhs: Scalar<$float>) -> Self::Output {
404 $vec { $( $component: self.$component - rhs.0, )* }
405 }
406 }
407 impl ops::Sub<$vec<$float>> for Scalar<$float> {
408 type Output = $vec<$float>;
409 #[inline]
410 fn sub(self, rhs: $vec<$float>) -> Self::Output {
411 $vec { $( $component: self.0 - rhs.$component, )* }
412 }
413 }
414 impl ops::Mul<Scalar<$float>> for $vec<$float> {
415 type Output = $vec<$float>;
416 #[inline]
417 fn mul(self, rhs: Scalar<$float>) -> Self::Output {
418 $vec { $( $component: self.$component * rhs.0, )* }
419 }
420 }
421 impl ops::Div<Scalar<$float>> for $vec<$float> {
422 type Output = $vec<$float>;
423 #[inline]
424 fn div(self, rhs: Scalar<$float>) -> Self::Output {
425 $vec { $( $component: self.$component / rhs.0, )* }
426 }
427 }
428 impl ops::Div<$vec<$float>> for Scalar<$float> {
429 type Output = $vec<$float>;
430 #[inline]
431 fn div(self, rhs: $vec<$float>) -> Self::Output {
432 $vec { $( $component: self.0 / rhs.$component, )* }
433 }
434 }
435 impl ops::Rem<Scalar<$float>> for $vec<$float> {
436 type Output = $vec<$float>;
437 #[inline]
438 fn rem(self, rhs: Scalar<$float>) -> Self::Output {
439 $vec { $( $component: self.$component % rhs.0, )* }
440 }
441 }
442 }
443}
444
445macro_rules! impl_vector_bitwise_with_bool {
447 ($vec:ident, $int:ty, $( $component:tt )*) => {
448 impl ops::BitAnd for $vec<$int> {
449 type Output = Self;
450 fn bitand(self, rhs: Self) -> Self::Output {
451 $vec { $( $component: self.$component & rhs.$component, )* }
452 }
453 }
454 impl ops::BitOr for $vec<$int> {
455 type Output = Self;
456 fn bitor(self, rhs: Self) -> Self::Output {
457 $vec { $( $component: self.$component | rhs.$component, )* }
458 }
459 }
460 impl ops::BitXor for $vec<$int> {
461 type Output = Self;
462 fn bitxor(self, rhs: Self) -> Self::Output {
463 $vec { $( $component: self.$component ^ rhs.$component, )* }
464 }
465 }
466 impl ops::Not for $vec<$int> {
467 type Output = Self;
468 fn not(self) -> Self::Output {
469 $vec { $( $component: !self.$component, )* }
470 }
471 }
472 }
473}
474
475macro_rules! impl_vector_bitwise_without_bool {
477 ($vec:ident, $int:ty, $( $component:tt )*) => {
478 impl_vector_bitwise_with_bool!($vec, $int, $($component)*);
479
480 impl ops::Shl<$vec<u32>> for $vec<$int> {
481 type Output = Self;
482 fn shl(self, rhs: $vec<u32>) -> Self::Output {
483 $vec { $( $component: self.$component.unbounded_shl(rhs.$component), )* }
484 }
485 }
486 impl ops::Shr<$vec<u32>> for $vec<$int> {
487 type Output = Self;
488 fn shr(self, rhs: $vec<u32>) -> Self::Output {
489 $vec { $( $component: self.$component.unbounded_shr(rhs.$component), )* }
490 }
491 }
492
493 }
494}
495
496macro_rules! impl_element_casts {
497 ($ty:ident) => {
498 impl_element_casts!($ty, []);
499 };
500 ($ty:ident, [$($extra:tt)*]) => {
501 pub fn cast_elem_as_u32(self) -> $ty<u32> {
504 self.map(|component| component $($extra)* as u32)
505 }
506 pub fn cast_elem_as_i32(self) -> $ty<i32> {
507 self.map(|component| component $($extra)* as i32)
508 }
509 pub fn cast_elem_as_f32(self) -> $ty<f32> {
510 self.map(|component| component $($extra)* as f32)
511 }
512 pub fn cast_elem_as_f64(self) -> $ty<f64> {
513 self.map(|component| component $($extra)* as f64)
514 }
515 };
516}
517
518macro_rules! impl_index {
520 ($component_count:literal, $vector_type:ident, $index_type:ty) => {
521 impl<T> ops::Index<$index_type> for $vector_type<T> {
522 type Output = Scalar<T>;
523
524 #[inline]
525 fn index(&self, index: $index_type) -> &Self::Output {
526 if (0..$component_count).contains(&index) {
529 &self.as_array_ref()[index as usize]
530 } else {
531 panic!("matrix indexing out of bounds")
532 }
533 }
534 }
535
536 impl<T> ops::IndexMut<$index_type> for $vector_type<T> {
537 #[inline]
538 fn index_mut(&mut self, index: $index_type) -> &mut Self::Output {
539 if (0..$component_count).contains(&index) {
540 &mut self.as_array_mut()[index as usize]
541 } else {
542 panic!("vector indexing out of bounds")
543 }
544 }
545 }
546 };
547}
548
549macro_rules! impl_vector_regular_fns {
550 ( $ty:ident $component_count:literal : $( $component:tt )* ) => {
551 impl<T> $ty<T> {
552 pub fn splat(value: T) -> Self
553 where
554 T: Copy
555 {
556 Self { $( $component: value, )* }
557 }
558 pub fn splat_from_scalar(value: Scalar<T>) -> Self
559 where
560 T: Copy
561 {
562 Self { $( $component: value.0, )* }
563 }
564
565 pub const fn select(self, trues: Self, mask: $ty<bool>) -> Self
568 where
569 T: Copy
570 {
571 Self {
572 $(
573 $component: if mask.$component {
574 trues.$component
575 } else {
576 self.$component
577 },
578 )*
579 }
580 }
581
582 pub fn map<U, F>(self, mut f: F) -> $ty<U>
583 where
584 F: FnMut(T) -> U,
585 {
586 $ty {
587 $(
588 $component: f(self.$component),
589 )*
590 }
591 }
592
593 paste::paste! {
594 $(
595 pub fn [< set_ $component >](&mut self, value: Scalar<T>) {
596 self.$component = value.0;
597 }
598 )*
599 }
600
601 #[inline]
602 fn as_array_ref(&self) -> &[Scalar<T>; $component_count] {
603 unsafe { &*(&raw const *self).cast::<[Scalar<T>; $component_count]>() }
606 }
607 #[inline]
608 fn as_array_mut(&mut self) -> &mut [Scalar<T>; $component_count] {
609 unsafe { &mut *(&raw mut *self).cast::<[Scalar<T>; $component_count]>() }
612 }
613
614 #[inline]
618 pub fn dot(self, rhs: Self) -> Scalar<T>
619 where
620 Scalar<T>: ops::Mul<Output = Scalar<T>> + num_traits::ConstZero,
622 {
623 $( Scalar(self.$component) * Scalar(rhs.$component) + )* Scalar::<T>::ZERO
624 }
625
626 }
627
628 impl_vector_integer_arithmetic!($ty, i32, $($component)*);
629 impl_vector_integer_arithmetic!($ty, u32, $($component)*);
630 impl_vector_float_arithmetic!($ty, f32, $($component)*);
631 impl_vector_float_arithmetic!($ty, f64, $($component)*);
632
633 impl_vector_bitwise_with_bool!($ty, bool, $($component)*);
634 impl_vector_bitwise_without_bool!($ty, i32, $($component)*);
635 impl_vector_bitwise_without_bool!($ty, u32, $($component)*);
636
637 impl $ty<i32> {
638 impl_element_casts!($ty);
639 }
640 impl $ty<u32> {
641 impl_element_casts!($ty);
642 }
643 impl $ty<f32> {
644 impl_element_casts!($ty);
645 }
646 impl $ty<f64> {
647 impl_element_casts!($ty);
648 }
649 impl $ty<bool> {
650 impl_element_casts!($ty, [as u8]);
651 }
652
653 impl_index!($component_count, $ty, usize);
655 impl_index!($component_count, $ty, i32);
656 impl_index!($component_count, $ty, u32);
657
658 impl<T: ConstZero> $ty<T> {
660 pub const ZERO: Self = Self { $( $component: T::ZERO, )* };
662 }
663 impl<T: ConstZero> ConstZero for $ty<T>
664 where
665 Self: ops::Add<Output = Self>
666 {
667 const ZERO: Self = Self { $( $component: T::ZERO, )* };
668 }
669 impl<T: ConstZero> num_traits::Zero for $ty<T>
670 where
671 Self: ops::Add<Output = Self>
672 {
673 fn zero() -> Self {
674 Self::ZERO
675 }
676 fn is_zero(&self) -> bool {
677 $(T::is_zero(&self.$component) & )* true
678 }
679 }
680
681 impl<T: PartialOrd> $ty<T> {
683 pub fn elementwise_eq(self, rhs: Self) -> $ty<bool> {
684 self.partial_cmp(rhs).map(|cmp| matches!(cmp, Some(cmp::Ordering::Equal)))
685 }
686 pub fn elementwise_ne(self, rhs: Self) -> $ty<bool> {
687 self.partial_cmp(rhs).map(|cmp| !matches!(cmp, Some(cmp::Ordering::Equal)))
688 }
689 pub fn elementwise_lt(self, rhs: Self) -> $ty<bool> {
690 self.partial_cmp(rhs).map(|cmp| matches!(cmp, Some(cmp::Ordering::Less)))
691 }
692 pub fn elementwise_le(self, rhs: Self) -> $ty<bool> {
693 self.partial_cmp(rhs).map(|cmp| {
694 matches!(cmp, Some(cmp::Ordering::Less | cmp::Ordering::Equal))
695 })
696 }
697 pub fn elementwise_gt(self, rhs: Self) -> $ty<bool> {
698 self.partial_cmp(rhs).map(|cmp| matches!(cmp, Some(cmp::Ordering::Greater)))
699 }
700 pub fn elementwise_ge(self, rhs: Self) -> $ty<bool> {
701 self.partial_cmp(rhs).map(|cmp| {
702 matches!(cmp, Some(cmp::Ordering::Greater | cmp::Ordering::Equal))
703 })
704 }
705
706 fn partial_cmp(self, rhs: Self) -> $ty<Option<cmp::Ordering>> {
708 $ty {
709 $(
710 $component: self.$component.partial_cmp(&rhs.$component),
711 )*
712 }
713 }
714 }
715
716 impl<T> From<$ty<T>> for [T; $component_count] {
718 fn from(value: $ty<T>) -> Self {
719 [$( value.$component ),*]
720 }
721 }
722
723 impl $ty<i32> {
726 delegate_unary_methods_elementwise!(const { abs } ($($component)*));
727 }
728 impl $ty<u32> {
729 pub fn abs(self) -> Self { self }
730 }
731
732 impl $ty<bool> {
734 pub fn any(self) -> Scalar<bool> {
736 Scalar($( self.$component | )* false)
737 }
738 pub fn all(self) -> Scalar<bool> {
740 Scalar($( self.$component & )* true)
741 }
742 }
743 }
744}
745
746impl_vector_regular_fns!(Scalar 1 : 0);
747impl_vector_regular_fns!(Vec2 2 : x y);
748impl_vector_regular_fns!(Vec3 3 : x y z);
749impl_vector_regular_fns!(Vec4 4 : x y z w);
750
751macro_rules! impl_vector_not_scalar_fns {
756 ( $ty:ident $component_count:literal : $( $component:tt )* ) => {
757 impl<T> $ty<T> {
758 pub const fn new($( $component: T, )*) -> Self {
760 Self { $( $component, )* }
761 }
762
763 pub const fn from_scalars($( $component: Scalar<T>, )*) -> Self
764 where
765 T: Copy
766 {
767 Self { $( $component: $component.0, )* }
768 }
769 }
770
771 impl<T> From<[T; $component_count]> for $ty<T> {
772 fn from(value: [T; $component_count]) -> Self {
773 let [$( $component ),*] = value;
774 Self::new($( $component ),*)
775 }
776 }
777
778 impl_vector_scalar_integer_arithmetic!($ty, i32, $($component)*);
779 impl_vector_scalar_integer_arithmetic!($ty, u32, $($component)*);
780 impl_vector_scalar_float_arithmetic!($ty, f32, $($component)*);
781 impl_vector_scalar_float_arithmetic!($ty, f64, $($component)*);
782
783 impl<T> ops::Add<$ty<T>> for Scalar<T>
785 where
786 $ty<T>: ops::Add<Scalar<T>>
787 {
788 type Output = <$ty<T> as ops::Add<Scalar<T>>>::Output;
789 fn add(self, rhs: $ty<T>) -> Self::Output {
790 rhs + self
791 }
792 }
793 impl<T> ops::Mul<$ty<T>> for Scalar<T>
794 where
795 $ty<T>: ops::Mul<Scalar<T>>
796 {
797 type Output = <$ty<T> as ops::Mul<Scalar<T>>>::Output;
798 fn mul(self, rhs: $ty<T>) -> Self::Output {
799 rhs * self
800 }
801 }
802
803 }
804}
805
806impl_vector_not_scalar_fns!(Vec2 2 : x y);
807impl_vector_not_scalar_fns!(Vec3 3 : x y z);
808impl_vector_not_scalar_fns!(Vec4 4 : x y z w);
809
810impl<T> Scalar<T> {
811 pub fn new(value: T) -> Self {
812 Self(value)
813 }
814}
815impl<T> From<[T; 1]> for Scalar<T> {
816 fn from([value]: [T; 1]) -> Self {
817 Self(value)
818 }
819}
820
821macro_rules! impl_from_scalar_to_inner {
823 ($t:ty) => {
824 impl From<Scalar<$t>> for $t {
825 fn from(value: Scalar<$t>) -> Self {
826 value.0
827 }
828 }
829 };
830}
831impl_from_scalar_to_inner!(bool);
832impl_from_scalar_to_inner!(i32);
833impl_from_scalar_to_inner!(u32);
834impl_from_scalar_to_inner!(f32);
835impl_from_scalar_to_inner!(f64);
836
837impl<T> Scalar<T> {
841 pub fn into_inner(self) -> T {
843 self.0
844 }
845
846 pub fn into_array_index(self) -> usize
847 where
848 T: Copy + TryInto<usize> + fmt::Debug,
849 {
850 match self.into_inner().try_into() {
851 Ok(index) => index,
852 Err(_) => panic!("impossible array index {self:?}"),
853 }
854 }
855}
856
857impl Scalar<bool> {
858 #[mutants::skip] pub fn into_branch_condition(self) -> bool {
864 self.0
865 }
866}
867
868impl<T> From<T> for Scalar<T> {
869 fn from(value: T) -> Self {
870 Self(value)
871 }
872}
873
874impl<T: Default> Default for Scalar<T> {
875 fn default() -> Self {
876 Self(Default::default())
877 }
878}
879
880macro_rules! impl_flattening_ctor {
883 (fn $fn_name:ident ( $($param:tt)* ) => ( $($arg:tt)* )) => {
884 pub const fn $fn_name ($($param)*) -> Self {
885 Self::new($($arg)*)
886 }
887 }
888}
889impl<T: Copy> Vec3<T> {
891 impl_flattening_ctor!(fn new_12(x: Scalar<T>, yz: Vec2<T>) => (x.0, yz.x, yz.y));
892 impl_flattening_ctor!(fn new_21(xy: Vec2<T>, z: Scalar<T>) => (xy.x, xy.y, z.0));
893}
894impl<T: Copy> Vec4<T> {
895 impl_flattening_ctor!(fn new_112(x: Scalar<T>, y: Scalar<T>, zw: Vec2<T>) => (x.0, y.0, zw.x, zw.y));
896 impl_flattening_ctor!(fn new_121(x: Scalar<T>, yz: Vec2<T>, w: Scalar<T>) => (x.0, yz.x, yz.y, w.0));
897 impl_flattening_ctor!(fn new_211(xy: Vec2<T>, z: Scalar<T>, w: Scalar<T>) => (xy.x, xy.y, z.0, w.0));
898 impl_flattening_ctor!(fn new_22(xy: Vec2<T>, zw: Vec2<T>) => (xy.x, xy.y, zw.x, zw.y));
899 impl_flattening_ctor!(fn new_13(x: Scalar<T>, yzw: Vec3<T>) => (x.0, yzw.x, yzw.y, yzw.z));
900 impl_flattening_ctor!(fn new_31(xyz: Vec3<T>, w: Scalar<T>) => (xyz.x, xyz.y, xyz.z, w.0));
901}
902
903impl<T> Vec3<T> {
905 pub fn cross(self, rhs: Self) -> Self
907 where
908 T: Copy + ops::Mul<Output = T> + ops::Sub<Output = T>,
909 {
910 Self {
911 x: self.y * rhs.z - self.z * rhs.y,
912 y: self.z * rhs.x - self.x * rhs.z,
913 z: self.x * rhs.y - self.y * rhs.x,
914 }
915 }
916}
917
918macro_rules! scalar_accessors {
922 ($get:ident $get_mut:ident $component:ident ) => {
923 #[doc = stringify!($component)]
925 pub fn $get(self) -> Scalar<T> {
927 Scalar(self.$component)
928 }
929
930 #[doc = stringify!($component)]
932 pub fn $get_mut(&mut self) -> &mut Scalar<T> {
934 unsafe { &mut *(&raw mut self.$component).cast::<Scalar<T>>() }
936 }
937 };
938}
939
940macro_rules! swizzle_fn {
941 ($name:ident $output:ident ($($cin:ident)*) ) => {
942 #[doc = stringify!($($cin),*)]
944 pub fn $name(self) -> $output<T> {
946 $output::new($(self.$cin,)*)
947 }
948 }
949}
950
951impl<T: Copy> Vec2<T> {
952 scalar_accessors!(x x_mut x);
953 scalar_accessors!(y y_mut y);
954 swizzle_fn!(xy Vec2(x y));
955 swizzle_fn!(yx Vec2(y x));
956}
957impl<T: Copy> Vec3<T> {
958 scalar_accessors!(x x_mut x);
959 scalar_accessors!(y y_mut y);
960 scalar_accessors!(z z_mut z);
961 swizzle_fn!(xy Vec2(x y));
962 swizzle_fn!(yx Vec2(y x));
963 swizzle_fn!(xyz Vec3(x y z));
964 swizzle_fn!(xzy Vec3(x z y));
965 swizzle_fn!(yxz Vec3(y x z));
966 swizzle_fn!(yzx Vec3(y z x));
967 swizzle_fn!(zxy Vec3(z x y));
968 swizzle_fn!(zyx Vec3(z y x));
969}
970impl<T: Copy> Vec4<T> {
971 scalar_accessors!(x x_mut x);
972 scalar_accessors!(y y_mut y);
973 scalar_accessors!(z z_mut z);
974 scalar_accessors!(w w_mut w);
975 swizzle_fn!(xy Vec2(x y));
976 swizzle_fn!(yx Vec2(y x));
977 swizzle_fn!(xyz Vec3(x y z));
978 swizzle_fn!(xzy Vec3(x z y));
979 swizzle_fn!(yxz Vec3(y x z));
980 swizzle_fn!(yzx Vec3(y z x));
981 swizzle_fn!(zxy Vec3(z x y));
982 swizzle_fn!(zyx Vec3(z y x));
983 swizzle_fn!(xyzw Vec4(x y z w));
984 swizzle_fn!(xywz Vec4(x y w z));
985 swizzle_fn!(xzwy Vec4(x z w y));
986 swizzle_fn!(xzyw Vec4(x z y w));
987 swizzle_fn!(xwyz Vec4(x w y z));
988 swizzle_fn!(xwzy Vec4(x w z y));
989 swizzle_fn!(yxzw Vec4(y x z w));
990 swizzle_fn!(yxwz Vec4(y x w z));
991 swizzle_fn!(yzxw Vec4(y z x w));
992 swizzle_fn!(yzwx Vec4(y z w x));
993 swizzle_fn!(ywzx Vec4(y w z x));
994 swizzle_fn!(ywxz Vec4(y w x z));
995 swizzle_fn!(zxyw Vec4(z x y w));
996 swizzle_fn!(zxwy Vec4(z x w y));
997 swizzle_fn!(zyxw Vec4(z y x w));
998 swizzle_fn!(zywx Vec4(z y w x));
999 swizzle_fn!(zwxy Vec4(z w x y));
1000 swizzle_fn!(zwyx Vec4(z w y x));
1001 swizzle_fn!(wxyz Vec4(w x y z));
1002 swizzle_fn!(wxzy Vec4(w x z y));
1003 swizzle_fn!(wyxz Vec4(w y x z));
1004 swizzle_fn!(wyzx Vec4(w y z x));
1005 swizzle_fn!(wzxy Vec4(w z x y));
1006 swizzle_fn!(wzyx Vec4(w z y x));
1007}