mirror of
https://github.com/griffi-gh/kubi.git
synced 2024-11-14 03:18:41 -06:00
decoration and layers
This commit is contained in:
parent
b1de67339e
commit
0fac4531e0
|
@ -12,6 +12,8 @@ use crate::{
|
||||||
mod _01_terrain;
|
mod _01_terrain;
|
||||||
mod _02_water;
|
mod _02_water;
|
||||||
mod _03_caves;
|
mod _03_caves;
|
||||||
|
mod _04_layers;
|
||||||
|
mod _05_decorate;
|
||||||
|
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
#[derive(Clone, Copy, Debug, Default, NoUninit, CheckedBitPattern)]
|
#[derive(Clone, Copy, Debug, Default, NoUninit, CheckedBitPattern)]
|
||||||
|
@ -83,11 +85,17 @@ macro_rules! run_steps {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct WorldGeneratorData {
|
||||||
|
pub master_height_map: Option<Vec<Vec<i32>>>,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct WorldGenerator {
|
pub struct WorldGenerator {
|
||||||
seed: u64,
|
seed: u64,
|
||||||
chunk_position: IVec3,
|
chunk_position: IVec3,
|
||||||
blocks: BlockData,
|
blocks: BlockData,
|
||||||
queue: Vec<QueuedBlock>,
|
queue: Vec<QueuedBlock>,
|
||||||
|
pub data: WorldGeneratorData,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorldGenerator {
|
impl WorldGenerator {
|
||||||
|
@ -153,12 +161,23 @@ impl WorldGenerator {
|
||||||
(0..CHUNK_SIZE as i32).contains(&position).then_some(position)
|
(0..CHUNK_SIZE as i32).contains(&position).then_some(position)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// crude hash of self.seed and x
|
||||||
|
fn seeded_hash(&self, x: impl std::hash::Hash) -> u64 {
|
||||||
|
//use std::hash to hash the seed and x
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
|
let mut hasher = std::collections::hash_map::DefaultHasher::new();
|
||||||
|
x.hash(&mut hasher);
|
||||||
|
self.seed.hash(&mut hasher);
|
||||||
|
hasher.finish()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new(chunk_position: IVec3, seed: u64) -> Self {
|
pub fn new(chunk_position: IVec3, seed: u64) -> Self {
|
||||||
Self {
|
Self {
|
||||||
seed,
|
seed,
|
||||||
chunk_position,
|
chunk_position,
|
||||||
blocks: Box::new([[[Block::Air; CHUNK_SIZE]; CHUNK_SIZE]; CHUNK_SIZE]),
|
blocks: Box::new([[[Block::Air; CHUNK_SIZE]; CHUNK_SIZE]; CHUNK_SIZE]),
|
||||||
queue: Vec::with_capacity(0),
|
queue: Vec::with_capacity(0),
|
||||||
|
data: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +189,8 @@ impl WorldGenerator {
|
||||||
_01_terrain::TerrainStep,
|
_01_terrain::TerrainStep,
|
||||||
_02_water::WaterStep,
|
_02_water::WaterStep,
|
||||||
_03_caves::CaveStep,
|
_03_caves::CaveStep,
|
||||||
|
_04_layers::LayersStep,
|
||||||
|
_05_decorate::DecorateStep,
|
||||||
]).then_some((self.blocks, self.queue))
|
]).then_some((self.blocks, self.queue))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,14 +18,17 @@ impl WorldGenStep for TerrainStep {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate(&mut self, gen: &mut WorldGenerator) {
|
fn generate(&mut self, gen: &mut WorldGenerator) {
|
||||||
|
let mut height_map = vec![vec![0; CHUNK_SIZE]; CHUNK_SIZE];
|
||||||
for x in 0..CHUNK_SIZE as i32 {
|
for x in 0..CHUNK_SIZE as i32 {
|
||||||
for z in 0..CHUNK_SIZE as i32 {
|
for z in 0..CHUNK_SIZE as i32 {
|
||||||
let global_xz = gen.global_position(ivec3(x, 0, z));
|
let global_xz = gen.global_position(ivec3(x, 0, z));
|
||||||
let height = (self.noise.get_noise_2d(global_xz.x as f64, global_xz.z as f64) * 32.0) as i32;
|
let height = (self.noise.get_noise_2d(global_xz.x as f64, global_xz.z as f64) * 32.0) as i32;
|
||||||
|
height_map[x as usize][z as usize] = height;
|
||||||
for y in 0..gen.local_height(height) {
|
for y in 0..gen.local_height(height) {
|
||||||
gen.place(ivec3(x, y, z), Block::Stone);
|
gen.place(ivec3(x, y, z), Block::Stone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
gen.data.master_height_map = Some(height_map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ use glam::ivec3;
|
||||||
use crate::{block::Block, chunk::CHUNK_SIZE};
|
use crate::{block::Block, chunk::CHUNK_SIZE};
|
||||||
use super::{WorldGenerator, WorldGenStep};
|
use super::{WorldGenerator, WorldGenStep};
|
||||||
|
|
||||||
|
pub const WATER_LEVEL: i32 = 0;
|
||||||
|
|
||||||
pub struct WaterStep;
|
pub struct WaterStep;
|
||||||
|
|
||||||
impl WorldGenStep for WaterStep {
|
impl WorldGenStep for WaterStep {
|
||||||
|
@ -9,7 +11,7 @@ impl WorldGenStep for WaterStep {
|
||||||
fn generate(&mut self, gen: &mut WorldGenerator) {
|
fn generate(&mut self, gen: &mut WorldGenerator) {
|
||||||
for x in 0..CHUNK_SIZE as i32 {
|
for x in 0..CHUNK_SIZE as i32 {
|
||||||
for z in 0..CHUNK_SIZE as i32 {
|
for z in 0..CHUNK_SIZE as i32 {
|
||||||
for y in 0..gen.local_height(0) {
|
for y in 0..gen.local_height(WATER_LEVEL) {
|
||||||
gen.place_if_empty(ivec3(x, y, z), Block::Water);
|
gen.place_if_empty(ivec3(x, y, z), Block::Water);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
use fastnoise_lite::{FastNoiseLite, FractalType};
|
use fastnoise_lite::{FastNoiseLite, FractalType};
|
||||||
use glam::{ivec3, IVec3};
|
use glam::{ivec3, FloatExt, IVec3};
|
||||||
use crate::{block::Block, chunk::CHUNK_SIZE};
|
use crate::{block::Block, chunk::CHUNK_SIZE};
|
||||||
use super::{SeedThingy, WorldGenStep, WorldGenerator};
|
use super::{SeedThingy, WorldGenStep, WorldGenerator};
|
||||||
|
|
||||||
|
@ -25,22 +24,26 @@ impl WorldGenStep for CaveStep {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate(&mut self, gen: &mut WorldGenerator) {
|
fn generate(&mut self, gen: &mut WorldGenerator) {
|
||||||
//TODO
|
for x in 0..CHUNK_SIZE as i32 {
|
||||||
|
for y in 0..CHUNK_SIZE as i32 {
|
||||||
|
for z in 0..CHUNK_SIZE as i32 {
|
||||||
|
let cave_size = ((gen.offset().y + y - 50) as f64 / -200.).clamp(0., 1.) as f32;
|
||||||
|
let inv_cave_size = 1. - cave_size;
|
||||||
|
if cave_size < 0.1 { continue }
|
||||||
|
|
||||||
// for x in 0..CHUNK_SIZE as i32 {
|
let pos = ivec3(x, y, z);
|
||||||
// for y in 0..CHUNK_SIZE as i32 {
|
if gen.query(pos) != Block::Stone { continue }
|
||||||
// for z in 0..CHUNK_SIZE as i32 {
|
|
||||||
// let pos = ivec3(x, y, z);
|
let pos_global = gen.global_position(pos);
|
||||||
// if gen.query(pos) != Block::Stone { continue }
|
let noise_a = self.a.get_noise_3d(pos_global.x as f64, pos_global.y as f64, pos_global.z as f64) * 0.5 + 0.5;
|
||||||
// let pos_global = gen.global_position(pos);
|
let noise_b = self.b.get_noise_3d(pos_global.x as f64, pos_global.y as f64, pos_global.z as f64) * 0.5 + 0.5;
|
||||||
// let noise_a = self.a.get_noise_3d(pos_global.x as f64, pos_global.y as f64, pos_global.z as f64) * 0.5 + 0.5;
|
|
||||||
// let noise_b = self.b.get_noise_3d(pos_global.x as f64, pos_global.y as f64, pos_global.z as f64) * 0.5 + 0.5;
|
if noise_a.min(noise_b) > (0.6 + 0.4 * inv_cave_size) {
|
||||||
// if noise_a.min(noise_b) > (1. - (-y as f32 / 400.).clamp(0., 1.)) {
|
gen.place(pos, Block::Air);
|
||||||
// gen.place(pos, Block::Air);
|
}
|
||||||
// }
|
//TODO
|
||||||
// //TODO
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
32
kubi-shared/src/worldgen/_04_layers.rs
Normal file
32
kubi-shared/src/worldgen/_04_layers.rs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
use glam::ivec3;
|
||||||
|
use crate::{block::Block, chunk::CHUNK_SIZE};
|
||||||
|
use super::{WorldGenStep, WorldGenerator, _02_water::WATER_LEVEL};
|
||||||
|
pub struct LayersStep;
|
||||||
|
|
||||||
|
impl WorldGenStep for LayersStep {
|
||||||
|
fn initialize(_: &WorldGenerator) -> Self { Self }
|
||||||
|
|
||||||
|
fn generate(&mut self, gen: &mut WorldGenerator) {
|
||||||
|
for x in 0..CHUNK_SIZE as i32 {
|
||||||
|
for z in 0..CHUNK_SIZE as i32 {
|
||||||
|
let terrain_height = gen.data.master_height_map.as_ref().unwrap()[x as usize][z as usize];
|
||||||
|
|
||||||
|
// Dirt layer height, naturally gets thinner as height gets deeper
|
||||||
|
let mut dirt_layer_height = (((terrain_height as f32 + 15.) / 20.).clamp(0., 1.) * 8.).round() as i32;
|
||||||
|
dirt_layer_height -= (gen.seeded_hash((x, z, 1)) & 1) as i32; //+ (gen.seeded_hash((x, z, 0xbau8)) & 1) as i32;
|
||||||
|
|
||||||
|
// Place dirt layer
|
||||||
|
for y in gen.local_height(terrain_height - dirt_layer_height)..gen.local_height(terrain_height) {
|
||||||
|
gen.place(ivec3(x, y, z), Block::Dirt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If above water level, place grass
|
||||||
|
if terrain_height >= WATER_LEVEL {
|
||||||
|
if let Some(local_y) = gen.local_y_position(terrain_height - 1) {
|
||||||
|
gen.place(ivec3(x, local_y, z), Block::Grass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
kubi-shared/src/worldgen/_05_decorate.rs
Normal file
28
kubi-shared/src/worldgen/_05_decorate.rs
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
use glam::ivec3;
|
||||||
|
use crate::{block::Block, chunk::CHUNK_SIZE};
|
||||||
|
use super::{WorldGenStep, WorldGenerator, _02_water::WATER_LEVEL};
|
||||||
|
|
||||||
|
pub struct DecorateStep;
|
||||||
|
|
||||||
|
impl WorldGenStep for DecorateStep {
|
||||||
|
fn initialize(_: &WorldGenerator) -> Self { Self }
|
||||||
|
|
||||||
|
fn generate(&mut self, gen: &mut WorldGenerator) {
|
||||||
|
for x in 0..CHUNK_SIZE as i32 {
|
||||||
|
for z in 0..CHUNK_SIZE as i32 {
|
||||||
|
let global_xz = gen.global_position(ivec3(x, 0, z));
|
||||||
|
|
||||||
|
let terrain_height = gen.data.master_height_map.as_ref().unwrap()[x as usize][z as usize];
|
||||||
|
|
||||||
|
//Place tall grass
|
||||||
|
if terrain_height >= WATER_LEVEL {
|
||||||
|
if let Some(local_y) = gen.local_y_position(terrain_height) {
|
||||||
|
if (gen.seeded_hash((global_xz.x, global_xz.z)) & 0xf) == 0xf {
|
||||||
|
gen.place_if_empty(ivec3(x, local_y, z), Block::TallGrass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue