use super::icon_renderer::IconRenderer; use crate::map::Mappable; use crate::math::{Vec2, Rect}; use crate::transform::Transform; use raylib::core::drawing::{RaylibDraw, RaylibDrawHandle}; use raylib::ffi::Color; use serde::{Deserialize, Serialize}; use std::ops::{Deref, DerefMut}; use std::rc::Rc; #[derive(Clone, Serialize, Deserialize)] pub struct IconData { /// The id of the icon is the icons position in the currently loaded icon_data vector. pub id: usize, /// The position of the icon on the map, given by the vector in meters. pub position: Vec2, /// Rotation of the icon texture in degrees. pub rotation: f64, } #[derive(Clone)] pub struct Icon { data: IconData, renderer: Rc, } impl Icon { pub fn new(id: usize, position: Vec2, rotation: f64, renderer: Rc) -> Self { Self::from_data( IconData { id, position, rotation, }, renderer, ) } pub fn from_data(data: IconData, renderer: Rc) -> Self { Self { data, renderer } } } impl Mappable for Icon { fn draw(&self, rld: &mut RaylibDrawHandle, transform: &Transform) { let (texture, info) = self.renderer.get(self.id); // Round the position to whole pixels to fix rotation problems. let mut position_px = transform.point_m_to_px(&(self.position - (info.anchor / info.pixels_per_m))); position_px.x = position_px.x.floor(); position_px.y = position_px.y.floor(); rld.draw_texture_ex( texture, position_px, self.rotation as f32, (transform.pixels_per_m() / info.pixels_per_m) as f32, Color { r: 255, g: 255, b: 255, a: 255, }, ); } fn bounding_rect(&self) -> Rect { Rect::new(self.data.position.x, self.data.position.y, 0., 0.) } } impl Deref for Icon { type Target = IconData; fn deref(&self) -> &Self::Target { &self.data } } impl DerefMut for Icon { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.data } }