1use std::{fmt::Display, ops::Neg};
2
3use auto_ops::{impl_op_ex, impl_op_ex_commutative};
4
5#[derive(Debug, Clone, Copy, PartialEq)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7#[repr(C)]
8pub struct Vec4 {
9 pub x: f32,
10 pub y: f32,
11 pub z: f32,
12 pub w: f32,
13}
14
15impl Default for Vec4 {
16 fn default() -> Self {
18 Self::zero()
19 }
20}
21
22impl Display for Vec4 {
23 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24 let Self { x, y, z, w } = self;
25 write!(f, "({x}, {y}, {z}, {w})")
26 }
27}
28
29impl Vec4 {
30 pub const fn new(x: f32, y: f32, z: f32, w: f32) -> Self {
31 Self { x, y, z, w }
32 }
33
34 pub const fn zero() -> Self {
36 Self {
37 x: 0.0,
38 y: 0.0,
39 z: 0.0,
40 w: 0.0,
41 }
42 }
43
44 pub const fn one() -> Self {
46 Self {
47 x: 1.0,
48 y: 1.0,
49 z: 1.0,
50 w: 1.0,
51 }
52 }
53
54 pub fn sqr_magnitude(&self) -> f32 {
58 self.x * self.x + self.y * self.y + self.z * self.z + self.w * self.w
59 }
60
61 pub fn magnitude(&self) -> f32 {
63 self.sqr_magnitude().sqrt()
64 }
65
66 pub fn normalize(&mut self) -> &mut Self {
68 let m = self.magnitude();
69 self.x /= m;
70 self.y /= m;
71 self.z /= m;
72 self.w /= m;
73 self
74 }
75 #[must_use]
77 pub fn normalized(&self) -> Self {
78 *self.clone().normalize()
79 }
80
81 pub fn dot(&self, b: Vec4) -> f32 {
83 self.x * b.x + self.y * b.y + self.z * b.z + self.w * b.w
84 }
85
86 swizzle!(x, x);
87 swizzle!(x, y);
88 swizzle!(x, z);
89 swizzle!(x, w);
90 swizzle!(y, x);
91 swizzle!(y, y);
92 swizzle!(y, z);
93 swizzle!(y, w);
94 swizzle!(z, x);
95 swizzle!(z, y);
96 swizzle!(z, z);
97 swizzle!(z, w);
98 swizzle!(w, x);
99 swizzle!(w, y);
100 swizzle!(w, z);
101 swizzle!(w, w);
102
103 swizzle!(x, x, x);
104 swizzle!(x, x, y);
105 swizzle!(x, x, z);
106 swizzle!(x, x, w);
107 swizzle!(x, y, x);
108 swizzle!(x, y, y);
109 swizzle!(x, y, z);
110 swizzle!(x, y, w);
111 swizzle!(x, z, x);
112 swizzle!(x, z, y);
113 swizzle!(x, z, z);
114 swizzle!(x, z, w);
115 swizzle!(x, w, x);
116 swizzle!(x, w, y);
117 swizzle!(x, w, z);
118 swizzle!(x, w, w);
119 swizzle!(y, x, x);
120 swizzle!(y, x, y);
121 swizzle!(y, x, z);
122 swizzle!(y, x, w);
123 swizzle!(y, y, x);
124 swizzle!(y, y, y);
125 swizzle!(y, y, z);
126 swizzle!(y, y, w);
127 swizzle!(y, z, x);
128 swizzle!(y, z, y);
129 swizzle!(y, z, z);
130 swizzle!(y, z, w);
131 swizzle!(y, w, x);
132 swizzle!(y, w, y);
133 swizzle!(y, w, z);
134 swizzle!(y, w, w);
135 swizzle!(z, x, x);
136 swizzle!(z, x, y);
137 swizzle!(z, x, z);
138 swizzle!(z, x, w);
139 swizzle!(z, y, x);
140 swizzle!(z, y, y);
141 swizzle!(z, y, z);
142 swizzle!(z, y, w);
143 swizzle!(z, z, x);
144 swizzle!(z, z, y);
145 swizzle!(z, z, z);
146 swizzle!(z, z, w);
147 swizzle!(z, w, x);
148 swizzle!(z, w, y);
149 swizzle!(z, w, z);
150 swizzle!(z, w, w);
151 swizzle!(w, x, x);
152 swizzle!(w, x, y);
153 swizzle!(w, x, z);
154 swizzle!(w, x, w);
155 swizzle!(w, y, x);
156 swizzle!(w, y, y);
157 swizzle!(w, y, z);
158 swizzle!(w, y, w);
159 swizzle!(w, z, x);
160 swizzle!(w, z, y);
161 swizzle!(w, z, z);
162 swizzle!(w, z, w);
163 swizzle!(w, w, x);
164 swizzle!(w, w, y);
165 swizzle!(w, w, z);
166 swizzle!(w, w, w);
167
168 swizzle!(x, x, x, x);
169 swizzle!(x, x, x, y);
170 swizzle!(x, x, x, z);
171 swizzle!(x, x, x, w);
172 swizzle!(x, x, y, x);
173 swizzle!(x, x, y, y);
174 swizzle!(x, x, y, z);
175 swizzle!(x, x, y, w);
176 swizzle!(x, x, z, x);
177 swizzle!(x, x, z, y);
178 swizzle!(x, x, z, z);
179 swizzle!(x, x, z, w);
180 swizzle!(x, x, w, x);
181 swizzle!(x, x, w, y);
182 swizzle!(x, x, w, z);
183 swizzle!(x, x, w, w);
184 swizzle!(x, y, x, x);
185 swizzle!(x, y, x, y);
186 swizzle!(x, y, x, z);
187 swizzle!(x, y, x, w);
188 swizzle!(x, y, y, x);
189 swizzle!(x, y, y, y);
190 swizzle!(x, y, y, z);
191 swizzle!(x, y, y, w);
192 swizzle!(x, y, z, x);
193 swizzle!(x, y, z, y);
194 swizzle!(x, y, z, z);
195 swizzle!(x, y, z, w);
196 swizzle!(x, y, w, x);
197 swizzle!(x, y, w, y);
198 swizzle!(x, y, w, z);
199 swizzle!(x, y, w, w);
200 swizzle!(x, z, x, x);
201 swizzle!(x, z, x, y);
202 swizzle!(x, z, x, z);
203 swizzle!(x, z, x, w);
204 swizzle!(x, z, y, x);
205 swizzle!(x, z, y, y);
206 swizzle!(x, z, y, z);
207 swizzle!(x, z, y, w);
208 swizzle!(x, z, z, x);
209 swizzle!(x, z, z, y);
210 swizzle!(x, z, z, z);
211 swizzle!(x, z, z, w);
212 swizzle!(x, z, w, x);
213 swizzle!(x, z, w, y);
214 swizzle!(x, z, w, z);
215 swizzle!(x, z, w, w);
216 swizzle!(x, w, x, x);
217 swizzle!(x, w, x, y);
218 swizzle!(x, w, x, z);
219 swizzle!(x, w, x, w);
220 swizzle!(x, w, y, x);
221 swizzle!(x, w, y, y);
222 swizzle!(x, w, y, z);
223 swizzle!(x, w, y, w);
224 swizzle!(x, w, z, x);
225 swizzle!(x, w, z, y);
226 swizzle!(x, w, z, z);
227 swizzle!(x, w, z, w);
228 swizzle!(x, w, w, x);
229 swizzle!(x, w, w, y);
230 swizzle!(x, w, w, z);
231 swizzle!(x, w, w, w);
232 swizzle!(y, x, x, x);
233 swizzle!(y, x, x, y);
234 swizzle!(y, x, x, z);
235 swizzle!(y, x, x, w);
236 swizzle!(y, x, y, x);
237 swizzle!(y, x, y, y);
238 swizzle!(y, x, y, z);
239 swizzle!(y, x, y, w);
240 swizzle!(y, x, z, x);
241 swizzle!(y, x, z, y);
242 swizzle!(y, x, z, z);
243 swizzle!(y, x, z, w);
244 swizzle!(y, x, w, x);
245 swizzle!(y, x, w, y);
246 swizzle!(y, x, w, z);
247 swizzle!(y, x, w, w);
248 swizzle!(y, y, x, x);
249 swizzle!(y, y, x, y);
250 swizzle!(y, y, x, z);
251 swizzle!(y, y, x, w);
252 swizzle!(y, y, y, x);
253 swizzle!(y, y, y, y);
254 swizzle!(y, y, y, z);
255 swizzle!(y, y, y, w);
256 swizzle!(y, y, z, x);
257 swizzle!(y, y, z, y);
258 swizzle!(y, y, z, z);
259 swizzle!(y, y, z, w);
260 swizzle!(y, y, w, x);
261 swizzle!(y, y, w, y);
262 swizzle!(y, y, w, z);
263 swizzle!(y, y, w, w);
264 swizzle!(y, z, x, x);
265 swizzle!(y, z, x, y);
266 swizzle!(y, z, x, z);
267 swizzle!(y, z, x, w);
268 swizzle!(y, z, y, x);
269 swizzle!(y, z, y, y);
270 swizzle!(y, z, y, z);
271 swizzle!(y, z, y, w);
272 swizzle!(y, z, z, x);
273 swizzle!(y, z, z, y);
274 swizzle!(y, z, z, z);
275 swizzle!(y, z, z, w);
276 swizzle!(y, z, w, x);
277 swizzle!(y, z, w, y);
278 swizzle!(y, z, w, z);
279 swizzle!(y, z, w, w);
280 swizzle!(y, w, x, x);
281 swizzle!(y, w, x, y);
282 swizzle!(y, w, x, z);
283 swizzle!(y, w, x, w);
284 swizzle!(y, w, y, x);
285 swizzle!(y, w, y, y);
286 swizzle!(y, w, y, z);
287 swizzle!(y, w, y, w);
288 swizzle!(y, w, z, x);
289 swizzle!(y, w, z, y);
290 swizzle!(y, w, z, z);
291 swizzle!(y, w, z, w);
292 swizzle!(y, w, w, x);
293 swizzle!(y, w, w, y);
294 swizzle!(y, w, w, z);
295 swizzle!(y, w, w, w);
296 swizzle!(z, x, x, x);
297 swizzle!(z, x, x, y);
298 swizzle!(z, x, x, z);
299 swizzle!(z, x, x, w);
300 swizzle!(z, x, y, x);
301 swizzle!(z, x, y, y);
302 swizzle!(z, x, y, z);
303 swizzle!(z, x, y, w);
304 swizzle!(z, x, z, x);
305 swizzle!(z, x, z, y);
306 swizzle!(z, x, z, z);
307 swizzle!(z, x, z, w);
308 swizzle!(z, x, w, x);
309 swizzle!(z, x, w, y);
310 swizzle!(z, x, w, z);
311 swizzle!(z, x, w, w);
312 swizzle!(z, y, x, x);
313 swizzle!(z, y, x, y);
314 swizzle!(z, y, x, z);
315 swizzle!(z, y, x, w);
316 swizzle!(z, y, y, x);
317 swizzle!(z, y, y, y);
318 swizzle!(z, y, y, z);
319 swizzle!(z, y, y, w);
320 swizzle!(z, y, z, x);
321 swizzle!(z, y, z, y);
322 swizzle!(z, y, z, z);
323 swizzle!(z, y, z, w);
324 swizzle!(z, y, w, x);
325 swizzle!(z, y, w, y);
326 swizzle!(z, y, w, z);
327 swizzle!(z, y, w, w);
328 swizzle!(z, z, x, x);
329 swizzle!(z, z, x, y);
330 swizzle!(z, z, x, z);
331 swizzle!(z, z, x, w);
332 swizzle!(z, z, y, x);
333 swizzle!(z, z, y, y);
334 swizzle!(z, z, y, z);
335 swizzle!(z, z, y, w);
336 swizzle!(z, z, z, x);
337 swizzle!(z, z, z, y);
338 swizzle!(z, z, z, z);
339 swizzle!(z, z, z, w);
340 swizzle!(z, z, w, x);
341 swizzle!(z, z, w, y);
342 swizzle!(z, z, w, z);
343 swizzle!(z, z, w, w);
344 swizzle!(z, w, x, x);
345 swizzle!(z, w, x, y);
346 swizzle!(z, w, x, z);
347 swizzle!(z, w, x, w);
348 swizzle!(z, w, y, x);
349 swizzle!(z, w, y, y);
350 swizzle!(z, w, y, z);
351 swizzle!(z, w, y, w);
352 swizzle!(z, w, z, x);
353 swizzle!(z, w, z, y);
354 swizzle!(z, w, z, z);
355 swizzle!(z, w, z, w);
356 swizzle!(z, w, w, x);
357 swizzle!(z, w, w, y);
358 swizzle!(z, w, w, z);
359 swizzle!(z, w, w, w);
360 swizzle!(w, x, x, x);
361 swizzle!(w, x, x, y);
362 swizzle!(w, x, x, z);
363 swizzle!(w, x, x, w);
364 swizzle!(w, x, y, x);
365 swizzle!(w, x, y, y);
366 swizzle!(w, x, y, z);
367 swizzle!(w, x, y, w);
368 swizzle!(w, x, z, x);
369 swizzle!(w, x, z, y);
370 swizzle!(w, x, z, z);
371 swizzle!(w, x, z, w);
372 swizzle!(w, x, w, x);
373 swizzle!(w, x, w, y);
374 swizzle!(w, x, w, z);
375 swizzle!(w, x, w, w);
376 swizzle!(w, y, x, x);
377 swizzle!(w, y, x, y);
378 swizzle!(w, y, x, z);
379 swizzle!(w, y, x, w);
380 swizzle!(w, y, y, x);
381 swizzle!(w, y, y, y);
382 swizzle!(w, y, y, z);
383 swizzle!(w, y, y, w);
384 swizzle!(w, y, z, x);
385 swizzle!(w, y, z, y);
386 swizzle!(w, y, z, z);
387 swizzle!(w, y, z, w);
388 swizzle!(w, y, w, x);
389 swizzle!(w, y, w, y);
390 swizzle!(w, y, w, z);
391 swizzle!(w, y, w, w);
392 swizzle!(w, z, x, x);
393 swizzle!(w, z, x, y);
394 swizzle!(w, z, x, z);
395 swizzle!(w, z, x, w);
396 swizzle!(w, z, y, x);
397 swizzle!(w, z, y, y);
398 swizzle!(w, z, y, z);
399 swizzle!(w, z, y, w);
400 swizzle!(w, z, z, x);
401 swizzle!(w, z, z, y);
402 swizzle!(w, z, z, z);
403 swizzle!(w, z, z, w);
404 swizzle!(w, z, w, x);
405 swizzle!(w, z, w, y);
406 swizzle!(w, z, w, z);
407 swizzle!(w, z, w, w);
408 swizzle!(w, w, x, x);
409 swizzle!(w, w, x, y);
410 swizzle!(w, w, x, z);
411 swizzle!(w, w, x, w);
412 swizzle!(w, w, y, x);
413 swizzle!(w, w, y, y);
414 swizzle!(w, w, y, z);
415 swizzle!(w, w, y, w);
416 swizzle!(w, w, z, x);
417 swizzle!(w, w, z, y);
418 swizzle!(w, w, z, z);
419 swizzle!(w, w, z, w);
420 swizzle!(w, w, w, x);
421 swizzle!(w, w, w, y);
422 swizzle!(w, w, w, z);
423 swizzle!(w, w, w, w);
424}
425
426impl_op_ex!(+= |a: &mut Vec4, b: &Vec4| { a.x += b.x; a.y += b.y; a.z += b.z; a.w += b.w; });
427impl_op_ex!(-= |a: &mut Vec4, b: &Vec4| { a.x -= b.x; a.y -= b.y; a.z -= b.z; a.w -= b.w; });
428impl_op_ex!(*= |a: &mut Vec4, b: &Vec4| { a.x *= b.x; a.y *= b.y; a.z *= b.z; a.w *= b.w; });
429impl_op_ex!(/= |a: &mut Vec4, b: &Vec4| { a.x /= b.x; a.y /= b.y; a.z /= b.z; a.w /= b.w; });
430
431impl_op_ex!(*= |a: &mut Vec4, b: &f32| { a.x *= b; a.y *= b; a.z *= b; a.w *= b; });
432impl_op_ex!(/= |a: &mut Vec4, b: &f32| { a.x /= b; a.y /= b; a.z /= b; a.w /= b; });
433
434impl_op_ex!(+ |a: &Vec4, b: &Vec4| -> Vec4 { Vec4{x: a.x + b.x, y: a.y + b.y, z: a.z + b.z, w: a.w + b.w } });
435impl_op_ex!(-|a: &Vec4, b: &Vec4| -> Vec4 {
436 Vec4 {
437 x: a.x - b.x,
438 y: a.y - b.y,
439 z: a.z - b.z,
440 w: a.w - b.w,
441 }
442});
443impl_op_ex!(*|a: &Vec4, b: &Vec4| -> Vec4 {
444 Vec4 {
445 x: a.x * b.x,
446 y: a.y * b.y,
447 z: a.z * b.z,
448 w: a.w * b.w,
449 }
450});
451impl_op_ex!(/ |a: &Vec4, b: &Vec4| -> Vec4 { Vec4{x: a.x / b.x, y: a.y / b.y, z: a.z / b.z, w: a.w / b.w } });
452
453impl_op_ex_commutative!(*|a: &Vec4, b: &f32| -> Vec4 {
454 Vec4 {
455 x: a.x * b,
456 y: a.y * b,
457 z: a.z * b,
458 w: a.w * b,
459 }
460});
461impl_op_ex!(/ |a: &Vec4, b: &f32| -> Vec4 { Vec4{x: a.x / b, y: a.y / b, z: a.z / b, w: a.w / b } });
462impl_op_ex!(/ |a: &f32, b: &Vec4| -> Vec4 { Vec4{x: a / b.x, y: a / b.y, z: a / b.z, w: a / b.w } });
463
464impl Neg for Vec4 {
465 type Output = Vec4;
466 fn neg(self) -> Self::Output {
467 Vec4 {
468 x: -self.x,
469 y: -self.y,
470 z: -self.z,
471 w: -self.w,
472 }
473 }
474}
475
476impl From<[f32; 4]> for Vec4 {
477 fn from(d: [f32; 4]) -> Self {
478 Self {
479 x: d[0],
480 y: d[1],
481 z: d[2],
482 w: d[3],
483 }
484 }
485}
486
487#[cfg(test)]
488mod tests {
489 use super::*;
490
491 #[test]
492 fn operators() {
493 let a = Vec4::new(1.0, 2.0, 3.0, 4.0);
494 let b = Vec4::new(3.0, 4.0, 5.0, 6.0);
495
496 assert_eq!(
497 -a,
498 Vec4 {
499 x: -1.0,
500 y: -2.0,
501 z: -3.0,
502 w: -4.0
503 }
504 );
505
506 assert_eq!(a.sqr_magnitude(), 30.0);
507 assert_eq!(a.magnitude(), 30.0f32.sqrt());
508
509 assert_eq!(a.dot(b), 50.0);
510
511 assert_eq!(
512 a + b,
513 Vec4 {
514 x: 4.0,
515 y: 6.0,
516 z: 8.0,
517 w: 10.0
518 }
519 );
520 assert_eq!(
521 a - b,
522 Vec4 {
523 x: -2.0,
524 y: -2.0,
525 z: -2.0,
526 w: -2.0
527 }
528 );
529 assert_eq!(
530 a * b,
531 Vec4 {
532 x: 3.0,
533 y: 8.0,
534 z: 15.0,
535 w: 24.0
536 }
537 );
538 assert_eq!(
539 a / b,
540 Vec4 {
541 x: 1.0 / 3.0,
542 y: 0.5,
543 z: 3.0 / 5.0,
544 w: 4.0 / 6.0
545 }
546 );
547
548 assert_eq!(
549 a * 2.0,
550 Vec4 {
551 x: 2.0,
552 y: 4.0,
553 z: 6.0,
554 w: 8.0
555 }
556 );
557 assert_eq!(
558 2.0 * a,
559 Vec4 {
560 x: 2.0,
561 y: 4.0,
562 z: 6.0,
563 w: 8.0
564 }
565 );
566
567 assert_eq!(
568 a / 2.0,
569 Vec4 {
570 x: 0.5,
571 y: 1.0,
572 z: 1.5,
573 w: 2.0
574 }
575 );
576 assert_eq!(
577 2.0 / a,
578 Vec4 {
579 x: 2.0,
580 y: 1.0,
581 z: 2.0 / 3.0,
582 w: 0.5
583 }
584 );
585
586 let mut c = a;
587
588 assert_eq!(c.normalized(), a / a.magnitude());
589
590 c.normalize();
591 assert_eq!(c, a / a.magnitude());
592
593 c = a;
594 c += b;
595 assert_eq!(c, a + b);
596
597 c = a;
598 c -= b;
599 assert_eq!(c, a - b);
600
601 c = a;
602 c *= b;
603 assert_eq!(c, a * b);
604
605 c = a;
606 c /= b;
607 assert_eq!(c, a / b);
608
609 c = a;
610 c *= 2.0;
611 assert_eq!(c, a * 2.0);
612
613 c = a;
614 c /= 2.0;
615 assert_eq!(c, a / 2.0);
616 }
617}