1use std::ops::{Add, Div, Mul, Neg, Sub};
34
35pub use cgmath::{Matrix3, Matrix4, Point3, Quaternion};
37
38#[repr(C)]
48#[derive(Clone, Copy, Debug, PartialEq, Default)]
49pub struct Vec2 {
50 pub x: f32,
52 pub y: f32,
54}
55
56impl Vec2 {
57 #[inline]
59 pub const fn new(x: f32, y: f32) -> Self {
60 Self { x, y }
61 }
62
63 #[inline]
65 pub const fn zero() -> Self {
66 Self { x: 0.0, y: 0.0 }
67 }
68
69 #[inline]
71 pub const fn one() -> Self {
72 Self { x: 1.0, y: 1.0 }
73 }
74
75 #[inline]
77 pub const fn unit_x() -> Self {
78 Self { x: 1.0, y: 0.0 }
79 }
80
81 #[inline]
83 pub const fn unit_y() -> Self {
84 Self { x: 0.0, y: 1.0 }
85 }
86
87 #[inline]
89 pub fn dot(self, other: Self) -> f32 {
90 self.x * other.x + self.y * other.y
91 }
92
93 #[inline]
97 pub fn length_squared(self) -> f32 {
98 self.dot(self)
99 }
100
101 #[inline]
103 pub fn length(self) -> f32 {
104 self.length_squared().sqrt()
105 }
106
107 #[inline]
111 pub fn normalize(self) -> Self {
112 let len = self.length();
113 if len == 0.0 {
114 Self::zero()
115 } else {
116 self / len
117 }
118 }
119
120 #[inline]
124 pub fn lerp(self, other: Self, t: f32) -> Self {
125 Self {
126 x: self.x + (other.x - self.x) * t,
127 y: self.y + (other.y - self.y) * t,
128 }
129 }
130
131 #[inline]
133 pub fn perpendicular(self) -> Self {
134 Self {
135 x: -self.y,
136 y: self.x,
137 }
138 }
139}
140
141impl Add for Vec2 {
143 type Output = Self;
144 #[inline]
145 fn add(self, other: Self) -> Self {
146 Self {
147 x: self.x + other.x,
148 y: self.y + other.y,
149 }
150 }
151}
152
153impl Sub for Vec2 {
154 type Output = Self;
155 #[inline]
156 fn sub(self, other: Self) -> Self {
157 Self {
158 x: self.x - other.x,
159 y: self.y - other.y,
160 }
161 }
162}
163
164impl Mul<f32> for Vec2 {
165 type Output = Self;
166 #[inline]
167 fn mul(self, scalar: f32) -> Self {
168 Self {
169 x: self.x * scalar,
170 y: self.y * scalar,
171 }
172 }
173}
174
175impl Mul<Vec2> for f32 {
176 type Output = Vec2;
177 #[inline]
178 fn mul(self, vec: Vec2) -> Vec2 {
179 vec * self
180 }
181}
182
183impl Div<f32> for Vec2 {
184 type Output = Self;
185 #[inline]
186 fn div(self, scalar: f32) -> Self {
187 Self {
188 x: self.x / scalar,
189 y: self.y / scalar,
190 }
191 }
192}
193
194impl Neg for Vec2 {
195 type Output = Self;
196 #[inline]
197 fn neg(self) -> Self {
198 Self {
199 x: -self.x,
200 y: -self.y,
201 }
202 }
203}
204
205impl From<cgmath::Vector2<f32>> for Vec2 {
207 #[inline]
208 fn from(v: cgmath::Vector2<f32>) -> Self {
209 Self { x: v.x, y: v.y }
210 }
211}
212
213impl From<Vec2> for cgmath::Vector2<f32> {
214 #[inline]
215 fn from(v: Vec2) -> Self {
216 cgmath::Vector2::new(v.x, v.y)
217 }
218}
219
220#[repr(C)]
230#[derive(Clone, Copy, Debug, PartialEq, Default)]
231pub struct Vec3 {
232 pub x: f32,
234 pub y: f32,
236 pub z: f32,
238}
239
240impl Vec3 {
241 #[inline]
243 pub const fn new(x: f32, y: f32, z: f32) -> Self {
244 Self { x, y, z }
245 }
246
247 #[inline]
249 pub const fn zero() -> Self {
250 Self {
251 x: 0.0,
252 y: 0.0,
253 z: 0.0,
254 }
255 }
256
257 #[inline]
259 pub const fn one() -> Self {
260 Self {
261 x: 1.0,
262 y: 1.0,
263 z: 1.0,
264 }
265 }
266
267 #[inline]
269 pub const fn unit_x() -> Self {
270 Self {
271 x: 1.0,
272 y: 0.0,
273 z: 0.0,
274 }
275 }
276
277 #[inline]
279 pub const fn unit_y() -> Self {
280 Self {
281 x: 0.0,
282 y: 1.0,
283 z: 0.0,
284 }
285 }
286
287 #[inline]
289 pub const fn unit_z() -> Self {
290 Self {
291 x: 0.0,
292 y: 0.0,
293 z: 1.0,
294 }
295 }
296
297 #[inline]
299 pub fn dot(self, other: Self) -> f32 {
300 self.x * other.x + self.y * other.y + self.z * other.z
301 }
302
303 #[inline]
307 pub fn cross(self, other: Self) -> Self {
308 Self {
309 x: self.y * other.z - self.z * other.y,
310 y: self.z * other.x - self.x * other.z,
311 z: self.x * other.y - self.y * other.x,
312 }
313 }
314
315 #[inline]
317 pub fn length_squared(self) -> f32 {
318 self.dot(self)
319 }
320
321 #[inline]
323 pub fn length(self) -> f32 {
324 self.length_squared().sqrt()
325 }
326
327 #[inline]
331 pub fn normalize(self) -> Self {
332 let len = self.length();
333 if len == 0.0 {
334 Self::zero()
335 } else {
336 self / len
337 }
338 }
339
340 #[inline]
342 pub fn lerp(self, other: Self, t: f32) -> Self {
343 Self {
344 x: self.x + (other.x - self.x) * t,
345 y: self.y + (other.y - self.y) * t,
346 z: self.z + (other.z - self.z) * t,
347 }
348 }
349}
350
351impl Add for Vec3 {
353 type Output = Self;
354 #[inline]
355 fn add(self, other: Self) -> Self {
356 Self {
357 x: self.x + other.x,
358 y: self.y + other.y,
359 z: self.z + other.z,
360 }
361 }
362}
363
364impl Sub for Vec3 {
365 type Output = Self;
366 #[inline]
367 fn sub(self, other: Self) -> Self {
368 Self {
369 x: self.x - other.x,
370 y: self.y - other.y,
371 z: self.z - other.z,
372 }
373 }
374}
375
376impl Mul<f32> for Vec3 {
377 type Output = Self;
378 #[inline]
379 fn mul(self, scalar: f32) -> Self {
380 Self {
381 x: self.x * scalar,
382 y: self.y * scalar,
383 z: self.z * scalar,
384 }
385 }
386}
387
388impl Mul<Vec3> for f32 {
389 type Output = Vec3;
390 #[inline]
391 fn mul(self, vec: Vec3) -> Vec3 {
392 vec * self
393 }
394}
395
396impl Div<f32> for Vec3 {
397 type Output = Self;
398 #[inline]
399 fn div(self, scalar: f32) -> Self {
400 Self {
401 x: self.x / scalar,
402 y: self.y / scalar,
403 z: self.z / scalar,
404 }
405 }
406}
407
408impl Neg for Vec3 {
409 type Output = Self;
410 #[inline]
411 fn neg(self) -> Self {
412 Self {
413 x: -self.x,
414 y: -self.y,
415 z: -self.z,
416 }
417 }
418}
419
420impl From<cgmath::Vector3<f32>> for Vec3 {
422 #[inline]
423 fn from(v: cgmath::Vector3<f32>) -> Self {
424 Self {
425 x: v.x,
426 y: v.y,
427 z: v.z,
428 }
429 }
430}
431
432impl From<Vec3> for cgmath::Vector3<f32> {
433 #[inline]
434 fn from(v: Vec3) -> Self {
435 cgmath::Vector3::new(v.x, v.y, v.z)
436 }
437}
438
439#[repr(C)]
449#[derive(Clone, Copy, Debug, PartialEq, Default)]
450pub struct Vec4 {
451 pub x: f32,
453 pub y: f32,
455 pub z: f32,
457 pub w: f32,
459}
460
461impl Vec4 {
462 #[inline]
464 pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
465 Self { x, y, z, w }
466 }
467
468 #[inline]
470 pub const fn zero() -> Self {
471 Self {
472 x: 0.0,
473 y: 0.0,
474 z: 0.0,
475 w: 0.0,
476 }
477 }
478
479 #[inline]
481 pub const fn one() -> Self {
482 Self {
483 x: 1.0,
484 y: 1.0,
485 z: 1.0,
486 w: 1.0,
487 }
488 }
489
490 #[inline]
492 pub const fn from_vec3(v: Vec3, w: f32) -> Self {
493 Self {
494 x: v.x,
495 y: v.y,
496 z: v.z,
497 w,
498 }
499 }
500
501 #[inline]
503 pub const fn xyz(self) -> Vec3 {
504 Vec3 {
505 x: self.x,
506 y: self.y,
507 z: self.z,
508 }
509 }
510
511 #[inline]
513 pub fn dot(self, other: Self) -> f32 {
514 self.x * other.x + self.y * other.y + self.z * other.z + self.w * other.w
515 }
516
517 #[inline]
519 pub fn length_squared(self) -> f32 {
520 self.dot(self)
521 }
522
523 #[inline]
525 pub fn length(self) -> f32 {
526 self.length_squared().sqrt()
527 }
528
529 #[inline]
531 pub fn normalize(self) -> Self {
532 let len = self.length();
533 if len == 0.0 {
534 Self::zero()
535 } else {
536 self / len
537 }
538 }
539
540 #[inline]
542 pub fn lerp(self, other: Self, t: f32) -> Self {
543 Self {
544 x: self.x + (other.x - self.x) * t,
545 y: self.y + (other.y - self.y) * t,
546 z: self.z + (other.z - self.z) * t,
547 w: self.w + (other.w - self.w) * t,
548 }
549 }
550}
551
552impl Add for Vec4 {
554 type Output = Self;
555 #[inline]
556 fn add(self, other: Self) -> Self {
557 Self {
558 x: self.x + other.x,
559 y: self.y + other.y,
560 z: self.z + other.z,
561 w: self.w + other.w,
562 }
563 }
564}
565
566impl Sub for Vec4 {
567 type Output = Self;
568 #[inline]
569 fn sub(self, other: Self) -> Self {
570 Self {
571 x: self.x - other.x,
572 y: self.y - other.y,
573 z: self.z - other.z,
574 w: self.w - other.w,
575 }
576 }
577}
578
579impl Mul<f32> for Vec4 {
580 type Output = Self;
581 #[inline]
582 fn mul(self, scalar: f32) -> Self {
583 Self {
584 x: self.x * scalar,
585 y: self.y * scalar,
586 z: self.z * scalar,
587 w: self.w * scalar,
588 }
589 }
590}
591
592impl Mul<Vec4> for f32 {
593 type Output = Vec4;
594 #[inline]
595 fn mul(self, vec: Vec4) -> Vec4 {
596 vec * self
597 }
598}
599
600impl Div<f32> for Vec4 {
601 type Output = Self;
602 #[inline]
603 fn div(self, scalar: f32) -> Self {
604 Self {
605 x: self.x / scalar,
606 y: self.y / scalar,
607 z: self.z / scalar,
608 w: self.w / scalar,
609 }
610 }
611}
612
613impl Neg for Vec4 {
614 type Output = Self;
615 #[inline]
616 fn neg(self) -> Self {
617 Self {
618 x: -self.x,
619 y: -self.y,
620 z: -self.z,
621 w: -self.w,
622 }
623 }
624}
625
626impl From<cgmath::Vector4<f32>> for Vec4 {
628 #[inline]
629 fn from(v: cgmath::Vector4<f32>) -> Self {
630 Self {
631 x: v.x,
632 y: v.y,
633 z: v.z,
634 w: v.w,
635 }
636 }
637}
638
639impl From<Vec4> for cgmath::Vector4<f32> {
640 #[inline]
641 fn from(v: Vec4) -> Self {
642 cgmath::Vector4::new(v.x, v.y, v.z, v.w)
643 }
644}
645
646#[repr(C)]
655#[derive(Clone, Copy, Debug, PartialEq, Default)]
656pub struct Rect {
657 pub x: f32,
659 pub y: f32,
661 pub width: f32,
663 pub height: f32,
665}
666
667impl Rect {
668 #[inline]
670 pub const fn new(x: f32, y: f32, width: f32, height: f32) -> Self {
671 Self {
672 x,
673 y,
674 width,
675 height,
676 }
677 }
678
679 #[inline]
681 pub fn from_min_max(min: Vec2, max: Vec2) -> Self {
682 Self {
683 x: min.x,
684 y: min.y,
685 width: max.x - min.x,
686 height: max.y - min.y,
687 }
688 }
689
690 #[inline]
692 pub const fn unit() -> Self {
693 Self {
694 x: 0.0,
695 y: 0.0,
696 width: 1.0,
697 height: 1.0,
698 }
699 }
700
701 #[inline]
703 pub const fn min(&self) -> Vec2 {
704 Vec2 {
705 x: self.x,
706 y: self.y,
707 }
708 }
709
710 #[inline]
712 pub fn max(&self) -> Vec2 {
713 Vec2 {
714 x: self.x + self.width,
715 y: self.y + self.height,
716 }
717 }
718
719 #[inline]
721 pub fn center(&self) -> Vec2 {
722 Vec2 {
723 x: self.x + self.width * 0.5,
724 y: self.y + self.height * 0.5,
725 }
726 }
727
728 #[inline]
730 pub const fn size(&self) -> Vec2 {
731 Vec2 {
732 x: self.width,
733 y: self.height,
734 }
735 }
736
737 #[inline]
739 pub fn area(&self) -> f32 {
740 self.width * self.height
741 }
742
743 #[inline]
745 pub fn contains(&self, point: Vec2) -> bool {
746 point.x >= self.x
747 && point.x < self.x + self.width
748 && point.y >= self.y
749 && point.y < self.y + self.height
750 }
751
752 #[inline]
754 pub fn intersects(&self, other: &Rect) -> bool {
755 self.x < other.x + other.width
756 && self.x + self.width > other.x
757 && self.y < other.y + other.height
758 && self.y + self.height > other.y
759 }
760
761 pub fn intersection(&self, other: &Rect) -> Option<Rect> {
763 let x = self.x.max(other.x);
764 let y = self.y.max(other.y);
765 let max_x = (self.x + self.width).min(other.x + other.width);
766 let max_y = (self.y + self.height).min(other.y + other.height);
767
768 if x < max_x && y < max_y {
769 Some(Rect {
770 x,
771 y,
772 width: max_x - x,
773 height: max_y - y,
774 })
775 } else {
776 None
777 }
778 }
779}
780
781#[repr(C)]
790#[derive(Clone, Copy, Debug, PartialEq, Default)]
791pub struct Color {
792 pub r: f32,
794 pub g: f32,
796 pub b: f32,
798 pub a: f32,
800}
801
802impl Color {
803 pub const WHITE: Color = Color::rgb(1.0, 1.0, 1.0);
806 pub const BLACK: Color = Color::rgb(0.0, 0.0, 0.0);
808 pub const RED: Color = Color::rgb(1.0, 0.0, 0.0);
810 pub const GREEN: Color = Color::rgb(0.0, 1.0, 0.0);
812 pub const BLUE: Color = Color::rgb(0.0, 0.0, 1.0);
814 pub const YELLOW: Color = Color::rgb(1.0, 1.0, 0.0);
816 pub const CYAN: Color = Color::rgb(0.0, 1.0, 1.0);
818 pub const MAGENTA: Color = Color::rgb(1.0, 0.0, 1.0);
820 pub const TRANSPARENT: Color = Color::rgba(0.0, 0.0, 0.0, 0.0);
822 pub const GRAY: Color = Color::rgb(0.5, 0.5, 0.5);
824
825 #[inline]
827 pub const fn new(r: f32, g: f32, b: f32, a: f32) -> Self {
828 Self { r, g, b, a }
829 }
830
831 #[inline]
833 pub const fn rgb(r: f32, g: f32, b: f32) -> Self {
834 Self { r, g, b, a: 1.0 }
835 }
836
837 #[inline]
839 pub const fn rgba(r: f32, g: f32, b: f32, a: f32) -> Self {
840 Self { r, g, b, a }
841 }
842
843 #[inline]
845 pub fn from_u8(r: u8, g: u8, b: u8, a: u8) -> Self {
846 Self {
847 r: r as f32 / 255.0,
848 g: g as f32 / 255.0,
849 b: b as f32 / 255.0,
850 a: a as f32 / 255.0,
851 }
852 }
853
854 #[inline]
856 pub fn from_hex(hex: u32) -> Self {
857 if hex > 0xFFFFFF {
858 Self::from_u8(
860 ((hex >> 24) & 0xFF) as u8,
861 ((hex >> 16) & 0xFF) as u8,
862 ((hex >> 8) & 0xFF) as u8,
863 (hex & 0xFF) as u8,
864 )
865 } else {
866 Self::from_u8(
868 ((hex >> 16) & 0xFF) as u8,
869 ((hex >> 8) & 0xFF) as u8,
870 (hex & 0xFF) as u8,
871 255,
872 )
873 }
874 }
875
876 #[inline]
878 pub const fn to_vec3(&self) -> Vec3 {
879 Vec3 {
880 x: self.r,
881 y: self.g,
882 z: self.b,
883 }
884 }
885
886 #[inline]
888 pub const fn to_vec4(&self) -> Vec4 {
889 Vec4 {
890 x: self.r,
891 y: self.g,
892 z: self.b,
893 w: self.a,
894 }
895 }
896
897 #[inline]
899 pub const fn from_vec3(v: Vec3) -> Self {
900 Self {
901 r: v.x,
902 g: v.y,
903 b: v.z,
904 a: 1.0,
905 }
906 }
907
908 #[inline]
910 pub const fn from_vec4(v: Vec4) -> Self {
911 Self {
912 r: v.x,
913 g: v.y,
914 b: v.z,
915 a: v.w,
916 }
917 }
918
919 #[inline]
921 pub fn lerp(self, other: Self, t: f32) -> Self {
922 Self {
923 r: self.r + (other.r - self.r) * t,
924 g: self.g + (other.g - self.g) * t,
925 b: self.b + (other.b - self.b) * t,
926 a: self.a + (other.a - self.a) * t,
927 }
928 }
929
930 #[inline]
932 pub const fn with_alpha(self, a: f32) -> Self {
933 Self {
934 r: self.r,
935 g: self.g,
936 b: self.b,
937 a,
938 }
939 }
940
941 #[inline]
943 pub fn clamp(self) -> Self {
944 Self {
945 r: self.r.clamp(0.0, 1.0),
946 g: self.g.clamp(0.0, 1.0),
947 b: self.b.clamp(0.0, 1.0),
948 a: self.a.clamp(0.0, 1.0),
949 }
950 }
951}
952
953#[cfg(test)]
958mod tests {
959 use super::*;
960
961 #[test]
966 fn test_vec2_constructors() {
967 assert_eq!(Vec2::new(1.0, 2.0), Vec2 { x: 1.0, y: 2.0 });
968 assert_eq!(Vec2::zero(), Vec2 { x: 0.0, y: 0.0 });
969 assert_eq!(Vec2::one(), Vec2 { x: 1.0, y: 1.0 });
970 assert_eq!(Vec2::unit_x(), Vec2 { x: 1.0, y: 0.0 });
971 assert_eq!(Vec2::unit_y(), Vec2 { x: 0.0, y: 1.0 });
972 }
973
974 #[test]
975 fn test_vec2_dot() {
976 let a = Vec2::new(2.0, 3.0);
977 let b = Vec2::new(4.0, 5.0);
978 assert_eq!(a.dot(b), 23.0); }
980
981 #[test]
982 fn test_vec2_length() {
983 let v = Vec2::new(3.0, 4.0);
984 assert_eq!(v.length_squared(), 25.0);
985 assert_eq!(v.length(), 5.0);
986 }
987
988 #[test]
989 fn test_vec2_normalize() {
990 let v = Vec2::new(3.0, 4.0);
991 let n = v.normalize();
992 assert!((n.length() - 1.0).abs() < 0.0001);
993 assert_eq!(Vec2::zero().normalize(), Vec2::zero());
994 }
995
996 #[test]
997 fn test_vec2_operators() {
998 let a = Vec2::new(1.0, 2.0);
999 let b = Vec2::new(3.0, 4.0);
1000
1001 assert_eq!(a + b, Vec2::new(4.0, 6.0));
1002 assert_eq!(a - b, Vec2::new(-2.0, -2.0));
1003 assert_eq!(a * 2.0, Vec2::new(2.0, 4.0));
1004 assert_eq!(2.0 * a, Vec2::new(2.0, 4.0));
1005 assert_eq!(a / 2.0, Vec2::new(0.5, 1.0));
1006 assert_eq!(-a, Vec2::new(-1.0, -2.0));
1007 }
1008
1009 #[test]
1010 fn test_vec2_lerp() {
1011 let a = Vec2::new(0.0, 0.0);
1012 let b = Vec2::new(10.0, 20.0);
1013 assert_eq!(a.lerp(b, 0.0), a);
1014 assert_eq!(a.lerp(b, 1.0), b);
1015 assert_eq!(a.lerp(b, 0.5), Vec2::new(5.0, 10.0));
1016 }
1017
1018 #[test]
1019 fn test_vec2_cgmath_conversion() {
1020 let goud = Vec2::new(1.0, 2.0);
1021 let cg: cgmath::Vector2<f32> = goud.into();
1022 assert_eq!(cg.x, 1.0);
1023 assert_eq!(cg.y, 2.0);
1024
1025 let back: Vec2 = cg.into();
1026 assert_eq!(back, goud);
1027 }
1028
1029 #[test]
1034 fn test_vec3_constructors() {
1035 assert_eq!(
1036 Vec3::new(1.0, 2.0, 3.0),
1037 Vec3 {
1038 x: 1.0,
1039 y: 2.0,
1040 z: 3.0
1041 }
1042 );
1043 assert_eq!(
1044 Vec3::zero(),
1045 Vec3 {
1046 x: 0.0,
1047 y: 0.0,
1048 z: 0.0
1049 }
1050 );
1051 assert_eq!(
1052 Vec3::one(),
1053 Vec3 {
1054 x: 1.0,
1055 y: 1.0,
1056 z: 1.0
1057 }
1058 );
1059 assert_eq!(
1060 Vec3::unit_x(),
1061 Vec3 {
1062 x: 1.0,
1063 y: 0.0,
1064 z: 0.0
1065 }
1066 );
1067 assert_eq!(
1068 Vec3::unit_y(),
1069 Vec3 {
1070 x: 0.0,
1071 y: 1.0,
1072 z: 0.0
1073 }
1074 );
1075 assert_eq!(
1076 Vec3::unit_z(),
1077 Vec3 {
1078 x: 0.0,
1079 y: 0.0,
1080 z: 1.0
1081 }
1082 );
1083 }
1084
1085 #[test]
1086 fn test_vec3_cross() {
1087 let x = Vec3::unit_x();
1088 let y = Vec3::unit_y();
1089 let z = x.cross(y);
1090 assert!((z - Vec3::unit_z()).length() < 0.0001);
1091 }
1092
1093 #[test]
1094 fn test_vec3_operators() {
1095 let a = Vec3::new(1.0, 2.0, 3.0);
1096 let b = Vec3::new(4.0, 5.0, 6.0);
1097
1098 assert_eq!(a + b, Vec3::new(5.0, 7.0, 9.0));
1099 assert_eq!(a - b, Vec3::new(-3.0, -3.0, -3.0));
1100 assert_eq!(a * 2.0, Vec3::new(2.0, 4.0, 6.0));
1101 assert_eq!(2.0 * a, Vec3::new(2.0, 4.0, 6.0));
1102 assert_eq!(-a, Vec3::new(-1.0, -2.0, -3.0));
1103 }
1104
1105 #[test]
1106 fn test_vec3_cgmath_conversion() {
1107 let goud = Vec3::new(1.0, 2.0, 3.0);
1108 let cg: cgmath::Vector3<f32> = goud.into();
1109 assert_eq!(cg.x, 1.0);
1110 assert_eq!(cg.y, 2.0);
1111 assert_eq!(cg.z, 3.0);
1112
1113 let back: Vec3 = cg.into();
1114 assert_eq!(back, goud);
1115 }
1116
1117 #[test]
1118 fn test_vec3_dot() {
1119 let a = Vec3::new(1.0, 2.0, 3.0);
1120 let b = Vec3::new(4.0, 5.0, 6.0);
1121 assert_eq!(a.dot(b), 32.0);
1123
1124 assert_eq!(a.dot(a), a.length_squared());
1126
1127 assert_eq!(a.dot(b), b.dot(a));
1129
1130 let x = Vec3::unit_x();
1132 let y = Vec3::unit_y();
1133 assert_eq!(x.dot(y), 0.0);
1134 }
1135
1136 #[test]
1137 fn test_vec3_cross_properties() {
1138 let a = Vec3::new(1.0, 2.0, 3.0);
1139 let b = Vec3::new(4.0, 5.0, 6.0);
1140
1141 let ab = a.cross(b);
1143 let ba = b.cross(a);
1144 assert!((ab + ba).length() < 0.0001);
1145
1146 assert!(ab.dot(a).abs() < 0.0001);
1148 assert!(ab.dot(b).abs() < 0.0001);
1149
1150 assert!((Vec3::unit_x().cross(Vec3::unit_y()) - Vec3::unit_z()).length() < 0.0001);
1152 assert!((Vec3::unit_y().cross(Vec3::unit_z()) - Vec3::unit_x()).length() < 0.0001);
1153 assert!((Vec3::unit_z().cross(Vec3::unit_x()) - Vec3::unit_y()).length() < 0.0001);
1154 }
1155
1156 #[test]
1157 fn test_vec3_length() {
1158 let v = Vec3::new(1.0, 2.0, 2.0);
1160 assert_eq!(v.length_squared(), 9.0);
1161 assert_eq!(v.length(), 3.0);
1162
1163 assert_eq!(Vec3::zero().length(), 0.0);
1165
1166 assert_eq!(Vec3::unit_x().length(), 1.0);
1168 assert_eq!(Vec3::unit_y().length(), 1.0);
1169 assert_eq!(Vec3::unit_z().length(), 1.0);
1170 }
1171
1172 #[test]
1173 fn test_vec3_normalize() {
1174 let v = Vec3::new(3.0, 4.0, 0.0);
1175 let n = v.normalize();
1176 assert!((n.length() - 1.0).abs() < 0.0001);
1177 assert!((n.x - 0.6).abs() < 0.0001);
1178 assert!((n.y - 0.8).abs() < 0.0001);
1179 assert_eq!(n.z, 0.0);
1180
1181 assert_eq!(Vec3::zero().normalize(), Vec3::zero());
1183
1184 assert!((Vec3::unit_x().normalize() - Vec3::unit_x()).length() < 0.0001);
1186 }
1187
1188 #[test]
1189 fn test_vec3_lerp() {
1190 let a = Vec3::new(0.0, 0.0, 0.0);
1191 let b = Vec3::new(10.0, 20.0, 30.0);
1192
1193 assert_eq!(a.lerp(b, 0.0), a);
1195
1196 assert_eq!(a.lerp(b, 1.0), b);
1198
1199 assert_eq!(a.lerp(b, 0.5), Vec3::new(5.0, 10.0, 15.0));
1201
1202 assert_eq!(a.lerp(b, 2.0), Vec3::new(20.0, 40.0, 60.0));
1204
1205 assert_eq!(a.lerp(b, -0.5), Vec3::new(-5.0, -10.0, -15.0));
1207 }
1208
1209 #[test]
1210 fn test_vec3_ffi_layout() {
1211 use std::mem::{align_of, size_of};
1212
1213 assert_eq!(size_of::<Vec3>(), 12); assert_eq!(align_of::<Vec3>(), 4); let v = Vec3::new(1.0, 2.0, 3.0);
1219 let ptr = &v as *const Vec3 as *const f32;
1220 unsafe {
1221 assert_eq!(*ptr, 1.0); assert_eq!(*ptr.add(1), 2.0); assert_eq!(*ptr.add(2), 3.0); }
1225
1226 assert_eq!(Vec3::default(), Vec3::zero());
1228 }
1229
1230 #[test]
1235 fn test_vec4_constructors() {
1236 assert_eq!(
1237 Vec4::new(1.0, 2.0, 3.0, 4.0),
1238 Vec4 {
1239 x: 1.0,
1240 y: 2.0,
1241 z: 3.0,
1242 w: 4.0
1243 }
1244 );
1245 assert_eq!(
1246 Vec4::zero(),
1247 Vec4 {
1248 x: 0.0,
1249 y: 0.0,
1250 z: 0.0,
1251 w: 0.0
1252 }
1253 );
1254 assert_eq!(
1255 Vec4::one(),
1256 Vec4 {
1257 x: 1.0,
1258 y: 1.0,
1259 z: 1.0,
1260 w: 1.0
1261 }
1262 );
1263 }
1264
1265 #[test]
1266 fn test_vec4_from_vec3() {
1267 let v3 = Vec3::new(1.0, 2.0, 3.0);
1268 let v4 = Vec4::from_vec3(v3, 4.0);
1269 assert_eq!(v4, Vec4::new(1.0, 2.0, 3.0, 4.0));
1270 assert_eq!(v4.xyz(), v3);
1271 }
1272
1273 #[test]
1274 fn test_vec4_cgmath_conversion() {
1275 let goud = Vec4::new(1.0, 2.0, 3.0, 4.0);
1276 let cg: cgmath::Vector4<f32> = goud.into();
1277 let back: Vec4 = cg.into();
1278 assert_eq!(back, goud);
1279 }
1280
1281 #[test]
1286 fn test_rect_constructors() {
1287 let r = Rect::new(10.0, 20.0, 100.0, 50.0);
1288 assert_eq!(r.x, 10.0);
1289 assert_eq!(r.y, 20.0);
1290 assert_eq!(r.width, 100.0);
1291 assert_eq!(r.height, 50.0);
1292 }
1293
1294 #[test]
1295 fn test_rect_from_min_max() {
1296 let r = Rect::from_min_max(Vec2::new(10.0, 20.0), Vec2::new(110.0, 70.0));
1297 assert_eq!(r.x, 10.0);
1298 assert_eq!(r.y, 20.0);
1299 assert_eq!(r.width, 100.0);
1300 assert_eq!(r.height, 50.0);
1301 }
1302
1303 #[test]
1304 fn test_rect_accessors() {
1305 let r = Rect::new(10.0, 20.0, 100.0, 50.0);
1306 assert_eq!(r.min(), Vec2::new(10.0, 20.0));
1307 assert_eq!(r.max(), Vec2::new(110.0, 70.0));
1308 assert_eq!(r.center(), Vec2::new(60.0, 45.0));
1309 assert_eq!(r.size(), Vec2::new(100.0, 50.0));
1310 assert_eq!(r.area(), 5000.0);
1311 }
1312
1313 #[test]
1314 fn test_rect_contains() {
1315 let r = Rect::new(0.0, 0.0, 100.0, 100.0);
1316 assert!(r.contains(Vec2::new(50.0, 50.0)));
1317 assert!(r.contains(Vec2::new(0.0, 0.0)));
1318 assert!(!r.contains(Vec2::new(100.0, 100.0))); assert!(!r.contains(Vec2::new(-1.0, 50.0)));
1320 assert!(!r.contains(Vec2::new(50.0, -1.0)));
1321 }
1322
1323 #[test]
1324 fn test_rect_intersects() {
1325 let a = Rect::new(0.0, 0.0, 100.0, 100.0);
1326 let b = Rect::new(50.0, 50.0, 100.0, 100.0);
1327 let c = Rect::new(200.0, 200.0, 10.0, 10.0);
1328
1329 assert!(a.intersects(&b));
1330 assert!(b.intersects(&a));
1331 assert!(!a.intersects(&c));
1332 assert!(!c.intersects(&a));
1333 }
1334
1335 #[test]
1336 fn test_rect_intersection() {
1337 let a = Rect::new(0.0, 0.0, 100.0, 100.0);
1338 let b = Rect::new(50.0, 50.0, 100.0, 100.0);
1339
1340 let inter = a.intersection(&b).unwrap();
1341 assert_eq!(inter.x, 50.0);
1342 assert_eq!(inter.y, 50.0);
1343 assert_eq!(inter.width, 50.0);
1344 assert_eq!(inter.height, 50.0);
1345
1346 let c = Rect::new(200.0, 200.0, 10.0, 10.0);
1347 assert!(a.intersection(&c).is_none());
1348 }
1349
1350 #[test]
1355 fn test_color_constants() {
1356 assert_eq!(Color::WHITE, Color::rgba(1.0, 1.0, 1.0, 1.0));
1357 assert_eq!(Color::BLACK, Color::rgba(0.0, 0.0, 0.0, 1.0));
1358 assert_eq!(Color::RED, Color::rgba(1.0, 0.0, 0.0, 1.0));
1359 assert_eq!(Color::TRANSPARENT, Color::rgba(0.0, 0.0, 0.0, 0.0));
1360 }
1361
1362 #[test]
1363 fn test_color_from_u8() {
1364 let c = Color::from_u8(255, 128, 0, 255);
1365 assert!((c.r - 1.0).abs() < 0.01);
1366 assert!((c.g - 0.5).abs() < 0.01);
1367 assert_eq!(c.b, 0.0);
1368 assert_eq!(c.a, 1.0);
1369 }
1370
1371 #[test]
1372 fn test_color_from_hex() {
1373 let c1 = Color::from_hex(0xFF0000); assert_eq!(c1.r, 1.0);
1375 assert_eq!(c1.g, 0.0);
1376 assert_eq!(c1.b, 0.0);
1377 assert_eq!(c1.a, 1.0);
1378
1379 let c2 = Color::from_hex(0xFF000080); assert_eq!(c2.r, 1.0);
1381 assert_eq!(c2.g, 0.0);
1382 assert_eq!(c2.b, 0.0);
1383 assert!((c2.a - 0.5).abs() < 0.01);
1384 }
1385
1386 #[test]
1387 fn test_color_vec_conversions() {
1388 let c = Color::rgba(0.1, 0.2, 0.3, 0.4);
1389 let v3 = c.to_vec3();
1390 assert_eq!(v3, Vec3::new(0.1, 0.2, 0.3));
1391
1392 let v4 = c.to_vec4();
1393 assert_eq!(v4, Vec4::new(0.1, 0.2, 0.3, 0.4));
1394
1395 let c2 = Color::from_vec4(v4);
1396 assert_eq!(c2, c);
1397 }
1398
1399 #[test]
1400 fn test_color_lerp() {
1401 let a = Color::BLACK;
1402 let b = Color::WHITE;
1403 let mid = a.lerp(b, 0.5);
1404 assert!((mid.r - 0.5).abs() < 0.0001);
1405 assert!((mid.g - 0.5).abs() < 0.0001);
1406 assert!((mid.b - 0.5).abs() < 0.0001);
1407 }
1408
1409 #[test]
1410 fn test_color_with_alpha() {
1411 let c = Color::RED.with_alpha(0.5);
1412 assert_eq!(c.r, 1.0);
1413 assert_eq!(c.g, 0.0);
1414 assert_eq!(c.b, 0.0);
1415 assert_eq!(c.a, 0.5);
1416 }
1417
1418 #[test]
1423 fn test_ffi_layout_sizes() {
1424 use std::mem::size_of;
1425
1426 assert_eq!(size_of::<Vec2>(), 8); assert_eq!(size_of::<Vec3>(), 12); assert_eq!(size_of::<Vec4>(), 16); assert_eq!(size_of::<Rect>(), 16); assert_eq!(size_of::<Color>(), 16); }
1433}