//! 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::client::colours::DEFAULT_COLOURS; use crate::client::transform::Transform; use crate::client::FLOAT_MARGIN; use crate::math::{self, Triangle}; use crate::world::{Component, Room}; use raylib::drawing::{RaylibDraw, RaylibDrawHandle}; use std::ops::Deref; /// A polygon room, which can be placed and modified in the world. pub struct RoomMark { room: Room, // The polygon shape, but in triangles, so the polygon does not have to be triangulated every frame. triangulated: Vec>, selected: bool, } impl RoomMark { /// Create a room from the given polygon data. pub fn from_room(room: Room) -> Self { let shape = room.shape().clone(); Self { room, triangulated: math::triangulate(shape, FLOAT_MARGIN), selected: false, } } /// Replace the room this mark describes with the new room. pub fn set_room(&mut self, room: Room) { self.room = room; self.retriangulate(); } /* 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.room.shape().clone(), FLOAT_MARGIN); } } impl Mappable for RoomMark { 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 as_component(&self) -> &dyn Component { self.deref() } } impl Deref for RoomMark { type Target = Room; fn deref(&self) -> &Self::Target { &self.room } }