From 7879e572755a4b09b7e8ea5269b72a6fa7477646 Mon Sep 17 00:00:00 2001 From: zomseffen Date: Sun, 4 Aug 2024 14:48:07 +0200 Subject: [PATCH] first chunk implementation --- Cargo.lock | 37 +++++++++++++++++ Cargo.toml | 3 +- src/scene.rs | 114 +++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 146 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e264b69..bf0c4d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -819,6 +819,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "pretty_env_logger" version = "0.5.0" @@ -865,6 +871,36 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "raw-window-handle" version = "0.6.0" @@ -1181,6 +1217,7 @@ dependencies = [ "log", "png", "pretty_env_logger", + "rand", "serde", "thiserror", "tobj", diff --git a/Cargo.toml b/Cargo.toml index 4d2f700..f61cfbf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,4 +15,5 @@ thiserror = "1" tobj = { version = "3", features = ["log"] } vulkanalia = { version = "=0.23.0", features = ["libloading", "provisional", "window"] } winit = "0.29" -serde = { version = "1.0", features = ["derive"] } \ No newline at end of file +serde = { version = "1.0", features = ["derive"] } +rand = "0.8" \ No newline at end of file diff --git a/src/scene.rs b/src/scene.rs index 59657f7..abc1874 100644 --- a/src/scene.rs +++ b/src/scene.rs @@ -3,11 +3,18 @@ use anyhow::Result; use cgmath::{vec2, vec3}; +use std::collections::HashMap; + use crate::app_data::AppData; use crate::buffer; use crate::vertex; use crate::primitives::cube::Cube; +extern crate rand; +use rand::Rng; + +const CHUNK_SIZE: usize = 100; + #[derive(Clone, Debug, Default)] pub struct Scene { pub vertices: Vec, @@ -22,20 +29,35 @@ pub struct Scene { impl Scene { pub unsafe fn prepare_data(&mut self, instance: &vulkanalia::Instance, device: &vulkanalia::Device, data: &AppData) -> Result<()> { + let mut rng = rand::thread_rng(); + let grid_size = CHUNK_SIZE as i32; + + // todo store the chunks somewhere (or only use them as intermediary for neighbouthood calculation idc) + let mut chunks = vec![Chunk::create()?]; - let grid_size = 1000; //todo use the 14 vertice box method. Not using geometry shaders seems to be faster... make this a setting? // have cube elements with a method asking for vertices, while giving a primitive type -> method for preferred primitive type as well as one collecting all primitives - for x_index in -grid_size..grid_size { - for y_index in -grid_size..grid_size { - let index = self.vertices.len(); + for x_index in 0..grid_size { + for y_index in 0..grid_size { + let shade = (rng.gen_range(0..25) as f32) / 100.0; let cube = Cube { pos: vec3(x_index as f32, y_index as f32, 0.0), - color: vec3(0.0, 1.0, 0.0), + color: vec3(shade, 1.0, shade), tex_coord: vec2(0.0, 0.0) }; + chunks[0].set_cube(cube); + } + } - cube.draw(&data.topology, index, self); + let chunk = &chunks[0]; + let chunk_iter = ChunkIter::create(chunk)?; + for item in chunk_iter { + let index = self.vertices.len(); + match item { + Some(cube) => { + cube.draw(&data.topology, index, self); + } + None => {} } } @@ -53,4 +75,82 @@ impl Scene { device.destroy_buffer(self.vertex_buffer, None); device.free_memory(self.vertex_buffer_memory, None); } -} \ No newline at end of file +} + +#[derive(Clone, Debug)] +struct Chunk { + //todo change to hashmap? + blocks: HashMap, Cube>, +} + +impl Chunk { + pub fn create() -> Result { + let mut map = HashMap::new(); + Ok(Self { + blocks: map + }) + } + + pub fn set_cube(&mut self, cube: Cube) { + let x = cube.pos.x as usize; + let y = cube.pos.y as usize; + let z = cube.pos.z as usize; + assert!(x < CHUNK_SIZE, "x value out of range!"); + assert!(y < CHUNK_SIZE, "y value out of range!"); + assert!(z < CHUNK_SIZE, "z value out of range!"); + self.blocks.insert(vec3(x as u32, y as u32, z as u32), cube); + } + + pub fn clear_cube(&mut self, x: usize, y: usize, z: usize) { + assert!(x < CHUNK_SIZE, "x value out of range!"); + assert!(y < CHUNK_SIZE, "y value out of range!"); + assert!(z < CHUNK_SIZE, "z value out of range!"); + self.blocks.remove(&vec3(x as u32, y as u32, z as u32)); + } + +} + +struct ChunkIter<'a> { + iter_x: usize, + iter_y: usize, + iter_z: usize, + chunk: &'a Chunk +} + +impl<'a> ChunkIter<'a> { + pub fn create(chunk: &'a Chunk) -> Result { + + Ok(Self { + iter_x: 0, + iter_y: 0, + iter_z: 0, + chunk + }) + } +} + +impl<'a> Iterator for ChunkIter<'a> { + type Item = Option<&'a Cube>; + + fn next(&mut self) -> Option { + if self.iter_x < CHUNK_SIZE && self.iter_y < CHUNK_SIZE && self.iter_z < CHUNK_SIZE { + let result = self.chunk.blocks.get(&vec3(self.iter_x as u32, self.iter_y as u32, self.iter_z as u32)); + + self.iter_x += 1; + if self.iter_x >= CHUNK_SIZE { + self.iter_x = 0; + self.iter_y += 1; + } + if self.iter_y >= CHUNK_SIZE { + self.iter_y = 0; + self.iter_z += 1; + } + return Some(result.clone()) + } + self.iter_x = 0; + self.iter_y = 0; + self.iter_z = 0; + None + } +} +