gfx_maths/
vec4.rs

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    /// Creates a zero vector
17    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    /// Creates (0, 0, 0, 0)
35    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    /// Creates (1, 1, 1, 1)
45    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    /// Returns the square of the vector's length.
55    ///
56    /// Faster to compute than [`magnitude()`](Self::magnitude())
57    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    /// Returns the vector's length
62    pub fn magnitude(&self) -> f32 {
63        self.sqr_magnitude().sqrt()
64    }
65
66    /// Normalizes `self` in place
67    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    /// Returns a normalized copy of `self`
76    #[must_use]
77    pub fn normalized(&self) -> Self {
78        *self.clone().normalize()
79    }
80
81    /// Returns the dot product of `self` and `b`
82    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}