diff --git a/pumpkin-world/src/generation/biome.rs b/pumpkin-world/src/generation/biome.rs index 535a039d0..e97260b09 100644 --- a/pumpkin-world/src/generation/biome.rs +++ b/pumpkin-world/src/generation/biome.rs @@ -1,4 +1,4 @@ -use pumpkin_util::math::{square, vector3::Vector3}; +use pumpkin_util::math::{floor_mod, square, vector3::Vector3}; use super::biome_coords; @@ -134,13 +134,7 @@ fn score_permutation( #[inline] fn scale_mix(l: i64) -> f64 { - const RECIPROCAL_1024: f64 = 1.0 / 1024.0; - - // Use a bitwise AND for a faster modulus by a power of two - let scaled_l = (l >> 24) & 1023; - - // Use a multiplication instead of a division - let d = scaled_l as f64 * RECIPROCAL_1024; + let d = floor_mod(l >> 24, 1024i32 as i64) as i32 as f64 / 1024.0; (d - 0.5) * 0.9 } diff --git a/pumpkin-world/src/generation/surface/mod.rs b/pumpkin-world/src/generation/surface/mod.rs index 7f4547bf4..518afef86 100644 --- a/pumpkin-world/src/generation/surface/mod.rs +++ b/pumpkin-world/src/generation/surface/mod.rs @@ -1,3 +1,6 @@ +use std::{cell::RefCell, num::NonZeroUsize}; + +use lru::LruCache; use pumpkin_data::chunk::Biome; use pumpkin_util::{ math::{lerp2, vector2::Vector2, vector3::Vector3, vertical_surface_type::VerticalSurfaceType}, @@ -395,7 +398,7 @@ pub struct VerticalGradientMaterialCondition { true_at_and_below: YOffset, false_at_and_above: YOffset, #[serde(skip)] - random_deriver: ThreadLocal, + random_deriver: ThreadLocal>>, } impl VerticalGradientMaterialCondition { @@ -403,9 +406,21 @@ impl VerticalGradientMaterialCondition { let true_at = self.true_at_and_below.get_y(context.min_y, context.height); let false_at = self.false_at_and_above.get_y(context.min_y, context.height); - let splitter = self.random_deriver.get_or(|| { - let random_deriver_clone = context.random_deriver; - random_deriver_clone + let context_pointer: *const RandomDeriver = context.random_deriver; + let key = context_pointer.addr(); + + let mut cache = self + .random_deriver + .get_or(|| { + let cache_size = NonZeroUsize::new(128).unwrap(); + let cache = LruCache::new(cache_size); + RefCell::new(cache) + }) + .borrow_mut(); + + let splitter = cache.get_or_insert(key, || { + context + .random_deriver .split_string(&self.random_name) .next_splitter() });