From 6ae79eb7585569075186344d6a65220f81e0cd77 Mon Sep 17 00:00:00 2001 From: osmarks Date: Tue, 23 Jul 2024 12:43:26 +0100 Subject: [PATCH] Nutrient soil map --- src/worldgen.rs | 31 +++++++++++++++++++++++++++---- src/worldgen_test.rs | 13 ++++++++----- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/worldgen.rs b/src/worldgen.rs index fe93c60..55808d8 100644 --- a/src/worldgen.rs +++ b/src/worldgen.rs @@ -301,7 +301,7 @@ pub fn distance_map>(radius: i32, sources: I) -> Map, rain: &Map, heightmap: &Map) -> Map { let mut groundwater = distance_map( water.radius, - water.iter().filter_map(|(c, i)| if *i > 0.0 { Some(c) } else { None }));; + water.iter().filter_map(|(c, i)| if *i > 0.0 { Some(c) } else { None })); percentilize(&mut groundwater, |x| (1.0 - x).powf(0.3)); for (coord, h) in heightmap.iter() { groundwater[coord] -= *h * 0.05; @@ -437,6 +437,19 @@ pub fn simulate_water(heightmap: &mut Map, rain_map: &Map, sea: &HashS (watermap, salt) } +const NUTRIENT_NOISE_SCALE: f32 = 0.0015; + +// As a handwave, define soil nutrients to be partly randomized and partly based on water. +// This kind of sort of makes sense because nitrogen is partly fixed by plants, which would have grown in water-having areas. +pub fn soil_nutrients(groundwater: &Map) -> Map { + let mut soil_nutrients = Map::::from_fn(|cr| { + let c = to_cubic(cr); + noise_functions::OpenSimplex2s.seed(406).sample3([10.0 + c.x as f32 * NUTRIENT_NOISE_SCALE, c.y as f32 * NUTRIENT_NOISE_SCALE, c.z as f32 * NUTRIENT_NOISE_SCALE]) + groundwater[cr] + }, groundwater.radius); + percentilize(&mut soil_nutrients, |x| x.powf(0.4)); + soil_nutrients +} + struct WindSlice { coord: Coord, humidity: f32, // hPa @@ -560,7 +573,11 @@ pub enum TerrainType { pub struct GeneratedWorld { heightmap: Map, terrain: Map, - humidity: Map + groundwater: Map, + salt: Map, + atmo_humidity: Map, + temperature: Map, + soil_nutrients: Map } pub fn generate_world() -> GeneratedWorld { @@ -587,12 +604,18 @@ pub fn generate_world() -> GeneratedWorld { } } - let humidity = compute_groundwater(&water, &rain, &heightmap); + let groundwater = compute_groundwater(&water, &rain, &heightmap); + + let soil_nutrients = soil_nutrients(&groundwater); GeneratedWorld { heightmap, terrain, - humidity + groundwater, + salt, + atmo_humidity, + temperature, + soil_nutrients } } diff --git a/src/worldgen_test.rs b/src/worldgen_test.rs index 3b9aa31..c09f29d 100644 --- a/src/worldgen_test.rs +++ b/src/worldgen_test.rs @@ -28,18 +28,21 @@ fn main() -> Result<()> { *entry = std::cmp::max(*entry, (steepness * 4000.0).abs() as u8); } - println!("humidity..."); + println!("groundwater..."); let groundwater = compute_groundwater(&water, &rain, &heightmap); + println!("soil..."); + let soil_nutrients = soil_nutrients(&groundwater); + println!("rendering..."); let mut image = ImageBuffer::from_pixel((WORLD_RADIUS * 2 + 1) as u32, (WORLD_RADIUS * 2 + 1) as u32, Rgb::from([0u8, 0, 0])); - for (position, value) in heightmap.iter() { + for (position, height) in heightmap.iter() { let col = position.x + (position.y - (position.y & 1)) / 2 + WORLD_RADIUS; let row = position.y + WORLD_RADIUS; - //let height = ((*value + 1.0) * 127.5) as u8; - let green_channel = groundwater[position]; - let red_channel = salt[position]; + let height = *height * 0.5 + 1.0; + let green_channel = height; + let red_channel = soil_nutrients[position]; let blue_channel = water[position].min(1.0); image.put_pixel(col as u32, row as u32, Rgb::from([(red_channel * 255.0) as u8, (green_channel * 255.0) as u8, (blue_channel * 255.0) as u8])); }