From 2cc4b6f2e0ea443e8fa52df06ee38aa1cf486152 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Mon, 16 Jan 2023 19:45:27 +0100 Subject: [PATCH] ok --- Cargo.toml | 1 + src/game/options.rs | 8 +++++ src/game/world.rs | 17 +++++++---- src/game/world/chunk.rs | 42 +++++++++++++++++++------- src/game/world/thread.rs | 47 ++++++++++++++++++++++++++++++ src/game/world/thread/mesh_gen.rs | 0 src/game/world/thread/world_gen.rs | 8 +++++ 7 files changed, 108 insertions(+), 15 deletions(-) create mode 100644 src/game/world/thread.rs create mode 100644 src/game/world/thread/mesh_gen.rs create mode 100644 src/game/world/thread/world_gen.rs diff --git a/Cargo.toml b/Cargo.toml index cf4ba9c..546759e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,3 +9,4 @@ image = { version = "0.24", default_features = false, features = ["png"] } log = "0.4" env_logger = "0.10" strum = { version = "0.24", features = ["derive"] } +glam = { version = "0.22", features = ["debug-glam-assert", "mint", "fast-math"] } diff --git a/src/game/options.rs b/src/game/options.rs index 27f54bf..d4d0c26 100644 --- a/src/game/options.rs +++ b/src/game/options.rs @@ -1,3 +1,11 @@ +#[derive(Clone, Debug)] pub struct GameOptions { pub render_distance: u8, } +impl Default for GameOptions { + fn default() -> Self { + Self { + render_distance: 8, + } + } +} diff --git a/src/game/world.rs b/src/game/world.rs index 4ce8f1f..c905440 100644 --- a/src/game/world.rs +++ b/src/game/world.rs @@ -1,13 +1,20 @@ +use glam::{Vec2, IVec2}; use std::collections::HashMap; +use crate::game::options::GameOptions; mod chunk; -use chunk::Chunk; +mod thread; + +use chunk::{Chunk, CHUNK_SIZE}; pub struct World { - chunks: HashMap<(i32, i32), Chunk> + pub chunks: HashMap } impl World { - // pub fn update_loaded_chunks(around: ) { - - // } + pub fn update_loaded_chunks(&mut self, around_position: Vec2, game_opt: &GameOptions) { + let render_dist = game_opt.render_distance as i32; + let inside_chunk = (around_position / CHUNK_SIZE as f32).as_ivec2(); + + todo!() + } } diff --git a/src/game/world/chunk.rs b/src/game/world/chunk.rs index 0ca150e..8910d71 100644 --- a/src/game/world/chunk.rs +++ b/src/game/world/chunk.rs @@ -1,3 +1,4 @@ +use glam::IVec2; use glium::VertexBuffer; use crate::game::{ blocks::Block, @@ -8,16 +9,37 @@ pub const CHUNK_SIZE: usize = 16; pub const CHUNK_HEIGHT: usize = 255; pub enum ChunkState { - //AwaitsLoading, - //Loaded, - //AwaitsMesh, - //Rendered, - //AwaitsUnload + AwaitsLoading, + Loaded, + AwaitsMesh, + Rendered, + AwaitsUnload } -pub struct Chunk { - pub coords: (i32, i32), - pub block_data: Option<[[[Block; CHUNK_SIZE]; CHUNK_HEIGHT]; CHUNK_SIZE]>, - pub vertex_buffer: Option>, - pub state: ChunkState +pub enum DesiredState { + Unloaded, + Loaded, + Rendered, +} + +pub type ChunkData = [[[Block; CHUNK_SIZE]; CHUNK_HEIGHT]; CHUNK_SIZE]; +pub type ChunkMesh = VertexBuffer; + +pub struct Chunk { + pub position: IVec2, + pub block_data: Option, + pub vertex_buffer: Option, + pub state: ChunkState, + pub desired: DesiredState, +} +impl Chunk { + pub fn new(position: IVec2) -> Self { + Self { + position, + block_data: None, + vertex_buffer: None, + state: ChunkState::AwaitsLoading, + desired: DesiredState::Loaded, + } + } } diff --git a/src/game/world/thread.rs b/src/game/world/thread.rs new file mode 100644 index 0000000..7cc4106 --- /dev/null +++ b/src/game/world/thread.rs @@ -0,0 +1,47 @@ +use glam::IVec2; +use std::{ + thread::{self, JoinHandle}, + collections::HashMap, + mem +}; +use super::chunk::{ChunkData, Chunk}; + +mod world_gen; +mod mesh_gen; + +struct WorldThreading { + //drain_filter is not stable yet so + //Options are needed here to take ownership, + //None values should never appear here! + pub load_tasks: HashMap>>, + pub mesh_tasks: HashMap>>, +} +impl WorldThreading { + pub fn is_done(&self) -> bool { + self.load_tasks.is_empty() && + self.mesh_tasks.is_empty() + } + pub fn queue_load(&mut self, position: IVec2) { + let handle = thread::spawn(|| { + world_gen::generate_chunk() + }); + if self.load_tasks.insert(position, Some(handle)).is_some() { + log::warn!("load: discarded {}, reason: new task started", position); + } + } + pub fn apply_tasks(&mut self, chunks: &mut HashMap) { + self.load_tasks.retain(|position, handle| { + if !chunks.contains_key(position) { + log::warn!("load: discarded {}, reason: chunk no longer exists", position); + return false + } + if !handle.as_ref().expect("Something went terribly wrong").is_finished() { + return true + } + let handle = mem::take(handle).unwrap(); + let data = handle.join().unwrap(); + chunks.get_mut(position).unwrap().block_data = Some(data); + false + }); + } +} diff --git a/src/game/world/thread/mesh_gen.rs b/src/game/world/thread/mesh_gen.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/game/world/thread/world_gen.rs b/src/game/world/thread/world_gen.rs new file mode 100644 index 0000000..fd76af0 --- /dev/null +++ b/src/game/world/thread/world_gen.rs @@ -0,0 +1,8 @@ +use crate::game::{ + world::chunk::{ChunkData, CHUNK_SIZE, CHUNK_HEIGHT}, + blocks::Block +}; + +pub fn generate_chunk() -> ChunkData { + [[[Block::Stone; CHUNK_SIZE]; CHUNK_HEIGHT]; CHUNK_SIZE] +}