diff options
| author | Arne Dußin | 2021-01-11 14:21:03 +0100 |
|---|---|---|
| committer | Arne Dußin | 2021-01-11 16:02:03 +0100 |
| commit | b1179849c28e50c39ac3c94af9dda86ee24beca0 (patch) | |
| tree | 6fc845d3547bdeb87de75e0f049132de3e05a81d /src/map/room.rs | |
| parent | ec071d5bc677101c0168b5fb3065f2d928234ed9 (diff) | |
| download | graf_karto-b1179849c28e50c39ac3c94af9dda86ee24beca0.tar.gz graf_karto-b1179849c28e50c39ac3c94af9dda86ee24beca0.zip | |
Rename PolygonRoom to just Room
Diffstat (limited to 'src/map/room.rs')
| -rw-r--r-- | src/map/room.rs | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/map/room.rs b/src/map/room.rs new file mode 100644 index 0000000..3050763 --- /dev/null +++ b/src/map/room.rs @@ -0,0 +1,98 @@ +//! Polygon rooms are the standard rooms in graf karto. They can take the form of anything that a +//! [Polygon](crate::math::Polygon) can have. + +use super::Mappable; +use crate::colours::DEFAULT_COLOURS; +use crate::math::{self, Polygon, Rect, Triangle}; +use crate::transform::Transform; +use crate::transformable::NonRigidTransformable; +use crate::FLOAT_MARGIN; +use nalgebra::{Matrix3, Point2}; +use raylib::drawing::{RaylibDraw, RaylibDrawHandle}; +use std::ops::Deref; + +/// Data type for the Polygon room. +pub type RoomData = Polygon<f64>; + +/// A polygon room, which can be placed and modified in the world. +pub struct Room { + data: RoomData, + // The polygon shape, but in triangles, so the polygon does not have to be triangulated every frame. + triangulated: Vec<Triangle<f64>>, + selected: bool, +} + +impl Room { + /// Create a room from the given polygon data. + pub fn from_data(data: RoomData) -> Self { + Self { + data: data.clone(), + triangulated: math::triangulate(data, FLOAT_MARGIN), + selected: false, + } + } + + /* When the internal polygon changes, it must be retriangulated to be drawn on the screen + * properly, so this function must be called any time that happens. + */ + fn retriangulate(&mut self) { + self.triangulated = math::triangulate(self.data.clone(), FLOAT_MARGIN); + } +} + +impl Mappable for Room { + fn draw(&self, rld: &mut RaylibDrawHandle, transform: &Transform) { + for triangle in &self.triangulated { + rld.draw_triangle( + transform.point_m_to_px(&triangle.corners()[0]), + transform.point_m_to_px(&triangle.corners()[1]), + transform.point_m_to_px(&triangle.corners()[2]), + if self.selected() { + DEFAULT_COLOURS.room_selected + } else { + DEFAULT_COLOURS.room_normal + }, + ) + } + } + + fn set_selected(&mut self, selected: bool) { + self.selected = selected; + } + + fn selected(&self) -> bool { + self.selected + } + + fn bounding_rect(&self) -> Rect<f64> { + Rect::bounding_rect_n(&self.data.corners()) + } + + fn as_non_rigid(&self) -> Option<&dyn NonRigidTransformable> { + Some(self as &dyn NonRigidTransformable) + } + + fn as_non_rigid_mut(&mut self) -> Option<&mut dyn NonRigidTransformable> { + Some(self as &mut dyn NonRigidTransformable) + } +} + +impl NonRigidTransformable for Room { + fn apply_matrix(&mut self, matrix: &Matrix3<f64>) { + for corner in self.data.corners_mut() { + *corner = matrix + .transform_point(&Point2::new(corner.x, corner.y)) + .into(); + } + + self.retriangulate(); + } +} + +impl Deref for Room { + type Target = RoomData; + + fn deref(&self) -> &Self::Target { + &self.data + } +} |
