1use crate::*;
2use std::convert::{TryFrom, TryInto};
3use std::ops::*;
4
5pub trait MulAdd<A = Self, B = Self> {
6 type Output;
8
9 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 #[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 #[inline]
69 pub fn into_homogeneous_point(self) -> $v3t {
70 $v3t { x: self.x, y: self.y, z: 1 }
71 }
72
73 #[inline]
76 pub fn into_homogeneous_vector(self) -> $v3t {
77 $v3t { x: self.x, y: self.y, z: 0 }
78 }
79
80 #[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 #[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 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 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 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 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 #[inline]
253 pub fn as_ptr(&self) -> *const $t {
254 self as *const $n as *const $t
255 }
256
257 #[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 $(#[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 #[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 #[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 #[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 #[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 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 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 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 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 #[inline]
701 pub fn as_ptr(&self) -> *const $t {
702 self as *const $n as *const $t
703 }
704
705 #[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 $(#[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 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 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 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 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 #[inline]
1129 pub fn as_ptr(&self) -> *const $t {
1130 self as *const $n as *const $t
1131 }
1132
1133 #[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
1469macro_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);