diff --git a/Cargo.lock b/Cargo.lock index 060d7b7..ef790c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -948,6 +948,8 @@ dependencies = [ "bincode", "bracket-noise", "glam", + "rand", + "rand_xoshiro", "shipyard", "strum", ] @@ -986,6 +988,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "libm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" + [[package]] name = "libudev-sys" version = "0.1.4" @@ -1310,6 +1318,16 @@ dependencies = [ "shared_library", ] +[[package]] +name = "packed_simd_2" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1914cd452d8fccd6f9db48147b29fd4ae05bea9dc5d9ad578509f72415de282" +dependencies = [ + "cfg-if", + "libm", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -1377,6 +1395,12 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "proc-macro-crate" version = "1.3.0" @@ -1411,6 +1435,19 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ + "libc", + "packed_simd_2", + "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", ] @@ -1419,6 +1456,9 @@ name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] [[package]] name = "rand_xorshift" @@ -1429,6 +1469,15 @@ dependencies = [ "rand_core", ] +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core", +] + [[package]] name = "raw-window-handle" version = "0.4.3" diff --git a/kubi-shared/Cargo.toml b/kubi-shared/Cargo.toml index b615b4f..b16a3b3 100644 --- a/kubi-shared/Cargo.toml +++ b/kubi-shared/Cargo.toml @@ -13,3 +13,9 @@ strum = { version = "0.24", features = ["derive"] } bincode = "2.0.0-rc" anyhow = "1.0" bracket-noise = "0.8" +rand = { version = "0.8", default_features = false, features = ["std", "min_const_gen"] } +rand_xoshiro = "0.6" + +[features] +default = [] +nightly = ["rand/nightly", "rand/simd_support"] diff --git a/kubi-shared/src/block.rs b/kubi-shared/src/block.rs index e42c367..76a126b 100644 --- a/kubi-shared/src/block.rs +++ b/kubi-shared/src/block.rs @@ -128,23 +128,27 @@ impl CubeTexture { } #[derive(Clone, Copy, Debug)] -pub struct CrossTexture { - pub a_front: BlockTexture, - pub a_back: BlockTexture, - pub b_front: BlockTexture, - pub b_back: BlockTexture, +pub struct CrossTextureSides { + pub front: BlockTexture, + pub back: BlockTexture } -impl CrossTexture { - pub const fn same_front_back(a: BlockTexture, b: BlockTexture) -> Self { +impl CrossTextureSides { + pub const fn all(texture: BlockTexture) -> Self { Self { - a_front: a, - a_back: a, - b_front: b, - b_back: b, + front: texture, + back: texture } } +} + +#[derive(Clone, Copy, Debug)] +pub struct CrossTexture(pub CrossTextureSides, pub CrossTextureSides); +impl CrossTexture { pub const fn all(texture: BlockTexture) -> Self { - Self::same_front_back(texture, texture) + Self( + CrossTextureSides::all(texture), + CrossTextureSides::all(texture) + ) } } diff --git a/kubi-shared/src/worldgen.rs b/kubi-shared/src/worldgen.rs index ca2df3e..57cb98c 100644 --- a/kubi-shared/src/worldgen.rs +++ b/kubi-shared/src/worldgen.rs @@ -1,5 +1,7 @@ -use glam::{IVec3, ivec3}; use bracket_noise::prelude::*; +use rand::prelude::*; +use glam::{IVec3, ivec3}; +use rand_xoshiro::Xoshiro256StarStar; use crate::{ chunk::{BlockData, CHUNK_SIZE}, block::Block @@ -41,6 +43,14 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> BlockData { elevation_noise.set_fractal_octaves(1); elevation_noise.set_frequency(0.001); + let mut rng = Xoshiro256StarStar::seed_from_u64( + seed + ^ ((chunk_position.x as u32 as u64) << 0) + ^ ((chunk_position.y as u32 as u64) << 16) + ^ ((chunk_position.z as u32 as u64) << 32) + ); + let tall_grass_map: [[u8; CHUNK_SIZE]; CHUNK_SIZE] = rng.gen(); + // let mut cave_noise = FastNoise::seeded(seed.rotate_left(1)); // cave_noise.set_fractal_type(FractalType::FBM); // cave_noise.set_fractal_octaves(2); @@ -75,6 +85,12 @@ pub fn generate_world(chunk_position: IVec3, seed: u64) -> BlockData { if let Some(y) = local_y_position(height, chunk_position) { blocks[x][y][z] = Block::Grass; } + //place tall grass + if tall_grass_map[x][z] < 10 { + if let Some(y) = local_y_position(height + 1, chunk_position) { + blocks[x][y][z] = Block::TallGrass; + } + } } } diff --git a/kubi/Cargo.toml b/kubi/Cargo.toml index 56f5841..78a8b35 100644 --- a/kubi/Cargo.toml +++ b/kubi/Cargo.toml @@ -26,4 +26,4 @@ winapi = { version = "0.3" } [features] default = [] -unstable = ["glam/core-simd"] +nightly = ["glam/core-simd", "kubi-shared/nightly"] diff --git a/kubi/src/world/mesh.rs b/kubi/src/world/mesh.rs index 9275730..4f81538 100644 --- a/kubi/src/world/mesh.rs +++ b/kubi/src/world/mesh.rs @@ -8,7 +8,7 @@ pub mod data; mod builder; use data::MeshGenData; -use builder::{CubeFace, MeshBuilder}; +use builder::{MeshBuilder, CubeFace, DiagonalFace}; pub fn generate_mesh(data: MeshGenData) -> (Vec, Vec) { let get_block = |pos: IVec3| -> Block { @@ -58,9 +58,20 @@ pub fn generate_mesh(data: MeshGenData) -> (Vec, Vec) { } } }, - RenderType::CrossShape(_) => { - todo!() - } + RenderType::CrossShape(textures) => { + builder.add_diagonal_face( + coord, + DiagonalFace::LeftZ, + textures.0.front as u8, + textures.0.back as u8 + ); + builder.add_diagonal_face( + coord, + DiagonalFace::RigthZ, + textures.1.front as u8, + textures.1.back as u8 + ); + }, } } } diff --git a/kubi/src/world/mesh/builder.rs b/kubi/src/world/mesh/builder.rs index 09bde30..ed1ffd7 100644 --- a/kubi/src/world/mesh/builder.rs +++ b/kubi/src/world/mesh/builder.rs @@ -2,14 +2,16 @@ use strum::EnumIter; use glam::{Vec3, vec3, IVec3, ivec3}; use crate::rendering::world::ChunkVertex; +const INV_SQRT_2: f32 = 0.70710678118655; // 1 / 2.sqrt() + #[repr(usize)] #[derive(Clone, Copy, Debug, EnumIter)] pub enum CubeFace { Top = 0, - Front = 1, + Front = 4, Left = 2, Right = 3, - Back = 4, + Back = 1, Bottom = 5, } impl CubeFace { @@ -43,6 +45,40 @@ const CUBE_FACE_NORMALS: [Vec3; 6] = [ vec3(0., -1.,0.) ]; const CUBE_FACE_INDICES: [u32; 6] = [0, 1, 2, 2, 1, 3]; + +#[repr(usize)] +pub enum DiagonalFace { + RigthZ = 0, + LeftZ = 1, +} +const CROSS_FACES: [[Vec3; 4]; 2] = [ + [ + vec3(0., 0., 0.), + vec3(0., 1., 0.), + vec3(1., 0., 1.), + vec3(1., 1., 1.), + ], + [ + vec3(0., 0., 1.), + vec3(0., 1., 1.), + vec3(1., 0., 0.), + vec3(1., 1., 0.), + ] +]; +const CROSS_FACE_NORMALS: [Vec3; 2] = [ + vec3(-INV_SQRT_2, 0., INV_SQRT_2), + vec3(INV_SQRT_2, 0., INV_SQRT_2), +]; +const CROSS_FACE_NORMALS_BACK: [Vec3; 2] = [ + vec3(INV_SQRT_2, 0., -INV_SQRT_2), + vec3(-INV_SQRT_2, 0., -INV_SQRT_2), +]; +const CROSS_FACE_INDICES: [u32; 12] = [ + 0, 1, 2, 2, 1, 3, //Front side + 6, 5, 4, 7, 5, 6, //Back side +]; + + const UV_COORDS: [[f32; 2]; 4] = [ [0., 0.], [0., 1.], @@ -80,9 +116,61 @@ impl MeshBuilder { //Push indices self.index_buffer.extend_from_slice(&CUBE_FACE_INDICES.map(|x| x + self.idx_counter)); + + //Increment idx counter self.idx_counter += 4; } + pub fn add_diagonal_face(&mut self, coord: IVec3, face_type: DiagonalFace, front_texture: u8, back_texture: u8) { + //Push vertices + let face_type = face_type as usize; + let vertices = CROSS_FACES[face_type]; + let normal_front = CROSS_FACE_NORMALS[face_type].to_array(); + let normal_back = CROSS_FACE_NORMALS[face_type].to_array(); + self.vertex_buffer.reserve(8); + for i in 0..4 { //push front vertices + self.vertex_buffer.push(ChunkVertex { + position: (coord.as_vec3() + vertices[i]).to_array(), + normal: normal_front, + uv: UV_COORDS[i], + tex_index: front_texture + }) + } + for i in 0..4 { //push back vertices + self.vertex_buffer.push(ChunkVertex { + position: (coord.as_vec3() + vertices[i]).to_array(), + normal: normal_back, + uv: UV_COORDS[i], + tex_index: back_texture + }) + } + + //Push indices + self.index_buffer.extend_from_slice(&CROSS_FACE_INDICES.map(|x| x + self.idx_counter)); + + //Increment idx counter + self.idx_counter += 8; + } + + pub fn add_model(&mut self, position: Vec3, vertices: &[ChunkVertex], indices: Option<&[u32]>) { + //push vertices + self.vertex_buffer.extend(vertices.iter().map(|vertex| { + let mut vertex = *vertex; + vertex.position[0] += position.x; + vertex.position[0] += position.y; + vertex.position[0] += position.z; + vertex + })); + //push indices + if let Some(indices) = indices { + self.index_buffer.extend(indices.iter().map(|x| x + self.idx_counter)); + } else { + self.index_buffer.extend(0..(self.vertex_buffer.len() as u32)); + } + //increment idx counter + self.idx_counter += vertices.len() as u32; + } + pub fn finish(self) -> (Vec, Vec) { (self.vertex_buffer, self.index_buffer) }