tuix_core/state/style/
transform.rs

1// Rename to Transform when I've come up with a better name for the current transform mod
2use crate::state::animation::Interpolator;
3
4use std::ops::{
5    Index,
6    IndexMut,
7};
8
9#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
10pub struct Transform2D(pub [f32; 6]);
11
12impl Transform2D {
13    pub fn new(a: f32, b: f32, c: f32, d: f32, e: f32, f: f32) -> Self {
14        Self([a,b,c,d,e,f])
15    }
16
17    pub fn identity() -> Self {
18        Self([1.0, 0.0, 0.0, 1.0, 0.0, 0.0])
19    }
20
21    pub fn rotate(&mut self, a: f32) {
22        let cs = a.cos();
23        let sn = a.sin();
24
25        self[0] = cs;
26        self[1] = sn;
27        self[2] = -sn;
28        self[3] = cs;
29        self[4] = 0.0;
30        self[5] = 0.0;
31    }
32
33    pub fn inverse(&mut self) {
34        let t = *self;
35        let det = t[0] as f64 * t[3] as f64 - t[2] as f64 * t[1] as f64;
36
37        if det > -1e-6 && det < 1e-6 {
38            *self = Self::identity();
39        }
40
41        let invdet = 1.0 / det;
42
43        self[0] = (t[3] as f64 * invdet) as f32;
44        self[2] = (-t[2] as f64 * invdet) as f32;
45        self[4] = ((t[2] as f64 * t[5] as f64 - t[3] as f64 * t[4] as f64) * invdet) as f32;
46        self[1] = (-t[1] as f64 * invdet) as f32;
47        self[3] = (t[0] as f64 * invdet) as f32;
48        self[5] = ((t[1] as f64 * t[4] as f64 - t[0] as f64 * t[5] as f64) * invdet) as f32;
49    }
50
51    pub fn translate(&mut self, tx: f32, ty: f32) {
52        self[4] = tx;
53        self[5] = ty;
54    }
55
56    pub fn scale(&mut self, sx: f32, sy: f32) {
57        self[0] = sx;
58        self[3] = sy;
59    }
60
61    pub fn transform_point(&self, sx: f32, sy: f32) -> (f32, f32) {
62        let dx = sx * self[0] + sy * self[2] + self[4];
63        let dy = sx * self[1] + sy * self[3] + self[5];
64        (dx, dy)
65    }
66
67    pub fn multiply(&mut self, other: &Self) {
68        let t0 = self[0] * other[0] + self[1] * other[2];
69        let t2 = self[2] * other[0] + self[3] * other[2];
70        let t4 = self[4] * other[0] + self[5] * other[2] + other[4];
71        self[1] = self[0] * other[1] + self[1] * other[3];
72        self[3] = self[2] * other[1] + self[3] * other[3];
73        self[5] = self[4] * other[1] + self[5] * other[3] + other[5];
74        self[0] = t0;
75        self[2] = t2;
76        self[4] = t4;
77    }
78
79    pub fn premultiply(&mut self, other: &Self) {
80        let mut other = *other;
81        other.multiply(self);
82        *self = other;
83    }
84}
85
86impl Default for Transform2D {
87    fn default() -> Self {
88        Self::identity()
89    }
90}
91
92impl Index<usize> for Transform2D {
93    type Output = f32;
94
95    fn index(&self, index: usize) -> &Self::Output {
96        &self.0[index]
97    }
98}
99
100impl IndexMut<usize> for Transform2D {
101    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
102        &mut self.0[index]
103    }
104}