Compare commits

..

No commits in common. "world-rewrite" and "main" have entirely different histories.

6 changed files with 65 additions and 236 deletions

48
Cargo.lock generated
View File

@ -829,16 +829,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "matrixmultiply"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2"
dependencies = [
"autocfg",
"rawpointer",
]
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.7.1" version = "2.7.1"
@ -889,19 +879,6 @@ dependencies = [
"unicode-xid", "unicode-xid",
] ]
[[package]]
name = "ndarray"
version = "0.15.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adb12d4e967ec485a5f71c6311fe28158e9d6f4bc4a447b474184d0f91a8fa32"
dependencies = [
"matrixmultiply",
"num-complex",
"num-integer",
"num-traits",
"rawpointer",
]
[[package]] [[package]]
name = "ndk" name = "ndk"
version = "0.8.0" version = "0.8.0"
@ -932,24 +909,6 @@ dependencies = [
"jni-sys", "jni-sys",
] ]
[[package]]
name = "num-complex"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6"
dependencies = [
"num-traits",
]
[[package]]
name = "num-integer"
version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
dependencies = [
"num-traits",
]
[[package]] [[package]]
name = "num-traits" name = "num-traits"
version = "0.2.18" version = "0.2.18"
@ -1197,12 +1156,6 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42a9830a0e1b9fb145ebb365b8bc4ccd75f290f98c0247deafbbe2c75cefb544" checksum = "42a9830a0e1b9fb145ebb365b8bc4ccd75f290f98c0247deafbbe2c75cefb544"
[[package]]
name = "rawpointer"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.3.5" version = "0.3.5"
@ -1587,7 +1540,6 @@ dependencies = [
"env_logger", "env_logger",
"glam", "glam",
"log", "log",
"ndarray",
"pollster", "pollster",
"simdnoise", "simdnoise",
"wgpu", "wgpu",

View File

@ -11,7 +11,6 @@ bytemuck = { version = "1.15.0", features = ["derive"] }
env_logger = "0.11.3" env_logger = "0.11.3"
glam = "0.26.0" glam = "0.26.0"
log = "0.4.21" log = "0.4.21"
ndarray = "0.15.6"
pollster = "0.3.0" pollster = "0.3.0"
simdnoise = "3.1.6" simdnoise = "3.1.6"
wgpu = "0.19.3" wgpu = "0.19.3"

View File

@ -79,10 +79,7 @@ impl<'window> App<'window> {
gain: 0.5, gain: 0.5,
lacunarity: 2.0, lacunarity: 2.0,
}, },
voxel::world::ChunkSettings { glam::uvec3(32, 32, 32),
dimensions: glam::uvec3(32, 32, 32),
block_dimensions: glam::uvec3(8, 8, 8),
},
); );
let mut renderer = BrickmapRenderer::new(&self.render_ctx, &camera_controller)?; let mut renderer = BrickmapRenderer::new(&self.render_ctx, &camera_controller)?;

View File

