mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'imbris/mesh-speed' into 'master'
Cache most recent chunk access in terrain meshing See merge request veloren/veloren!522
This commit is contained in:
commit
9ef7036024
@ -3,7 +3,7 @@ use crate::{
|
||||
volumes::dyna::DynaError,
|
||||
};
|
||||
use hashbrown::{hash_map, HashMap};
|
||||
use std::{fmt::Debug, sync::Arc};
|
||||
use std::{fmt::Debug, ops::Deref, sync::Arc};
|
||||
use vek::*;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -159,6 +159,56 @@ impl<V: RectRasterableVol> VolGrid2d<V> {
|
||||
iter: self.chunks.iter(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cached<'a>(&'a self) -> CachedVolGrid2d<'a, V> {
|
||||
CachedVolGrid2d::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct CachedVolGrid2d<'a, V: RectRasterableVol> {
|
||||
vol_grid_2d: &'a VolGrid2d<V>,
|
||||
cache: Option<(Vec2<i32>, Arc<V>)>,
|
||||
}
|
||||
impl<'a, V: RectRasterableVol> CachedVolGrid2d<'a, V> {
|
||||
pub fn new(vol_grid_2d: &'a VolGrid2d<V>) -> Self {
|
||||
Self {
|
||||
vol_grid_2d,
|
||||
cache: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'a, V: RectRasterableVol + ReadVol> CachedVolGrid2d<'a, V> {
|
||||
// Note: this may be invalidated by mutations of the chunks hashmap
|
||||
#[inline(always)]
|
||||
pub fn get(&mut self, pos: Vec3<i32>) -> Result<&V::Vox, VolGrid2dError<V>> {
|
||||
let ck = VolGrid2d::<V>::chunk_key(pos);
|
||||
let chunk = if self
|
||||
.cache
|
||||
.as_ref()
|
||||
.map(|(key, _)| *key == ck)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
&self.cache.as_ref().unwrap().1
|
||||
} else {
|
||||
let chunk = self
|
||||
.vol_grid_2d
|
||||
.chunks
|
||||
.get(&ck)
|
||||
.ok_or(VolGrid2dError::NoSuchChunk)?;
|
||||
self.cache = Some((ck, chunk.clone()));
|
||||
chunk
|
||||
};
|
||||
let co = VolGrid2d::<V>::chunk_offs(pos);
|
||||
chunk.get(co).map_err(VolGrid2dError::ChunkError)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, V: RectRasterableVol> Deref for CachedVolGrid2d<'a, V> {
|
||||
type Target = VolGrid2d<V>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.vol_grid_2d
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ChunkIter<'a, V: RectRasterableVol> {
|
||||
|
@ -41,13 +41,15 @@ fn calc_light<V: RectRasterableVol<Vox = Block> + ReadVol + Debug>(
|
||||
max: bounds.max + sunlight,
|
||||
};
|
||||
|
||||
let mut vol_cached = vol.cached();
|
||||
|
||||
let mut voids = HashMap::new();
|
||||
let mut rays = vec![outer.size().d; outer.size().product() as usize];
|
||||
for x in 0..outer.size().w {
|
||||
for y in 0..outer.size().h {
|
||||
let mut outside = true;
|
||||
for z in (0..outer.size().d).rev() {
|
||||
let block = vol
|
||||
let block = vol_cached
|
||||
.get(outer.min + Vec3::new(x, y, z))
|
||||
.ok()
|
||||
.copied()
|
||||
@ -140,6 +142,8 @@ impl<V: RectRasterableVol<Vox = Block> + ReadVol + Debug> Meshable<TerrainPipeli
|
||||
|
||||
let light = calc_light(range, self);
|
||||
|
||||
let mut vol_cached = self.cached();
|
||||
|
||||
for x in range.min.x + 1..range.max.x - 1 {
|
||||
for y in range.min.y + 1..range.max.y - 1 {
|
||||
let mut lights = [[[0.0; 3]; 3]; 3];
|
||||
@ -155,9 +159,8 @@ impl<V: RectRasterableVol<Vox = Block> + ReadVol + Debug> Meshable<TerrainPipeli
|
||||
}
|
||||
}
|
||||
|
||||
let get_color = |pos| {
|
||||
self.get(pos)
|
||||
.ok()
|
||||
let get_color = |maybe_block: Option<&Block>| {
|
||||
maybe_block
|
||||
.filter(|vox| vox.is_opaque())
|
||||
.and_then(|vox| vox.get_color())
|
||||
.map(|col| Rgba::from_opaque(col))
|
||||
@ -169,9 +172,13 @@ impl<V: RectRasterableVol<Vox = Block> + ReadVol + Debug> Meshable<TerrainPipeli
|
||||
for j in 0..3 {
|
||||
for k in 0..3 {
|
||||
colors[k][j][i] = get_color(
|
||||
Vec3::new(x, y, range.min.z)
|
||||
+ Vec3::new(i as i32, j as i32, k as i32)
|
||||
- 1,
|
||||
vol_cached
|
||||
.get(
|
||||
Vec3::new(x, y, range.min.z)
|
||||
+ Vec3::new(i as i32, j as i32, k as i32)
|
||||
- 1,
|
||||
)
|
||||
.ok(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -193,11 +200,15 @@ impl<V: RectRasterableVol<Vox = Block> + ReadVol + Debug> Meshable<TerrainPipeli
|
||||
}
|
||||
for i in 0..3 {
|
||||
for j in 0..3 {
|
||||
colors[2][j][i] = get_color(pos + Vec3::new(i as i32, j as i32, 2) - 1);
|
||||
colors[2][j][i] = get_color(
|
||||
vol_cached
|
||||
.get(pos + Vec3::new(i as i32, j as i32, 2) - 1)
|
||||
.ok(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let block = self.get(pos).ok();
|
||||
let block = vol_cached.get(pos).ok();
|
||||
|
||||
// Create mesh polygons
|
||||
if block.map(|vox| vox.is_opaque()).unwrap_or(false) {
|
||||
|
Loading…
Reference in New Issue
Block a user