mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-11-01 08:50:06 +00:00
Hydrology climate zones
- Hydrology climate splits the land into wet and dry zones with a noise style - Dry zones keep only the dryRainfall share of rainfall and pond density - Zone edges ease across the transition band - Policy climateZones exempts an area from the dry zones - Policy fluid also fills streams and rivers that flow through the area - Bank steepness reads the steepest natural ground between the bank and the water - Bank edges roughen with smooth noise - Natural ground heights reach the rasterizer at full precision - Settings reject climate values outside 0..1 - Hydrology probes read the full precision natural heights
This commit is contained in:
1 parent
304e66b74b
commit
c2eca3e6bd
26 files changed
+427
-73
No files matched your search
@@ -86,7 +86,7 @@ final class HydrologyBlockMetrics {
|
||||
|
||||
@Override
|
||||
public int natural(int x, int z) {
|
||||
return inputs.naturalHeight().applyAsInt(x, z);
|
||||
return (int) Math.round(inputs.naturalHeight().height(x, z));
|
||||
}
|
||||
};
|
||||
int minX = key.wx() * WindowKey.SIZE;
|
||||
|
||||
@@ -11,10 +11,12 @@ import art.arcane.iris.generation.hydrology.plan.RegionPlan;
|
||||
import art.arcane.iris.generation.hydrology.plan.WindowKey;
|
||||
import art.arcane.iris.generation.hydrology.plan.WindowPlan;
|
||||
import art.arcane.iris.generation.hydrology.plan.WindowPlanner;
|
||||
import art.arcane.iris.generation.hydrology.raster.ChannelFluids;
|
||||
import art.arcane.iris.generation.hydrology.raster.ChunkRasterizer;
|
||||
import art.arcane.iris.generation.hydrology.raster.ChunkWaterRaster;
|
||||
import art.arcane.iris.generation.hydrology.raster.ReachIndex;
|
||||
import art.arcane.iris.generation.hydrology.water.Pond;
|
||||
import art.arcane.iris.generation.hydrology.raster.NaturalHeights;
|
||||
import com.sun.management.OperatingSystemMXBean;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
@@ -32,7 +34,6 @@ import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.IntBinaryOperator;
|
||||
|
||||
final class HydrologyPlanHarness {
|
||||
private static final double TILE_AREA = 1024D * 1024D;
|
||||
@@ -43,7 +44,7 @@ final class HydrologyPlanHarness {
|
||||
|
||||
static final class Plans {
|
||||
private final HydrologySettings settings;
|
||||
private final IntBinaryOperator naturalHeight;
|
||||
private final NaturalHeights naturalHeight;
|
||||
private final HydrologyWindows.WindowRange planned;
|
||||
private final CountingTerrain counting;
|
||||
private final HydrologyPlanners planners;
|
||||
@@ -54,13 +55,13 @@ final class HydrologyPlanHarness {
|
||||
private final Map<WindowKey, Double> windowCpu = new HashMap<>();
|
||||
private final List<String> failures = new ArrayList<>();
|
||||
|
||||
Plans(HydrologySettings settings, HydrologyTerrainSource terrain, IntBinaryOperator naturalHeight, HydrologyWindows.WindowRange range) {
|
||||
Plans(HydrologySettings settings, HydrologyTerrainSource terrain, NaturalHeights naturalHeight, HydrologyWindows.WindowRange range) {
|
||||
this.settings = settings;
|
||||
this.naturalHeight = naturalHeight;
|
||||
this.planned = range.grown(1);
|
||||
this.counting = new CountingTerrain(terrain);
|
||||
this.planners = HydrologyPlanners.create(settings, counting);
|
||||
this.rasterizer = new ChunkRasterizer(settings);
|
||||
this.rasterizer = new ChunkRasterizer(settings, ChannelFluids.TIER);
|
||||
Set<RegionKey> regionKeys = new TreeSet<>(REGION_ORDER);
|
||||
for (WindowKey key : planned.keys()) {
|
||||
regionKeys.addAll(WindowPlanner.lakeRegions(key));
|
||||
|
||||
@@ -11,6 +11,7 @@ import art.arcane.iris.generation.hydrology.plan.WindowPlan;
|
||||
import art.arcane.iris.generation.hydrology.raster.ChunkWaterRaster;
|
||||
import art.arcane.iris.generation.runtime.Engine;
|
||||
import art.arcane.iris.generation.terrain.IrisDimension;
|
||||
import art.arcane.iris.generation.hydrology.raster.NaturalHeights;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -27,7 +28,6 @@ import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.ForkJoinTask;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.function.IntBinaryOperator;
|
||||
|
||||
public final class HydrologyProbe {
|
||||
private static final int RASTER_CACHE = 8192;
|
||||
@@ -56,7 +56,7 @@ public final class HydrologyProbe {
|
||||
}
|
||||
}
|
||||
|
||||
record Inputs(HydrologySettings settings, HydrologyTerrainSource terrain, IntBinaryOperator naturalHeight, ForkJoinPool planningPool,
|
||||
record Inputs(HydrologySettings settings, HydrologyTerrainSource terrain, NaturalHeights naturalHeight, ForkJoinPool planningPool,
|
||||
ExecutorService workers, HydrologyVoxels.ChunkSource blocks, HydrologyUnderground.Source underground, int worldHeight) {
|
||||
Inputs {
|
||||
Objects.requireNonNull(settings, "settings");
|
||||
@@ -98,7 +98,7 @@ public final class HydrologyProbe {
|
||||
ForkJoinPool planningPool = MultiBurst.hydrology.submit((Callable<ForkJoinPool>) ForkJoinTask::getPool).get();
|
||||
ExecutorService workers = Executors.newFixedThreadPool(configuration.threads());
|
||||
try {
|
||||
Inputs inputs = new Inputs(settings, terrain, terrain::naturalHeight, planningPool, workers,
|
||||
Inputs inputs = new Inputs(settings, terrain, terrain::naturalSurface, planningPool, workers,
|
||||
(chunkX, chunkZ) -> HydrologyVoxels.generate(engine, chunkX, chunkZ), HydrologyUnderground.generated(engine, workers),
|
||||
engine.getTarget().getHeight());
|
||||
HydrologyReport.Result measured = measure(inputs, target.windows());
|
||||
|
||||
@@ -8,15 +8,15 @@ import art.arcane.iris.generation.hydrology.raster.WaterRole;
|
||||
import art.arcane.iris.generation.hydrology.water.Pond;
|
||||
import art.arcane.iris.generation.hydrology.water.Reach;
|
||||
import art.arcane.iris.generation.hydrology.water.ReachStyle;
|
||||
import art.arcane.iris.generation.hydrology.raster.NaturalHeights;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.IntBinaryOperator;
|
||||
|
||||
final class HydrologyRasterMetrics {
|
||||
private final HydrologySettings settings;
|
||||
private final HydrologyPlanMetrics plans;
|
||||
private final Rasters rasters;
|
||||
private final IntBinaryOperator naturalHeight;
|
||||
private final NaturalHeights naturalHeight;
|
||||
private final HydrologyWindows.WindowRange range;
|
||||
private final Consumer<String> examples;
|
||||
|
||||
@@ -25,7 +25,7 @@ final class HydrologyRasterMetrics {
|
||||
ChunkWaterRaster get(int chunkX, int chunkZ);
|
||||
}
|
||||
|
||||
HydrologyRasterMetrics(HydrologySettings settings, HydrologyPlanMetrics plans, Rasters rasters, IntBinaryOperator naturalHeight,
|
||||
HydrologyRasterMetrics(HydrologySettings settings, HydrologyPlanMetrics plans, Rasters rasters, NaturalHeights naturalHeight,
|
||||
HydrologyWindows.WindowRange range, Consumer<String> examples) {
|
||||
this.settings = settings;
|
||||
this.plans = plans;
|
||||
@@ -115,7 +115,7 @@ final class HydrologyRasterMetrics {
|
||||
continue;
|
||||
}
|
||||
int terrain = raster.terrainHeight(x & 15, z & 15);
|
||||
int natural = naturalHeight.applyAsInt(x, z);
|
||||
int natural = (int) Math.round(naturalHeight.height(x, z));
|
||||
if (terrain > natural + maxFill) {
|
||||
overCap++;
|
||||
examples.accept("berm raised " + x + "," + z + " from " + natural + " to " + terrain);
|
||||
@@ -131,7 +131,7 @@ final class HydrologyRasterMetrics {
|
||||
|
||||
int terrain(int x, int z) {
|
||||
ChunkWaterRaster raster = rasters.get(x >> 4, z >> 4);
|
||||
return raster.empty() ? naturalHeight.applyAsInt(x, z) : raster.terrainHeight(x & 15, z & 15);
|
||||
return raster.empty() ? (int) Math.round(naturalHeight.height(x, z)) : raster.terrainHeight(x & 15, z & 15);
|
||||
}
|
||||
|
||||
private boolean seamMismatch(int x, int z, int nx, int nz) {
|
||||
|
||||
@@ -16,6 +16,7 @@ import art.arcane.iris.generation.hydrology.water.Reach;
|
||||
import art.arcane.iris.generation.hydrology.water.ReachStyle;
|
||||
import art.arcane.iris.generation.runtime.Engine;
|
||||
import art.arcane.iris.generation.terrain.IrisDimension;
|
||||
import art.arcane.iris.generation.hydrology.raster.NaturalHeights;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.BasicStroke;
|
||||
@@ -33,7 +34,6 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.function.IntBinaryOperator;
|
||||
|
||||
public final class RiverTransectProbe {
|
||||
static final int NO_WATER = Integer.MIN_VALUE;
|
||||
@@ -116,16 +116,16 @@ public final class RiverTransectProbe {
|
||||
engine.getHeight());
|
||||
IrisHydrologyTerrainSource terrain = new IrisHydrologyTerrainSource(engine.getComplex(), dimension, settings, MultiBurst.hydrology,
|
||||
MultiBurst.hydrology.parallelism(), HydrologyBinding.UNBOUND);
|
||||
HydrologyPlanHarness.Plans plans = new HydrologyPlanHarness.Plans(settings, terrain, terrain::naturalHeight, target.windows());
|
||||
HydrologyPlanHarness.Plans plans = new HydrologyPlanHarness.Plans(settings, terrain, terrain::naturalSurface, target.windows());
|
||||
List<Rendered> rendered = new ArrayList<>();
|
||||
for (WindowKey key : target.windows().keys()) {
|
||||
rendered.add(render(plans, key, terrain::naturalHeight, target.windows(), configuration.output()));
|
||||
rendered.add(render(plans, key, terrain::naturalSurface, target.windows(), configuration.output()));
|
||||
}
|
||||
return rendered;
|
||||
}
|
||||
}
|
||||
|
||||
static Rendered render(HydrologyPlanHarness.Plans plans, WindowKey key, IntBinaryOperator natural, HydrologyWindows.WindowRange range,
|
||||
static Rendered render(HydrologyPlanHarness.Plans plans, WindowKey key, NaturalHeights natural, HydrologyWindows.WindowRange range,
|
||||
File output) throws Exception {
|
||||
Map<Long, ChunkWaterRaster> rasters = new HashMap<>();
|
||||
Columns columns = (x, z) -> {
|
||||
@@ -134,7 +134,7 @@ public final class RiverTransectProbe {
|
||||
}
|
||||
ChunkWaterRaster raster = rasters.computeIfAbsent(HydrologyVoxels.chunkKey(x >> 4, z >> 4),
|
||||
ignored -> plans.rasterize(x >> 4, z >> 4));
|
||||
int ground = natural.applyAsInt(x, z);
|
||||
int ground = (int) Math.round(natural.height(x, z));
|
||||
return new Column(ground, raster.empty() ? ground : raster.terrainHeight(x & 15, z & 15), raster.waterHead(x & 15, z & 15),
|
||||
raster.role(x & 15, z & 15));
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user