diff --git a/assets/font.ttf b/assets/font.ttf index 9d65196..951dccc 100644 Binary files a/assets/font.ttf and b/assets/font.ttf differ 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); }