improvement: fog doesn't go back and forth anymore

This commit is contained in:
timokoesters
2020-01-12 12:09:37 +01:00
committed by Imbris
parent b3cdde3ce9
commit ae1fa5e4c4
3 changed files with 25 additions and 15 deletions

View File

@ -69,7 +69,7 @@ pub struct Client {
entity: EcsEntity, entity: EcsEntity,
view_distance: Option<u32>, view_distance: Option<u32>,
loaded_distance: Option<u32>, loaded_distance: f32,
pending_chunks: HashMap<Vec2<i32>, Instant>, pending_chunks: HashMap<Vec2<i32>, Instant>,
} }
@ -153,7 +153,7 @@ impl Client {
state, state,
entity, entity,
view_distance, view_distance,
loaded_distance: None, loaded_distance: 0.0,
pending_chunks: HashMap::new(), pending_chunks: HashMap::new(),
}) })
@ -260,7 +260,7 @@ impl Client {
self.view_distance self.view_distance
} }
pub fn loaded_distance(&self) -> Option<u32> { pub fn loaded_distance(&self) -> f32 {
self.loaded_distance self.loaded_distance
} }
@ -410,8 +410,9 @@ impl Client {
} }
// Request chunks from the server. // Request chunks from the server.
let mut all_loaded = true; self.loaded_distance = ((view_distance * TerrainChunkSize::RECT_SIZE.x) as f32).powi(2);
'outer: for dist in 0..(view_distance as i32) + 1 { // +1 so we can find a chunk that's outside the vd for better fog
for dist in 0..view_distance as i32 + 1 {
// Only iterate through chunks that need to be loaded for circular vd // Only iterate through chunks that need to be loaded for circular vd
// The (dist - 2) explained: // The (dist - 2) explained:
// -0.5 because a chunk is visible if its corner is within the view distance // -0.5 because a chunk is visible if its corner is within the view distance
@ -428,6 +429,7 @@ impl Client {
dist dist
}; };
let mut skip_mode = false;
for i in -top..top + 1 { for i in -top..top + 1 {
let keys = [ let keys = [
chunk_pos + Vec2::new(dist, i), chunk_pos + Vec2::new(dist, i),
@ -438,25 +440,32 @@ impl Client {
for key in keys.iter() { for key in keys.iter() {
if self.state.terrain().get_key(*key).is_none() { if self.state.terrain().get_key(*key).is_none() {
if !self.pending_chunks.contains_key(key) { if !skip_mode && !self.pending_chunks.contains_key(key) {
if self.pending_chunks.len() < 4 { if self.pending_chunks.len() < 4 {
self.postbox self.postbox
.send_message(ClientMsg::TerrainChunkRequest { key: *key }); .send_message(ClientMsg::TerrainChunkRequest { key: *key });
self.pending_chunks.insert(*key, Instant::now()); self.pending_chunks.insert(*key, Instant::now());
} else { } else {
break 'outer; skip_mode = true;
} }
} }
all_loaded = false; let dist_to_player =
(self.state.terrain().key_pos(*key).map(|x| x as f32)
+ TerrainChunkSize::RECT_SIZE.map(|x| x as f32) / 2.0)
.distance_squared(pos.0.into());
if dist_to_player < self.loaded_distance {
self.loaded_distance = dist_to_player;
}
} }
} }
} }
if all_loaded {
self.loaded_distance = Some((dist - 1).max(0) as u32);
}
} }
self.loaded_distance = self.loaded_distance.sqrt()
- ((TerrainChunkSize::RECT_SIZE.x as f32 / 2.0).powi(2)
+ (TerrainChunkSize::RECT_SIZE.y as f32 / 2.0).powi(2))
.sqrt();
// If chunks are taking too long, assume they're no longer pending. // If chunks are taking too long, assume they're no longer pending.
let now = Instant::now(); let now = Instant::now();

View File

@ -1433,8 +1433,9 @@ impl Hud {
.set(self.ids.velocity, ui_widgets); .set(self.ids.velocity, ui_widgets);
// Loaded distance // Loaded distance
Text::new(&format!( Text::new(&format!(
"View distance: {} chunks", "View distance: {:.2} blocks ({:.2} chunks)",
client.loaded_distance().unwrap_or(0) client.loaded_distance(),
client.loaded_distance() / TerrainChunk::RECT_SIZE.x as f32,
)) ))
.color(TEXT_COLOR) .color(TEXT_COLOR)
.down_from(self.ids.velocity, 5.0) .down_from(self.ids.velocity, 5.0)

View File

@ -208,7 +208,7 @@ impl Scene {
let (view_mat, proj_mat, cam_pos) = self.camera.compute_dependents(client); let (view_mat, proj_mat, cam_pos) = self.camera.compute_dependents(client);
// Update chunk loaded distance smoothly for nice shader fog // Update chunk loaded distance smoothly for nice shader fog
let loaded_distance = client.loaded_distance().unwrap_or(0) as f32 * 32.0; // TODO: No magic! let loaded_distance = client.loaded_distance();
self.loaded_distance = (0.98 * self.loaded_distance + 0.02 * loaded_distance).max(0.01); self.loaded_distance = (0.98 * self.loaded_distance + 0.02 * loaded_distance).max(0.01);
// Update light constants // Update light constants