From 362387177558926a5c27857239d6688b3e80383a Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Fri, 5 Jul 2019 00:14:55 +0100 Subject: [PATCH] Initial implementation of z cache --- world/src/block/mod.rs | 68 +++++++++++++++++++++++++++++++----------- world/src/lib.rs | 6 ++-- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index 2ec165464c..301a79b221 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -74,20 +74,40 @@ impl<'a> BlockGen<'a> { }, ) } -} -impl<'a> SamplerMut for BlockGen<'a> { - type Index = Vec3; - type Sample = Option; - - fn get(&mut self, wpos: Vec3) -> Option { + pub fn get_z_cache(&mut self, wpos: Vec2) -> Option> { let BlockGen { world, column_cache, column_gen, } = self; - let ColumnSample { + let sample = Self::sample_column(column_gen, column_cache, wpos)?; + + let mut tree_samples = [None, None, None, None, None, None, None, None, None]; + + for i in 0..tree_samples.len() { + tree_samples[i] = Self::sample_column( + column_gen, + column_cache, + Vec2::from(sample.close_trees[i].0), + ); + } + + Some(ZCache { + sample, + tree_samples, + }) + } + + pub fn get_with_z_cache(&mut self, wpos: Vec3, z_cache: Option<&ZCache>) -> Option { + let BlockGen { + world, + column_cache, + column_gen, + } = self; + + let &ColumnSample { alt, chaos, water_level, @@ -105,7 +125,9 @@ impl<'a> SamplerMut for BlockGen<'a> { close_cliffs, //temp, .. - } = Self::sample_column(column_gen, column_cache, Vec2::from(wpos))?; + } = &z_cache?.sample; + + let tree_samples = &z_cache?.tree_samples; let wposf = wpos.map(|e| e as f64); @@ -285,17 +307,13 @@ impl<'a> SamplerMut for BlockGen<'a> { } else { match block { Some(block) => block, - None => (&close_trees) - .iter() - .fold(air, |block, (tree_pos, tree_seed)| { + None => (&close_trees).iter().enumerate().fold( + air, + |block, (tree_idx, (tree_pos, tree_seed))| { if !block.is_empty() { block } else { - match Self::sample_column( - column_gen, - column_cache, - Vec2::from(*tree_pos), - ) { + match &tree_samples[tree_idx] { Some(tree_sample) if tree_sample.tree_density > 0.5 + (*tree_seed as f32 / 1000.0).fract() * 0.2 @@ -332,10 +350,26 @@ impl<'a> SamplerMut for BlockGen<'a> { _ => block, } } - }), + }, + ), } }; Some(block) } } + +pub struct ZCache<'a> { + sample: ColumnSample<'a>, + tree_samples: [Option>; 9], +} + +impl<'a> SamplerMut for BlockGen<'a> { + type Index = Vec3; + type Sample = Option; + + fn get(&mut self, wpos: Vec3) -> Option { + let z_cache = self.get_z_cache(wpos.into()); + self.get_with_z_cache(wpos, z_cache.as_ref()) + } +} diff --git a/world/src/lib.rs b/world/src/lib.rs index f54460d297..15c691f0d9 100644 --- a/world/src/lib.rs +++ b/world/src/lib.rs @@ -52,7 +52,7 @@ impl World { ColumnGen::new(self) } - pub fn sample_blocks(&self) -> impl SamplerMut, Sample = Option> + '_ { + pub fn sample_blocks(&self) -> BlockGen { BlockGen::new(self, ColumnGen::new(self)) } @@ -96,12 +96,14 @@ impl World { .get_interpolated(wpos2d, |chunk| chunk.get_max_z()) .unwrap_or(0.0) as i32; + let z_cache = sampler.get_z_cache(wpos2d); + for z in min_z..max_z { let lpos = Vec3::new(x, y, z); let wpos = lpos + Vec3::from(chunk_pos) * TerrainChunkSize::SIZE.map(|e| e as i32); - if let Some(block) = sampler.get(wpos) { + if let Some(block) = sampler.get_with_z_cache(wpos, z_cache.as_ref()) { let _ = chunk.set(lpos, block); } }