From 00c518b9c14b9f10c2503975c3d88bae276f47e2 Mon Sep 17 00:00:00 2001 From: Piotrek Date: Fri, 14 May 2021 19:54:46 +0200 Subject: [PATCH] Endless world, still some bugs to figure out --- assets/font.ttf | Bin 58088 -> 28340 bytes src/game/camera_controller.rs | 10 +++- src/game/mod.rs | 106 ++++++++++++++++++++-------------- src/game/world/chunk.rs | 2 - src/game/world/generator.rs | 15 ++++- src/game/world/mod.rs | 1 + src/main.rs | 4 +- src/renderer/camera.rs | 2 +- src/renderer/renderer_view.rs | 11 ++-- 9 files changed, 91 insertions(+), 60 deletions(-) diff --git a/assets/font.ttf b/assets/font.ttf index 9d6519685ea5279857034c8a01a59c2cdbd2b5db..951dccc46390cce6038e0a03acc7d37d3f600238 100644 GIT binary patch literal 28340 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 diff --git a/src/game/camera_controller.rs b/src/game/camera_controller.rs index d99adc7..cdca27d 100644 --- a/src/game/camera_controller.rs +++ b/src/game/camera_controller.rs @@ -42,12 +42,16 @@ impl CameraController { pub fn new() -> Self { Self { enabled: false, - movement: CameraMovement { speed: 2.0, .. CameraMovement::default()}, + movement: CameraMovement { speed: 3.0, .. CameraMovement::default()}, rotation: CameraRotation { yaw: 135.0, sensitivity: 0.2, .. CameraRotation::default() }, - cam_position: (-1.0, 2.0, -1.0).into(), + cam_position: (1.0, 2.0, 1.0).into(), } } + pub fn get_yaw(&self) -> f32 { + self.rotation.yaw + } + pub fn set_enabled(&mut self, enabled: bool) { self.enabled = enabled; } pub fn handle_input(&mut self, event: &Event<()>) -> bool { @@ -105,7 +109,7 @@ impl CameraController { // Movement amount let mut amount = delta_time * self.movement.speed; - if self.movement.shift { amount *= 4.0; } + if self.movement.shift { amount *= 8.0; } // Forward and backwards if self.movement.fwd && cam_forward.magnitude() > amount { self.cam_position += cam_forward.normalize() * amount; } diff --git a/src/game/mod.rs b/src/game/mod.rs index c102c0d..cd839e4 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -24,74 +24,92 @@ pub struct Game { } impl Game { - pub fn new() -> Self { - Self { + pub fn new(renderer: &mut impl RendererView) -> Self { + let mut instance = Self { state: GameState::Paused, player: Player::new(), world: World::init("hello".to_string()), prev_pos: None, prev_chunk_pos: None, + }; + + // Preload chunks around player + for x in -2..2 { + for z in -2..2 { + let pos = Vector3{x, y: 00, z}; + if instance.world.load_chunk(pos) { + let chunk = instance.world.get_chunk(&pos).unwrap(); + chunk.write_to(renderer, pos * world::chunk::SIZE as i32); + println!("Writing chunk to {:?}", pos * world::chunk::SIZE as i32); + } + } } - // // Try to load world from file - // let timer = Instant::now(); - // if app.world.load() { - // for (pos, block) in app.world.all_blocks() { - // content.write(&pos, block); - // } - // println!("Loaded in {}", timer.elapsed().as_secs_f32()); - // } - // // Generate new world - // else { - // let timer = Instant::now(); - // for x in 0..32 { - // for z in 0..32 { - // let pos = &Point3{x,y:0,z}; - // let block = app.world.gen_block(pos); - // content.write(pos, block); - // } - // } - // println!("Generated in {}", timer.elapsed().as_secs_f32()); - - // let timer = Instant::now(); - // app.world.save(); - // println!("Saved in {}", timer.elapsed().as_secs_f32()); - // } + // Return generated instance + instance } pub fn update(&mut self, delta: f32, renderer: &mut impl RendererView) { - // Update camera controller + // Update camera let camera = renderer.get_camera_transform(); self.player.camera_controller.update(delta, camera); // Get positions - let pos = camera.get_position(); - let pos = Vector3{x: pos.x as i32, y: pos.y as i32, z: pos.z as i32}; - let mut chunk_pos = pos / world::chunk::SIZE as i32; - if pos.x < 0 { chunk_pos.x -= 1; } - if pos.y < 0 { chunk_pos.y -= 1; } - if pos.z < 0 { chunk_pos.z -= 1; } + let cam_pos = camera.get_position(); + let cam_pos = Vector3{x: cam_pos.x as i32, y: cam_pos.y as i32, z: cam_pos.z as i32}; + let mut chunk_pos = cam_pos / world::chunk::SIZE as i32; + if cam_pos.x < 0 { chunk_pos.x -= 1; } + if cam_pos.y < 0 { chunk_pos.y -= 1; } + if cam_pos.z < 0 { chunk_pos.z -= 1; } + + // Update pointing direction + let yaw = self.player.camera_controller.get_yaw(); + let mut yaw_str = ""; + if yaw >= 315.0 || yaw <= 45.0 { yaw_str = "+z"; } + else if yaw >= 45.0 && yaw < 135.0 { yaw_str = "+x"; } + else if yaw >= 135.0 && yaw < 225.0 { yaw_str = "-z"; } + else if yaw >= 225.0 && yaw < 315.0 { yaw_str = "-x"; } + renderer.get_ui().set_text("World", 0, format!("Direction: {}", yaw_str)); // Block position - if self.prev_pos == None || self.prev_pos != Some(pos) { - renderer.get_ui().set_text("World", 0, format!("Position: {}, {}, {}", pos.x, pos.y, pos.z)); - self.prev_pos = Some(pos); + if self.prev_pos == None || self.prev_pos != Some(cam_pos) { + renderer.get_ui().set_text("World", 1, format!("Position: {}, {}, {}", cam_pos.x, cam_pos.y, cam_pos.z)); + self.prev_pos = Some(cam_pos); } // Chunk position if self.prev_chunk_pos == None || self.prev_chunk_pos != Some(chunk_pos) { - renderer.get_ui().set_text("World", 1, format!("Chunk: {}, {}, {}", chunk_pos.x, chunk_pos.y, chunk_pos.z)); + renderer.get_ui().set_text("World", 2, format!("Chunk: {}, {}, {}", chunk_pos.x, chunk_pos.y, chunk_pos.z)); // Shift world - let dir = chunk_pos - self.prev_chunk_pos.unwrap_or(chunk_pos); - renderer.shift(&(dir * world::chunk::SIZE as i32)); + let dir = chunk_pos - self.prev_chunk_pos.unwrap_or(chunk_pos); //TODO: clamp to -1,1 + renderer.shift(dir * world::chunk::SIZE as i32); - // Load chunk - if self.world.load_chunk(chunk_pos) { - let chunk = self.world.get_chunk(&chunk_pos).unwrap(); - chunk.write_to(renderer, chunk_pos * world::chunk::SIZE as i32); - println!("Writing chunk to {:?}", chunk_pos * world::chunk::SIZE as i32); + // Load chunks at the edge + let center = chunk_pos.clone() + 2*dir; + let mask = Vector3{x: dir.x.abs(), y: dir.y.abs(), z: dir.z.abs()}; + println!("Load at {:?}", center); + + for a in -2..3 { + let pos = center + Vector3{x: mask.z*a, y: 0, z: mask.x*a}; + + self.world.load_chunk(pos); + let chunk = self.world.get_chunk(&pos).unwrap(); + chunk.write_to(renderer, pos * world::chunk::SIZE as i32); } + + //println!("Writing chunk to {:?}", pos * world::chunk::SIZE as i32); + + // for i in -2..2 { + + // } + + + // if self.world.load_chunk(chunk_pos) { + // let chunk = self.world.get_chunk(&chunk_pos).unwrap(); + // chunk.write_to(renderer, chunk_pos * world::chunk::SIZE as i32); + // println!("Writing chunk to {:?}", chunk_pos * world::chunk::SIZE as i32); + // } self.prev_chunk_pos = Some(chunk_pos); } diff --git a/src/game/world/chunk.rs b/src/game/world/chunk.rs index 71bdc1a..7ad102b 100644 --- a/src/game/world/chunk.rs +++ b/src/game/world/chunk.rs @@ -53,7 +53,6 @@ impl WorldChunk { } // Blocks - let timer = Instant::now(); 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); @@ -85,7 +84,6 @@ impl WorldChunk { blocks.sort_by(|a, b| (*a).0.cmp(&(*b).0)); for b in blocks { instance.blocks.push(b.1); } - println!("Blocks: {} ms, {}", timer.elapsed().as_millis(), instance.blocks.len()); instance } diff --git a/src/game/world/generator.rs b/src/game/world/generator.rs index 408db8e..5d68002 100644 --- a/src/game/world/generator.rs +++ b/src/game/world/generator.rs @@ -42,19 +42,28 @@ impl WorldGen { * Generate block */ pub fn generate(block_pos: &Vector3, block: &mut WorldBlock) { + if block_pos.z > 32 as i32 { return; } + let mut rng = rand::thread_rng(); let noise = Perlin::new(); // Generate height map let (map, _max) = WorldGen::gen_height_map(block_pos.x, block_pos.z, &mut rng, &noise); - + // Fill for x in 0..block::SIZE { for z in 0..block::SIZE { - let h = map[x][z]; + let mut h = map[x][z]; + let mut t = 2; + + if block_pos.x == 8 && block_pos.z == 8 { + h = 32; + t = 3; + } + //let h = 16; // testing for y in 0..h { - block.set(Vector3{x, y, z}, 2); + block.set(Vector3{x, y, z}, t); } } } diff --git a/src/game/world/mod.rs b/src/game/world/mod.rs index 5986190..cc338ce 100644 --- a/src/game/world/mod.rs +++ b/src/game/world/mod.rs @@ -81,6 +81,7 @@ impl World { pub fn load_chunk(&mut self, pos: Vector3) ->bool { // Abort if chunk is already loaded if let Some(_) = self.chunks.get(&pos) { + println!("Chunk at {:?} already loaded", pos); return false; } diff --git a/src/main.rs b/src/main.rs index 6fde57f..9080702 100644 --- a/src/main.rs +++ b/src/main.rs @@ -26,7 +26,7 @@ fn main() { .expect("Failed to create window"); let mut renderer = Renderer::new(&window); - let mut game = Game::new(); + let mut game = Game::new(&mut renderer); // Stats let mut fps_timer = std::time::Instant::now(); @@ -59,7 +59,7 @@ fn main() { // Test key VirtualKeyCode::T => { let t = &mut renderer as &mut dyn RendererView; - t.shift(&Vector3::{ x:32, y:0, z:0 }); + t.shift(Vector3::{ x:16, y:0, z:0 }); println!("shifted"); } _ => () diff --git a/src/renderer/camera.rs b/src/renderer/camera.rs index 62049cf..90a7794 100644 --- a/src/renderer/camera.rs +++ b/src/renderer/camera.rs @@ -11,7 +11,7 @@ impl Camera { pub fn new(aspect: f32) -> Self { let mut instance = Self { - position: (2.0,1.0,2.0).into(), + position: (1.0,2.0,1.0).into(), view_matrix: Matrix4::look_to_rh( (0.0,0.0,0.0).into(), Vector3{ x:0.66, y:0.0, z:0.66}.normalize(), diff --git a/src/renderer/renderer_view.rs b/src/renderer/renderer_view.rs index 3d6f2d9..eea90e0 100644 --- a/src/renderer/renderer_view.rs +++ b/src/renderer/renderer_view.rs @@ -6,7 +6,7 @@ use cgmath::Vector3; pub trait RendererView { fn write(&mut self, block_pos: &Vector3, block: &WorldBlock); - fn shift(&mut self, offset: &Vector3); + fn shift(&mut self, offset: Vector3); fn get_camera_transform(&mut self) -> &mut dyn CameraTransform; fn get_ui(&mut self) -> &mut UserInterface; fn get_world_offset(&self) -> Vector3; @@ -15,12 +15,13 @@ pub trait RendererView { impl RendererView for Renderer { fn write(&mut self, block_pos: &Vector3, block: &WorldBlock) { - self.buffers.content.write(&self.queue, &block_pos, block) + let block_pos = block_pos + (self.world_offset); + self.buffers.content.write(&self.queue, &block_pos, block); } - fn shift(&mut self, offset: &Vector3) { - //self.buffers.content.shift(offset); - //self.world_offset += *offset; + fn shift(&mut self, offset: Vector3) { + self.buffers.content.shift(&-offset); + self.world_offset -= offset; //println!("World shifted by {:?}. World offset is now {:?}", offset, self.world_offset); }