From d68cf09f7b8e5cb783dc495097c17eaf2a4d5427 Mon Sep 17 00:00:00 2001 From: Kai Stevenson Date: Mon, 31 Aug 2026 00:03:32 -0700 Subject: cleanup --- src/proc_gen/mod.rs | 101 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 66 insertions(+), 35 deletions(-) (limited to 'src/proc_gen/mod.rs') diff --git a/src/proc_gen/mod.rs b/src/proc_gen/mod.rs index 049ad1a..caec241 100644 --- a/src/proc_gen/mod.rs +++ b/src/proc_gen/mod.rs @@ -6,66 +6,97 @@ use glam::IVec2; use crate::{ config::{CHUNK_SIZE, TILESET_SCALING}, proc_gen::{ - herringbone::tiles_overlapping, + herringbone::{tiles_overlapping, variant_index}, tileset_loader::{Tile, TileOrientation, Tileset, load_tileset}, }, sim::{cell::Cell, cell_manager::chunk::Chunk, entity::EntityDef}, }; +pub struct TileCells { + pub size: IVec2, + pub cells: Vec, +} + pub trait Biome { - fn derive_world_from_tile(&self, _tile: &Tile) -> Vec { - Vec::new() - } - fn derive_entities_from_tile(&self, _tile: &Tile) -> Vec { + fn derive_world_from_tile(&self, tile: &Tile) -> TileCells; + fn derive_entities_from_tile(&self, tile: &Tile) -> Vec { Vec::new() } } pub struct TilesetWorldGenerator { tileset: Tileset, - biome: Box, + horizontal_tiles: Vec, + vertical_tiles: Vec, } impl TilesetWorldGenerator { + pub fn new(tileset_path: &str, biome: &dyn Biome) -> Self { + let tileset = load_tileset(tileset_path); + + let horizontal_tiles = tileset + .horizontal_tiles + .iter() + .map(|tile| biome.derive_world_from_tile(tile)) + .collect(); + let vertical_tiles = tileset + .vertical_tiles + .iter() + .map(|tile| biome.derive_world_from_tile(tile)) + .collect(); + + TilesetWorldGenerator { + tileset, + horizontal_tiles, + vertical_tiles, + } + } + + fn grid_size(&self) -> IVec2 { + IVec2::splat(self.tileset.dimensions.short as i32 * TILESET_SCALING) + } + + fn tile_at(&self, grid: IVec2, orientation: TileOrientation) -> &TileCells { + let tiles = match orientation { + TileOrientation::Horizontal => &self.horizontal_tiles, + TileOrientation::Vertical => &self.vertical_tiles, + }; + &tiles[variant_index(grid, tiles.len())] + } + pub fn generate_chunk(&self, chunk_position: IVec2) -> Chunk { let mut chunk = Chunk::void(); - let a = chunk_position * CHUNK_SIZE; - let b = (chunk_position + 1) * CHUNK_SIZE; - let tiles = tiles_overlapping(a * TILESET_SCALING, b * TILESET_SCALING, &self.tileset); - let world_tiles = tiles.map(|(p, t, o)| (p, self.biome.derive_world_from_tile(t), o)); + let chunk_min = chunk_position * CHUNK_SIZE; + let chunk_max = chunk_min + CHUNK_SIZE; + + let grid = self.grid_size(); + let tiles = tiles_overlapping( + chunk_min.div_euclid(grid), + (chunk_max - 1).div_euclid(grid) + 1, + ); - for (tp, t, o) in world_tiles { - let p = tp * self.tileset.dimensions.short as i32 * TILESET_SCALING; - let ta = p.max(a); - let tb = p.min(b); - if ta.x >= tb.x || ta.y >= tb.y { + for (grid_position, orientation) in tiles { + let tile = self.tile_at(grid_position, orientation); + let tile_min = grid_position * grid; + + // subset of tile in chunk + let min = tile_min.max(chunk_min); + let max = (tile_min + tile.size).min(chunk_max); + if min.x >= max.x { continue; } + let width = (max.x - min.x) as usize; - for y in ta.y..tb.y { - for x in ta.x..tb.x { - let sw = match o { - TileOrientation::Horizontal => { - self.tileset.dimensions.long as i32 * TILESET_SCALING - } - TileOrientation::Vertical => { - self.tileset.dimensions.short as i32 * TILESET_SCALING - } - }; - - let src = (y - p.y) * sw + (x - p.x); - let dst = (y - a.y) * CHUNK_SIZE + (x - a.x); - chunk.cells[dst as usize] = t[src as usize]; - } + for y in min.y..max.y { + let src = ((y - tile_min.y) * tile.size.x + (min.x - tile_min.x)) as usize; + let dst = ((y - chunk_min.y) * CHUNK_SIZE + (min.x - chunk_min.x)) as usize; + chunk.cells[dst..dst + width].copy_from_slice(&tile.cells[src..src + width]); } } - chunk - } + chunk.mark_collider_dirty(0); - pub fn new(tileset_path: &str, biome: Box) -> Self { - let tileset = load_tileset(tileset_path); - TilesetWorldGenerator { tileset, biome } + chunk } } -- cgit v1.3.1