feat: migrate quilter rendering to Bevy TilemapChunk
Replaces the CPU pixel-baking quilter system (QuiltCache, TerrainSprite, pixel_buffers) with Bevy's native TilemapChunk GPU-index-lookup API. Architecture: - TilemapChunk entities replace TerrainSprite entities per (chunk, z, layer) - Tileset PNG stacked vertically as texture_2d_array (11 rows: 6 floor + 5 fixture) - populate_chunk_tiles reads TileMap HashMap directly; no ECS FloorTile entities - Chunk spawn deferred to apply_terrain_blobs (after TileMap data exists) - Dirty key system triggers repopulate on occlusion/camera-z changes Bug fixes: - populate_chunk_tiles: add chunk_pos offset to world tile lookups (was always (0,0)) - spawn_tilemap_chunks: offset Transform by -TILE_SIZE/2 (tile-centre vs bottom-left) - spawn_tilemap_chunks: AlphaMode2d::Blend (was Opaque, blocking DF fade) - update_tilemap_chunk_visibility: actually mutate Visibility (was read-only) - handle_tile_occlusion_updates: mark dirty keys inline (was double-reading events) - TilemapChunkSpawner: deduplicate pending queue and guard stale registry Performance: - ~115K FloorTile ECS entities eliminated - GPU memory: O(tile_data) instead of O(CHUNK_TILES² × z_levels × pixel_bytes) - Z-scroll: only TilemapChunkTileData repopulates (no entity re-spawn) - Benchmarks via TilemapBenchmark resource (F9 to report)
This commit is contained in:
@@ -182,30 +182,11 @@ pub struct TileMap {
|
||||
}
|
||||
|
||||
impl TileMap {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_floor(&self, pos: &IVec3) -> Option<&FloorTileData> {
|
||||
self.floor_tiles.get(pos)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_fixture(&self, pos: &IVec3) -> Option<&FixtureTileData> {
|
||||
self.fixture_tiles.get(pos)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn has_floor(&self, pos: &IVec3) -> bool {
|
||||
self.floor_tiles.contains_key(pos)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn has_fixture(&self, pos: &IVec3) -> bool {
|
||||
self.fixture_tiles.contains_key(pos)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn insert_floor(&mut self, pos: IVec3, tile: FloorTileData) {
|
||||
self.floor_tiles.insert(pos, tile);
|
||||
@@ -242,34 +223,6 @@ impl TileMap {
|
||||
chunk.is_standable(local_x, local_y, z)
|
||||
}
|
||||
|
||||
/// Fallback standability check using HashMap lookups.
|
||||
fn is_standable_slow(&self, pos: IVec3) -> bool {
|
||||
let can_stand_in_floor = self
|
||||
.floor_tiles
|
||||
.get(&pos)
|
||||
.map(|t| t.can_stand_in())
|
||||
.unwrap_or(false);
|
||||
let can_stand_in_fixture = self
|
||||
.fixture_tiles
|
||||
.get(&pos)
|
||||
.map(|t| t.can_stand_in())
|
||||
.unwrap_or(false);
|
||||
|
||||
let pos_below = IVec3::new(pos.x, pos.y, pos.z - crate::constants::ITILE_SIZE);
|
||||
let can_stand_on_floor = self
|
||||
.floor_tiles
|
||||
.get(&pos_below)
|
||||
.map(|t| t.can_stand_on())
|
||||
.unwrap_or(false);
|
||||
let can_stand_on_fixture = self
|
||||
.fixture_tiles
|
||||
.get(&pos_below)
|
||||
.map(|t| t.can_stand_on())
|
||||
.unwrap_or(false);
|
||||
|
||||
(can_stand_in_floor || can_stand_in_fixture) && (can_stand_on_floor || can_stand_on_fixture)
|
||||
}
|
||||
|
||||
/// Get A* pathfinding weight for a tile position.
|
||||
/// Returns 100 (default) if tile not found. Lower is better.
|
||||
pub fn get_astar_weight(&self, world_pos: IVec3) -> u8 {
|
||||
|
||||
Reference in New Issue
Block a user