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