lighthouse_protocol/utils/
vec3.rs1use std::{fmt, ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign}};
2
3use serde::{Deserialize, Serialize};
4
5use super::{Sqrt, Zero};
6
7#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
9pub struct Vec3<T> {
10 pub x: T,
11 pub y: T,
12 pub z: T,
13}
14
15impl<T> Vec3<T> {
16 pub const fn new(x: T, y: T, z: T) -> Self {
18 Self { x, y, z }
19 }
20
21 pub fn map<U>(self, mut f: impl FnMut(T) -> U) -> Vec3<U> {
23 Vec3 {
24 x: f(self.x),
25 y: f(self.y),
26 z: f(self.z),
27 }
28 }
29}
30
31impl<T> Zero for Vec3<T> where T: Zero {
32 const ZERO: Self = Self::new(T::ZERO, T::ZERO, T::ZERO);
34}
35
36impl<T> Vec3<T> where T: Add<Output = T> + Mul<Output = T> + Sqrt + Copy {
37 pub fn length(&self) -> T {
39 (self.x * self.x + self.y * self.y + self.z * self.z).sqrt()
40 }
41}
42
43impl<T> fmt::Display for Vec3<T> where T: fmt::Display {
44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45 write!(f, "({}, {}, {})", self.x, self.y, self.z)
46 }
47}
48
49impl<T> Add for Vec3<T> where T: Add<Output = T> {
50 type Output = Self;
51
52 fn add(self, rhs: Vec3<T>) -> Self {
53 Self::new(self.x + rhs.x, self.y + rhs.y, self.z + rhs.z)
54 }
55}
56
57impl<T> Neg for Vec3<T> where T: Neg<Output = T> {
58 type Output = Self;
59
60 fn neg(self) -> Self {
61 Self::new(-self.x, -self.y, -self.z)
62 }
63}
64
65impl<T> Sub for Vec3<T> where T: Sub<Output = T> {
66 type Output = Self;
67
68 fn sub(self, rhs: Vec3<T>) -> Self {
69 Self::new(self.x - rhs.x, self.y - rhs.y, self.z - rhs.z)
70 }
71}
72
73impl<T> AddAssign<Self> for Vec3<T> where T: AddAssign<T> {
74 fn add_assign(&mut self, rhs: Vec3<T>) {
75 self.x += rhs.x;
76 self.y += rhs.y;
77 self.z += rhs.z;
78 }
79}
80
81impl<T> SubAssign<Self> for Vec3<T> where T: SubAssign<T> {
82 fn sub_assign(&mut self, rhs: Vec3<T>) {
83 self.x -= rhs.x;
84 self.y -= rhs.y;
85 self.z -= rhs.z;
86 }
87}