1use crate::traits::{
31 DotProduct, IntoDegrees, IntoRadians, Length, LengthSquared, Lerp, Normalize, NormalizeAssign,
32 Real,
33};
34use crate::vector::TVec2;
35use crate::vector::TVec3;
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 TVec4<T: Real> {
48 pub(crate) data: [T; 4],
49}
50
51pub const fn vector_4_f32(x: f32, y: f32, z: f32, w: f32) -> TVec4<f32> {
55 TVec4::<f32> { data: [x, y, z, w] }
56}
57
58pub const fn vector_4_f64(x: f64, y: f64, z: f64, w: f64) -> TVec4<f64> {
62 TVec4::<f64> { data: [x, y, z, w] }
63}
64
65impl<T: Real> TVec4<T> {
66 #[inline]
70 pub fn new(x: T, y: T, z: T, w: T) -> Self {
71 TVec4 { data: [x, y, z, w] }
72 }
73
74 #[inline]
78 pub fn zero() -> Self {
79 Self::new(T::zero(), T::zero(), T::zero(), T::zero())
80 }
81}
82
83impl<T: Real> Display for TVec4<T> {
84 fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
85 write!(
86 f,
87 "[ {:precision$} {:precision$} {:precision$} {:precision$} ]",
88 self.data[0],
89 self.data[1],
90 self.data[2],
91 self.data[3],
92 precision = f.precision().unwrap_or(f.width().unwrap_or(4)),
93 )
94 }
95}
96
97impl<T: Real> From<T> for TVec4<T> {
98 #[inline]
99 fn from(other: T) -> Self {
100 Self::new(other, T::zero(), T::zero(), T::zero())
101 }
102}
103
104impl<T: Real> From<TVec2<T>> for TVec4<T> {
105 #[inline]
106 fn from(other: TVec2<T>) -> Self {
107 Self::new(other.data[0], other.data[1], T::zero(), T::zero())
108 }
109}
110
111impl<T: Real> From<TVec3<T>> for TVec4<T> {
112 #[inline]
113 fn from(other: TVec3<T>) -> Self {
114 Self::new(other.data[0], other.data[1], other.data[2], T::zero())
115 }
116}
117
118impl<T: Real> From<[T; 4]> for TVec4<T> {
119 #[inline]
123 fn from(other: [T; 4]) -> Self {
124 Self { data: other }
125 }
126}
127
128impl<T: Real> Into<[T; 4]> for TVec4<T> {
129 #[inline]
130 fn into(self) -> [T; 4] {
131 self.data
132 }
133}
134
135impl<T: Real> Index<usize> for TVec4<T> {
136 type Output = T;
137
138 #[inline]
139 fn index(&self, index: usize) -> &Self::Output {
140 &self.data[index]
141 }
142}
143
144impl<T: Real> IndexMut<usize> for TVec4<T> {
145 #[inline]
146 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
147 &mut self.data[index]
148 }
149}
150
151impl<T: Real> Add<TVec4<T>> for TVec4<T> {
156 type Output = TVec4<T>;
157
158 #[inline]
159 fn add(mut self, rhs: TVec4<T>) -> Self::Output {
160 self.data[0] += rhs.data[0];
161 self.data[1] += rhs.data[1];
162 self.data[2] += rhs.data[2];
163 self.data[3] += rhs.data[3];
164 self
165 }
166}
167
168impl<T: Real> AddAssign<TVec4<T>> for TVec4<T> {
169 #[inline]
170 fn add_assign(&mut self, rhs: TVec4<T>) {
171 self.data[0] += rhs.data[0];
172 self.data[1] += rhs.data[1];
173 self.data[2] += rhs.data[2];
174 self.data[3] += rhs.data[3];
175 }
176}
177
178impl<T: Real> Sub<TVec4<T>> for TVec4<T> {
179 type Output = TVec4<T>;
180
181 #[inline]
182 fn sub(mut self, rhs: TVec4<T>) -> Self::Output {
183 self.data[0] -= rhs.data[0];
184 self.data[1] -= rhs.data[1];
185 self.data[2] -= rhs.data[2];
186 self.data[3] -= rhs.data[3];
187 self
188 }
189}
190
191impl<T: Real> SubAssign<TVec4<T>> for TVec4<T> {
192 #[inline]
193 fn sub_assign(&mut self, rhs: TVec4<T>) {
194 self.data[0] -= rhs.data[0];
195 self.data[1] -= rhs.data[1];
196 self.data[2] -= rhs.data[2];
197 self.data[3] -= rhs.data[3];
198 }
199}
200
201impl<T: Real> Mul<TVec4<T>> for TVec4<T> {
202 type Output = TVec4<T>;
203
204 #[inline]
205 fn mul(mut self, rhs: TVec4<T>) -> Self::Output {
206 self.data[0] *= rhs.data[0];
207 self.data[1] *= rhs.data[1];
208 self.data[2] *= rhs.data[2];
209 self.data[3] *= rhs.data[3];
210 self
211 }
212}
213
214impl<T: Real> MulAssign<TVec4<T>> for TVec4<T> {
215 #[inline]
216 fn mul_assign(&mut self, rhs: TVec4<T>) {
217 self.data[0] *= rhs.data[0];
218 self.data[1] *= rhs.data[1];
219 self.data[2] *= rhs.data[2];
220 self.data[3] *= rhs.data[3];
221 }
222}
223
224impl<T: Real> Div<TVec4<T>> for TVec4<T> {
225 type Output = TVec4<T>;
226
227 #[inline]
228 fn div(mut self, rhs: TVec4<T>) -> Self::Output {
229 self.data[0] /= rhs.data[0];
230 self.data[1] /= rhs.data[1];
231 self.data[2] /= rhs.data[2];
232 self.data[3] /= rhs.data[3];
233 self
234 }
235}
236
237impl<T: Real> DivAssign<TVec4<T>> for TVec4<T> {
238 #[inline]
239 fn div_assign(&mut self, rhs: TVec4<T>) {
240 self.data[0] /= rhs.data[0];
241 self.data[1] /= rhs.data[1];
242 self.data[2] /= rhs.data[2];
243 self.data[3] /= rhs.data[3];
244 }
245}
246
247impl<T: Real> Add<T> for TVec4<T> {
252 type Output = TVec4<T>;
253
254 #[inline]
255 fn add(mut self, rhs: T) -> Self::Output {
256 self.data[0] += rhs;
257 self.data[1] += rhs;
258 self.data[2] += rhs;
259 self.data[3] += rhs;
260 self
261 }
262}
263
264impl<T: Real> AddAssign<T> for TVec4<T> {
265 #[inline]
266 fn add_assign(&mut self, rhs: T) {
267 self.data[0] += rhs;
268 self.data[1] += rhs;
269 self.data[2] += rhs;
270 self.data[3] += rhs;
271 }
272}
273
274impl<T: Real> Sub<T> for TVec4<T> {
275 type Output = TVec4<T>;
276
277 #[inline]
278 fn sub(mut self, rhs: T) -> Self::Output {
279 self.data[0] -= rhs;
280 self.data[1] -= rhs;
281 self.data[2] -= rhs;
282 self.data[3] -= rhs;
283 self
284 }
285}
286
287impl<T: Real> SubAssign<T> for TVec4<T> {
288 #[inline]
289 fn sub_assign(&mut self, rhs: T) {
290 self.data[0] -= rhs;
291 self.data[1] -= rhs;
292 self.data[2] -= rhs;
293 self.data[3] -= rhs;
294 }
295}
296
297impl<T: Real> Mul<T> for TVec4<T> {
298 type Output = TVec4<T>;
299
300 #[inline]
301 fn mul(mut self, rhs: T) -> Self::Output {
302 self.data[0] *= rhs;
303 self.data[1] *= rhs;
304 self.data[2] *= rhs;
305 self.data[3] *= rhs;
306 self
307 }
308}
309
310impl<T: Real> MulAssign<T> for TVec4<T> {
311 #[inline]
312 fn mul_assign(&mut self, rhs: T) {
313 self.data[0] *= rhs;
314 self.data[1] *= rhs;
315 self.data[2] *= rhs;
316 self.data[3] *= rhs;
317 }
318}
319
320impl<T: Real> Div<T> for TVec4<T> {
321 type Output = TVec4<T>;
322
323 #[inline]
324 fn div(mut self, rhs: T) -> Self::Output {
325 self.data[0] /= rhs;
326 self.data[1] /= rhs;
327 self.data[2] /= rhs;
328 self.data[3] /= rhs;
329 self
330 }
331}
332
333impl<T: Real> DivAssign<T> for TVec4<T> {
334 #[inline]
335 fn div_assign(&mut self, rhs: T) {
336 self.data[0] /= rhs;
337 self.data[1] /= rhs;
338 self.data[2] /= rhs;
339 self.data[3] /= rhs;
340 }
341}
342
343impl<T: Real> Neg for TVec4<T> {
344 type Output = Self;
345
346 #[inline]
347 fn neg(mut self) -> Self::Output {
348 self.data[0] = -self.data[0];
349 self.data[1] = -self.data[1];
350 self.data[2] = -self.data[2];
351 self.data[3] = -self.data[3];
352 self
353 }
354}
355
356impl<T: Real> Lerp<T> for TVec4<T> {
357 #[inline]
358 fn lerp(&self, b: &Self, factor: T) -> Self {
359 *self + ((*self - *b) * factor)
360 }
361}
362
363impl<T: Real> Length for TVec4<T> {
364 type Output = T;
365
366 fn length(&self) -> Self::Output {
367 self.length_squared().sqrt()
368 }
369}
370
371impl<T: Real> LengthSquared for TVec4<T> {
372 type Output = T;
373
374 fn length_squared(&self) -> Self::Output {
375 self.dot(self)
376 }
377}
378
379impl<T: Real> Normalize for TVec4<T> {
380 fn normalize(mut self) -> Self {
381 self.normalize_assign();
382 self
383 }
384}
385
386impl<T: Real> NormalizeAssign for TVec4<T> {
387 fn normalize_assign(&mut self) {
388 let len = self.length();
389 *self *= T::one() / len;
390 }
391}
392
393impl<T: Real> IntoDegrees for TVec4<T> {
394 #[inline]
395 fn into_degrees(mut self) -> Self {
396 self.data[0] = self.data[0].into_degrees();
397 self.data[1] = self.data[1].into_degrees();
398 self.data[2] = self.data[2].into_degrees();
399 self.data[3] = self.data[3].into_degrees();
400 self
401 }
402}
403
404impl<T: Real> IntoRadians for TVec4<T> {
405 #[inline]
406 fn into_radians(mut self) -> Self {
407 self.data[0] = self.data[0].into_radians();
408 self.data[1] = self.data[1].into_radians();
409 self.data[2] = self.data[2].into_radians();
410 self.data[3] = self.data[3].into_radians();
411 self
412 }
413}
414
415impl<T: Real> DotProduct<T> for TVec4<T> {
416 #[inline]
417 fn dot(&self, rhs: &Self) -> T {
418 (self.data[0] * rhs.data[0])
419 + (self.data[1] * rhs.data[1])
420 + (self.data[2] * rhs.data[2])
421 + (self.data[3] * rhs.data[3])
422 }
423}
424
425impl<T: Real> PartialEq<TVec4<T>> for TVec4<T> {
426 #[inline]
427 fn eq(&self, other: &TVec4<T>) -> bool {
428 self.data[0] == other.data[0]
429 && self.data[1] == other.data[1]
430 && self.data[2] == other.data[2]
431 && self.data[3] == other.data[3]
432 }
433
434 #[inline]
435 fn ne(&self, other: &TVec4<T>) -> bool {
436 self.data[0] != other.data[0]
437 || self.data[1] != other.data[1]
438 || self.data[2] != other.data[2]
439 || self.data[3] != other.data[3]
440 }
441}