minedmap/tile_renderer: avoid calling block_color() more often than necessary

Collect all biome indices/weights for a chunk and deduplicate using a
hash map.
This commit is contained in:
Matthias Schiffer 2023-08-03 23:02:49 +02:00
parent fb712cd2f5
commit deb33814ee
Signed by: neocturne
GPG key ID: 16EF3F64CB201D9C
3 changed files with 29 additions and 9 deletions

7
Cargo.lock generated
View file

@ -401,6 +401,7 @@ dependencies = [
"indexmap",
"itertools",
"num-integer",
"rustc-hash",
"serde",
"serde_json",
"zstd",
@ -489,6 +490,12 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustix"
version = "0.38.4"

View file

@ -20,6 +20,7 @@ image = { version = "0.24.5", default-features = false, features = ["png"] }
indexmap = { version = "2.0.0", features = ["serde"] }
itertools = "0.11.0"
num-integer = "0.1.45"
rustc-hash = "1.1.0"
serde = "1.0.152"
serde_json = "1.0.99"
zstd = "0.12.3"

View file

@ -9,7 +9,7 @@ use num_integer::div_mod_floor;
use minedmap::{
io::{fs, storage},
resource::{block_color, needs_biome, Biome},
resource::{block_color, needs_biome},
types::*,
};
@ -44,7 +44,7 @@ fn biome_at(
block: LayerBlockCoords,
dx: i32,
dz: i32,
) -> Option<&Biome> {
) -> Option<(i8, i8, u16)> {
let (region_x, chunk_x, block_x) = coord_offset(chunk.x, block.x, dx);
let (region_z, chunk_z, block_z) = coord_offset(chunk.z, block.z, dz);
let chunk = ChunkCoords {
@ -56,8 +56,11 @@ fn biome_at(
z: block_z,
};
let region = region_group.get(region_x, region_z)?;
let index = region.chunks[chunk].as_ref()?.biomes[block]?.get() - 1;
region.biome_list.get_index(index.into())
Some((
region_x,
region_z,
region.chunks[chunk].as_ref()?.biomes[block]?.get() - 1,
))
}
pub struct TileRenderer<'a> {
@ -96,8 +99,7 @@ impl<'a> TileRenderer<'a> {
return Some(block_color(block, None, depth.0 as f32));
}
let mut total = 0.0;
let mut color = Vec3::ZERO;
let mut weights = rustc_hash::FxHashMap::<(i8, i8, u16), f32>::default();
for dz in -Z..=Z {
for dx in -X..=X {
let w = SMOOTH[dz.unsigned_abs()][dx.unsigned_abs()];
@ -109,15 +111,25 @@ impl<'a> TileRenderer<'a> {
continue;
};
total += w;
color += w * block_color(block, Some(biome), depth.0 as f32);
*weights.entry(biome).or_default() += w;
}
}
if total == 0.0 {
if weights.is_empty() {
return None;
}
let mut color = Vec3::ZERO;
let mut total = 0.0;
for ((region_x, region_z, index), w) in weights {
let region = region_group.get(region_x, region_z)?;
let biome = region.biome_list.get_index(index.into())?;
total += w;
color += w * block_color(block, Some(biome), depth.0 as f32);
}
Some(color / total)
}