1use bincode::{Decode, Encode};
18use serde::{Deserialize, Serialize};
19
20use super::EPSILON;
21use std::ops::{Add, Div, Index, IndexMut, Mul, Neg, Sub};
22
23#[derive(
27 Debug,
28 Default,
29 Copy,
30 Clone,
31 PartialEq,
32 bytemuck::Pod,
33 bytemuck::Zeroable,
34 Serialize,
35 Deserialize,
36 Encode,
37 Decode,
38)]
39#[repr(C)]
40pub struct Vec2 {
41 pub x: f32,
43 pub y: f32,
45}
46
47impl Vec2 {
48 pub const ZERO: Self = Self { x: 0.0, y: 0.0 };
50 pub const ONE: Self = Self { x: 1.0, y: 1.0 };
52 pub const X: Self = Self { x: 1.0, y: 0.0 };
54 pub const Y: Self = Self { x: 0.0, y: 1.0 };
56
57 #[inline]
59 pub const fn new(x: f32, y: f32) -> Self {
60 Self { x, y }
61 }
62
63 #[inline]
65 pub const fn abs(self) -> Self {
66 Self {
67 x: if self.x < 0.0 { -self.x } else { self.x },
68 y: if self.y < 0.0 { -self.y } else { self.y },
69 }
70 }
71
72 #[inline]
75 pub fn length_squared(&self) -> f32 {
76 self.dot(*self)
77 }
78
79 #[inline]
81 pub fn length(&self) -> f32 {
82 self.length_squared().sqrt()
83 }
84
85 #[inline]
88 pub fn normalize(&self) -> Self {
89 let len_sq = self.length_squared();
90 if len_sq > EPSILON * EPSILON {
91 *self * (1.0 / len_sq.sqrt())
92 } else {
93 Self::ZERO
94 }
95 }
96
97 #[inline]
99 pub fn dot(&self, rhs: Self) -> f32 {
100 self.x * rhs.x + self.y * rhs.y
101 }
102
103 #[inline]
106 pub fn lerp(start: Self, end: Self, t: f32) -> Self {
107 start + (end - start) * t.clamp(0.0, 1.0)
108 }
109
110 #[inline]
112 pub fn to_array(self) -> [f32; 2] {
113 [self.x, self.y]
114 }
115}
116
117impl From<Vec2> for [f32; 2] {
118 #[inline]
119 fn from(v: Vec2) -> Self {
120 [v.x, v.y]
121 }
122}
123
124impl From<[f32; 2]> for Vec2 {
125 #[inline]
126 fn from(v: [f32; 2]) -> Self {
127 Self::new(v[0], v[1])
128 }
129}
130
131impl Add for Vec2 {
134 type Output = Self;
135 #[inline]
137 fn add(self, rhs: Self) -> Self::Output {
138 Self {
139 x: self.x + rhs.x,
140 y: self.y + rhs.y,
141 }
142 }
143}
144
145impl Sub for Vec2 {
146 type Output = Self;
147 #[inline]
149 fn sub(self, rhs: Self) -> Self::Output {
150 Self {
151 x: self.x - rhs.x,
152 y: self.y - rhs.y,
153 }
154 }
155}
156
157impl Mul<f32> for Vec2 {
158 type Output = Self;
159 #[inline]
161 fn mul(self, rhs: f32) -> Self::Output {
162 Self {
163 x: self.x * rhs,
164 y: self.y * rhs,
165 }
166 }
167}
168
169impl Mul<Vec2> for f32 {
170 type Output = Vec2;
171 #[inline]
173 fn mul(self, rhs: Vec2) -> Self::Output {
174 rhs * self
175 }
176}
177
178impl Mul<Vec2> for Vec2 {
179 type Output = Self;
180 #[inline]
182 fn mul(self, rhs: Vec2) -> Self::Output {
183 Self {
184 x: self.x * rhs.x,
185 y: self.y * rhs.y,
186 }
187 }
188}
189
190impl Div<f32> for Vec2 {
191 type Output = Self;
192 #[inline]
194 fn div(self, rhs: f32) -> Self::Output {
195 let inv_rhs = 1.0 / rhs;
196 Self {
197 x: self.x * inv_rhs,
198 y: self.y * inv_rhs,
199 }
200 }
201}
202
203impl Neg for Vec2 {
204 type Output = Self;
205 #[inline]
207 fn neg(self) -> Self::Output {
208 Self {
209 x: -self.x,
210 y: -self.y,
211 }
212 }
213}
214
215impl Index<usize> for Vec2 {
216 type Output = f32;
217 #[inline]
222 fn index(&self, index: usize) -> &Self::Output {
223 match index {
224 0 => &self.x,
225 1 => &self.y,
226 _ => panic!("Index out of bounds for Vec2"),
227 }
228 }
229}
230
231impl IndexMut<usize> for Vec2 {
232 #[inline]
237 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
238 match index {
239 0 => &mut self.x,
240 1 => &mut self.y,
241 _ => panic!("Index out of bounds for Vec2"),
242 }
243 }
244}
245
246#[derive(
274 Debug,
275 Clone,
276 Copy,
277 PartialEq,
278 bytemuck::Pod,
279 bytemuck::Zeroable,
280 Serialize,
281 Deserialize,
282 Encode,
283 Decode,
284)]
285#[repr(C)]
286pub struct Vec3 {
287 pub x: f32,
289 pub y: f32,
291 pub z: f32,
293}
294
295impl Vec3 {
296 pub const ZERO: Self = Self {
298 x: 0.0,
299 y: 0.0,
300 z: 0.0,
301 };
302 pub const ONE: Self = Self {
304 x: 1.0,
305 y: 1.0,
306 z: 1.0,
307 };
308 pub const X: Self = Self {
310 x: 1.0,
311 y: 0.0,
312 z: 0.0,
313 };
314 pub const Y: Self = Self {
316 x: 0.0,
317 y: 1.0,
318 z: 0.0,
319 };
320 pub const Z: Self = Self {
322 x: 0.0,
323 y: 0.0,
324 z: 1.0,
325 };
326 pub const NEG_X: Self = Self {
328 x: -1.0,
329 y: 0.0,
330 z: 0.0,
331 };
332 pub const NEG_Y: Self = Self {
334 x: 0.0,
335 y: -1.0,
336 z: 0.0,
337 };
338 pub const NEG_Z: Self = Self {
340 x: 0.0,
341 y: 0.0,
342 z: -1.0,
343 };
344
345 #[inline]
347 pub const fn new(x: f32, y: f32, z: f32) -> Self {
348 Self { x, y, z }
349 }
350
351 #[inline]
353 pub const fn abs(self) -> Self {
354 Self {
355 x: if self.x < 0.0 { -self.x } else { self.x },
356 y: if self.y < 0.0 { -self.y } else { self.y },
357 z: if self.z < 0.0 { -self.z } else { self.z },
358 }
359 }
360
361 #[inline]
367 pub fn max_element(self) -> f32 {
368 self.x.max(self.y).max(self.z)
369 }
370
371 #[inline]
373 pub fn min_element(self) -> f32 {
374 self.x.min(self.y).min(self.z)
375 }
376
377 #[inline]
379 pub fn length_squared(&self) -> f32 {
380 self.dot(*self)
381 }
382
383 #[inline]
385 pub fn length(&self) -> f32 {
386 self.length_squared().sqrt()
387 }
388
389 #[inline]
391 pub fn normalize(&self) -> Self {
392 let len_sq = self.length_squared();
393 if len_sq > EPSILON * EPSILON {
394 *self * (1.0 / len_sq.sqrt())
397 } else {
398 Self::ZERO
399 }
400 }
401
402 #[inline]
404 pub fn dot(&self, other: Self) -> f32 {
405 self.x * other.x + self.y * other.y + self.z * other.z
406 }
407
408 #[inline]
410 pub fn cross(&self, other: Self) -> Self {
411 Self {
412 x: self.y * other.z - self.z * other.y,
413 y: self.z * other.x - self.x * other.z,
414 z: self.x * other.y - self.y * other.x,
415 }
416 }
417
418 #[inline]
420 pub fn distance_squared(&self, other: Self) -> f32 {
421 let dx = self.x - other.x;
422 let dy = self.y - other.y;
423 let dz = self.z - other.z;
424 dx * dx + dy * dy + dz * dz
425 }
426
427 #[inline]
429 pub fn distance(&self, other: Self) -> f32 {
430 self.distance_squared(other).sqrt()
431 }
432
433 #[inline]
435 pub fn lerp(start: Self, end: Self, t: f32) -> Self {
436 Self {
437 x: start.x + (end.x - start.x) * t,
438 y: start.y + (end.y - start.y) * t,
439 z: start.z + (end.z - start.z) * t,
440 }
441 }
442
443 #[inline]
448 pub fn get(&self, index: usize) -> f32 {
449 match index {
450 0 => self.x,
451 1 => self.y,
452 2 => self.z,
453 _ => panic!("Index out of bounds for Vec3"),
454 }
455 }
456}
457
458impl Default for Vec3 {
461 #[inline]
463 fn default() -> Self {
464 Self::ZERO
465 }
466}
467
468impl Add for Vec3 {
469 type Output = Self;
470 #[inline]
472 fn add(self, rhs: Self) -> Self::Output {
473 Self {
474 x: self.x + rhs.x,
475 y: self.y + rhs.y,
476 z: self.z + rhs.z,
477 }
478 }
479}
480
481impl Sub for Vec3 {
482 type Output = Self;
483 #[inline]
485 fn sub(self, rhs: Self) -> Self::Output {
486 Self {
487 x: self.x - rhs.x,
488 y: self.y - rhs.y,
489 z: self.z - rhs.z,
490 }
491 }
492}
493
494impl Mul<f32> for Vec3 {
495 type Output = Self;
496 #[inline]
498 fn mul(self, rhs: f32) -> Self::Output {
499 Self {
500 x: self.x * rhs,
501 y: self.y * rhs,
502 z: self.z * rhs,
503 }
504 }
505}
506
507impl Mul<Vec3> for f32 {
508 type Output = Vec3;
509 #[inline]
511 fn mul(self, rhs: Vec3) -> Self::Output {
512 rhs * self
513 }
514}
515
516impl Mul<Vec3> for Vec3 {
517 type Output = Self;
518 #[inline]
520 fn mul(self, rhs: Self) -> Self::Output {
521 Self {
522 x: self.x * rhs.x,
523 y: self.y * rhs.y,
524 z: self.z * rhs.z,
525 }
526 }
527}
528
529impl Div<f32> for Vec3 {
530 type Output = Self;
531 #[inline]
533 fn div(self, rhs: f32) -> Self::Output {
534 let inv_rhs = 1.0 / rhs;
535 Self {
536 x: self.x * inv_rhs,
537 y: self.y * inv_rhs,
538 z: self.z * inv_rhs,
539 }
540 }
541}
542
543impl Neg for Vec3 {
544 type Output = Self;
545 #[inline]
547 fn neg(self) -> Self::Output {
548 Self {
549 x: -self.x,
550 y: -self.y,
551 z: -self.z,
552 }
553 }
554}
555
556impl Index<usize> for Vec3 {
557 type Output = f32;
558 #[inline]
562 fn index(&self, index: usize) -> &Self::Output {
563 match index {
564 0 => &self.x,
565 1 => &self.y,
566 2 => &self.z,
567 _ => panic!("Index out of bounds for Vec3"),
568 }
569 }
570}
571
572impl IndexMut<usize> for Vec3 {
573 #[inline]
577 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
578 match index {
579 0 => &mut self.x,
580 1 => &mut self.y,
581 2 => &mut self.z,
582 _ => panic!("Index out of bounds for Vec3"),
583 }
584 }
585}
586
587#[derive(
594 Debug,
595 Default,
596 Copy,
597 Clone,
598 PartialEq,
599 bytemuck::Pod,
600 bytemuck::Zeroable,
601 Serialize,
602 Deserialize,
603 Encode,
604 Decode,
605)]
606#[repr(C)]
607pub struct Vec4 {
608 pub x: f32,
610 pub y: f32,
612 pub z: f32,
614 pub w: f32,
616}
617
618impl Vec4 {
619 pub const ZERO: Self = Self {
621 x: 0.0,
622 y: 0.0,
623 z: 0.0,
624 w: 0.0,
625 };
626 pub const ONE: Self = Self {
628 x: 1.0,
629 y: 1.0,
630 z: 1.0,
631 w: 1.0,
632 };
633 pub const X: Self = Self {
635 x: 1.0,
636 y: 0.0,
637 z: 0.0,
638 w: 0.0,
639 };
640 pub const Y: Self = Self {
642 x: 0.0,
643 y: 1.0,
644 z: 0.0,
645 w: 0.0,
646 };
647 pub const Z: Self = Self {
649 x: 0.0,
650 y: 0.0,
651 z: 1.0,
652 w: 0.0,
653 };
654 pub const W: Self = Self {
656 x: 0.0,
657 y: 0.0,
658 z: 0.0,
659 w: 1.0,
660 };
661
662 #[inline]
664 pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
665 Self { x, y, z, w }
666 }
667
668 #[inline]
670 pub const fn abs(self) -> Self {
671 Self {
672 x: if self.x < 0.0 { -self.x } else { self.x },
673 y: if self.y < 0.0 { -self.y } else { self.y },
674 z: if self.z < 0.0 { -self.z } else { self.z },
675 w: if self.w < 0.0 { -self.w } else { self.w },
676 }
677 }
678
679 #[inline]
681 pub fn from_vec3(v: Vec3, w: f32) -> Self {
682 Self::new(v.x, v.y, v.z, w)
683 }
684
685 #[inline]
687 pub fn truncate(&self) -> Vec3 {
688 Vec3::new(self.x, self.y, self.z)
689 }
690
691 #[inline]
693 pub fn dot(&self, other: Self) -> f32 {
694 self.x * other.x + self.y * other.y + self.z * other.z + self.w * other.w
695 }
696
697 #[inline]
702 pub fn get(&self, index: usize) -> f32 {
703 match index {
704 0 => self.x,
705 1 => self.y,
706 2 => self.z,
707 3 => self.w,
708 _ => panic!("Index out of bounds for Vec4"),
709 }
710 }
711
712 #[inline]
714 pub fn to_array(self) -> [f32; 4] {
715 [self.x, self.y, self.z, self.w]
716 }
717}
718
719impl From<Vec4> for [f32; 4] {
720 #[inline]
721 fn from(v: Vec4) -> Self {
722 [v.x, v.y, v.z, v.w]
723 }
724}
725
726impl From<[f32; 4]> for Vec4 {
727 #[inline]
728 fn from(v: [f32; 4]) -> Self {
729 Self::new(v[0], v[1], v[2], v[3])
730 }
731}
732
733impl Add for Vec4 {
736 type Output = Self;
737 #[inline]
739 fn add(self, rhs: Self) -> Self::Output {
740 Self {
741 x: self.x + rhs.x,
742 y: self.y + rhs.y,
743 z: self.z + rhs.z,
744 w: self.w + rhs.w,
745 }
746 }
747}
748
749impl Sub for Vec4 {
750 type Output = Self;
751 #[inline]
753 fn sub(self, rhs: Self) -> Self::Output {
754 Self {
755 x: self.x - rhs.x,
756 y: self.y - rhs.y,
757 z: self.z - rhs.z,
758 w: self.w - rhs.w,
759 }
760 }
761}
762
763impl Mul<f32> for Vec4 {
764 type Output = Self;
765 #[inline]
767 fn mul(self, rhs: f32) -> Self::Output {
768 Self {
769 x: self.x * rhs,
770 y: self.y * rhs,
771 z: self.z * rhs,
772 w: self.w * rhs,
773 }
774 }
775}
776
777impl Mul<Vec4> for f32 {
778 type Output = Vec4;
779 #[inline]
781 fn mul(self, rhs: Vec4) -> Self::Output {
782 rhs * self
783 }
784}
785
786impl Mul<Vec4> for Vec4 {
787 type Output = Self;
788 #[inline]
790 fn mul(self, rhs: Self) -> Self::Output {
791 Self {
792 x: self.x * rhs.x,
793 y: self.y * rhs.y,
794 z: self.z * rhs.z,
795 w: self.w * rhs.w,
796 }
797 }
798}
799
800impl Div<f32> for Vec4 {
801 type Output = Self;
802 #[inline]
804 fn div(self, rhs: f32) -> Self::Output {
805 let inv_rhs = 1.0 / rhs;
806 Self {
807 x: self.x * inv_rhs,
808 y: self.y * inv_rhs,
809 z: self.z * inv_rhs,
810 w: self.w * inv_rhs,
811 }
812 }
813}
814
815impl Neg for Vec4 {
816 type Output = Self;
817 #[inline]
819 fn neg(self) -> Self::Output {
820 Self {
821 x: -self.x,
822 y: -self.y,
823 z: -self.z,
824 w: -self.w,
825 }
826 }
827}
828
829impl Index<usize> for Vec4 {
830 type Output = f32;
831 #[inline]
835 fn index(&self, index: usize) -> &Self::Output {
836 match index {
837 0 => &self.x,
838 1 => &self.y,
839 2 => &self.z,
840 3 => &self.w,
841 _ => panic!("Index out of bounds for Vec4"),
842 }
843 }
844}
845
846impl IndexMut<usize> for Vec4 {
847 #[inline]
851 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
852 match index {
853 0 => &mut self.x,
854 1 => &mut self.y,
855 2 => &mut self.z,
856 3 => &mut self.w,
857 _ => panic!("Index out of bounds for Vec4"),
858 }
859 }
860}
861
862#[cfg(test)]
864mod tests {
865 use super::*; use crate::math::approx_eq;
867
868 fn vec2_approx_eq(a: Vec2, b: Vec2) -> bool {
869 approx_eq(a.x, b.x) && approx_eq(a.y, b.y)
870 }
871
872 fn vec3_approx_eq(a: Vec3, b: Vec3) -> bool {
873 approx_eq(a.x, b.x) && approx_eq(a.y, b.y) && approx_eq(a.z, b.z)
874 }
875
876 #[test]
879 fn test_vec2_new() {
880 let v = Vec2::new(1.0, 2.0);
881 assert_eq!(v.x, 1.0);
882 assert_eq!(v.y, 2.0);
883 }
884
885 #[test]
886 fn test_vec2_abs() {
887 let v = Vec2::new(-1.0, 2.0);
888 assert_eq!(v.abs(), Vec2::new(1.0, 2.0));
889 }
890
891 #[test]
892 fn test_vec2_constants() {
893 assert_eq!(Vec2::ZERO, Vec2::new(0.0, 0.0));
894 assert_eq!(Vec2::ONE, Vec2::new(1.0, 1.0));
895 assert_eq!(Vec2::X, Vec2::new(1.0, 0.0));
896 assert_eq!(Vec2::Y, Vec2::new(0.0, 1.0));
897 }
898
899 #[test]
900 fn test_vec2_ops() {
901 let v1 = Vec2::new(1.0, 2.0);
902 let v2 = Vec2::new(3.0, 4.0);
903 assert_eq!(v1 + v2, Vec2::new(4.0, 6.0));
904 assert_eq!(v2 - v1, Vec2::new(2.0, 2.0));
905 assert_eq!(v1 * 2.0, Vec2::new(2.0, 4.0));
906 assert_eq!(3.0 * v1, Vec2::new(3.0, 6.0));
907 assert_eq!(v1 * v2, Vec2::new(3.0, 8.0)); assert_eq!(-v1, Vec2::new(-1.0, -2.0));
909 assert!(vec2_approx_eq(
910 Vec2::new(4.0, 6.0) / 2.0,
911 Vec2::new(2.0, 3.0)
912 ));
913 }
914
915 #[test]
916 fn test_vec2_dot() {
917 let v1 = Vec2::new(1.0, 2.0);
918 let v2 = Vec2::new(3.0, 4.0);
919 assert!(approx_eq(v1.dot(v2), 1.0 * 3.0 + 2.0 * 4.0)); }
921
922 #[test]
923 fn test_vec2_length() {
924 let v = Vec2::new(3.0, 4.0);
925 assert!(approx_eq(v.length_squared(), 25.0));
926 assert!(approx_eq(v.length(), 5.0));
927 assert!(approx_eq(Vec2::ZERO.length(), 0.0));
928 }
929
930 #[test]
931 fn test_vec2_normalize() {
932 let v1 = Vec2::new(3.0, 0.0);
933 let norm_v1 = v1.normalize();
934 assert!(vec2_approx_eq(norm_v1, Vec2::X));
935 assert!(approx_eq(norm_v1.length(), 1.0));
936
937 let v_zero = Vec2::ZERO;
938 assert_eq!(v_zero.normalize(), Vec2::ZERO);
939 }
940
941 #[test]
942 fn test_vec2_lerp() {
943 let start = Vec2::new(0.0, 10.0);
944 let end = Vec2::new(10.0, 0.0);
945 assert!(vec2_approx_eq(Vec2::lerp(start, end, 0.0), start));
946 assert!(vec2_approx_eq(Vec2::lerp(start, end, 1.0), end));
947 assert!(vec2_approx_eq(
948 Vec2::lerp(start, end, 0.5),
949 Vec2::new(5.0, 5.0)
950 ));
951 assert!(vec2_approx_eq(Vec2::lerp(start, end, -0.5), start));
953 assert!(vec2_approx_eq(Vec2::lerp(start, end, 1.5), end));
954 }
955
956 #[test]
957 fn test_vec2_index() {
958 let mut v = Vec2::new(5.0, 6.0);
959 assert_eq!(v[0], 5.0);
960 assert_eq!(v[1], 6.0);
961 v[0] = 10.0;
962 assert_eq!(v.x, 10.0);
963 }
964
965 #[test]
966 #[should_panic]
967 fn test_vec2_index_out_of_bounds() {
968 let v = Vec2::new(1.0, 2.0);
969 let _ = v[2]; }
971
972 #[test]
975 fn test_new() {
976 let v = Vec3::new(1.0, 2.0, 3.0);
977 assert_eq!(v.x, 1.0);
978 assert_eq!(v.y, 2.0);
979 assert_eq!(v.z, 3.0);
980 }
981
982 #[test]
983 fn test_vec3_abs() {
984 let v = Vec3::new(-1.0, 2.0, -3.0);
985 assert_eq!(v.abs(), Vec3::new(1.0, 2.0, 3.0));
986 assert_eq!(Vec3::ZERO.abs(), Vec3::ZERO);
987 }
988
989 #[test]
990 fn test_constants() {
991 assert_eq!(Vec3::ZERO, Vec3::new(0.0, 0.0, 0.0));
992 assert_eq!(Vec3::ONE, Vec3::new(1.0, 1.0, 1.0));
993 assert_eq!(Vec3::X, Vec3::new(1.0, 0.0, 0.0));
994 assert_eq!(Vec3::Y, Vec3::new(0.0, 1.0, 0.0));
995 assert_eq!(Vec3::Z, Vec3::new(0.0, 0.0, 1.0));
996 }
997
998 #[test]
999 fn test_add() {
1000 let v1 = Vec3::new(1.0, 2.0, 3.0);
1001 let v2 = Vec3::new(4.0, 5.0, 6.0);
1002 assert_eq!(v1 + v2, Vec3::new(5.0, 7.0, 9.0));
1003 }
1004
1005 #[test]
1006 fn test_sub() {
1007 let v1 = Vec3::new(5.0, 7.0, 9.0);
1008 let v2 = Vec3::new(1.0, 2.0, 3.0);
1009 assert_eq!(v1 - v2, Vec3::new(4.0, 5.0, 6.0));
1010 }
1011
1012 #[test]
1013 fn test_scalar_mul() {
1014 let v = Vec3::new(1.0, 2.0, 3.0);
1015 assert_eq!(v * 2.0, Vec3::new(2.0, 4.0, 6.0));
1016 assert_eq!(3.0 * v, Vec3::new(3.0, 6.0, 9.0)); }
1018
1019 #[test]
1020 fn test_component_mul() {
1021 let v1 = Vec3::new(1.0, 2.0, 3.0);
1022 let v2 = Vec3::new(4.0, 5.0, 6.0);
1023 assert_eq!(v1 * v2, Vec3::new(4.0, 10.0, 18.0));
1024 }
1025
1026 #[test]
1027 fn test_scalar_div() {
1028 let v = Vec3::new(2.0, 4.0, 6.0);
1029 assert_eq!(v / 2.0, Vec3::new(1.0, 2.0, 3.0));
1030 }
1031
1032 #[test]
1033 fn test_neg() {
1034 let v = Vec3::new(1.0, -2.0, 3.0);
1035 assert_eq!(-v, Vec3::new(-1.0, 2.0, -3.0));
1036 }
1037
1038 #[test]
1039 fn test_length() {
1040 let v1 = Vec3::new(3.0, 4.0, 0.0);
1041 assert!(approx_eq(v1.length_squared(), 25.0));
1042 assert!(approx_eq(v1.length(), 5.0));
1043
1044 let v2 = Vec3::ZERO;
1045 assert!(approx_eq(v2.length_squared(), 0.0));
1046 assert!(approx_eq(v2.length(), 0.0));
1047 }
1048
1049 #[test]
1050 fn test_dot() {
1051 let v1 = Vec3::new(1.0, 2.0, 3.0);
1052 let v2 = Vec3::new(4.0, -5.0, 6.0);
1053 assert!(approx_eq(v1.dot(v2), 12.0));
1055
1056 assert!(approx_eq(Vec3::X.dot(Vec3::Y), 0.0));
1058 }
1059
1060 #[test]
1061 fn test_distance() {
1062 let v1 = Vec3::new(1.0, 2.0, 3.0);
1063 let v2 = Vec3::new(4.0, 5.0, 6.0);
1064 assert!(approx_eq(v1.distance(v2), 3.0 * (3.0_f32).sqrt()));
1066 }
1067
1068 #[test]
1069 fn test_cross() {
1070 assert_eq!(Vec3::X.cross(Vec3::Y), Vec3::Z);
1072 assert_eq!(Vec3::Y.cross(Vec3::Z), Vec3::X);
1073 assert_eq!(Vec3::Z.cross(Vec3::X), Vec3::Y);
1074
1075 assert_eq!(Vec3::Y.cross(Vec3::X), -Vec3::Z);
1077
1078 assert_eq!(Vec3::X.cross(Vec3::X), Vec3::ZERO);
1080 }
1081
1082 #[test]
1083 fn test_normalize() {
1084 let v1 = Vec3::new(3.0, 0.0, 0.0);
1085 let norm_v1 = v1.normalize();
1086 assert!(vec3_approx_eq(norm_v1, Vec3::X));
1087 assert!(approx_eq(norm_v1.length(), 1.0));
1088
1089 let v2 = Vec3::new(1.0, 1.0, 1.0);
1090 let norm_v2 = v2.normalize();
1091 assert!(approx_eq(norm_v2.length(), 1.0)); let v_zero = Vec3::ZERO;
1095 assert_eq!(v_zero.normalize(), Vec3::ZERO);
1096 }
1097
1098 #[test]
1099 fn test_lerp() {
1100 let start = Vec3::new(0.0, 0.0, 0.0);
1101 let end = Vec3::new(10.0, 10.0, 10.0);
1102
1103 assert!(vec3_approx_eq(Vec3::lerp(start, end, 0.0), start));
1104 assert!(vec3_approx_eq(Vec3::lerp(start, end, 1.0), end));
1105 assert!(vec3_approx_eq(
1106 Vec3::lerp(start, end, 0.5),
1107 Vec3::new(5.0, 5.0, 5.0)
1108 ));
1109 }
1110
1111 #[test]
1114 fn test_vec4_new() {
1115 let v = Vec4::new(1.0, 2.0, 3.0, 4.0);
1116 assert_eq!(v.x, 1.0);
1117 assert_eq!(v.y, 2.0);
1118 assert_eq!(v.z, 3.0);
1119 assert_eq!(v.w, 4.0);
1120 }
1121
1122 #[test]
1123 fn test_vec4_abs() {
1124 let v = Vec4::new(-1.0, 2.0, -3.0, -0.5);
1125 assert_eq!(v.abs(), Vec4::new(1.0, 2.0, 3.0, 0.5));
1126 }
1127
1128 #[test]
1129 fn test_vec4_from_vec3() {
1130 let v3 = Vec3::new(1.0, 2.0, 3.0);
1131 let v4 = Vec4::from_vec3(v3, 4.0);
1132 assert_eq!(v4, Vec4::new(1.0, 2.0, 3.0, 4.0));
1133 }
1134
1135 #[test]
1136 fn test_vec4_truncate() {
1137 let v4 = Vec4::new(1.0, 2.0, 3.0, 4.0);
1138 let v3 = v4.truncate();
1139 assert_eq!(v3, Vec3::new(1.0, 2.0, 3.0));
1140 }
1141
1142 #[test]
1143 fn vec3_neg_constants_have_unit_length() {
1144 assert!((Vec3::NEG_X.length() - 1.0).abs() < EPSILON);
1145 assert!((Vec3::NEG_Y.length() - 1.0).abs() < EPSILON);
1146 assert!((Vec3::NEG_Z.length() - 1.0).abs() < EPSILON);
1147 }
1148
1149 #[test]
1150 fn vec3_neg_constants_oppose_positive_axes() {
1151 assert_eq!(Vec3::NEG_X, -Vec3::X);
1152 assert_eq!(Vec3::NEG_Y, -Vec3::Y);
1153 assert_eq!(Vec3::NEG_Z, -Vec3::Z);
1154 assert_eq!(Vec3::NEG_X.dot(Vec3::X), -1.0);
1155 assert_eq!(Vec3::NEG_Y.dot(Vec3::Y), -1.0);
1156 assert_eq!(Vec3::NEG_Z.dot(Vec3::Z), -1.0);
1157 }
1158
1159 #[test]
1160 fn vec3_max_element_picks_largest_signed() {
1161 assert_eq!(Vec3::new(1.0, 2.0, 3.0).max_element(), 3.0);
1162 assert_eq!(Vec3::new(-1.0, -2.0, -3.0).max_element(), -1.0);
1163 assert_eq!(Vec3::new(5.0, -10.0, 0.0).max_element(), 5.0);
1164 assert_eq!(Vec3::ZERO.max_element(), 0.0);
1165 }
1166
1167 #[test]
1168 fn vec3_min_element_picks_smallest_signed() {
1169 assert_eq!(Vec3::new(1.0, 2.0, 3.0).min_element(), 1.0);
1170 assert_eq!(Vec3::new(-1.0, -2.0, -3.0).min_element(), -3.0);
1171 assert_eq!(Vec3::new(5.0, -10.0, 0.0).min_element(), -10.0);
1172 assert_eq!(Vec3::ZERO.min_element(), 0.0);
1173 }
1174}