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.
|
// First, defragment all subchunks.
|
||||||
self.sub_chunks.iter_mut().for_each(SubChunk::defragment);
|
self.sub_chunks.iter_mut().for_each(SubChunk::defragment);
|
||||||
// For each homogeneous subchunk (i.e. those where all blocks are the same),
|
// 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.
|
// 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
|
// 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.
|
// 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)]
|
#[inline(always)]
|
||||||
fn grp_idx(pos: Vec3<i32>) -> u32 {
|
fn grp_idx(pos: Vec3<i32>) -> u32 {
|
||||||
let grp_pos = pos.map2(Self::GROUP_SIZE, |e, s| e as u32 / s);
|
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.x * (Self::GROUP_COUNT.y * Self::GROUP_COUNT.z))
|
||||||
+ (grp_pos.y * Self::GROUP_COUNT.x)
|
+ (grp_pos.y * Self::GROUP_COUNT.z)
|
||||||
+ (grp_pos.x)
|
+ (grp_pos.z)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn rel_idx(pos: Vec3<i32>) -> u32 {
|
fn rel_idx(pos: Vec3<i32>) -> u32 {
|
||||||
let rel_pos = pos.map2(Self::GROUP_SIZE, |e, s| e as u32 % s);
|
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.x * (Self::GROUP_SIZE.y * Self::GROUP_SIZE.z))
|
||||||
+ (rel_pos.y * Self::GROUP_SIZE.x)
|
+ (rel_pos.y * Self::GROUP_SIZE.z)
|
||||||
+ (rel_pos.x)
|
+ (rel_pos.z)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@ -386,6 +386,56 @@ impl<V, S: VolSize<V>, M> Iterator for ChunkPosIter<V, S, M> {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
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 {
|
if self.pos.z >= self.ub.z {
|
||||||
return None;
|
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;
|
self.pos.z = (self.pos.z | (Chunk::<V, S, M>::GROUP_SIZE.z as i32 - 1)) + 1;
|
||||||
|
|
||||||
res
|
res
|
||||||
}
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ChunkVolIter<'a, V, S: VolSize<V>, M> {
|
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);
|
bench_group("generate_citadel", "render_citadel", Site::generate_citadel);
|
||||||
|
|
||||||
c.bench_function("generate_chunk", |b| {
|
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(9500 / 32, 29042 / 32);
|
||||||
// let chunk_pos = Vec2::new(26944 / 32, 26848 / 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(24507/32, 20682/32);
|
||||||
// let chunk_pos = Vec2::new(19638/32, 19621/32);
|
// let chunk_pos = Vec2::new(19638/32, 19621/32);
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
@ -311,10 +311,10 @@ fn dungeon(c: &mut Criterion) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
c.bench_function("deserialize_chunk", |b| {
|
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(9500 / 32, 29042 / 32);
|
||||||
// let chunk_pos = Vec2::new(26944 / 32, 26848 / 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;
|
let chunk = world.generate_chunk(index.as_index_ref(), chunk_pos, || false, None).unwrap().0;
|
||||||
/* println!("{:?}", chunk.sub_chunks_len());
|
/* println!("{:?}", chunk.sub_chunks_len());
|
||||||
let chunk = chunk.sub_chunks().next().unwrap(); */
|
let chunk = chunk.sub_chunks().next().unwrap(); */
|
||||||
|
@ -239,12 +239,39 @@ impl World {
|
|||||||
let calendar = self.sim.calendar.as_ref();
|
let calendar = self.sim.calendar.as_ref();
|
||||||
|
|
||||||
// FIXME: Deal with this properly if it's not okay to exit early.
|
// 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);
|
// 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_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 chunk_center_wpos2d = chunk_wpos2d + TerrainChunkSize::RECT_SIZE.map(|e| e as i32 / 2);
|
||||||
let grid_border = /*4*/0;
|
|
||||||
let zcache_grid: Grid<ColumnSample> =
|
let zcache_grid: Grid<ColumnSample> =
|
||||||
Grid::populate_by_row::<_, _, {TerrainChunkSize::RECT_SIZE.x}, {TerrainChunkSize::RECT_SIZE.y}>(
|
Grid::populate_by_row::<_, _, {TerrainChunkSize::RECT_SIZE.x}, {TerrainChunkSize::RECT_SIZE.y}>(
|
||||||
/* TerrainChunkSize::RECT_SIZE.map(|e| e as i32) + grid_border * 2, */
|
/* 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*/ */
|
/* |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(
|
let stone = Block::new(
|
||||||
BlockKind::Rock,
|
BlockKind::Rock,
|
||||||
zcache_grid
|
zcache_grid
|
||||||
@ -269,32 +301,6 @@ impl World {
|
|||||||
.map(|zcache| zcache/*.sample*/.stone_col)
|
.map(|zcache| zcache/*.sample*/.stone_col)
|
||||||
.unwrap_or_else(|| index.colors.deep_stone_color.into()),
|
.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(
|
let meta = TerrainChunkMeta::new(
|
||||||
sim_chunk
|
sim_chunk
|
||||||
.sites
|
.sites
|
||||||
@ -332,6 +338,11 @@ impl World {
|
|||||||
let mut chunk = TerrainChunk::new(base_z, stone, air, meta);
|
let mut chunk = TerrainChunk::new(base_z, stone, air, meta);
|
||||||
let calendar = self.sim.calendar.as_ref();
|
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 y in 0..TerrainChunkSize::RECT_SIZE.y as i32 {
|
||||||
for x in 0..TerrainChunkSize::RECT_SIZE.x as i32 {
|
for x in 0..TerrainChunkSize::RECT_SIZE.x as i32 {
|
||||||
if should_continue() {
|
if should_continue() {
|
||||||
@ -351,10 +362,22 @@ impl World {
|
|||||||
let (min_z, max_z) = z_cache.get_z_limits();
|
let (min_z, max_z) = z_cache.get_z_limits();
|
||||||
/* let max_z = min_z + 1.0;
|
/* let max_z = min_z + 1.0;
|
||||||
let base_z = min_z as i32 - 1; */
|
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| {
|
(base_z..min_z as i32).for_each(|z| {
|
||||||
let _ = chunk.set(Vec3::new(x, y, z), stone);
|
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;
|
let mut block_ = None;
|
||||||
(min_z as i32..max_z as i32).for_each(|z| {
|
(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/*)*/) {
|
if let Some(block) = sampler.get_with_z_cache(wpos, /*Some(&*/z_cache/*)*/) {
|
||||||
// block_ = Some(block);
|
// block_ = Some(block);
|
||||||
|
// let _ = chunk.set(lpos, 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_ {
|
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| {
|
let sample_get = |offs| {
|
||||||
zcache_grid
|
zcache_grid
|
||||||
|
@ -2480,7 +2480,7 @@ impl SimChunk {
|
|||||||
self.water_alt > self.alt || self.river.river_kind.is_some()
|
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 {
|
pub fn get_biome(&self) -> BiomeKind {
|
||||||
let savannah_hum_temp = [0.05..0.55, 0.3..1.6];
|
let savannah_hum_temp = [0.05..0.55, 0.3..1.6];
|
||||||
|
Loading…
Reference in New Issue
Block a user