1use crate::Project;
2
3#[derive(Clone, Default, Debug)]
4pub struct Point(pub usize, pub usize);
5
6impl From<(usize, usize)> for Point {
7 fn from(tup: (usize, usize)) -> Self {
8 Point(tup.0, tup.1)
9 }
10}
11
12pub fn grid_point_to_coord(point: Point, grid_width: usize) -> usize {
14 point.0 + point.1 * grid_width
15}
16
17pub fn grid_coord_to_point(coord: usize, grid_width: usize) -> Point {
19 let grid_y = coord / grid_width;
20 Point(coord - grid_y * grid_width, coord / grid_width)
21}
22
23pub fn tile_id_to_atlas_pixel(
25 tile_id: usize,
26 atlas_width: usize,
27 grid_width: usize,
28 padding: usize,
29 spacing: usize,
30) -> Point {
31 let grid_x = tile_id - atlas_width * (tile_id / atlas_width);
32 let grid_y = tile_id / atlas_width;
33
34 Point(
35 padding + grid_x * (grid_width + spacing),
36 padding + grid_y * (grid_width + spacing),
37 )
38}
39
40#[derive(Clone, Debug)]
41pub struct RenderCell {
42 pub is_empty: bool,
43 pub tile_id: usize,
44 pub atlas_pos: Point,
45}
46
47#[derive(Debug)]
48pub struct RenderGrid {
49 pub tiles: Vec<RenderCell>,
50 pub tile_size: Point,
51 pub grid_size: Point,
52}
53
54impl RenderGrid {
55 pub fn new(num_cells: usize, tile_size: Point, grid_size: Point) -> Self {
56 RenderGrid {
57 tiles: vec![
58 RenderCell {
59 is_empty: true,
60 tile_id: 0,
61 atlas_pos: Point::default(),
62 };
63 num_cells
64 ],
65 tile_size,
66 grid_size,
67 }
68 }
69
70 pub fn get_tile(&self, x: usize, y: usize) -> &RenderCell {
71 let coord_id = grid_point_to_coord((x, y).into(), self.grid_size.0);
72 &self.tiles[coord_id]
73 }
74
75 pub fn rows(&self) -> std::slice::Chunks<'_, RenderCell> {
77 self.tiles.chunks(self.grid_size.0)
78 }
79}
80
81pub trait ToRenderGrid {
82 fn to_merged_render_grid(&self, level: usize) -> Result<RenderGrid, anyhow::Error>;
85
86 }
88
89impl ToRenderGrid for Project {
90 fn to_merged_render_grid(&self, level: usize) -> Result<RenderGrid, anyhow::Error> {
91 if self.levels.len() < level {
92 panic!("Level not found in the parsed map");
93 }
94
95 let level = &self.levels[level];
96
97 let first_layer = &level.layer_instances[0];
99 let cell_count = first_layer.grid_width * first_layer.grid_height;
100 let mut grid = RenderGrid::new(
101 cell_count,
102 Point(16, 16),
103 Point(first_layer.grid_width, first_layer.grid_height),
104 );
105
106 level.layer_instances.iter().rev().for_each(|layer| {
108 layer.auto_tiles.iter().for_each(|rule| {
109 rule.tiles.iter().for_each(|tile| {
110 grid.tiles[tile.coord_id].is_empty = false;
111 grid.tiles[tile.coord_id].tile_id = tile.tile_id;
112 grid.tiles[tile.coord_id].atlas_pos.0 = tile.tile_x;
113 grid.tiles[tile.coord_id].atlas_pos.1 = tile.tile_y;
114 })
115 });
116
117 layer.grid_tiles.iter().for_each(|tile| {
118 grid.tiles[tile.coord_id].is_empty = false;
119 grid.tiles[tile.coord_id].tile_id = tile.tile_id;
120 grid.tiles[tile.coord_id].atlas_pos.0 = tile.tile_x;
121 grid.tiles[tile.coord_id].atlas_pos.1 = tile.tile_x;
122 })
123 });
124
125 Ok(grid)
126 }
127}