1use std::convert::{From, TryInto};
2use std::ops;
3use ultraviolet::Vec3;
4
5#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6#[derive(Eq, PartialEq, Copy, Clone, Debug)]
7pub struct Point3 {
9 pub x: i32,
11 pub y: i32,
13 pub z: i32,
15}
16
17#[cfg(feature = "specs")]
18impl specs::prelude::Component for Point3 {
19 type Storage = specs::prelude::VecStorage<Self>;
20}
21
22#[cfg(feature = "bevy")]
23impl bevy::ecs::component::Component for Point3 {
24 type Storage = bevy::ecs::component::TableStorage;
25}
26
27impl Point3 {
28 pub fn new<T>(x: T, y: T, z: T) -> Self
30 where
31 T: TryInto<i32>,
32 {
33 Self {
34 x: x.try_into().ok().unwrap(),
35 y: y.try_into().ok().unwrap(),
36 z: z.try_into().ok().unwrap(),
37 }
38 }
39
40 #[must_use]
42 pub fn from_tuple(t: (i32, i32, i32)) -> Self {
43 Self {
44 x: t.0,
45 y: t.1,
46 z: t.2,
47 }
48 }
49
50 pub fn to_vec3(&self) -> Vec3 {
52 Vec3::new(self.x as f32, self.y as f32, self.z as f32)
53 }
54
55 }
62
63impl From<Vec3> for Point3 {
64 fn from(item: Vec3) -> Self {
65 Self {
66 x: item.x as i32,
67 y: item.y as i32,
68 z: item.z as i32,
69 }
70 }
71}
72
73impl ops::Add<Point3> for Point3 {
90 type Output = Point3;
91 fn add(mut self, rhs: Point3) -> Point3 {
92 self.x += rhs.x;
93 self.y += rhs.y;
94 self.z += rhs.z;
95 self
96 }
97}
98
99impl ops::Add<i32> for Point3 {
101 type Output = Point3;
102 fn add(mut self, rhs: i32) -> Point3 {
103 self.x += rhs;
104 self.y += rhs;
105 self.z += rhs;
106 self
107 }
108}
109
110impl ops::Sub<Point3> for Point3 {
112 type Output = Point3;
113 fn sub(mut self, rhs: Point3) -> Point3 {
114 self.x -= rhs.x;
115 self.y -= rhs.y;
116 self.z -= rhs.z;
117 self
118 }
119}
120
121impl ops::Sub<i32> for Point3 {
123 type Output = Point3;
124 fn sub(mut self, rhs: i32) -> Point3 {
125 self.x -= rhs;
126 self.y -= rhs;
127 self.z -= rhs;
128 self
129 }
130}
131
132impl ops::Mul<Point3> for Point3 {
134 type Output = Point3;
135 fn mul(mut self, rhs: Point3) -> Point3 {
136 self.x *= rhs.x;
137 self.y *= rhs.y;
138 self.z *= rhs.z;
139 self
140 }
141}
142
143impl ops::Mul<i32> for Point3 {
145 type Output = Point3;
146 fn mul(mut self, rhs: i32) -> Point3 {
147 self.x *= rhs;
148 self.y *= rhs;
149 self.z *= rhs;
150 self
151 }
152}
153
154impl ops::Mul<f32> for Point3 {
156 type Output = Point3;
157 fn mul(mut self, rhs: f32) -> Point3 {
158 self.x = (self.x as f32 * rhs) as i32;
159 self.y = (self.y as f32 * rhs) as i32;
160 self.z = (self.z as f32 * rhs) as i32;
161 self
162 }
163}
164
165impl ops::Div<Point3> for Point3 {
167 type Output = Point3;
168 fn div(mut self, rhs: Point3) -> Point3 {
169 self.x /= rhs.x;
170 self.y /= rhs.y;
171 self.z /= rhs.z;
172 self
173 }
174}
175
176impl ops::Div<i32> for Point3 {
178 type Output = Point3;
179 fn div(mut self, rhs: i32) -> Point3 {
180 self.x /= rhs;
181 self.y /= rhs;
182 self.z /= rhs;
183 self
184 }
185}
186
187impl ops::Div<f32> for Point3 {
189 type Output = Point3;
190 fn div(mut self, rhs: f32) -> Point3 {
191 self.x = (self.x as f32 / rhs) as i32;
192 self.y = (self.y as f32 / rhs) as i32;
193 self.z = (self.z as f32 / rhs) as i32;
194 self
195 }
196}
197
198impl ops::AddAssign for Point3 {
200 fn add_assign(&mut self, other: Self) {
201 *self = Self {
202 x: self.x + other.x,
203 y: self.y + other.y,
204 z: self.z + other.z,
205 };
206 }
207}
208
209impl ops::SubAssign for Point3 {
211 fn sub_assign(&mut self, other: Self) {
212 *self = Self {
213 x: self.x - other.x,
214 y: self.y - other.y,
215 z: self.z - other.z,
216 };
217 }
218}
219
220impl ops::MulAssign for Point3 {
222 fn mul_assign(&mut self, other: Self) {
223 *self = Self {
224 x: self.x * other.x,
225 y: self.y * other.y,
226 z: self.z * other.z,
227 };
228 }
229}
230
231impl ops::DivAssign for Point3 {
233 fn div_assign(&mut self, other: Self) {
234 *self = Self {
235 x: self.x / other.x,
236 y: self.y / other.y,
237 z: self.z / other.z,
238 };
239 }
240}
241
242#[cfg(test)]
244mod tests {
245 use super::Point3;
246
247 #[test]
248 fn new_point3() {
249 let pt = Point3::new(1, 2, 3);
250 assert_eq!(pt.x, 1);
251 assert_eq!(pt.y, 2);
252 assert_eq!(pt.z, 3);
253 }
254
255 #[test]
256 fn add_point_to_point3() {
257 let pt = Point3::new(0, 0, 0);
258 let p2 = pt + Point3::new(1, 2, 3);
259 assert_eq!(p2.x, 1);
260 assert_eq!(p2.y, 2);
261 assert_eq!(p2.z, 3);
262 }
263
264 #[test]
265 fn add_assign_point_to_point3() {
266 let mut pt = Point3::new(0, 0, 0);
267 pt += Point3::new(1, 2, 3);
268 assert_eq!(pt.x, 1);
269 assert_eq!(pt.y, 2);
270 assert_eq!(pt.z, 3);
271 }
272
273 #[test]
274 fn add_point3_to_int() {
275 let pt = Point3::new(0, 0, 0);
276 let p2 = pt + 2;
277 assert_eq!(p2.x, 2);
278 assert_eq!(p2.y, 2);
279 assert_eq!(p2.z, 2);
280 }
281
282 #[test]
283 fn sub_point3_to_point() {
284 let pt = Point3::new(0, 0, 0);
285 let p2 = pt - Point3::new(1, 2, 3);
286 assert_eq!(p2.x, -1);
287 assert_eq!(p2.y, -2);
288 assert_eq!(p2.z, -3);
289 }
290
291 #[test]
292 fn sub_assign_point3_to_point() {
293 let mut pt = Point3::new(0, 0, 0);
294 pt -= Point3::new(1, 2, 3);
295 assert_eq!(pt.x, -1);
296 assert_eq!(pt.y, -2);
297 assert_eq!(pt.z, -3);
298 }
299
300 #[test]
301 fn sub_point3_to_int() {
302 let pt = Point3::new(0, 0, 0);
303 let p2 = pt - 2;
304 assert_eq!(p2.x, -2);
305 assert_eq!(p2.y, -2);
306 assert_eq!(p2.z, -2);
307 }
308
309 #[test]
310 fn mul_point3_to_point() {
311 let pt = Point3::new(1, 1, 1);
312 let p2 = pt * Point3::new(1, 2, 4);
313 assert_eq!(p2.x, 1);
314 assert_eq!(p2.y, 2);
315 assert_eq!(p2.z, 4);
316 }
317
318 #[test]
319 fn mul_assign_point3_to_point() {
320 let mut pt = Point3::new(1, 1, 1);
321 pt *= Point3::new(1, 2, 4);
322 assert_eq!(pt.x, 1);
323 assert_eq!(pt.y, 2);
324 assert_eq!(pt.z, 4);
325 }
326
327 #[test]
328 fn mul_point3_to_int() {
329 let pt = Point3::new(1, 1, 1);
330 let p2 = pt * 2;
331 assert_eq!(p2.x, 2);
332 assert_eq!(p2.y, 2);
333 assert_eq!(p2.z, 2);
334 }
335
336 #[test]
337 fn mul_point3_to_float() {
338 let pt = Point3::new(1, 1, 1);
339 let p2 = pt * 4.0;
340 assert_eq!(p2.x, 4);
341 assert_eq!(p2.y, 4);
342 assert_eq!(p2.z, 4);
343 }
344
345 #[test]
346 fn div_point3_to_point() {
347 let pt = Point3::new(4, 4, 4);
348 let p2 = pt / Point3::new(2, 4, 1);
349 assert_eq!(p2.x, 2);
350 assert_eq!(p2.y, 1);
351 assert_eq!(p2.z, 4);
352 }
353
354 #[test]
355 fn div_assign_point3_to_point() {
356 let mut pt = Point3::new(4, 4, 4);
357 pt /= Point3::new(2, 4, 1);
358 assert_eq!(pt.x, 2);
359 assert_eq!(pt.y, 1);
360 assert_eq!(pt.z, 4);
361 }
362
363 #[test]
364 fn div_point3_to_int() {
365 let pt = Point3::new(4, 4, 4);
366 let p2 = pt / 2;
367 assert_eq!(p2.x, 2);
368 assert_eq!(p2.y, 2);
369 assert_eq!(p2.z, 2);
370 }
371
372 #[test]
373 fn div_point3_to_float() {
374 let pt = Point3::new(4, 4, 4);
375 let p2 = pt / 2.0;
376 assert_eq!(p2.x, 2);
377 assert_eq!(p2.y, 2);
378 assert_eq!(p2.z, 2);
379 }
380}