mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Improved base_z => faster and smaller chunks!
This commit is contained in:
parent
d1c06e619f
commit
0b14ca2f3a
@ -146,7 +146,7 @@ impl<V, Storage: core::ops::DerefMut<Target=Vec<V>>, S: RectVolSize, M: Clone> C
|
||||
// First, defragment all subchunks.
|
||||
self.sub_chunks.iter_mut().for_each(SubChunk::defragment);
|
||||
// For each homogeneous subchunk (i.e. those where all blocks are the same),
|
||||
// find those which match `below` at the bottom of the cunk, or `above`
|
||||
// find those which match `below` at the bottom of the chunk, or `above`
|
||||
// at the top, since these subchunks are redundant and can be removed.
|
||||
// Note that we find (and drain) the above chunks first, so that when we
|
||||
// remove the below chunks we have fewer remaining chunks to backshift.
|
||||
|
@ -247,17 +247,17 @@ impl<V, S: core::ops::DerefMut<Target=Vec<V>> + VolSize<V>, M> Chunk<V, S, M> {
|
||||
#[inline(always)]
|
||||
fn grp_idx(pos: Vec3<i32>) -> u32 {
|
||||
let grp_pos = pos.map2(Self::GROUP_SIZE, |e, s| e as u32 / s);
|
||||
(grp_pos.z * (Self::GROUP_COUNT.y * Self::GROUP_COUNT.x))
|
||||
+ (grp_pos.y * Self::GROUP_COUNT.x)
|
||||
+ (grp_pos.x)
|
||||
(grp_pos.x * (Self::GROUP_COUNT.y * Self::GROUP_COUNT.z))
|
||||
+ (grp_pos.y * Self::GROUP_COUNT.z)
|
||||
+ (grp_pos.z)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn rel_idx(pos: Vec3<i32>) -> u32 {
|
||||
let rel_pos = pos.map2(Self::GROUP_SIZE, |e, s| e as u32 % s);
|
||||
(rel_pos.z * (Self::GROUP_SIZE.y * Self::GROUP_SIZE.x))
|
||||
+ (rel_pos.y * Self::GROUP_SIZE.x)
|
||||
+ (rel_pos.x)
|
||||
(rel_pos.x * (Self::GROUP_SIZE.y * Self::GROUP_SIZE.z))
|
||||
+ (rel_pos.y * Self::GROUP_SIZE.z)
|
||||
+ (rel_pos.z)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
@ -386,6 +386,56 @@ impl<V, S: VolSize<V>, M> Iterator for ChunkPosIter<V, S, M> {
|
||||
|
||||
#[inline(always)]
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.pos.x >= self.ub.x {
|
||||
return None;
|
||||
}
|
||||
let res = Some(self.pos);
|
||||
|
||||
self.pos.z += 1;
|
||||
if self.pos.z != self.ub.z && self.pos.z % Chunk::<V, S, M>::GROUP_SIZE.z as i32 != 0 {
|
||||
return res;
|
||||
}
|
||||
self.pos.z = std::cmp::max(
|
||||
self.lb.z,
|
||||
(self.pos.z - 1) & !(Chunk::<V, S, M>::GROUP_SIZE.z as i32 - 1),
|
||||
);
|
||||
|
||||
self.pos.y += 1;
|
||||
if self.pos.y != self.ub.y && self.pos.y % Chunk::<V, S, M>::GROUP_SIZE.y as i32 != 0 {
|
||||
return res;
|
||||
}
|
||||
self.pos.y = std::cmp::max(
|
||||
self.lb.y,
|
||||
(self.pos.y - 1) & !(Chunk::<V, S, M>::GROUP_SIZE.y as i32 - 1),
|
||||
);
|
||||
|
||||
self.pos.x += 1;
|
||||
if self.pos.x != self.ub.x && self.pos.x % Chunk::<V, S, M>::GROUP_SIZE.x as i32 != 0 {
|
||||
return res;
|
||||
}
|
||||
self.pos.x = std::cmp::max(
|
||||
self.lb.x,
|
||||
(self.pos.x - 1) & !(Chunk::<V, S, M>::GROUP_SIZE.x as i32 - 1),
|
||||
);
|
||||
|
||||
self.pos.z = (self.pos.z | (Chunk::<V, S, M>::GROUP_SIZE.z as i32 - 1)) + 1;
|
||||
if self.pos.z < self.ub.z {
|
||||
return res;
|
||||
}
|
||||
self.pos.z = self.lb.z;
|
||||
|
||||
self.pos.y = (self.pos.y | (Chunk::<V, S, M>::GROUP_SIZE.y as i32 - 1)) + 1;
|
||||
if self.pos.y < self.ub.y {
|
||||
return res;
|
||||
}
|
||||
self.pos.y = self.lb.y;
|
||||
|
||||
self.pos.x = (self.pos.x | (Chunk::<V, S, M>::GROUP_SIZE.x as i32 - 1)) + 1;
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
/* fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.pos.z >= self.ub.z {
|
||||
return None;
|
||||
}
|
||||
@ -433,7 +483,7 @@ impl<V, S: VolSize<V>, M> Iterator for ChunkPosIter<V, S, M> {
|
||||
self.pos.z = (self.pos.z | (Chunk::<V, S, M>::GROUP_SIZE.z as i32 - 1)) + 1;
|
||||
|
||||
res
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
pub struct ChunkVolIter<'a, V, S: VolSize<V>, M> {
|
||||
|
@ -299,10 +299,10 @@ fn dungeon(c: &mut Criterion) {
|
||||
bench_group("generate_citadel", "render_citadel", Site::generate_citadel);
|
||||
|
||||
c.bench_function("generate_chunk", |b| {
|
||||
// let chunk_pos = (world.sim().map_size_lg().chunks() >> 1).as_();
|
||||
let chunk_pos = (world.sim().map_size_lg().chunks() >> 1).as_();
|
||||
// let chunk_pos = Vec2::new(9500 / 32, 29042 / 32);
|
||||
// let chunk_pos = Vec2::new(26944 / 32, 26848 / 32);
|
||||
let chunk_pos = Vec2::new(842, 839);
|
||||
// let chunk_pos = Vec2::new(842, 839);
|
||||
// let chunk_pos = Vec2::new(24507/32, 20682/32);
|
||||
// let chunk_pos = Vec2::new(19638/32, 19621/32);
|
||||
b.iter(|| {
|
||||
@ -311,10 +311,10 @@ fn dungeon(c: &mut Criterion) {
|
||||
});
|
||||
|
||||
c.bench_function("deserialize_chunk", |b| {
|
||||
// let chunk_pos = (world.sim().map_size_lg().chunks() >> 1).as_();
|
||||
let chunk_pos = (world.sim().map_size_lg().chunks() >> 1).as_();
|
||||
// let chunk_pos = Vec2::new(9500 / 32, 29042 / 32);
|
||||
// let chunk_pos = Vec2::new(26944 / 32, 26848 / 32);
|
||||
let chunk_pos = Vec2::new(842, 839);
|
||||
// let chunk_pos = Vec2::new(842, 839);
|
||||
let chunk = world.generate_chunk(index.as_index_ref(), chunk_pos, || false, None).unwrap().0;
|
||||
/* println!("{:?}", chunk.sub_chunks_len());
|
||||
let chunk = chunk.sub_chunks().next().unwrap(); */
|
||||
|
@ -239,12 +239,39 @@ impl World {
|
||||
let calendar = self.sim.calendar.as_ref();
|
||||
|
||||
// FIXME: Deal with this properly if it's not okay to exit early.
|
||||
let mut sampler = self.sample_blocks(chunk_pos, index/*, calendar*/).ok_or(())?;
|
||||
let sampler = self.sample_blocks(chunk_pos, index/*, calendar*/);
|
||||
// dbg!(&sampler.column_gen.chaos_spline);
|
||||
|
||||
let air = Block::air(SpriteKind::Empty);
|
||||
let water = Block::new(BlockKind::Water, Rgb::zero());
|
||||
let (/*base_z, */sim_chunk, mut sampler) = match sampler/*.zip(
|
||||
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(),
|
||||
)
|
||||
.and_then(|base_z| self.sim.get(chunk_pos).map(|sim_chunk| (base_z, sim_chunk))) */
|
||||
.get_base_z(chunk_pos))*/
|
||||
{
|
||||
/* Some((sampler, base_z)) => (base_z as i32, sampler.column_gen.sim_chunk, sampler),*/
|
||||
Some(sampler) => (/*base_z as i32, */sampler.column_gen.sim_chunk, sampler),
|
||||
// Some((base_z, sim_chunk)) => (base_z as i32, sim_chunk),
|
||||
None => {
|
||||
return Ok((
|
||||
TerrainChunk::new(
|
||||
CONFIG.sea_level as i32,
|
||||
water,
|
||||
air,
|
||||
TerrainChunkMeta::void(),
|
||||
),
|
||||
ChunkSupplement::default(),
|
||||
));
|
||||
},
|
||||
};
|
||||
|
||||
let grid_border = /*4*/0;
|
||||
let chunk_wpos2d = chunk_pos * TerrainChunkSize::RECT_SIZE.map(|e| e as i32);
|
||||
let chunk_center_wpos2d = chunk_wpos2d + TerrainChunkSize::RECT_SIZE.map(|e| e as i32 / 2);
|
||||
let grid_border = /*4*/0;
|
||||
let zcache_grid: Grid<ColumnSample> =
|
||||
Grid::populate_by_row::<_, _, {TerrainChunkSize::RECT_SIZE.x}, {TerrainChunkSize::RECT_SIZE.y}>(
|
||||
/* TerrainChunkSize::RECT_SIZE.map(|e| e as i32) + grid_border * 2, */
|
||||
@ -260,7 +287,12 @@ impl World {
|
||||
/* |offs| sampler.get_z_cache(chunk_wpos2d - grid_border + offs/*, index, calendar*/)/*None*/ */
|
||||
);
|
||||
|
||||
let air = Block::air(SpriteKind::Empty);
|
||||
let base_z = ZCache {
|
||||
sample: zcache_grid.get(grid_border + TerrainChunkSize::RECT_SIZE.map(|e| e as i32) / 2) .unwrap()
|
||||
}
|
||||
.get_z_limits()
|
||||
.0 as i32 + 4;
|
||||
|
||||
let stone = Block::new(
|
||||
BlockKind::Rock,
|
||||
zcache_grid
|
||||
@ -269,32 +301,6 @@ impl World {
|
||||
.map(|zcache| zcache/*.sample*/.stone_col)
|
||||
.unwrap_or_else(|| index.colors.deep_stone_color.into()),
|
||||
);
|
||||
let water = Block::new(BlockKind::Water, Rgb::zero());
|
||||
|
||||
let (base_z, sim_chunk) = 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(),
|
||||
)
|
||||
.and_then(|base_z| self.sim.get(chunk_pos).map(|sim_chunk| (base_z, sim_chunk))) */
|
||||
.get_base_z(chunk_pos)
|
||||
{
|
||||
Some(base_z) => (base_z as i32, self.sim.get(chunk_pos).unwrap()),
|
||||
// Some((base_z, sim_chunk)) => (base_z as i32, sim_chunk),
|
||||
None => {
|
||||
return Ok((
|
||||
TerrainChunk::new(
|
||||
CONFIG.sea_level as i32,
|
||||
water,
|
||||
air,
|
||||
TerrainChunkMeta::void(),
|
||||
),
|
||||
ChunkSupplement::default(),
|
||||
));
|
||||
},
|
||||
};
|
||||
|
||||
let meta = TerrainChunkMeta::new(
|
||||
sim_chunk
|
||||
.sites
|
||||
@ -332,6 +338,11 @@ impl World {
|
||||
let mut chunk = TerrainChunk::new(base_z, stone, air, meta);
|
||||
let calendar = self.sim.calendar.as_ref();
|
||||
|
||||
let mut delta0 = 0;
|
||||
let mut delta1 = 0;
|
||||
let mut delta2 = 0;
|
||||
let mut delta3 = 0;
|
||||
let mut delta4 = 0;
|
||||
for y in 0..TerrainChunkSize::RECT_SIZE.y as i32 {
|
||||
for x in 0..TerrainChunkSize::RECT_SIZE.x as i32 {
|
||||
if should_continue() {
|
||||
@ -351,10 +362,22 @@ impl World {
|
||||
let (min_z, max_z) = z_cache.get_z_limits();
|
||||
/* let max_z = min_z + 1.0;
|
||||
let base_z = min_z as i32 - 1; */
|
||||
delta0 = delta0.max(min_z as i32 - base_z);
|
||||
delta1 = delta1.max(base_z - min_z as i32);
|
||||
delta2 += (min_z as i32 - base_z).max(0);
|
||||
delta4 += (base_z - max_z as i32).max(0);
|
||||
|
||||
/* if base_z as f32 > min_z {
|
||||
dbg!(base_z, min_z, max_z, chunk_pos, sim_chunk);
|
||||
panic!("base_z > min_z");
|
||||
} */
|
||||
|
||||
(base_z..min_z as i32).for_each(|z| {
|
||||
let _ = chunk.set(Vec3::new(x, y, z), stone);
|
||||
});
|
||||
(max_z as i32..base_z).for_each(|z| {
|
||||
let _ = chunk.set(Vec3::new(x, y, z), air);
|
||||
});
|
||||
|
||||
let mut block_ = None;
|
||||
(min_z as i32..max_z as i32).for_each(|z| {
|
||||
@ -363,7 +386,11 @@ impl World {
|
||||
|
||||
if let Some(block) = sampler.get_with_z_cache(wpos, /*Some(&*/z_cache/*)*/) {
|
||||
// block_ = Some(block);
|
||||
// let _ = chunk.set(lpos, block);
|
||||
let _ = chunk.set(lpos, block);
|
||||
}else if z < base_z {
|
||||
let _ = chunk.set(lpos, air);
|
||||
delta3 += 1;
|
||||
}
|
||||
});
|
||||
if let Some(block_) = block_ {
|
||||
@ -371,6 +398,20 @@ impl World {
|
||||
}
|
||||
}
|
||||
}
|
||||
if /*delta1 > 0*/delta2 + delta3 + delta4 > 1024 {
|
||||
let delta2 = delta2 as f32 / 1024.0;
|
||||
let delta3 = delta3 as f32 / 1024.0;
|
||||
let delta4 = delta4 as f32 / 1024.0;
|
||||
/* dbg!(
|
||||
sim_chunk,
|
||||
base_z,
|
||||
delta0,
|
||||
delta1,
|
||||
delta2,
|
||||
delta3,
|
||||
delta4,
|
||||
); */
|
||||
}
|
||||
|
||||
let sample_get = |offs| {
|
||||
zcache_grid
|
||||
|
@ -2480,7 +2480,7 @@ impl SimChunk {
|
||||
self.water_alt > self.alt || self.river.river_kind.is_some()
|
||||
}
|
||||
|
||||
pub fn get_base_z(&self) -> f32 { self.alt - self.chaos * 50.0 - 16.0 }
|
||||
pub fn get_base_z(&self) -> f32 { self.alt/* - self.chaos * 16.0 - self.cliff_height.max(0.0) * /*3.125.powf(1.5)*/5.625 - 4.0/*/* * 50.0 - 16.0 */- 7.5*/*/ - 6.0 }
|
||||
|
||||
pub fn get_biome(&self) -> BiomeKind {
|
||||
let savannah_hum_temp = [0.05..0.55, 0.3..1.6];
|
||||
|
Loading…
Reference in New Issue
Block a user