mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Performance improvements for terrain watcher
This commit is contained in:
parent
1cfad833c7
commit
5c0026f4a7
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -6275,6 +6275,7 @@ dependencies = [
|
||||
"ordered-float 2.8.0",
|
||||
"profiling",
|
||||
"rand 0.8.4",
|
||||
"rand_chacha 0.3.1",
|
||||
"rayon",
|
||||
"rodio",
|
||||
"ron",
|
||||
|
@ -69,6 +69,22 @@ impl<V, S: RectVolSize, M: Clone> Chonk<V, S, M> {
|
||||
self.sub_chunks.iter().map(SubChunk::num_groups).sum()
|
||||
}
|
||||
|
||||
/// Iterate through the voxels in this chunk, attempting to avoid those that are unchanged (i.e: match the `below`
|
||||
/// and `above` voxels). This is generally useful for performance reasons.
|
||||
pub fn iter_changed(&self) -> impl Iterator<Item = (Vec3<i32>, &V)> + '_ {
|
||||
self.sub_chunks
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, sc)| sc.num_groups() > 0)
|
||||
.map(move |(i, sc)| {
|
||||
let z_offset = self.z_offset + i as i32 * SubChunkSize::<S>::SIZE.z as i32;
|
||||
sc
|
||||
.vol_iter(Vec3::zero(), SubChunkSize::<S>::SIZE.map(|e| e as i32))
|
||||
.map(move |(pos, vox)| (pos + Vec3::unit_z() * z_offset, vox))
|
||||
})
|
||||
.flatten()
|
||||
}
|
||||
|
||||
// Returns the index (in self.sub_chunks) of the SubChunk that contains
|
||||
// layer z; note that this index changes when more SubChunks are prepended
|
||||
fn sub_chunk_idx(&self, z: i32) -> i32 {
|
||||
|
@ -1,8 +1,5 @@
|
||||
use crate::hud::CraftingTab;
|
||||
use common::{
|
||||
terrain::{BlockKind, SpriteKind, TerrainChunk},
|
||||
vol::{IntoVolIterator, RectRasterableVol},
|
||||
};
|
||||
use common::terrain::{BlockKind, SpriteKind, TerrainChunk};
|
||||
use common_base::span;
|
||||
use rand::prelude::*;
|
||||
use rand_chacha::ChaCha8Rng;
|
||||
@ -64,14 +61,7 @@ impl BlocksOfInterest {
|
||||
let mut rng = ChaCha8Rng::from_seed(thread_rng().gen());
|
||||
|
||||
chunk
|
||||
.vol_iter(
|
||||
Vec3::new(0, 0, chunk.get_min_z()),
|
||||
Vec3::new(
|
||||
TerrainChunk::RECT_SIZE.x as i32,
|
||||
TerrainChunk::RECT_SIZE.y as i32,
|
||||
chunk.get_max_z(),
|
||||
),
|
||||
)
|
||||
.iter_changed()
|
||||
.for_each(|(pos, block)| {
|
||||
match block.kind() {
|
||||
BlockKind::Leaves if rng.gen_range(0..16) == 0 => leaves.push(pos),
|
||||
|
@ -607,14 +607,6 @@ pub fn apply_caverns_to<R: Rng>(canvas: &mut Canvas, dynamic_rng: &mut R) {
|
||||
.mul((cavern_height as f64 - 5.0).mul(0.15).clamped(0.0, 1.0))
|
||||
.mul(32.0 + cavern_avg_height as f64 * 0.85);
|
||||
|
||||
let lake = info.index().noise.cave_nz
|
||||
.get(wpos2d.map(|e| e as f64 * 0.01).into_array())
|
||||
.sub(0.5)
|
||||
.max(0.0)
|
||||
.mul(2.0)
|
||||
.mul(80.0);
|
||||
let lake = 0.0;
|
||||
|
||||
let rugged = 0.25; // How bumpy should the floor be relative to the ceiling?
|
||||
let cavern_bottom = (cavern_avg_alt - cavern_height * rugged) as i32;
|
||||
let cavern_avg_bottom = (cavern_avg_alt - ((height_range.start + height_range.end) * 0.5) * rugged) as i32;
|
||||
@ -626,7 +618,7 @@ pub fn apply_caverns_to<R: Rng>(canvas: &mut Canvas, dynamic_rng: &mut R) {
|
||||
|
||||
let floor = stalagmite as i32;
|
||||
|
||||
(cavern_bottom, cavern_top, cavern_avg_bottom, cavern_avg_top, floor, lake, stalagtite)
|
||||
(cavern_bottom, cavern_top, cavern_avg_bottom, cavern_avg_top, floor, stalagtite)
|
||||
};
|
||||
|
||||
let mut mushroom_cache = HashMap::new();
|
||||
@ -644,8 +636,8 @@ pub fn apply_caverns_to<R: Rng>(canvas: &mut Canvas, dynamic_rng: &mut R) {
|
||||
.entry(wpos2d)
|
||||
.or_insert_with(|| {
|
||||
let mut rng = RandomPerm::new(seed);
|
||||
let (cavern_bottom, _, _, _, floor, _, _) = cavern_at(wpos2d);
|
||||
if rng.gen_bool(0.1) {
|
||||
let (cavern_bottom, cavern_top, _, _, floor, _) = cavern_at(wpos2d);
|
||||
if rng.gen_bool(0.1) && cavern_top - cavern_bottom > 32 {
|
||||
Some(Mushroom {
|
||||
pos: wpos2d.with_z(cavern_bottom + floor),
|
||||
stalk: rng.gen_range(8.0..26.0),
|
||||
@ -684,7 +676,7 @@ pub fn apply_caverns_to<R: Rng>(canvas: &mut Canvas, dynamic_rng: &mut R) {
|
||||
return Some(Block::new(BlockKind::GlowingMushroom, mushroom.head_color));
|
||||
} else if rpos.z <= mushroom.stalk && rpos.xy().magnitude_squared() < stalk_radius.powi(2) { // Stalk
|
||||
return Some(Block::new(BlockKind::Wood, Rgb::new(50, 120, 180)));
|
||||
} else if ((mushroom.stalk - 1.0)..mushroom.stalk).contains(&rpos.z) // Hanging orbs
|
||||
} else if ((mushroom.stalk - 0.5)..mushroom.stalk).contains(&rpos.z) // Hanging orbs
|
||||
&& ((head_radius * 0.5)..(head_radius * 0.8)).contains(&dist)
|
||||
&& dynamic_rng.gen_bool(0.025)
|
||||
{
|
||||
@ -697,7 +689,7 @@ pub fn apply_caverns_to<R: Rng>(canvas: &mut Canvas, dynamic_rng: &mut R) {
|
||||
};
|
||||
|
||||
canvas.foreach_col(|canvas, wpos2d, _col| {
|
||||
let (cavern_bottom, cavern_top, cavern_avg_bottom, cavern_avg_top, floor, lake, stalagtite) = cavern_at(wpos2d);
|
||||
let (cavern_bottom, cavern_top, cavern_avg_bottom, cavern_avg_top, floor, stalagtite) = cavern_at(wpos2d);
|
||||
|
||||
let mini_stalagtite = info.index().noise.cave_nz
|
||||
.get(wpos2d.map(|e| e as f64 * 0.08).into_array())
|
||||
@ -708,14 +700,13 @@ pub fn apply_caverns_to<R: Rng>(canvas: &mut Canvas, dynamic_rng: &mut R) {
|
||||
let stalagtite_height = (stalagtite + mini_stalagtite) as i32;
|
||||
|
||||
let cavern_top = cavern_top as i32;
|
||||
let lower_bound = cavern_bottom - lake as i32;
|
||||
let mut on_ground = true;
|
||||
for z in lower_bound..cavern_top {
|
||||
for z in cavern_bottom..cavern_top {
|
||||
use SpriteKind::*;
|
||||
|
||||
let wpos = wpos2d.with_z(z);
|
||||
|
||||
let block = if z < lower_bound + floor {
|
||||
let block = if z < cavern_bottom + floor {
|
||||
Block::new(BlockKind::WeakRock, Rgb::new(110, 120, 150))
|
||||
} else if z > cavern_top - stalagtite_height {
|
||||
if dynamic_rng.gen_bool(0.0035) { // Glowing rock in stalagtites
|
||||
|
@ -55,6 +55,8 @@ use common_net::msg::{world_msg, WorldMapMsg};
|
||||
use rand::Rng;
|
||||
use serde::Deserialize;
|
||||
use std::time::Duration;
|
||||
use rand_chacha::ChaCha8Rng;
|
||||
use rand::prelude::*;
|
||||
use vek::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -329,7 +331,7 @@ impl World {
|
||||
};
|
||||
|
||||
// Only use for rng affecting dynamic elements like chests and entities!
|
||||
let mut dynamic_rng = rand::thread_rng();
|
||||
let mut dynamic_rng = ChaCha8Rng::from_seed(thread_rng().gen());
|
||||
|
||||
// Apply layers (paths, caves, etc.)
|
||||
let mut canvas = Canvas {
|
||||
@ -365,7 +367,7 @@ impl World {
|
||||
entities: canvas.entities,
|
||||
};
|
||||
|
||||
let gen_entity_pos = |dynamic_rng: &mut rand::rngs::ThreadRng| {
|
||||
let gen_entity_pos = |dynamic_rng: &mut ChaCha8Rng| {
|
||||
let lpos2d = TerrainChunkSize::RECT_SIZE
|
||||
.map(|sz| dynamic_rng.gen::<u32>().rem_euclid(sz) as i32);
|
||||
let mut lpos = Vec3::new(
|
||||
|
Loading…
Reference in New Issue
Block a user