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
111impl Add for Vec2 {
114 type Output = Self;
115 #[inline]
117 fn add(self, rhs: Self) -> Self::Output {
118 Self {
119 x: self.x + rhs.x,
120 y: self.y + rhs.y,
121 }
122 }
123}
124
125impl Sub for Vec2 {
126 type Output = Self;
127 #[inline]
129 fn sub(self, rhs: Self) -> Self::Output {
130 Self {
131 x: self.x - rhs.x,
132 y: self.y - rhs.y,
133 }
134 }
135}
136
137impl Mul<f32> for Vec2 {
138 type Output = Self;
139 #[inline]
141 fn mul(self, rhs: f32) -> Self::Output {
142 Self {
143 x: self.x * rhs,
144 y: self.y * rhs,
145 }
146 }
147}
148
149impl Mul<Vec2> for f32 {
150 type Output = Vec2;
151 #[inline]
153 fn mul(self, rhs: Vec2) -> Self::Output {
154 rhs * self
155 }
156}
157
158impl Mul<Vec2> for Vec2 {
159 type Output = Self;
160 #[inline]
162 fn mul(self, rhs: Vec2) -> Self::Output {
163 Self {
164 x: self.x * rhs.x,
165 y: self.y * rhs.y,
166 }
167 }
168}
169
170impl Div<f32> for Vec2 {
171 type Output = Self;
172 #[inline]
174 fn div(self, rhs: f32) -> Self::Output {
175 let inv_rhs = 1.0 / rhs;
176 Self {
177 x: self.x * inv_rhs,
178 y: self.y * inv_rhs,
179 }
180 }
181}
182
183impl Neg for Vec2 {
184 type Output = Self;
185 #[inline]
187 fn neg(self) -> Self::Output {
188 Self {
189 x: -self.x,
190 y: -self.y,
191 }
192 }
193}
194
195impl Index<usize> for Vec2 {
196 type Output = f32;
197 #[inline]
202 fn index(&self, index: usize) -> &Self::Output {
203 match index {
204 0 => &self.x,
205 1 => &self.y,
206 _ => panic!("Index out of bounds for Vec2"),
207 }
208 }
209}
210
211impl IndexMut<usize> for Vec2 {
212 #[inline]
217 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
218 match index {
219 0 => &mut self.x,
220 1 => &mut self.y,
221 _ => panic!("Index out of bounds for Vec2"),
222 }
223 }
224}
225
226#[derive(
230 Debug,
231 Clone,
232 Copy,
233 PartialEq,
234 bytemuck::Pod,
235 bytemuck::Zeroable,
236 Serialize,
237 Deserialize,
238 Encode,
239 Decode,
240)]
241#[repr(C)]
242pub struct Vec3 {
243 pub x: f32,
245 pub y: f32,
247 pub z: f32,
249}
250
251impl Vec3 {
252 pub const ZERO: Self = Self {
254 x: 0.0,
255 y: 0.0,
256 z: 0.0,
257 };
258 pub const ONE: Self = Self {
260 x: 1.0,
261 y: 1.0,
262 z: 1.0,
263 };
264 pub const X: Self = Self {
266 x: 1.0,
267 y: 0.0,
268 z: 0.0,
269 };
270 pub const Y: Self = Self {
272 x: 0.0,
273 y: 1.0,
274 z: 0.0,
275 };
276 pub const Z: Self = Self {
278 x: 0.0,
279 y: 0.0,
280 z: 1.0,
281 };
282
283 #[inline]
285 pub const fn new(x: f32, y: f32, z: f32) -> Self {
286 Self { x, y, z }
287 }
288
289 #[inline]
291 pub const fn abs(self) -> Self {
292 Self {
293 x: if self.x < 0.0 { -self.x } else { self.x },
294 y: if self.y < 0.0 { -self.y } else { self.y },
295 z: if self.z < 0.0 { -self.z } else { self.z },
296 }
297 }
298
299 #[inline]
301 pub fn length_squared(&self) -> f32 {
302 self.dot(*self)
303 }
304
305 #[inline]
307 pub fn length(&self) -> f32 {
308 self.length_squared().sqrt()
309 }
310
311 #[inline]
313 pub fn normalize(&self) -> Self {
314 let len_sq = self.length_squared();
315 if len_sq > EPSILON * EPSILON {
316 *self * (1.0 / len_sq.sqrt())
319 } else {
320 Self::ZERO
321 }
322 }
323
324 #[inline]
326 pub fn dot(&self, other: Self) -> f32 {
327 self.x * other.x + self.y * other.y + self.z * other.z
328 }
329
330 #[inline]
332 pub fn cross(&self, other: Self) -> Self {
333 Self {
334 x: self.y * other.z - self.z * other.y,
335 y: self.z * other.x - self.x * other.z,
336 z: self.x * other.y - self.y * other.x,
337 }
338 }
339
340 #[inline]
342 pub fn distance_squared(&self, other: Self) -> f32 {
343 let dx = self.x - other.x;
344 let dy = self.y - other.y;
345 let dz = self.z - other.z;
346 dx * dx + dy * dy + dz * dz
347 }
348
349 #[inline]
351 pub fn distance(&self, other: Self) -> f32 {
352 self.distance_squared(other).sqrt()
353 }
354
355 #[inline]
357 pub fn lerp(start: Self, end: Self, t: f32) -> Self {
358 Self {
359 x: start.x + (end.x - start.x) * t,
360 y: start.y + (end.y - start.y) * t,
361 z: start.z + (end.z - start.z) * t,
362 }
363 }
364
365 #[inline]
370 pub fn get(&self, index: usize) -> f32 {
371 match index {
372 0 => self.x,
373 1 => self.y,
374 2 => self.z,
375 _ => panic!("Index out of bounds for Vec3"),
376 }
377 }
378}
379
380impl Default for Vec3 {
383 #[inline]
385 fn default() -> Self {
386 Self::ZERO
387 }
388}
389
390impl Add for Vec3 {
391 type Output = Self;
392 #[inline]
394 fn add(self, rhs: Self) -> Self::Output {
395 Self {
396 x: self.x + rhs.x,
397 y: self.y + rhs.y,
398 z: self.z + rhs.z,
399 }
400 }
401}
402
403impl Sub for Vec3 {
404 type Output = Self;
405 #[inline]
407 fn sub(self, rhs: Self) -> Self::Output {
408 Self {
409 x: self.x - rhs.x,
410 y: self.y - rhs.y,
411 z: self.z - rhs.z,
412 }
413 }
414}
415
416impl Mul<f32> for Vec3 {
417 type Output = Self;
418 #[inline]
420 fn mul(self, rhs: f32) -> Self::Output {
421 Self {
422 x: self.x * rhs,
423 y: self.y * rhs,
424 z: self.z * rhs,
425 }
426 }
427}
428
429impl Mul<Vec3> for f32 {
430 type Output = Vec3;
431 #[inline]
433 fn mul(self, rhs: Vec3) -> Self::Output {
434 rhs * self
435 }
436}
437
438impl Mul<Vec3> for Vec3 {
439 type Output = Self;
440 #[inline]
442 fn mul(self, rhs: Self) -> Self::Output {
443 Self {
444 x: self.x * rhs.x,
445 y: self.y * rhs.y,
446 z: self.z * rhs.z,
447 }
448 }
449}
450
451impl Div<f32> for Vec3 {
452 type Output = Self;
453 #[inline]
455 fn div(self, rhs: f32) -> Self::Output {
456 let inv_rhs = 1.0 / rhs;
457 Self {
458 x: self.x * inv_rhs,
459 y: self.y * inv_rhs,
460 z: self.z * inv_rhs,
461 }
462 }
463}
464
465impl Neg for Vec3 {
466 type Output = Self;
467 #[inline]
469 fn neg(self) -> Self::Output {
470 Self {
471 x: -self.x,
472 y: -self.y,
473 z: -self.z,
474 }
475 }
476}
477
478impl Index<usize> for Vec3 {
479 type Output = f32;
480 #[inline]
484 fn index(&self, index: usize) -> &Self::Output {
485 match index {
486 0 => &self.x,
487 1 => &self.y,
488 2 => &self.z,
489 _ => panic!("Index out of bounds for Vec3"),
490 }
491 }
492}
493
494impl IndexMut<usize> for Vec3 {
495 #[inline]
499 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
500 match index {
501 0 => &mut self.x,
502 1 => &mut self.y,
503 2 => &mut self.z,
504 _ => panic!("Index out of bounds for Vec3"),
505 }
506 }
507}
508
509#[derive(
516 Debug,
517 Default,
518 Copy,
519 Clone,
520 PartialEq,
521 bytemuck::Pod,
522 bytemuck::Zeroable,
523 Serialize,
524 Deserialize,
525 Encode,
526 Decode,
527)]
528#[repr(C)]
529pub struct Vec4 {
530 pub x: f32,
532 pub y: f32,
534 pub z: f32,
536 pub w: f32,
538}
539
540impl Vec4 {
541 pub const ZERO: Self = Self {
543 x: 0.0,
544 y: 0.0,
545 z: 0.0,
546 w: 0.0,
547 };
548 pub const ONE: Self = Self {
550 x: 1.0,
551 y: 1.0,
552 z: 1.0,
553 w: 1.0,
554 };
555 pub const X: Self = Self {
557 x: 1.0,
558 y: 0.0,
559 z: 0.0,
560 w: 0.0,
561 };
562 pub const Y: Self = Self {
564 x: 0.0,
565 y: 1.0,
566 z: 0.0,
567 w: 0.0,
568 };
569 pub const Z: Self = Self {
571 x: 0.0,
572 y: 0.0,
573 z: 1.0,
574 w: 0.0,
575 };
576 pub const W: Self = Self {
578 x: 0.0,
579 y: 0.0,
580 z: 0.0,
581 w: 1.0,
582 };
583
584 #[inline]
586 pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
587 Self { x, y, z, w }
588 }
589
590 #[inline]
592 pub const fn abs(self) -> Self {
593 Self {
594 x: if self.x < 0.0 { -self.x } else { self.x },
595 y: if self.y < 0.0 { -self.y } else { self.y },
596 z: if self.z < 0.0 { -self.z } else { self.z },
597 w: if self.w < 0.0 { -self.w } else { self.w },
598 }
599 }
600
601 #[inline]
603 pub fn from_vec3(v: Vec3, w: f32) -> Self {
604 Self::new(v.x, v.y, v.z, w)
605 }
606
607 #[inline]
609 pub fn truncate(&self) -> Vec3 {
610 Vec3::new(self.x, self.y, self.z)
611 }
612
613 #[inline]
615 pub fn dot(&self, other: Self) -> f32 {
616 self.x * other.x + self.y * other.y + self.z * other.z + self.w * other.w
617 }
618
619 #[inline]
624 pub fn get(&self, index: usize) -> f32 {
625 match index {
626 0 => self.x,
627 1 => self.y,
628 2 => self.z,
629 3 => self.w,
630 _ => panic!("Index out of bounds for Vec4"),
631 }
632 }
633}
634
635impl Add for Vec4 {
638 type Output = Self;
639 #[inline]
641 fn add(self, rhs: Self) -> Self::Output {
642 Self {
643 x: self.x + rhs.x,
644 y: self.y + rhs.y,
645 z: self.z + rhs.z,
646 w: self.w + rhs.w,
647 }
648 }
649}
650
651impl Sub for Vec4 {
652 type Output = Self;
653 #[inline]
655 fn sub(self, rhs: Self) -> Self::Output {
656 Self {
657 x: self.x - rhs.x,
658 y: self.y - rhs.y,
659 z: self.z - rhs.z,
660 w: self.w - rhs.w,
661 }
662 }
663}
664
665impl Mul<f32> for Vec4 {
666 type Output = Self;
667 #[inline]
669 fn mul(self, rhs: f32) -> Self::Output {
670 Self {
671 x: self.x * rhs,
672 y: self.y * rhs,
673 z: self.z * rhs,
674 w: self.w * rhs,
675 }
676 }
677}
678
679impl Mul<Vec4> for f32 {
680 type Output = Vec4;
681 #[inline]
683 fn mul(self, rhs: Vec4) -> Self::Output {
684 rhs * self
685 }
686}
687
688impl Mul<Vec4> for Vec4 {
689 type Output = Self;
690 #[inline]
692 fn mul(self, rhs: Self) -> Self::Output {
693 Self {
694 x: self.x * rhs.x,
695 y: self.y * rhs.y,
696 z: self.z * rhs.z,
697 w: self.w * rhs.w,
698 }
699 }
700}
701
702impl Div<f32> for Vec4 {
703 type Output = Self;
704 #[inline]
706 fn div(self, rhs: f32) -> Self::Output {
707 let inv_rhs = 1.0 / rhs;
708 Self {
709 x: self.x * inv_rhs,
710 y: self.y * inv_rhs,
711 z: self.z * inv_rhs,
712 w: self.w * inv_rhs,
713 }
714 }
715}
716
717impl Neg for Vec4 {
718 type Output = Self;
719 #[inline]
721 fn neg(self) -> Self::Output {
722 Self {
723 x: -self.x,
724 y: -self.y,
725 z: -self.z,
726 w: -self.w,
727 }
728 }
729}
730
731impl Index<usize> for Vec4 {
732 type Output = f32;
733 #[inline]
737 fn index(&self, index: usize) -> &Self::Output {
738 match index {
739 0 => &self.x,
740 1 => &self.y,
741 2 => &self.z,
742 3 => &self.w,
743 _ => panic!("Index out of bounds for Vec4"),
744 }
745 }
746}
747
748impl IndexMut<usize> for Vec4 {
749 #[inline]
753 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
754 match index {
755 0 => &mut self.x,
756 1 => &mut self.y,
757 2 => &mut self.z,
758 3 => &mut self.w,
759 _ => panic!("Index out of bounds for Vec4"),
760 }
761 }
762}
763
764#[cfg(test)]
766mod tests {
767 use super::*; use crate::math::approx_eq;
769
770 fn vec2_approx_eq(a: Vec2, b: Vec2) -> bool {
771 approx_eq(a.x, b.x) && approx_eq(a.y, b.y)
772 }
773
774 fn vec3_approx_eq(a: Vec3, b: Vec3) -> bool {
775 approx_eq(a.x, b.x) && approx_eq(a.y, b.y) && approx_eq(a.z, b.z)
776 }
777
778 #[test]
781 fn test_vec2_new() {
782 let v = Vec2::new(1.0, 2.0);
783 assert_eq!(v.x, 1.0);
784 assert_eq!(v.y, 2.0);
785 }
786
787 #[test]
788 fn test_vec2_abs() {
789 let v = Vec2::new(-1.0, 2.0);
790 assert_eq!(v.abs(), Vec2::new(1.0, 2.0));
791 }
792
793 #[test]
794 fn test_vec2_constants() {
795 assert_eq!(Vec2::ZERO, Vec2::new(0.0, 0.0));
796 assert_eq!(Vec2::ONE, Vec2::new(1.0, 1.0));
797 assert_eq!(Vec2::X, Vec2::new(1.0, 0.0));
798 assert_eq!(Vec2::Y, Vec2::new(0.0, 1.0));
799 }
800
801 #[test]
802 fn test_vec2_ops() {
803 let v1 = Vec2::new(1.0, 2.0);
804 let v2 = Vec2::new(3.0, 4.0);
805 assert_eq!(v1 + v2, Vec2::new(4.0, 6.0));
806 assert_eq!(v2 - v1, Vec2::new(2.0, 2.0));
807 assert_eq!(v1 * 2.0, Vec2::new(2.0, 4.0));
808 assert_eq!(3.0 * v1, Vec2::new(3.0, 6.0));
809 assert_eq!(v1 * v2, Vec2::new(3.0, 8.0)); assert_eq!(-v1, Vec2::new(-1.0, -2.0));
811 assert!(vec2_approx_eq(
812 Vec2::new(4.0, 6.0) / 2.0,
813 Vec2::new(2.0, 3.0)
814 ));
815 }
816
817 #[test]
818 fn test_vec2_dot() {
819 let v1 = Vec2::new(1.0, 2.0);
820 let v2 = Vec2::new(3.0, 4.0);
821 assert!(approx_eq(v1.dot(v2), 1.0 * 3.0 + 2.0 * 4.0)); }
823
824 #[test]
825 fn test_vec2_length() {
826 let v = Vec2::new(3.0, 4.0);
827 assert!(approx_eq(v.length_squared(), 25.0));
828 assert!(approx_eq(v.length(), 5.0));
829 assert!(approx_eq(Vec2::ZERO.length(), 0.0));
830 }
831
832 #[test]
833 fn test_vec2_normalize() {
834 let v1 = Vec2::new(3.0, 0.0);
835 let norm_v1 = v1.normalize();
836 assert!(vec2_approx_eq(norm_v1, Vec2::X));
837 assert!(approx_eq(norm_v1.length(), 1.0));
838
839 let v_zero = Vec2::ZERO;
840 assert_eq!(v_zero.normalize(), Vec2::ZERO);
841 }
842
843 #[test]
844 fn test_vec2_lerp() {
845 let start = Vec2::new(0.0, 10.0);
846 let end = Vec2::new(10.0, 0.0);
847 assert!(vec2_approx_eq(Vec2::lerp(start, end, 0.0), start));
848 assert!(vec2_approx_eq(Vec2::lerp(start, end, 1.0), end));
849 assert!(vec2_approx_eq(
850 Vec2::lerp(start, end, 0.5),
851 Vec2::new(5.0, 5.0)
852 ));
853 assert!(vec2_approx_eq(Vec2::lerp(start, end, -0.5), start));
855 assert!(vec2_approx_eq(Vec2::lerp(start, end, 1.5), end));
856 }
857
858 #[test]
859 fn test_vec2_index() {
860 let mut v = Vec2::new(5.0, 6.0);
861 assert_eq!(v[0], 5.0);
862 assert_eq!(v[1], 6.0);
863 v[0] = 10.0;
864 assert_eq!(v.x, 10.0);
865 }
866
867 #[test]
868 #[should_panic]
869 fn test_vec2_index_out_of_bounds() {
870 let v = Vec2::new(1.0, 2.0);
871 let _ = v[2]; }
873
874 #[test]
877 fn test_new() {
878 let v = Vec3::new(1.0, 2.0, 3.0);
879 assert_eq!(v.x, 1.0);
880 assert_eq!(v.y, 2.0);
881 assert_eq!(v.z, 3.0);
882 }
883
884 #[test]
885 fn test_vec3_abs() {
886 let v = Vec3::new(-1.0, 2.0, -3.0);
887 assert_eq!(v.abs(), Vec3::new(1.0, 2.0, 3.0));
888 assert_eq!(Vec3::ZERO.abs(), Vec3::ZERO);
889 }
890
891 #[test]
892 fn test_constants() {
893 assert_eq!(Vec3::ZERO, Vec3::new(0.0, 0.0, 0.0));
894 assert_eq!(Vec3::ONE, Vec3::new(1.0, 1.0, 1.0));
895 assert_eq!(Vec3::X, Vec3::new(1.0, 0.0, 0.0));
896 assert_eq!(Vec3::Y, Vec3::new(0.0, 1.0, 0.0));
897 assert_eq!(Vec3::Z, Vec3::new(0.0, 0.0, 1.0));
898 }
899
900 #[test]
901 fn test_add() {
902 let v1 = Vec3::new(1.0, 2.0, 3.0);
903 let v2 = Vec3::new(4.0, 5.0, 6.0);
904 assert_eq!(v1 + v2, Vec3::new(5.0, 7.0, 9.0));
905 }
906
907 #[test]
908 fn test_sub() {
909 let v1 = Vec3::new(5.0, 7.0, 9.0);
910 let v2 = Vec3::new(1.0, 2.0, 3.0);
911 assert_eq!(v1 - v2, Vec3::new(4.0, 5.0, 6.0));
912 }
913
914 #[test]
915 fn test_scalar_mul() {
916 let v = Vec3::new(1.0, 2.0, 3.0);
917 assert_eq!(v * 2.0, Vec3::new(2.0, 4.0, 6.0));
918 assert_eq!(3.0 * v, Vec3::new(3.0, 6.0, 9.0)); }
920
921 #[test]
922 fn test_component_mul() {
923 let v1 = Vec3::new(1.0, 2.0, 3.0);
924 let v2 = Vec3::new(4.0, 5.0, 6.0);
925 assert_eq!(v1 * v2, Vec3::new(4.0, 10.0, 18.0));
926 }
927
928 #[test]
929 fn test_scalar_div() {
930 let v = Vec3::new(2.0, 4.0, 6.0);
931 assert_eq!(v / 2.0, Vec3::new(1.0, 2.0, 3.0));
932 }
933
934 #[test]
935 fn test_neg() {
936 let v = Vec3::new(1.0, -2.0, 3.0);
937 assert_eq!(-v, Vec3::new(-1.0, 2.0, -3.0));
938 }
939
940 #[test]
941 fn test_length() {
942 let v1 = Vec3::new(3.0, 4.0, 0.0);
943 assert!(approx_eq(v1.length_squared(), 25.0));
944 assert!(approx_eq(v1.length(), 5.0));
945
946 let v2 = Vec3::ZERO;
947 assert!(approx_eq(v2.length_squared(), 0.0));
948 assert!(approx_eq(v2.length(), 0.0));
949 }
950
951 #[test]
952 fn test_dot() {
953 let v1 = Vec3::new(1.0, 2.0, 3.0);
954 let v2 = Vec3::new(4.0, -5.0, 6.0);
955 assert!(approx_eq(v1.dot(v2), 12.0));
957
958 assert!(approx_eq(Vec3::X.dot(Vec3::Y), 0.0));
960 }
961
962 #[test]
963 fn test_distance() {
964 let v1 = Vec3::new(1.0, 2.0, 3.0);
965 let v2 = Vec3::new(4.0, 5.0, 6.0);
966 assert!(approx_eq(v1.distance(v2), 3.0 * (3.0_f32).sqrt()));
968 }
969
970 #[test]
971 fn test_cross() {
972 assert_eq!(Vec3::X.cross(Vec3::Y), Vec3::Z);
974 assert_eq!(Vec3::Y.cross(Vec3::Z), Vec3::X);
975 assert_eq!(Vec3::Z.cross(Vec3::X), Vec3::Y);
976
977 assert_eq!(Vec3::Y.cross(Vec3::X), -Vec3::Z);
979
980 assert_eq!(Vec3::X.cross(Vec3::X), Vec3::ZERO);
982 }
983
984 #[test]
985 fn test_normalize() {
986 let v1 = Vec3::new(3.0, 0.0, 0.0);
987 let norm_v1 = v1.normalize();
988 assert!(vec3_approx_eq(norm_v1, Vec3::X));
989 assert!(approx_eq(norm_v1.length(), 1.0));
990
991 let v2 = Vec3::new(1.0, 1.0, 1.0);
992 let norm_v2 = v2.normalize();
993 assert!(approx_eq(norm_v2.length(), 1.0)); let v_zero = Vec3::ZERO;
997 assert_eq!(v_zero.normalize(), Vec3::ZERO);
998 }
999
1000 #[test]
1001 fn test_lerp() {
1002 let start = Vec3::new(0.0, 0.0, 0.0);
1003 let end = Vec3::new(10.0, 10.0, 10.0);
1004
1005 assert!(vec3_approx_eq(Vec3::lerp(start, end, 0.0), start));
1006 assert!(vec3_approx_eq(Vec3::lerp(start, end, 1.0), end));
1007 assert!(vec3_approx_eq(
1008 Vec3::lerp(start, end, 0.5),
1009 Vec3::new(5.0, 5.0, 5.0)
1010 ));
1011 }
1012
1013 #[test]
1016 fn test_vec4_new() {
1017 let v = Vec4::new(1.0, 2.0, 3.0, 4.0);
1018 assert_eq!(v.x, 1.0);
1019 assert_eq!(v.y, 2.0);
1020 assert_eq!(v.z, 3.0);
1021 assert_eq!(v.w, 4.0);
1022 }
1023
1024 #[test]
1025 fn test_vec4_abs() {
1026 let v = Vec4::new(-1.0, 2.0, -3.0, -0.5);
1027 assert_eq!(v.abs(), Vec4::new(1.0, 2.0, 3.0, 0.5));
1028 }
1029
1030 #[test]
1031 fn test_vec4_from_vec3() {
1032 let v3 = Vec3::new(1.0, 2.0, 3.0);
1033 let v4 = Vec4::from_vec3(v3, 4.0);
1034 assert_eq!(v4, Vec4::new(1.0, 2.0, 3.0, 4.0));
1035 }
1036
1037 #[test]
1038 fn test_vec4_truncate() {
1039 let v4 = Vec4::new(1.0, 2.0, 3.0, 4.0);
1040 let v3 = v4.truncate();
1041 assert_eq!(v3, Vec3::new(1.0, 2.0, 3.0));
1042 }
1043}