From f118d15745c1278d6c876c25ec4a4f4f6e88416f Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Fri, 3 Sep 2021 02:17:47 +0100 Subject: [PATCH] Fixed oceans --- common/src/terrain/mod.rs | 37 ++++++++++++++++++++++++------------- world/src/block/mod.rs | 2 +- world/src/column/mod.rs | 17 +++++++++++++---- world/src/layer/scatter.rs | 3 ++- 4 files changed, 40 insertions(+), 19 deletions(-) diff --git a/common/src/terrain/mod.rs b/common/src/terrain/mod.rs index 8aaf7357c5..553c688ce5 100644 --- a/common/src/terrain/mod.rs +++ b/common/src/terrain/mod.rs @@ -295,14 +295,14 @@ pub fn quadratic_nearest_point( point: Vec2, line: Vec2>, ) -> Option<(f64, Vec2, f64)> { - let line = LineSegment2 { - start: line.x, - end: line.y, - }; - let len_sq = line.start.distance_squared(line.end); - let t = ((point - line.start).dot(line.end - line.start) / len_sq).clamped(0.0, 1.0); - let pos = line.start + (line.end - line.start) * t; - return Some((t, pos, pos.distance_squared(point))); + // let line = LineSegment2 { + // start: line.x, + // end: line.y, + // }; + // let len_sq = line.start.distance_squared(line.end); + // let t = ((point - line.start).dot(line.end - line.start) / len_sq).clamped(0.0, 1.0); + // let pos = line.start + (line.end - line.start) * t; + // return Some((t, pos, pos.distance_squared(point))); // let curve = QuadraticBezier2 { // start: spline.x, @@ -346,19 +346,25 @@ pub fn quadratic_nearest_point( let min_root = roots .iter() .copied() + // .chain((0..30).map(|i| i as f64 / 30.0)) .filter_map(|root| { let river_point = spline.x * root * root + spline.y * root + spline.z; let river_zero = spline.z; let river_one = spline.x + spline.y + spline.z; if root > 0.0 && root < 1.0 { Some((root, river_point)) - } else if river_point.distance_squared(river_zero) < 0.5 { - Some((root, /*river_point*/ river_zero)) - } else if river_point.distance_squared(river_one) < 0.5 { - Some((root, /*river_point*/ river_one)) } else { - None + let root = root.clamped(0.0, 1.0); + let river_point = spline.x * root * root + spline.y * root + spline.z; + Some((root, river_point)) } + // } else if river_point.distance_squared(river_zero) < 0.5 { + // Some((root, /*river_point*/ river_zero)) + // } else if river_point.distance_squared(river_one) < 0.5 { + // Some((root, /*river_point*/ river_one)) + // } else { + // None + // } }) .map(|(root, river_point)| { let river_distance = river_point.distance_squared(point); @@ -372,4 +378,9 @@ pub fn quadratic_nearest_point( .unwrap() }); min_root + // .map(|(t, pt, dist)| { + // let t = t.clamped(0.0, 1.0); + // let pos = spline.x * t * t + spline.y * t + spline.z; + // (t, pos, pos.distance_squared(point)) + // }) } diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index 84512102f0..ad9219d54b 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -152,7 +152,7 @@ impl<'a> BlockGen<'a> { .div(grass_depth) .sqrt(); // Surface - Some(if water_level.floor() > height { + Some(if water_level > height.ceil() { Block::new( BlockKind::Sand, sub_surface_color.map(|e| (e * 255.0) as u8), diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index e86bbad9b7..b75655b015 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -145,6 +145,13 @@ impl<'a> Sampler<'a> for ColumnGen<'a> { let (t, pos) = curve.binary_search_point_by_steps(wposf, 16, 0.001); Some((t, pos, curve.evaluate(t).distance_squared(wposf))) }*/ { + let (t, pt, dist) = if dist > wposf.distance_squared(neighbor_wpos) { + (0.0, neighbor_wpos, wposf.distance_squared(neighbor_wpos)) + } else if dist > wposf.distance_squared(downhill_wpos) { + (1.0, downhill_wpos, wposf.distance_squared(downhill_wpos)) + } else { + (t, pt, dist) + }; (direction, coeffs, downhill_chunk, t, pt, dist.sqrt()) } else { let ndist = wposf.distance_squared(neighbor_wpos); @@ -325,7 +332,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> { } let water_level = neighbor_river_data.clone().fold( - WeightedSum::default(), + WeightedSum::default().with_max(CONFIG.sea_level + 2.0), // TODO: Don't add 2.0 |water_level, (river_chunk_idx, river_chunk, river, dist_info)| match (river.river_kind, dist_info) { ( Some(kind/*RiverKind::River { cross_section }*/), @@ -345,7 +352,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> { water_level.with(river_water_alt, near_river) }, // Slightly wider threshold is chosen in case the lake bounds are a bit wrong - RiverKind::Lake { .. } if river_edge_dist <= 16.0 => { + RiverKind::Lake { .. } if river_edge_dist <= 8.0 => { let lake_water_alt = Lerp::lerp( river_chunk.alt.max(river_chunk.water_alt), downhill_chunk.alt.max(downhill_chunk.water_alt), @@ -399,7 +406,9 @@ impl<'a> Sampler<'a> for ColumnGen<'a> { const MIN_DEPTH: f32 = 0.5; let near_centre = ((river_dist / (river_width * 0.5)) as f32).min(1.0).mul(f32::consts::PI).cos().add(1.0).mul(0.5);; let riverbed_depth = near_centre * river_width as f32 * 0.35 + MIN_DEPTH; - alt.with_min(water_alt - riverbed_depth) + // Handle rivers debouching into the ocean nicely by 'flattening' their bottom + let riverbed_alt = (water_alt - riverbed_depth).max(riverless_alt.min(CONFIG.sea_level)); + alt.with_min(riverbed_alt) } else { const GORGE: f32 = 0.5; const BANK_SCALE: f32 = 24.0; @@ -1223,7 +1232,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> { // Land ground, // Beach - ((ocean_level - 1.0) / 2.0).max(0.0), + ((ocean_level - 0.0) / 2.0).max(0.0), ), surface_veg, ), diff --git a/world/src/layer/scatter.rs b/world/src/layer/scatter.rs index 90ccfce307..ee221edf32 100644 --- a/world/src/layer/scatter.rs +++ b/world/src/layer/scatter.rs @@ -603,7 +603,8 @@ pub fn apply_scatter_to(canvas: &mut Canvas, rng: &mut impl Rng) { ]; canvas.foreach_col(|canvas, wpos2d, col| { - let underwater = col.alt < col.water_level; + // TODO: Why do we need to add 1.0 here? Idk... + let underwater = col.alt.floor() + 1.0 < col.water_level.floor(); let kind = scatter .iter()