1use std::fmt;
4use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign};
5
6use super::single::{self, InvariantF32};
7use super::{Matrix4x4, Quaternion, Vector2};
8use crate::Vector3D;
9
10#[derive(Clone, Copy, Debug, PartialEq, Default)]
16#[repr(C)]
17pub struct Vector3 {
18 pub x: f32,
20 pub y: f32,
22 pub z: f32,
24}
25
26impl Vector3 {
27 pub const ZERO: Vector3 = Vector3::new(0.0, 0.0, 0.0);
29 pub const ONE: Vector3 = Vector3::new(1.0, 1.0, 1.0);
31 pub const UNIT_X: Vector3 = Vector3::new(1.0, 0.0, 0.0);
33 pub const UNIT_Y: Vector3 = Vector3::new(0.0, 1.0, 0.0);
35 pub const UNIT_Z: Vector3 = Vector3::new(0.0, 0.0, 1.0);
37
38 #[inline]
40 pub const fn new(x: f32, y: f32, z: f32) -> Self {
41 Self { x, y, z }
42 }
43
44 #[inline]
46 pub const fn from_value(value: f32) -> Self {
47 Self::new(value, value, value)
48 }
49
50 #[inline]
52 pub const fn from_vector2(value: Vector2, z: f32) -> Self {
53 Self::new(value.x, value.y, z)
54 }
55
56 #[inline]
59 pub fn abs(value: Vector3) -> Vector3 {
60 Vector3::new(value.x.abs(), value.y.abs(), value.z.abs())
61 }
62
63 #[inline]
66 pub fn clamp(value1: Vector3, min: Vector3, max: Vector3) -> Vector3 {
67 Vector3::min(Vector3::max(value1, min), max)
68 }
69
70 #[inline]
72 pub fn cross(vector1: Vector3, vector2: Vector3) -> Vector3 {
73 Vector3::new(
74 (vector1.y * vector2.z) - (vector1.z * vector2.y),
75 (vector1.z * vector2.x) - (vector1.x * vector2.z),
76 (vector1.x * vector2.y) - (vector1.y * vector2.x),
77 )
78 }
79
80 #[inline]
82 pub fn distance(value1: Vector3, value2: Vector3) -> f32 {
83 Vector3::distance_squared(value1, value2).sqrt()
84 }
85
86 #[inline]
88 pub fn distance_squared(value1: Vector3, value2: Vector3) -> f32 {
89 (value1 - value2).length_squared()
90 }
91
92 #[inline]
94 pub fn dot(vector1: Vector3, vector2: Vector3) -> f32 {
95 (vector1.x * vector2.x) + (vector1.y * vector2.y) + (vector1.z * vector2.z)
96 }
97
98 #[inline]
100 pub fn length(&self) -> f32 {
101 self.length_squared().sqrt()
102 }
103
104 #[inline]
106 pub fn length_squared(&self) -> f32 {
107 Vector3::dot(*self, *self)
108 }
109
110 #[inline]
112 pub fn lerp(value1: Vector3, value2: Vector3, amount: f32) -> Vector3 {
113 (value1 * (1.0 - amount)) + (value2 * amount)
114 }
115
116 #[inline]
119 pub fn max(value1: Vector3, value2: Vector3) -> Vector3 {
120 Vector3::new(
121 single::max(value1.x, value2.x),
122 single::max(value1.y, value2.y),
123 single::max(value1.z, value2.z),
124 )
125 }
126
127 #[inline]
130 pub fn min(value1: Vector3, value2: Vector3) -> Vector3 {
131 Vector3::new(
132 single::min(value1.x, value2.x),
133 single::min(value1.y, value2.y),
134 single::min(value1.z, value2.z),
135 )
136 }
137
138 #[inline]
141 pub fn normalize(value: Vector3) -> Vector3 {
142 value / value.length()
143 }
144
145 #[inline]
148 pub fn square_root(value: Vector3) -> Vector3 {
149 Vector3::new(value.x.sqrt(), value.y.sqrt(), value.z.sqrt())
150 }
151
152 #[inline]
154 pub fn transform(position: Vector3, matrix: Matrix4x4) -> Vector3 {
155 Vector3::new(
156 (position.x * matrix.m11) + (position.y * matrix.m21) + (position.z * matrix.m31) + matrix.m41,
157 (position.x * matrix.m12) + (position.y * matrix.m22) + (position.z * matrix.m32) + matrix.m42,
158 (position.x * matrix.m13) + (position.y * matrix.m23) + (position.z * matrix.m33) + matrix.m43,
159 )
160 }
161
162 pub fn transform_quaternion(value: Vector3, rotation: Quaternion) -> Vector3 {
164 let x2 = rotation.x + rotation.x;
165 let y2 = rotation.y + rotation.y;
166 let z2 = rotation.z + rotation.z;
167
168 let wx2 = rotation.w * x2;
169 let wy2 = rotation.w * y2;
170 let wz2 = rotation.w * z2;
171 let xx2 = rotation.x * x2;
172 let xy2 = rotation.x * y2;
173 let xz2 = rotation.x * z2;
174 let yy2 = rotation.y * y2;
175 let yz2 = rotation.y * z2;
176 let zz2 = rotation.z * z2;
177
178 Vector3::new(
179 value.x * (1.0 - yy2 - zz2) + value.y * (xy2 - wz2) + value.z * (xz2 + wy2),
180 value.x * (xy2 + wz2) + value.y * (1.0 - xx2 - zz2) + value.z * (yz2 - wx2),
181 value.x * (xz2 - wy2) + value.y * (yz2 + wx2) + value.z * (1.0 - xx2 - yy2),
182 )
183 }
184
185 #[inline]
187 pub fn transform_normal(normal: Vector3, matrix: Matrix4x4) -> Vector3 {
188 Vector3::new(
189 (normal.x * matrix.m11) + (normal.y * matrix.m21) + (normal.z * matrix.m31),
190 (normal.x * matrix.m12) + (normal.y * matrix.m22) + (normal.z * matrix.m32),
191 (normal.x * matrix.m13) + (normal.y * matrix.m23) + (normal.z * matrix.m33),
192 )
193 }
194}
195
196impl From<Vector3D> for Vector3 {
198 #[inline]
199 fn from(value: Vector3D) -> Vector3 {
200 Vector3::new(value.x as f32, value.y as f32, value.z as f32)
201 }
202}
203
204impl From<Vector3> for Vector3D {
206 #[inline]
207 fn from(value: Vector3) -> Vector3D {
208 Vector3D::new(value.x as f64, value.y as f64, value.z as f64)
209 }
210}
211
212impl Add for Vector3 {
213 type Output = Vector3;
214 #[inline]
215 fn add(self, right: Vector3) -> Vector3 {
216 Vector3::new(self.x + right.x, self.y + right.y, self.z + right.z)
217 }
218}
219
220impl Sub for Vector3 {
221 type Output = Vector3;
222 #[inline]
223 fn sub(self, right: Vector3) -> Vector3 {
224 Vector3::new(self.x - right.x, self.y - right.y, self.z - right.z)
225 }
226}
227
228impl Mul for Vector3 {
229 type Output = Vector3;
230 #[inline]
231 fn mul(self, right: Vector3) -> Vector3 {
232 Vector3::new(self.x * right.x, self.y * right.y, self.z * right.z)
233 }
234}
235
236impl Mul<f32> for Vector3 {
237 type Output = Vector3;
238 #[inline]
239 fn mul(self, right: f32) -> Vector3 {
240 Vector3::new(self.x * right, self.y * right, self.z * right)
241 }
242}
243
244impl Mul<Vector3> for f32 {
245 type Output = Vector3;
246 #[inline]
247 fn mul(self, right: Vector3) -> Vector3 {
248 right * self
249 }
250}
251
252impl Div for Vector3 {
253 type Output = Vector3;
254 #[inline]
255 fn div(self, right: Vector3) -> Vector3 {
256 Vector3::new(self.x / right.x, self.y / right.y, self.z / right.z)
257 }
258}
259
260impl Div<f32> for Vector3 {
261 type Output = Vector3;
262 #[inline]
263 fn div(self, right: f32) -> Vector3 {
264 Vector3::new(self.x / right, self.y / right, self.z / right)
265 }
266}
267
268impl Neg for Vector3 {
269 type Output = Vector3;
270 #[inline]
271 fn neg(self) -> Vector3 {
272 Vector3::new(-self.x, -self.y, -self.z)
273 }
274}
275
276impl AddAssign for Vector3 {
277 #[inline]
278 fn add_assign(&mut self, right: Vector3) {
279 *self = *self + right;
280 }
281}
282
283impl SubAssign for Vector3 {
284 #[inline]
285 fn sub_assign(&mut self, right: Vector3) {
286 *self = *self - right;
287 }
288}
289
290impl MulAssign for Vector3 {
291 #[inline]
292 fn mul_assign(&mut self, right: Vector3) {
293 *self = *self * right;
294 }
295}
296
297impl MulAssign<f32> for Vector3 {
298 #[inline]
299 fn mul_assign(&mut self, right: f32) {
300 *self = *self * right;
301 }
302}
303
304impl DivAssign for Vector3 {
305 #[inline]
306 fn div_assign(&mut self, right: Vector3) {
307 *self = *self / right;
308 }
309}
310
311impl DivAssign<f32> for Vector3 {
312 #[inline]
313 fn div_assign(&mut self, right: f32) {
314 *self = *self / right;
315 }
316}
317
318impl fmt::Display for Vector3 {
319 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
320 write!(
321 f,
322 "<{}, {}, {}>",
323 InvariantF32(self.x),
324 InvariantF32(self.y),
325 InvariantF32(self.z)
326 )
327 }
328}