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
93            .0
94            .mul_vec4(Vec4::new(self.width, self.height, 1.0, 0.0));
95
96        Size::new(new_size.x, new_size.y)
97    }
98}
99
100impl Mul<Transformation> for Rectangle {
101    type Output = Self;
102
103    fn mul(self, transformation: Transformation) -> Self {
104        let position = self.position();
105        let size = self.size();
106
107        Self::new(position * transformation, size * transformation)
108    }
109}
110
111impl AsRef<[f32; 16]> for Transformation {
112    fn as_ref(&self) -> &[f32; 16] {
113        self.0.as_ref()
114    }
115}
116
117impl From<Transformation> for [f32; 16] {
118    fn from(t: Transformation) -> [f32; 16] {
119        *t.as_ref()
120    }
121}
122
123impl From<Transformation> for Mat4 {
124    fn from(transformation: Transformation) -> Self {
125        transformation.0
126    }
127}