Removed RefCell from column cache

This commit is contained in:
Joshua Barretto 2019-06-22 16:53:21 +01:00
parent d75160e2f8
commit b94c0ace8c
3 changed files with 34 additions and 24 deletions

Binary file not shown.

View File

@ -104,7 +104,7 @@ impl<V: BaseVol<Vox = Block> + ReadVol + Debug, S: VolSize + Clone> Meshable for
.ok() .ok()
.and_then(|vox| vox.get_opacity()) .and_then(|vox| vox.get_opacity())
{ {
(neighbour_light[0][i][j] * (1.0 - opacity * 0.4)) (neighbour_light[0][i][j] * (1.0 - opacity * 0.1))
.max(1.0 - opacity) .max(1.0 - opacity)
} else { } else {
(neighbour_light[0][i][j] * 1.025).min(1.0) (neighbour_light[0][i][j] * 1.025).min(1.0)

View File

@ -10,15 +10,12 @@ use common::{
vol::{ReadVol, Vox}, vol::{ReadVol, Vox},
}; };
use noise::NoiseFn; use noise::NoiseFn;
use std::{ use std::ops::{Add, Div, Mul, Neg, Sub};
cell::RefCell,
ops::{Add, Div, Mul, Neg, Sub},
};
use vek::*; use vek::*;
pub struct BlockGen<'a> { pub struct BlockGen<'a> {
world: &'a World, world: &'a World,
column_cache: RefCell<HashCache<Vec2<i32>, Option<ColumnSample<'a>>>>, column_cache: HashCache<Vec2<i32>, Option<ColumnSample<'a>>>,
column_gen: ColumnGen<'a>, column_gen: ColumnGen<'a>,
} }
@ -26,24 +23,31 @@ impl<'a> BlockGen<'a> {
pub fn new(world: &'a World, column_gen: ColumnGen<'a>) -> Self { pub fn new(world: &'a World, column_gen: ColumnGen<'a>) -> Self {
Self { Self {
world, world,
column_cache: RefCell::new(HashCache::with_capacity(1024)), column_cache: HashCache::with_capacity(64),
column_gen, column_gen,
} }
} }
fn sample_column(&self, wpos: Vec2<i32>) -> Option<ColumnSample> { fn sample_column(
let column_gen = &self.column_gen; column_gen: &ColumnGen<'a>,
self.column_cache cache: &mut HashCache<Vec2<i32>, Option<ColumnSample<'a>>>, wpos: Vec2<i32>,
.borrow_mut() ) -> Option<ColumnSample<'a>> {
cache
.get(Vec2::from(wpos), |wpos| column_gen.get(wpos)) .get(Vec2::from(wpos), |wpos| column_gen.get(wpos))
.clone() .clone()
} }
fn get_cliff_height(&self, wpos: Vec2<f32>, close_cliffs: &[(Vec2<i32>, u32); 9], cliff_hill: f32) -> f32 { fn get_cliff_height(
column_gen: &ColumnGen<'a>,
cache: &mut HashCache<Vec2<i32>, Option<ColumnSample<'a>>>,
wpos: Vec2<f32>,
close_cliffs: &[(Vec2<i32>, u32); 9],
cliff_hill: f32,
) -> f32 {
close_cliffs close_cliffs
.iter() .iter()
.fold(0.0f32, |max_height, (cliff_pos, seed)| { .fold(0.0f32, |max_height, (cliff_pos, seed)| {
match self.sample_column(Vec2::from(*cliff_pos)) { match Self::sample_column(column_gen, cache, Vec2::from(*cliff_pos)) {
Some(cliff_sample) if cliff_sample.cliffs => { Some(cliff_sample) if cliff_sample.cliffs => {
let cliff_pos3d = Vec3::from(*cliff_pos); let cliff_pos3d = Vec3::from(*cliff_pos);
@ -67,6 +71,12 @@ impl<'a> SamplerMut for BlockGen<'a> {
type Sample = Option<Block>; type Sample = Option<Block>;
fn get(&mut self, wpos: Vec3<i32>) -> Option<Block> { fn get(&mut self, wpos: Vec3<i32>) -> Option<Block> {
let BlockGen {
world,
column_cache,
column_gen,
} = self;
let ColumnSample { let ColumnSample {
alt, alt,
chaos, chaos,
@ -84,7 +94,7 @@ impl<'a> SamplerMut for BlockGen<'a> {
close_cliffs, close_cliffs,
temp, temp,
.. ..
} = self.sample_column(Vec2::from(wpos))?; } = Self::sample_column(column_gen, column_cache, Vec2::from(wpos))?;
let wposf = wpos.map(|e| e as f64); let wposf = wpos.map(|e| e as f64);
@ -108,12 +118,12 @@ impl<'a> SamplerMut for BlockGen<'a> {
alt + warp alt + warp
} else { } else {
let turb = Vec2::new( let turb = Vec2::new(
self.world.sim().gen_ctx.turb_x_nz.get((wposf.div(48.0)).into_array()) as f32, world.sim().gen_ctx.turb_x_nz.get((wposf.div(48.0)).into_array()) as f32,
self.world.sim().gen_ctx.turb_y_nz.get((wposf.div(48.0)).into_array()) as f32, world.sim().gen_ctx.turb_y_nz.get((wposf.div(48.0)).into_array()) as f32,
) * 12.0; ) * 12.0;
let wpos_turb = Vec2::from(wpos).map(|e: i32| e as f32) + turb; let wpos_turb = Vec2::from(wpos).map(|e: i32| e as f32) + turb;
let cliff_height = self.get_cliff_height(wpos_turb, &close_cliffs, cliff_hill); let cliff_height = Self::get_cliff_height(column_gen, column_cache, wpos_turb, &close_cliffs, cliff_hill);
(alt + warp).max(cliff_height) (alt + warp).max(cliff_height)
}; };
@ -179,9 +189,9 @@ impl<'a> SamplerMut for BlockGen<'a> {
// Rocks // Rocks
let block = block.or_else(|| { let block = block.or_else(|| {
if (height + 2.5 - wposf.z as f32).div(7.5).abs().powf(2.0) < rock { if (height + 2.5 - wposf.z as f32).div(7.5).abs().powf(2.0) < rock {
let field0 = RandomField::new(self.world.sim().seed + 0); let field0 = RandomField::new(world.sim().seed + 0);
let field1 = RandomField::new(self.world.sim().seed + 1); let field1 = RandomField::new(world.sim().seed + 1);
let field2 = RandomField::new(self.world.sim().seed + 2); let field2 = RandomField::new(world.sim().seed + 2);
Some(Block::new( Some(Block::new(
1, 1,
@ -248,13 +258,13 @@ impl<'a> SamplerMut for BlockGen<'a> {
.fold(air, |block, (tree_pos, tree_seed)| if !block.is_empty() { .fold(air, |block, (tree_pos, tree_seed)| if !block.is_empty() {
block block
} else { } else {
match self.sample_column(Vec2::from(*tree_pos)) { match Self::sample_column(column_gen, column_cache, Vec2::from(*tree_pos)) {
Some(tree_sample) Some(tree_sample)
if tree_sample.tree_density if tree_sample.tree_density
> 0.5 + (*tree_seed as f32 / 1000.0).fract() * 0.2 > 0.5 + (*tree_seed as f32 / 1000.0).fract() * 0.2
&& tree_sample.alt > tree_sample.water_level => && tree_sample.alt > tree_sample.water_level =>
{ {
let cliff_height = self.get_cliff_height(tree_pos.map(|e| e as f32), &tree_sample.close_cliffs, cliff_hill); let cliff_height = Self::get_cliff_height(column_gen, column_cache, tree_pos.map(|e| e as f32), &tree_sample.close_cliffs, cliff_hill);
let height = tree_sample.alt.max(cliff_height); let height = tree_sample.alt.max(cliff_height);
let tree_pos3d = Vec3::new(tree_pos.x, tree_pos.y, height as i32); let tree_pos3d = Vec3::new(tree_pos.x, tree_pos.y, height as i32);
let rpos = wpos - tree_pos3d; let rpos = wpos - tree_pos3d;