1use crate::{Real, Scalar};
2
3#[derive(Clone, Copy, Debug, Default, PartialEq)]
5#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6pub struct Vec2<T: Scalar> {
7 pub x: T,
9 pub y: T,
11}
12
13#[derive(Clone, Copy, Debug, Default, PartialEq)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
16pub struct Vec3<T: Scalar> {
17 pub x: T,
19 pub y: T,
21 pub z: T,
23}
24
25#[derive(Clone, Copy, Debug, Default, PartialEq)]
27#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
28pub struct Vec4<T: Scalar> {
29 pub x: T,
31 pub y: T,
33 pub z: T,
35 pub w: T,
37}
38
39impl<T: Scalar> Vec3<T> {
40 #[must_use]
42 pub const fn new(x: T, y: T, z: T) -> Self {
43 Self { x, y, z }
44 }
45}
46
47impl<T: Scalar> core::ops::Add for Vec3<T> {
48 type Output = Self;
49
50 fn add(self, rhs: Self) -> Self::Output {
51 Self::new(self.x + rhs.x, self.y + rhs.y, self.z + rhs.z)
52 }
53}
54
55impl<T: Scalar> core::ops::Sub for Vec3<T> {
56 type Output = Self;
57
58 fn sub(self, rhs: Self) -> Self::Output {
59 Self::new(self.x - rhs.x, self.y - rhs.y, self.z - rhs.z)
60 }
61}
62
63impl<T: Real> Vec3<T> {
64 #[must_use]
66 pub fn dot(self, other: Self) -> T {
67 self.x * other.x + self.y * other.y + self.z * other.z
68 }
69
70 #[must_use]
72 pub fn cross(self, other: Self) -> Self {
73 Self {
74 x: self.y * other.z - self.z * other.y,
75 y: self.z * other.x - self.x * other.z,
76 z: self.x * other.y - self.y * other.x,
77 }
78 }
79
80 #[must_use]
82 pub fn length_squared(self) -> T {
83 self.dot(self)
84 }
85
86 #[must_use]
88 pub fn length(self) -> T {
89 self.length_squared().sqrt()
90 }
91
92 #[must_use]
94 pub fn normalize(self) -> Self {
95 let len = self.length();
96 if len == T::default() {
97 return self;
98 }
99 Self { x: self.x / len, y: self.y / len, z: self.z / len }
100 }
101}
102
103#[cfg(test)]
104mod tests {
105 use super::Vec3;
106
107 #[test]
108 fn vec3_dot_and_cross() {
109 let a = Vec3::new(1.0_f32, 0.0, 0.0);
110 let b = Vec3::new(0.0, 1.0, 0.0);
111 assert_eq!(a.dot(b), 0.0);
112 assert_eq!(a.cross(b), Vec3::new(0.0, 0.0, 1.0));
113 }
114
115 #[test]
116 fn vec3_normalize() {
117 let v = Vec3::new(3.0_f32, 0.0, 4.0);
118 let n = v.normalize();
119 assert!((n.length() - 1.0).abs() < 1e-6);
120 }
121}