mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Reverting changes except to humidity and temperature
noise.
This commit is contained in:
parent
28d0afbfb6
commit
1b864887e7
@ -21,21 +21,50 @@ fn main() {
|
||||
|
||||
while win.is_open() {
|
||||
let mut buf = vec![0; W * H];
|
||||
const QUADRANTS : usize = 4;
|
||||
let mut quads = [[0u32; QUADRANTS]; QUADRANTS];
|
||||
let mut rivers = 0u32;
|
||||
let mut lakes = 0u32;
|
||||
let mut oceans = 0u32;
|
||||
|
||||
for i in 0..W {
|
||||
for j in 0..H {
|
||||
let pos = focus + Vec2::new(i as i32, j as i32) * scale;
|
||||
|
||||
let (alt, water_alt, river_kind) = sampler
|
||||
let (alt, water_alt, humidity, temperature, river_kind) = sampler
|
||||
.get(pos)
|
||||
.map(|sample| (sample.alt, sample.water_alt, sample.river.river_kind))
|
||||
.unwrap_or((CONFIG.sea_level, CONFIG.sea_level, None));
|
||||
let alt = ((alt - CONFIG.sea_level) / CONFIG.mountain_scale)
|
||||
.map(|sample| (sample.alt, sample.water_alt, sample.humidity, sample.temp, sample.river.river_kind))
|
||||
.unwrap_or((CONFIG.sea_level, CONFIG.sea_level, 0.0, 0.0, None));
|
||||
let humidity = humidity
|
||||
.min(1.0)
|
||||
.max(0.0);
|
||||
let temperature = temperature
|
||||
.min(1.0)
|
||||
.max(-1.0)
|
||||
* 0.5 + 0.5;
|
||||
let water_alt = ((alt.max(water_alt) - CONFIG.sea_level) / CONFIG.mountain_scale)
|
||||
.min(1.0)
|
||||
.max(0.0);
|
||||
let alt = ((alt - CONFIG.sea_level) / CONFIG.mountain_scale)
|
||||
.min(1.0)
|
||||
.max(0.0);
|
||||
let quad = |x: f32| ((x as f64 * QUADRANTS as f64).floor() as usize).min(QUADRANTS - 1);
|
||||
if river_kind.is_none() || humidity != 0.0 {
|
||||
quads[quad(humidity)][quad(temperature)] += 1;
|
||||
}
|
||||
match river_kind {
|
||||
Some(RiverKind::River { .. }) => {
|
||||
rivers += 1;
|
||||
},
|
||||
Some(RiverKind::Lake { .. }) => {
|
||||
lakes += 1;
|
||||
},
|
||||
Some(RiverKind::Ocean { .. }) => {
|
||||
oceans += 1;
|
||||
},
|
||||
None => {},
|
||||
}
|
||||
|
||||
buf[j * W + i] = match river_kind {
|
||||
Some(RiverKind::Ocean) => u32::from_le_bytes([64, 32, 0, 255]),
|
||||
Some(RiverKind::Lake { .. }) => u32::from_le_bytes([
|
||||
@ -50,12 +79,30 @@ fn main() {
|
||||
0,
|
||||
255,
|
||||
]),
|
||||
None => u32::from_le_bytes([0, (alt * 255.0) as u8, 0, 255]),
|
||||
None => u32::from_le_bytes([
|
||||
(/*alt * *//*(1.0 - humidity)*/(alt * humidity).sqrt()/*temperature*/ * 255.0) as u8,
|
||||
(/*alt*//*alt*//* * humidity*//*alt * 255.0*//*humidity*/alt * 255.0) as u8,
|
||||
(/*alt*//*alt * *//*(1.0 - humidity)*/(alt * temperature).sqrt() * 255.0) as u8,
|
||||
255,
|
||||
]),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let spd = 32;
|
||||
if win.is_key_down(minifb::Key::P) {
|
||||
println!("\
|
||||
Land(adjacent): (X = temp, Y = humidity): {:?}\n\
|
||||
Rivers: {:?}\n\
|
||||
Lakes: {:?}\n\
|
||||
Oceans: {:?}\n\
|
||||
Total water: {:?}\n\
|
||||
Total land(adjacent): {:?}",
|
||||
quads, rivers, lakes, oceans,
|
||||
rivers + lakes + oceans,
|
||||
quads.iter().map( |x| x.iter().sum::<u32>() ).sum::<u32>()
|
||||
);
|
||||
}
|
||||
if win.is_key_down(minifb::Key::W) {
|
||||
focus.y -= spd * scale;
|
||||
}
|
||||
|
@ -829,21 +829,36 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
||||
//let humidity = humidity.add((marble - 0.5) * 0.10);
|
||||
|
||||
// Colours
|
||||
let cold_grass = Rgb::new(0.1, 0.5, 0.1);
|
||||
let warm_grass = Rgb::new(0.1, 0.9, 0.2);
|
||||
let dark_grass = Rgb::new(0.1, 0.3, 0.2);
|
||||
let wet_grass = Rgb::new(0.1, 0.5, 0.5);
|
||||
let cold_stone = Rgb::new(0.5, 0.5, 0.5);
|
||||
//let warm_stone = Rgb::new(0.6, 0.6, 0.5);
|
||||
let warm_stone = Rgb::new(0.6, 0.5, 0.1);
|
||||
let cold_grass = Rgb::new(0.0, 0.5, 0.25);
|
||||
// let cold_grass = Rgb::new(0.1, 0.5, 0.1);
|
||||
let warm_grass = Rgb::new(0.4, 0.8, 0.0);
|
||||
// let warm_grass = Rgb::new(0.1, 0.9, 0.2);
|
||||
let dark_grass = Rgb::new(0.15, 0.4, 0.1);
|
||||
// let dark_grass = Rgb::new(0.1, 0.3, 0.2);
|
||||
let wet_grass = Rgb::new(0.1, 0.8, 0.2);
|
||||
// let wet_grass = Rgb::new(0.1, 0.5, 0.5);
|
||||
let cold_stone = Rgb::new(0.57, 0.67, 0.8);
|
||||
// let cold_stone = Rgb::new(0.5, 0.5, 0.5);
|
||||
let warm_stone = Rgb::new(0.77, 0.77, 0.64);
|
||||
// //let warm_stone = Rgb::new(0.6, 0.6, 0.5);
|
||||
// let warm_stone = Rgb::new(0.6, 0.5, 0.1);
|
||||
let beach_sand = Rgb::new(0.9, 0.82, 0.6);
|
||||
let desert_sand = Rgb::new(0.7, 0.7, 0.4);
|
||||
let snow = Rgb::new(0.0, 0.0, 0.1);
|
||||
let stone_col = Rgb::new(152, 98, 16);
|
||||
let dirt = Lerp::lerp(
|
||||
let desert_sand = Rgb::new(0.95, 0.75, 0.5);
|
||||
// let desert_sand = Rgb::new(0.7, 0.7, 0.4);
|
||||
let snow = Rgb::new(0.8, 0.85, 1.0);
|
||||
// let snow = Rgb::new(0.0, 0.0, 0.1);
|
||||
|
||||
// let stone_col = Rgb::new(152, 98, 16);
|
||||
let stone_col = Rgb::new(195, 187, 201);
|
||||
/*let dirt = Lerp::lerp(
|
||||
Rgb::new(0.4, 0.4, 0.4),
|
||||
Rgb::new(0.4, 0.4, 0.4),
|
||||
marble,
|
||||
);*/
|
||||
let dirt = Lerp::lerp(
|
||||
Rgb::new(0.075, 0.07, 0.3),
|
||||
Rgb::new(0.75, 0.55, 0.1),
|
||||
marble,
|
||||
);
|
||||
let tundra = Lerp::lerp(snow, Rgb::new(0.01, 0.3, 0.0), 0.4 + marble * 0.6);
|
||||
let dead_tundra = Lerp::lerp(warm_stone, Rgb::new(0.3, 0.12, 0.2), marble);
|
||||
@ -881,7 +896,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
||||
sand,
|
||||
temp.sub(CONFIG.snow_temp)
|
||||
.div(CONFIG.desert_temp.sub(CONFIG.snow_temp))
|
||||
.mul(4.5),
|
||||
.mul(/*4.5*/0.5),
|
||||
),
|
||||
cliff,
|
||||
alt.sub(CONFIG.mountain_scale * 0.25)
|
||||
@ -902,7 +917,8 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
||||
.div(CONFIG.snow_temp.neg())
|
||||
/*.sub((marble - 0.5) * 0.05)
|
||||
.mul(256.0)*/
|
||||
.mul(2.0),
|
||||
.mul(1.0),
|
||||
// .mul(2.0),
|
||||
),
|
||||
// 0 to tropical_temp
|
||||
grass,
|
||||
@ -912,18 +928,21 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
||||
moss,
|
||||
temp.sub(CONFIG.tropical_temp)
|
||||
.div(CONFIG.desert_temp.sub(CONFIG.tropical_temp))
|
||||
.mul(2.0),
|
||||
.mul(1.0),
|
||||
// .mul(2.0),
|
||||
),
|
||||
// above desert_temp
|
||||
sand,
|
||||
temp.sub(CONFIG.desert_temp)
|
||||
.div(1.0 - CONFIG.desert_temp)
|
||||
.mul(2.0),
|
||||
.mul(4.0),
|
||||
// .mul(2.0),
|
||||
),
|
||||
humidity
|
||||
.sub(CONFIG.desert_hum)
|
||||
.div(CONFIG.forest_hum.sub(CONFIG.desert_hum))
|
||||
.mul(2.0),
|
||||
.mul(1.0),
|
||||
// .mul(2.0),
|
||||
);
|
||||
// From forest to jungle humidity, we go from snow to dark grass to grass to tropics to sand
|
||||
// depending on temperature.
|
||||
@ -941,18 +960,21 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
||||
tropical,
|
||||
temp.sub(CONFIG.tropical_temp)
|
||||
.div(CONFIG.desert_temp.sub(CONFIG.tropical_temp))
|
||||
.mul(2.0),
|
||||
.mul(1.0),
|
||||
// .mul(2.0),
|
||||
),
|
||||
// above desert_temp
|
||||
sand,
|
||||
temp.sub(CONFIG.desert_temp)
|
||||
.div(1.0 - CONFIG.desert_temp)
|
||||
.mul(2.0),
|
||||
.mul(4.0),
|
||||
// .mul(2.0),
|
||||
),
|
||||
humidity
|
||||
.sub(CONFIG.forest_hum)
|
||||
.div(CONFIG.jungle_hum.sub(CONFIG.forest_hum))
|
||||
.mul(2.0),
|
||||
.mul(1.0),
|
||||
// .mul(2.0),
|
||||
);
|
||||
// From jungle humidity upwards, we go from snow to grass to rainforest to tropics to sand.
|
||||
let ground = Rgb::lerp(
|
||||
@ -969,13 +991,15 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
||||
tropical,
|
||||
temp.sub(CONFIG.tropical_temp)
|
||||
.div(CONFIG.desert_temp.sub(CONFIG.tropical_temp))
|
||||
.mul(2.0),
|
||||
.mul(4.0),
|
||||
// .mul(2.0),
|
||||
),
|
||||
// above desert_temp
|
||||
sand,
|
||||
temp.sub(CONFIG.desert_temp)
|
||||
.div(1.0 - CONFIG.desert_temp)
|
||||
.mul(2.0),
|
||||
.mul(4.0),
|
||||
// .mul(2.0),
|
||||
),
|
||||
humidity.sub(CONFIG.jungle_hum).mul(1.0),
|
||||
);
|
||||
@ -1046,7 +1070,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
||||
// Beach
|
||||
((ocean_level - 1.0) / 2.0).max(0.0),
|
||||
),
|
||||
sub_surface_color: warm_grass,
|
||||
sub_surface_color: /*warm_grass*/dirt,
|
||||
tree_density,
|
||||
forest_kind: sim_chunk.forest_kind,
|
||||
close_structures: self.gen_close_structures(wpos),
|
||||
|
@ -48,7 +48,7 @@ pub const CONFIG: Config = Config {
|
||||
mountain_scale: 2048.0,
|
||||
snow_temp: -0.6,
|
||||
tropical_temp: 0.2,
|
||||
desert_temp: 0.9,
|
||||
desert_temp: 0.6,
|
||||
desert_hum: 0.15,
|
||||
forest_hum: 0.5,
|
||||
jungle_hum: 0.85,
|
||||
|
@ -112,26 +112,30 @@ impl WorldSim {
|
||||
let gen_ctx = GenCtx {
|
||||
turb_x_nz: SuperSimplex::new().set_seed(rng.gen()),
|
||||
turb_y_nz: SuperSimplex::new().set_seed(rng.gen()),
|
||||
chaos_nz: RidgedMulti::new().set_octaves(2).set_seed(rng.gen()),
|
||||
chaos_nz: RidgedMulti::new().set_octaves(7).set_seed(rng.gen()),
|
||||
hill_nz: SuperSimplex::new().set_seed(rng.gen()),
|
||||
alt_nz: HybridMulti::new()
|
||||
.set_octaves(2)
|
||||
.set_octaves(8)
|
||||
.set_persistence(0.1)
|
||||
.set_seed(rng.gen()),
|
||||
//temp_nz: SuperSimplex::new().set_seed(rng.gen()),
|
||||
|
||||
temp_nz: Fbm::new()
|
||||
.set_octaves(8)
|
||||
.set_persistence(0.9)
|
||||
.set_octaves(6)
|
||||
.set_persistence(0.5)
|
||||
.set_frequency(/*4.0 / /*(1024.0 * 4.0/* * 8.0*/)*//*32.0*/((1 << 6) * (WORLD_SIZE.x)) as f64*/1.0 / (((1 << 6) * 64) as f64))
|
||||
// .set_frequency(1.0 / 1024.0)
|
||||
// .set_frequency(1.0 / (1024.0 * 8.0))
|
||||
.set_lacunarity(2.0)
|
||||
.set_seed(rng.gen()),
|
||||
|
||||
small_nz: BasicMulti::new().set_octaves(1).set_seed(rng.gen()),
|
||||
small_nz: BasicMulti::new().set_octaves(2).set_seed(rng.gen()),
|
||||
rock_nz: HybridMulti::new().set_persistence(0.3).set_seed(rng.gen()),
|
||||
cliff_nz: HybridMulti::new().set_persistence(0.1).set_seed(rng.gen()),
|
||||
warp_nz: FastNoise::new(rng.gen()), //BasicMulti::new().set_octaves(1).set_seed(gen_seed()),
|
||||
cliff_nz: HybridMulti::new().set_persistence(0.3).set_seed(rng.gen()),
|
||||
warp_nz: FastNoise::new(rng.gen()), //BasicMulti::new().set_octaves(3).set_seed(gen_seed()),
|
||||
tree_nz: BasicMulti::new()
|
||||
.set_octaves(1)
|
||||
.set_persistence(0.1)
|
||||
.set_octaves(12)
|
||||
.set_persistence(0.75)
|
||||
.set_seed(rng.gen()),
|
||||
cave_0_nz: SuperSimplex::new().set_seed(rng.gen()),
|
||||
cave_1_nz: SuperSimplex::new().set_seed(rng.gen()),
|
||||
@ -141,7 +145,7 @@ impl WorldSim {
|
||||
cliff_gen: StructureGen2d::new(rng.gen(), 80, 56),
|
||||
humid_nz: Billow::new()
|
||||
.set_octaves(9)
|
||||
.set_persistence(0.7)
|
||||
.set_persistence(0.4)
|
||||
.set_frequency(0.2)
|
||||
// .set_octaves(6)
|
||||
// .set_persistence(0.5)
|
||||
@ -159,6 +163,7 @@ impl WorldSim {
|
||||
.set_persistence(0.9)
|
||||
.set_seed(rng.gen());
|
||||
|
||||
// No NaNs in these uniform vectors, since the original noise value always returns Some.
|
||||
let ((alt_base, _), (chaos, _)) = rayon::join(
|
||||
|| {
|
||||
uniform_noise(|_, wposf| {
|
||||
@ -192,7 +197,7 @@ impl WorldSim {
|
||||
.get((wposf.div(400.0)).into_array())
|
||||
.min(1.0)
|
||||
.max(-1.0)
|
||||
.mul(0.9))
|
||||
.mul(0.3))
|
||||
.add(0.3)
|
||||
.max(0.0);
|
||||
|
||||
@ -232,6 +237,8 @@ impl WorldSim {
|
||||
// We ignore sea level because we actually want to be relative to sea level here and want
|
||||
// things in CONFIG.mountain_scale units, but otherwise this is a correct altitude
|
||||
// calculation. Note that this is using the "unadjusted" temperature.
|
||||
//
|
||||
// No NaNs in these uniform vectors, since the original noise value always returns Some.
|
||||
let (alt_old, alt_old_inverse) = uniform_noise(|posi, wposf| {
|
||||
// This is the extension upwards from the base added to some extra noise from -1 to
|
||||
// 1.
|
||||
@ -289,7 +296,7 @@ impl WorldSim {
|
||||
// = [-.3675, .3325] + ([-0.5785, 0.7345])
|
||||
// = [-0.946, 1.067]
|
||||
Some(
|
||||
((alt_base[posi].1 + alt_main.mul((chaos[posi].1 as f64).powf(1.2)))
|
||||
((alt_base[posi].1 + alt_main.mul((chaos[posi].1 as f64).powf(1.2)/*0.25*/))
|
||||
.mul(map_edge_factor(posi) as f64)
|
||||
.add(
|
||||
(CONFIG.sea_level as f64)
|
||||
@ -301,9 +308,28 @@ impl WorldSim {
|
||||
)
|
||||
});
|
||||
|
||||
// Calculate oceans.
|
||||
let old_height = |posi: usize| alt_old[posi].1;
|
||||
let is_ocean = get_oceans(old_height);
|
||||
let is_ocean_fn = |posi: usize| is_ocean[posi];
|
||||
|
||||
/* // Recalculate altitudes without oceans.
|
||||
// NaNs in these uniform vectors wherever pure_water() returns true.
|
||||
let (alt_old_no_ocean, /*alt_old_inverse*/_) = uniform_noise(|posi, _| {
|
||||
if is_ocean_fn(posi) {
|
||||
None
|
||||
} else {
|
||||
Some(old_height(posi)/*.abs()*/)
|
||||
}
|
||||
});
|
||||
|
||||
let old_height_uniform = |posi: usize| alt_old_no_ocean[posi].0;
|
||||
let alt_old_min_uniform = 0.0;
|
||||
let alt_old_max_uniform = 1.0; */
|
||||
// Find the minimum and maximum original altitudes.
|
||||
// NOTE: Will panic if there is no land, and will not work properly if the minimum and
|
||||
// maximum land altitude are identical (will most likely panic later).
|
||||
let old_height_uniform = |posi: usize| alt_old[posi].0;
|
||||
let (alt_old_min_index, _alt_old_min) = alt_old_inverse
|
||||
.iter()
|
||||
.copied()
|
||||
@ -313,12 +339,6 @@ impl WorldSim {
|
||||
let alt_old_min_uniform = alt_old[alt_old_min_index].0;
|
||||
let alt_old_max_uniform = alt_old[alt_old_max_index].0;
|
||||
|
||||
// Calculate oceans.
|
||||
let old_height = |posi: usize| alt_old[posi].1;
|
||||
let old_height_uniform = |posi: usize| alt_old[posi].0;
|
||||
let is_ocean = get_oceans(old_height);
|
||||
let is_ocean_fn = |posi: usize| is_ocean[posi];
|
||||
|
||||
// Perform some erosion.
|
||||
let max_erosion_per_delta_t = 32.0 / CONFIG.mountain_scale as f64;
|
||||
|
||||
@ -349,9 +369,12 @@ impl WorldSim {
|
||||
|posi| {
|
||||
let height = ((old_height_uniform(posi) - alt_old_min_uniform) as f64
|
||||
/ (alt_old_max_uniform - alt_old_min_uniform) as f64)
|
||||
/*.mul(1.0 - f64::EPSILON * 0.5)
|
||||
.add(f64::EPSILON * 0.5);*/
|
||||
.max(1e-7 / CONFIG.mountain_scale as f64)
|
||||
.min(1.0f64 - 1e-7);
|
||||
let height = erosion_factor(height);
|
||||
assert!(height >= 0.0);
|
||||
let height = height
|
||||
.mul(max_erosion_per_delta_t * 7.0 / 8.0)
|
||||
.add(max_erosion_per_delta_t / 8.0);
|
||||
@ -473,25 +496,31 @@ impl WorldSim {
|
||||
true
|
||||
};
|
||||
|
||||
let (pure_flux, _) = uniform_noise(|posi, _| {
|
||||
if pure_water(posi) {
|
||||
None
|
||||
} else {
|
||||
Some(flux_old[posi])
|
||||
}
|
||||
});
|
||||
|
||||
let ((alt_no_water, _), ((temp_base, _), (humid_base, _))) = rayon::join(
|
||||
// NaNs in these uniform vectors wherever pure_water() returns true.
|
||||
let (((alt_no_water, _), (pure_flux, _)), ((temp_base, _), (humid_base, _))) = rayon::join(
|
||||
|| {
|
||||
uniform_noise(|posi, _| {
|
||||
if pure_water(posi) {
|
||||
None
|
||||
} else {
|
||||
// A version of alt that is uniform over *non-water* (or land-adjacent water)
|
||||
// chunks.
|
||||
Some(alt[posi])
|
||||
}
|
||||
})
|
||||
rayon::join(
|
||||
|| {
|
||||
uniform_noise(|posi, _| {
|
||||
if pure_water(posi) {
|
||||
None
|
||||
} else {
|
||||
// A version of alt that is uniform over *non-water* (or land-adjacent water)
|
||||
// chunks.
|
||||
Some(alt[posi])
|
||||
}
|
||||
})
|
||||
},
|
||||
|| {
|
||||
uniform_noise(|posi, _| {
|
||||
if pure_water(posi) {
|
||||
None
|
||||
} else {
|
||||
Some(flux_old[posi])
|
||||
}
|
||||
})
|
||||
},
|
||||
)
|
||||
},
|
||||
|| {
|
||||
rayon::join(
|
||||
@ -501,7 +530,7 @@ impl WorldSim {
|
||||
None
|
||||
} else {
|
||||
// -1 to 1.
|
||||
Some(gen_ctx.temp_nz.get((wposf.div(12000.0)).into_array()) as f32)
|
||||
Some(gen_ctx.temp_nz.get((wposf/*.div(12000.0)*/).into_array()) as f32)
|
||||
}
|
||||
})
|
||||
},
|
||||
@ -1007,15 +1036,18 @@ impl SimChunk {
|
||||
|
||||
let _map_edge_factor = map_edge_factor(posi);
|
||||
let (_, chaos) = gen_cdf.chaos[posi];
|
||||
let (humid_uniform, _) = gen_cdf.humid_base[posi];
|
||||
let alt_pre = gen_cdf.alt[posi];
|
||||
let water_alt_pre = gen_cdf.water_alt[posi];
|
||||
let downhill_pre = gen_cdf.dh[posi];
|
||||
let (flux_uniform, _) = gen_cdf.pure_flux[posi];
|
||||
let flux = gen_cdf.flux[posi];
|
||||
let river = gen_cdf.rivers[posi].clone();
|
||||
|
||||
// Can have NaNs in non-uniform part where pure_water returned true. We just test one of
|
||||
// the four in order to find out whether this is the case.
|
||||
let (flux_uniform, /*flux_non_uniform*/_) = gen_cdf.pure_flux[posi];
|
||||
let (alt_uniform, _) = gen_cdf.alt_no_water[posi];
|
||||
let (temp_uniform, _) = gen_cdf.temp_base[posi];
|
||||
let river = gen_cdf.rivers[posi].clone();
|
||||
let (humid_uniform, _) = gen_cdf.humid_base[posi];
|
||||
|
||||
/* // Vertical difference from the equator (NOTE: "uniform" with much lower granularity than
|
||||
// other uniform quantities, but hopefully this doesn't matter *too* much--if it does, we
|
||||
@ -1030,25 +1062,36 @@ impl SimChunk {
|
||||
// Take the weighted average of our randomly generated base humidity, the scaled
|
||||
// negative altitude, and the calculated water flux over this point in order to compute
|
||||
// humidity.
|
||||
const HUMID_WEIGHTS: [f32; 3] = [4.0, 0.1, 0.1];
|
||||
let humidity = cdf_irwin_hall(
|
||||
&HUMID_WEIGHTS,
|
||||
[humid_uniform, flux_uniform, 1.0 - alt_uniform],
|
||||
);
|
||||
const HUMID_WEIGHTS: [f32; /*3*/2] = [4.0, 1.0/*, 1.0*/];
|
||||
let humidity = /*if flux_non_uniform.is_nan() {
|
||||
0.0
|
||||
} else */{
|
||||
cdf_irwin_hall(
|
||||
&HUMID_WEIGHTS,
|
||||
[humid_uniform, flux_uniform/*, 1.0 - alt_uniform*/],
|
||||
)
|
||||
};
|
||||
|
||||
// We also correlate temperature negatively with altitude and absolute latitude, using
|
||||
// different weighting than we use for humidity.
|
||||
const TEMP_WEIGHTS: [f32; 2] = [2.0, 16.0 /*, 1.0*/];
|
||||
let temp = cdf_irwin_hall(
|
||||
&TEMP_WEIGHTS,
|
||||
[
|
||||
temp_uniform,
|
||||
1.0 - alt_uniform, /* 1.0 - abs_lat_uniform*/
|
||||
],
|
||||
)
|
||||
const TEMP_WEIGHTS: [f32; 2] = [/*1.5, */1.0, 2.0];
|
||||
let temp = /*if flux_non_uniform.is_nan() {
|
||||
0.0
|
||||
} else */{
|
||||
cdf_irwin_hall(
|
||||
&TEMP_WEIGHTS,
|
||||
[
|
||||
temp_uniform,
|
||||
1.0 - alt_uniform, /* 1.0 - abs_lat_uniform*/
|
||||
],
|
||||
)
|
||||
}
|
||||
// Convert to [-1, 1]
|
||||
.sub(0.5)
|
||||
.mul(2.0);
|
||||
/* if (temp - (1.0 - alt_uniform).sub(0.5).mul(2.0)).abs() >= 1e-7 {
|
||||
panic!("Halp!");
|
||||
} */
|
||||
|
||||
let mut alt = CONFIG.sea_level.add(alt_pre.mul(CONFIG.mountain_scale));
|
||||
let water_alt = CONFIG
|
||||
|
@ -74,13 +74,13 @@ pub fn cdf_irwin_hall<const N: usize>(weights: &[f32; N], samples: [f32; N]) ->
|
||||
// We should be able to iterate through the whole power set
|
||||
// instead, and figure out K by calling count_ones(), so we can compute the result in O(2^N)
|
||||
// iterations.
|
||||
let x: f32 = weights
|
||||
let x: f64 = weights
|
||||
.iter()
|
||||
.zip(samples.iter())
|
||||
.map(|(weight, sample)| weight * sample)
|
||||
.map(|(&weight, &sample)| weight as f64 * sample as f64)
|
||||
.sum();
|
||||
|
||||
let mut y = 0.0f32;
|
||||
let mut y = 0.0f64;
|
||||
for subset in 0u32..(1 << N) {
|
||||
// Number of set elements
|
||||
let k = subset.count_ones();
|
||||
@ -89,8 +89,8 @@ pub fn cdf_irwin_hall<const N: usize>(weights: &[f32; N], samples: [f32; N]) ->
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(i, _)| subset & (1 << i) as u32 != 0)
|
||||
.map(|(_, k)| k)
|
||||
.sum::<f32>();
|
||||
.map(|(_, &k)| k as f64)
|
||||
.sum::<f64>();
|
||||
// Compute max(0, x - B_subset)^N
|
||||
let z = (x - z).max(0.0).powi(N as i32);
|
||||
// The parity of k determines whether the sum is negated.
|
||||
@ -98,10 +98,10 @@ pub fn cdf_irwin_hall<const N: usize>(weights: &[f32; N], samples: [f32; N]) ->
|
||||
}
|
||||
|
||||
// Divide by the product of the weights.
|
||||
y /= weights.iter().product::<f32>();
|
||||
y /= weights.iter().map(|&k| k as f64).product::<f64>();
|
||||
|
||||
// Remember to multiply by 1 / N! at the end.
|
||||
y / (1..(N as i32) + 1).product::<i32>() as f32
|
||||
(y / (1..(N as i32) + 1).product::<i32>() as f64) as f32
|
||||
}
|
||||
|
||||
/// First component of each element of the vector is the computed CDF of the noise function at this
|
||||
@ -148,7 +148,7 @@ pub fn vec2_as_uniform_idx(idx: Vec2<i32>) -> usize {
|
||||
/// vector returned by uniform_noise, and (for convenience) the float-translated version of those
|
||||
/// coordinates.
|
||||
/// f should return a value with no NaNs. If there is a NaN, it will panic. There are no other
|
||||
/// conditions on f. If f returns None, the value will be set to 0.0, and will be ignored for the
|
||||
/// conditions on f. If f returns None, the value will be set to NaN, and will be ignored for the
|
||||
/// purposes of computing the uniform range.
|
||||
///
|
||||
/// Returns a vec of (f32, f32) pairs consisting of the percentage of chunks with a value lower than
|
||||
@ -179,7 +179,7 @@ pub fn uniform_noise<F: Float + Send>(
|
||||
// position of the noise in the sorted vector (divided by the vector length).
|
||||
// This guarantees a uniform distribution among the samples (excluding those that returned
|
||||
// None, which will remain at zero).
|
||||
let mut uniform_noise = vec![(0.0, F::zero()); WORLD_SIZE.x * WORLD_SIZE.y].into_boxed_slice();
|
||||
let mut uniform_noise = vec![(0.0, F::nan()/*zero()*/); WORLD_SIZE.x * WORLD_SIZE.y].into_boxed_slice();
|
||||
// NOTE: Consider using try_into here and elsewhere in this function, since i32::MAX
|
||||
// technically doesn't fit in an f32 (even if we should never reach that limit).
|
||||
let total = noise.len() as f32;
|
||||
|
Loading…
Reference in New Issue
Block a user