1use super::Vec3;
2use super::prelude::*;
3use super::vec3;
4
5use glam::Vec3A;
6use glam::vec3a;
7#[cfg(target_arch = "spirv")]
8use num_traits::Float;
9
10pub trait Vec3Ext {
14 #[must_use]
16 fn trunc(self) -> Self;
17
18 #[must_use]
22 fn step(self, value: Self) -> Self;
23
24 #[must_use]
26 fn step_select(self, value: Self, tru: Self, fals: Self) -> Self;
27
28 #[must_use]
30 fn fract(self) -> Self;
31
32 #[must_use]
34 fn saturate(self) -> Self;
35
36 #[must_use]
38 fn sqrt(self) -> Self;
39
40 #[must_use]
42 fn ln(self) -> Self;
43
44 #[must_use]
46 fn reflect(self, normal: Self) -> Self;
47
48 #[must_use]
50 fn mean(self) -> f32;
51
52 #[must_use]
54 fn has_equal_components(self, max_abs_diff: f32) -> bool;
55
56 #[must_use]
62 fn eerp(self, other: Self, a: f32) -> Self;
63}
64
65impl Vec3Ext for Vec3 {
66 #[inline]
68 fn trunc(self) -> Self {
69 vec3(self.x.trunc(), self.y.trunc(), self.z.trunc())
70 }
71
72 #[inline]
73 fn step(self, value: Self) -> Self {
74 vec3(
75 self.x.step(value.x),
76 self.y.step(value.y),
77 self.z.step(value.z),
78 )
79 }
80
81 #[inline]
82 fn step_select(self, value: Self, less: Self, greater_or_equal: Self) -> Self {
83 vec3(
84 self.x.step_select(value.x, less.x, greater_or_equal.x),
85 self.y.step_select(value.y, less.y, greater_or_equal.y),
86 self.z.step_select(value.z, less.z, greater_or_equal.z),
87 )
88 }
89
90 #[inline]
91 fn fract(self) -> Self {
92 vec3(self.x.fract(), self.y.fract(), self.z.fract())
93 }
94
95 #[inline]
96 fn saturate(self) -> Self {
97 vec3(self.x.saturate(), self.y.saturate(), self.z.saturate())
98 }
99
100 #[inline]
101 fn sqrt(self) -> Self {
102 vec3(self.x.sqrt(), self.y.sqrt(), self.z.sqrt())
103 }
104
105 #[inline]
106 fn ln(self) -> Self {
107 vec3(self.x.ln(), self.y.ln(), self.z.ln())
108 }
109
110 #[inline]
111 fn reflect(self, normal: Self) -> Self {
112 self - 2.0 * normal * self.dot(normal)
113 }
114
115 #[inline]
116 fn mean(self) -> f32 {
117 (self.x + self.y + self.z) / 3.0
118 }
119
120 #[inline]
121 fn has_equal_components(self, max_abs_diff: f32) -> bool {
122 (self.x - self.y).abs() < max_abs_diff
123 && (self.y - self.z).abs() < max_abs_diff
124 && (self.x - self.z).abs() < max_abs_diff
125 }
126
127 #[inline(always)]
128 fn eerp(self, other: Self, a: f32) -> Self {
129 Self::new(
130 self.x.eerp(other.x, a),
131 self.y.eerp(other.y, a),
132 self.z.eerp(other.z, a),
133 )
134 }
135}
136
137impl Vec3Ext for Vec3A {
138 #[inline]
140 fn trunc(self) -> Self {
141 vec3a(self.x.trunc(), self.y.trunc(), self.z.trunc())
142 }
143
144 #[inline]
145 fn step(self, value: Self) -> Self {
146 vec3a(
147 self.x.step(value.x),
148 self.y.step(value.y),
149 self.z.step(value.z),
150 )
151 }
152
153 #[inline]
154 fn step_select(self, value: Self, less: Self, greater_or_equal: Self) -> Self {
155 vec3a(
156 self.x.step_select(value.x, less.x, greater_or_equal.x),
157 self.y.step_select(value.y, less.y, greater_or_equal.y),
158 self.z.step_select(value.z, less.z, greater_or_equal.z),
159 )
160 }
161
162 #[inline]
163 fn fract(self) -> Self {
164 vec3a(self.x.fract(), self.y.fract(), self.z.fract())
165 }
166
167 #[inline]
168 fn saturate(self) -> Self {
169 vec3a(self.x.saturate(), self.y.saturate(), self.z.saturate())
170 }
171
172 #[inline]
173 fn sqrt(self) -> Self {
174 vec3a(self.x.sqrt(), self.y.sqrt(), self.z.sqrt())
175 }
176
177 #[inline]
178 fn ln(self) -> Self {
179 vec3a(self.x.ln(), self.y.ln(), self.z.ln())
180 }
181
182 #[inline]
183 fn reflect(self, normal: Self) -> Self {
184 self - 2.0 * normal * self.dot(normal)
185 }
186
187 #[inline]
188 fn mean(self) -> f32 {
189 (self.x + self.y + self.z) / 3.0
190 }
191
192 #[inline]
193 fn has_equal_components(self, max_abs_diff: f32) -> bool {
194 (self.x - self.y).abs() < max_abs_diff
195 && (self.y - self.z).abs() < max_abs_diff
196 && (self.x - self.z).abs() < max_abs_diff
197 }
198
199 #[inline(always)]
200 fn eerp(self, other: Self, a: f32) -> Self {
201 Self::new(
202 self.x.eerp(other.x, a),
203 self.y.eerp(other.y, a),
204 self.z.eerp(other.z, a),
205 )
206 }
207}
208
209pub trait CoordinateSystem {
216 fn up() -> Self;
218
219 fn down() -> Self;
221
222 fn right() -> Self;
226
227 fn left() -> Self;
229
230 fn forward() -> Self;
234
235 fn back() -> Self;
237}
238
239impl CoordinateSystem for Vec3 {
240 fn up() -> Self {
241 Self::new(0.0, 1.0, 0.0)
242 }
243
244 fn down() -> Self {
245 Self::new(0.0, -1.0, 0.0)
246 }
247
248 fn right() -> Self {
249 Self::new(1.0, 0.0, 0.0)
250 }
251
252 fn left() -> Self {
253 Self::new(-1.0, 0.0, 0.0)
254 }
255
256 fn forward() -> Self {
257 Self::new(0.0, 0.0, -1.0)
258 }
259
260 fn back() -> Self {
261 Self::new(0.0, 0.0, 1.0)
262 }
263}
264
265#[cfg(test)]
266mod test {
267 use super::*;
268
269 #[test]
270 fn test_mean() {
271 assert!((Vec3::ONE.mean() - 1.0).abs() < 0.0001);
272 }
273
274 #[test]
275 fn test_mean_2() {
276 assert!((vec3(1.0, 2.0, 3.0).mean() - 2.0).abs() < 0.0001);
277 }
278
279 #[test]
280 fn test_has_equal_components() {
281 assert!(Vec3::ONE.has_equal_components(0.001));
282 }
283
284 #[test]
285 fn test_has_equal_components_2() {
286 assert!(vec3(0.0, 0.00001, -0.00001).has_equal_components(0.001));
287 }
288
289 #[test]
290 fn test_has_equal_components_3() {
291 assert!(!vec3(1.0, 0.0, 0.0).has_equal_components(0.0001));
292 }
293}