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",
|
"ordered-float 2.8.0",
|
||||||
"profiling",
|
"profiling",
|
||||||
"rand 0.8.4",
|
"rand 0.8.4",
|
||||||
|
"rand_chacha 0.3.1",
|
||||||
"rayon",
|
"rayon",
|
||||||
"rodio",
|
"rodio",
|
||||||
"ron",
|
"ron",
|
||||||
|
@ -69,6 +69,22 @@ impl<V, S: RectVolSize, M: Clone> Chonk<V, S, M> {
|
|||||||
self.sub_chunks.iter().map(SubChunk::num_groups).sum()
|
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
|
// Returns the index (in self.sub_chunks) of the SubChunk that contains
|
||||||
// layer z; note that this index changes when more SubChunks are prepended
|
// layer z; note that this index changes when more SubChunks are prepended
|
||||||
fn sub_chunk_idx(&self, z: i32) -> i32 {
|
fn sub_chunk_idx(&self, z: i32) -> i32 {
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
use crate::hud::CraftingTab;
|
use crate::hud::CraftingTab;
|
||||||
use common::{
|
use common::terrain::{BlockKind, SpriteKind, TerrainChunk};
|
||||||
terrain::{BlockKind, SpriteKind, TerrainChunk},
|
|
||||||
vol::{IntoVolIterator, RectRasterableVol},
|
|
||||||
};
|
|
||||||
use common_base::span;
|
use common_base::span;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use rand_chacha::ChaCha8Rng;
|
use rand_chacha::ChaCha8Rng;
|
||||||
@ -64,14 +61,7 @@ impl BlocksOfInterest {
|
|||||||
let mut rng = ChaCha8Rng::from_seed(thread_rng().gen());
|
let mut rng = ChaCha8Rng::from_seed(thread_rng().gen());
|
||||||
|
|
||||||
chunk
|
chunk
|
||||||
.vol_iter(
|
.iter_changed()
|
||||||
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(),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.for_each(|(pos, block)| {
|
.for_each(|(pos, block)| {
|
||||||
match block.kind() {
|
match block.kind() {
|
||||||
BlockKind::Leaves if rng.gen_range(0..16) == 0 => leaves.push(pos),
|
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((cavern_height as f64 - 5.0).mul(0.15).clamped(0.0, 1.0))
|
||||||
.mul(32.0 + cavern_avg_height as f64 * 0.85);
|
.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 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_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;
|
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;
|
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();
|
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)
|
.entry(wpos2d)
|
||||||
.or_insert_with(|| {
|
.or_insert_with(|| {
|
||||||
let mut rng = RandomPerm::new(seed);
|
let mut rng = RandomPerm::new(seed);
|
||||||
let (cavern_bottom, _, _, _, floor, _, _) = cavern_at(wpos2d);
|
let (cavern_bottom, cavern_top, _, _, floor, _) = cavern_at(wpos2d);
|
||||||
if rng.gen_bool(0.1) {
|
if rng.gen_bool(0.1) && cavern_top - cavern_bottom > 32 {
|
||||||
Some(Mushroom {
|
Some(Mushroom {
|
||||||
pos: wpos2d.with_z(cavern_bottom + floor),
|
pos: wpos2d.with_z(cavern_bottom + floor),
|
||||||
stalk: rng.gen_range(8.0..26.0),
|
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));
|
return Some(Block::new(BlockKind::GlowingMushroom, mushroom.head_color));
|
||||||
} else if rpos.z <= mushroom.stalk && rpos.xy().magnitude_squared() < stalk_radius.powi(2) { // Stalk
|
} 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)));
|
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)
|
&& ((head_radius * 0.5)..(head_radius * 0.8)).contains(&dist)
|
||||||
&& dynamic_rng.gen_bool(0.025)
|
&& 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| {
|
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
|
let mini_stalagtite = info.index().noise.cave_nz
|
||||||
.get(wpos2d.map(|e| e as f64 * 0.08).into_array())
|
.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 stalagtite_height = (stalagtite + mini_stalagtite) as i32;
|
||||||
|
|
||||||
let cavern_top = cavern_top as i32;
|
let cavern_top = cavern_top as i32;
|
||||||
let lower_bound = cavern_bottom - lake as i32;
|
|
||||||
let mut on_ground = true;
|
let mut on_ground = true;
|
||||||
for z in lower_bound..cavern_top {
|
for z in cavern_bottom..cavern_top {
|
||||||
use SpriteKind::*;
|
use SpriteKind::*;
|
||||||
|
|
||||||
let wpos = wpos2d.with_z(z);
|
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))
|
Block::new(BlockKind::WeakRock, Rgb::new(110, 120, 150))
|
||||||
} else if z > cavern_top - stalagtite_height {
|
} else if z > cavern_top - stalagtite_height {
|
||||||
if dynamic_rng.gen_bool(0.0035) { // Glowing rock in stalagtites
|
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 rand::Rng;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use rand_chacha::ChaCha8Rng;
|
||||||
|
use rand::prelude::*;
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -329,7 +331,7 @@ impl World {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Only use for rng affecting dynamic elements like chests and entities!
|
// 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.)
|
// Apply layers (paths, caves, etc.)
|
||||||
let mut canvas = Canvas {
|
let mut canvas = Canvas {
|
||||||
@ -365,7 +367,7 @@ impl World {
|
|||||||
entities: canvas.entities,
|
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
|
let lpos2d = TerrainChunkSize::RECT_SIZE
|
||||||
.map(|sz| dynamic_rng.gen::<u32>().rem_euclid(sz) as i32);
|
.map(|sz| dynamic_rng.gen::<u32>().rem_euclid(sz) as i32);
|
||||||
let mut lpos = Vec3::new(
|
let mut lpos = Vec3::new(
|
||||||
|
Loading…
Reference in New Issue
Block a user