Point basis samples carry terrain slope

Routing, validation and the valley solver sampled basis columns with slope 0; the forward slope now rides on every point sample.
This commit is contained in:
Brian Neumann-Fopiano
2026-09-01 19:21:25 -04:00
parent 2585b2105a
commit 5b1b636539
3 changed files with 22 additions and 4 deletions
@@ -106,7 +106,9 @@ final class IrisHydrologyRoutingTerrainSampler implements HydrologyNaturalTerrai
@Override
public HydrologyTerrainSample sampleBasis(int blockX, int blockZ) {
return basis(blockX, blockZ).terrain();
// Point samples carry the forward slope; the aligned grid derives its own from neighbouring bases.
TerrainBasis basis = basis(blockX, blockZ);
return basis.terrain().withSlope(localSlope(blockX, blockZ, basis.naturalHeight()));
}
TerrainBasis basis(int blockX, int blockZ) {
@@ -387,9 +387,7 @@ public final class IrisHydrologyRuntime implements AutoCloseable {
}
private HydrologyTerrainSample createDetailedTerrainSample(int x, int z) {
IrisHydrologyRoutingTerrainSampler.TerrainBasis basis = routingTerrainSampler.basis(x, z);
double slope = routingTerrainSampler.localSlope(x, z, basis.naturalHeight());
return basis.terrain().withSlope(slope);
return routingTerrainSampler.sampleBasis(x, z);
}
private IrisHydrologyRoutingTerrainSampler.TerrainBasis createTerrainBasis(
@@ -93,6 +93,24 @@ public class IrisHydrologyRoutingTerrainSamplerTest {
}
}
@Test
public void pointBasisSamplesCarryTheForwardSlope() {
IrisHydrologyRoutingTerrainSampler sampler = sampler(64);
int[][] points = {{0, 0}, {-129, -257}, {37, 1024}};
for (int[] point : points) {
int x = point[0];
int z = point[1];
double expected = IrisHydrologyRoutingTerrainSampler.localSlope(
height(x, z), height(x + 3, z), height(x, z + 3));
double actual = sampler.sampleBasis(x, z).slope();
assertTrue(expected > 0D);
assertEquals(Double.doubleToRawLongBits(expected), Double.doubleToRawLongBits(actual));
}
}
@Test
public void adjacentGridsShareBasesAndProduceIdenticalOverlap() {
AtomicInteger calls = new AtomicInteger();