diff --git a/src/game/mod.rs b/src/game/mod.rs index 5ff5bed..df12b4e 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -80,28 +80,28 @@ impl Game { } // Chunk position - if self.prev_chunk_pos == None || self.prev_chunk_pos != Some(chunk_pos) { - renderer.get_ui().set_text("World", 2, format!("Chunk: {}, {}, {}", chunk_pos.x, chunk_pos.y, chunk_pos.z)); + // if self.prev_chunk_pos == None || self.prev_chunk_pos != Some(chunk_pos) { + // renderer.get_ui().set_text("World", 2, format!("Chunk: {}, {}, {}", chunk_pos.x, chunk_pos.y, chunk_pos.z)); - let dir = chunk_pos - self.prev_chunk_pos.unwrap_or(chunk_pos); //TODO: clamp to -1,1 - if dir.x != 0 || dir.y != 0 || dir.z != 0 { + // let dir = chunk_pos - self.prev_chunk_pos.unwrap_or(chunk_pos); //TODO: clamp to -1,1 + // if dir.x != 0 || dir.y != 0 || dir.z != 0 { - // Shift world - renderer.shift(dir * world::chunk::SIZE as i32); + // // Shift world + // renderer.shift(dir * world::chunk::SIZE as i32); - // Load chunks at the edge - let center = chunk_pos.clone() + RENDER_DIST*dir; - let mask = Vector3{x: dir.x.abs(), y: dir.y.abs(), z: dir.z.abs()}; - println!("Load at {:?}", center); + // // Load chunks at the edge + // let center = chunk_pos.clone() + RENDER_DIST*dir; + // let mask = Vector3{x: dir.x.abs(), y: dir.y.abs(), z: dir.z.abs()}; + // println!("Load at {:?}", center); - for a in -RENDER_DIST..RENDER_DIST+1 { - let pos = center + Vector3{x: mask.z*a, y: 0, z: mask.x*a}; - self.world.load_chunk(pos); - } - } - self.prev_chunk_pos = Some(chunk_pos); - } + // for a in -RENDER_DIST..RENDER_DIST+1 { + // let pos = center + Vector3{x: mask.z*a, y: 0, z: mask.x*a}; + // self.world.load_chunk(pos); + // } + // } + // self.prev_chunk_pos = Some(chunk_pos); + // } // Send dirty chunks to renderer // TODO: Unload chunks above certain radius diff --git a/src/game/world/chunk.rs b/src/game/world/chunk.rs index 779ba5c..72020f7 100644 --- a/src/game/world/chunk.rs +++ b/src/game/world/chunk.rs @@ -56,35 +56,16 @@ impl WorldChunk { // Blocks let mut block_bytes = vec![0_u8; num_blocks*block::SIZE_QB]; - lz4::decompress(&block_bytes_compressed, &mut block_bytes[0..num_blocks*block::SIZE_QB]).unwrap(); - let block_bytes = Arc::new(block_bytes); - - // Spawn workers - let (tx, rx) = mpsc::channel(); - let per_worker = num_blocks / NUM_WORKERS; - let mut workers = vec![]; - for t in 0..NUM_WORKERS { - let by = block_bytes.clone(); - let tx = tx.clone(); - - // Each worker will process their part - workers.push(thread::spawn(move || { - for i in t*per_worker..(t+1)*per_worker { - let mut block = WorldBlock::new(); - let idx = i * block::SIZE_QB; - block.materials.clone_from_slice(&by[idx..idx+block::SIZE_QB]); - tx.send((i, block)).unwrap(); - } - })); + if lz4::decompress(&block_bytes_compressed, &mut block_bytes[0..num_blocks*block::SIZE_QB]).is_err() { + } - // Wait for workers to finish. - for handle in workers { handle.join().unwrap(); } - let mut blocks: Vec<(usize, WorldBlock)> = rx.try_iter().collect(); - - // Sort and add result blocks to chunk - blocks.sort_by(|a, b| (*a).0.cmp(&(*b).0)); - for b in blocks { instance.blocks.push(b.1); } + for i in 0..num_blocks { + let mut block = WorldBlock::new(); + let idx = i * block::SIZE_QB; + block.materials.clone_from_slice(&block_bytes[idx..idx+block::SIZE_QB]); + instance.blocks.push(block); + } instance } diff --git a/src/game/world/loader.rs b/src/game/world/loader.rs index 79ac29f..44aba4a 100644 --- a/src/game/world/loader.rs +++ b/src/game/world/loader.rs @@ -61,7 +61,7 @@ impl ChunkLoader { * Schedule loading chunks */ pub fn load(&mut self, pos: ChunkPos) { - self.queue.send(pos); + self.queue.send(pos).unwrap(); } /* diff --git a/src/renderer/buffers/nodes.rs b/src/renderer/buffers/nodes.rs index a9d7cc9..785d007 100644 --- a/src/renderer/buffers/nodes.rs +++ b/src/renderer/buffers/nodes.rs @@ -1,8 +1,3 @@ -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::Arc; -use std::thread::JoinHandle; -use std::sync::Mutex; -use std::thread; use std::cmp::{min, max}; use cgmath::Vector3; use byteorder::{LittleEndian, ByteOrder}; @@ -13,46 +8,33 @@ pub const NODE_TEX_SIZE_QB: usize = NODE_TEX_SIZE*NODE_TEX_SIZE*NODE_TEX_SIZE; pub struct Nodes { - node_buffer_a: Mutex>, - node_buffer_b: Mutex>, - active_buffer: u8, - busy: Arc, + node_buffer: [Box<[u32]>; 2], + active_buffer: usize, modified: bool, } impl Nodes { pub fn new() -> Self { Self { - node_buffer_a: Mutex::new(vec![0_u32; NODE_TEX_SIZE_QB].into_boxed_slice()), - node_buffer_b: Mutex::new(vec![0_u32; NODE_TEX_SIZE_QB].into_boxed_slice()), + node_buffer: [vec![0_u32; NODE_TEX_SIZE_QB].into_boxed_slice(), vec![0_u32; NODE_TEX_SIZE_QB].into_boxed_slice()], active_buffer: 0, - busy: Arc::new(AtomicBool::new(false)), modified: false, } } pub fn get_node(&self, index: usize) -> u32 { - if self.active_buffer == 0 { self.node_buffer_a.lock().unwrap()[index] } - else { self.node_buffer_b.lock().unwrap()[index] } + self.node_buffer[self.active_buffer][index] } pub fn set_node(&mut self, index: usize, value: u32) { - if self.active_buffer == 0 { self.node_buffer_a.lock().unwrap()[index] = value; } - else { self.node_buffer_b.lock().unwrap()[index] = value; } - self.modified = true; + self.node_buffer[self.active_buffer][index] = value; } pub fn shift(&mut self, offset: &Vector3) -> bool { - // Prevent shifting if busy - if self.busy.load(Ordering::Relaxed) { - return false; - } - // Perform shift - self.busy.store(true, Ordering::Relaxed); + let a = if self.active_buffer == 0 { 0 } else { 1 }; + let b = if self.active_buffer == 0 { 1 } else { 0 }; - let from = if self.active_buffer == 0 { self.node_buffer_a.lock().unwrap() } else { self.node_buffer_b.lock().unwrap() }; - let mut to = if self.active_buffer == 0 { self.node_buffer_b.lock().unwrap() } else { self.node_buffer_a.lock().unwrap() }; let (ox, oy, oz) = (offset.x, offset.y, offset.z); let size = NODE_TEX_SIZE as i32; @@ -61,27 +43,20 @@ impl Nodes { for z in max(0, -oz)..min(size-oz, size) { let idx0 = x + size * (y + size * z); let idx1 = (x+ox) + size * ((y+oy) + size * (z+oz)); - to[idx1 as usize] = from[idx0 as usize]; + self.node_buffer[b][idx1 as usize] = self.node_buffer[a][idx0 as usize]; } } } - self.active_buffer = !self.active_buffer; + self.active_buffer = b; self.modified = true; - self.busy.store(false, Ordering::Relaxed); - true } pub fn update(&mut self, queue: &wgpu::Queue, texture: &wgpu::Texture) { - if self.modified && !self.busy.load(Ordering::Relaxed) { + if self.modified { self.modified = false; - // Select target node buffer - let node_buffer; - if self.active_buffer == 0 { node_buffer = &self.node_buffer_a; } - else { node_buffer = &self.node_buffer_b; } - // Write all nodes to gpu for z in 0..NODE_TEX_SIZE { @@ -90,7 +65,7 @@ impl Nodes { let node_size = wgpu::Extent3d { width: NODE_TEX_SIZE as u32, height: NODE_TEX_SIZE as u32, depth: 1 }; let mut node_bytes = [0_u8; NODE_TEX_SIZE_SQ*4]; let offset = NODE_TEX_SIZE_SQ*z; - LittleEndian::write_u32_into(&node_buffer.lock().unwrap()[offset..offset+NODE_TEX_SIZE_SQ], &mut node_bytes); + LittleEndian::write_u32_into(&self.node_buffer[self.active_buffer][offset..offset+NODE_TEX_SIZE_SQ], &mut node_bytes); // Write nodes queue.write_texture(