open_dis_rust/common/
vector3_float.rs1use bytes::{Buf, BufMut, BytesMut};
8
9#[derive(Copy, Clone, Debug, Default, PartialEq)]
10pub struct Vector3Float {
12 pub x: f32,
14 pub y: f32,
16 pub z: f32,
18}
19
20impl Vector3Float {
21 #[must_use]
23 pub const fn new(x: f32, y: f32, z: f32) -> Self {
24 Vector3Float { x, y, z }
25 }
26
27 #[must_use]
29 pub const fn zero() -> Self {
30 Self::new(0.0, 0.0, 0.0)
31 }
32
33 #[must_use]
35 pub const fn one() -> Self {
36 Self::new(1.0, 1.0, 1.0)
37 }
38
39 #[must_use]
41 pub const fn unit_x() -> Self {
42 Self::new(1.0, 0.0, 0.0)
43 }
44
45 #[must_use]
47 pub const fn unit_y() -> Self {
48 Self::new(0.0, 1.0, 0.0)
49 }
50
51 #[must_use]
53 pub const fn unit_z() -> Self {
54 Self::new(0.0, 0.0, 1.0)
55 }
56
57 #[must_use]
59 pub fn dot(&self, other: &Self) -> f32 {
60 self.x * other.x + self.y * other.y + self.z * other.z
61 }
62
63 #[must_use]
65 pub fn cross(&self, other: &Self) -> Self {
66 Self::new(
67 self.y * other.z - self.z * other.y,
68 self.z * other.x - self.x * other.z,
69 self.x * other.y - self.y * other.x,
70 )
71 }
72
73 #[must_use]
75 pub fn magnitude(&self) -> f32 {
76 (self.x * self.x + self.y * self.y + self.z * self.z).sqrt()
77 }
78
79 #[must_use]
81 pub fn normalize(&self) -> Option<Self> {
82 let mag = self.magnitude();
83 if mag == 0.0 {
84 None
85 } else {
86 Some(Self::new(self.x / mag, self.y / mag, self.z / mag))
87 }
88 }
89
90 pub fn serialize(&self, buf: &mut BytesMut) {
91 buf.put_f32(self.x);
92 buf.put_f32(self.y);
93 buf.put_f32(self.z);
94 }
95
96 pub fn deserialize(buf: &mut BytesMut) -> Vector3Float {
97 Vector3Float {
98 x: buf.get_f32(),
99 y: buf.get_f32(),
100 z: buf.get_f32(),
101 }
102 }
103}
104
105impl std::ops::Add for Vector3Float {
106 type Output = Self;
107
108 fn add(self, other: Self) -> Self {
109 Self::new(self.x + other.x, self.y + other.y, self.z + other.z)
110 }
111}
112
113impl std::ops::Sub for Vector3Float {
114 type Output = Self;
115
116 fn sub(self, other: Self) -> Self {
117 Self::new(self.x - other.x, self.y - other.y, self.z - other.z)
118 }
119}
120
121impl std::ops::Mul<f32> for Vector3Float {
122 type Output = Self;
123
124 fn mul(self, scalar: f32) -> Self {
125 Self::new(self.x * scalar, self.y * scalar, self.z * scalar)
126 }
127}
128
129impl std::ops::Div<f32> for Vector3Float {
130 type Output = Self;
131
132 fn div(self, scalar: f32) -> Self {
133 Self::new(self.x / scalar, self.y / scalar, self.z / scalar)
134 }
135}
136
137#[cfg(test)]
138mod tests {
139 use super::*;
140
141 #[test]
142 fn test_vector_operations() {
143 let v1 = Vector3Float::new(1.0, 2.0, 3.0);
144 let v2 = Vector3Float::new(4.0, 5.0, 6.0);
145
146 let sum = v1 + v2;
148 assert_eq!(sum, Vector3Float::new(5.0, 7.0, 9.0));
149
150 let dot = v1.dot(&v2);
152 assert_eq!(dot, 32.0);
153
154 let cross = v1.cross(&v2);
156 assert_eq!(cross, Vector3Float::new(-3.0, 6.0, -3.0));
157
158 let scaled = v1 * 2.0;
160 assert_eq!(scaled, Vector3Float::new(2.0, 4.0, 6.0));
161
162 let normalized = v1.normalize().unwrap();
164 let mag = normalized.magnitude();
165 assert!((mag - 1.0).abs() < f32::EPSILON);
166 }
167
168 #[test]
169 fn test_const_constructors() {
170 let zero = Vector3Float::zero();
171 assert_eq!(zero, Vector3Float::new(0.0, 0.0, 0.0));
172
173 let unit_x = Vector3Float::unit_x();
174 assert_eq!(unit_x, Vector3Float::new(1.0, 0.0, 0.0));
175 }
176}