1use std::ops::*;
2
3use crate::util::EqualsEps;
4use crate::*;
5
6macro_rules! vec4s {
7 ($($n:ident, $v2t:ident, $v3t:ident => $t:ident),+) => {
8 $(#[derive(Clone, Copy, Debug, Default, PartialEq)]
15 #[repr(C)]
16 pub struct $n {
17 pub x: $t,
18 pub y: $t,
19 pub z: $t,
20 pub w: $t,
21 }
22
23 impl $n {
24 #[inline]
25 pub const fn new(x: $t, y: $t, z: $t, w: $t) -> Self {
26 $n { x, y, z, w }
27 }
28
29 #[inline]
30 pub const fn broadcast(val: $t) -> Self {
31 Self::new(val, val, val, val)
32 }
33
34 #[inline]
35 pub fn unit_x() -> Self {
36 $n{ x: $t::splat(1.0), y: $t::splat(0.0), z: $t::splat(0.0), w: $t::splat(0.0) }
37 }
38
39 #[inline]
40 pub fn unit_y() -> Self {
41 $n{ x: $t::splat(0.0), y: $t::splat(1.0), z: $t::splat(0.0), w: $t::splat(0.0) }
42 }
43
44 #[inline]
45 pub fn unit_z() -> Self {
46 $n{ x: $t::splat(0.0), y: $t::splat(0.0), z: $t::splat(1.0), w: $t::splat(0.0) }
47 }
48
49 #[inline]
50 pub fn unit_w() -> Self {
51 $n{ x: $t::splat(0.0), y: $t::splat(0.0), z: $t::splat(0.0), w: $t::splat(1.0) }
52 }
53
54 #[inline]
55 pub fn dot(&self, other: $n) -> $t {
56 (self.x * other.x) + (self.y * other.y) + (self.z * other.z) + (self.w * other.w)
57 }
58
59 #[inline]
60 pub fn reflect(&mut self, normal: $n) {
61 *self -= $t::splat(2.0) * self.dot(normal) * normal;
62 }
63
64 #[inline]
65 pub fn reflected(&self, normal: $n) -> Self {
66 let mut a = *self;
67 a.reflect(normal);
68 a
69 }
70
71 #[inline]
72 pub fn mag_sq(&self) -> $t {
73 (self.x * self.x) + (self.y * self.y) + (self.z * self.z) + (self.w * self.w)
74 }
75
76 #[inline]
77 pub fn mag(&self) -> $t {
78 self.mag_sq().sqrt()
79 }
80
81 #[inline]
82 pub fn normalize(&mut self) {
83 let r_mag = $t::splat(1.0) / self.mag();
84 self.x *= r_mag;
85 self.y *= r_mag;
86 self.z *= r_mag;
87 self.w *= r_mag;
88 }
89
90 #[inline]
91 #[must_use = "Did you mean to use `.normalize()` to normalize `self` in place?"]
92 pub fn normalized(&self) -> Self {
93 let mut r = self.clone();
94 r.normalize();
95 r
96 }
97
98 #[inline]
101 pub fn normalize_homogeneous_point(&mut self) {
102 let recip_z = $t::splat(1.0) / self.w;
103 self.x *= recip_z;
104 self.y *= recip_z;
105 self.z *= recip_z;
106 self.w = $t::splat(1.0);
107 }
108
109 #[must_use = "Did you mean to use `.normalize_homogeneous_point()` to normalize `self` in place?"]
112 #[inline]
113 pub fn normalized_homogeneous_point(&self) -> Self{
114 let mut r = self.clone();
115 r.normalize_homogeneous_point();
116 r
117 }
118
119 #[inline]
121 pub fn truncated(&self) -> $v3t {
122 $v3t::new(
123 self.x,
124 self.y,
125 self.z
126 )
127 }
128
129 #[inline]
130 pub fn mul_add(&self, mul: $n, add: $n) -> Self {
131 $n::new(
132 self.x.mul_add(mul.x, add.x),
133 self.y.mul_add(mul.y, add.y),
134 self.z.mul_add(mul.z, add.z),
135 self.w.mul_add(mul.w, add.w),
136 )
137 }
138
139 #[inline]
140 pub fn abs(&self) -> Self {
141 Self::new(self.x.abs(), self.y.abs(), self.z.abs(), self.w.abs())
142 }
143
144 #[inline]
145 pub fn clamp(&mut self, min: Self, max: Self) {
146 self.x = self.x.max(min.x).min(max.x);
147 self.y = self.y.max(min.y).min(max.y);
148 self.z = self.z.max(min.z).min(max.z);
149 self.w = self.w.max(min.w).min(max.w);
150 }
151
152 #[inline]
153 pub fn clamped(mut self, min: Self, max: Self) -> Self {
154 self.clamp(min, max);
155 self
156 }
157
158 #[inline]
159 pub fn map<F>(&self, mut f: F) -> Self
160 where F: FnMut($t) -> $t
161 {
162 $n::new(
163 f(self.x),
164 f(self.y),
165 f(self.z),
166 f(self.w),
167 )
168 }
169
170 #[inline]
171 pub fn apply<F>(&mut self, mut f: F)
172 where F: FnMut($t) -> $t
173 {
174 self.x = f(self.x);
175 self.y = f(self.y);
176 self.z = f(self.z);
177 self.w = f(self.w);
178 }
179
180 #[inline]
181 pub fn max_by_component(mut self, other: Self) -> Self {
182 self.x = self.x.max(other.x);
183 self.y = self.y.max(other.y);
184 self.z = self.z.max(other.z);
185 self.w = self.w.max(other.w);
186 self
187 }
188
189 #[inline]
190 pub fn min_by_component(mut self, other: Self) -> Self {
191 self.x = self.x.min(other.x);
192 self.y = self.y.min(other.y);
193 self.z = self.z.min(other.z);
194 self.w = self.w.min(other.w);
195 self
196 }
197
198 #[inline]
199 pub fn component_max(&self) -> $t {
200 self.x.max(self.y).max(self.z).max(self.w)
201 }
202
203 #[inline]
204 pub fn component_min(&self) -> $t {
205 self.x.min(self.y).min(self.z).min(self.w)
206 }
207
208 #[inline]
209 pub fn zero() -> Self {
210 Self::broadcast($t::splat(0.0))
211 }
212
213 #[inline]
214 pub fn one() -> Self {
215 Self::broadcast($t::splat(1.0))
216 }
217
218 #[inline]
219 pub const fn xy(&self) -> $v2t {
220 $v2t::new(self.x, self.y)
221 }
222
223 #[inline]
224 pub const fn xyz(&self) -> $v3t {
225 $v3t::new(self.x, self.y, self.z)
226 }
227
228 #[inline]
230 pub fn layout() -> alloc::alloc::Layout {
231 alloc::alloc::Layout::from_size_align(std::mem::size_of::<Self>(), std::mem::align_of::<$t>()).unwrap()
232 }
233
234 #[inline]
236 pub fn as_array(&self) -> &[$t; 4] {
237 let ptr = self as *const $n as *const [$t; 4];
238 unsafe { &*ptr }
239 }
240
241 #[inline]
243 pub fn as_mut_array(&mut self) -> &mut [$t; 4] {
244 let ptr = self as *mut $n as *mut [$t; 4];
245 unsafe { &mut *ptr }
246 }
247
248 #[inline]
250 pub fn as_slice(&self) -> &[$t] {
251 unsafe {
254 std::slice::from_raw_parts(self as *const $n as *const $t, 4)
255 }
256 }
257
258 #[inline]
260 pub fn as_mut_slice(&mut self) -> &mut [$t] {
261 unsafe {
264 std::slice::from_raw_parts_mut(self as *mut $n as *mut $t, 4)
265 }
266 }
267
268 #[inline]
269 pub fn as_byte_slice(&self) -> &[u8] {
270 unsafe {
273 std::slice::from_raw_parts(self as *const $n as *const u8, 4 * std::mem::size_of::<$t>())
274 }
275 }
276
277 #[inline]
278 pub fn as_mut_byte_slice(&mut self) -> &mut [u8] {
279 unsafe {
282 std::slice::from_raw_parts_mut(self as *mut $n as *mut u8, 4 * std::mem::size_of::<$t>())
283 }
284 }
285
286 #[inline]
294 pub const fn as_ptr(&self) -> *const $t {
295 self as *const $n as *const $t
296 }
297
298 #[inline]
306 pub fn as_mut_ptr(&mut self) -> *mut $t {
307 self as *mut $n as *mut $t
308 }
309 }
310
311 impl EqualsEps for $n {
312 fn eq_eps(self, other: Self) -> bool {
313 self.x.eq_eps(other.x) && self.y.eq_eps(other.y) && self.z.eq_eps(other.z) && self.w.eq_eps(other.w)
314 }
315 }
316
317 impl From<$n> for [$t; 4] {
318 #[inline]
319 fn from(v: $n) -> Self {
320 [v.x, v.y, v.z, v.w]
321 }
322 }
323
324 impl From<[$t; 4]> for $n {
325 #[inline]
326 fn from(comps: [$t; 4]) -> Self {
327 Self::new(comps[0], comps[1], comps[2], comps[3])
328 }
329 }
330
331 impl From<&[$t; 4]> for $n {
332 #[inline]
333 fn from(comps: &[$t; 4]) -> Self {
334 Self::from(*comps)
335 }
336 }
337
338 impl From<&mut [$t; 4]> for $n {
339 #[inline]
340 fn from(comps: &mut [$t; 4]) -> Self {
341 Self::from(*comps)
342 }
343 }
344
345 impl From<($t, $t, $t, $t)> for $n {
346 #[inline]
347 fn from(comps: ($t, $t, $t, $t)) -> Self {
348 Self::new(comps.0, comps.1, comps.2, comps.3)
349 }
350 }
351
352 impl From<&($t, $t, $t, $t)> for $n {
353 #[inline]
354 fn from(comps: &($t, $t, $t, $t)) -> Self {
355 Self::from(*comps)
356 }
357 }
358
359 impl From<$n> for ($t, $t, $t, $t) {
360 #[inline]
361 fn from(v: $n) -> Self {
362 (v.x, v.y, v.z, v.w)
363 }
364 }
365
366 impl Add for $n {
367 type Output = Self;
368 #[inline]
369 fn add(self, rhs: $n) -> Self {
370 $n::new(self.x + rhs.x, self.y + rhs.y, self.z + rhs.z, self.w + rhs.w)
371 }
372 }
373
374 impl AddAssign for $n {
375 #[inline]
376 fn add_assign(&mut self, rhs: $n) {
377 self.x += rhs.x;
378 self.y += rhs.y;
379 self.z += rhs.z;
380 self.w += rhs.w;
381 }
382 }
383
384 impl Sub for $n {
385 type Output = Self;
386 #[inline]
387 fn sub(self, rhs: $n) -> Self {
388 $n::new(self.x - rhs.x, self.y - rhs.y, self.z - rhs.z, self.w - rhs.w)
389 }
390 }
391
392 impl SubAssign for $n {
393 #[inline]
394 fn sub_assign(&mut self, rhs: $n) {
395 self.x -= rhs.x;
396 self.y -= rhs.y;
397 self.z -= rhs.z;
398 self.w -= rhs.w;
399 }
400 }
401
402 impl Mul for $n {
403 type Output = Self;
404 #[inline]
405 fn mul(self, rhs: $n) -> Self {
406 $n::new(self.x * rhs.x, self.y * rhs.y, self.z * rhs.z, self.w * rhs. w)
407 }
408 }
409
410 impl Mul<$n> for $t {
411 type Output = $n;
412 #[inline]
413 fn mul(self, rhs: $n) -> $n {
414 $n::new(self * rhs.x, self * rhs.y, self * rhs.z, self * rhs.w)
415 }
416 }
417
418 impl Mul<$t> for $n {
419 type Output = $n;
420 #[inline]
421 fn mul(self, rhs: $t) -> $n {
422 $n::new(self.x * rhs, self.y * rhs, self.z * rhs, self.w * rhs)
423 }
424 }
425
426 impl MulAssign for $n {
427 #[inline]
428 fn mul_assign(&mut self, rhs: $n) {
429 self.x *= rhs.x;
430 self.y *= rhs.y;
431 self.z *= rhs.z;
432 self.w *= rhs.w;
433 }
434 }
435
436 impl MulAssign<$t> for $n {
437 #[inline]
438 fn mul_assign(&mut self, rhs: $t) {
439 self.x *= rhs;
440 self.y *= rhs;
441 self.z *= rhs;
442 self.w *= rhs;
443 }
444 }
445
446 impl Div for $n {
447 type Output = Self;
448 #[inline]
449 fn div(self, rhs: $n) -> Self {
450 $n::new(self.x / rhs.x, self.y / rhs.y, self.z / rhs.z, self.w / rhs.w)
451 }
452 }
453
454 impl Div<$t> for $n {
455 type Output = $n;
456 #[inline]
457 fn div(self, rhs: $t) -> $n {
458 $n::new(self.x / rhs, self.y / rhs, self.z / rhs, self.w / rhs)
459 }
460 }
461
462 impl DivAssign for $n {
463 #[inline]
464 fn div_assign(&mut self, rhs: $n) {
465 self.x /= rhs.x;
466 self.y /= rhs.y;
467 self.z /= rhs.z;
468 self.w /= rhs.w;
469 }
470 }
471
472 impl DivAssign<$t> for $n {
473 #[inline]
474 fn div_assign(&mut self, rhs: $t) {
475 self.x /= rhs;
476 self.y /= rhs;
477 self.z /= rhs;
478 self.w /= rhs;
479 }
480 }
481
482 impl Neg for $n {
483 type Output = $n;
484 #[inline]
485 fn neg(self) -> $n {
486 self * $t::splat(-1.0)
487 }
488 }
489
490 impl Index<usize> for $n {
491 type Output = $t;
492
493 fn index(&self, index: usize) -> &Self::Output {
494 match index {
495 0 => &self.x,
496 1 => &self.y,
497 2 => &self.z,
498 3 => &self.w,
499 _ => panic!("Invalid for vector of type: {}", std::any::type_name::<$n>()),
500 }
501 }
502 }
503
504 impl IndexMut<usize> for $n {
505 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
506 match index {
507 0 => &mut self.x,
508 1 => &mut self.y,
509 2 => &mut self.z,
510 3 => &mut self.w,
511 _ => panic!("Invalid for vector of type: {}", std::any::type_name::<$n>()),
512 }
513 }
514 }
515
516 impl std::iter::Sum<$n> for $n {
517 fn sum<I>(iter: I) -> Self where I: Iterator<Item = Self> {
518 let mut sum = $n::zero();
521 let mut c = $n::zero();
522 for v in iter {
523 let y = v - c;
524 let t = sum + y;
525 c = (t - sum) - y;
526 sum = t;
527 }
528 sum
529 }
530 }
531 )+
532 }
533}
534
535macro_rules! impl_scalar_vec4s {
538 ($(($vt:ident, $v3t:ident) => $t:ident),+) => {
539 $(impl $vt {
540 #[inline]
541 pub fn refract(&mut self, normal: Self, eta: $t) {
542 *self = self.refracted(normal, eta);
543 }
544
545 #[inline]
546 pub fn refracted(&self, normal: Self, eta: $t) -> Self {
547 let n = normal;
548 let i = *self;
549 let ndi = n.dot(i);
550 let k = 1.0 - eta * eta * (1.0 - ndi * ndi);
551 if k < 0.0 {
552 Self::zero()
553 } else {
554 i * eta - (eta * ndi + k.sqrt()) * n
555 }
556 }
557 }
558
559 impl From<$v3t> for $vt {
560 #[inline]
561 fn from(vec: $v3t) -> Self {
562 Self {
563 x: vec.x,
564 y: vec.y,
565 z: vec.z,
566 w: 0.0,
567 }
568 }
569 })+
570 }
571}
572
573macro_rules! impl_wide_vec4s {
576 ($($vt:ident => $tt:ident, $t:ident, $maskt:ident, $nonwidet:ident, $v3t:ident),+) => {
577 $(impl $vt {
578 #[inline]
579 pub fn new_splat(x: $tt, y: $tt, z: $tt, w: $tt) -> Self {
580 Self {
581 x: $t::splat(x),
582 y: $t::splat(y),
583 z: $t::splat(z),
584 w: $t::splat(w),
585 }
586 }
587
588 #[inline]
589 pub fn splat(vec: $nonwidet) -> Self {
590 Self {
591 x: $t::splat(vec.x),
592 y: $t::splat(vec.y),
593 z: $t::splat(vec.z),
594 w: $t::splat(vec.w),
595 }
596 }
597
598 #[inline]
604 pub fn blend(mask: $maskt, tru: Self, fals: Self) -> Self {
605 Self {
606 x: mask.blend(tru.x, fals.x),
607 y: mask.blend(tru.y, fals.y),
608 z: mask.blend(tru.z, fals.z),
609 w: mask.blend(tru.w, fals.w),
610 }
611 }
612 }
613
614 impl From<$nonwidet> for $vt {
615 #[inline]
616 fn from(vec: $nonwidet) -> Self {
617 Self::splat(vec)
618 }
619 }
620
621 impl From<$v3t> for $vt {
622 #[inline]
623 fn from(vec: $v3t) -> Self {
624 Self {
625 x: vec.x,
626 y: vec.y,
627 z: vec.z,
628 w: $t::splat(0.0),
629 }
630 }
631 })+
632 };
633}
634
635impl From<Vec4x4> for [Vec4; 4] {
636 #[inline]
637 fn from(v: Vec4x4) -> [Vec4; 4] {
638 let xs: [f32; 4] = v.x.into();
639 let ys: [f32; 4] = v.y.into();
640 let zs: [f32; 4] = v.z.into();
641 let ws: [f32; 4] = v.w.into();
642 [
643 Vec4::new(xs[0], ys[0], zs[0], ws[0]),
644 Vec4::new(xs[1], ys[1], zs[1], ws[1]),
645 Vec4::new(xs[2], ys[2], zs[2], ws[2]),
646 Vec4::new(xs[3], ys[3], zs[3], ws[3]),
647 ]
648 }
649}
650
651impl From<[Vec4; 4]> for Vec4x4 {
652 #[inline]
653 fn from(vecs: [Vec4; 4]) -> Self {
654 Self {
655 x: f32x4::from([vecs[0].x, vecs[1].x, vecs[2].x, vecs[3].x]),
656 y: f32x4::from([vecs[0].y, vecs[1].y, vecs[2].y, vecs[3].y]),
657 z: f32x4::from([vecs[0].z, vecs[1].z, vecs[2].z, vecs[3].z]),
658 w: f32x4::from([vecs[0].w, vecs[1].w, vecs[2].w, vecs[3].w]),
659 }
660 }
661}
662
663impl From<Vec4x8> for [Vec4; 8] {
664 #[inline]
665 fn from(v: Vec4x8) -> [Vec4; 8] {
666 let xs: [f32; 8] = v.x.into();
667 let ys: [f32; 8] = v.y.into();
668 let zs: [f32; 8] = v.z.into();
669 let ws: [f32; 8] = v.w.into();
670 [
671 Vec4::new(xs[0], ys[0], zs[0], ws[0]),
672 Vec4::new(xs[1], ys[1], zs[1], ws[1]),
673 Vec4::new(xs[2], ys[2], zs[2], ws[2]),
674 Vec4::new(xs[3], ys[3], zs[3], ws[3]),
675 Vec4::new(xs[4], ys[4], zs[4], ws[4]),
676 Vec4::new(xs[5], ys[5], zs[5], ws[5]),
677 Vec4::new(xs[6], ys[6], zs[6], ws[6]),
678 Vec4::new(xs[7], ys[7], zs[7], ws[7]),
679 ]
680 }
681}
682
683impl From<[Vec4; 8]> for Vec4x8 {
684 #[inline]
685 fn from(vecs: [Vec4; 8]) -> Self {
686 Self {
687 x: f32x8::from([
688 vecs[0].x, vecs[1].x, vecs[2].x, vecs[3].x, vecs[4].x, vecs[5].x, vecs[6].x,
689 vecs[7].x,
690 ]),
691 y: f32x8::from([
692 vecs[0].y, vecs[1].y, vecs[2].y, vecs[3].y, vecs[4].y, vecs[5].y, vecs[6].y,
693 vecs[7].y,
694 ]),
695 z: f32x8::from([
696 vecs[0].z, vecs[1].z, vecs[2].z, vecs[3].z, vecs[4].z, vecs[5].z, vecs[6].z,
697 vecs[7].z,
698 ]),
699 w: f32x8::from([
700 vecs[0].w, vecs[1].w, vecs[2].w, vecs[3].w, vecs[4].w, vecs[5].w, vecs[6].w,
701 vecs[7].w,
702 ]),
703 }
704 }
705}
706
707#[cfg(feature = "f64")]
708impl From<DVec4x2> for [DVec4; 2] {
709 #[inline]
710 fn from(v: DVec4x2) -> Self {
711 let xs: [f64; 2] = v.x.into();
712 let ys: [f64; 2] = v.y.into();
713 let zs: [f64; 2] = v.z.into();
714 let ws: [f64; 2] = v.w.into();
715 [
716 DVec4::new(xs[0], ys[0], zs[0], ws[0]),
717 DVec4::new(xs[1], ys[1], zs[1], ws[1]),
718 ]
719 }
720}
721
722#[cfg(feature = "f64")]
723impl From<[DVec4; 2]> for DVec4x2 {
724 #[inline]
725 fn from(vecs: [DVec4; 2]) -> Self {
726 Self {
727 x: f64x2::from([vecs[0].x, vecs[1].x]),
728 y: f64x2::from([vecs[0].y, vecs[1].y]),
729 z: f64x2::from([vecs[0].z, vecs[1].z]),
730 w: f64x2::from([vecs[0].w, vecs[1].w]),
731 }
732 }
733}
734
735#[cfg(feature = "f64")]
736impl From<DVec4x4> for [DVec4; 4] {
737 #[inline]
738 fn from(v: DVec4x4) -> Self {
739 let xs: [f64; 4] = v.x.into();
740 let ys: [f64; 4] = v.y.into();
741 let zs: [f64; 4] = v.z.into();
742 let ws: [f64; 4] = v.w.into();
743 [
744 DVec4::new(xs[0], ys[0], zs[0], ws[0]),
745 DVec4::new(xs[1], ys[1], zs[1], ws[1]),
746 DVec4::new(xs[2], ys[2], zs[2], ws[2]),
747 DVec4::new(xs[3], ys[3], zs[3], ws[3]),
748 ]
749 }
750}
751
752#[cfg(feature = "f64")]
753impl From<[DVec4; 4]> for DVec4x4 {
754 #[inline]
755 fn from(vecs: [DVec4; 4]) -> Self {
756 Self {
757 x: f64x4::from([vecs[0].x, vecs[1].x, vecs[2].x, vecs[3].x]),
758 y: f64x4::from([vecs[0].y, vecs[1].y, vecs[2].y, vecs[3].y]),
759 z: f64x4::from([vecs[0].z, vecs[1].z, vecs[2].z, vecs[3].z]),
760 w: f64x4::from([vecs[0].w, vecs[1].w, vecs[2].w, vecs[3].w]),
761 }
762 }
763}
764
765vec4s!(
766 Vec4, Vec2, Vec3 => f32,
767 Vec4x4, Vec2x4, Vec3x4 => f32x4,
768 Vec4x8, Vec2x8, Vec3x8 => f32x8
769);
770
771#[cfg(feature = "f64")]
772vec4s!(
773 DVec4, DVec2, DVec3 => f64,
774 DVec4x2, DVec2x2, DVec3x2 => f64x2,
775 DVec4x4, DVec2x4, DVec3x4 => f64x4
776);
777
778impl_scalar_vec4s!(
779 (Vec4, Vec3) => f32
780);
781
782#[cfg(feature = "f64")]
783impl_scalar_vec4s!(
784 (DVec4, DVec3) => f64
785);
786
787impl_wide_vec4s!(
788 Vec4x4 => f32, f32x4, m32x4, Vec4, Vec3x4,
789 Vec4x8 => f32, f32x8, m32x8, Vec4, Vec3x8
790);
791
792#[cfg(feature = "f64")]
793impl_wide_vec4s!(
794 DVec4x2 => f64, f64x2, m64x2, DVec4, DVec3x2,
795 DVec4x4 => f64, f64x4, m64x4, DVec4, DVec3x4
796);