ultraviolet/
int.rs

1use crate::*;
2use std::convert::{TryFrom, TryInto};
3use std::ops::*;
4
5pub trait MulAdd<A = Self, B = Self> {
6    /// The resulting type after applying the fused multiply-add.
7    type Output;
8
9    /// Performs the fused multiply-add operation.
10    fn mul_add(self, a: A, b: B) -> Self::Output;
11}
12
13impl MulAdd<u32, u32> for u32 {
14    type Output = u32;
15
16    fn mul_add(self, a: u32, b: u32) -> Self::Output {
17        (self * a) + b
18    }
19}
20
21impl MulAdd<i32, i32> for i32 {
22    type Output = i32;
23
24    fn mul_add(self, a: i32, b: i32) -> Self::Output {
25        (self * a) + b
26    }
27}
28
29macro_rules! ivec2s {
30    ($(($n:ident, $v3t:ident, $v4t:ident) => $t:ident),+) => {
31        $(
32        /// A set of two coordinates which may be interpreted as a vector or point in 2d space.
33        ///
34        /// Generally this distinction between a point and vector is more of a pain than it is worth
35        /// to distinguish on a type level, however when converting to and from homogeneous
36        /// coordinates it is quite important.
37        #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
38        #[repr(C)]
39        pub struct $n {
40            pub x: $t,
41            pub y: $t,
42        }
43
44
45        impl $n {
46            #[inline]
47            pub const fn new(x: $t, y: $t) -> Self {
48                $n { x, y }
49            }
50
51            #[inline]
52            pub fn broadcast(val: $t) -> Self {
53                Self::new(val, val)
54            }
55
56            #[inline]
57            pub fn unit_x() -> Self {
58                $n{ x: 1, y: 0 }
59            }
60
61            #[inline]
62            pub fn unit_y() -> Self {
63                $n{ x: 0, y: 1 }
64            }
65
66            /// Create a homogeneous 2d *point* from this vector interpreted as a point,
67            /// meaning the homogeneous component will start with a value of 1.
68            #[inline]
69            pub fn into_homogeneous_point(self) -> $v3t {
70                $v3t { x: self.x, y: self.y, z: 1 }
71            }
72
73            /// Create a homogeneous 2d *vector* from this vector,
74            /// meaning the homogeneous component will always have a value of 0.
75            #[inline]
76            pub fn into_homogeneous_vector(self) -> $v3t {
77                $v3t { x: self.x, y: self.y, z: 0 }
78            }
79
80            /// Create a 2d point from a homogeneous 2d *point*, performing
81            /// division by the homogeneous component. This should not be used
82            /// for homogeneous 2d *vectors*, which will have 0 as their
83            /// homogeneous component.
84            #[inline]
85            pub fn from_homogeneous_point(v: $v3t) -> Self {
86                Self { x: v.x / v.z, y: v.y / v.z }
87            }
88
89            /// Create a 2d vector from homogeneous 2d *vector*, which simply
90            /// discards the homogeneous component.
91            #[inline]
92            pub fn from_homogeneous_vector(v: $v3t) -> Self {
93                v.into()
94            }
95
96            #[inline]
97            pub fn dot(&self, other: $n) -> $t {
98                (self.x * other.x) + (self.y * other.y)
99            }
100
101            #[inline]
102            pub fn reflected(&self, normal: $n) -> Self {
103                *self - (2 * self.dot(normal) * normal)
104            }
105
106            #[inline]
107            pub fn mag(&self) -> $t {
108                (self.mag_sq() as f64).sqrt() as $t
109            }
110
111            #[inline]
112            pub fn mag_sq(&self) -> $t {
113                (self.x * self.x) + (self.y * self.y)
114            }
115
116            #[inline]
117            pub fn mul_add(&self, mul: $n, add: $n) -> Self {
118                $n::new(
119                    self.x.mul_add(mul.x, add.x),
120                    self.y.mul_add(mul.y, add.y),
121                )
122            }
123
124            #[inline]
125            pub fn clamp(&mut self, min: Self, max: Self) {
126                self.x = self.x.max(min.x).min(max.x);
127                self.y = self.y.max(min.y).min(max.y);
128            }
129
130            #[inline]
131            pub fn clamped(mut self, min: Self, max: Self) -> Self {
132                self.clamp(min, max);
133                self
134            }
135
136            #[inline]
137            pub fn map<F>(&self, mut f: F) -> Self
138                where F: FnMut($t) -> $t
139            {
140                $n::new(
141                    f(self.x),
142                    f(self.y),
143                )
144            }
145
146            #[inline]
147            pub fn apply<F>(&mut self, mut f: F)
148                where F: FnMut($t) -> $t
149            {
150                self.x = f(self.x);
151                self.y = f(self.y);
152            }
153
154            #[inline]
155            pub fn max_by_component(mut self, other: Self) -> Self {
156                self.x = self.x.max(other.x);
157                self.y = self.y.max(other.y);
158                self
159            }
160
161            #[inline]
162            pub fn min_by_component(mut self, other: Self) -> Self {
163                self.x = self.x.min(other.x);
164                self.y = self.y.min(other.y);
165                self
166            }
167
168            #[inline]
169            pub fn component_max(&self) -> $t {
170                self.x.max(self.y)
171            }
172
173            #[inline]
174            pub fn component_min(&self) -> $t {
175                self.x.min(self.y)
176            }
177
178            #[inline]
179            pub fn zero() -> Self {
180                Self::broadcast(0)
181            }
182
183            #[inline]
184            pub fn one() -> Self {
185                Self::broadcast(1)
186            }
187
188            #[inline]
189            pub fn xyz(&self) -> $v3t {
190                $v3t::new(self.x, self.y, 0)
191            }
192
193            #[inline]
194            pub fn xyzw(&self) -> $v4t {
195                $v4t::new(self.x, self.y, 0, 0)
196            }
197
198            #[inline]
199            pub fn layout() -> alloc::alloc::Layout {
200                alloc::alloc::Layout::from_size_align(std::mem::size_of::<Self>(), std::mem::align_of::<$t>()).unwrap()
201            }
202
203            #[inline]
204            pub fn as_slice(&self) -> &[$t] {
205                // This is safe because we are statically bounding our slices to the size of these
206                // vectors
207                unsafe {
208                    std::slice::from_raw_parts(self as *const $n as *const $t, 2)
209                }
210            }
211
212            #[inline]
213            pub fn as_array(&self) -> [$t; 2] {
214                use std::convert::TryInto;
215                self.as_slice().try_into().unwrap()
216            }
217
218            #[inline]
219            pub fn as_byte_slice(&self) -> &[u8] {
220                // This is safe because we are statically bounding our slices to the size of these
221                // vectors
222                unsafe {
223                    std::slice::from_raw_parts(self as *const $n as *const u8, 2 * std::mem::size_of::<$t>())
224                }
225            }
226
227            #[inline]
228            pub fn as_mut_slice(&mut self) -> &mut [$t] {
229                // This is safe because we are statically bounding our slices to the size of these
230                // vectors
231                unsafe {
232                    std::slice::from_raw_parts_mut(self as *mut $n as *mut $t, 2)
233                }
234            }
235
236            #[inline]
237            pub fn as_mut_byte_slice(&mut self) -> &mut [u8] {
238                // This is safe because we are statically bounding our slices to the size of these
239                // vectors
240                unsafe {
241                    std::slice::from_raw_parts_mut(self as *mut $n as *mut u8, 2 * std::mem::size_of::<$t>())
242                }
243            }
244
245            /// Returns a constant unsafe pointer to the underlying data in the underlying type.
246            /// This function is safe because all types here are repr(C) and can be represented
247            /// as their underlying type.
248            ///
249            /// # Safety
250            ///
251            /// It is up to the caller to correctly use this pointer and its bounds.
252            #[inline]
253            pub fn as_ptr(&self) -> *const $t {
254                self as *const $n as *const $t
255            }
256
257            /// Returns a mutable unsafe pointer to the underlying data in the underlying type.
258            /// This function is safe because all types here are repr(C) and can be represented
259            /// as their underlying type.
260            ///
261            /// # Safety
262            ///
263            /// It is up to the caller to correctly use this pointer and its bounds.
264            #[inline]
265            pub fn as_mut_ptr(&mut self) -> *mut $t {
266                self as *mut $n as *mut $t
267            }
268        }
269
270        impl From<[$t; 2]> for $n {
271            #[inline]
272            fn from(comps: [$t; 2]) -> Self {
273                Self::new(comps[0], comps[1])
274            }
275        }
276
277        impl From<$n> for [$t; 2] {
278            #[inline]
279            fn from(v: $n) -> Self {
280                [v.x, v.y]
281            }
282        }
283
284        impl From<&[$t; 2]> for $n {
285            #[inline]
286            fn from(comps: &[$t; 2]) -> Self {
287                Self::from(*comps)
288            }
289        }
290
291        impl From<&mut [$t; 2]> for $n {
292            #[inline]
293            fn from(comps: &mut [$t; 2]) -> Self {
294                Self::from(*comps)
295            }
296        }
297
298        impl From<($t, $t)> for $n {
299            #[inline]
300            fn from(comps: ($t, $t)) -> Self {
301                Self::new(comps.0, comps.1)
302            }
303        }
304
305        impl From<&($t, $t)> for $n {
306            #[inline]
307            fn from(comps: &($t, $t)) -> Self {
308                Self::from(*comps)
309            }
310        }
311
312        impl From<$n> for ($t, $t) {
313            #[inline]
314            fn from(v: $n) -> Self {
315                (v.x, v.y)
316            }
317        }
318
319        impl Add for $n {
320            type Output = Self;
321            #[inline]
322            fn add(self, rhs: $n) -> Self {
323                $n::new(self.x + rhs.x, self.y + rhs.y)
324            }
325        }
326
327        impl AddAssign for $n {
328            #[inline]
329            fn add_assign(&mut self, rhs: $n) {
330                self.x += rhs.x;
331                self.y += rhs.y;
332            }
333        }
334
335        impl Sub for $n {
336            type Output = Self;
337            #[inline]
338            fn sub(self, rhs: $n) -> Self {
339                $n::new(self.x - rhs.x, self.y - rhs.y)
340            }
341        }
342
343        impl SubAssign for $n {
344            #[inline]
345            fn sub_assign(&mut self, rhs: $n) {
346                self.x -= rhs.x;
347                self.y -= rhs.y;
348            }
349        }
350
351        impl Mul for $n {
352            type Output = Self;
353            #[inline]
354            fn mul(self, rhs: $n) -> Self {
355                $n::new(self.x * rhs.x, self.y * rhs.y)
356            }
357        }
358
359        impl Mul<$n> for $t {
360            type Output = $n;
361            #[inline]
362            fn mul(self, rhs: $n) -> $n {
363                $n::new(self * rhs.x, self * rhs.y)
364            }
365        }
366
367        impl Mul<$t> for $n {
368            type Output = $n;
369            #[inline]
370            fn mul(self, rhs: $t) -> $n {
371                $n::new(self.x * rhs, self.y * rhs)
372            }
373        }
374
375        impl MulAssign for $n {
376            #[inline]
377            fn mul_assign(&mut self, rhs: $n) {
378                self.x *= rhs.x;
379                self.y *= rhs.y;
380            }
381        }
382
383        impl MulAssign<$t> for $n {
384            #[inline]
385            fn mul_assign(&mut self, rhs: $t) {
386                self.x *= rhs;
387                self.y *= rhs;
388            }
389        }
390
391        impl Div for $n {
392            type Output = Self;
393            #[inline]
394            fn div(self, rhs: $n) -> Self {
395                $n::new(self.x / rhs.x, self.y / rhs.y)
396            }
397        }
398
399        impl Div<$t> for $n {
400            type Output = $n;
401            #[inline]
402            fn div(self, rhs: $t) -> $n {
403                $n::new(self.x / rhs, self.y / rhs)
404            }
405        }
406
407        impl DivAssign for $n {
408            #[inline]
409            fn div_assign(&mut self, rhs: $n) {
410                self.x /= rhs.x;
411                self.y /= rhs.y;
412            }
413        }
414
415        impl DivAssign<$t> for $n {
416            #[inline]
417            fn div_assign(&mut self, rhs: $t) {
418                self.x /= rhs;
419                self.y /= rhs;
420            }
421        }
422
423        impl Index<usize> for $n {
424            type Output = $t;
425
426            fn index(&self, index: usize) -> &Self::Output {
427                match index {
428                    0 => &self.x,
429                    1 => &self.y,
430                    _ => panic!("Invalid for vector of type: {}", std::any::type_name::<$n>()),
431                }
432            }
433        }
434
435        impl IndexMut<usize> for $n {
436            fn index_mut(&mut self, index: usize) -> &mut Self::Output {
437                match index {
438                    0 => &mut self.x,
439                    1 => &mut self.y,
440                    _ => panic!("Invalid for vector of type: {}", std::any::type_name::<$n>()),
441                }
442            }
443        }
444        )+
445    };
446}
447
448macro_rules! ivec3s {
449    ($(($v2t:ident, $n:ident, $v4t:ident) => $t:ident),+) => {
450        /// A set of three coordinates which may be interpreted as a point or vector in 3d space,
451        /// or as a homogeneous 2d vector or point.
452        ///
453        /// Generally this distinction between a point and vector is more of a pain than it is worth
454        /// to distinguish on a type level, however when converting to and from homogeneous
455        /// coordinates it is quite important.
456        $(#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
457        #[repr(C)]
458        pub struct $n {
459            pub x: $t,
460            pub y: $t,
461            pub z: $t,
462        }
463
464        impl $n {
465            #[inline]
466            pub const fn new(x: $t, y: $t, z: $t) -> Self {
467                $n { x, y, z }
468            }
469
470            #[inline]
471            pub fn broadcast(val: $t) -> Self {
472                Self::new(val, val, val)
473            }
474
475            #[inline]
476            pub fn unit_x() -> Self {
477                $n{ x: 1, y: 0, z: 0 }
478            }
479
480            #[inline]
481            pub fn unit_y() -> Self {
482                $n{ x: 0, y: 1, z: 0 }
483            }
484
485            #[inline]
486            pub fn unit_z() -> Self {
487                $n{ x: 0, y: 0, z: 1 }
488            }
489
490            #[inline]
491            pub fn cross(&self, other: $n) -> Self {
492                $n::new(
493                    self.y.mul_add(other.z, -(self.z as i32) as $t * other.y),
494                    self.z.mul_add(other.x, -(self.x as i32) as $t * other.z),
495                    self.x.mul_add(other.y, -(self.y as i32) as $t * other.x),
496                )
497            }
498
499            /// Create a homogeneous 3d *point* from this vector interpreted as a point,
500            /// meaning the homogeneous component will start with a value of 1.
501            #[inline]
502            pub fn into_homogeneous_point(self) -> $v4t {
503                $v4t { x: self.x, y: self.y, z: self.z, w: 1 }
504            }
505
506            /// Create a homogeneous 3d *vector* from this vector,
507            /// meaning the homogeneous component will always have a value of 0.
508            #[inline]
509            pub fn into_homogeneous_vector(self) -> $v4t {
510                $v4t { x: self.x, y: self.y, z: self.z, w: 0 }
511            }
512
513            /// Create a 3d point from a homogeneous 3d *point*, performing
514            /// division by the homogeneous component. This should not be used
515            /// for homogeneous 3d *vectors*, which will have 0 as their
516            /// homogeneous component.
517            #[inline]
518            pub fn from_homogeneous_point(v: $v4t) -> Self {
519                Self { x: v.x / v.w, y: v.y / v.w, z: v.z / v.w }
520            }
521
522            /// Create a 3d vector from homogeneous 2d *vector*, which simply
523            /// discards the homogeneous component.
524            #[inline]
525            pub fn from_homogeneous_vector(v: $v4t) -> Self {
526                v.into()
527            }
528
529
530            #[inline]
531            pub fn dot(&self, other: $n) -> $t {
532                (self.x * other.x) + (self.y * other.y) + (self.z * other.z)
533            }
534
535            #[inline]
536            pub fn reflect(&mut self, normal: $n) {
537                *self -= 2 * self.dot(normal) * normal;
538            }
539
540            #[inline]
541            pub fn reflected(&self, normal: $n) -> Self {
542                let mut a = *self;
543                a.reflect(normal);
544                a
545            }
546
547            #[inline]
548            pub fn mag(&self) -> $t {
549                (self.mag_sq() as f64).sqrt() as $t
550            }
551
552            #[inline]
553            pub fn mag_sq(&self) -> $t {
554                (self.x * self.x) + (self.y * self.y) + (self.z * self.z)
555            }
556
557            #[inline]
558            pub fn mul_add(&self, mul: $n, add: $n) -> Self {
559                $n::new(
560                    self.x.mul_add(mul.x, add.x),
561                    self.y.mul_add(mul.y, add.y),
562                    self.z.mul_add(mul.z, add.z),
563                )
564            }
565
566            #[inline]
567            pub fn clamp(&mut self, min: Self, max: Self) {
568                self.x = self.x.max(min.x).min(max.x);
569                self.y = self.y.max(min.y).min(max.y);
570                self.z = self.z.max(min.z).min(max.z);
571            }
572
573            #[inline]
574            pub fn clamped(mut self, min: Self, max: Self) -> Self {
575                self.clamp(min, max);
576                self
577            }
578
579            #[inline]
580            pub fn map<F>(&self, mut f: F) -> Self
581                where F: FnMut($t) -> $t
582            {
583                $n::new(
584                    f(self.x),
585                    f(self.y),
586                    f(self.z)
587                )
588            }
589
590            #[inline]
591            pub fn apply<F>(&mut self, mut f: F)
592                where F: FnMut($t) -> $t
593            {
594                self.x = f(self.x);
595                self.y = f(self.y);
596                self.z = f(self.z);
597            }
598
599            #[inline]
600            pub fn max_by_component(mut self, other: Self) -> Self {
601                self.x = self.x.max(other.x);
602                self.y = self.y.max(other.y);
603                self.z = self.z.max(other.z);
604                self
605            }
606
607            #[inline]
608            pub fn min_by_component(mut self, other: Self) -> Self {
609                self.x = self.x.min(other.x);
610                self.y = self.y.min(other.y);
611                self.z = self.z.min(other.z);
612                self
613            }
614
615            #[inline]
616            pub fn component_max(&self) -> $t {
617                self.x.max(self.y).max(self.z)
618            }
619
620            #[inline]
621            pub fn component_min(&self) -> $t {
622                self.x.min(self.y).min(self.z)
623            }
624
625            #[inline]
626            pub fn zero() -> Self {
627                Self::broadcast(0)
628            }
629
630            #[inline]
631            pub fn one() -> Self {
632                Self::broadcast(1)
633            }
634
635
636            #[inline]
637            pub fn xy(&self) -> $v2t {
638                $v2t::new(self.x, self.y)
639            }
640
641            #[inline]
642            pub fn xyzw(&self) -> $v4t {
643                $v4t::new(self.x, self.y, self.z, 0)
644            }
645
646            #[inline]
647            pub fn layout() -> alloc::alloc::Layout {
648                alloc::alloc::Layout::from_size_align(std::mem::size_of::<Self>(), std::mem::align_of::<$t>()).unwrap()
649            }
650
651            #[inline]
652            pub fn as_slice(&self) -> &[$t] {
653                // This is safe because we are statically bounding our slices to the size of these
654                // vectors
655                unsafe {
656                    std::slice::from_raw_parts(self as *const $n as *const $t, 3)
657                }
658            }
659
660            #[inline]
661            pub fn as_array(&self) -> [$t; 3] {
662                use std::convert::TryInto;
663                self.as_slice().try_into().unwrap()
664            }
665
666            #[inline]
667            pub fn as_byte_slice(&self) -> &[u8] {
668                // This is safe because we are statically bounding our slices to the size of these
669                // vectors
670                unsafe {
671                    std::slice::from_raw_parts(self as *const $n as *const u8, 3 * std::mem::size_of::<$t>())
672                }
673            }
674
675            #[inline]
676            pub fn as_mut_slice(&mut self) -> &mut [$t] {
677                // This is safe because we are statically bounding our slices to the size of these
678                // vectors
679                unsafe {
680                    std::slice::from_raw_parts_mut(self as *mut $n as *mut $t, 3)
681                }
682            }
683
684            #[inline]
685            pub fn as_mut_byte_slice(&mut self) -> &mut [u8] {
686                // This is safe because we are statically bounding our slices to the size of these
687                // vectors
688                unsafe {
689                    std::slice::from_raw_parts_mut(self as *mut $n as *mut u8, 3 * std::mem::size_of::<$t>())
690                }
691            }
692
693            /// Returns a constant unsafe pointer to the underlying data in the underlying type.
694            /// This function is safe because all types here are repr(C) and can be represented
695            /// as their underlying type.
696            ///
697            /// # Safety
698            ///
699            /// It is up to the caller to correctly use this pointer and its bounds.
700            #[inline]
701            pub fn as_ptr(&self) -> *const $t {
702                self as *const $n as *const $t
703            }
704
705            /// Returns a mutable unsafe pointer to the underlying data in the underlying type.
706            /// This function is safe because all types here are repr(C) and can be represented
707            /// as their underlying type.
708            ///
709            /// # Safety
710            ///
711            /// It is up to the caller to correctly use this pointer and its bounds.
712            #[inline]
713            pub fn as_mut_ptr(&mut self) -> *mut $t {
714                self as *mut $n as *mut $t
715            }
716        }
717
718        impl From<[$t; 3]> for $n {
719            #[inline]
720            fn from(comps: [$t; 3]) -> Self {
721                Self::new(comps[0], comps[1], comps[2])
722            }
723        }
724
725        impl From<$n> for [$t; 3] {
726            #[inline]
727            fn from(v: $n) -> Self {
728                [v.x, v.y, v.z]
729            }
730        }
731
732        impl From<&[$t; 3]> for $n {
733            #[inline]
734            fn from(comps: &[$t; 3]) -> Self {
735                Self::from(*comps)
736            }
737        }
738
739        impl From<&mut [$t; 3]> for $n {
740            #[inline]
741            fn from(comps: &mut [$t; 3]) -> Self {
742                Self::from(*comps)
743            }
744        }
745
746        impl From<($t, $t, $t)> for $n {
747            #[inline]
748            fn from(comps: ($t, $t, $t)) -> Self {
749                Self::new(comps.0, comps.1, comps.2)
750            }
751        }
752
753        impl From<&($t, $t, $t)> for $n {
754            #[inline]
755            fn from(comps: &($t, $t, $t)) -> Self {
756                Self::from(*comps)
757            }
758        }
759
760        impl From<$n> for ($t, $t, $t) {
761            #[inline]
762            fn from(v: $n) -> Self {
763                (v.x, v.y, v.z)
764            }
765        }
766
767        impl Add for $n {
768            type Output = Self;
769            #[inline]
770            fn add(self, rhs: $n) -> Self {
771                $n::new(self.x + rhs.x, self.y + rhs.y, self.z + rhs.z)
772            }
773        }
774
775        impl AddAssign for $n {
776            #[inline]
777            fn add_assign(&mut self, rhs: $n) {
778                self.x += rhs.x;
779                self.y += rhs.y;
780                self.z += rhs.z;
781            }
782        }
783
784        impl Sub for $n {
785            type Output = Self;
786            #[inline]
787            fn sub(self, rhs: $n) -> Self {
788                $n::new(self.x - rhs.x, self.y - rhs.y, self.z - rhs.z)
789            }
790        }
791
792        impl SubAssign for $n {
793            #[inline]
794            fn sub_assign(&mut self, rhs: $n) {
795                self.x -= rhs.x;
796                self.y -= rhs.y;
797                self.z -= rhs.z;
798            }
799        }
800
801        impl Mul for $n {
802            type Output = Self;
803            #[inline]
804            fn mul(self, rhs: $n) -> Self {
805                $n::new(self.x * rhs.x, self.y * rhs.y, self.z * rhs.z)
806            }
807        }
808
809        impl Mul<$n> for $t {
810            type Output = $n;
811            #[inline]
812            fn mul(self, rhs: $n) -> $n {
813                $n::new(self * rhs.x, self * rhs.y, self * rhs.z)
814            }
815        }
816
817        impl Mul<$t> for $n {
818            type Output = $n;
819            #[inline]
820            fn mul(self, rhs: $t) -> $n {
821                $n::new(self.x * rhs, self.y * rhs, self.z * rhs)
822            }
823        }
824
825        impl MulAssign for $n {
826            #[inline]
827            fn mul_assign(&mut self, rhs: $n) {
828                self.x *= rhs.x;
829                self.y *= rhs.y;
830                self.z *= rhs.z;
831            }
832        }
833
834        impl MulAssign<$t> for $n {
835            #[inline]
836            fn mul_assign(&mut self, rhs: $t) {
837                self.x *= rhs;
838                self.y *= rhs;
839                self.z *= rhs;
840            }
841        }
842
843        impl Div for $n {
844            type Output = Self;
845            #[inline]
846            fn div(self, rhs: $n) -> Self {
847                $n::new(self.x / rhs.x, self.y / rhs.y, self.z / rhs.z)
848            }
849        }
850
851        impl Div<$t> for $n {
852            type Output = $n;
853            #[inline]
854            fn div(self, rhs: $t) -> $n {
855                $n::new(self.x / rhs, self.y / rhs, self.z / rhs)
856            }
857        }
858
859        impl DivAssign for $n {
860            #[inline]
861            fn div_assign(&mut self, rhs: $n) {
862                self.x /= rhs.x;
863                self.y /= rhs.y;
864                self.z /= rhs.z;
865            }
866        }
867
868        impl DivAssign<$t> for $n {
869            #[inline]
870            fn div_assign(&mut self, rhs: $t) {
871                self.x /= rhs;
872                self.y /= rhs;
873                self.z /= rhs;
874            }
875        }
876
877        impl Index<usize> for $n {
878            type Output = $t;
879
880            fn index(&self, index: usize) -> &Self::Output {
881                match index {
882                    0 => &self.x,
883                    1 => &self.y,
884                    2 => &self.z,
885                    _ => panic!("Invalid for vector of type: {}", std::any::type_name::<$n>()),
886                }
887            }
888        }
889
890        impl IndexMut<usize> for $n {
891            fn index_mut(&mut self, index: usize) -> &mut Self::Output {
892                match index {
893                    0 => &mut self.x,
894                    1 => &mut self.y,
895                    2 => &mut self.z,
896                    _ => panic!("Invalid for vector of type: {}", std::any::type_name::<$n>()),
897                }
898            }
899        }
900        )+
901    }
902}
903
904macro_rules! ivec4s {
905    ($($n:ident, $v2t:ident, $v3t:ident => $t:ident),+) => {
906        /// A set of four coordinates which may be interpreted as a point or vector in 4d space,
907        /// or as a homogeneous 3d vector or point.
908        ///
909        /// Generally this distinction between a point and vector is more of a pain than it is worth
910        /// to distinguish on a type level, however when converting to and from homogeneous
911        /// coordinates it is quite important.
912        $(#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
913        #[repr(C)]
914        pub struct $n {
915            pub x: $t,
916            pub y: $t,
917            pub z: $t,
918            pub w: $t,
919        }
920
921        impl $n {
922            #[inline]
923            pub const fn new(x: $t, y: $t, z: $t, w: $t) -> Self {
924                $n { x, y, z, w }
925            }
926
927            #[inline]
928            pub fn broadcast(val: $t) -> Self {
929                Self::new(val, val, val, val)
930            }
931
932            #[inline]
933            pub fn unit_x() -> Self {
934                $n{ x: 1, y: 0, z: 0, w: 0 }
935            }
936
937            #[inline]
938            pub fn unit_y() -> Self {
939                $n{ x: 0, y: 1, z: 0, w: 0 }
940            }
941
942            #[inline]
943            pub fn unit_z() -> Self {
944                $n{ x: 0, y: 0, z: 1, w: 0 }
945            }
946
947            #[inline]
948            pub fn unit_w() -> Self {
949                $n{ x: 0, y: 0, z: 0, w: 1 }
950            }
951
952            #[inline]
953            pub fn dot(&self, other: $n) -> $t {
954                (self.x * other.x) + (self.y * other.y) + (self.z * other.z) + (self.w * other.w)
955            }
956
957            #[inline]
958            pub fn reflect(&mut self, normal: $n) {
959                *self -= 2 * self.dot(normal) * normal;
960            }
961
962            #[inline]
963            pub fn reflected(&self, normal: $n) -> Self {
964                let mut a = *self;
965                a.reflect(normal);
966                a
967            }
968
969            #[inline]
970            pub fn mag(&self) -> $t {
971                (self.mag_sq() as f64).sqrt() as $t
972            }
973
974            #[inline]
975            pub fn mag_sq(&self) -> $t {
976                (self.x * self.x) + (self.y * self.y) + (self.z * self.z) + (self.w * self.w)
977            }
978
979            #[inline]
980            pub fn mul_add(&self, mul: $n, add: $n) -> Self {
981                $n::new(
982                    self.x.mul_add(mul.x, add.x),
983                    self.y.mul_add(mul.y, add.y),
984                    self.z.mul_add(mul.z, add.z),
985                    self.w.mul_add(mul.w, add.w),
986                )
987            }
988
989            #[inline]
990            pub fn clamp(&mut self, min: Self, max: Self) {
991                self.x = self.x.max(min.x).min(max.x);
992                self.y = self.y.max(min.y).min(max.y);
993                self.z = self.z.max(min.z).min(max.z);
994                self.w = self.w.max(min.w).min(max.w);
995            }
996
997            #[inline]
998            pub fn clamped(mut self, min: Self, max: Self) -> Self {
999                self.clamp(min, max);
1000                self
1001            }
1002
1003            #[inline]
1004            pub fn map<F>(&self, mut f: F) -> Self
1005                where F: FnMut($t) -> $t
1006            {
1007                $n::new(
1008                    f(self.x),
1009                    f(self.y),
1010                    f(self.z),
1011                    f(self.w),
1012                )
1013            }
1014
1015            #[inline]
1016            pub fn apply<F>(&mut self, mut f: F)
1017                where F: FnMut($t) -> $t
1018            {
1019                self.x = f(self.x);
1020                self.y = f(self.y);
1021                self.z = f(self.z);
1022                self.w = f(self.w);
1023            }
1024
1025            #[inline]
1026            pub fn max_by_component(mut self, other: Self) -> Self {
1027                self.x = self.x.max(other.x);
1028                self.y = self.y.max(other.y);
1029                self.z = self.z.max(other.z);
1030                self.w = self.w.max(other.w);
1031                self
1032            }
1033
1034            #[inline]
1035            pub fn min_by_component(mut self, other: Self) -> Self {
1036                self.x = self.x.min(other.x);
1037                self.y = self.y.min(other.y);
1038                self.z = self.z.min(other.z);
1039                self.w = self.w.min(other.w);
1040                self
1041            }
1042
1043            #[inline]
1044            pub fn component_max(&self) -> $t {
1045                self.x.max(self.y).max(self.z).max(self.w)
1046            }
1047
1048            #[inline]
1049            pub fn component_min(&self) -> $t {
1050                self.x.min(self.y).min(self.z).min(self.w)
1051            }
1052
1053            #[inline]
1054            pub fn zero() -> Self {
1055                Self::broadcast(0 as $t)
1056            }
1057
1058            #[inline]
1059            pub fn one() -> Self {
1060                Self::broadcast(1 as $t)
1061            }
1062
1063            #[inline]
1064            pub fn xy(&self) -> $v2t {
1065                $v2t::new(self.x, self.y)
1066            }
1067
1068            #[inline]
1069            pub fn xyz(&self) -> $v3t {
1070                $v3t::new(self.x, self.y, self.z)
1071            }
1072
1073
1074            #[inline]
1075            pub fn layout() -> alloc::alloc::Layout {
1076                alloc::alloc::Layout::from_size_align(std::mem::size_of::<Self>(), std::mem::align_of::<$t>()).unwrap()
1077            }
1078
1079            #[inline]
1080            pub fn as_slice(&self) -> &[$t] {
1081                // This is safe because we are statically bounding our slices to the size of these
1082                // vectors
1083                unsafe {
1084                    std::slice::from_raw_parts(self as *const $n as *const $t, 4)
1085                }
1086            }
1087
1088            #[inline]
1089            pub fn as_array(&self) -> [$t; 4] {
1090                use std::convert::TryInto;
1091                self.as_slice().try_into().unwrap()
1092            }
1093
1094            #[inline]
1095            pub fn as_byte_slice(&self) -> &[u8] {
1096                // This is safe because we are statically bounding our slices to the size of these
1097                // vectors
1098                unsafe {
1099                    std::slice::from_raw_parts(self as *const $n as *const u8, 4 * std::mem::size_of::<$t>())
1100                }
1101            }
1102
1103            #[inline]
1104            pub fn as_mut_slice(&mut self) -> &mut [$t] {
1105                // This is safe because we are statically bounding our slices to the size of these
1106                // vectors
1107                unsafe {
1108                    std::slice::from_raw_parts_mut(self as *mut $n as *mut $t, 4)
1109                }
1110            }
1111
1112            #[inline]
1113            pub fn as_mut_byte_slice(&mut self) -> &mut [u8] {
1114                // This is safe because we are statically bounding our slices to the size of these
1115                // vectors
1116                unsafe {
1117                    std::slice::from_raw_parts_mut(self as *mut $n as *mut u8, 4 * std::mem::size_of::<$t>())
1118                }
1119            }
1120
1121            /// Returns a constant unsafe pointer to the underlying data in the underlying type.
1122            /// This function is safe because all types here are repr(C) and can be represented
1123            /// as their underlying type.
1124            ///
1125            /// # Safety
1126            ///
1127            /// It is up to the caller to correctly use this pointer and its bounds.
1128            #[inline]
1129            pub fn as_ptr(&self) -> *const $t {
1130                self as *const $n as *const $t
1131            }
1132
1133            /// Returns a mutable unsafe pointer to the underlying data in the underlying type.
1134            /// This function is safe because all types here are repr(C) and can be represented
1135            /// as their underlying type.
1136            ///
1137            /// # Safety
1138            ///
1139            /// It is up to the caller to correctly use this pointer and its bounds.
1140            #[inline]
1141            pub fn as_mut_ptr(&mut self) -> *mut $t {
1142                self as *mut $n as *mut $t
1143            }
1144        }
1145
1146        impl From<[$t; 4]> for $n {
1147            #[inline]
1148            fn from(comps: [$t; 4]) -> Self {
1149                Self::new(comps[0], comps[1], comps[2], comps[3])
1150            }
1151        }
1152
1153        impl From<$n> for [$t; 4] {
1154            #[inline]
1155            fn from(v: $n) -> Self {
1156                [v.x, v.y, v.z, v.w]
1157            }
1158        }
1159
1160        impl From<&[$t; 4]> for $n {
1161            #[inline]
1162            fn from(comps: &[$t; 4]) -> Self {
1163                Self::from(*comps)
1164            }
1165        }
1166
1167        impl From<&mut [$t; 4]> for $n {
1168            #[inline]
1169            fn from(comps: &mut [$t; 4]) -> Self {
1170                Self::from(*comps)
1171            }
1172        }
1173
1174        impl From<($t, $t, $t, $t)> for $n {
1175            #[inline]
1176            fn from(comps: ($t, $t, $t, $t)) -> Self {
1177                Self::new(comps.0, comps.1, comps.2, comps.3)
1178            }
1179        }
1180
1181        impl From<&($t, $t, $t, $t)> for $n {
1182            #[inline]
1183            fn from(comps: &($t, $t, $t, $t)) -> Self {
1184                Self::from(*comps)
1185            }
1186        }
1187
1188        impl From<$n> for ($t, $t, $t, $t) {
1189            #[inline]
1190            fn from(v: $n) -> Self {
1191                (v.x, v.y, v.z, v.w)
1192            }
1193        }
1194
1195        impl Add for $n {
1196            type Output = Self;
1197            #[inline]
1198            fn add(self, rhs: $n) -> Self {
1199                $n::new(self.x + rhs.x, self.y + rhs.y, self.z + rhs.z, self.w + rhs.w)
1200            }
1201        }
1202
1203        impl AddAssign for $n {
1204            #[inline]
1205            fn add_assign(&mut self, rhs: $n) {
1206                self.x += rhs.x;
1207                self.y += rhs.y;
1208                self.z += rhs.z;
1209                self.w += rhs.w;
1210            }
1211        }
1212
1213        impl Sub for $n {
1214            type Output = Self;
1215            #[inline]
1216            fn sub(self, rhs: $n) -> Self {
1217                $n::new(self.x - rhs.x, self.y - rhs.y, self.z - rhs.z, self.w - rhs.w)
1218            }
1219        }
1220
1221        impl SubAssign for $n {
1222            #[inline]
1223            fn sub_assign(&mut self, rhs: $n) {
1224                self.x -= rhs.x;
1225                self.y -= rhs.y;
1226                self.z -= rhs.z;
1227                self.w -= rhs.w;
1228            }
1229        }
1230
1231        impl Mul for $n {
1232            type Output = Self;
1233            #[inline]
1234            fn mul(self, rhs: $n) -> Self {
1235                $n::new(self.x * rhs.x, self.y * rhs.y, self.z * rhs.z, self.w * rhs. w)
1236            }
1237        }
1238
1239        impl Mul<$n> for $t {
1240            type Output = $n;
1241            #[inline]
1242            fn mul(self, rhs: $n) -> $n {
1243                $n::new(self * rhs.x, self * rhs.y, self * rhs.z, self * rhs.w)
1244            }
1245        }
1246
1247        impl Mul<$t> for $n {
1248            type Output = $n;
1249            #[inline]
1250            fn mul(self, rhs: $t) -> $n {
1251                $n::new(self.x * rhs, self.y * rhs, self.z * rhs, self.w * rhs)
1252            }
1253        }
1254
1255        impl MulAssign for $n {
1256            #[inline]
1257            fn mul_assign(&mut self, rhs: $n) {
1258                self.x *= rhs.x;
1259                self.y *= rhs.y;
1260                self.z *= rhs.z;
1261                self.w *= rhs.w;
1262            }
1263        }
1264
1265        impl MulAssign<$t> for $n {
1266            #[inline]
1267            fn mul_assign(&mut self, rhs: $t) {
1268                self.x *= rhs;
1269                self.y *= rhs;
1270                self.z *= rhs;
1271                self.w *= rhs;
1272            }
1273        }
1274
1275        impl Div for $n {
1276            type Output = Self;
1277            #[inline]
1278            fn div(self, rhs: $n) -> Self {
1279                $n::new(self.x / rhs.x, self.y / rhs.y, self.z / rhs.z, self.w / rhs.w)
1280            }
1281        }
1282
1283        impl Div<$t> for $n {
1284            type Output = $n;
1285            #[inline]
1286            fn div(self, rhs: $t) -> $n {
1287                $n::new(self.x / rhs, self.y / rhs, self.z / rhs, self.w / rhs)
1288            }
1289        }
1290
1291        impl DivAssign for $n {
1292            #[inline]
1293            fn div_assign(&mut self, rhs: $n) {
1294                self.x /= rhs.x;
1295                self.y /= rhs.y;
1296                self.z /= rhs.z;
1297                self.w /= rhs.w;
1298            }
1299        }
1300
1301        impl DivAssign<$t> for $n {
1302            #[inline]
1303            fn div_assign(&mut self, rhs: $t) {
1304                self.x /= rhs;
1305                self.y /= rhs;
1306                self.z /= rhs;
1307                self.w /= rhs;
1308            }
1309        }
1310
1311        impl Index<usize> for $n {
1312            type Output = $t;
1313
1314            fn index(&self, index: usize) -> &Self::Output {
1315                match index {
1316                    0 => &self.x,
1317                    1 => &self.y,
1318                    2 => &self.z,
1319                    3 => &self.w,
1320                    _ => panic!("Invalid for vector of type: {}", std::any::type_name::<$n>()),
1321                }
1322            }
1323        }
1324
1325        impl IndexMut<usize> for $n {
1326            fn index_mut(&mut self, index: usize) -> &mut Self::Output {
1327                match index {
1328                    0 => &mut self.x,
1329                    1 => &mut self.y,
1330                    2 => &mut self.z,
1331                    3 => &mut self.w,
1332                    _ => panic!("Invalid for vector of type: {}", std::any::type_name::<$n>()),
1333                }
1334            }
1335        }
1336
1337        impl std::iter::Sum<$n> for $n {
1338            fn sum<I>(iter: I) -> Self where I: Iterator<Item = Self> {
1339                iter.fold($n::zero(), Add::add)
1340            }
1341        }
1342        )+
1343    }
1344}
1345
1346impl Neg for IVec2 {
1347    type Output = Self;
1348
1349    #[inline]
1350    fn neg(self) -> Self::Output {
1351        Self {
1352            x: -self.x,
1353            y: -self.y,
1354        }
1355    }
1356}
1357
1358impl Neg for IVec3 {
1359    type Output = Self;
1360
1361    #[inline]
1362    fn neg(self) -> Self::Output {
1363        Self {
1364            x: -self.x,
1365            y: -self.y,
1366            z: -self.z,
1367        }
1368    }
1369}
1370
1371impl Neg for IVec4 {
1372    type Output = Self;
1373
1374    #[inline]
1375    fn neg(self) -> Self::Output {
1376        Self {
1377            x: -self.x,
1378            y: -self.y,
1379            z: -self.z,
1380            w: -self.w,
1381        }
1382    }
1383}
1384
1385impl From<UVec3> for UVec2 {
1386    #[inline]
1387    fn from(vec: UVec3) -> Self {
1388        Self { x: vec.x, y: vec.y }
1389    }
1390}
1391
1392impl From<UVec3> for UVec4 {
1393    #[inline]
1394    fn from(vec: UVec3) -> Self {
1395        Self {
1396            x: vec.x,
1397            y: vec.y,
1398            z: vec.z,
1399            w: 0,
1400        }
1401    }
1402}
1403
1404impl From<UVec4> for UVec3 {
1405    #[inline]
1406    fn from(vec: UVec4) -> Self {
1407        Self {
1408            x: vec.x,
1409            y: vec.y,
1410            z: vec.z,
1411        }
1412    }
1413}
1414
1415impl From<IVec3> for IVec2 {
1416    #[inline]
1417    fn from(vec: IVec3) -> Self {
1418        Self { x: vec.x, y: vec.y }
1419    }
1420}
1421
1422impl From<IVec3> for IVec4 {
1423    #[inline]
1424    fn from(vec: IVec3) -> Self {
1425        Self {
1426            x: vec.x,
1427            y: vec.y,
1428            z: vec.z,
1429            w: 0,
1430        }
1431    }
1432}
1433
1434impl From<IVec4> for IVec3 {
1435    #[inline]
1436    fn from(vec: IVec4) -> Self {
1437        Self {
1438            x: vec.x,
1439            y: vec.y,
1440            z: vec.z,
1441        }
1442    }
1443}
1444
1445impl TryFrom<UVec3> for IVec3 {
1446    type Error = <i32 as TryFrom<u32>>::Error;
1447
1448    fn try_from(rhv: UVec3) -> Result<Self, Self::Error> {
1449        Ok(Self {
1450            x: rhv.x.try_into()?,
1451            y: rhv.y.try_into()?,
1452            z: rhv.z.try_into()?,
1453        })
1454    }
1455}
1456
1457impl TryFrom<IVec3> for UVec3 {
1458    type Error = <u32 as TryFrom<i32>>::Error;
1459
1460    fn try_from(rhv: IVec3) -> Result<Self, Self::Error> {
1461        Ok(Self {
1462            x: rhv.x.try_into()?,
1463            y: rhv.y.try_into()?,
1464            z: rhv.z.try_into()?,
1465        })
1466    }
1467}
1468
1469/// A macro to implement abs for unsigned and signed IVecs
1470/// the attributes (x, y, z etc.) must be given in the correct order.
1471/// example macro use:
1472/// impl_abs!(IVec2 => [x, y]);
1473/// or for unsigned
1474/// impl_abs!(UVec2 => [x, y] nosign);
1475macro_rules! impl_abs {
1476    ($n:ident => [$($var:ident),*]) => {
1477        impl $n {
1478            #[inline]
1479            pub fn abs(&self) -> Self {
1480                Self::new($(self.$var.abs(),)* )
1481            }
1482        }
1483    };
1484    ($n:ident => [$($var:ident),*] nosign) => {
1485        impl $n {
1486            #[inline]
1487            pub fn abs(&self) -> Self {
1488                Self::new($(self.$var,)* )
1489            }
1490        }
1491    }
1492}
1493
1494ivec2s!((UVec2, UVec3, UVec4) => u32);
1495ivec2s!((IVec2, IVec3, IVec4) => i32);
1496
1497ivec3s!((UVec2, UVec3, UVec4) => u32);
1498ivec3s!((IVec2, IVec3, IVec4) => i32);
1499
1500ivec4s!(UVec4, UVec2, UVec3 => u32);
1501ivec4s!(IVec4, IVec2, IVec3 => i32);
1502
1503impl_abs!(IVec2 => [x, y]);
1504impl_abs!(IVec3 => [x, y, z]);
1505impl_abs!(IVec4 => [x, y, z, w]);
1506impl_abs!(UVec2 => [x, y] nosign);
1507impl_abs!(UVec3 => [x, y, z] nosign);
1508impl_abs!(UVec4 => [x, y, z, w] nosign);