@ -1,153 +1,38 @@
use ndarray::{s, Array3};
use wgpu::naga::FastHashSet;
use crate::math; use crate::math;
use super::{GenerationSettings, Voxel}; use super::Voxel;
#[derive(Debug, Clone, Copy)]
pub struct ChunkSettings {
pub dimensions: glam::UVec3,
pub block_dimensions: glam::UVec3,
}
#[derive(Debug)] #[derive(Debug)]
pub struct Chunk { pub struct Chunk {
settings: ChunkSettings, pos: glam::IVec3,
genned_blocks: FastHashSet<(usize, usize, usize)>,
noise: Vec<f32>, noise: Vec<f32>,
blocks: Array3<Voxel>, blocks: Vec<Vec<Voxel>>,
} }
impl Chunk { impl Chunk {
pub fn new( pub fn new(pos: glam::IVec3, noise: Vec<f32>, blocks: Vec<Vec<Voxel>>) -> Self {
generation_settings: &GenerationSettings, Self { pos, noise, blocks }
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 genned_blocks = FastHashSet::default();
let shape = chunk_settings.dimensions * chunk_settings.block_dimensions;
let num_voxels = shape.x * shape.y * shape.z;
let blocks = Array3::from_shape_vec(
(shape.x as usize, shape.y as usize, shape.z as usize),
vec![Voxel::Empty; num_voxels as usize],
)
.unwrap();
Self {
settings: chunk_settings,
noise,
blocks,
genned_blocks,
}
} }
pub fn get_region( pub fn get_block(&mut self, block_pos: glam::UVec3, chunk_dims: glam::UVec3) -> Vec<Voxel> {
&mut self, assert_eq!(
region_start: glam::UVec3, self.blocks.len(),
region_dims: glam::UVec3, (chunk_dims.x * chunk_dims.y * chunk_dims.z) as usize
) -> Vec<Voxel> { );
let start = region_start;
let end = region_start + region_dims;
let dims = self.settings.dimensions * self.settings.block_dimensions;
assert!(end.x <= dims.x && end.y <= dims.y && end.z <= dims.z);
// Check that all the blocks needed are generated and generated them if needed let block_idx = math::to_1d_index(block_pos, chunk_dims);
let block_dims = self.settings.block_dimensions; let mut block = &self.blocks[block_idx];
let start_block = start / block_dims; if block.is_empty() {
let end_block = end / block_dims; self.gen_block(block_pos, block_idx, chunk_dims);
for z in start_block.z..(end_block.z) { block = &self.blocks[block_idx]
for y in (start_block.y)..(end_block.y) {
for x in (start_block.x)..(end_block.x) {
if !self
.genned_blocks
.contains(&(x as usize, y as usize, z as usize))
{
self.gen_block(glam::uvec3(x, y, z));
}
}
}
} }
// block.to_owned()
let region = self
.blocks
.slice(s![
(start.x as usize)..(end.x as usize),
(start.y as usize)..(end.y as usize),
(start.z as usize)..(end.z as usize)
])
.to_owned()
.into_raw_vec();
// dbg!(&region);
region
} }
// pub fn get_voxel(&mut self, pos: glam::UVec3) -> Voxel { pub fn gen_block(&mut self, block_pos: glam::UVec3, block_idx: usize, chunk_dims: glam::UVec3) {
// let dims = self.settings.dimensions * self.settings.block_dimensions; let block = &mut self.blocks[block_idx];
// debug_assert!(pos.x < dims.x && pos.y < dims.y && pos.z < dims.z); let noise_dims = chunk_dims + glam::uvec3(1, 1, 1);
// let block_pos = pos / self.settings.block_dimensions;
// let block_idx = math::to_1d_index(block_pos, self.settings.dimensions);
// let mut block = &self.blocks[block_idx];
// if block.is_empty() {
// self.gen_block(block_pos, block_idx);
// block = &self.blocks[block_idx]
// }
// let local_pos = pos % self.settings.block_dimensions;
// let local_idx = math::to_1d_index(local_pos, self.settings.block_dimensions);
// block[local_idx]
// }
pub fn get_block(&mut self, pos: glam::UVec3) -> Vec<Voxel> {
let dims = self.settings.dimensions;
assert!(pos.x < dims.x && pos.y < dims.y && pos.z < dims.z);
let gen_key = &(pos.x as usize, pos.y as usize, pos.z as usize);
if !self.genned_blocks.contains(gen_key) {
self.gen_block(pos);
}
let block_dims = self.settings.block_dimensions;
let start = pos * block_dims;
let end = start + block_dims;
let region = self
.blocks
.slice(s![
(start.x as usize)..(end.x as usize),
(start.y as usize)..(end.y as usize),
(start.z as usize)..(end.z as usize)
])
.to_owned()
.into_raw_vec();
region
}
pub fn gen_block(&mut self, block_pos: glam::UVec3) {
let noise_dims = self.settings.dimensions + glam::uvec3(1, 1, 1);
// Extract relevant noise values from the chunk // Extract relevant noise values from the chunk
let mut noise_vals = Vec::new(); let mut noise_vals = Vec::new();
@ -165,51 +50,32 @@ impl Chunk {
} }
// If all the corners are negative, then all the interpolated values // If all the corners are negative, then all the interpolated values
// will be negative too. The chunk voxels are initialised as empty already // will be negative too. In that case we can just fill with empty.
// so we only need to modify them if we have at least one positive corner if block_sign == -8.0 {
if block_sign != -8.0 { block.resize(512, Voxel::Empty);
let block_dims = self.settings.block_dimensions; } else {
let mut vals = [0.0f32; 512]; let mut vals = [0.0f32; 512];
math::tri_lerp_block( math::tri_lerp_block(&noise_vals, &[8, 8, 8], &mut vals);
&noise_vals,
&[block_dims.x, block_dims.y, block_dims.z],
&mut vals,
);
let start = block_pos * block_dims;
let end = start + block_dims;
let mut block = self.blocks.slice_mut(s![
(start.x as usize)..(end.x as usize),
(start.y as usize)..(end.y as usize),
(start.z as usize)..(end.z as usize)
]);
// TODO: Better voxel colours // TODO: Better voxel colours
let mut val_idx = 0; let mut idx = 0;
for z in 0..block_dims.z { for z in 0..8 {
for y in 0..block_dims.y { for y in 0..8 {
for x in 0..block_dims.x { for x in 0..8 {
let val = vals[val_idx]; let val = vals[idx];
val_idx += 1; idx += 1;
if val > 0.0 { if val > 0.0 {
let r = ((x + 1) * 32 - 1) as u8; let r = ((x + 1) * 32 - 1) as u8;
let g = ((y + 1) * 32 - 1) as u8; let g = ((y + 1) * 32 - 1) as u8;
let b = ((z + 1) * 32 - 1) as u8; let b = ((z + 1) * 32 - 1) as u8;
let block_idx = [z as usize, y as usize, x as usize]; block.push(Voxel::Color(r, g, b));
block[block_idx] = Voxel::Color(r, g, b); } else {
block.push(Voxel::Empty);
} }
} }
} }
} }
} }
let key = (
block_pos.x as usize,
block_pos.y as usize,
block_pos.z as usize,
);
self.genned_blocks.insert(key);
} }
} }

