1use super::EPSILON;
18use std::ops::{Add, Div, Index, IndexMut, Mul, Neg, Sub};
19
20#[derive(Debug, Default, Copy, Clone, PartialEq)]
24#[repr(C)]
25pub struct Vec2 {
26 pub x: f32,
28 pub y: f32,
30}
31
32impl Vec2 {
33 pub const ZERO: Self = Self { x: 0.0, y: 0.0 };
35 pub const ONE: Self = Self { x: 1.0, y: 1.0 };
37 pub const X: Self = Self { x: 1.0, y: 0.0 };
39 pub const Y: Self = Self { x: 0.0, y: 1.0 };
41
42 #[inline]
44 pub const fn new(x: f32, y: f32) -> Self {
45 Self { x, y }
46 }
47
48 #[inline]
50 pub const fn abs(self) -> Self {
51 Self {
52 x: if self.x < 0.0 { -self.x } else { self.x },
53 y: if self.y < 0.0 { -self.y } else { self.y },
54 }
55 }
56
57 #[inline]
60 pub fn length_squared(&self) -> f32 {
61 self.dot(*self)
62 }
63
64 #[inline]
66 pub fn length(&self) -> f32 {
67 self.length_squared().sqrt()
68 }
69
70 #[inline]
73 pub fn normalize(&self) -> Self {
74 let len_sq = self.length_squared();
75 if len_sq > EPSILON * EPSILON {
76 *self * (1.0 / len_sq.sqrt())
77 } else {
78 Self::ZERO
79 }
80 }
81
82 #[inline]
84 pub fn dot(&self, rhs: Self) -> f32 {
85 self.x * rhs.x + self.y * rhs.y
86 }
87
88 #[inline]
91 pub fn lerp(start: Self, end: Self, t: f32) -> Self {
92 start + (end - start) * t.clamp(0.0, 1.0)
93 }
94}
95
96impl Add for Vec2 {
99 type Output = Self;
100 #[inline]
102 fn add(self, rhs: Self) -> Self::Output {
103 Self {
104 x: self.x + rhs.x,
105 y: self.y + rhs.y,
106 }
107 }
108}
109
110impl Sub for Vec2 {
111 type Output = Self;
112 #[inline]
114 fn sub(self, rhs: Self) -> Self::Output {
115 Self {
116 x: self.x - rhs.x,
117 y: self.y - rhs.y,
118 }
119 }
120}
121
122impl Mul<f32> for Vec2 {
123 type Output = Self;
124 #[inline]
126 fn mul(self, rhs: f32) -> Self::Output {
127 Self {
128 x: self.x * rhs,
129 y: self.y * rhs,
130 }
131 }
132}
133
134impl Mul<Vec2> for f32 {
135 type Output = Vec2;
136 #[inline]
138 fn mul(self, rhs: Vec2) -> Self::Output {
139 rhs * self
140 }
141}
142
143impl Mul<Vec2> for Vec2 {
144 type Output = Self;
145 #[inline]
147 fn mul(self, rhs: Vec2) -> Self::Output {
148 Self {
149 x: self.x * rhs.x,
150 y: self.y * rhs.y,
151 }
152 }
153}
154
155impl Div<f32> for Vec2 {
156 type Output = Self;
157 #[inline]
159 fn div(self, rhs: f32) -> Self::Output {
160 let inv_rhs = 1.0 / rhs;
161 Self {
162 x: self.x * inv_rhs,
163 y: self.y * inv_rhs,
164 }
165 }
166}
167
168impl Neg for Vec2 {
169 type Output = Self;
170 #[inline]
172 fn neg(self) -> Self::Output {
173 Self {
174 x: -self.x,
175 y: -self.y,
176 }
177 }
178}
179
180impl Index<usize> for Vec2 {
181 type Output = f32;
182 #[inline]
187 fn index(&self, index: usize) -> &Self::Output {
188 match index {
189 0 => &self.x,
190 1 => &self.y,
191 _ => panic!("Index out of bounds for Vec2"),
192 }
193 }
194}
195
196impl IndexMut<usize> for Vec2 {
197 #[inline]
202 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
203 match index {
204 0 => &mut self.x,
205 1 => &mut self.y,
206 _ => panic!("Index out of bounds for Vec2"),
207 }
208 }
209}
210
211#[derive(Debug, Clone, Copy, PartialEq)]
215#[repr(C)]
216pub struct Vec3 {
217 pub x: f32,
219 pub y: f32,
221 pub z: f32,
223}
224
225impl Vec3 {
226 pub const ZERO: Self = Self {
228 x: 0.0,
229 y: 0.0,
230 z: 0.0,
231 };
232 pub const ONE: Self = Self {
234 x: 1.0,
235 y: 1.0,
236 z: 1.0,
237 };
238 pub const X: Self = Self {
240 x: 1.0,
241 y: 0.0,
242 z: 0.0,
243 };
244 pub const Y: Self = Self {
246 x: 0.0,
247 y: 1.0,
248 z: 0.0,
249 };
250 pub const Z: Self = Self {
252 x: 0.0,
253 y: 0.0,
254 z: 1.0,
255 };
256
257 #[inline]
259 pub const fn new(x: f32, y: f32, z: f32) -> Self {
260 Self { x, y, z }
261 }
262
263 #[inline]
265 pub const fn abs(self) -> Self {
266 Self {
267 x: if self.x < 0.0 { -self.x } else { self.x },
268 y: if self.y < 0.0 { -self.y } else { self.y },
269 z: if self.z < 0.0 { -self.z } else { self.z },
270 }
271 }
272
273 #[inline]
275 pub fn length_squared(&self) -> f32 {
276 self.dot(*self)
277 }
278
279 #[inline]
281 pub fn length(&self) -> f32 {
282 self.length_squared().sqrt()
283 }
284
285 #[inline]
287 pub fn normalize(&self) -> Self {
288 let len_sq = self.length_squared();
289 if len_sq > EPSILON * EPSILON {
290 *self * (1.0 / len_sq.sqrt())
293 } else {
294 Self::ZERO
295 }
296 }
297
298 #[inline]
300 pub fn dot(&self, other: Self) -> f32 {
301 self.x * other.x + self.y * other.y + self.z * other.z
302 }
303
304 #[inline]
306 pub fn cross(&self, other: Self) -> Self {
307 Self {
308 x: self.y * other.z - self.z * other.y,
309 y: self.z * other.x - self.x * other.z,
310 z: self.x * other.y - self.y * other.x,
311 }
312 }
313
314 #[inline]
316 pub fn distance_squared(&self, other: Self) -> f32 {
317 let dx = self.x - other.x;
318 let dy = self.y - other.y;
319 let dz = self.z - other.z;
320 dx * dx + dy * dy + dz * dz
321 }
322
323 #[inline]
325 pub fn distance(&self, other: Self) -> f32 {
326 self.distance_squared(other).sqrt()
327 }
328
329 #[inline]
331 pub fn lerp(start: Self, end: Self, t: f32) -> Self {
332 Self {
333 x: start.x + (end.x - start.x) * t,
334 y: start.y + (end.y - start.y) * t,
335 z: start.z + (end.z - start.z) * t,
336 }
337 }
338
339 #[inline]
344 pub fn get(&self, index: usize) -> f32 {
345 match index {
346 0 => self.x,
347 1 => self.y,
348 2 => self.z,
349 _ => panic!("Index out of bounds for Vec3"),
350 }
351 }
352}
353
354impl Default for Vec3 {
357 #[inline]
359 fn default() -> Self {
360 Self::ZERO
361 }
362}
363
364impl Add for Vec3 {
365 type Output = Self;
366 #[inline]
368 fn add(self, rhs: Self) -> Self::Output {
369 Self {
370 x: self.x + rhs.x,
371 y: self.y + rhs.y,
372 z: self.z + rhs.z,
373 }
374 }
375}
376
377impl Sub for Vec3 {
378 type Output = Self;
379 #[inline]
381 fn sub(self, rhs: Self) -> Self::Output {
382 Self {
383 x: self.x - rhs.x,
384 y: self.y - rhs.y,
385 z: self.z - rhs.z,
386 }
387 }
388}
389
390impl Mul<f32> for Vec3 {
391 type Output = Self;
392 #[inline]
394 fn mul(self, rhs: f32) -> Self::Output {
395 Self {
396 x: self.x * rhs,
397 y: self.y * rhs,
398 z: self.z * rhs,
399 }
400 }
401}
402
403impl Mul<Vec3> for f32 {
404 type Output = Vec3;
405 #[inline]
407 fn mul(self, rhs: Vec3) -> Self::Output {
408 rhs * self
409 }
410}
411
412impl Mul<Vec3> for Vec3 {
413 type Output = Self;
414 #[inline]
416 fn mul(self, rhs: Self) -> Self::Output {
417 Self {
418 x: self.x * rhs.x,
419 y: self.y * rhs.y,
420 z: self.z * rhs.z,
421 }
422 }
423}
424
425impl Div<f32> for Vec3 {
426 type Output = Self;
427 #[inline]
429 fn div(self, rhs: f32) -> Self::Output {
430 let inv_rhs = 1.0 / rhs;
431 Self {
432 x: self.x * inv_rhs,
433 y: self.y * inv_rhs,
434 z: self.z * inv_rhs,
435 }
436 }
437}
438
439impl Neg for Vec3 {
440 type Output = Self;
441 #[inline]
443 fn neg(self) -> Self::Output {
444 Self {
445 x: -self.x,
446 y: -self.y,
447 z: -self.z,
448 }
449 }
450}
451
452impl Index<usize> for Vec3 {
453 type Output = f32;
454 #[inline]
458 fn index(&self, index: usize) -> &Self::Output {
459 match index {
460 0 => &self.x,
461 1 => &self.y,
462 2 => &self.z,
463 _ => panic!("Index out of bounds for Vec3"),
464 }
465 }
466}
467
468impl IndexMut<usize> for Vec3 {
469 #[inline]
473 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
474 match index {
475 0 => &mut self.x,
476 1 => &mut self.y,
477 2 => &mut self.z,
478 _ => panic!("Index out of bounds for Vec3"),
479 }
480 }
481}
482
483#[derive(Debug, Default, Copy, Clone, PartialEq)]
490#[repr(C)]
491pub struct Vec4 {
492 pub x: f32,
494 pub y: f32,
496 pub z: f32,
498 pub w: f32,
500}
501
502impl Vec4 {
503 pub const ZERO: Self = Self {
505 x: 0.0,
506 y: 0.0,
507 z: 0.0,
508 w: 0.0,
509 };
510 pub const ONE: Self = Self {
512 x: 1.0,
513 y: 1.0,
514 z: 1.0,
515 w: 1.0,
516 };
517 pub const X: Self = Self {
519 x: 1.0,
520 y: 0.0,
521 z: 0.0,
522 w: 0.0,
523 };
524 pub const Y: Self = Self {
526 x: 0.0,
527 y: 1.0,
528 z: 0.0,
529 w: 0.0,
530 };
531 pub const Z: Self = Self {
533 x: 0.0,
534 y: 0.0,
535 z: 1.0,
536 w: 0.0,
537 };
538 pub const W: Self = Self {
540 x: 0.0,
541 y: 0.0,
542 z: 0.0,
543 w: 1.0,
544 };
545
546 #[inline]
548 pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
549 Self { x, y, z, w }
550 }
551
552 #[inline]
554 pub const fn abs(self) -> Self {
555 Self {
556 x: if self.x < 0.0 { -self.x } else { self.x },
557 y: if self.y < 0.0 { -self.y } else { self.y },
558 z: if self.z < 0.0 { -self.z } else { self.z },
559 w: if self.w < 0.0 { -self.w } else { self.w },
560 }
561 }
562
563 #[inline]
565 pub fn from_vec3(v: Vec3, w: f32) -> Self {
566 Self::new(v.x, v.y, v.z, w)
567 }
568
569 #[inline]
571 pub fn truncate(&self) -> Vec3 {
572 Vec3::new(self.x, self.y, self.z)
573 }
574
575 #[inline]
577 pub fn dot(&self, other: Self) -> f32 {
578 self.x * other.x + self.y * other.y + self.z * other.z + self.w * other.w
579 }
580
581 #[inline]
586 pub fn get(&self, index: usize) -> f32 {
587 match index {
588 0 => self.x,
589 1 => self.y,
590 2 => self.z,
591 3 => self.w,
592 _ => panic!("Index out of bounds for Vec4"),
593 }
594 }
595}
596
597impl Add for Vec4 {
600 type Output = Self;
601 #[inline]
603 fn add(self, rhs: Self) -> Self::Output {
604 Self {
605 x: self.x + rhs.x,
606 y: self.y + rhs.y,
607 z: self.z + rhs.z,
608 w: self.w + rhs.w,
609 }
610 }
611}
612
613impl Sub for Vec4 {
614 type Output = Self;
615 #[inline]
617 fn sub(self, rhs: Self) -> Self::Output {
618 Self {
619 x: self.x - rhs.x,
620 y: self.y - rhs.y,
621 z: self.z - rhs.z,
622 w: self.w - rhs.w,
623 }
624 }
625}
626
627impl Mul<f32> for Vec4 {
628 type Output = Self;
629 #[inline]
631 fn mul(self, rhs: f32) -> Self::Output {
632 Self {
633 x: self.x * rhs,
634 y: self.y * rhs,
635 z: self.z * rhs,
636 w: self.w * rhs,
637 }
638 }
639}
640
641impl Mul<Vec4> for f32 {
642 type Output = Vec4;
643 #[inline]
645 fn mul(self, rhs: Vec4) -> Self::Output {
646 rhs * self
647 }
648}
649
650impl Mul<Vec4> for Vec4 {
651 type Output = Self;
652 #[inline]
654 fn mul(self, rhs: Self) -> Self::Output {
655 Self {
656 x: self.x * rhs.x,
657 y: self.y * rhs.y,
658 z: self.z * rhs.z,
659 w: self.w * rhs.w,
660 }
661 }
662}
663
664impl Div<f32> for Vec4 {
665 type Output = Self;
666 #[inline]
668 fn div(self, rhs: f32) -> Self::Output {
669 let inv_rhs = 1.0 / rhs;
670 Self {
671 x: self.x * inv_rhs,
672 y: self.y * inv_rhs,
673 z: self.z * inv_rhs,
674 w: self.w * inv_rhs,
675 }
676 }
677}
678
679impl Neg for Vec4 {
680 type Output = Self;
681 #[inline]
683 fn neg(self) -> Self::Output {
684 Self {
685 x: -self.x,
686 y: -self.y,
687 z: -self.z,
688 w: -self.w,
689 }
690 }
691}
692
693impl Index<usize> for Vec4 {
694 type Output = f32;
695 #[inline]
699 fn index(&self, index: usize) -> &Self::Output {
700 match index {
701 0 => &self.x,
702 1 => &self.y,
703 2 => &self.z,
704 3 => &self.w,
705 _ => panic!("Index out of bounds for Vec4"),
706 }
707 }
708}
709
710impl IndexMut<usize> for Vec4 {
711 #[inline]
715 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
716 match index {
717 0 => &mut self.x,
718 1 => &mut self.y,
719 2 => &mut self.z,
720 3 => &mut self.w,
721 _ => panic!("Index out of bounds for Vec4"),
722 }
723 }
724}
725
726#[cfg(test)]
728mod tests {
729 use super::*; use crate::math::approx_eq;
731
732 fn vec2_approx_eq(a: Vec2, b: Vec2) -> bool {
733 approx_eq(a.x, b.x) && approx_eq(a.y, b.y)
734 }
735
736 fn vec3_approx_eq(a: Vec3, b: Vec3) -> bool {
737 approx_eq(a.x, b.x) && approx_eq(a.y, b.y) && approx_eq(a.z, b.z)
738 }
739
740 #[test]
743 fn test_vec2_new() {
744 let v = Vec2::new(1.0, 2.0);
745 assert_eq!(v.x, 1.0);
746 assert_eq!(v.y, 2.0);
747 }
748
749 #[test]
750 fn test_vec2_abs() {
751 let v = Vec2::new(-1.0, 2.0);
752 assert_eq!(v.abs(), Vec2::new(1.0, 2.0));
753 }
754
755 #[test]
756 fn test_vec2_constants() {
757 assert_eq!(Vec2::ZERO, Vec2::new(0.0, 0.0));
758 assert_eq!(Vec2::ONE, Vec2::new(1.0, 1.0));
759 assert_eq!(Vec2::X, Vec2::new(1.0, 0.0));
760 assert_eq!(Vec2::Y, Vec2::new(0.0, 1.0));
761 }
762
763 #[test]
764 fn test_vec2_ops() {
765 let v1 = Vec2::new(1.0, 2.0);
766 let v2 = Vec2::new(3.0, 4.0);
767 assert_eq!(v1 + v2, Vec2::new(4.0, 6.0));
768 assert_eq!(v2 - v1, Vec2::new(2.0, 2.0));
769 assert_eq!(v1 * 2.0, Vec2::new(2.0, 4.0));
770 assert_eq!(3.0 * v1, Vec2::new(3.0, 6.0));
771 assert_eq!(v1 * v2, Vec2::new(3.0, 8.0)); assert_eq!(-v1, Vec2::new(-1.0, -2.0));
773 assert!(vec2_approx_eq(
774 Vec2::new(4.0, 6.0) / 2.0,
775 Vec2::new(2.0, 3.0)
776 ));
777 }
778
779 #[test]
780 fn test_vec2_dot() {
781 let v1 = Vec2::new(1.0, 2.0);
782 let v2 = Vec2::new(3.0, 4.0);
783 assert!(approx_eq(v1.dot(v2), 1.0 * 3.0 + 2.0 * 4.0)); }
785
786 #[test]
787 fn test_vec2_length() {
788 let v = Vec2::new(3.0, 4.0);
789 assert!(approx_eq(v.length_squared(), 25.0));
790 assert!(approx_eq(v.length(), 5.0));
791 assert!(approx_eq(Vec2::ZERO.length(), 0.0));
792 }
793
794 #[test]
795 fn test_vec2_normalize() {
796 let v1 = Vec2::new(3.0, 0.0);
797 let norm_v1 = v1.normalize();
798 assert!(vec2_approx_eq(norm_v1, Vec2::X));
799 assert!(approx_eq(norm_v1.length(), 1.0));
800
801 let v_zero = Vec2::ZERO;
802 assert_eq!(v_zero.normalize(), Vec2::ZERO);
803 }
804
805 #[test]
806 fn test_vec2_lerp() {
807 let start = Vec2::new(0.0, 10.0);
808 let end = Vec2::new(10.0, 0.0);
809 assert!(vec2_approx_eq(Vec2::lerp(start, end, 0.0), start));
810 assert!(vec2_approx_eq(Vec2::lerp(start, end, 1.0), end));
811 assert!(vec2_approx_eq(
812 Vec2::lerp(start, end, 0.5),
813 Vec2::new(5.0, 5.0)
814 ));
815 assert!(vec2_approx_eq(Vec2::lerp(start, end, -0.5), start));
817 assert!(vec2_approx_eq(Vec2::lerp(start, end, 1.5), end));
818 }
819
820 #[test]
821 fn test_vec2_index() {
822 let mut v = Vec2::new(5.0, 6.0);
823 assert_eq!(v[0], 5.0);
824 assert_eq!(v[1], 6.0);
825 v[0] = 10.0;
826 assert_eq!(v.x, 10.0);
827 }
828
829 #[test]
830 #[should_panic]
831 fn test_vec2_index_out_of_bounds() {
832 let v = Vec2::new(1.0, 2.0);
833 let _ = v[2]; }
835
836 #[test]
839 fn test_new() {
840 let v = Vec3::new(1.0, 2.0, 3.0);
841 assert_eq!(v.x, 1.0);
842 assert_eq!(v.y, 2.0);
843 assert_eq!(v.z, 3.0);
844 }
845
846 #[test]
847 fn test_vec3_abs() {
848 let v = Vec3::new(-1.0, 2.0, -3.0);
849 assert_eq!(v.abs(), Vec3::new(1.0, 2.0, 3.0));
850 assert_eq!(Vec3::ZERO.abs(), Vec3::ZERO);
851 }
852
853 #[test]
854 fn test_constants() {
855 assert_eq!(Vec3::ZERO, Vec3::new(0.0, 0.0, 0.0));
856 assert_eq!(Vec3::ONE, Vec3::new(1.0, 1.0, 1.0));
857 assert_eq!(Vec3::X, Vec3::new(1.0, 0.0, 0.0));
858 assert_eq!(Vec3::Y, Vec3::new(0.0, 1.0, 0.0));
859 assert_eq!(Vec3::Z, Vec3::new(0.0, 0.0, 1.0));
860 }
861
862 #[test]
863 fn test_add() {
864 let v1 = Vec3::new(1.0, 2.0, 3.0);
865 let v2 = Vec3::new(4.0, 5.0, 6.0);
866 assert_eq!(v1 + v2, Vec3::new(5.0, 7.0, 9.0));
867 }
868
869 #[test]
870 fn test_sub() {
871 let v1 = Vec3::new(5.0, 7.0, 9.0);
872 let v2 = Vec3::new(1.0, 2.0, 3.0);
873 assert_eq!(v1 - v2, Vec3::new(4.0, 5.0, 6.0));
874 }
875
876 #[test]
877 fn test_scalar_mul() {
878 let v = Vec3::new(1.0, 2.0, 3.0);
879 assert_eq!(v * 2.0, Vec3::new(2.0, 4.0, 6.0));
880 assert_eq!(3.0 * v, Vec3::new(3.0, 6.0, 9.0)); }
882
883 #[test]
884 fn test_component_mul() {
885 let v1 = Vec3::new(1.0, 2.0, 3.0);
886 let v2 = Vec3::new(4.0, 5.0, 6.0);
887 assert_eq!(v1 * v2, Vec3::new(4.0, 10.0, 18.0));
888 }
889
890 #[test]
891 fn test_scalar_div() {
892 let v = Vec3::new(2.0, 4.0, 6.0);
893 assert_eq!(v / 2.0, Vec3::new(1.0, 2.0, 3.0));
894 }
895
896 #[test]
897 fn test_neg() {
898 let v = Vec3::new(1.0, -2.0, 3.0);
899 assert_eq!(-v, Vec3::new(-1.0, 2.0, -3.0));
900 }
901
902 #[test]
903 fn test_length() {
904 let v1 = Vec3::new(3.0, 4.0, 0.0);
905 assert!(approx_eq(v1.length_squared(), 25.0));
906 assert!(approx_eq(v1.length(), 5.0));
907
908 let v2 = Vec3::ZERO;
909 assert!(approx_eq(v2.length_squared(), 0.0));
910 assert!(approx_eq(v2.length(), 0.0));
911 }
912
913 #[test]
914 fn test_dot() {
915 let v1 = Vec3::new(1.0, 2.0, 3.0);
916 let v2 = Vec3::new(4.0, -5.0, 6.0);
917 assert!(approx_eq(v1.dot(v2), 12.0));
919
920 assert!(approx_eq(Vec3::X.dot(Vec3::Y), 0.0));
922 }
923
924 #[test]
925 fn test_distance() {
926 let v1 = Vec3::new(1.0, 2.0, 3.0);
927 let v2 = Vec3::new(4.0, 5.0, 6.0);
928 assert!(approx_eq(v1.distance(v2), 3.0 * (3.0_f32).sqrt()));
930 }
931
932 #[test]
933 fn test_cross() {
934 assert_eq!(Vec3::X.cross(Vec3::Y), Vec3::Z);
936 assert_eq!(Vec3::Y.cross(Vec3::Z), Vec3::X);
937 assert_eq!(Vec3::Z.cross(Vec3::X), Vec3::Y);
938
939 assert_eq!(Vec3::Y.cross(Vec3::X), -Vec3::Z);
941
942 assert_eq!(Vec3::X.cross(Vec3::X), Vec3::ZERO);
944 }
945
946 #[test]
947 fn test_normalize() {
948 let v1 = Vec3::new(3.0, 0.0, 0.0);
949 let norm_v1 = v1.normalize();
950 assert!(vec3_approx_eq(norm_v1, Vec3::X));
951 assert!(approx_eq(norm_v1.length(), 1.0));
952
953 let v2 = Vec3::new(1.0, 1.0, 1.0);
954 let norm_v2 = v2.normalize();
955 assert!(approx_eq(norm_v2.length(), 1.0)); let v_zero = Vec3::ZERO;
959 assert_eq!(v_zero.normalize(), Vec3::ZERO);
960 }
961
962 #[test]
963 fn test_lerp() {
964 let start = Vec3::new(0.0, 0.0, 0.0);
965 let end = Vec3::new(10.0, 10.0, 10.0);
966
967 assert!(vec3_approx_eq(Vec3::lerp(start, end, 0.0), start));
968 assert!(vec3_approx_eq(Vec3::lerp(start, end, 1.0), end));
969 assert!(vec3_approx_eq(
970 Vec3::lerp(start, end, 0.5),
971 Vec3::new(5.0, 5.0, 5.0)
972 ));
973 }
974
975 #[test]
978 fn test_vec4_new() {
979 let v = Vec4::new(1.0, 2.0, 3.0, 4.0);
980 assert_eq!(v.x, 1.0);
981 assert_eq!(v.y, 2.0);
982 assert_eq!(v.z, 3.0);
983 assert_eq!(v.w, 4.0);
984 }
985
986 #[test]
987 fn test_vec4_abs() {
988 let v = Vec4::new(-1.0, 2.0, -3.0, -0.5);
989 assert_eq!(v.abs(), Vec4::new(1.0, 2.0, 3.0, 0.5));
990 }
991
992 #[test]
993 fn test_vec4_from_vec3() {
994 let v3 = Vec3::new(1.0, 2.0, 3.0);
995 let v4 = Vec4::from_vec3(v3, 4.0);
996 assert_eq!(v4, Vec4::new(1.0, 2.0, 3.0, 4.0));
997 }
998
999 #[test]
1000 fn test_vec4_truncate() {
1001 let v4 = Vec4::new(1.0, 2.0, 3.0, 4.0);
1002 let v3 = v4.truncate();
1003 assert_eq!(v3, Vec3::new(1.0, 2.0, 3.0));
1004 }
1005}