mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
fix: panic in terrain meshing
This commit is contained in:
parent
5666f18ded
commit
b3cdde3ce9
@ -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
|
- Made shadows and lights use interpolated positions
|
||||||
- Changed "Create Character" button position
|
- Changed "Create Character" button position
|
||||||
- Made clouds bigger, more performant and prettier
|
- Made clouds bigger, more performant and prettier
|
||||||
|
- Terrain meshing optimized further
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
@ -243,7 +243,10 @@ impl<V: RectRasterableVol<Vox = Block> + ReadVol + Debug> Meshable<TerrainPipeli
|
|||||||
for x in 0..range.size().w {
|
for x in 0..range.size().w {
|
||||||
for y in 0..range.size().h {
|
for y in 0..range.size().h {
|
||||||
for z in -1..range.size().d + 1 {
|
for z in -1..range.size().d + 1 {
|
||||||
let block = *volume.get(range.min + Vec3::new(x, y, z)).unwrap();
|
let block = volume
|
||||||
|
.get(range.min + Vec3::new(x, y, z))
|
||||||
|
.map(|b| *b)
|
||||||
|
.unwrap_or(Block::empty());
|
||||||
if block.is_opaque() {
|
if block.is_opaque() {
|
||||||
lowest_opaque = lowest_opaque.min(z);
|
lowest_opaque = lowest_opaque.min(z);
|
||||||
highest_opaque = highest_opaque.max(z);
|
highest_opaque = highest_opaque.max(z);
|
||||||
|
@ -16,7 +16,7 @@ use common::{
|
|||||||
};
|
};
|
||||||
use crossbeam::channel;
|
use crossbeam::channel;
|
||||||
use dot_vox::DotVoxData;
|
use dot_vox::DotVoxData;
|
||||||
use hashbrown::{hash_map::Entry, HashMap};
|
use hashbrown::HashMap;
|
||||||
use std::{f32, fmt::Debug, i32, marker::PhantomData, time::Duration};
|
use std::{f32, fmt::Debug, i32, marker::PhantomData, time::Duration};
|
||||||
use treeculler::{BVol, Frustum, AABB};
|
use treeculler::{BVol, Frustum, AABB};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
@ -837,60 +837,60 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
.map(|(p, _)| *p)
|
.map(|(p, _)| *p)
|
||||||
{
|
{
|
||||||
let chunk_pos = client.state().terrain().pos_key(pos);
|
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
|
// 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
|
let mut neighbours = true;
|
||||||
// mesh_todo
|
for i in -1..2 {
|
||||||
match self.mesh_todo.entry(chunk_pos) {
|
for j in -1..2 {
|
||||||
Entry::Occupied(mut entry) => {
|
neighbours &= client
|
||||||
entry.insert(new_mesh_state);
|
.state()
|
||||||
}
|
.terrain()
|
||||||
Entry::Vacant(entry) => {
|
.get_key(chunk_pos + Vec2::new(i, j))
|
||||||
if self.chunks.contains_key(&chunk_pos) {
|
.is_some();
|
||||||
entry.insert(new_mesh_state);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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
|
// 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 x in -1..2 {
|
||||||
for y in -1..2 {
|
for y in -1..2 {
|
||||||
let neighbour_pos = pos + Vec3::new(x, y, 0);
|
let neighbour_pos = pos + Vec3::new(x, y, 0);
|
||||||
let neighbour_chunk_pos = client.state().terrain().pos_key(neighbour_pos);
|
let neighbour_chunk_pos = client.state().terrain().pos_key(neighbour_pos);
|
||||||
|
|
||||||
if neighbour_chunk_pos != chunk_pos {
|
if neighbour_chunk_pos != chunk_pos {
|
||||||
let new_mesh_state = ChunkMeshState {
|
// Only remesh if this chunk has all its neighbors
|
||||||
pos: neighbour_chunk_pos,
|
let mut neighbours = true;
|
||||||
started_tick: current_tick,
|
for i in -1..2 {
|
||||||
active_worker: None,
|
for j in -1..2 {
|
||||||
};
|
neighbours &= client
|
||||||
// Only mesh if this chunk has all its neighbors
|
.state()
|
||||||
match self.mesh_todo.entry(neighbour_chunk_pos) {
|
.terrain()
|
||||||
Entry::Occupied(mut entry) => {
|
.get_key(neighbour_chunk_pos + Vec2::new(i, j))
|
||||||
entry.insert(new_mesh_state);
|
.is_some();
|
||||||
}
|
|
||||||
Entry::Vacant(entry) => {
|
|
||||||
if self.chunks.contains_key(&neighbour_chunk_pos) {
|
|
||||||
entry.insert(new_mesh_state);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user