iced_core/
transformation.rs

1use crate::{Point, Rectangle, Size, Vector};
2
3use glam::{Mat4, Vec3, Vec4};
4use std::ops::Mul;
5
6/// A 2D transformation matrix.
7#[derive(Debug, Clone, Copy, PartialEq)]
8pub struct Transformation(Mat4);
9
10impl Transformation {
11    /// A [`Transformation`] that preserves whatever is transformed.
12    pub const IDENTITY: Self = Self(Mat4::IDENTITY);
13
14    /// Creates an orthographic projection.
15    #[rustfmt::skip]
16    pub fn orthographic(width: u32, height: u32) -> Self{
17        Self(Mat4::orthographic_rh_gl(
18            0.0, width as f32,
19            height as f32, 0.0,
20            -1.0, 1.0
21        ))
22    }
23
24    /// Creates a translate transformation.
25    pub fn translate(x: f32, y: f32) -> Self {
26        Self(Mat4::from_translation(Vec3::new(x, y, 0.0)))
27    }
28
29    /// Creates a uniform scaling transformation.
30    pub fn scale(scaling: f32) -> Self {
31        Self(Mat4::from_scale(Vec3::new(scaling, scaling, 1.0)))
32    }
33
34    /// Returns the inverse of the [`Transformation`].
35    pub fn inverse(self) -> Self {
36        Self(self.0.inverse())
37    }
38
39    /// Returns the scale factor of the [`Transformation`].
40    pub fn scale_factor(&self) -> f32 {
41        self.0.x_axis.x
42    }
43
44    /// Returns the translation of the [`Transformation`].
45    pub fn translation(&self) -> Vector {
46        Vector::new(self.0.w_axis.x, self.0.w_axis.y)
47    }
48}
49
50impl Default for Transformation {
51    fn default() -> Self {
52        Transformation::IDENTITY
53    }
54}
55
56impl Mul for Transformation {
57    type Output = Self;
58
59    fn mul(self, rhs: Self) -> Self {
60        Self(self.0 * rhs.0)
61    }
62}
63
64impl Mul<Transformation> for Point {
65    type Output = Self;
66
67    fn mul(self, transformation: Transformation) -> Self {
68        let point = transformation
69            .0
70            .mul_vec4(Vec4::new(self.x, self.y, 1.0, 1.0));
71
72        Point::new(point.x, point.y)
73    }
74}
75
76impl Mul<Transformation> for Vector {
77    type Output = Self;
78
79    fn mul(self, transformation: Transformation) -> Self {
80        let new_vector = transformation
81            .0
82            .mul_vec4(Vec4::new(self.x, self.y, 1.0, 0.0));
83
84        Vector::new(new_vector.x, new_vector.y)
85    }
86}
87
88impl Mul<Transformation> for Size {
89    type Output = Self;
90
91    fn mul(self, transformation: Transformation) -> Self {
92        let new_size = transformation.0.mul_vec4(Vec4::new(
93            self.width,
94            self.height,
95            1.0,
96            0.0,
97        ));
98
99        Size::new(new_size.x, new_size.y)
100    }
101}
102
103impl Mul<Transformation> for Rectangle {
104    type Output = Self;
105
106    fn mul(self, transformation: Transformation) -> Self {
107        let position = self.position();
108        let size = self.size();
109
110        Self::new(position * transformation, size * transformation)
111    }
112}
113
114impl AsRef<[f32; 16]> for Transformation {
115    fn as_ref(&self) -> &[f32; 16] {
116        self.0.as_ref()
117    }
118}
119
120impl From<Transformation> for [f32; 16] {
121    fn from(t: Transformation) -> [f32; 16] {
122        *t.as_ref()
123    }
124}
125
126impl From<Transformation> for Mat4 {
127    fn from(transformation: Transformation) -> Self {
128        transformation.0
129    }
130}