From a49e061c7b6ae59c40b09857f6b58b8e69a9a11b Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 4 Jun 2019 18:19:40 +0100 Subject: [PATCH] Added rocks --- common/src/terrain/chonk.rs | 4 +- voxygen/src/scene/terrain.rs | 12 +- world/src/lib.rs | 12 +- world/src/sim.rs | 256 +++++++++++++++++++---------------- 4 files changed, 151 insertions(+), 133 deletions(-) diff --git a/common/src/terrain/chonk.rs b/common/src/terrain/chonk.rs index eed0b24e8f..4373d378c5 100644 --- a/common/src/terrain/chonk.rs +++ b/common/src/terrain/chonk.rs @@ -35,11 +35,11 @@ impl Chonk { } } - pub fn get_z_min(&self) -> i32 { + pub fn get_min_z(&self) -> i32 { self.z_offset } - pub fn get_z_max(&self) -> i32 { + pub fn get_max_z(&self) -> i32 { self.z_offset + (self.sub_chunks.len() as u32 * SUB_CHUNK_HEIGHT) as i32 } diff --git a/voxygen/src/scene/terrain.rs b/voxygen/src/scene/terrain.rs index 9b072e9564..8e1a39d57c 100644 --- a/voxygen/src/scene/terrain.rs +++ b/voxygen/src/scene/terrain.rs @@ -143,16 +143,16 @@ impl Terrain { }; // The region to actually mesh - let z_min = volume + let min_z = volume .iter() - .fold(i32::MAX, |min, (_, chunk)| chunk.get_z_min().min(min)); - let z_max = volume + .fold(i32::MAX, |min, (_, chunk)| chunk.get_min_z().min(min)); + let max_z = volume .iter() - .fold(i32::MIN, |max, (_, chunk)| chunk.get_z_max().max(max)); + .fold(i32::MIN, |max, (_, chunk)| chunk.get_max_z().max(max)); let aabb = Aabb { - min: Vec3::from(aabr.min) + Vec3::unit_z() * (z_min - 1), - max: Vec3::from(aabr.max) + Vec3::unit_z() * (z_max + 1), + min: Vec3::from(aabr.min) + Vec3::unit_z() * (min_z - 1), + max: Vec3::from(aabr.max) + Vec3::unit_z() * (max_z + 1), }; // Clone various things so that they can be moved into the thread. diff --git a/world/src/lib.rs b/world/src/lib.rs index a94a887a27..7fa22f96de 100644 --- a/world/src/lib.rs +++ b/world/src/lib.rs @@ -49,16 +49,16 @@ impl World { let warp_nz = BasicMulti::new().set_octaves(3).set_seed(self.sim.seed + 0); - let base_z = match self - .sim - .get(chunk_pos.map(|e| e as u32)) - .map(|chunk| chunk.get_base_z()) - { + let chunk_size2d = Vec2::from(TerrainChunkSize::SIZE); + let base_z = match self.sim.get_interpolated( + chunk_pos.map2(chunk_size2d, |e, sz: u32| e * sz as i32 + sz as i32 / 2), + |chunk| chunk.get_base_z(), + ) { Some(base_z) => base_z as i32, None => return TerrainChunk::new(0, water, air, TerrainChunkMeta::void()), }; - let mut chunk = TerrainChunk::new(base_z, stone, air, TerrainChunkMeta::void()); + let mut chunk = TerrainChunk::new(base_z - 8, stone, air, TerrainChunkMeta::void()); let mut world_sampler = self.sim.sampler(); diff --git a/world/src/sim.rs b/world/src/sim.rs index d38ed87a93..e5329f35de 100644 --- a/world/src/sim.rs +++ b/world/src/sim.rs @@ -75,7 +75,7 @@ impl WorldSim { seed, chunks, gen_ctx, - tree_gen: StructureGen2d::new(seed, 32, 28), + tree_gen: StructureGen2d::new(seed, 24, 16), } } @@ -165,15 +165,14 @@ impl<'a> Sampler<'a> { let rock = (sim.gen_ctx.small_nz.get((wposf.div(100.0)).into_array()) as f32) .mul(rockiness) - .sub(0.2) + .sub(0.35) .max(0.0) - .mul(2.0); + .mul(6.0); let alt = sim.get_interpolated(wpos, |chunk| chunk.alt)? + sim.gen_ctx.small_nz.get((wposf.div(256.0)).into_array()) as f32 * chaos.max(0.2) - * 64.0 - + rock * 15.0; + * 64.0; let wposf3d = Vec3::new(wposf.x, wposf.y, alt as f64); @@ -191,7 +190,7 @@ impl<'a> Sampler<'a> { let snow = Rgb::broadcast(1.0); let grass = Rgb::lerp(cold_grass, warm_grass, marble); - let grassland = Rgb::lerp(grass, warm_stone, rock.mul(5.0).min(0.8)); + let grassland = grass; //Rgb::lerp(grass, warm_stone, rock.mul(5.0).min(0.8)); let cliff = Rgb::lerp(cold_stone, warm_stone, marble); let ground = Rgb::lerp( @@ -240,9 +239,14 @@ impl<'a> Sampler<'a> { Rgb::lerp( cliff, snow, - (alt - SEA_LEVEL - 350.0 - alt_base - temp * 48.0) / 12.0, + (alt - SEA_LEVEL + - 0.3 * MOUNTAIN_HEIGHT + - alt_base + - temp * 96.0 + - marble * 24.0) + / 12.0, ), - (alt - SEA_LEVEL - 150.0) / 180.0, + (alt - SEA_LEVEL - 0.15 * MOUNTAIN_HEIGHT) / 180.0, ), // Beach (alt - SEA_LEVEL - 2.0) / 5.0, @@ -251,6 +255,7 @@ impl<'a> Sampler<'a> { close_trees: sim.tree_gen.sample(wpos), cave_xy, cave_alt, + rock, }) } @@ -275,6 +280,7 @@ impl<'a> Sampler<'a> { close_trees, cave_xy, cave_alt, + rock, } = *self.sample_2d(wpos2d)?; // Apply warping @@ -289,7 +295,6 @@ impl<'a> Sampler<'a> { .mul(110.0); let height = alt + warp; - let temp = 0.0; // Sample blocks @@ -298,6 +303,7 @@ impl<'a> Sampler<'a> { let dirt = Block::new(1, Rgb::new(128, 90, 0)); let sand = Block::new(1, Rgb::new(180, 150, 50)); let water = Block::new(1, Rgb::new(100, 150, 255)); + let warm_stone = Block::new(1, Rgb::new(165, 165, 90)); let ground_block = if (wposf.z as f32) < height - 4.0 { // Underground @@ -312,7 +318,8 @@ impl<'a> Sampler<'a> { None }; - let ground_block = if let Some(block) = ground_block { + // Caves + let block = ground_block.or_else(|| { // Underground let cave = cave_xy.powf(2.0) * (wposf.z as f32 - cave_alt) @@ -325,13 +332,20 @@ impl<'a> Sampler<'a> { if cave { None } else { - Some(block) + ground_block } - } else { - None - }; + }); - let block = match ground_block { + // Rocks + let block = block.or_else(|| { + if (height + 2.5 - wposf.z as f32).div(7.5).abs().powf(2.0) < rock { + Some(warm_stone) + } else { + None + } + }); + + let block = match block { Some(block) => block, None => (&close_trees) .iter() @@ -357,6 +371,114 @@ impl<'a> Sampler<'a> { } } +#[derive(Copy, Clone)] +pub struct Sample2d { + pub alt: f32, + pub chaos: f32, + pub surface_color: Rgb, + pub tree_density: f32, + pub close_trees: [(Vec2, u32); 9], + pub cave_xy: f32, + pub cave_alt: f32, + pub rock: f32, +} + +#[derive(Copy, Clone)] +pub struct Sample3d { + pub block: Block, +} + +pub const SEA_LEVEL: f32 = 128.0; +pub const MOUNTAIN_HEIGHT: f32 = 900.0; + +const Z_TOLERANCE: (f32, f32) = (64.0, 64.0); + +pub struct SimChunk { + pub chaos: f32, + pub alt_base: f32, + pub alt: f32, + pub temp: f32, + pub rockiness: f32, + pub tree_density: f32, +} + +impl SimChunk { + fn generate(pos: Vec2, gen_ctx: &mut GenCtx) -> Self { + let wposf = (pos * Vec2::from(TerrainChunkSize::SIZE)).map(|e| e as f64); + + let hill = (0.0 + + gen_ctx + .hill_nz + .get((wposf.div(3_500.0)).into_array()) + .mul(1.0) as f32 + + gen_ctx + .hill_nz + .get((wposf.div(1_000.0)).into_array()) + .mul(0.3) as f32) + .add(0.3) + .max(0.0); + + let chaos = (gen_ctx.chaos_nz.get((wposf.div(2_000.0)).into_array()) as f32) + .add(1.0) + .mul(0.5) + .powf(1.5) + .add(0.1 * hill); + + let chaos = chaos + chaos.mul(16.0).sin().mul(0.02); + + let alt_base = gen_ctx.alt_nz.get((wposf.div(6_000.0)).into_array()) as f32; + let alt_base = alt_base + .mul(0.4) + .add(alt_base.mul(128.0).sin().mul(0.005)) + .mul(800.0); + + let alt_main = gen_ctx.alt_nz.get((wposf.div(2_500.0)).into_array()) as f32; + + let alt = SEA_LEVEL + + alt_base + + (0.0 + + alt_main + + gen_ctx.small_nz.get((wposf.div(300.0)).into_array()) as f32 + * alt_main.max(0.05) + * chaos + * 1.6) + .add(1.0) + .mul(0.5) + .mul(chaos) + .mul(MOUNTAIN_HEIGHT); + + Self { + chaos, + alt_base, + alt, + temp: (gen_ctx.temp_nz.get((wposf.div(8192.0)).into_array()) as f32), + rockiness: (gen_ctx.rock_nz.get((wposf.div(1024.0)).into_array()) as f32) + .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.85) + .mul(1.25) + .add(0.1) + .mul(if alt > SEA_LEVEL + 2.0 { 1.0 } else { 0.0 }), + } + } + + pub fn get_base_z(&self) -> f32 { + self.alt + } + + pub fn get_min_z(&self) -> f32 { + self.alt - Z_TOLERANCE.0 * (self.chaos + 0.5) + } + + pub fn get_max_z(&self) -> f32 { + (self.alt + Z_TOLERANCE.1).max(SEA_LEVEL + 1.0) + } +} + lazy_static! { static ref TREES: [Arc; 61] = [ // green oaks @@ -653,107 +775,3 @@ lazy_static! { ]; } - -#[derive(Copy, Clone)] -pub struct Sample2d { - pub alt: f32, - pub chaos: f32, - pub surface_color: Rgb, - pub tree_density: f32, - pub close_trees: [(Vec2, u32); 9], - pub cave_xy: f32, - pub cave_alt: f32, -} - -#[derive(Copy, Clone)] -pub struct Sample3d { - pub block: Block, -} - -const Z_TOLERANCE: (f32, f32) = (126.0, 94.0); -pub const SEA_LEVEL: f32 = 128.0; - -pub struct SimChunk { - pub chaos: f32, - pub alt_base: f32, - pub alt: f32, - pub temp: f32, - pub rockiness: f32, - pub tree_density: f32, -} - -impl SimChunk { - fn generate(pos: Vec2, gen_ctx: &mut GenCtx) -> Self { - let wposf = (pos * Vec2::from(TerrainChunkSize::SIZE)).map(|e| e as f64); - - let hill = (0.0 - + gen_ctx - .hill_nz - .get((wposf.div(3_500.0)).into_array()) - .mul(1.0) as f32 - + gen_ctx - .hill_nz - .get((wposf.div(1_000.0)).into_array()) - .mul(0.3) as f32) - .add(0.3) - .max(0.0); - - let chaos = (gen_ctx.chaos_nz.get((wposf.div(4_000.0)).into_array()) as f32) - .add(1.0) - .mul(0.5) - .powf(1.5) - .add(0.1 * hill); - - let chaos = chaos + chaos.mul(16.0).sin().mul(0.02); - - let alt_base = gen_ctx.alt_nz.get((wposf.div(6_000.0)).into_array()) as f32; - let alt_base = alt_base - .mul(0.4) - .add(alt_base.mul(128.0).sin().mul(0.004)) - .mul(600.0); - - let alt_main = gen_ctx.alt_nz.get((wposf.div(1_500.0)).into_array()) as f32; - - let alt = SEA_LEVEL - + alt_base - + (0.0 - + alt_main - + gen_ctx.small_nz.get((wposf.div(300.0)).into_array()) as f32 - * alt_main.max(0.05) - * chaos - * 1.3) - .add(1.0) - .mul(0.5) - .mul(chaos) - .mul(1200.0); - - Self { - chaos, - alt_base, - alt, - temp: (gen_ctx.temp_nz.get((wposf.div(8192.0)).into_array()) as f32), - rockiness: (gen_ctx.rock_nz.get((wposf.div(1024.0)).into_array()) as f32) - .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.85) - .add(0.1) - .mul(if alt > SEA_LEVEL + 3.0 { 1.0 } else { 0.0 }), - } - } - - pub fn get_base_z(&self) -> f32 { - self.alt - 8.0 - } - - pub fn get_min_z(&self) -> f32 { - self.alt - Z_TOLERANCE.0 * (self.chaos + 0.3) - } - - pub fn get_max_z(&self) -> f32 { - (self.alt + Z_TOLERANCE.1).max(SEA_LEVEL) - } -}