diff --git a/src/core/app.rs b/src/core/app.rs index e5f1cb0..b1cb0e6 100644 --- a/src/core/app.rs +++ b/src/core/app.rs @@ -79,7 +79,10 @@ impl<'window> App<'window> { gain: 0.5, lacunarity: 2.0, }, - glam::uvec3(32, 32, 32), + voxel::world::ChunkSettings { + dimensions: glam::uvec3(32, 32, 32), + block_dimensions: glam::uvec3(8, 8, 8), + }, ); let mut renderer = BrickmapRenderer::new(&self.render_ctx, &camera_controller)?; diff --git a/src/voxel/world/chunk.rs b/src/voxel/world/chunk.rs index c9e8c3c..8c90700 100644 --- a/src/voxel/world/chunk.rs +++ b/src/voxel/world/chunk.rs @@ -1,38 +1,74 @@ use crate::math; -use super::Voxel; +use super::{GenerationSettings, Voxel}; + +#[derive(Debug, Clone, Copy)] +pub struct ChunkSettings { + pub dimensions: glam::UVec3, + pub block_dimensions: glam::UVec3, +} #[derive(Debug)] pub struct Chunk { - pos: glam::IVec3, + settings: ChunkSettings, noise: Vec, blocks: Vec>, } impl Chunk { - pub fn new(pos: glam::IVec3, noise: Vec, blocks: Vec>) -> Self { - Self { pos, noise, blocks } + pub fn new( + generation_settings: &GenerationSettings, + chunk_settings: ChunkSettings, + pos: glam::IVec3, + ) -> Self { + let dims = chunk_settings.dimensions; + + // We use dimensions of `chunk_dims + 1` because the corners on the last chunk + // block of each axis step outside of our 0..N bounds, sharing a value with the + // neighbouring chunk + let noise = simdnoise::NoiseBuilder::fbm_3d_offset( + pos.x as f32 * dims.x as f32, + dims.x as usize + 1, + pos.y as f32 * dims.y as f32, + dims.y as usize + 1, + pos.z as f32 * dims.z as f32, + dims.z as usize + 1, + ) + .with_seed(generation_settings.seed) + .with_freq(generation_settings.frequency) + .with_octaves(generation_settings.octaves) + .with_gain(generation_settings.gain) + .with_lacunarity(generation_settings.lacunarity) + .generate() + .0; + + let num_blocks = dims.x * dims.y * dims.z; + let blocks = vec![vec![]; num_blocks as usize]; + + Self { + settings: chunk_settings, + noise, + blocks, + } } - pub fn get_block(&mut self, block_pos: glam::UVec3, chunk_dims: glam::UVec3) -> Vec { - assert_eq!( - self.blocks.len(), - (chunk_dims.x * chunk_dims.y * chunk_dims.z) as usize - ); + pub fn get_block(&mut self, pos: glam::UVec3) -> Vec { + let dims = self.settings.dimensions; + assert!(pos.x < dims.x && pos.y < dims.y && pos.z < dims.z); - let block_idx = math::to_1d_index(block_pos, chunk_dims); + let block_idx = math::to_1d_index(pos, dims); let mut block = &self.blocks[block_idx]; if block.is_empty() { - self.gen_block(block_pos, block_idx, chunk_dims); + self.gen_block(pos, block_idx); block = &self.blocks[block_idx] } block.to_owned() } - pub fn gen_block(&mut self, block_pos: glam::UVec3, block_idx: usize, chunk_dims: glam::UVec3) { + pub fn gen_block(&mut self, block_pos: glam::UVec3, block_idx: usize) { let block = &mut self.blocks[block_idx]; - let noise_dims = chunk_dims + glam::uvec3(1, 1, 1); + let noise_dims = self.settings.dimensions + glam::uvec3(1, 1, 1); // Extract relevant noise values from the chunk let mut noise_vals = Vec::new(); diff --git a/src/voxel/world/manager.rs b/src/voxel/world/manager.rs index 9698ac9..3f2349d 100644 --- a/src/voxel/world/manager.rs +++ b/src/voxel/world/manager.rs @@ -1,25 +1,25 @@ use std::collections::HashMap; -use super::{Chunk, GenerationSettings, Voxel}; +use super::{chunk::ChunkSettings, Chunk, GenerationSettings, Voxel}; pub struct WorldManager { - settings: GenerationSettings, - chunk_dims: glam::UVec3, + generation_settings: GenerationSettings, + chunk_settings: ChunkSettings, chunks: HashMap, } impl WorldManager { - pub fn new(settings: GenerationSettings, chunk_dims: glam::UVec3) -> Self { + pub fn new(generation_settings: GenerationSettings, chunk_settings: ChunkSettings) -> Self { let chunks = HashMap::new(); Self { - settings, - chunk_dims, + generation_settings, + chunk_settings, chunks, } } pub fn get_chunk_dims(&self) -> glam::UVec3 { - self.chunk_dims + self.chunk_settings.dimensions } pub fn get_block(&mut self, chunk_pos: glam::IVec3, local_pos: glam::UVec3) -> Vec { @@ -31,31 +31,10 @@ impl WorldManager { } let chunk = self.chunks.get_mut(&chunk_pos).unwrap(); - chunk.get_block(local_pos, self.chunk_dims) + chunk.get_block(local_pos) } fn gen_chunk(&mut self, pos: glam::IVec3) -> Chunk { - // We use dimensions of `chunk_dims + 1` because the corners on the last chunk - // block of each axis step outside of our 0..N bounds, sharing a value with the - // neighbouring chunk - let noise = simdnoise::NoiseBuilder::fbm_3d_offset( - pos.x as f32 * self.chunk_dims.x as f32, - self.chunk_dims.x as usize + 1, - pos.y as f32 * self.chunk_dims.y as f32, - self.chunk_dims.y as usize + 1, - pos.z as f32 * self.chunk_dims.z as f32, - self.chunk_dims.z as usize + 1, - ) - .with_seed(self.settings.seed) - .with_freq(self.settings.frequency) - .with_octaves(self.settings.octaves) - .with_gain(self.settings.gain) - .with_lacunarity(self.settings.lacunarity) - .generate() - .0; - - let num_blocks = self.chunk_dims.x * self.chunk_dims.y * self.chunk_dims.z; - let blocks = vec![vec![]; num_blocks as usize]; - Chunk::new(pos, noise, blocks) + Chunk::new(&self.generation_settings, self.chunk_settings, pos) } } diff --git a/src/voxel/world/mod.rs b/src/voxel/world/mod.rs index 5fb1671..b293cdd 100644 --- a/src/voxel/world/mod.rs +++ b/src/voxel/world/mod.rs @@ -1,7 +1,10 @@ mod chunk; mod manager; -pub use {chunk::Chunk, manager::*}; +pub use { + chunk::{Chunk, ChunkSettings}, + manager::*, +}; #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum Voxel {