zaplib_shader_compiler/
math.rs

1use crate::util::PrettyPrintedFloat;
2use std::f32::consts::PI;
3use std::f32::EPSILON;
4use std::fmt;
5use std::ops;
6
7/// 4x4 matrix; very common in graphics programming.
8#[derive(Clone, Copy, Default, PartialEq, Debug)]
9#[repr(C)]
10pub struct Mat4 {
11    pub v: [f32; 16],
12}
13
14/// A common type of transformation, that includes a rotation ([`Transform::orientation`])
15/// and translation ([`Transform::position`]).
16///
17/// TODO(JP): Maybe rename orientation/position to rotation/translation?
18#[derive(Clone, Copy, Default, PartialEq, Debug)]
19pub struct Transform {
20    pub orientation: Quat,
21    pub position: Vec3,
22}
23
24impl Transform {
25    pub fn to_mat4(&self) -> Mat4 {
26        let q = self.orientation;
27        let t = self.position;
28        Mat4 {
29            v: [
30                (1.0 - 2.0 * q.b * q.b - 2.0 * q.c * q.c),
31                (2.0 * q.a * q.b - 2.0 * q.c * q.d),
32                (2.0 * q.a * q.c + 2.0 * q.b * q.d),
33                0.0,
34                (2.0 * q.a * q.b + 2.0 * q.c * q.d),
35                (1.0 - 2.0 * q.a * q.a - 2.0 * q.c * q.c),
36                (2.0 * q.b * q.c - 2.0 * q.a * q.d),
37                0.0,
38                (2.0 * q.a * q.c - 2.0 * q.b * q.d),
39                (2.0 * q.b * q.c + 2.0 * q.a * q.d),
40                (1.0 - 2.0 * q.a * q.a - 2.0 * q.b * q.b),
41                0.0,
42                t.x,
43                t.y,
44                t.z,
45                1.0,
46            ],
47        }
48    }
49
50    pub fn from_lerp(a: Transform, b: Transform, f: f32) -> Self {
51        Transform {
52            orientation: Quat::from_slerp(a.orientation, b.orientation, f),
53            position: Vec3::from_lerp(a.position, b.position, f),
54        }
55    }
56
57    pub fn from_slerp_orientation(a: Transform, b: Transform, f: f32) -> Self {
58        Transform { orientation: Quat::from_slerp(a.orientation, b.orientation, f), position: b.position }
59    }
60}
61
62/// Convenience function for making a [`Vec2`].
63pub const fn vec2(x: f32, y: f32) -> Vec2 {
64    Vec2 { x, y }
65}
66/// Convenience function for making a [`Vec3`].
67pub const fn vec3(x: f32, y: f32, z: f32) -> Vec3 {
68    Vec3 { x, y, z }
69}
70/// Convenience function for making a [`Vec4`].
71pub const fn vec4(x: f32, y: f32, z: f32, w: f32) -> Vec4 {
72    Vec4 { x, y, z, w }
73}
74
75/// Vector (as in linear algebra, not as in [`Vec`]!) with two elements.
76#[derive(Clone, Copy, Default, Debug, PartialEq)]
77#[repr(C)]
78pub struct Vec2 {
79    pub x: f32,
80    pub y: f32,
81}
82
83impl Vec2 {
84    pub const fn all(x: f32) -> Vec2 {
85        Vec2 { x, y: x }
86    }
87
88    pub fn distance(&self, other: &Vec2) -> f32 {
89        let dx = self.x - other.x;
90        let dy = self.y - other.y;
91        (dx * dx + dy * dy).sqrt()
92    }
93
94    pub fn min(&self, other: &Vec2) -> Vec2 {
95        vec2(self.x.min(other.x), self.y.min(other.y))
96    }
97
98    pub fn max(&self, other: &Vec2) -> Vec2 {
99        vec2(self.x.max(other.x), self.y.max(other.y))
100    }
101
102    pub fn clamp(&self, min: &Vec2, max: &Vec2) -> Vec2 {
103        vec2(self.x.clamp(min.x, max.x), self.y.clamp(min.y, max.y))
104    }
105
106    pub fn to_vec3(&self) -> Vec3 {
107        Vec3 { x: self.x, y: self.y, z: 0.0 }
108    }
109
110    pub fn as_array(&self) -> &[f32; 2] {
111        unsafe { &*(self as *const _ as *const [f32; 2]) }
112    }
113
114    pub fn as_mut_array(&mut self) -> &mut [f32; 2] {
115        unsafe { &mut *(self as *mut _ as *mut [f32; 2]) }
116    }
117}
118
119impl fmt::Display for Vec2 {
120    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
121        write!(f, "vec2({}, {})", PrettyPrintedFloat(self.x), PrettyPrintedFloat(self.y),)
122    }
123}
124
125const TORAD: f32 = 0.017_453_292;
126const TODEG: f32 = 57.295_78;
127
128/// Vector (as in linear algebra, not as in [`Vec`]!) with three elements.
129#[derive(Clone, Copy, Default, PartialEq, Debug)]
130#[repr(C)]
131pub struct Vec3 {
132    pub x: f32,
133    pub y: f32,
134    pub z: f32,
135}
136
137impl Vec3 {
138    pub fn from_lerp(a: Vec3, b: Vec3, f: f32) -> Vec3 {
139        Vec3 { x: (b.x - a.x) * f + a.x, y: (b.y - a.y) * f + a.y, z: (b.z - a.z) * f + a.z }
140    }
141
142    pub const fn all(x: f32) -> Vec3 {
143        Vec3 { x, y: x, z: x }
144    }
145
146    pub fn to_vec2(&self) -> Vec2 {
147        Vec2 { x: self.x, y: self.y }
148    }
149
150    pub fn scale(&self, f: f32) -> Vec3 {
151        Vec3 { x: self.x * f, y: self.y * f, z: self.z * f }
152    }
153
154    pub fn cross(a: Vec3, b: Vec3) -> Vec3 {
155        Vec3 { x: a.y * b.z - a.z * b.y, y: a.z * b.x - a.x * b.z, z: a.x * b.y - a.y * b.x }
156    }
157
158    pub fn dot(&self, other: Vec3) -> f32 {
159        self.x * other.x + self.y * other.y + self.z * other.z
160    }
161
162    pub fn normalize(&self) -> Vec3 {
163        let sz = self.x * self.x + self.y * self.y + self.z * self.z;
164        if sz > 0.0 {
165            let sr = 1.0 / sz.sqrt();
166            return Vec3 { x: self.x * sr, y: self.y * sr, z: self.z * sr };
167        }
168        Vec3::default()
169    }
170
171    pub fn distance(&self, other: &Vec3) -> f32 {
172        (*other - *self).length()
173    }
174
175    pub fn length(self) -> f32 {
176        self.dot(self).sqrt()
177    }
178
179    pub fn clamp(&self, min: &Vec3, max: &Vec3) -> Vec3 {
180        vec3(self.x.clamp(min.x, max.x), self.y.clamp(min.y, max.y), self.z.clamp(min.z, max.z))
181    }
182
183    pub fn as_array(&self) -> &[f32; 3] {
184        unsafe { &*(self as *const _ as *const [f32; 3]) }
185    }
186
187    pub fn as_mut_array(&mut self) -> &mut [f32; 3] {
188        unsafe { &mut *(self as *mut _ as *mut [f32; 3]) }
189    }
190}
191
192impl fmt::Display for Vec3 {
193    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
194        write!(f, "vec3({}, {}, {})", PrettyPrintedFloat(self.x), PrettyPrintedFloat(self.y), PrettyPrintedFloat(self.z),)
195    }
196}
197
198/// Vector (as in linear algebra, not as in [`Vec`]!) with four elements.
199#[derive(Clone, Copy, Default, Debug, PartialEq)]
200#[repr(C)]
201pub struct Vec4 {
202    pub x: f32,
203    pub y: f32,
204    pub z: f32,
205    pub w: f32,
206}
207
208impl fmt::Display for Vec4 {
209    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
210        write!(
211            f,
212            "vec4({}, {}, {}, {})",
213            PrettyPrintedFloat(self.x),
214            PrettyPrintedFloat(self.y),
215            PrettyPrintedFloat(self.z),
216            PrettyPrintedFloat(self.w),
217        )
218    }
219}
220
221impl Vec4 {
222    pub const fn all(v: f32) -> Self {
223        Self { x: v, y: v, z: v, w: v }
224    }
225
226    pub fn to_vec3(&self) -> Vec3 {
227        Vec3 { x: self.x, y: self.y, z: self.z }
228    }
229
230    pub fn dot(&self, other: Vec4) -> f32 {
231        self.x * other.x + self.y * other.y + self.z * other.z + self.w * other.w
232    }
233
234    pub fn mix(a: Vec4, b: Vec4, f: f32) -> Vec4 {
235        let nf = 1.0 - f;
236        Vec4 { x: nf * a.x + f * b.x, y: nf * a.y + f * b.y, z: nf * a.z + f * b.z, w: nf * a.w + f * b.w }
237    }
238
239    pub fn is_equal_enough(&self, other: &Vec4) -> bool {
240        (self.x - other.x).abs() < 0.0001
241            && (self.y - other.y).abs() < 0.0001
242            && (self.z - other.z).abs() < 0.0001
243            && (self.w - other.w).abs() < 0.0001
244    }
245
246    pub fn from_hsva(hsv: Vec4) -> Vec4 {
247        fn mix(x: f32, y: f32, t: f32) -> f32 {
248            x + (y - x) * t
249        }
250        fn clamp(x: f32, mi: f32, ma: f32) -> f32 {
251            if x < mi {
252                mi
253            } else if x > ma {
254                ma
255            } else {
256                x
257            }
258        }
259        fn fract(x: f32) -> f32 {
260            x.fract()
261        }
262        fn abs(x: f32) -> f32 {
263            x.abs()
264        }
265        Vec4 {
266            x: hsv.z * mix(1.0, clamp(abs(fract(hsv.x + 1.0) * 6.0 - 3.0) - 1.0, 0.0, 1.0), hsv.y),
267            y: hsv.z * mix(1.0, clamp(abs(fract(hsv.x + 2.0 / 3.0) * 6.0 - 3.0) - 1.0, 0.0, 1.0), hsv.y),
268            z: hsv.z * mix(1.0, clamp(abs(fract(hsv.x + 1.0 / 3.0) * 6.0 - 3.0) - 1.0, 0.0, 1.0), hsv.y),
269            w: 1.0,
270        }
271    }
272
273    pub fn to_hsva(&self) -> Vec4 {
274        let pc = self.y < self.z; //step(c[2],c[1])
275        let p0 = if pc { self.z } else { self.y }; //mix(c[2],c[1],pc)
276        let p1 = if pc { self.y } else { self.z }; //mix(c[1],c[2],pc)
277        let p2 = if pc { -1.0 } else { 0.0 }; //mix(-1,0,pc)
278        let p3 = if pc { 2.0 / 3.0 } else { -1.0 / 3.0 }; //mix(2/3,-1/3,pc)
279
280        let qc = self.x < p0; //step(p0, c[0])
281        let q0 = if qc { p0 } else { self.x }; //mix(p0, c[0], qc)
282        let q1 = p1;
283        let q2 = if qc { p3 } else { p2 }; //mix(p3, p2, qc)
284        let q3 = if qc { self.x } else { p0 }; //mix(c[0], p0, qc)
285
286        let d = q0 - q3.min(q1);
287        let e = 1.0e-10;
288        Vec4 { x: (q2 + (q3 - q1) / (6.0 * d + e)).abs(), y: d / (q0 + e), z: q0, w: self.w }
289    }
290
291    pub fn from_u32(val: u32) -> Vec4 {
292        Vec4 {
293            x: ((val >> 24) & 0xff) as f32 / 255.0,
294            y: ((val >> 16) & 0xff) as f32 / 255.0,
295            z: ((val >> 8) & 0xff) as f32 / 255.0,
296            w: ((val >> 0) & 0xff) as f32 / 255.0,
297        }
298    }
299
300    pub fn to_hex_string(&self) -> String {
301        fn int_to_hex(d: u8) -> char {
302            if d >= 10 {
303                return (d + 55) as char;
304            }
305            (d + 48) as char
306        }
307
308        let r = (self.x * 255.0) as u8;
309        let g = (self.y * 255.0) as u8;
310        let b = (self.z * 255.0) as u8;
311        let mut out = String::new();
312        out.push(int_to_hex((r >> 4) & 0xf));
313        out.push(int_to_hex((r) & 0xf));
314        out.push(int_to_hex((g >> 4) & 0xf));
315        out.push(int_to_hex((g) & 0xf));
316        out.push(int_to_hex((b >> 4) & 0xf));
317        out.push(int_to_hex((b) & 0xf));
318        out
319    }
320
321    pub fn color(value: &str) -> Vec4 {
322        if let Ok(val) = Self::from_hex_str(value) {
323            val
324        } else {
325            Vec4 { x: 1.0, y: 0.0, z: 1.0, w: 1.0 }
326        }
327    }
328
329    fn from_hex_str(hex: &str) -> Result<Vec4, ()> {
330        let bytes = hex.as_bytes();
331        if bytes[0] == b'#' {
332            Self::from_hex_bytes(&bytes[1..])
333        } else {
334            Self::from_hex_bytes(bytes)
335        }
336    }
337
338    pub fn from_hex_bytes(bytes: &[u8]) -> Result<Vec4, ()> {
339        fn hex_to_int(c: u32) -> Result<u32, ()> {
340            if (48..=57).contains(&c) {
341                return Ok(c - 48);
342            }
343            if (65..=70).contains(&c) {
344                return Ok(c - 65 + 10);
345            }
346            if (97..=102).contains(&c) {
347                return Ok(c - 97 + 10);
348            }
349            Err(())
350        }
351
352        match bytes.len() {
353            1 => {
354                // #w
355                let val = hex_to_int(bytes[0] as u32)? as f32 / 15.0;
356                return Ok(vec4(val, val, val, 1.0));
357            }
358            2 => {
359                //#ww
360                let w = ((hex_to_int(bytes[0] as u32)? << 4) + hex_to_int(bytes[1] as u32)?) as f32 / 255.0;
361                return Ok(vec4(w, w, w, 1.0));
362            }
363            3 => {
364                // #rgb
365                let r = hex_to_int(bytes[0] as u32)? as f32 / 15.0;
366                let g = hex_to_int(bytes[1] as u32)? as f32 / 15.0;
367                let b = hex_to_int(bytes[2] as u32)? as f32 / 15.0;
368                return Ok(vec4(r, g, b, 1.0));
369            }
370            4 => {
371                // #rgba
372                let r = hex_to_int(bytes[0] as u32)? as f32 / 15.0;
373                let g = hex_to_int(bytes[1] as u32)? as f32 / 15.0;
374                let b = hex_to_int(bytes[2] as u32)? as f32 / 15.0;
375                let a = hex_to_int(bytes[3] as u32)? as f32 / 15.0;
376                return Ok(vec4(r, g, b, a));
377            }
378            6 => {
379                // #rrggbb
380                let r = ((hex_to_int(bytes[0] as u32)? << 4) + hex_to_int(bytes[1] as u32)?) as f32 / 255.0;
381                let g = ((hex_to_int(bytes[2] as u32)? << 4) + hex_to_int(bytes[3] as u32)?) as f32 / 255.0;
382                let b = ((hex_to_int(bytes[4] as u32)? << 4) + hex_to_int(bytes[5] as u32)?) as f32 / 255.0;
383                return Ok(vec4(r, g, b, 1.0));
384            }
385            8 => {
386                // #rrggbbaa
387                let r = ((hex_to_int(bytes[0] as u32)? << 4) + hex_to_int(bytes[1] as u32)?) as f32 / 255.0;
388                let g = ((hex_to_int(bytes[2] as u32)? << 4) + hex_to_int(bytes[3] as u32)?) as f32 / 255.0;
389                let b = ((hex_to_int(bytes[4] as u32)? << 4) + hex_to_int(bytes[5] as u32)?) as f32 / 255.0;
390                let a = ((hex_to_int(bytes[6] as u32)? << 4) + hex_to_int(bytes[7] as u32)?) as f32 / 255.0;
391                return Ok(vec4(r, g, b, a));
392            }
393            _ => (),
394        }
395        Err(())
396    }
397
398    pub fn clamp(&self, min: &Vec4, max: &Vec4) -> Vec4 {
399        vec4(self.x.clamp(min.x, max.x), self.y.clamp(min.y, max.y), self.z.clamp(min.z, max.z), self.w.clamp(min.w, max.w))
400    }
401
402    pub fn as_array(&self) -> &[f32; 4] {
403        unsafe { &*(self as *const _ as *const [f32; 4]) }
404    }
405
406    pub fn as_mut_array(&mut self) -> &mut [f32; 4] {
407        unsafe { &mut *(self as *mut _ as *mut [f32; 4]) }
408    }
409}
410
411/// Represents an (axis-aligned) rectangle. Axis-aligned means that you can't
412/// rotate it.
413#[derive(Clone, Copy, Default, Debug, PartialEq)]
414pub struct Rect {
415    pub pos: Vec2,
416    pub size: Vec2,
417}
418
419impl Rect {
420    pub fn translate(self, pos: Vec2) -> Rect {
421        Rect { pos: self.pos + pos, size: self.size }
422    }
423
424    pub fn contains(&self, pos: Vec2) -> bool {
425        pos.x >= self.pos.x && pos.x <= self.pos.x + self.size.x && pos.y >= self.pos.y && pos.y <= self.pos.y + self.size.y
426    }
427
428    pub fn intersects(&self, r: Rect) -> bool {
429        !(r.pos.x > self.pos.x + self.size.x
430            || r.pos.x + r.size.x < self.pos.x
431            || r.pos.y > self.pos.y + self.size.y
432            || r.pos.y + r.size.y < self.pos.y)
433    }
434
435    /// This returns the [`Rect`] for if you'd add padding all around the given [`Rect`].
436    ///
437    /// This means that the `pos` will move according to the left/top padding, and the size will be adjusted
438    /// based on the sum of the vertical/horizontal paddings.
439    ///
440    /// If you just want to adjust the size while keeping `pos` the same, you can simply add the desired
441    /// dimensions to `size`.
442    pub fn add_padding(self, padding: Padding) -> Self {
443        Self {
444            pos: Vec2 { x: self.pos.x - padding.l, y: self.pos.y - padding.t },
445            size: Vec2 { x: self.size.x + padding.l + padding.r, y: self.size.y + padding.t + padding.b },
446        }
447    }
448}
449
450/// Inner padding dimensions that should be applied on top of a [`Rect`] or other
451/// object that defines dimensions.
452///
453/// TODO(JP): these values can be negative, which can be quite confusing, but we
454/// seem to actually honor that in the layout boxes code. Might be good to look into that
455/// and see if we should forbid that or not (we seem to never actually do that yet).
456#[derive(Clone, Copy, Debug)]
457pub struct Padding {
458    pub l: f32,
459    pub t: f32,
460    pub r: f32,
461    pub b: f32,
462}
463impl Padding {
464    pub const ZERO: Padding = Padding { l: 0.0, t: 0.0, r: 0.0, b: 0.0 };
465
466    /// TODO(JP): Replace these with Padding::default() when
467    /// <https://github.com/rust-lang/rust/issues/67792> gets done
468    pub const DEFAULT: Padding = Padding::ZERO;
469
470    pub const fn all(v: f32) -> Padding {
471        Padding { l: v, t: v, r: v, b: v }
472    }
473
474    pub const fn left(v: f32) -> Padding {
475        Padding { l: v, ..Padding::ZERO }
476    }
477
478    pub const fn top(v: f32) -> Padding {
479        Padding { t: v, ..Padding::ZERO }
480    }
481
482    pub const fn right(v: f32) -> Padding {
483        Padding { r: v, ..Padding::ZERO }
484    }
485
486    pub const fn bottom(v: f32) -> Padding {
487        Padding { b: v, ..Padding::ZERO }
488    }
489
490    /// Helper function to set vertical and horizontal padding
491    /// This is a common case when top=bottom left=right
492    pub const fn vh(v: f32, h: f32) -> Padding {
493        Padding { l: h, r: h, t: v, b: v }
494    }
495}
496impl Default for Padding {
497    fn default() -> Self {
498        Padding::DEFAULT
499    }
500}
501
502/// [Quaternion](https://en.wikipedia.org/wiki/Quaternion); used for rotations.
503///
504/// Let's give it up for [Hamilton](https://www.youtube.com/watch?v=SZXHoWwBcDc).
505#[derive(Clone, Copy, Default, Debug, PartialEq)]
506pub struct Quat {
507    pub a: f32,
508    pub b: f32,
509    pub c: f32,
510    pub d: f32,
511}
512
513impl Quat {
514    pub fn dot(&self, other: Quat) -> f32 {
515        self.a * other.a + self.b * other.b + self.c * other.c + self.d * other.d
516    }
517
518    pub fn neg(&self) -> Quat {
519        Quat { a: -self.a, b: -self.b, c: -self.c, d: -self.d }
520    }
521
522    pub fn get_angle_with(&self, other: Quat) -> f32 {
523        let dot = self.dot(other);
524        (2.0 * dot * dot - 1.0).acos() * TODEG
525    }
526
527    pub fn from_slerp(n: Quat, mut m: Quat, t: f32) -> Quat {
528        // calc cosine
529        let mut cosom = n.dot(m);
530        // adjust signs (if necessary)
531        if cosom < 0.0 {
532            cosom = -cosom;
533            m = m.neg();
534        }
535        // calculate coefficients
536        let (scale0, scale1) = if 1.0 - cosom > 0.000001 {
537            // standard case (slerp)
538            let omega = cosom.acos();
539            let sinom = omega.sin();
540            (((1.0 - t) * omega).sin() / sinom, (t * omega).sin() / sinom)
541        } else {
542            (1.0 - t, t)
543        };
544        // calculate final values
545        (Quat {
546            a: scale0 * n.a + scale1 * m.a,
547            b: scale0 * n.b + scale1 * m.b,
548            c: scale0 * n.c + scale1 * m.c,
549            d: scale0 * m.d + scale1 * m.d,
550        })
551        .normalized()
552    }
553
554    /// Creates a [`Quat`] from a given rotation axis and angle (in radians)
555    pub fn from_axis_angle(axis: Vec3, angle: f32) -> Quat {
556        let theta = 0.5 * angle;
557        let sin_theta = theta.sin();
558        Quat { a: sin_theta * axis.x, b: sin_theta * axis.y, c: sin_theta * axis.z, d: theta.cos() }
559    }
560
561    /// Creates a [`Quat`] representing the shortest rotation from one
562    /// [`Vec3`] to another.
563    pub fn rotation_to(a: Vec3, b: Vec3) -> Quat {
564        let dot = a.dot(b);
565        if dot < -(1.0 - EPSILON) {
566            // Input vectors are pointing in opposite directions
567            // Rotate using an arbitrary vector
568            const UNIT_X: Vec3 = vec3(1.0, 0.0, 0.0);
569            const UNIT_Y: Vec3 = vec3(0.0, 1.0, 0.0);
570            let mut axis = Vec3::cross(UNIT_X, a);
571            if axis.length() < EPSILON {
572                axis = Vec3::cross(UNIT_Y, a);
573            }
574            axis.normalize();
575            Quat::from_axis_angle(axis, PI)
576        } else if dot > (1.0 - EPSILON) {
577            // Input vectors have the same orientation
578            Quat { a: 0., b: 0., c: 0., d: 1. }
579        } else {
580            let axis = Vec3::cross(a, b);
581            Quat { a: axis.x, b: axis.y, c: axis.z, d: (1. + dot) }.normalized()
582        }
583    }
584
585    pub fn length(self) -> f32 {
586        self.dot(self).sqrt()
587    }
588
589    pub fn normalized(&mut self) -> Quat {
590        let len = self.length();
591        Quat { a: self.a / len, b: self.b / len, c: self.c / len, d: self.d / len }
592    }
593
594    /// Transforms a [`Vec3`] by rotating it
595    pub fn rotate_vec(&self, a: Vec3) -> Vec3 {
596        let qv = vec3(self.a, self.b, self.c);
597        let mut u = Vec3::cross(qv, a);
598        let mut v = Vec3::cross(qv, u);
599        u *= 2.0 * self.d;
600        v *= 2.0;
601        a + u + v
602    }
603
604    /// Rotates a [`Quat`] by the given angle (in radians) in the Y-axis
605    pub fn rotate_y(&self, angle: f32) -> Quat {
606        let theta = 0.5 * angle;
607        let cos_theta = theta.cos();
608        let sin_theta = theta.sin();
609
610        Quat {
611            a: self.a * cos_theta - self.c * sin_theta,
612            b: self.b * cos_theta + self.d * sin_theta,
613            c: self.c * cos_theta + self.a * sin_theta,
614            d: self.d * cos_theta - self.b * sin_theta,
615        }
616    }
617}
618
619impl Mat4 {
620    pub fn identity() -> Mat4 {
621        Mat4 { v: [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0] }
622    }
623
624    pub fn txyz_s_ry_rx_txyz(t1: Vec3, s: f32, ry: f32, rx: f32, t2: Vec3) -> Mat4 {
625        let cx = f32::cos(rx * TORAD);
626        let cy = f32::cos(ry * TORAD);
627        //let cz = f32::cos(r.z * TORAD);
628        let sx = f32::sin(rx * TORAD);
629        let sy = f32::sin(ry * TORAD);
630        //let sz = f32::sin(r.z * TORAD);
631        // y first, then x, then z
632
633        // Y
634        // |  cy,  0,  sy  |
635        // |  0,   1,  0  |
636        // | -sy,  0,  cy  |
637
638        // X:
639        // |  1,  0,  0  |
640        // |  0,  cx, -sx  |
641        // |  0,  sx,  cx  |
642
643        // Z:
644        // |  cz, -sz,  0  |
645        // |  sz,  cz,  0  |
646        // |  0,    0,  1  |
647
648        // X * Y
649        // | cy,           0,    sy |
650        // | -sx*-sy,     cx,   -sx*cy  |
651        // | -sy * cx,    sx,  cx*cy  |
652
653        // Z * X * Y
654        // | cz * cy + -sz * -sx *-sy,   -sz * cx,    sy *cz + -sz * -sx * cy |
655        // | sz * cy + -sx*-sy * cz,     sz * cx,   sy * sz + cz * -sz * cy  |
656        // | -sy * cx,    sx,  cx*cy  |
657
658        // Y * X * Z
659        // | c*c,  c, s*s   |
660        // |   0,  c,  -s   |
661        // |  -s,  c*s, c*c |
662
663        /*
664        let m0 = s * (cz * cy + (-sz) * (-sx) *(-sy));
665        let m1 = s * (-sz * cx);
666        let m2 = s * (sy *cz + (-sz) * (-sx) * cy);
667
668        let m4 = s * (sz * cy + (-sx)*(-sy) * cz);
669        let m5 = s * (sz * cx);
670        let m6 = s * (sy * sz + cz * (-sx) * cy);
671
672        let m8 = s * (-sy*cx);
673        let m9 = s * (sx);
674        let m10 = s * (cx * cy);
675        */
676
677        let m0 = s * (cy);
678        let m1 = s * (0.0);
679        let m2 = s * (sy);
680
681        let m4 = s * (-sx * -sy);
682        let m5 = s * (cx);
683        let m6 = s * (-sx * cy);
684
685        let m8 = s * (-sy * cx);
686        let m9 = s * (sx);
687        let m10 = s * (cx * cy);
688
689        /*
690        let m0 = s * (cy * cz + sx * sy * sz);
691        let m1 = s * (-sz * cy + cz * sx * sy);
692        let m2 = s * (sy * cx);
693
694        let m4 = s * (sz * cx);
695        let m5 = s * (cx * cz);
696        let m6 = s * (-sx);
697
698        let m8 = s * (-sy * cz + cy * sx * sz);
699        let m9 = s * (sy * sz + cy * sx * cz);
700        let m10 = s * (cx * cy);
701        */
702        Mat4 {
703            v: [
704                m0,
705                m4,
706                m8,
707                0.0,
708                m1,
709                m5,
710                m9,
711                0.0,
712                m2,
713                m6,
714                m10,
715                0.0,
716                t2.x + (m0 * t1.x + m1 * t1.y + m2 * t1.z),
717                t2.y + (m4 * t1.x + m5 * t1.y + m6 * t1.z),
718                t2.z + (m8 * t1.x + m9 * t1.y + m10 * t1.z),
719                1.0,
720            ],
721        }
722    }
723
724    pub fn perspective(fov_y: f32, aspect: f32, near: f32, far: f32) -> Mat4 {
725        let f = 1.0 / f32::tan(fov_y * TORAD / 2.0);
726        let nf = 1.0 / (near - far);
727        Mat4 {
728            v: [
729                f / aspect,
730                0.0,
731                0.0,
732                0.0,
733                0.0,
734                f,
735                0.0,
736                0.0,
737                0.0,
738                0.0,
739                (far + near) * nf,
740                -1.0,
741                0.0,
742                0.0,
743                (2.0 * far * near) * nf,
744                0.0,
745            ],
746        }
747    }
748
749    pub fn translation(x: f32, y: f32, z: f32) -> Mat4 {
750        Mat4 { v: [1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, x, y, z, 1.0] }
751    }
752
753    pub fn scaled_translation(s: f32, x: f32, y: f32, z: f32) -> Mat4 {
754        Mat4 { v: [s, 0.0, 0.0, 0.0, 0.0, s, 0.0, 0.0, 0.0, 0.0, s, 0.0, x, y, z, 1.0] }
755    }
756
757    pub fn rotation(rx: f32, ry: f32, rz: f32) -> Mat4 {
758        const TORAD: f32 = 0.017_453_292;
759        let cx = f32::cos(rx * TORAD);
760        let cy = f32::cos(ry * TORAD);
761        let cz = f32::cos(rz * TORAD);
762        let sx = f32::sin(rx * TORAD);
763        let sy = f32::sin(ry * TORAD);
764        let sz = f32::sin(rz * TORAD);
765        let m0 = cy * cz + sx * sy * sz;
766        let m1 = -sz * cy + cz * sx * sy;
767        let m2 = sy * cx;
768        let m4 = sz * cx;
769        let m5 = cx * cz;
770        let m6 = -sx;
771        let m8 = -sy * cz + cy * sx * sz;
772        let m9 = sy * sz + cy * sx * cz;
773        let m10 = cx * cy;
774        Mat4 { v: [m0, m4, m8, 0.0, m1, m5, m9, 0.0, m2, m6, m10, 0.0, 0.0, 0.0, 0.0, 1.0] }
775    }
776
777    pub fn ortho(left: f32, right: f32, top: f32, bottom: f32, near: f32, far: f32, scalex: f32, scaley: f32) -> Mat4 {
778        let lr = 1.0 / (left - right);
779        let bt = 1.0 / (bottom - top);
780        let nf = 1.0 / (near - far);
781        /*return Mat4{v:[
782            -2.0 * lr * scalex, 0.0, 0.0, (left+right) * lr,
783            0.0, -2.0 * bt * scaley, 0.0, (top+bottom) * bt,
784            0.0, 0.0, 2.0 * nf, (far + near) * nf,
785            0.0, 0.0, 0.0, 1.0
786        ]}*/
787        Mat4 {
788            v: [
789                -2.0 * lr * scalex,
790                0.0,
791                0.0,
792                0.0,
793                0.0,
794                -2.0 * bt * scaley,
795                0.0,
796                0.0,
797                0.0,
798                0.0,
799                -1.0 * nf,
800                0.0,
801                (left + right) * lr,
802                (top + bottom) * bt,
803                0.5 + (far + near) * nf,
804                1.0,
805            ],
806        }
807    }
808
809    pub fn transform_vec4(&self, v: Vec4) -> Vec4 {
810        let m = &self.v;
811        Vec4 {
812            x: m[0] * v.x + m[4] * v.y + m[8] * v.z + m[12] * v.w,
813            y: m[1] * v.x + m[5] * v.y + m[9] * v.z + m[13] * v.w,
814            z: m[2] * v.x + m[6] * v.y + m[10] * v.z + m[14] * v.w,
815            w: m[3] * v.x + m[7] * v.y + m[11] * v.z + m[15] * v.w,
816        }
817    }
818
819    pub fn mul(a: &Mat4, b: &Mat4) -> Mat4 {
820        // this is probably stupid. Programmed JS for too long.
821        let a = &a.v;
822        let b = &b.v;
823        fn d(i: &[f32; 16], x: usize, y: usize) -> f32 {
824            i[x + 4 * y]
825        }
826        Mat4 {
827            v: [
828                d(a, 0, 0) * d(b, 0, 0) + d(a, 1, 0) * d(b, 0, 1) + d(a, 2, 0) * d(b, 0, 2) + d(a, 3, 0) * d(b, 0, 3),
829                d(a, 0, 0) * d(b, 1, 0) + d(a, 1, 0) * d(b, 1, 1) + d(a, 2, 0) * d(b, 1, 2) + d(a, 3, 0) * d(b, 1, 3),
830                d(a, 0, 0) * d(b, 2, 0) + d(a, 1, 0) * d(b, 2, 1) + d(a, 2, 0) * d(b, 2, 2) + d(a, 3, 0) * d(b, 2, 3),
831                d(a, 0, 0) * d(b, 3, 0) + d(a, 1, 0) * d(b, 3, 1) + d(a, 2, 0) * d(b, 3, 2) + d(a, 3, 0) * d(b, 3, 3),
832                d(a, 0, 1) * d(b, 0, 0) + d(a, 1, 1) * d(b, 0, 1) + d(a, 2, 1) * d(b, 0, 2) + d(a, 3, 1) * d(b, 0, 3),
833                d(a, 0, 1) * d(b, 1, 0) + d(a, 1, 1) * d(b, 1, 1) + d(a, 2, 1) * d(b, 1, 2) + d(a, 3, 1) * d(b, 1, 3),
834                d(a, 0, 1) * d(b, 2, 0) + d(a, 1, 1) * d(b, 2, 1) + d(a, 2, 1) * d(b, 2, 2) + d(a, 3, 1) * d(b, 2, 3),
835                d(a, 0, 1) * d(b, 3, 0) + d(a, 1, 1) * d(b, 3, 1) + d(a, 2, 1) * d(b, 3, 2) + d(a, 3, 1) * d(b, 3, 3),
836                d(a, 0, 2) * d(b, 0, 0) + d(a, 1, 2) * d(b, 0, 1) + d(a, 2, 2) * d(b, 0, 2) + d(a, 3, 2) * d(b, 0, 3),
837                d(a, 0, 2) * d(b, 1, 0) + d(a, 1, 2) * d(b, 1, 1) + d(a, 2, 2) * d(b, 1, 2) + d(a, 3, 2) * d(b, 1, 3),
838                d(a, 0, 2) * d(b, 2, 0) + d(a, 1, 2) * d(b, 2, 1) + d(a, 2, 2) * d(b, 2, 2) + d(a, 3, 2) * d(b, 2, 3),
839                d(a, 0, 2) * d(b, 3, 0) + d(a, 1, 2) * d(b, 3, 1) + d(a, 2, 2) * d(b, 3, 2) + d(a, 3, 2) * d(b, 3, 3),
840                d(a, 0, 3) * d(b, 0, 0) + d(a, 1, 3) * d(b, 0, 1) + d(a, 2, 3) * d(b, 0, 2) + d(a, 3, 3) * d(b, 0, 3),
841                d(a, 0, 3) * d(b, 1, 0) + d(a, 1, 3) * d(b, 1, 1) + d(a, 2, 3) * d(b, 1, 2) + d(a, 3, 3) * d(b, 1, 3),
842                d(a, 0, 3) * d(b, 2, 0) + d(a, 1, 3) * d(b, 2, 1) + d(a, 2, 3) * d(b, 2, 2) + d(a, 3, 3) * d(b, 2, 3),
843                d(a, 0, 3) * d(b, 3, 0) + d(a, 1, 3) * d(b, 3, 1) + d(a, 2, 3) * d(b, 3, 2) + d(a, 3, 3) * d(b, 3, 3),
844            ],
845        }
846    }
847
848    pub fn invert(&self) -> Mat4 {
849        let a = &self.v;
850        let a00 = a[0];
851        let a01 = a[1];
852        let a02 = a[2];
853        let a03 = a[3];
854        let a10 = a[4];
855        let a11 = a[5];
856        let a12 = a[6];
857        let a13 = a[7];
858        let a20 = a[8];
859        let a21 = a[9];
860        let a22 = a[10];
861        let a23 = a[11];
862        let a30 = a[12];
863        let a31 = a[13];
864        let a32 = a[14];
865        let a33 = a[15];
866
867        let b00 = a00 * a11 - a01 * a10;
868        let b01 = a00 * a12 - a02 * a10;
869        let b02 = a00 * a13 - a03 * a10;
870        let b03 = a01 * a12 - a02 * a11;
871        let b04 = a01 * a13 - a03 * a11;
872        let b05 = a02 * a13 - a03 * a12;
873        let b06 = a20 * a31 - a21 * a30;
874        let b07 = a20 * a32 - a22 * a30;
875        let b08 = a20 * a33 - a23 * a30;
876        let b09 = a21 * a32 - a22 * a31;
877        let b10 = a21 * a33 - a23 * a31;
878        let b11 = a22 * a33 - a23 * a32;
879
880        // Calculate the determinant
881        let det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
882
883        if det == 0.0 {
884            return Mat4::identity();
885        }
886
887        let idet = 1.0 / det;
888        Mat4 {
889            v: [
890                (a11 * b11 - a12 * b10 + a13 * b09) * idet,
891                (a02 * b10 - a01 * b11 - a03 * b09) * idet,
892                (a31 * b05 - a32 * b04 + a33 * b03) * idet,
893                (a22 * b04 - a21 * b05 - a23 * b03) * idet,
894                (a12 * b08 - a10 * b11 - a13 * b07) * idet,
895                (a00 * b11 - a02 * b08 + a03 * b07) * idet,
896                (a32 * b02 - a30 * b05 - a33 * b01) * idet,
897                (a20 * b05 - a22 * b02 + a23 * b01) * idet,
898                (a10 * b10 - a11 * b08 + a13 * b06) * idet,
899                (a01 * b08 - a00 * b10 - a03 * b06) * idet,
900                (a30 * b04 - a31 * b02 + a33 * b00) * idet,
901                (a21 * b02 - a20 * b04 - a23 * b00) * idet,
902                (a11 * b07 - a10 * b09 - a12 * b06) * idet,
903                (a00 * b09 - a01 * b07 + a02 * b06) * idet,
904                (a31 * b01 - a30 * b03 - a32 * b00) * idet,
905                (a20 * b03 - a21 * b01 + a22 * b00) * idet,
906            ],
907        }
908    }
909
910    /// Transpose a matrix
911    pub fn transpose(&self) -> Mat4 {
912        Mat4 {
913            v: [
914                self.v[0], self.v[4], self.v[8], self.v[12], self.v[1], self.v[5], self.v[9], self.v[13], self.v[2], self.v[6],
915                self.v[10], self.v[14], self.v[3], self.v[7], self.v[11], self.v[15],
916            ],
917        }
918    }
919
920    /// Extracts just the rotation values from a transformation matrix.
921    pub fn as_rotation(&self) -> Mat4 {
922        Mat4 {
923            v: [
924                self.v[0], self.v[1], self.v[2], 0., self.v[4], self.v[5], self.v[6], 0., self.v[8], self.v[9], self.v[10], 0.,
925                0., 0., 0., 1.,
926            ],
927        }
928    }
929}
930
931//------ Vec2 operators
932
933impl ops::Add<Vec2> for Vec2 {
934    type Output = Vec2;
935    fn add(self, rhs: Vec2) -> Vec2 {
936        Vec2 { x: self.x + rhs.x, y: self.y + rhs.y }
937    }
938}
939
940impl ops::Sub<Vec2> for Vec2 {
941    type Output = Vec2;
942    fn sub(self, rhs: Vec2) -> Vec2 {
943        Vec2 { x: self.x - rhs.x, y: self.y - rhs.y }
944    }
945}
946
947impl ops::Mul<Vec2> for Vec2 {
948    type Output = Vec2;
949    fn mul(self, rhs: Vec2) -> Vec2 {
950        Vec2 { x: self.x * rhs.x, y: self.y * rhs.y }
951    }
952}
953
954impl ops::Div<Vec2> for Vec2 {
955    type Output = Vec2;
956    fn div(self, rhs: Vec2) -> Vec2 {
957        Vec2 { x: self.x / rhs.x, y: self.y / rhs.y }
958    }
959}
960
961impl ops::Add<Vec2> for f32 {
962    type Output = Vec2;
963    fn add(self, rhs: Vec2) -> Vec2 {
964        Vec2 { x: self + rhs.x, y: self + rhs.y }
965    }
966}
967
968impl ops::Sub<Vec2> for f32 {
969    type Output = Vec2;
970    fn sub(self, rhs: Vec2) -> Vec2 {
971        Vec2 { x: self - rhs.x, y: self - rhs.y }
972    }
973}
974
975impl ops::Mul<Vec2> for f32 {
976    type Output = Vec2;
977    fn mul(self, rhs: Vec2) -> Vec2 {
978        Vec2 { x: self * rhs.x, y: self * rhs.y }
979    }
980}
981
982impl ops::Div<Vec2> for f32 {
983    type Output = Vec2;
984    fn div(self, rhs: Vec2) -> Vec2 {
985        Vec2 { x: self / rhs.x, y: self / rhs.y }
986    }
987}
988
989impl ops::Add<f32> for Vec2 {
990    type Output = Vec2;
991    fn add(self, rhs: f32) -> Vec2 {
992        Vec2 { x: self.x + rhs, y: self.y + rhs }
993    }
994}
995
996impl ops::Sub<f32> for Vec2 {
997    type Output = Vec2;
998    fn sub(self, rhs: f32) -> Vec2 {
999        Vec2 { x: self.x - rhs, y: self.y - rhs }
1000    }
1001}
1002
1003impl ops::Mul<f32> for Vec2 {
1004    type Output = Vec2;
1005    fn mul(self, rhs: f32) -> Vec2 {
1006        Vec2 { x: self.x * rhs, y: self.y * rhs }
1007    }
1008}
1009
1010impl ops::Div<f32> for Vec2 {
1011    type Output = Vec2;
1012    fn div(self, rhs: f32) -> Vec2 {
1013        Vec2 { x: self.x / rhs, y: self.y / rhs }
1014    }
1015}
1016
1017impl ops::AddAssign<Vec2> for Vec2 {
1018    fn add_assign(&mut self, rhs: Vec2) {
1019        self.x = self.x + rhs.x;
1020        self.y = self.y + rhs.y;
1021    }
1022}
1023
1024impl ops::SubAssign<Vec2> for Vec2 {
1025    fn sub_assign(&mut self, rhs: Vec2) {
1026        self.x = self.x - rhs.x;
1027        self.y = self.y - rhs.y;
1028    }
1029}
1030
1031impl ops::MulAssign<Vec2> for Vec2 {
1032    fn mul_assign(&mut self, rhs: Vec2) {
1033        self.x = self.x * rhs.x;
1034        self.y = self.y * rhs.y;
1035    }
1036}
1037
1038impl ops::DivAssign<Vec2> for Vec2 {
1039    fn div_assign(&mut self, rhs: Vec2) {
1040        self.x = self.x / rhs.x;
1041        self.y = self.y / rhs.y;
1042    }
1043}
1044
1045impl ops::AddAssign<f32> for Vec2 {
1046    fn add_assign(&mut self, rhs: f32) {
1047        self.x = self.x + rhs;
1048        self.y = self.y + rhs;
1049    }
1050}
1051
1052impl ops::SubAssign<f32> for Vec2 {
1053    fn sub_assign(&mut self, rhs: f32) {
1054        self.x = self.x - rhs;
1055        self.y = self.y - rhs;
1056    }
1057}
1058
1059impl ops::MulAssign<f32> for Vec2 {
1060    fn mul_assign(&mut self, rhs: f32) {
1061        self.x = self.x * rhs;
1062        self.y = self.y * rhs;
1063    }
1064}
1065
1066impl ops::DivAssign<f32> for Vec2 {
1067    fn div_assign(&mut self, rhs: f32) {
1068        self.x = self.x / rhs;
1069        self.y = self.y / rhs;
1070    }
1071}
1072
1073impl ops::Neg for Vec2 {
1074    type Output = Vec2;
1075    fn neg(self) -> Self {
1076        Vec2 { x: -self.x, y: -self.y }
1077    }
1078}
1079
1080impl ops::Neg for Vec3 {
1081    type Output = Vec3;
1082    fn neg(self) -> Self {
1083        Vec3 { x: -self.x, y: -self.y, z: -self.z }
1084    }
1085}
1086
1087impl ops::Neg for Vec4 {
1088    type Output = Vec4;
1089    fn neg(self) -> Self {
1090        Vec4 { x: -self.x, y: -self.y, z: -self.z, w: -self.w }
1091    }
1092}
1093
1094//------ Vec3 operators
1095
1096impl ops::Add<Vec3> for Vec3 {
1097    type Output = Vec3;
1098    fn add(self, rhs: Vec3) -> Vec3 {
1099        Vec3 { x: self.x + rhs.x, y: self.y + rhs.y, z: self.z + rhs.z }
1100    }
1101}
1102
1103impl ops::Sub<Vec3> for Vec3 {
1104    type Output = Vec3;
1105    fn sub(self, rhs: Vec3) -> Vec3 {
1106        Vec3 { x: self.x - rhs.x, y: self.y - rhs.y, z: self.z - rhs.z }
1107    }
1108}
1109
1110impl ops::Mul<Vec3> for Vec3 {
1111    type Output = Vec3;
1112    fn mul(self, rhs: Vec3) -> Vec3 {
1113        Vec3 { x: self.x * rhs.x, y: self.y * rhs.y, z: self.z * rhs.z }
1114    }
1115}
1116
1117impl ops::Div<Vec3> for Vec3 {
1118    type Output = Vec3;
1119    fn div(self, rhs: Vec3) -> Vec3 {
1120        Vec3 { x: self.x / rhs.x, y: self.y / rhs.y, z: self.z / rhs.z }
1121    }
1122}
1123
1124impl ops::Add<Vec3> for f32 {
1125    type Output = Vec3;
1126    fn add(self, rhs: Vec3) -> Vec3 {
1127        Vec3 { x: self + rhs.x, y: self + rhs.y, z: self + rhs.z }
1128    }
1129}
1130
1131impl ops::Sub<Vec3> for f32 {
1132    type Output = Vec3;
1133    fn sub(self, rhs: Vec3) -> Vec3 {
1134        Vec3 { x: self - rhs.x, y: self - rhs.y, z: self - rhs.z }
1135    }
1136}
1137
1138impl ops::Mul<Vec3> for f32 {
1139    type Output = Vec3;
1140    fn mul(self, rhs: Vec3) -> Vec3 {
1141        Vec3 { x: self * rhs.x, y: self * rhs.y, z: self * rhs.z }
1142    }
1143}
1144
1145impl ops::Div<Vec3> for f32 {
1146    type Output = Vec3;
1147    fn div(self, rhs: Vec3) -> Vec3 {
1148        Vec3 { x: self / rhs.x, y: self / rhs.y, z: self / rhs.z }
1149    }
1150}
1151
1152impl ops::Add<f32> for Vec3 {
1153    type Output = Vec3;
1154    fn add(self, rhs: f32) -> Vec3 {
1155        Vec3 { x: self.x + rhs, y: self.y + rhs, z: self.z + rhs }
1156    }
1157}
1158
1159impl ops::Sub<f32> for Vec3 {
1160    type Output = Vec3;
1161    fn sub(self, rhs: f32) -> Vec3 {
1162        Vec3 { x: self.x - rhs, y: self.y - rhs, z: self.z - rhs }
1163    }
1164}
1165
1166impl ops::Mul<f32> for Vec3 {
1167    type Output = Vec3;
1168    fn mul(self, rhs: f32) -> Vec3 {
1169        Vec3 { x: self.x * rhs, y: self.y * rhs, z: self.z * rhs }
1170    }
1171}
1172
1173impl ops::Div<f32> for Vec3 {
1174    type Output = Vec3;
1175    fn div(self, rhs: f32) -> Vec3 {
1176        Vec3 { x: self.x / rhs, y: self.y / rhs, z: self.z / rhs }
1177    }
1178}
1179
1180impl ops::AddAssign<Vec3> for Vec3 {
1181    fn add_assign(&mut self, rhs: Vec3) {
1182        self.x = self.x + rhs.x;
1183        self.y = self.y + rhs.y;
1184        self.z = self.z + rhs.z;
1185    }
1186}
1187
1188impl ops::SubAssign<Vec3> for Vec3 {
1189    fn sub_assign(&mut self, rhs: Vec3) {
1190        self.x = self.x - rhs.x;
1191        self.y = self.y - rhs.y;
1192        self.z = self.z - rhs.z;
1193    }
1194}
1195
1196impl ops::MulAssign<Vec3> for Vec3 {
1197    fn mul_assign(&mut self, rhs: Vec3) {
1198        self.x = self.x * rhs.x;
1199        self.y = self.y * rhs.y;
1200        self.z = self.z * rhs.z;
1201    }
1202}
1203
1204impl ops::DivAssign<Vec3> for Vec3 {
1205    fn div_assign(&mut self, rhs: Vec3) {
1206        self.x = self.x / rhs.x;
1207        self.y = self.y / rhs.y;
1208        self.z = self.z / rhs.z;
1209    }
1210}
1211
1212impl ops::AddAssign<f32> for Vec3 {
1213    fn add_assign(&mut self, rhs: f32) {
1214        self.x = self.x + rhs;
1215        self.y = self.y + rhs;
1216        self.z = self.z + rhs;
1217    }
1218}
1219
1220impl ops::SubAssign<f32> for Vec3 {
1221    fn sub_assign(&mut self, rhs: f32) {
1222        self.x = self.x - rhs;
1223        self.y = self.y - rhs;
1224        self.z = self.z - rhs;
1225    }
1226}
1227
1228impl ops::MulAssign<f32> for Vec3 {
1229    fn mul_assign(&mut self, rhs: f32) {
1230        self.x = self.x * rhs;
1231        self.y = self.y * rhs;
1232        self.z = self.z * rhs;
1233    }
1234}
1235
1236impl ops::DivAssign<f32> for Vec3 {
1237    fn div_assign(&mut self, rhs: f32) {
1238        self.x = self.x / rhs;
1239        self.y = self.y / rhs;
1240        self.z = self.z / rhs;
1241    }
1242}
1243
1244//------ Vec4 operators
1245
1246impl ops::Add<Vec4> for Vec4 {
1247    type Output = Vec4;
1248    fn add(self, rhs: Vec4) -> Vec4 {
1249        Vec4 { x: self.x + rhs.x, y: self.y + rhs.y, z: self.z + rhs.z, w: self.w + rhs.w }
1250    }
1251}
1252
1253impl ops::Sub<Vec4> for Vec4 {
1254    type Output = Vec4;
1255    fn sub(self, rhs: Vec4) -> Vec4 {
1256        Vec4 { x: self.x - rhs.x, y: self.y - rhs.y, z: self.z - rhs.z, w: self.w - rhs.w }
1257    }
1258}
1259
1260impl ops::Mul<Vec4> for Vec4 {
1261    type Output = Vec4;
1262    fn mul(self, rhs: Vec4) -> Vec4 {
1263        Vec4 { x: self.x * rhs.x, y: self.y * rhs.y, z: self.z * rhs.z, w: self.w * rhs.w }
1264    }
1265}
1266
1267impl ops::Div<Vec4> for Vec4 {
1268    type Output = Vec4;
1269    fn div(self, rhs: Vec4) -> Vec4 {
1270        Vec4 { x: self.x / rhs.x, y: self.y / rhs.y, z: self.z / rhs.z, w: self.w / rhs.w }
1271    }
1272}
1273
1274impl ops::Add<Vec4> for f32 {
1275    type Output = Vec4;
1276    fn add(self, rhs: Vec4) -> Vec4 {
1277        Vec4 { x: self + rhs.x, y: self + rhs.y, z: self + rhs.z, w: self + rhs.z }
1278    }
1279}
1280
1281impl ops::Sub<Vec4> for f32 {
1282    type Output = Vec4;
1283    fn sub(self, rhs: Vec4) -> Vec4 {
1284        Vec4 { x: self - rhs.x, y: self - rhs.y, z: self - rhs.z, w: self - rhs.z }
1285    }
1286}
1287
1288impl ops::Mul<Vec4> for f32 {
1289    type Output = Vec4;
1290    fn mul(self, rhs: Vec4) -> Vec4 {
1291        Vec4 { x: self * rhs.x, y: self * rhs.y, z: self * rhs.z, w: self * rhs.z }
1292    }
1293}
1294
1295impl ops::Div<Vec4> for f32 {
1296    type Output = Vec4;
1297    fn div(self, rhs: Vec4) -> Vec4 {
1298        Vec4 { x: self / rhs.x, y: self / rhs.y, z: self / rhs.z, w: self / rhs.z }
1299    }
1300}
1301
1302impl ops::Add<f32> for Vec4 {
1303    type Output = Vec4;
1304    fn add(self, rhs: f32) -> Vec4 {
1305        Vec4 { x: self.x + rhs, y: self.y + rhs, z: self.z + rhs, w: self.w + rhs }
1306    }
1307}
1308
1309impl ops::Sub<f32> for Vec4 {
1310    type Output = Vec4;
1311    fn sub(self, rhs: f32) -> Vec4 {
1312        Vec4 { x: self.x - rhs, y: self.y - rhs, z: self.z - rhs, w: self.w - rhs }
1313    }
1314}
1315
1316impl ops::Mul<f32> for Vec4 {
1317    type Output = Vec4;
1318    fn mul(self, rhs: f32) -> Vec4 {
1319        Vec4 { x: self.x * rhs, y: self.y * rhs, z: self.z * rhs, w: self.w * rhs }
1320    }
1321}
1322
1323impl ops::Div<f32> for Vec4 {
1324    type Output = Vec4;
1325    fn div(self, rhs: f32) -> Vec4 {
1326        Vec4 { x: self.x / rhs, y: self.y / rhs, z: self.z / rhs, w: self.w / rhs }
1327    }
1328}
1329
1330impl ops::AddAssign<Vec4> for Vec4 {
1331    fn add_assign(&mut self, rhs: Vec4) {
1332        self.x = self.x + rhs.x;
1333        self.y = self.y + rhs.y;
1334        self.z = self.z + rhs.z;
1335        self.w = self.w + rhs.w;
1336    }
1337}
1338
1339impl ops::SubAssign<Vec4> for Vec4 {
1340    fn sub_assign(&mut self, rhs: Vec4) {
1341        self.x = self.x - rhs.x;
1342        self.y = self.y - rhs.y;
1343        self.z = self.z - rhs.z;
1344        self.w = self.w - rhs.w;
1345    }
1346}
1347
1348impl ops::MulAssign<Vec4> for Vec4 {
1349    fn mul_assign(&mut self, rhs: Vec4) {
1350        self.x = self.x * rhs.x;
1351        self.y = self.y * rhs.y;
1352        self.z = self.z * rhs.z;
1353        self.w = self.w * rhs.w;
1354    }
1355}
1356
1357impl ops::DivAssign<Vec4> for Vec4 {
1358    fn div_assign(&mut self, rhs: Vec4) {
1359        self.x = self.x / rhs.x;
1360        self.y = self.y / rhs.y;
1361        self.z = self.z / rhs.z;
1362        self.w = self.w / rhs.w;
1363    }
1364}
1365
1366impl ops::AddAssign<f32> for Vec4 {
1367    fn add_assign(&mut self, rhs: f32) {
1368        self.x = self.x + rhs;
1369        self.y = self.y + rhs;
1370        self.z = self.z + rhs;
1371        self.w = self.w + rhs;
1372    }
1373}
1374
1375impl ops::SubAssign<f32> for Vec4 {
1376    fn sub_assign(&mut self, rhs: f32) {
1377        self.x = self.x - rhs;
1378        self.y = self.y - rhs;
1379        self.z = self.z - rhs;
1380        self.w = self.w - rhs;
1381    }
1382}
1383
1384impl ops::MulAssign<f32> for Vec4 {
1385    fn mul_assign(&mut self, rhs: f32) {
1386        self.x = self.x * rhs;
1387        self.y = self.y * rhs;
1388        self.z = self.z * rhs;
1389        self.w = self.w * rhs;
1390    }
1391}
1392
1393impl ops::DivAssign<f32> for Vec4 {
1394    fn div_assign(&mut self, rhs: f32) {
1395        self.x = self.x / rhs;
1396        self.y = self.y / rhs;
1397        self.z = self.z / rhs;
1398        self.w = self.w / rhs;
1399    }
1400}