From 217ec33413290858a07dd267ebd1a93b695094c5 Mon Sep 17 00:00:00 2001 From: Thinkofname Date: Mon, 21 Mar 2016 16:51:19 +0000 Subject: [PATCH] Render chunks nearest to the player first --- src/chunk_builder.rs | 34 ++++++++++++++++++++++++++++++++-- src/main.rs | 2 +- src/world/mod.rs | 18 +++++++++++++----- 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/chunk_builder.rs b/src/chunk_builder.rs index 130206e..a4e18e2 100644 --- a/src/chunk_builder.rs +++ b/src/chunk_builder.rs @@ -13,6 +13,9 @@ pub struct ChunkBuilder { threads: Vec<(mpsc::Sender, thread::JoinHandle<()>)>, free_builders: Vec, built_recv: mpsc::Receiver<(usize, BuildReply)>, + + sections: Vec<(i32, i32, i32)>, + next_collection: f64, } impl ChunkBuilder { @@ -32,6 +35,8 @@ impl ChunkBuilder { threads: threads, free_builders: free, built_recv: built_recv, + sections: vec![], + next_collection: 0.0, } } @@ -42,7 +47,8 @@ impl ChunkBuilder { } } - pub fn tick(&mut self, world: &mut world::World, renderer: &mut render::Renderer) { + pub fn tick(&mut self, world: &mut world::World, renderer: &mut render::Renderer, delta: f64) { + use std::cmp::Ordering; while let Ok((id, val)) = self.built_recv.try_recv() { world.reset_building_flag(val.position); @@ -53,8 +59,32 @@ impl ChunkBuilder { if self.free_builders.is_empty() { return; } - while let Some((x, y, z)) = world.next_dirty_chunk_section() { + self.next_collection -= delta; + if self.next_collection <= 0.0 { + let mut sections = world.get_dirty_chunk_sections(); + sections.sort_by(|a, b| { + let xx = ((a.0<<4)+8) as f64 - renderer.camera.pos.x; + let yy = ((a.1<<4)+8) as f64 - renderer.camera.pos.y; + let zz = ((a.2<<4)+8) as f64 - renderer.camera.pos.z; + let a_dist = xx*xx + yy*yy + zz*zz; + let xx = ((b.0<<4)+8) as f64 - renderer.camera.pos.x; + let yy = ((b.1<<4)+8) as f64 - renderer.camera.pos.y; + let zz = ((b.2<<4)+8) as f64 - renderer.camera.pos.z; + let b_dist = xx*xx + yy*yy + zz*zz; + if a_dist == b_dist { + Ordering::Equal + } else if a_dist > b_dist { + Ordering::Less + } else { + Ordering::Greater + } + }); + self.sections = sections; + self.next_collection = 60.0; + } + while let Some((x, y, z)) = self.sections.pop() { let t_id = self.free_builders.pop().unwrap(); + world.set_building_flag((x, y, z)); let (cx, cy, cz) = (x << 4, y << 4, z << 4); let mut snapshot = world.capture_snapshot(cx - 2, cy - 2, cz - 2, 20, 20, 20); snapshot.make_relative(-2, -2, -2); diff --git a/src/main.rs b/src/main.rs index 11d1bd0..0790817 100644 --- a/src/main.rs +++ b/src/main.rs @@ -210,7 +210,7 @@ fn main() { game.tick(delta); game.server.tick(&mut game.renderer, delta); - game.chunk_builder.tick(&mut game.server.world, &mut game.renderer); + game.chunk_builder.tick(&mut game.server.world, &mut game.renderer, delta); game.screen_sys.tick(delta, &mut game.renderer, &mut ui_container); game.console diff --git a/src/world/mod.rs b/src/world/mod.rs index 078dc35..96653e3 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -47,19 +47,27 @@ impl World { } } - pub fn next_dirty_chunk_section(&mut self) -> Option<(i32, i32, i32)> { + pub fn get_dirty_chunk_sections(&mut self) -> Vec<(i32, i32, i32)> { + let mut out = vec![]; for (_, chunk) in &mut self.chunks { for sec in &mut chunk.sections { if let Some(sec) = sec.as_mut() { if !sec.building && sec.dirty { - sec.building = true; - sec.dirty = false; - return Some((chunk.position.0, sec.y as i32, chunk.position.1)); + out.push((chunk.position.0, sec.y as i32, chunk.position.1)); } } } } - None + out + } + + pub fn set_building_flag(&mut self, pos: (i32, i32, i32)) { + if let Some(chunk) = self.chunks.get_mut(&CPos(pos.0, pos.2)) { + if let Some(sec) = chunk.sections[pos.1 as usize].as_mut() { + sec.building = true; + sec.dirty = false; + } + } } pub fn reset_building_flag(&mut self, pos: (i32, i32, i32)) {