mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-12 03:24:14 +00:00
Prefer longer routes when ranking river sources
routing.lengthPreference adds route length to the source score so outlets take their longest legal course.
This commit is contained in:
@@ -278,6 +278,7 @@ final class PackHydrologyValidator {
|
||||
PackJsonFieldChecks.validateOptionalDoubleRange(path, routing, "uphillPenalty", 0D, 128D, errors);
|
||||
PackJsonFieldChecks.validateOptionalDoubleRange(path, routing, "slopePenalty", 0D, 16D, errors);
|
||||
PackJsonFieldChecks.validateOptionalDoubleRange(path, routing, "confluenceAttraction", 0D, 1D, errors);
|
||||
PackJsonFieldChecks.validateOptionalDoubleRange(path, routing, "lengthPreference", 0D, 8D, errors);
|
||||
|
||||
int tileSize = integerValue(routing, "tileSize", 2048);
|
||||
int sampleSpacing = integerValue(routing, "sampleSpacing", 64);
|
||||
|
||||
@@ -2113,9 +2113,10 @@ public final class HydrologyPlanner {
|
||||
addSourceDiagnostic(node, surface, stable, HydrologyCandidateRejection.COURSE_TOO_SHORT, diagnostics);
|
||||
continue;
|
||||
}
|
||||
// Elevation and route length share the same scale: 1000 route blocks count as 100 blocks of height.
|
||||
double score = (required ? 1.0E15D : 0D)
|
||||
+ weight * 1.0E9D
|
||||
+ terrain.naturalHeight() * 1.0E5D
|
||||
+ (terrain.naturalHeight() + routeLength * 0.1D * settings.routing().lengthPreference()) * 1.0E5D
|
||||
+ routing.potential()[node.index()]
|
||||
+ HydrologyHash.unit(stable);
|
||||
candidates.add(new SourceCandidate(node.index(), stable, score, required));
|
||||
|
||||
@@ -35,7 +35,7 @@ public record HydrologyPlannerSettings(
|
||||
Source undergroundSources = new Source(true, 0.25D, Integer.MIN_VALUE, 0, 1, 512);
|
||||
return new HydrologyPlannerSettings(
|
||||
63,
|
||||
new Routing(2048, 64, 8192, 8192, 384, 192, 1.5D, 24D, 2D, 0.2D),
|
||||
new Routing(2048, 64, 8192, 8192, 384, 192, 1.5D, 24D, 2D, 0.2D, 1D),
|
||||
new Surface(true, surfaceSources, 4, 8, 2, 4, 10, 1.5D, Banks.defaults()),
|
||||
new Hydraulics(8),
|
||||
new Underground(true, undergroundSources, -48, 72, 3, 8, 1, 3, 6, 14, true),
|
||||
@@ -151,7 +151,8 @@ public record HydrologyPlannerSettings(
|
||||
double valleyPreference,
|
||||
double uphillPenalty,
|
||||
double slopePenalty,
|
||||
double confluenceAttraction
|
||||
double confluenceAttraction,
|
||||
double lengthPreference
|
||||
) {
|
||||
public Routing {
|
||||
if (tileSize < 32 || sampleSpacing < 4 || tileSize % sampleSpacing != 0) {
|
||||
@@ -177,6 +178,7 @@ public record HydrologyPlannerSettings(
|
||||
requireFiniteNonNegative(uphillPenalty, "uphillPenalty");
|
||||
requireFiniteNonNegative(slopePenalty, "slopePenalty");
|
||||
requireFiniteNonNegative(confluenceAttraction, "confluenceAttraction");
|
||||
requireFiniteNonNegative(lengthPreference, "lengthPreference");
|
||||
}
|
||||
|
||||
// Route refinement is derived from the lattice, never authored.
|
||||
|
||||
+2
-1
@@ -671,7 +671,8 @@ public final class IrisHydrologyRuntime implements AutoCloseable {
|
||||
routing.getValleyPreference(),
|
||||
routing.getUphillPenalty(),
|
||||
routing.getSlopePenalty(),
|
||||
routing.getConfluenceAttraction()
|
||||
routing.getConfluenceAttraction(),
|
||||
routing.getLengthPreference()
|
||||
);
|
||||
HydrologyPlannerSettings.Source plannerSurfaceSources = new HydrologyPlannerSettings.Source(
|
||||
surfaceEnabled,
|
||||
|
||||
@@ -70,4 +70,9 @@ public class IrisRiverRoutingConfig {
|
||||
@MaxNumber(1)
|
||||
@Desc("How strongly routes are drawn toward existing drainage.")
|
||||
private double confluenceAttraction = 0.2D;
|
||||
|
||||
@MinNumber(0)
|
||||
@MaxNumber(8)
|
||||
@Desc("How strongly longer source-to-outlet routes are preferred when choosing river sources; 0 ranks by elevation alone.")
|
||||
private double lengthPreference = 1D;
|
||||
}
|
||||
|
||||
+1
-1
@@ -252,7 +252,7 @@ public class HydrologyPlannerCrossTileCaveAdmissionIntegrationTest {
|
||||
);
|
||||
return new HydrologyPlannerSettings(
|
||||
63,
|
||||
new HydrologyPlannerSettings.Routing(256, 16, 1_089, 256, 16, 8, 0.5D, 12D, 0.5D, 0.2D),
|
||||
new HydrologyPlannerSettings.Routing(256, 16, 1_089, 256, 16, 8, 0.5D, 12D, 0.5D, 0.2D, 1D),
|
||||
new HydrologyPlannerSettings.Surface(
|
||||
true,
|
||||
surfaceSources,
|
||||
|
||||
+1
-1
@@ -668,7 +668,7 @@ public class HydrologyPlannerGlobalInvariantTest {
|
||||
12D,
|
||||
0.5D,
|
||||
0.1D
|
||||
),
|
||||
, 1D),
|
||||
new HydrologyPlannerSettings.Surface(
|
||||
surfaceEnabled,
|
||||
surfaceSources,
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@ public class HydrologyPlannerSettingsTest {
|
||||
0D,
|
||||
0D,
|
||||
0D
|
||||
);
|
||||
, 1D);
|
||||
HydrologyPlannerSettings.Source sources = new HydrologyPlannerSettings.Source(true, 1D, 0, 0, 1, 0);
|
||||
HydrologyPlannerSettings.Surface surface = new HydrologyPlannerSettings.Surface(
|
||||
true,
|
||||
|
||||
@@ -581,7 +581,7 @@ public class HydrologyPlannerTest {
|
||||
routing.valleyPreference(),
|
||||
routing.uphillPenalty(),
|
||||
routing.slopePenalty(),
|
||||
routing.confluenceAttraction()
|
||||
routing.confluenceAttraction(), 1D
|
||||
),
|
||||
base.surface(),
|
||||
base.hydraulics(),
|
||||
@@ -1733,7 +1733,7 @@ public class HydrologyPlannerTest {
|
||||
);
|
||||
return new HydrologyPlannerSettings(
|
||||
63,
|
||||
new HydrologyPlannerSettings.Routing(128, 16, 512, 256, 0, 0, 0.5D, 12D, 0.5D, 0.1D),
|
||||
new HydrologyPlannerSettings.Routing(128, 16, 512, 256, 0, 0, 0.5D, 12D, 0.5D, 0.1D, 1D),
|
||||
new HydrologyPlannerSettings.Surface(
|
||||
surfaceDensity > 0D || surfaceSources.maximumPerTile() > 0,
|
||||
surfaceSources,
|
||||
@@ -1800,7 +1800,7 @@ public class HydrologyPlannerTest {
|
||||
24D,
|
||||
2D,
|
||||
0.2D
|
||||
),
|
||||
, 1D),
|
||||
new HydrologyPlannerSettings.Surface(
|
||||
true,
|
||||
new HydrologyPlannerSettings.Source(true, 8D, 80, 0, 8, 128),
|
||||
|
||||
+3
-2
@@ -96,7 +96,8 @@ public class HydrologyStyledGeometryTest {
|
||||
widestSurfaceWidth = Math.max(widestSurfaceWidth, segment.width());
|
||||
}
|
||||
assertTrue(widestSurfaceWidth >= surfaceStart.width());
|
||||
assertTrue(widestSurfaceWidth <= surfaceSettings.surface().maximumWidth() * 2);
|
||||
assertTrue(widestSurfaceWidth <= (int) Math.ceil(surfaceSettings.surface().maximumWidth()
|
||||
* Math.max(2D, surfaceSettings.surface().banks().springWidthRatio())));
|
||||
|
||||
RiverCourse underground = courses(undergroundFirst, RiverCourseType.UNDERGROUND).getFirst();
|
||||
DrainageNode undergroundSource = undergroundFirst.node(underground.sourceNodeId().orElseThrow()).orElseThrow();
|
||||
@@ -194,7 +195,7 @@ public class HydrologyStyledGeometryTest {
|
||||
);
|
||||
return new HydrologyPlannerSettings(
|
||||
63,
|
||||
new HydrologyPlannerSettings.Routing(128, 16, 512, 256, 16, 8, 0.5D, 12D, 0.5D, 0.1D),
|
||||
new HydrologyPlannerSettings.Routing(128, 16, 512, 256, 16, 8, 0.5D, 12D, 0.5D, 0.1D, 1D),
|
||||
new HydrologyPlannerSettings.Surface(
|
||||
surfaceDensity > 0D,
|
||||
surfaceSources,
|
||||
|
||||
@@ -243,7 +243,7 @@ public class HydrologyTileCacheTest {
|
||||
);
|
||||
return new HydrologyPlannerSettings(
|
||||
63,
|
||||
new HydrologyPlannerSettings.Routing(64, 16, 128, 64, 0, 0, 0D, 0D, 0D, 0D),
|
||||
new HydrologyPlannerSettings.Routing(64, 16, 128, 64, 0, 0, 0D, 0D, 0D, 0D, 1D),
|
||||
new HydrologyPlannerSettings.Surface(false, disabled, 2, 4, 1, 2, 4, 1D,
|
||||
HydrologyPlannerSettings.Banks.defaults()),
|
||||
new HydrologyPlannerSettings.Hydraulics(3),
|
||||
@@ -282,7 +282,7 @@ public class HydrologyTileCacheTest {
|
||||
);
|
||||
return new HydrologyPlannerSettings(
|
||||
63,
|
||||
new HydrologyPlannerSettings.Routing(64, 16, 128, 96, 16, 8, 0.5D, 12D, 0.5D, 0.1D),
|
||||
new HydrologyPlannerSettings.Routing(64, 16, 128, 96, 16, 8, 0.5D, 12D, 0.5D, 0.1D, 1D),
|
||||
new HydrologyPlannerSettings.Surface(true, surfaceSources, 4, 8, 2, 3, 20, 1.5D, tileBoundedBanks()),
|
||||
new HydrologyPlannerSettings.Hydraulics(3),
|
||||
new HydrologyPlannerSettings.Underground(false, disabled, -32, 32, 2, 4, 1, 2, 3, 4, false),
|
||||
|
||||
+1
-1
@@ -1530,7 +1530,7 @@ public class MantleHydrologyComponentTest {
|
||||
);
|
||||
return new HydrologyPlannerSettings(
|
||||
63,
|
||||
new HydrologyPlannerSettings.Routing(128, 16, 512, 256, 16, 8, 0.5D, 12D, 0.5D, 0.1D),
|
||||
new HydrologyPlannerSettings.Routing(128, 16, 512, 256, 16, 8, 0.5D, 12D, 0.5D, 0.1D, 1D),
|
||||
new HydrologyPlannerSettings.Surface(
|
||||
true,
|
||||
surfaceSources,
|
||||
|
||||
@@ -228,7 +228,7 @@ public final class HydrologyPlannerProbe {
|
||||
12D,
|
||||
0.5D,
|
||||
0.1D
|
||||
),
|
||||
, 1D),
|
||||
new HydrologyPlannerSettings.Surface(
|
||||
true,
|
||||
surfaceSources,
|
||||
@@ -439,7 +439,7 @@ public final class HydrologyPlannerProbe {
|
||||
12D,
|
||||
0.5D,
|
||||
0.2D
|
||||
),
|
||||
, 1D),
|
||||
new HydrologyPlannerSettings.Surface(
|
||||
true,
|
||||
surfaceSources,
|
||||
|
||||
Reference in New Issue
Block a user