1use super::*;
2
3#[allow(non_camel_case_types)]
5#[repr(C)]
6#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize)]
7pub struct vec3<T>(pub T, pub T, pub T);
8
9impl<T: std::fmt::Display> std::fmt::Display for vec3<T> {
10 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
11 write!(fmt, "({}, {}, {})", self.x, self.y, self.z)
12 }
13}
14
15impl<T> From<[T; 3]> for vec3<T> {
16 fn from(v: [T; 3]) -> vec3<T> {
17 let [x, y, z] = v;
18 vec3(x, y, z)
19 }
20}
21
22pub struct XYZ<T> {
24 #[allow(missing_docs)]
25 pub x: T,
26 #[allow(missing_docs)]
27 pub y: T,
28 #[allow(missing_docs)]
29 pub z: T,
30}
31
32impl<T> Deref for XYZ<T> {
33 type Target = [T; 3];
34 fn deref(&self) -> &[T; 3] {
35 unsafe { std::mem::transmute(self) }
36 }
37}
38
39impl<T> DerefMut for XYZ<T> {
40 fn deref_mut(&mut self) -> &mut [T; 3] {
41 unsafe { std::mem::transmute(self) }
42 }
43}
44
45impl<T> Deref for vec3<T> {
46 type Target = XYZ<T>;
47 fn deref(&self) -> &XYZ<T> {
48 unsafe { std::mem::transmute(self) }
49 }
50}
51
52impl<T> DerefMut for vec3<T> {
53 fn deref_mut(&mut self) -> &mut XYZ<T> {
54 unsafe { std::mem::transmute(self) }
55 }
56}
57
58impl<T> vec3<T> {
59 pub fn xy(self) -> vec2<T> {
61 vec2(self.0, self.1)
62 }
63
64 pub fn extend(self, w: T) -> vec4<T> {
66 vec4(self.0, self.1, self.2, w)
67 }
68
69 pub fn map<U, F: Fn(T) -> U>(self, f: F) -> vec3<U> {
71 vec3(f(self.0), f(self.1), f(self.2))
72 }
73
74 pub fn zip<U>(self, v: vec3<U>) -> vec3<(T, U)> {
76 vec3((self.0, v.0), (self.1, v.1), (self.2, v.2))
77 }
78}
79
80impl<T: Clone> vec3<T> {
81 pub fn splat(value: T) -> Self {
83 Self(value.clone(), value.clone(), value)
84 }
85}
86
87impl<T: UNum> vec3<T> {
88 pub const ZERO: Self = vec3(T::ZERO, T::ZERO, T::ZERO);
90
91 pub const UNIT_X: Self = Self(T::ONE, T::ZERO, T::ZERO);
93
94 pub const UNIT_Y: Self = Self(T::ZERO, T::ONE, T::ZERO);
96
97 pub const UNIT_Z: Self = Self(T::ZERO, T::ZERO, T::ONE);
99}
100
101impl<T: Copy + Num> vec3<T> {
102 pub fn dot(a: Self, b: Self) -> T {
110 a.x * b.x + a.y * b.y + a.z * b.z
111 }
112
113 pub fn cross(a: Self, b: Self) -> Self {
121 vec3(
122 a.y * b.z - a.z * b.y,
123 a.z * b.x - a.x * b.z,
124 a.x * b.y - a.y * b.x,
125 )
126 }
127}
128
129impl<T: Float> vec3<T> {
130 pub fn normalize(self) -> Self {
139 self / self.len()
140 }
141
142 pub fn normalize_or_zero(self) -> Self {
156 let len = self.len();
157 if len.approx_eq(&T::ZERO) {
158 vec3::ZERO
159 } else {
160 self / len
161 }
162 }
163
164 pub fn len(self) -> T {
166 T::sqrt(self.len_sqr())
167 }
168
169 pub fn len_sqr(self) -> T {
171 vec3::dot(self, self)
172 }
173
174 pub fn into_2d(self) -> vec2<T> {
178 self.xy() / self.z
179 }
180
181 pub fn clamp_len(self, len_range: impl FixedRangeBounds<T>) -> Self {
189 let len = self.len();
190 let target_len = len.clamp_range(len_range);
191 if len == target_len {
192 self
193 } else {
194 self * target_len / len
195 }
196 }
197
198 pub fn clamp_coordinates(
206 self,
207 x_range: impl FixedRangeBounds<T>,
208 y_range: impl FixedRangeBounds<T>,
209 z_range: impl FixedRangeBounds<T>,
210 ) -> Self {
211 vec3(
212 self.x.clamp_range(x_range),
213 self.y.clamp_range(y_range),
214 self.z.clamp_range(z_range),
215 )
216 }
217
218 pub fn transform(self, transform: mat4<T>) -> Self {
220 (transform * self.extend(T::ONE)).into_3d()
221 }
222}