mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Implement carving strategy for lake connections.
Also fix mapgen slopes and make a much more pleasing world.
This commit is contained in:
parent
1e02025ca8
commit
d2096f540d
@ -51,7 +51,7 @@ impl ClientInit {
|
|||||||
|
|
||||||
let mut last_err = None;
|
let mut last_err = None;
|
||||||
|
|
||||||
'tries: for _ in 0..60 + 1 {
|
'tries: for _ in 0..960 + 1 {
|
||||||
// 300 Seconds
|
// 300 Seconds
|
||||||
if cancel2.load(Ordering::Relaxed) {
|
if cancel2.load(Ordering::Relaxed) {
|
||||||
break;
|
break;
|
||||||
|
@ -64,8 +64,9 @@ fn main() {
|
|||||||
.unwrap_or((CONFIG.sea_level, CONFIG.sea_level, CONFIG.sea_level, 0.0, 0.0, None, None));
|
.unwrap_or((CONFIG.sea_level, CONFIG.sea_level, CONFIG.sea_level, 0.0, 0.0, None, None));
|
||||||
let humidity = humidity.min(1.0).max(0.0);
|
let humidity = humidity.min(1.0).max(0.0);
|
||||||
let temperature = temperature.min(1.0).max(-1.0) * 0.5 + 0.5;
|
let temperature = temperature.min(1.0).max(-1.0) * 0.5 + 0.5;
|
||||||
|
let pos = pos * TerrainChunkSize::RECT_SIZE.map(|e| e as i32);
|
||||||
let downhill_pos = (downhill
|
let downhill_pos = (downhill
|
||||||
.map(|downhill_pos| downhill_pos.map2(TerrainChunkSize::RECT_SIZE, |e, sz: u32| e / sz as i32))
|
.map(|downhill_pos| downhill_pos/*.map2(TerrainChunkSize::RECT_SIZE, |e, sz: u32| e / sz as i32)*/)
|
||||||
.unwrap_or(pos)
|
.unwrap_or(pos)
|
||||||
- pos)/* * scale*/
|
- pos)/* * scale*/
|
||||||
+ pos;
|
+ pos;
|
||||||
@ -92,12 +93,12 @@ fn main() {
|
|||||||
let forward_vec = Vec3::new(
|
let forward_vec = Vec3::new(
|
||||||
(downhill_pos.x - pos.x) as f64,
|
(downhill_pos.x - pos.x) as f64,
|
||||||
(downhill_pos.y - pos.y) as f64,
|
(downhill_pos.y - pos.y) as f64,
|
||||||
(downhill_alt - alt) as f64,
|
(downhill_alt - alt) as f64 * (CONFIG.mountain_scale as f64 / gain as f64),
|
||||||
);
|
);
|
||||||
let up_vec = Vec3::new(
|
let up_vec = Vec3::new(
|
||||||
(cross_pos.x - pos.x) as f64,
|
(cross_pos.x - pos.x) as f64,
|
||||||
(cross_pos.y - pos.y) as f64,
|
(cross_pos.y - pos.y) as f64,
|
||||||
(cross_alt - alt) as f64,
|
(cross_alt - alt) as f64 * (CONFIG.mountain_scale as f64 / gain as f64),
|
||||||
);
|
);
|
||||||
let surface_normal = forward_vec.cross(up_vec).normalized();
|
let surface_normal = forward_vec.cross(up_vec).normalized();
|
||||||
// let surface_normal = Vec3::new((alt_tl - alt_tr) as f64, 1.0, (alt_tl - alt_bl) as f64).normalized();
|
// let surface_normal = Vec3::new((alt_tl - alt_tr) as f64, 1.0, (alt_tl - alt_bl) as f64).normalized();
|
||||||
@ -139,23 +140,17 @@ fn main() {
|
|||||||
0,
|
0,
|
||||||
255,
|
255,
|
||||||
]),
|
]),
|
||||||
Some(RiverKind::Lake { .. }) => u32::from_le_bytes([
|
|
||||||
(((64.0 + water_alt * 191.0) + (- water_depth * 64.0)) * 1.0) as u8,
|
|
||||||
(((32.0 + water_alt * 95.0) + (- water_depth * 32.0)) * 1.0) as u8,
|
|
||||||
0,
|
|
||||||
255,
|
|
||||||
]),
|
|
||||||
Some(RiverKind::River { .. }) => u32::from_le_bytes([
|
Some(RiverKind::River { .. }) => u32::from_le_bytes([
|
||||||
64 + (alt * 191.0) as u8,
|
64 + (alt * 191.0) as u8,
|
||||||
32 + (alt * 95.0) as u8,
|
32 + (alt * 95.0) as u8,
|
||||||
0,
|
0,
|
||||||
255,
|
255,
|
||||||
]),
|
]),
|
||||||
None => {
|
None if water_alt >= water_depth => {
|
||||||
let (r, g, b) = (
|
let (r, g, b) = (
|
||||||
(alt * if is_temperature { temperature as f64 } else if is_shaded { alt } else { 0.0 }).sqrt(),
|
(if is_shaded { alt } else { alt } * if is_temperature { temperature as f64 } else if is_shaded { alt } else { 0.0 }).sqrt(),
|
||||||
if is_shaded { 0.2 + (alt * 0.8) } else { alt },
|
if is_shaded { 0.2 + (alt * 0.8) } else { alt },
|
||||||
(alt * if is_humidity { humidity as f64 } else if is_shaded { alt } else { 0.0 }).sqrt(),
|
(if is_shaded { alt } else { alt } * if is_humidity { humidity as f64 } else if is_shaded { alt } else { 0.0 }).sqrt(),
|
||||||
);
|
);
|
||||||
let light = if is_shaded {
|
let light = if is_shaded {
|
||||||
light
|
light
|
||||||
@ -174,7 +169,13 @@ fn main() {
|
|||||||
(/*alt*//*alt * *//*(1.0 - humidity)*/(alt * temperature).sqrt() * 255.0) as u8,
|
(/*alt*//*alt * *//*(1.0 - humidity)*/(alt * temperature).sqrt() * 255.0) as u8,
|
||||||
255,
|
255,
|
||||||
]) */
|
]) */
|
||||||
}
|
},
|
||||||
|
None | Some(RiverKind::Lake { .. }) => u32::from_le_bytes([
|
||||||
|
(((64.0 + water_alt * 191.0) + (- water_depth * 64.0)) * 1.0) as u8,
|
||||||
|
(((32.0 + water_alt * 95.0) + (- water_depth * 32.0)) * 1.0) as u8,
|
||||||
|
0,
|
||||||
|
255,
|
||||||
|
]),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -183,12 +184,16 @@ fn main() {
|
|||||||
if win.is_key_down(minifb::Key::P) {
|
if win.is_key_down(minifb::Key::P) {
|
||||||
println!(
|
println!(
|
||||||
"\
|
"\
|
||||||
|
Gain: {:?}\n\
|
||||||
|
Scale: {:?}\n\
|
||||||
Land(adjacent): (X = temp, Y = humidity): {:?}\n\
|
Land(adjacent): (X = temp, Y = humidity): {:?}\n\
|
||||||
Rivers: {:?}\n\
|
Rivers: {:?}\n\
|
||||||
Lakes: {:?}\n\
|
Lakes: {:?}\n\
|
||||||
Oceans: {:?}\n\
|
Oceans: {:?}\n\
|
||||||
Total water: {:?}\n\
|
Total water: {:?}\n\
|
||||||
Total land(adjacent): {:?}",
|
Total land(adjacent): {:?}",
|
||||||
|
gain,
|
||||||
|
scale,
|
||||||
quads,
|
quads,
|
||||||
rivers,
|
rivers,
|
||||||
lakes,
|
lakes,
|
||||||
|
@ -436,14 +436,14 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
|
|||||||
(temp < CONFIG.snow_temp ||
|
(temp < CONFIG.snow_temp ||
|
||||||
downhill_alt.sub(CONFIG.sea_level) >= CONFIG.mountain_scale * 0.25)*/
|
downhill_alt.sub(CONFIG.sea_level) >= CONFIG.mountain_scale * 0.25)*/
|
||||||
is_rocky {
|
is_rocky {
|
||||||
// sim.get_interpolated_monotone(wpos, |chunk| chunk.alt)?
|
sim.get_interpolated_monotone(wpos, |chunk| chunk.alt)?
|
||||||
// sim.get_interpolated_bilinear(wpos, |chunk| chunk.alt)?
|
// sim.get_interpolated_bilinear(wpos, |chunk| chunk.alt)?
|
||||||
sim.get_interpolated(wpos, |chunk| chunk.alt)?
|
// sim.get_interpolated(wpos, |chunk| chunk.alt)?
|
||||||
} else {
|
} else {
|
||||||
// sim.get_interpolated_monotone(wpos, |chunk| chunk.alt)?
|
sim.get_interpolated_monotone(wpos, |chunk| chunk.alt)?
|
||||||
sim.get_interpolated(wpos, |chunk| chunk.alt)?
|
// sim.get_interpolated(wpos, |chunk| chunk.alt)?
|
||||||
};
|
};
|
||||||
let basement = sim.get_interpolated/*get_interpolated_monotone*/(wpos, |chunk| chunk.basement)?;
|
let basement = sim./*get_interpolated*/get_interpolated_monotone(wpos, |chunk| chunk.basement)?;
|
||||||
|
|
||||||
// Find the average distance to each neighboring body of water.
|
// Find the average distance to each neighboring body of water.
|
||||||
let mut river_count = 0.0f64;
|
let mut river_count = 0.0f64;
|
||||||
|
@ -231,7 +231,7 @@ pub fn get_rivers(
|
|||||||
let indirection_idx = indirection[chunk_idx];
|
let indirection_idx = indirection[chunk_idx];
|
||||||
// Find the lake we are flowing into.
|
// Find the lake we are flowing into.
|
||||||
let lake_idx = if indirection_idx < 0 {
|
let lake_idx = if indirection_idx < 0 {
|
||||||
// If we're a lake bottom, our own indirection is negative.
|
/* // If we're a lake bottom, our own indirection is negative.
|
||||||
let mut lake = &mut rivers[chunk_idx];
|
let mut lake = &mut rivers[chunk_idx];
|
||||||
let neighbor_pass_idx = downhill_idx;
|
let neighbor_pass_idx = downhill_idx;
|
||||||
// Mass flow from this lake is treated as a weighting factor (this is currently
|
// Mass flow from this lake is treated as a weighting factor (this is currently
|
||||||
@ -278,7 +278,8 @@ pub fn get_rivers(
|
|||||||
// basically a flat vector, but that might be okay from lake to other side of pass.
|
// basically a flat vector, but that might be okay from lake to other side of pass.
|
||||||
lake_neighbor_pass.spline_derivative += /*Vec2::new(weighted_flow.x, weighted_flow.y)*/
|
lake_neighbor_pass.spline_derivative += /*Vec2::new(weighted_flow.x, weighted_flow.y)*/
|
||||||
weighted_flow.map(|e| e as f32);
|
weighted_flow.map(|e| e as f32);
|
||||||
continue;
|
continue; */
|
||||||
|
chunk_idx
|
||||||
} else {
|
} else {
|
||||||
indirection_idx as usize
|
indirection_idx as usize
|
||||||
};
|
};
|
||||||
@ -295,14 +296,21 @@ pub fn get_rivers(
|
|||||||
|
|
||||||
// Find the pass this lake is flowing into (i.e. water at the lake bottom gets
|
// Find the pass this lake is flowing into (i.e. water at the lake bottom gets
|
||||||
// pushed towards the point identified by pass_idx).
|
// pushed towards the point identified by pass_idx).
|
||||||
let neighbor_pass_idx = downhill[lake_idx];
|
let pass_idx = if /*downhill[lake_idx] >= 0*/true {
|
||||||
|
// This is a proper lake with a proper pass
|
||||||
|
(-indirection[lake_idx]) as usize
|
||||||
|
} else {
|
||||||
|
// This lake is actually the ocean.
|
||||||
|
lake_idx
|
||||||
|
};
|
||||||
|
let neighbor_pass_idx = downhill[pass_idx/*lake_idx*/];
|
||||||
// Find our own water height.
|
// Find our own water height.
|
||||||
let chunk_water_alt = water_alt[chunk_idx];
|
let chunk_water_alt = water_alt[chunk_idx];
|
||||||
if neighbor_pass_idx >= 0 {
|
if neighbor_pass_idx >= 0 {
|
||||||
// We may be a river. But we're not sure yet, since we still could be
|
// We may be a river. But we're not sure yet, since we still could be
|
||||||
// underwater. Check the lake height and see if our own water height is within ε of
|
// underwater. Check the lake height and see if our own water height is within ε of
|
||||||
// it.
|
// it.
|
||||||
let pass_idx = (-indirection[lake_idx]) as usize;
|
// let pass_idx = (-indirection[lake_idx]) as usize;
|
||||||
let lake_water_alt = water_alt[lake_idx];
|
let lake_water_alt = water_alt[lake_idx];
|
||||||
if chunk_water_alt == lake_water_alt {
|
if chunk_water_alt == lake_water_alt {
|
||||||
// Not a river.
|
// Not a river.
|
||||||
@ -315,7 +323,8 @@ pub fn get_rivers(
|
|||||||
// rather than downhill.
|
// rather than downhill.
|
||||||
// NOTE: Safe because neighbor_pass_idx >= 0.
|
// NOTE: Safe because neighbor_pass_idx >= 0.
|
||||||
(
|
(
|
||||||
uniform_idx_as_vec2(neighbor_pass_idx as usize),
|
uniform_idx_as_vec2(downhill_idx),
|
||||||
|
// uniform_idx_as_vec2(neighbor_pass_idx as usize),
|
||||||
river_spline_derivative,
|
river_spline_derivative,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@ -607,6 +616,8 @@ fn erode(
|
|||||||
log::debug!("Done draining...");
|
log::debug!("Done draining...");
|
||||||
let height_scale = 1.0; // 1.0 / CONFIG.mountain_scale as f64;
|
let height_scale = 1.0; // 1.0 / CONFIG.mountain_scale as f64;
|
||||||
let mmaxh = CONFIG.mountain_scale as f64 * height_scale;
|
let mmaxh = CONFIG.mountain_scale as f64 * height_scale;
|
||||||
|
// Minimum sediment thickness before we treat erosion as sediment based.
|
||||||
|
let sediment_thickness = 1.0;
|
||||||
// Since maximum uplift rate is expected to be 5.010e-4 m * y^-1, and
|
// Since maximum uplift rate is expected to be 5.010e-4 m * y^-1, and
|
||||||
// 1.0 height units is 1.0 / height_scale m, whatever the
|
// 1.0 height units is 1.0 / height_scale m, whatever the
|
||||||
// max uplift rate is (in units / y), we can find dt by multiplying by
|
// max uplift rate is (in units / y), we can find dt by multiplying by
|
||||||
@ -640,12 +651,12 @@ fn erode(
|
|||||||
// 2e-5 * dt;
|
// 2e-5 * dt;
|
||||||
// 2.244/2048*5*32/(250000/4)*10^6
|
// 2.244/2048*5*32/(250000/4)*10^6
|
||||||
// ln(tan(30/360*2*pi))-ln(tan(6/360*2*pi))*1500 = 3378
|
// ln(tan(30/360*2*pi))-ln(tan(6/360*2*pi))*1500 = 3378
|
||||||
erosion_base as f64 + 2.244 / mmaxh as f64 * /*10.0*//*5.0*//*9.0*//*7.5*/5.0/*3.75*/ * max_uplift as f64;
|
erosion_base as f64 + 2.244 / mmaxh as f64 * /*10.0*//*5.0*//*9.0*//*7.5*//*5.0*//*2.5*/1.5/*3.75*/ * max_uplift as f64;
|
||||||
// 1e-5 * dt;
|
// 1e-5 * dt;
|
||||||
// (2.244*(5.010e-4)/512)/(2.244*(5.010e-4)/2500) = 4.88...
|
// (2.244*(5.010e-4)/512)/(2.244*(5.010e-4)/2500) = 4.88...
|
||||||
// 2.444 * 5
|
// 2.444 * 5
|
||||||
// Stream power erosion constant (sediment), in m^(1-2m) / year (times dt).
|
// Stream power erosion constant (sediment), in m^(1-2m) / year (times dt).
|
||||||
let k_fs = k_fb * /*1.0*//*2.0*/1.0/*4.0*/;
|
let k_fs = k_fb * /*1.0*//*2.0*/2.0/*4.0*/;
|
||||||
let ((dh, indirection, newh, area), mut max_slopes) = rayon::join(
|
let ((dh, indirection, newh, area), mut max_slopes) = rayon::join(
|
||||||
|| {
|
|| {
|
||||||
let mut dh = downhill(h, |posi| is_ocean(posi));
|
let mut dh = downhill(h, |posi| is_ocean(posi));
|
||||||
@ -667,6 +678,8 @@ fn erode(
|
|||||||
// max angle of slope depends on rock strength, which is computed from noise function.
|
// max angle of slope depends on rock strength, which is computed from noise function.
|
||||||
let neighbor_coef = TerrainChunkSize::RECT_SIZE.map(|e| e as f64);
|
let neighbor_coef = TerrainChunkSize::RECT_SIZE.map(|e| e as f64);
|
||||||
let chunk_area = neighbor_coef.x * neighbor_coef.y;
|
let chunk_area = neighbor_coef.x * neighbor_coef.y;
|
||||||
|
// TODO: Make more principled.
|
||||||
|
let mid_slope = (30.0 / 360.0 * 2.0 * f64::consts::PI).tan();
|
||||||
// Iterate in ascending height order.
|
// Iterate in ascending height order.
|
||||||
let mut maxh = 0.0;
|
let mut maxh = 0.0;
|
||||||
let mut nland = 0usize;
|
let mut nland = 0usize;
|
||||||
@ -699,7 +712,7 @@ fn erode(
|
|||||||
let old_h_i = h[posi] as f64;
|
let old_h_i = h[posi] as f64;
|
||||||
let old_b_i = b[posi] as f64;
|
let old_b_i = b[posi] as f64;
|
||||||
let uplift_i = uplift(posi) as f64;
|
let uplift_i = uplift(posi) as f64;
|
||||||
let k = if (old_h_i - old_b_i as f64) > 1.0e-6 {
|
let k = if (old_h_i - old_b_i as f64) > sediment_thickness {
|
||||||
// Sediment
|
// Sediment
|
||||||
k_fs
|
k_fs
|
||||||
} else {
|
} else {
|
||||||
@ -723,8 +736,12 @@ fn erode(
|
|||||||
if new_h_i <= wh_j {
|
if new_h_i <= wh_j {
|
||||||
new_h_i = wh_j;
|
new_h_i = wh_j;
|
||||||
} else {
|
} else {
|
||||||
|
let dz = (new_h_i - /*h_j*//*h_k*/wh_j).max(0.0) / height_scale/* * CONFIG.mountain_scale as f64*/;
|
||||||
|
let mag_slope = dz/*.abs()*/ / neighbor_distance;
|
||||||
|
|
||||||
nland += 1;
|
nland += 1;
|
||||||
sumh += new_h_i;
|
sumh += new_h_i;
|
||||||
|
sums += mag_slope;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Set max_slope to this node's water height (max of receiver's water height and
|
// Set max_slope to this node's water height (max of receiver's water height and
|
||||||
@ -812,19 +829,28 @@ fn erode(
|
|||||||
// Apply thermal erosion.
|
// Apply thermal erosion.
|
||||||
maxh = 0.0;
|
maxh = 0.0;
|
||||||
sumh = 0.0;
|
sumh = 0.0;
|
||||||
|
sums = 0.0;
|
||||||
for &posi in &*newh {
|
for &posi in &*newh {
|
||||||
let posi = posi as usize;
|
let posi = posi as usize;
|
||||||
let posj = dh[posi];
|
let posj = dh[posi];
|
||||||
|
let old_h_i = h[posi] as f64;
|
||||||
|
let old_b_i = b[posi] as f64;
|
||||||
|
let max_slope = max_slopes[posi] as f64;
|
||||||
|
// Remember k_d for this chunk in max_slopes.
|
||||||
|
max_slopes[posi] = if (old_h_i - old_b_i as f64) > sediment_thickness {
|
||||||
|
// Sediment
|
||||||
|
kdsed
|
||||||
|
} else {
|
||||||
|
// Bedrock
|
||||||
|
kd(posi) / (max_slope / mid_slope/*.sqrt()*//*.powf(0.03125)*/)/*.sqrt()*/
|
||||||
|
};
|
||||||
if posj < 0 {
|
if posj < 0 {
|
||||||
if posj == -1 {
|
if posj == -1 {
|
||||||
panic!("Disconnected lake!");
|
panic!("Disconnected lake!");
|
||||||
}
|
}
|
||||||
// max_slopes[posi] = kd(posi);
|
// Egress with no outgoing flows.
|
||||||
// Egress with no outgoing flows.
|
|
||||||
} else {
|
} else {
|
||||||
let posj = posj as usize;
|
let posj = posj as usize;
|
||||||
let old_h_i = h[posi] as f64;
|
|
||||||
let old_b_i = b[posi] as f64;
|
|
||||||
// Find the water height for this chunk's receiver; we only apply thermal erosion
|
// Find the water height for this chunk's receiver; we only apply thermal erosion
|
||||||
// for chunks above water.
|
// for chunks above water.
|
||||||
let wh_j = wh[posj] as f64;
|
let wh_j = wh[posj] as f64;
|
||||||
@ -833,13 +859,15 @@ fn erode(
|
|||||||
if
|
if
|
||||||
/* !is_lake_bottom */ /* !fake_neighbor */
|
/* !is_lake_bottom */ /* !fake_neighbor */
|
||||||
wh_j < old_h_i {
|
wh_j < old_h_i {
|
||||||
let mut new_h_i = old_h_i;
|
let mut new_h_i = old_h_i;//old_b_i;
|
||||||
let h_j = h[posj] as f64;
|
// NOTE: Currently assuming that talus angle is the same once the substance is
|
||||||
|
// submerged in water, but actually that's probably not true.
|
||||||
|
let h_j = h[posj] as f64/*wh_j*/;
|
||||||
|
// let h_j = b[posj] as f64;
|
||||||
/* let indirection_idx = indirection[posi];
|
/* let indirection_idx = indirection[posi];
|
||||||
let is_lake_bottom = indirection_idx < 0;
|
let is_lake_bottom = indirection_idx < 0;
|
||||||
let _fake_neighbor = is_lake_bottom && dxy.x.abs() > 1.0 && dxy.y.abs() > 1.0; */
|
let _fake_neighbor = is_lake_bottom && dxy.x.abs() > 1.0 && dxy.y.abs() > 1.0; */
|
||||||
// Test the slope.
|
// Test the slope.
|
||||||
let max_slope = max_slopes[posi] as f64;
|
|
||||||
// Hacky version of thermal erosion: only consider lowest neighbor, don't redistribute
|
// Hacky version of thermal erosion: only consider lowest neighbor, don't redistribute
|
||||||
// uplift to other neighbors.
|
// uplift to other neighbors.
|
||||||
let (posk, h_k) = /* neighbors(posi)
|
let (posk, h_k) = /* neighbors(posi)
|
||||||
@ -879,11 +907,10 @@ fn erode(
|
|||||||
// new_h_i = slope * neighbor_distance * height_scale /* / CONFIG.mountain_scale as f64 */ + h_j;
|
// new_h_i = slope * neighbor_distance * height_scale /* / CONFIG.mountain_scale as f64 */ + h_j;
|
||||||
// sums += max_slope;
|
// sums += max_slope;
|
||||||
} else {
|
} else {
|
||||||
// max_slopes[posi] = 0.0;
|
|
||||||
sums += mag_slope;
|
sums += mag_slope;
|
||||||
// Just use the computed rate.
|
// Just use the computed rate.
|
||||||
}
|
}
|
||||||
h[posi] = new_h_i as f32;
|
h/*b*/[posi] = new_h_i as f32;
|
||||||
// Make sure to update the basement as well!
|
// Make sure to update the basement as well!
|
||||||
b[posi] = old_b_i.min(new_h_i) as f32;
|
b[posi] = old_b_i.min(new_h_i) as f32;
|
||||||
sumh += new_h_i;
|
sumh += new_h_i;
|
||||||
@ -914,8 +941,8 @@ fn erode(
|
|||||||
dt,
|
dt,
|
||||||
(),
|
(),
|
||||||
h, b,
|
h, b,
|
||||||
/*|posi| max_slopes[posi]*/kd,
|
|posi| max_slopes[posi]/*kd*/,
|
||||||
kdsed,
|
/* kdsed */-1.0,
|
||||||
);
|
);
|
||||||
log::debug!(
|
log::debug!(
|
||||||
"Done eroding (max height: {:?}) (avg height: {:?}) (avg slope: {:?})",
|
"Done eroding (max height: {:?}) (avg height: {:?}) (avg slope: {:?})",
|
||||||
@ -1327,19 +1354,69 @@ pub fn get_lakes(h: &[f32], downhill: &mut [isize]) -> (usize, Box<[i32]>, Box<[
|
|||||||
// in the "downhill" graph, this is guaranteed never to visit a node more than
|
// in the "downhill" graph, this is guaranteed never to visit a node more than
|
||||||
// once.
|
// once.
|
||||||
let start = newh.len();
|
let start = newh.len();
|
||||||
|
// First, find the neighbor pass (assuming this is not the ocean).
|
||||||
|
let neighbor_pass_idx = downhill[chunk_idx];
|
||||||
|
let first_idx = if neighbor_pass_idx < 0 {
|
||||||
|
// This is the ocean.
|
||||||
|
chunk_idx
|
||||||
|
} else {
|
||||||
|
// This is a "real" lake.
|
||||||
|
let neighbor_pass_idx = neighbor_pass_idx as usize;
|
||||||
|
// Let's find our side of the pass.
|
||||||
|
let pass_idx = -indirection[chunk_idx];
|
||||||
|
// NOTE: Since only lakes are on the boundary, this should be a valid array index.
|
||||||
|
assert!(pass_idx >= 0);
|
||||||
|
let pass_idx = pass_idx as usize;
|
||||||
|
// Now, we should recompute flow paths so downhill nodes are contiguous.
|
||||||
|
|
||||||
|
// Carving strategy: reverse the path from the lake side of the pass to the
|
||||||
|
// lake bottom, and also set the lake side of the pass's downhill to its
|
||||||
|
// neighbor pass.
|
||||||
|
//
|
||||||
|
// TODO: Implement filling strategy (not just carving strategy).
|
||||||
|
let mut to_idx = neighbor_pass_idx;
|
||||||
|
let mut from_idx = pass_idx;
|
||||||
|
// NOTE: Since our side of the lake pass must be in the same basin as chunk_idx,
|
||||||
|
// and chunk_idx is the basin bottom, we must reach it before we reach an ocean
|
||||||
|
// node or other node with an invalid index.
|
||||||
|
while from_idx != chunk_idx {
|
||||||
|
// Reverse this (from, to) edge by first replacing to_idx with from_idx,
|
||||||
|
// then replacing from_idx's downhill with the old to_idx, and finally
|
||||||
|
// replacing from_idx with from_idx's old downhill.
|
||||||
|
//
|
||||||
|
// println!("Reversing (lake={:?}): to={:?}, from={:?}, dh={:?}", chunk_idx, to_idx, from_idx, downhill[from_idx]);
|
||||||
|
from_idx = mem::replace(
|
||||||
|
&mut downhill[from_idx],
|
||||||
|
mem::replace(
|
||||||
|
&mut to_idx,
|
||||||
|
// NOTE: This cast should be valid since the node is either a path on the way
|
||||||
|
// to a lake bottom, or a lake bottom with an actual pass outwards.
|
||||||
|
from_idx
|
||||||
|
) as isize,
|
||||||
|
) as usize;
|
||||||
|
}
|
||||||
|
// Remember to set the actual lake's from_idx properly!
|
||||||
|
downhill[from_idx] = to_idx as isize;
|
||||||
|
// Use our side of the pass as the initial node in the stack order.
|
||||||
|
// TODO: Verify that this stack order will not "double reach" any lake chunks.
|
||||||
|
pass_idx
|
||||||
|
};
|
||||||
|
// newh.push(chunk_idx as u32);
|
||||||
// New lake root
|
// New lake root
|
||||||
newh.push(chunk_idx as u32);
|
newh.push(first_idx as u32);
|
||||||
let mut cur = start;
|
let mut cur = start;
|
||||||
while cur < newh.len() {
|
while cur < newh.len() {
|
||||||
let node = newh[cur as usize];
|
let node = newh[cur as usize];
|
||||||
|
|
||||||
for child in uphill(downhill, node as usize) {
|
for child in uphill(downhill, node as usize) {
|
||||||
// lake_idx is the index of our lake root.
|
// lake_idx is the index of our lake root.
|
||||||
// Check to make sure child (flowing into us) isn't a lake.
|
// Check to make sure child (flowing into us) is in the same lake.
|
||||||
if indirection[child] >= 0
|
if indirection[child] == chunk_idx as i32 || child == chunk_idx
|
||||||
|
// // Check to make sure child (flowing into us) isn't a lake.
|
||||||
|
// if indirection[child] >= 0 || child == chunk_idx
|
||||||
/* Note: equal to chunk_idx should be same */
|
/* Note: equal to chunk_idx should be same */
|
||||||
{
|
{
|
||||||
assert!(h[child] >= h[node as usize]);
|
// assert!(h[child] >= h[node as usize]);
|
||||||
newh.push(child as u32);
|
newh.push(child as u32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1403,14 +1480,14 @@ pub fn do_erosion(
|
|||||||
let height_scale = 1.0; // 1.0 / CONFIG.mountain_scale as f64;
|
let height_scale = 1.0; // 1.0 / CONFIG.mountain_scale as f64;
|
||||||
let mmaxh = CONFIG.mountain_scale as f64 * height_scale;
|
let mmaxh = CONFIG.mountain_scale as f64 * height_scale;
|
||||||
let dt = max_uplift as f64 / height_scale /* * CONFIG.mountain_scale as f64*/ / 5.010e-4;
|
let dt = max_uplift as f64 / height_scale /* * CONFIG.mountain_scale as f64*/ / 5.010e-4;
|
||||||
let k_fb = (erosion_base as f64 + 2.244 / mmaxh as f64 * /*10.0*//*5.0*//*9.0*//*7.5*/5.0/*3.75*/ * max_uplift as f64) / dt;
|
let k_fb = (erosion_base as f64 + 2.244 / mmaxh as f64 * /*10.0*//*5.0*//*9.0*//*7.5*//*5.0*//*2.5*//*1.5*/4.0/*1.0*//*3.75*/ * max_uplift as f64) / dt;
|
||||||
let kd_bedrock =
|
let kd_bedrock =
|
||||||
/*1e-2*//*0.25e-2*/1e-2 * height_scale * height_scale/* / (CONFIG.mountain_scale as f64 * CONFIG.mountain_scale as f64) */
|
/*1e-2*//*0.25e-2*/1e-2 * height_scale * height_scale/* / (CONFIG.mountain_scale as f64 * CONFIG.mountain_scale as f64) */
|
||||||
/* * k_fb / 2e-5 */;
|
/* * k_fb / 2e-5 */;
|
||||||
let kdsed =
|
let kdsed =
|
||||||
/*1.5e-2*//*1e-4*//*1.25e-2*/1.5e-2 * height_scale * height_scale/* / (CONFIG.mountain_scale as f64 * CONFIG.mountain_scale as f64) */
|
/*1.5e-2*//*1e-4*//*1.25e-2*/1.5e-2 * height_scale * height_scale/* / (CONFIG.mountain_scale as f64 * CONFIG.mountain_scale as f64) */
|
||||||
/* * k_fb / 2e-5 */;
|
/* * k_fb / 2e-5 */;
|
||||||
let kd = |posi: usize| if is_ocean(posi) { /*0.0*/kd_bedrock } else { kd_bedrock };
|
let kd = |posi: usize| kd_bedrock; // if is_ocean(posi) { /*0.0*/kd_bedrock } else { kd_bedrock };
|
||||||
// Hillslope diffusion coefficient for sediment.
|
// Hillslope diffusion coefficient for sediment.
|
||||||
let mut is_done = bitbox![0; WORLD_SIZE.x * WORLD_SIZE.y];
|
let mut is_done = bitbox![0; WORLD_SIZE.x * WORLD_SIZE.y];
|
||||||
for i in 0..n {
|
for i in 0..n {
|
||||||
|
@ -101,6 +101,9 @@ pub(crate) struct GenCtx {
|
|||||||
pub fast_turb_y_nz: FastNoise,
|
pub fast_turb_y_nz: FastNoise,
|
||||||
|
|
||||||
pub town_gen: StructureGen2d,
|
pub town_gen: StructureGen2d,
|
||||||
|
|
||||||
|
pub river_seed: RandomField,
|
||||||
|
pub rock_strength_nz: HybridMulti_,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WorldSim {
|
pub struct WorldSim {
|
||||||
@ -116,6 +119,7 @@ impl WorldSim {
|
|||||||
pub fn generate(seed: u32) -> Self {
|
pub fn generate(seed: u32) -> Self {
|
||||||
let mut rng = ChaChaRng::from_seed(seed_expan::rng_state(seed));
|
let mut rng = ChaChaRng::from_seed(seed_expan::rng_state(seed));
|
||||||
let continent_scale = 5_000.0f64/*32768.0*/.div(32.0).mul(TerrainChunkSize::RECT_SIZE.x as f64);
|
let continent_scale = 5_000.0f64/*32768.0*/.div(32.0).mul(TerrainChunkSize::RECT_SIZE.x as f64);
|
||||||
|
let rock_lacunarity = 0.5/*HybridMulti::DEFAULT_LACUNARITY*/;
|
||||||
|
|
||||||
let gen_ctx = GenCtx {
|
let gen_ctx = GenCtx {
|
||||||
turb_x_nz: SuperSimplex::new().set_seed(rng.gen()),
|
turb_x_nz: SuperSimplex::new().set_seed(rng.gen()),
|
||||||
@ -185,14 +189,12 @@ impl WorldSim {
|
|||||||
fast_turb_y_nz: FastNoise::new(rng.gen()),
|
fast_turb_y_nz: FastNoise::new(rng.gen()),
|
||||||
|
|
||||||
town_gen: StructureGen2d::new(rng.gen(), 2048, 1024),
|
town_gen: StructureGen2d::new(rng.gen(), 2048, 1024),
|
||||||
};
|
river_seed: RandomField::new(rng.gen()),
|
||||||
|
rock_strength_nz: /*Fbm*/HybridMulti_/*BasicMulti*//*Fbm*/::new()
|
||||||
let river_seed = RandomField::new(rng.gen());
|
|
||||||
let rock_lacunarity = 0.5/*HybridMulti::DEFAULT_LACUNARITY*/;
|
|
||||||
let rock_strength_nz = /*Fbm*/HybridMulti_/*BasicMulti*//*Fbm*/::new()
|
|
||||||
.set_octaves(/*6*//*5*//*4*//*5*//*4*/6)
|
.set_octaves(/*6*//*5*//*4*//*5*//*4*/6)
|
||||||
// persistence = lacunarity^(-(1.0 - fractal increment))
|
// persistence = lacunarity^(-(1.0 - fractal increment))
|
||||||
.set_persistence(/*0.9*/ /*2.0*//*1.5*//*HybridMulti::DEFAULT_LACUNARITY*/rock_lacunarity.powf(-(1.0 - 0.9)))
|
// NOTE: In paper, fractal increment is roughly 0.25.
|
||||||
|
.set_persistence(/*0.9*/ /*2.0*//*1.5*//*HybridMulti::DEFAULT_LACUNARITY*/rock_lacunarity.powf(-(1.0 - 0.25/*0.9*/)))
|
||||||
// 256*32/2^4
|
// 256*32/2^4
|
||||||
// (0.5^(-(1.0-0.9)))^4/256/32*2^4*16*32
|
// (0.5^(-(1.0-0.9)))^4/256/32*2^4*16*32
|
||||||
// (0.5^(-(1.0-0.9)))^4/256/32*2^4*256*4
|
// (0.5^(-(1.0-0.9)))^4/256/32*2^4*256*4
|
||||||
@ -203,7 +205,11 @@ impl WorldSim {
|
|||||||
// .set_persistence(/*0.9*/ /*2.0*/0.67)
|
// .set_persistence(/*0.9*/ /*2.0*/0.67)
|
||||||
// .set_frequency(/*0.9*/ Fbm::DEFAULT_FREQUENCY / (2.0 * 32.0))
|
// .set_frequency(/*0.9*/ Fbm::DEFAULT_FREQUENCY / (2.0 * 32.0))
|
||||||
// .set_lacunarity(0.5)
|
// .set_lacunarity(0.5)
|
||||||
.set_seed(rng.gen());
|
.set_seed(rng.gen()),
|
||||||
|
};
|
||||||
|
|
||||||
|
let river_seed = &gen_ctx.river_seed;
|
||||||
|
let rock_strength_nz = &gen_ctx.rock_strength_nz;
|
||||||
// NOTE: octaves should definitely fit into i32, but we should check anyway to make
|
// NOTE: octaves should definitely fit into i32, but we should check anyway to make
|
||||||
// sure.
|
// sure.
|
||||||
/* assert!(rock_strength_nz.persistence > 0.0);
|
/* assert!(rock_strength_nz.persistence > 0.0);
|
||||||
@ -216,11 +222,11 @@ impl WorldSim {
|
|||||||
.set_scale(1.0 / rock_strength_scale); */
|
.set_scale(1.0 / rock_strength_scale); */
|
||||||
|
|
||||||
let height_scale = 1.0f64; // 1.0 / CONFIG.mountain_scale as f64;
|
let height_scale = 1.0f64; // 1.0 / CONFIG.mountain_scale as f64;
|
||||||
let max_erosion_per_delta_t = /*32.0*//*128.0*/128.0 * height_scale;
|
let max_erosion_per_delta_t = /*32.0*//*128.0*/32.0 * height_scale;
|
||||||
let erosion_pow_low = /*0.25*//*1.5*//*2.0*//*0.5*//*4.0*//*0.25*//*1.0*//*2.0*//*1.5*//*1.5*//*0.35*//*0.43*//*0.5*//*0.45*//*0.37*/1.002;
|
let erosion_pow_low = /*0.25*//*1.5*//*2.0*//*0.5*//*4.0*//*0.25*//*1.0*//*2.0*//*1.5*//*1.5*//*0.35*//*0.43*//*0.5*//*0.45*//*0.37*/1.002;
|
||||||
let erosion_pow_high = /*1.5*//*1.0*//*0.55*//*0.51*//*2.0*/1.002;
|
let erosion_pow_high = /*1.5*//*1.0*//*0.55*//*0.51*//*2.0*/1.002;
|
||||||
let erosion_center = /*0.45*//*0.75*//*0.75*//*0.5*//*0.75*/0.5;
|
let erosion_center = /*0.45*//*0.75*//*0.75*//*0.5*//*0.75*/0.5;
|
||||||
let n_steps = /*100*/25/*100*//*37*/;//150;//37/*100*/;//50;//50;//37;//50;//37; // /*37*//*29*//*40*//*150*/37; //150;//200;
|
let n_steps = /*100*//*50*/100/*100*//*37*/;//150;//37/*100*/;//50;//50;//37;//50;//37; // /*37*//*29*//*40*//*150*/37; //150;//200;
|
||||||
let n_small_steps = 8;//8;//8; // 8
|
let n_small_steps = 8;//8;//8; // 8
|
||||||
|
|
||||||
// fractal dimension should be between 0 and 0.9999...
|
// fractal dimension should be between 0 and 0.9999...
|
||||||
@ -509,7 +515,8 @@ impl WorldSim {
|
|||||||
1.0 / (WORLD_SIZE.x as f64 * WORLD_SIZE.y as f64).max(f64::EPSILON as f64 * 0.5);
|
1.0 / (WORLD_SIZE.x as f64 * WORLD_SIZE.y as f64).max(f64::EPSILON as f64 * 0.5);
|
||||||
let max_epsilon = (1.0 - 1.0 / (WORLD_SIZE.x as f64 * WORLD_SIZE.y as f64))
|
let max_epsilon = (1.0 - 1.0 / (WORLD_SIZE.x as f64 * WORLD_SIZE.y as f64))
|
||||||
.min(1.0 - f64::EPSILON as f64 * 0.5);
|
.min(1.0 - f64::EPSILON as f64 * 0.5);
|
||||||
let inv_func = /*|x: f64| x*//*exp_inverse_cdf*/logit/*hypsec_inverse_cdf*/;
|
// ((ln(0.6)-ln(1-0.6)) - (ln(1/(2048*2048))-ln((1-1/(2048*2048)))))/((ln(1-1/(2048*2048))-ln(1-(1-1/(2048*2048)))) - (ln(1/(2048*2048))-ln((1-1/(2048*2048)))))
|
||||||
|
let inv_func = /*|x: f64| x*/exp_inverse_cdf/*logit*//*hypsec_inverse_cdf*/;
|
||||||
let alt_exp_min_uniform = /*exp_inverse_cdf*//*logit*/inv_func(min_epsilon);
|
let alt_exp_min_uniform = /*exp_inverse_cdf*//*logit*/inv_func(min_epsilon);
|
||||||
let alt_exp_max_uniform = /*exp_inverse_cdf*//*logit*/inv_func(max_epsilon);
|
let alt_exp_max_uniform = /*exp_inverse_cdf*//*logit*/inv_func(max_epsilon);
|
||||||
|
|
||||||
@ -525,7 +532,7 @@ impl WorldSim {
|
|||||||
/* let erosion_factor = |x: f64| logistic_cdf(logistic_base * if x <= /*erosion_center*/alt_old_center_uniform/*alt_old_center*/ { erosion_pow_low.ln() } else { erosion_pow_high.ln() } * log_odds(x))/*0.5 + (x - 0.5).signum() * ((x - 0.5).mul(2.0).abs(
|
/* let erosion_factor = |x: f64| logistic_cdf(logistic_base * if x <= /*erosion_center*/alt_old_center_uniform/*alt_old_center*/ { erosion_pow_low.ln() } else { erosion_pow_high.ln() } * log_odds(x))/*0.5 + (x - 0.5).signum() * ((x - 0.5).mul(2.0).abs(
|
||||||
).powf(erosion_pow).mul(0.5))*/; */
|
).powf(erosion_pow).mul(0.5))*/; */
|
||||||
let erosion_factor = |x: f64| (/*if x <= /*erosion_center*/alt_old_center_uniform/*alt_old_center*/ { erosion_pow_low.ln() } else { erosion_pow_high.ln() } * */(/*exp_inverse_cdf*//*logit*/inv_func(x) - alt_exp_min_uniform) / (alt_exp_max_uniform - alt_exp_min_uniform))/*0.5 + (x - 0.5).signum() * ((x - 0.5).mul(2.0).abs(
|
let erosion_factor = |x: f64| (/*if x <= /*erosion_center*/alt_old_center_uniform/*alt_old_center*/ { erosion_pow_low.ln() } else { erosion_pow_high.ln() } * */(/*exp_inverse_cdf*//*logit*/inv_func(x) - alt_exp_min_uniform) / (alt_exp_max_uniform - alt_exp_min_uniform))/*0.5 + (x - 0.5).signum() * ((x - 0.5).mul(2.0).abs(
|
||||||
).powf(erosion_pow).mul(0.5))*//*.powf(0.5)*//*.powf(1.5)*/.powf(2.0);
|
).powf(erosion_pow).mul(0.5))*/.powf(0.5)/*.powf(1.5)*//*.powf(2.0)*/;
|
||||||
let uplift_fn =
|
let uplift_fn =
|
||||||
|posi| {
|
|posi| {
|
||||||
if is_ocean_fn(posi) {
|
if is_ocean_fn(posi) {
|
||||||
@ -615,8 +622,15 @@ impl WorldSim {
|
|||||||
} else {
|
} else {
|
||||||
(0.0, 0.0)
|
(0.0, 0.0)
|
||||||
};
|
};
|
||||||
|
// tan(6/360*2*pi)*32 ~ 3.4
|
||||||
|
// 3.4/32*512 ~ 54
|
||||||
|
// 18/32*512 ~ 288
|
||||||
|
// tan(pi/6)*32 ~ 18
|
||||||
|
// tan(54/360*2*pi)*32
|
||||||
// let height = 1.0f64;
|
// let height = 1.0f64;
|
||||||
// let height = 1.0 / 7.0f64;
|
// let height = 1.0 / 7.0f64;
|
||||||
|
let bfrac = erosion_factor(0.5);
|
||||||
|
let height = (height - bfrac).abs().div(1.0 - bfrac);
|
||||||
let height = height
|
let height = height
|
||||||
/* .mul(15.0 / 16.0)
|
/* .mul(15.0 / 16.0)
|
||||||
.add(1.0 / 16.0) */
|
.add(1.0 / 16.0) */
|
||||||
@ -638,6 +652,7 @@ impl WorldSim {
|
|||||||
// -0.75
|
// -0.75
|
||||||
// -CONFIG.sea_level / CONFIG.mountain_scale
|
// -CONFIG.sea_level / CONFIG.mountain_scale
|
||||||
// 0.0
|
// 0.0
|
||||||
|
// 0.0
|
||||||
old_height(posi) // 0.0
|
old_height(posi) // 0.0
|
||||||
} else {
|
} else {
|
||||||
// uplift_fn(posi)
|
// uplift_fn(posi)
|
||||||
@ -673,6 +688,7 @@ impl WorldSim {
|
|||||||
.mul(0.045)*/)
|
.mul(0.045)*/)
|
||||||
};
|
};
|
||||||
old_height_uniform(posi)/*.powf(2.0)*/
|
old_height_uniform(posi)/*.powf(2.0)*/
|
||||||
|
// 0.0
|
||||||
/* // 0.0
|
/* // 0.0
|
||||||
// -/*CONFIG.sea_level / CONFIG.mountain_scale*//* 0.75 */1.0
|
// -/*CONFIG.sea_level / CONFIG.mountain_scale*//* 0.75 */1.0
|
||||||
// ((old_height(posi) - alt_old_min) as f64 / (alt_old_max - alt_old_min) as f64) as f32
|
// ((old_height(posi) - alt_old_min) as f64 / (alt_old_max - alt_old_min) as f64) as f32
|
||||||
@ -723,10 +739,10 @@ impl WorldSim {
|
|||||||
} else {
|
} else {
|
||||||
indirection_idx as usize
|
indirection_idx as usize
|
||||||
};
|
};
|
||||||
// Find the pass this lake is flowing into (i.e. water at the lake bottom gets
|
/* // Find the pass this lake is flowing into (i.e. water at the lake bottom gets
|
||||||
// pushed towards the point identified by pass_idx).
|
// pushed towards the point identified by pass_idx).
|
||||||
let neighbor_pass_idx = dh[lake_idx];
|
let neighbor_pass_idx = dh[lake_idx]; */
|
||||||
let chunk_water_alt = if neighbor_pass_idx < 0 {
|
let chunk_water_alt = if /*neighbor_pass_idx*/dh[lake_idx] < 0 {
|
||||||
// This is either a boundary node (dh[chunk_idx] == -2, i.e. water is at sea level)
|
// This is either a boundary node (dh[chunk_idx] == -2, i.e. water is at sea level)
|
||||||
// or part of a lake that flows directly into the ocean. In the former case, water
|
// or part of a lake that flows directly into the ocean. In the former case, water
|
||||||
// is at sea level so we just return 0.0. In the latter case, the lake bottom must
|
// is at sea level so we just return 0.0. In the latter case, the lake bottom must
|
||||||
@ -740,12 +756,15 @@ impl WorldSim {
|
|||||||
// figure out the initial water height (which fill_sinks will then extend to make
|
// figure out the initial water height (which fill_sinks will then extend to make
|
||||||
// sure it fills the entire basin).
|
// sure it fills the entire basin).
|
||||||
|
|
||||||
// Find the height of the pass into which our lake is flowing.
|
|
||||||
let pass_height_j = alt[neighbor_pass_idx as usize];
|
|
||||||
// Find the height of "our" side of the pass (the part of it that drains into this
|
// Find the height of "our" side of the pass (the part of it that drains into this
|
||||||
// chunk's lake).
|
// chunk's lake).
|
||||||
let pass_idx = -indirection[lake_idx];
|
let pass_idx = -indirection[lake_idx] as usize;
|
||||||
let pass_height_i = alt[pass_idx as usize];
|
let pass_height_i = alt[pass_idx];
|
||||||
|
// Find the pass this lake is flowing into (i.e. water at the lake bottom gets
|
||||||
|
// pushed towards the point identified by pass_idx).
|
||||||
|
let neighbor_pass_idx = dh[pass_idx/*lake_idx*/];
|
||||||
|
// Find the height of the pass into which our lake is flowing.
|
||||||
|
let pass_height_j = alt[neighbor_pass_idx as usize];
|
||||||
// Find the maximum of these two heights.
|
// Find the maximum of these two heights.
|
||||||
let pass_height = pass_height_i.max(pass_height_j);
|
let pass_height = pass_height_i.max(pass_height_j);
|
||||||
// Use the pass height as the initial water altitude.
|
// Use the pass height as the initial water altitude.
|
||||||
@ -769,10 +788,10 @@ impl WorldSim {
|
|||||||
} else {
|
} else {
|
||||||
indirection_idx as usize
|
indirection_idx as usize
|
||||||
};
|
};
|
||||||
// Find the pass this lake is flowing into (i.e. water at the lake bottom gets
|
/* // Find the pass this lake is flowing into (i.e. water at the lake bottom gets
|
||||||
// pushed towards the point identified by pass_idx).
|
// pushed towards the point identified by pass_idx).
|
||||||
let neighbor_pass_idx = dh[lake_idx];
|
let neighbor_pass_idx = dh[lake_idx]; */
|
||||||
if neighbor_pass_idx < 0 {
|
if /*neighbor_pass_idx*/dh[lake_idx] < 0 {
|
||||||
// This is either a boundary node (dh[chunk_idx] == -2, i.e. water is at sea level)
|
// This is either a boundary node (dh[chunk_idx] == -2, i.e. water is at sea level)
|
||||||
// or part of a lake that flows directly into the ocean. In the former case, water
|
// or part of a lake that flows directly into the ocean. In the former case, water
|
||||||
// is at sea level so we just return 0.0. In the latter case, the lake bottom must
|
// is at sea level so we just return 0.0. In the latter case, the lake bottom must
|
||||||
|
Loading…
x
Reference in New Issue
Block a user