diff --git a/Cargo.lock b/Cargo.lock index 0b4381092..e400be7f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -489,6 +489,12 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbdcdcb6d86f71c5e97409ad45898af11cbc995b4ee8112d59095a28d376c935" +[[package]] +name = "const_soft_float" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4001a314cf9c48da20f9d782592e5991012ed0ac952ddc73f9e8878cd8ae90da" + [[package]] name = "convert_case" version = "0.4.0" @@ -985,6 +991,7 @@ version = "0.6.0" dependencies = [ "approx 0.3.2", "bitvec", + "const_soft_float", "feather-base", "log", "num-traits", diff --git a/feather/worldgen/Cargo.toml b/feather/worldgen/Cargo.toml index ac61648e3..cf6efee96 100644 --- a/feather/worldgen/Cargo.toml +++ b/feather/worldgen/Cargo.toml @@ -7,6 +7,7 @@ edition = "2018" [dependencies] base = { path = "../base", package = "feather-base" } bitvec = "0.21" +const_soft_float = "0.1.3" log = "0.4" num-traits = "0.2" once_cell = "1" diff --git a/feather/worldgen/src/density_map/density.rs b/feather/worldgen/src/density_map/density.rs index 3d09f0f4f..9ccf85142 100644 --- a/feather/worldgen/src/density_map/density.rs +++ b/feather/worldgen/src/density_map/density.rs @@ -7,6 +7,7 @@ use crate::{block_index, noise, DensityMapGenerator, NearbyBiomes, NoiseLerper}; use base::{Biome, ChunkPosition}; use bitvec::order::LocalBits; use bitvec::vec::BitVec; +use const_soft_float::soft_f32::SoftF32; use once_cell::sync::Lazy; use simdnoise::NoiseBuilder; @@ -155,21 +156,34 @@ fn generate_density(chunk: ChunkPosition, biomes: &NearbyBiomes, seed: u64) -> V result } -/// Elevation height field, used to weight -/// the averaging of nearby biome heights. -static ELEVATION_WEIGHT: Lazy<[[f32; 19]; 19]> = Lazy::new(|| { - let mut array = [[0.0; 19]; 19]; - for (x, values) in array.iter_mut().enumerate() { - for (z, value) in values.iter_mut().enumerate() { +const fn elevation() -> [[f32; 19]; 19] { + let mut array = [[0.0f32; 19]; 19]; + let mut x = 0; + while x < 19 { + let mut z = 0; + while z < 19 { let mut x_squared = x as i32 - 9; x_squared *= x_squared; let mut z_sqaured = z as i32 - 9; z_sqaured *= z_sqaured; - *value = 10.0 / (x_squared as f32 + z_sqaured as f32 + 0.2).sqrt(); + array[x][z] = SoftF32(10.0) + .div( + (SoftF32(x_squared as f32) + .add(SoftF32(z_sqaured as f32)) + .add(SoftF32(0.2))) + .sqrt(), + ) + .to_f32(); + z += 1; } + x += 1; } array -}); +} + +/// Elevation height field, used to weight +/// the averaging of nearby biome heights. +static ELEVATION_WEIGHT: [[f32; 19]; 19] = elevation(); /// Computes the target amplitude and midpoint for the /// given column, using a 9x9 grid of biomes @@ -260,3 +274,27 @@ fn lerp(a: f32, b: f32, weight: f32) -> f32 { a + (b - a) * weight } + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn lazy_static_equality() { + static ELEVATION_WEIGHT_TEST: Lazy<[[f32; 19]; 19]> = Lazy::new(|| { + let mut array = [[0.0; 19]; 19]; + for (x, values) in array.iter_mut().enumerate() { + for (z, value) in values.iter_mut().enumerate() { + let mut x_squared = x as i32 - 9; + x_squared *= x_squared; + let mut z_sqaured = z as i32 - 9; + z_sqaured *= z_sqaured; + *value = 10.0 / (x_squared as f32 + z_sqaured as f32 + 0.2).sqrt(); + } + } + array + }); + + assert_eq!(*ELEVATION_WEIGHT_TEST, ELEVATION_WEIGHT) + } +}