lighthouse_protocol/utils/
vec3.rs

1use std::{fmt, ops::{Add, AddAssign, Mul, Neg, Sub, SubAssign}};
2
3use serde::{Deserialize, Serialize};
4
5use super::{Sqrt, Zero};
6
7/// A 3D vector.
8#[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    /// Creates a mew position.
17    pub const fn new(x: T, y: T, z: T) -> Self {
18        Self { x, y, z }
19    }
20
21    /// Maps a function over the vector.
22    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    /// The origin.
33    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    /// The vector's length.
38    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}