limelight_transform/
lib.rs

1use limelight::Uniform;
2
3pub struct TransformUniform {
4    scale: (f32, f32),
5    center: (f32, f32),
6    uniform: Uniform<[[f32; 4]; 4]>,
7    shear: (f32, f32),
8}
9
10fn scale_center_to_matrix(
11    (scale_x, scale_y): (f32, f32),
12    (center_x, center_y): (f32, f32),
13    (shear_x, shear_y): (f32, f32),
14) -> [[f32; 4]; 4] {
15    [
16        [scale_x, 0., 0., -center_x],
17        [0., scale_y, 0., -center_y],
18        [0., 0., 1., 0.],
19        [shear_x, shear_y, 0., 1.],
20    ]
21}
22
23impl Default for TransformUniform {
24    fn default() -> Self {
25        Self::new()
26    }
27}
28
29impl TransformUniform {
30    pub fn new() -> Self {
31        let scale = (1., 1.);
32        let center = (0., 0.);
33        let shear = (0., 0.);
34        let uniform = Uniform::new(scale_center_to_matrix(scale, center, shear));
35        TransformUniform {
36            scale,
37            center,
38            shear,
39            uniform,
40        }
41    }
42
43    pub fn uniform(&self) -> Uniform<[[f32; 4]; 4]> {
44        self.uniform.clone()
45    }
46
47    fn update_uniform(&self) {
48        self.uniform
49            .set_value(scale_center_to_matrix(self.scale, self.center, self.shear));
50    }
51
52    /// Multiply the current scale, in such a way that the given point
53    /// remains stationary.
54    ///
55    /// i.e. if `v * self.uniform.value = scale_center` is true before the
56    /// scale is applied, it should also be true after.
57    pub fn scale(&mut self, scale_factor: f32, scale_center: (f32, f32)) {
58        let old_scale_x = self.scale.0;
59        let old_scale_y = self.scale.1;
60
61        self.scale.0 *= scale_factor;
62        self.scale.1 *= scale_factor;
63
64        self.center.0 =
65            (self.scale.0 / old_scale_x) * (scale_center.0 + self.center.0) - scale_center.0;
66        self.center.1 =
67            (self.scale.1 / old_scale_y) * (scale_center.1 + self.center.1) - scale_center.1;
68
69        self.update_uniform();
70    }
71
72    // Pan by the given amount, provided in destination units.
73    pub fn pan(&mut self, vector: (f32, f32)) {
74        self.center.0 -= vector.0;
75        self.center.1 -= vector.1;
76        self.update_uniform();
77    }
78
79    pub fn shear(&mut self, vector: (f32, f32)) {
80        self.shear.0 -= vector.0;
81        self.shear.1 -= vector.1;
82        self.update_uniform();
83    }
84}