From c919f6fc83b6825c574c0561773bc76f85736a80 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sat, 25 May 2019 06:38:40 +0100 Subject: [PATCH] Better tree spawning, more trees Former-commit-id: abf4ff8a2eb005c2cd1832f5a3ae7182c4fc31f6 --- assets/world/tree/oak/1.vox | 3 +++ assets/world/tree/oak/2.vox | 3 +++ assets/world/tree/oak/3.vox | 3 +++ assets/world/tree/pine/4.vox | 3 +++ assets/world/tree/pine/5.vox | 3 +++ assets/world/tree/temperate/1.vox | 3 +++ assets/world/tree/temperate/2.vox | 3 +++ assets/world/tree/temperate/3.vox | 3 +++ assets/world/tree/temperate/4.vox | 3 +++ assets/world/tree/temperate/5.vox | 3 +++ assets/world/tree/temperate/6.vox | 3 +++ world/src/lib.rs | 11 -------- world/src/sim.rs | 45 ++++++++++++++++++++++--------- world/src/structure.rs | 10 +++---- 14 files changed, 71 insertions(+), 28 deletions(-) create mode 100644 assets/world/tree/oak/1.vox create mode 100644 assets/world/tree/oak/2.vox create mode 100644 assets/world/tree/oak/3.vox create mode 100644 assets/world/tree/pine/4.vox create mode 100644 assets/world/tree/pine/5.vox create mode 100644 assets/world/tree/temperate/1.vox create mode 100644 assets/world/tree/temperate/2.vox create mode 100644 assets/world/tree/temperate/3.vox create mode 100644 assets/world/tree/temperate/4.vox create mode 100644 assets/world/tree/temperate/5.vox create mode 100644 assets/world/tree/temperate/6.vox diff --git a/assets/world/tree/oak/1.vox b/assets/world/tree/oak/1.vox new file mode 100644 index 0000000000..203278ad8f --- /dev/null +++ b/assets/world/tree/oak/1.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:35751de0589d71666113dfea340a507be7fdc8dbe915ee391d65af618df2cdb2 +size 80890 diff --git a/assets/world/tree/oak/2.vox b/assets/world/tree/oak/2.vox new file mode 100644 index 0000000000..3d8275e987 --- /dev/null +++ b/assets/world/tree/oak/2.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:673d193d0d764ba88c666164d7cddd611353d25a189a94e83abdaf2fc57724e8 +size 89306 diff --git a/assets/world/tree/oak/3.vox b/assets/world/tree/oak/3.vox new file mode 100644 index 0000000000..7b92c5c638 --- /dev/null +++ b/assets/world/tree/oak/3.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fdb21e9e2511957496a5393314f61f6be8e6b32ffd4ed624f9bbc0283ec08b4e +size 114974 diff --git a/assets/world/tree/pine/4.vox b/assets/world/tree/pine/4.vox new file mode 100644 index 0000000000..ecd2c744ed --- /dev/null +++ b/assets/world/tree/pine/4.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:59759c3514ee0b801b8ca1c9924b3a81a183d621e8af95eabf93942d1802c728 +size 54202 diff --git a/assets/world/tree/pine/5.vox b/assets/world/tree/pine/5.vox new file mode 100644 index 0000000000..698bc1c557 --- /dev/null +++ b/assets/world/tree/pine/5.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e352fb6ed3d2a91e53af5bce46bff390d4af2c1d0044d96747cbb65706de43c +size 56194 diff --git a/assets/world/tree/temperate/1.vox b/assets/world/tree/temperate/1.vox new file mode 100644 index 0000000000..cd2bc5e392 --- /dev/null +++ b/assets/world/tree/temperate/1.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:35f3f75a98d65d7ade303de43bc5a5f73f1164e4ce2109729e2e7ed2ff25241b +size 45199 diff --git a/assets/world/tree/temperate/2.vox b/assets/world/tree/temperate/2.vox new file mode 100644 index 0000000000..95aa68c7cf --- /dev/null +++ b/assets/world/tree/temperate/2.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fd52f715f8f7ec53aa6fdade3588f4eac10f8d28ced35d89156fbb6952124410 +size 45415 diff --git a/assets/world/tree/temperate/3.vox b/assets/world/tree/temperate/3.vox new file mode 100644 index 0000000000..671519b840 --- /dev/null +++ b/assets/world/tree/temperate/3.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ecb880b8f653cb78117bbe4555931e36291f6ebd03adbb86ae051c90889015c3 +size 45395 diff --git a/assets/world/tree/temperate/4.vox b/assets/world/tree/temperate/4.vox new file mode 100644 index 0000000000..a33843f02f --- /dev/null +++ b/assets/world/tree/temperate/4.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8b0cc528255d725e4ffc198ac5b724b81e040ca0f406f251d677c1b64cd2181 +size 45063 diff --git a/assets/world/tree/temperate/5.vox b/assets/world/tree/temperate/5.vox new file mode 100644 index 0000000000..db8d9e5306 --- /dev/null +++ b/assets/world/tree/temperate/5.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0c1fadff5bbc66d0ccf5a9a737e44e4ff93191dbb8baf1b809770c51f2ba416d +size 45055 diff --git a/assets/world/tree/temperate/6.vox b/assets/world/tree/temperate/6.vox new file mode 100644 index 0000000000..c093a4241e --- /dev/null +++ b/assets/world/tree/temperate/6.vox @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b20e5ad4149174f2d1176b22cb21f87bb5ab03a3b6edbce04191d7f65127655f +size 45231 diff --git a/world/src/lib.rs b/world/src/lib.rs index da718b3c2e..8909f25e6d 100644 --- a/world/src/lib.rs +++ b/world/src/lib.rs @@ -64,17 +64,6 @@ impl World { + Vec3::from(chunk_pos) * TerrainChunkSize::SIZE.map(|e| e as i32); let wposf2d = wpos2d.map(|e| e as f64); - let sim::Sample2d { - alt, - chaos, - surface_color, - close_trees, - } = if let Some(sample) = world_sampler.sample_2d(wpos2d) { - sample - } else { - continue; - }; - let max_z = self .sim .get_interpolated(wpos2d, |chunk| chunk.get_max_z()) diff --git a/world/src/sim.rs b/world/src/sim.rs index 035c083bbd..9bc7377373 100644 --- a/world/src/sim.rs +++ b/world/src/sim.rs @@ -43,6 +43,7 @@ impl WorldSim { small_nz: BasicMulti::new().set_octaves(2).set_seed(seed + 6), rock_nz: HybridMulti::new().set_persistence(0.3).set_seed(seed + 7), warp_nz: BasicMulti::new().set_octaves(3).set_seed(seed + 8), + tree_nz: BasicMulti::new().set_octaves(6).set_seed(seed + 9), }; let mut chunks = Vec::new(); @@ -56,7 +57,7 @@ impl WorldSim { seed, chunks, gen_ctx, - tree_gen: StructureGen2d::new(seed, 96, 128), + tree_gen: StructureGen2d::new(seed, 32, 32), } } @@ -141,6 +142,7 @@ impl<'a> Sampler<'a> { let chaos = sim.get_interpolated(wpos, |chunk| chunk.chaos)?; let temp = sim.get_interpolated(wpos, |chunk| chunk.temp)?; let rockiness = sim.get_interpolated(wpos, |chunk| chunk.rockiness)?; + let tree_density = sim.get_interpolated(wpos, |chunk| chunk.tree_density)?; let rock = (sim.gen_ctx.small_nz.get((wposf.div(100.0)).into_array()) as f32) .mul(rockiness) @@ -191,6 +193,7 @@ impl<'a> Sampler<'a> { // Beach (alt - SEA_LEVEL - 2.0) / 5.0, ), + tree_density, close_trees: sim.tree_gen.sample(wpos), }) } @@ -210,6 +213,7 @@ impl<'a> Sampler<'a> { alt, chaos, surface_color, + tree_density, close_trees, } = *self.sample_2d(wpos2d)?; @@ -235,15 +239,15 @@ impl<'a> Sampler<'a> { let above_ground = (&close_trees) .iter() - .fold(air, |block, tree| { - match self.sample_2d(*tree) { - Some(tree_sample) => { - let tree_pos = Vec3::new(tree.x, tree.y, tree_sample.alt as i32); - block.or(TREE.get(wpos - tree_pos) + .fold(air, |block, (tree_pos, tree_seed)| { + match self.sample_2d(*tree_pos) { + Some(tree_sample) if tree_sample.tree_density > 0.5 => { + let tree_pos3d = Vec3::new(tree_pos.x, tree_pos.y, tree_sample.alt as i32); + block.or(TREES[*tree_seed as usize % TREES.len()].get(wpos - tree_pos3d) .map(|b| b.clone()) .unwrap_or(Block::empty())) }, - None => block, + _ => block, } }); @@ -263,10 +267,20 @@ impl<'a> Sampler<'a> { } lazy_static! { - static ref TREE: Arc = assets::load_map( - "world/tree/pine/3.vox", - |s: Structure| s.with_center(Vec3::new(15, 15, 14)), - ).unwrap(); + static ref TREES: [Arc; 12] = [ + assets::load_map("world/tree/oak/1.vox", |s: Structure| s.with_center(Vec3::new(15, 18, 14))).unwrap(), + assets::load_map("world/tree/oak/2.vox", |s: Structure| s.with_center(Vec3::new(15, 18, 14))).unwrap(), + assets::load_map("world/tree/oak/3.vox", |s: Structure| s.with_center(Vec3::new(15, 18, 14))).unwrap(), + assets::load_map("world/tree/pine/3.vox", |s: Structure| s.with_center(Vec3::new(15, 15, 14))).unwrap(), + assets::load_map("world/tree/pine/4.vox", |s: Structure| s.with_center(Vec3::new(15, 15, 14))).unwrap(), + assets::load_map("world/tree/pine/5.vox", |s: Structure| s.with_center(Vec3::new(15, 15, 12))).unwrap(), + assets::load_map("world/tree/temperate/1.vox", |s: Structure| s.with_center(Vec3::new(4, 4, 7))).unwrap(), + assets::load_map("world/tree/temperate/2.vox", |s: Structure| s.with_center(Vec3::new(4, 4, 7))).unwrap(), + assets::load_map("world/tree/temperate/3.vox", |s: Structure| s.with_center(Vec3::new(4, 4, 7))).unwrap(), + assets::load_map("world/tree/temperate/4.vox", |s: Structure| s.with_center(Vec3::new(4, 4, 7))).unwrap(), + assets::load_map("world/tree/temperate/5.vox", |s: Structure| s.with_center(Vec3::new(4, 4, 7))).unwrap(), + assets::load_map("world/tree/temperate/6.vox", |s: Structure| s.with_center(Vec3::new(4, 4, 7))).unwrap(), + ]; } #[derive(Copy, Clone)] @@ -274,7 +288,8 @@ pub struct Sample2d { pub alt: f32, pub chaos: f32, pub surface_color: Rgb, - pub close_trees: [Vec2; 9], + pub tree_density: f32, + pub close_trees: [(Vec2, u32); 9], } #[derive(Copy, Clone)] @@ -292,6 +307,7 @@ struct GenCtx { small_nz: BasicMulti, rock_nz: HybridMulti, warp_nz: BasicMulti, + tree_nz: BasicMulti, } const Z_TOLERANCE: (f32, f32) = (48.0, 64.0); @@ -303,6 +319,7 @@ pub struct SimChunk { pub alt: f32, pub temp: f32, pub rockiness: f32, + pub tree_density: f32, } impl SimChunk { @@ -351,6 +368,10 @@ impl SimChunk { .sub(0.1) .mul(1.2) .max(0.0), + tree_density: (gen_ctx.tree_nz.get((wposf.div(1024.0)).into_array()) as f32) + .add(1.0) + .mul(0.5) + .mul(1.0 - chaos * 0.75), } } diff --git a/world/src/structure.rs b/world/src/structure.rs index 54c3a886ac..55e5a5a532 100644 --- a/world/src/structure.rs +++ b/world/src/structure.rs @@ -25,11 +25,11 @@ impl StructureGen2d { let next = next.rotate_left(13).wrapping_mul(313322) ^ 0xDEADBEEF; let next = next.rotate_left(13).wrapping_mul(929009) ^ 0xFF329DE3; let next = next.rotate_left(13).wrapping_mul(422671) ^ 0x42892942; - next & 0xFFFF + next } - pub fn sample(&self, sample_pos: Vec2) -> [Vec2; 9] { - let mut samples = [Vec2::zero(); 9]; + pub fn sample(&self, sample_pos: Vec2) -> [(Vec2, u32); 9] { + let mut samples = [(Vec2::zero(), 0); 9]; let sample_closest = sample_pos.map(|e| e - e.rem_euclid(self.freq as i32)); @@ -38,10 +38,10 @@ impl StructureGen2d { let center = sample_closest + Vec2::new(i, j).map(|e| e as i32 - 1) * self.freq as i32 + self.freq as i32 / 2; - samples[i * 3 + j] = center + Vec2::new( + samples[i * 3 + j] = (center + Vec2::new( (self.random(1, center) % (self.spread * 2)) as i32 - self.spread as i32, (self.random(2, center) % (self.spread * 2)) as i32 - self.spread as i32, - ); + ), self.random(3, center)); } }