1
0
mirror of https://github.com/osmarks/ewo3.git synced 2025-02-10 16:10:16 +00:00

Nutrient soil map

This commit is contained in:
osmarks 2024-07-23 12:43:26 +01:00
parent 32a1a69db4
commit 6ae79eb758
2 changed files with 35 additions and 9 deletions

View File

@ -301,7 +301,7 @@ pub fn distance_map<I: Iterator<Item=Coord>>(radius: i32, sources: I) -> Map<f32
pub fn compute_groundwater(water: &Map<f32>, rain: &Map<f32>, heightmap: &Map<f32>) -> Map<f32> {
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<f32>, rain_map: &Map<f32>, 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<f32>) -> Map<f32> {
let mut soil_nutrients = Map::<f32>::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<f32>,
terrain: Map<TerrainType>,
humidity: Map<f32>
groundwater: Map<f32>,
salt: Map<f32>,
atmo_humidity: Map<f32>,
temperature: Map<f32>,
soil_nutrients: Map<f32>
}
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
}
}

View File

@ -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]));
}