three_d/renderer/geometry/
rectangle.rs

1use crate::renderer::*;
2
3///
4/// A rectangle 2D geometry which can be rendered using a camera created by [Camera::new_2d].
5///
6pub struct Rectangle {
7    mesh: Mesh,
8    width: f32,
9    height: f32,
10    center: PhysicalPoint,
11    rotation: Radians,
12}
13
14impl Rectangle {
15    ///
16    /// Constructs a new rectangle geometry.
17    ///
18    pub fn new(
19        context: &Context,
20        center: impl Into<PhysicalPoint>,
21        rotation: impl Into<Radians>,
22        width: f32,
23        height: f32,
24    ) -> Self {
25        let mut mesh = CpuMesh::square();
26        mesh.transform(Mat4::from_scale(0.5)).unwrap();
27        let mut rectangle = Self {
28            mesh: Mesh::new(context, &mesh),
29            width,
30            height,
31            center: center.into(),
32            rotation: rotation.into(),
33        };
34        rectangle.update();
35        rectangle
36    }
37
38    /// Set the size of the rectangle.
39    pub fn set_size(&mut self, width: f32, height: f32) {
40        self.width = width;
41        self.height = height;
42        self.update();
43    }
44
45    /// Get the size of the rectangle.
46    pub fn size(&self) -> (f32, f32) {
47        (self.width, self.height)
48    }
49
50    /// Set the center of the rectangle.
51    pub fn set_center(&mut self, center: impl Into<PhysicalPoint>) {
52        self.center = center.into();
53        self.update();
54    }
55
56    /// Get the center of the rectangle.
57    pub fn center(&self) -> PhysicalPoint {
58        self.center
59    }
60
61    /// Set the rotation of the rectangle.
62    pub fn set_rotation(&mut self, rotation: impl Into<Radians>) {
63        self.rotation = rotation.into();
64        self.update();
65    }
66
67    /// Get the rotation of the rectangle.
68    pub fn rotation(&self) -> Radians {
69        self.rotation
70    }
71
72    fn update(&mut self) {
73        self.mesh.set_transformation_2d(
74            Mat3::from_translation(self.center.into())
75                * Mat3::from_angle_z(self.rotation)
76                * Mat3::from_nonuniform_scale(self.width, self.height),
77        );
78    }
79}
80
81impl<'a> IntoIterator for &'a Rectangle {
82    type Item = &'a dyn Geometry;
83    type IntoIter = std::iter::Once<&'a dyn Geometry>;
84
85    fn into_iter(self) -> Self::IntoIter {
86        std::iter::once(self)
87    }
88}
89
90use std::ops::Deref;
91impl Deref for Rectangle {
92    type Target = Mesh;
93    fn deref(&self) -> &Self::Target {
94        &self.mesh
95    }
96}
97
98impl std::ops::DerefMut for Rectangle {
99    fn deref_mut(&mut self) -> &mut Self::Target {
100        &mut self.mesh
101    }
102}
103
104impl Geometry for Rectangle {
105    impl_geometry_body!(deref);
106
107    fn animate(&mut self, time: f32) {
108        self.mesh.animate(time)
109    }
110}