1use crate::traits::{
31 CrossProduct, DotProduct, IntoDegrees, IntoRadians, Length, LengthSquared, Lerp, Normalize,
32 NormalizeAssign, Real,
33};
34use crate::vector::TVec2;
35use crate::vector::TVec4;
36use core::fmt::{Display, Error, Formatter};
37use core::ops::{
38 Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign,
39};
40
41#[repr(align(16))]
46#[derive(Copy, Clone, Debug)]
47pub struct TVec3<T: Real> {
48 pub(crate) data: [T; 4],
49}
50
51pub const fn vector_3_f32(x: f32, y: f32, z: f32) -> TVec3<f32> {
55 TVec3::<f32> {
56 data: [x, y, z, 0.0],
57 }
58}
59
60pub const fn vector_3_f64(x: f64, y: f64, z: f64) -> TVec3<f64> {
64 TVec3::<f64> {
65 data: [x, y, z, 0.0],
66 }
67}
68
69impl<T: Real> TVec3<T> {
70 #[inline]
74 pub fn new(x: T, y: T, z: T) -> Self {
75 TVec3 {
76 data: [x, y, z, T::zero()],
77 }
78 }
79
80 #[inline]
84 pub fn zero() -> Self {
85 Self::new(T::zero(), T::zero(), T::zero())
86 }
87
88 #[inline]
92 pub fn one() -> Self {
93 Self::new(T::one(), T::one(), T::one())
94 }
95
96 #[inline]
100 pub fn up() -> Self {
101 Self::new(T::zero(), T::one(), T::zero())
102 }
103
104 #[inline]
108 pub fn down() -> Self {
109 Self::new(T::zero(), -T::one(), T::zero())
110 }
111
112 #[inline]
116 pub fn right() -> Self {
117 Self::new(T::one(), T::zero(), T::zero())
118 }
119
120 #[inline]
124 pub fn left() -> Self {
125 Self::new(-T::one(), T::zero(), T::zero())
126 }
127
128 #[inline]
132 pub fn forward() -> Self {
133 Self::new(T::zero(), T::zero(), T::one())
134 }
135
136 #[inline]
140 pub fn back() -> Self {
141 Self::new(T::zero(), T::zero(), -T::one())
142 }
143}
144
145impl<T: Real> Display for TVec3<T> {
146 fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
147 write!(
148 f,
149 "[ {:precision$} {:precision$} {:precision$} ]",
150 self.data[0],
151 self.data[1],
152 self.data[2],
153 precision = f.precision().unwrap_or(f.width().unwrap_or(4)),
154 )
155 }
156}
157
158impl<T: Real> From<T> for TVec3<T> {
159 #[inline]
160 fn from(other: T) -> Self {
161 Self::new(other, T::zero(), T::zero())
162 }
163}
164
165impl<T: Real> From<TVec2<T>> for TVec3<T> {
166 #[inline]
167 fn from(other: TVec2<T>) -> Self {
168 Self::new(other.data[0], other.data[1], T::zero())
169 }
170}
171
172impl<T: Real> From<TVec4<T>> for TVec3<T> {
173 #[inline]
174 fn from(other: TVec4<T>) -> Self {
175 Self::new(other.data[0], other.data[1], other.data[2])
176 }
177}
178
179impl<T: Real> From<[T; 3]> for TVec3<T> {
180 #[inline]
184 fn from(other: [T; 3]) -> Self {
185 Self {
186 data: [other[0], other[1], other[2], T::zero()],
187 }
188 }
189}
190
191impl<T: Real> Into<[T; 3]> for TVec3<T> {
192 #[inline]
193 fn into(self) -> [T; 3] {
194 [self.data[0], self.data[1], self.data[2]]
195 }
196}
197
198impl<T: Real> From<(T, T, T)> for TVec3<T> {
199 #[inline]
203 fn from(other: (T, T, T)) -> Self {
204 Self {
205 data: [other.0, other.1, other.2, T::zero()],
206 }
207 }
208}
209
210impl<T: Real> Into<(T, T, T)> for TVec3<T> {
211 #[inline]
212 fn into(self) -> (T, T, T) {
213 (self.data[0], self.data[1], self.data[2])
214 }
215}
216
217impl<T: Real> Index<usize> for TVec3<T> {
218 type Output = T;
219
220 #[inline]
221 fn index(&self, index: usize) -> &Self::Output {
222 &self.data[index]
223 }
224}
225
226impl<T: Real> IndexMut<usize> for TVec3<T> {
227 #[inline]
228 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
229 &mut self.data[index]
230 }
231}
232
233impl<T: Real> Add<TVec3<T>> for TVec3<T> {
238 type Output = TVec3<T>;
239
240 #[inline]
241 fn add(mut self, rhs: TVec3<T>) -> Self::Output {
242 self.data[0] += rhs.data[0];
243 self.data[1] += rhs.data[1];
244 self.data[2] += rhs.data[2];
245 self
246 }
247}
248
249impl<T: Real> AddAssign<TVec3<T>> for TVec3<T> {
250 #[inline]
251 fn add_assign(&mut self, rhs: TVec3<T>) {
252 self.data[0] += rhs.data[0];
253 self.data[1] += rhs.data[1];
254 self.data[2] += rhs.data[2];
255 }
256}
257
258impl<T: Real> Sub<TVec3<T>> for TVec3<T> {
259 type Output = TVec3<T>;
260
261 #[inline]
262 fn sub(mut self, rhs: TVec3<T>) -> Self::Output {
263 self.data[0] -= rhs.data[0];
264 self.data[1] -= rhs.data[1];
265 self.data[2] -= rhs.data[2];
266 self
267 }
268}
269
270impl<T: Real> SubAssign<TVec3<T>> for TVec3<T> {
271 #[inline]
272 fn sub_assign(&mut self, rhs: TVec3<T>) {
273 self.data[0] -= rhs.data[0];
274 self.data[1] -= rhs.data[1];
275 self.data[2] -= rhs.data[2];
276 }
277}
278
279impl<T: Real> Mul<TVec3<T>> for TVec3<T> {
280 type Output = TVec3<T>;
281
282 #[inline]
283 fn mul(mut self, rhs: TVec3<T>) -> Self::Output {
284 self.data[0] *= rhs.data[0];
285 self.data[1] *= rhs.data[1];
286 self.data[2] *= rhs.data[2];
287 self
288 }
289}
290
291impl<T: Real> MulAssign<TVec3<T>> for TVec3<T> {
292 #[inline]
293 fn mul_assign(&mut self, rhs: TVec3<T>) {
294 self.data[0] *= rhs.data[0];
295 self.data[1] *= rhs.data[1];
296 self.data[2] *= rhs.data[2];
297 }
298}
299
300impl<T: Real> Div<TVec3<T>> for TVec3<T> {
301 type Output = TVec3<T>;
302
303 #[inline]
304 fn div(mut self, rhs: TVec3<T>) -> Self::Output {
305 self.data[0] /= rhs.data[0];
306 self.data[1] /= rhs.data[1];
307 self.data[2] /= rhs.data[2];
308 self
309 }
310}
311
312impl<T: Real> DivAssign<TVec3<T>> for TVec3<T> {
313 #[inline]
314 fn div_assign(&mut self, rhs: TVec3<T>) {
315 self.data[0] /= rhs.data[0];
316 self.data[1] /= rhs.data[1];
317 self.data[2] /= rhs.data[2];
318 }
319}
320
321impl<T: Real> Add<T> for TVec3<T> {
326 type Output = TVec3<T>;
327
328 #[inline]
329 fn add(mut self, rhs: T) -> Self::Output {
330 self.data[0] += rhs;
331 self.data[1] += rhs;
332 self.data[2] += rhs;
333 self
334 }
335}
336
337impl<T: Real> AddAssign<T> for TVec3<T> {
338 #[inline]
339 fn add_assign(&mut self, rhs: T) {
340 self.data[0] += rhs;
341 self.data[1] += rhs;
342 self.data[2] += rhs;
343 }
344}
345
346impl<T: Real> Sub<T> for TVec3<T> {
347 type Output = TVec3<T>;
348
349 #[inline]
350 fn sub(mut self, rhs: T) -> Self::Output {
351 self.data[0] -= rhs;
352 self.data[1] -= rhs;
353 self.data[2] -= rhs;
354 self
355 }
356}
357
358impl<T: Real> SubAssign<T> for TVec3<T> {
359 #[inline]
360 fn sub_assign(&mut self, rhs: T) {
361 self.data[0] -= rhs;
362 self.data[1] -= rhs;
363 self.data[2] -= rhs;
364 }
365}
366
367impl<T: Real> Mul<T> for TVec3<T> {
368 type Output = TVec3<T>;
369
370 #[inline]
371 fn mul(mut self, rhs: T) -> Self::Output {
372 self.data[0] *= rhs;
373 self.data[1] *= rhs;
374 self.data[2] *= rhs;
375 self
376 }
377}
378
379impl<T: Real> MulAssign<T> for TVec3<T> {
380 #[inline]
381 fn mul_assign(&mut self, rhs: T) {
382 self.data[0] *= rhs;
383 self.data[1] *= rhs;
384 self.data[2] *= rhs;
385 }
386}
387
388impl<T: Real> Div<T> for TVec3<T> {
389 type Output = TVec3<T>;
390
391 #[inline]
392 fn div(mut self, rhs: T) -> Self::Output {
393 self.data[0] /= rhs;
394 self.data[1] /= rhs;
395 self.data[2] /= rhs;
396 self
397 }
398}
399
400impl<T: Real> DivAssign<T> for TVec3<T> {
401 #[inline]
402 fn div_assign(&mut self, rhs: T) {
403 self.data[0] /= rhs;
404 self.data[1] /= rhs;
405 self.data[2] /= rhs;
406 }
407}
408
409impl<T: Real> Neg for TVec3<T> {
410 type Output = Self;
411
412 #[inline]
413 fn neg(mut self) -> Self::Output {
414 self.data[0] = -self.data[0];
415 self.data[1] = -self.data[1];
416 self.data[2] = -self.data[2];
417 self
418 }
419}
420
421impl<T: Real> Lerp<T> for TVec3<T> {
422 #[inline]
423 fn lerp(&self, b: &Self, factor: T) -> Self {
424 *self + ((*self - *b) * factor)
425 }
426}
427
428impl<T: Real> Length for TVec3<T> {
429 type Output = T;
430
431 #[inline]
432 fn length(&self) -> Self::Output {
433 self.length_squared().sqrt()
434 }
435}
436
437impl<T: Real> LengthSquared for TVec3<T> {
438 type Output = T;
439
440 #[inline]
441 fn length_squared(&self) -> Self::Output {
442 self.dot(self)
443 }
444}
445
446impl<T: Real> Normalize for TVec3<T> {
447 #[inline]
448 fn normalize(mut self) -> Self {
449 self.normalize_assign();
450 self
451 }
452}
453
454impl<T: Real> NormalizeAssign for TVec3<T> {
455 #[inline]
456 fn normalize_assign(&mut self) {
457 let len = self.length();
458 *self *= T::one() / len;
459 }
460}
461
462impl<T: Real> DotProduct<T> for TVec3<T> {
463 #[inline]
464 fn dot(&self, rhs: &Self) -> T {
465 (self.data[0] * rhs.data[0]) + (self.data[1] * rhs.data[1]) + (self.data[2] * rhs.data[2])
466 }
467}
468
469impl<T: Real> IntoDegrees for TVec3<T> {
470 #[inline]
471 fn into_degrees(mut self) -> Self {
472 self.data[0] = self.data[0].into_degrees();
473 self.data[1] = self.data[1].into_degrees();
474 self.data[2] = self.data[2].into_degrees();
475 self
476 }
477}
478
479impl<T: Real> IntoRadians for TVec3<T> {
480 #[inline]
481 fn into_radians(mut self) -> Self {
482 self.data[0] = self.data[0].into_radians();
483 self.data[1] = self.data[1].into_radians();
484 self.data[2] = self.data[2].into_radians();
485 self
486 }
487}
488
489impl<T: Real> CrossProduct for TVec3<T> {
490 #[inline]
491 fn cross(&self, rhs: &Self) -> Self {
492 let x = (self.data[1] * rhs.data[2]) - (self.data[2] * rhs.data[1]);
493 let y = (self.data[2] * rhs.data[0]) - (self.data[0] * rhs.data[2]);
494 let z = (self.data[0] * rhs.data[1]) - (self.data[1] * rhs.data[0]);
495 Self::new(x, y, z)
496 }
497}
498
499impl<T: Real> PartialEq<TVec3<T>> for TVec3<T> {
500 #[inline]
501 fn eq(&self, other: &TVec3<T>) -> bool {
502 self.data[0] == other.data[0]
503 && self.data[1] == other.data[1]
504 && self.data[2] == other.data[2]
505 }
506
507 #[inline]
508 fn ne(&self, other: &TVec3<T>) -> bool {
509 self.data[0] != other.data[0]
510 || self.data[1] != other.data[1]
511 || self.data[2] != other.data[2]
512 }
513}