From b3cdde3ce99c61942535696db045c102c2861171 Mon Sep 17 00:00:00 2001 From: Imbris Date: Fri, 17 Jan 2020 23:05:26 -0500 Subject: [PATCH] fix: panic in terrain meshing --- CHANGELOG.md | 1 + voxygen/src/mesh/terrain.rs | 5 ++- voxygen/src/scene/terrain.rs | 82 ++++++++++++++++++------------------ 3 files changed, 46 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ed94cfcce..576ed42aa2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Made shadows and lights use interpolated positions - Changed "Create Character" button position - Made clouds bigger, more performant and prettier +- Terrain meshing optimized further ### Removed diff --git a/voxygen/src/mesh/terrain.rs b/voxygen/src/mesh/terrain.rs index 095cdb19f5..7b6e8fb069 100644 --- a/voxygen/src/mesh/terrain.rs +++ b/voxygen/src/mesh/terrain.rs @@ -243,7 +243,10 @@ impl + ReadVol + Debug> Meshable Terrain { .map(|(p, _)| *p) { let chunk_pos = client.state().terrain().pos_key(pos); - let new_mesh_state = ChunkMeshState { - pos: chunk_pos, - started_tick: current_tick, - active_worker: None, - }; // Only mesh if this chunk has all its neighbors - // If it does have all its neighbors either it should have already been meshed or is in - // mesh_todo - match self.mesh_todo.entry(chunk_pos) { - Entry::Occupied(mut entry) => { - entry.insert(new_mesh_state); - } - Entry::Vacant(entry) => { - if self.chunks.contains_key(&chunk_pos) { - entry.insert(new_mesh_state); - } + let mut neighbours = true; + for i in -1..2 { + for j in -1..2 { + neighbours &= client + .state() + .terrain() + .get_key(chunk_pos + Vec2::new(i, j)) + .is_some(); } } + if neighbours { + self.mesh_todo.insert( + chunk_pos, + ChunkMeshState { + pos: chunk_pos, + started_tick: current_tick, + active_worker: None, + }, + ); + } // Handle block changes on chunk borders + // Remesh all neighbours because we have complex lighting now + // TODO: if lighting is on the server this can be updated to only remesh when lighting + // changes in that neighbouring chunk or if the block change was on the border for x in -1..2 { for y in -1..2 { let neighbour_pos = pos + Vec3::new(x, y, 0); let neighbour_chunk_pos = client.state().terrain().pos_key(neighbour_pos); if neighbour_chunk_pos != chunk_pos { - let new_mesh_state = ChunkMeshState { - pos: neighbour_chunk_pos, - started_tick: current_tick, - active_worker: None, - }; - // Only mesh if this chunk has all its neighbors - match self.mesh_todo.entry(neighbour_chunk_pos) { - Entry::Occupied(mut entry) => { - entry.insert(new_mesh_state); - } - Entry::Vacant(entry) => { - if self.chunks.contains_key(&neighbour_chunk_pos) { - entry.insert(new_mesh_state); - } + // Only remesh if this chunk has all its neighbors + let mut neighbours = true; + for i in -1..2 { + for j in -1..2 { + neighbours &= client + .state() + .terrain() + .get_key(neighbour_chunk_pos + Vec2::new(i, j)) + .is_some(); } } + if neighbours { + self.mesh_todo.insert( + neighbour_chunk_pos, + ChunkMeshState { + pos: neighbour_chunk_pos, + started_tick: current_tick, + active_worker: None, + }, + ); + } } - - // TODO: Remesh all neighbours because we have complex lighting now - /*self.mesh_todo.insert( - neighbour_chunk_pos, - ChunkMeshState { - pos: chunk_pos + Vec2::new(x, y), - started_tick: current_tick, - active_worker: None, - }, - ); - */ } } }