diff --git a/Cargo.lock b/Cargo.lock index d771fd3..b525be4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/Cargo.toml b/Cargo.toml index aad8ff8..c74b56a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/src/bin/minedmap/tile_renderer.rs b/src/bin/minedmap/tile_renderer.rs index 556483b..76485bb 100644 --- a/src/bin/minedmap/tile_renderer.rs +++ b/src/bin/minedmap/tile_renderer.rs @@ -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) }