From 20c73199167ce3ef1b4a256db5a95acab8f467b3 Mon Sep 17 00:00:00 2001 From: Arne Dußin Date: Thu, 29 Oct 2020 15:02:08 +0100 Subject: Make grid "infinite" --- src/infinite_grid.rs | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 src/infinite_grid.rs (limited to 'src/infinite_grid.rs') diff --git a/src/infinite_grid.rs b/src/infinite_grid.rs new file mode 100644 index 0000000..163c2b2 --- /dev/null +++ b/src/infinite_grid.rs @@ -0,0 +1,63 @@ +//! Grid that can be moved and scaled, and which gives the appearance of being infinite, while +//! staying easily renderable. + +use crate::transform::Transform; +use piston_window::grid::Grid; +use piston_window::line::{Line, Shape}; +use piston_window::{Context, Graphics, Size, Transformed}; + +/// The line used to draw the grids lines +const GRID_LINE: Line = Line { + color: [1., 1., 1., 0.3], + radius: 1.2, + shape: Shape::Square, +}; + +pub struct InfiniteGrid(Grid); + +impl InfiniteGrid { + pub fn new(transform: &Transform, draw_size: Size) -> InfiniteGrid { + /* Create a grid with two extra columns and rows per draw_size, so when the user moves the + * grid up and down they can be seen, before the grid position is reset to create the + * infinitness illusion. + * The +3 instead of the +2 is necessary, since the amount needed may be underestimated + * because of rounding errors (I think) + */ + InfiniteGrid(Grid { + cols: (draw_size.width / transform.pixels_per_m()) as u32 + 3, + rows: (draw_size.height / transform.pixels_per_m()) as u32 + 3, + units: transform.pixels_per_m(), + }) + } + + // TODO: Yes, this is ugly af + pub fn on_scale_change(&mut self, transform: &Transform, draw_size: Size) { + self.0.cols = (draw_size.width / transform.pixels_per_m()) as u32 + 3; + self.0.rows = (draw_size.height / transform.pixels_per_m()) as u32 + 3; + self.0.units = transform.pixels_per_m() + } + + pub fn draw(&self, map_trans: &Transform, context: &Context, g: &mut G) + where + G: Graphics, + { + /* Since mouse movement is actually always provided as whole pixels, this is fine. + * the - cell_size (i.e. pixels_per_m) is provided, so that the grid is centered in the + * screen,and not at position 0.x, 0.x, which would mean there would be no row at the top + * and/or no column to the left. + */ + let actual_trans_px = [ + (map_trans.translation_px()[0] as i64 % self.0.units as i64) as f64 + - map_trans.pixels_per_m(), + (map_trans.translation_px()[1] as i64 % self.0.units as i64) as f64 + - map_trans.pixels_per_m(), + ]; + + self.0.draw( + &GRID_LINE, + &context.draw_state, + context.trans_pos(actual_trans_px).transform, + g, + ); + } +} -- cgit v1.2.3-70-g09d2