View File

@ -1,25 +1,25 @@
use std::collections::HashMap; use std::collections::HashMap;
use super::{chunk::ChunkSettings, Chunk, GenerationSettings, Voxel}; use super::{Chunk, GenerationSettings, Voxel};
pub struct WorldManager { pub struct WorldManager {
generation_settings: GenerationSettings, settings: GenerationSettings,
chunk_settings: ChunkSettings, chunk_dims: glam::UVec3,
chunks: HashMap<glam::IVec3, Chunk>, chunks: HashMap<glam::IVec3, Chunk>,
} }
impl WorldManager { impl WorldManager {
pub fn new(generation_settings: GenerationSettings, chunk_settings: ChunkSettings) -> Self { pub fn new(settings: GenerationSettings, chunk_dims: glam::UVec3) -> Self {
let chunks = HashMap::new(); let chunks = HashMap::new();
Self { Self {
generation_settings, settings,
chunk_settings, chunk_dims,
chunks, chunks,
} }
} }
pub fn get_chunk_dims(&self) -> glam::UVec3 { pub fn get_chunk_dims(&self) -> glam::UVec3 {
self.chunk_settings.dimensions self.chunk_dims
} }
pub fn get_block(&mut self, chunk_pos: glam::IVec3, local_pos: glam::UVec3) -> Vec<Voxel> { pub fn get_block(&mut self, chunk_pos: glam::IVec3, local_pos: glam::UVec3) -> Vec<Voxel> {
@ -31,13 +31,31 @@ impl WorldManager {
} }
let chunk = self.chunks.get_mut(&chunk_pos).unwrap(); let chunk = self.chunks.get_mut(&chunk_pos).unwrap();
let block_dims = self.chunk_settings.block_dimensions; chunk.get_block(local_pos, self.chunk_dims)
chunk.get_region(local_pos * block_dims, block_dims)
// chunk.get_block(local_pos)
} }
fn gen_chunk(&mut self, pos: glam::IVec3) -> Chunk { fn gen_chunk(&mut self, pos: glam::IVec3) -> Chunk {
Chunk::new(&self.generation_settings, self.chunk_settings, pos) // 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)
} }
} }

View File

@ -1,10 +1,7 @@
mod chunk; mod chunk;
mod manager; mod manager;
pub use { pub use {chunk::Chunk, manager::*};
chunk::{Chunk, ChunkSettings},
manager::*,
};
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Voxel { pub enum Voxel {