mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-11-01 08:50:06 +00:00
Cached more water rasters
- Stored raster tiers fluids and feature ids as per-chunk palettes - Derived cave ceilings from terrain heights and water heads - Raised the water raster cache from 1024 to 8192 chunks
This commit is contained in:
1 parent
c700138b66
commit
a879985875
3 files changed
+97
-34
No files matched your search
+1
-1
@@ -56,7 +56,7 @@ import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public final class HydrologyRuntime {
|
||||
private static final int RASTER_CAPACITY = 1024;
|
||||
private static final int RASTER_CAPACITY = 8192;
|
||||
private static final int KEEP_SCOPES = 2;
|
||||
private static final int CHUNKS_PER_WINDOW = WindowKey.SIZE >> 4;
|
||||
public static final int MAX_PREGENERATION_REGIONS = 4096;
|
||||
|
||||
+78
-18
@@ -2,6 +2,8 @@ package art.arcane.iris.generation.hydrology.raster;
|
||||
|
||||
import art.arcane.iris.generation.hydrology.water.HydrologyTier;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public final class ChunkWaterRaster {
|
||||
public static final int MAX_SHORE_DISTANCE = 32;
|
||||
public static final ChunkWaterRaster PROVISIONAL = new ChunkWaterRaster(true);
|
||||
@@ -13,10 +15,13 @@ public final class ChunkWaterRaster {
|
||||
private final int[] terrain;
|
||||
private final int[] head;
|
||||
private final byte[] role;
|
||||
private final HydrologyTier[] tier;
|
||||
private final long[] featureId;
|
||||
private final String[] fluid;
|
||||
private final int[] caveCeiling;
|
||||
private final byte[] tier;
|
||||
private final HydrologyTier[] tiers;
|
||||
private final byte[] feature;
|
||||
private final long[] features;
|
||||
private final byte[] fluid;
|
||||
private final String[] fluids;
|
||||
private final boolean caveMask;
|
||||
private final byte[] shoreDistance;
|
||||
|
||||
private ChunkWaterRaster(boolean provisional) {
|
||||
@@ -25,26 +30,32 @@ public final class ChunkWaterRaster {
|
||||
this.head = null;
|
||||
this.role = null;
|
||||
this.tier = null;
|
||||
this.featureId = null;
|
||||
this.tiers = null;
|
||||
this.feature = null;
|
||||
this.features = null;
|
||||
this.fluid = null;
|
||||
this.caveCeiling = null;
|
||||
this.fluids = null;
|
||||
this.caveMask = false;
|
||||
this.shoreDistance = null;
|
||||
}
|
||||
|
||||
ChunkWaterRaster(int[] terrain, int[] head, byte[] role, HydrologyTier[] tier, long[] featureId, String[] fluid, int[] caveCeiling,
|
||||
byte[] shoreDistance) {
|
||||
if (terrain.length != COLUMNS || head.length != COLUMNS || role.length != COLUMNS || tier.length != COLUMNS
|
||||
|| featureId.length != COLUMNS || fluid.length != COLUMNS || caveCeiling.length != COLUMNS || shoreDistance.length != COLUMNS) {
|
||||
ChunkWaterRaster(int[] terrain, int[] head, byte[] role, Palette<HydrologyTier> tiers, LongPalette features, Palette<String> fluids,
|
||||
boolean caveMask, byte[] shoreDistance) {
|
||||
if (terrain.length != COLUMNS || head.length != COLUMNS || role.length != COLUMNS || tiers.indices.length != COLUMNS
|
||||
|| features.indices.length != COLUMNS || fluids.indices.length != COLUMNS || shoreDistance.length != COLUMNS) {
|
||||
throw new IllegalArgumentException("A chunk water raster needs " + COLUMNS + " entries per array");
|
||||
}
|
||||
this.provisional = false;
|
||||
this.terrain = terrain;
|
||||
this.head = head;
|
||||
this.role = role;
|
||||
this.tier = tier;
|
||||
this.featureId = featureId;
|
||||
this.fluid = fluid;
|
||||
this.caveCeiling = caveCeiling;
|
||||
this.tier = tiers.indices;
|
||||
this.tiers = tiers.values();
|
||||
this.feature = features.indices;
|
||||
this.features = features.values();
|
||||
this.fluid = fluids.indices;
|
||||
this.fluids = fluids.values();
|
||||
this.caveMask = caveMask;
|
||||
this.shoreDistance = shoreDistance;
|
||||
}
|
||||
|
||||
@@ -68,22 +79,22 @@ public final class ChunkWaterRaster {
|
||||
|
||||
public HydrologyTier tier(int lx, int lz) {
|
||||
int index = index(lx, lz);
|
||||
return tier == null ? null : tier[index];
|
||||
return tier == null ? null : tiers[tier[index] & 0xFF];
|
||||
}
|
||||
|
||||
public long featureId(int lx, int lz) {
|
||||
int index = index(lx, lz);
|
||||
return featureId == null ? 0L : featureId[index];
|
||||
return feature == null ? 0L : features[feature[index] & 0xFF];
|
||||
}
|
||||
|
||||
public String fluid(int lx, int lz) {
|
||||
int index = index(lx, lz);
|
||||
return fluid == null ? null : fluid[index];
|
||||
return fluid == null ? null : fluids[fluid[index] & 0xFF];
|
||||
}
|
||||
|
||||
public int caveCeiling(int lx, int lz) {
|
||||
int index = index(lx, lz);
|
||||
return caveCeiling == null ? Integer.MAX_VALUE : caveCeiling[index];
|
||||
return caveMask && head[index] != Integer.MIN_VALUE ? terrain[index] - 1 : Integer.MAX_VALUE;
|
||||
}
|
||||
|
||||
public int shoreDistance(int lx, int lz) {
|
||||
@@ -105,4 +116,53 @@ public final class ChunkWaterRaster {
|
||||
}
|
||||
return lz << 4 | lx;
|
||||
}
|
||||
|
||||
static final class Palette<T> {
|
||||
private final byte[] indices = new byte[COLUMNS];
|
||||
private final T[] seen;
|
||||
private int size;
|
||||
|
||||
Palette(T[] seen) {
|
||||
if (seen.length != COLUMNS) {
|
||||
throw new IllegalArgumentException("A raster palette needs room for " + COLUMNS + " values");
|
||||
}
|
||||
this.seen = seen;
|
||||
}
|
||||
|
||||
void set(int column, T value) {
|
||||
int found = 0;
|
||||
while (found < size && seen[found] != value) {
|
||||
found++;
|
||||
}
|
||||
if (found == size) {
|
||||
seen[size++] = value;
|
||||
}
|
||||
indices[column] = (byte) found;
|
||||
}
|
||||
|
||||
private T[] values() {
|
||||
return Arrays.copyOf(seen, size);
|
||||
}
|
||||
}
|
||||
|
||||
static final class LongPalette {
|
||||
private final byte[] indices = new byte[COLUMNS];
|
||||
private final long[] seen = new long[COLUMNS];
|
||||
private int size;
|
||||
|
||||
void set(int column, long value) {
|
||||
int found = 0;
|
||||
while (found < size && seen[found] != value) {
|
||||
found++;
|
||||
}
|
||||
if (found == size) {
|
||||
seen[size++] = value;
|
||||
}
|
||||
indices[column] = (byte) found;
|
||||
}
|
||||
|
||||
private long[] values() {
|
||||
return Arrays.copyOf(seen, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
-15
@@ -385,34 +385,37 @@ final class RasterComposer {
|
||||
|
||||
private ChunkWaterRaster pack() {
|
||||
int columns = ChunkWaterRaster.COLUMNS;
|
||||
boolean affected = false;
|
||||
for (int lz = 0; lz < CHUNK && !affected; lz++) {
|
||||
for (int lx = 0; lx < CHUNK && !affected; lx++) {
|
||||
int cell = (lz + 1) * GRID + lx + 1;
|
||||
affected = role[cell] != WaterRole.NONE || terrain[cell] != natural[cell] || shore(cell) < ChunkWaterRaster.MAX_SHORE_DISTANCE;
|
||||
}
|
||||
}
|
||||
if (!affected) {
|
||||
return ChunkWaterRaster.EMPTY;
|
||||
}
|
||||
int[] terrainOut = new int[columns];
|
||||
int[] headOut = new int[columns];
|
||||
byte[] roleOut = new byte[columns];
|
||||
HydrologyTier[] tierOut = new HydrologyTier[columns];
|
||||
long[] featureOut = new long[columns];
|
||||
String[] fluidOut = new String[columns];
|
||||
int[] caveOut = new int[columns];
|
||||
ChunkWaterRaster.Palette<HydrologyTier> tierOut = new ChunkWaterRaster.Palette<>(new HydrologyTier[columns]);
|
||||
ChunkWaterRaster.LongPalette featureOut = new ChunkWaterRaster.LongPalette();
|
||||
ChunkWaterRaster.Palette<String> fluidOut = new ChunkWaterRaster.Palette<>(new String[columns]);
|
||||
byte[] shoreOut = new byte[columns];
|
||||
boolean caveMask = settings.deformation().caveMask();
|
||||
boolean affected = false;
|
||||
for (int lz = 0; lz < CHUNK; lz++) {
|
||||
for (int lx = 0; lx < CHUNK; lx++) {
|
||||
int cell = (lz + 1) * GRID + lx + 1;
|
||||
int index = lz << 4 | lx;
|
||||
int shore = shore(cell);
|
||||
terrainOut[index] = terrain[cell];
|
||||
headOut[index] = head[cell];
|
||||
roleOut[index] = (byte) role[cell].ordinal();
|
||||
tierOut[index] = tier[cell];
|
||||
featureOut[index] = feature[cell];
|
||||
fluidOut[index] = fluid[cell];
|
||||
caveOut[index] = caveMask && head[cell] != Integer.MIN_VALUE ? terrain[cell] - 1 : Integer.MAX_VALUE;
|
||||
shoreOut[index] = (byte) shore;
|
||||
affected |= role[cell] != WaterRole.NONE || terrain[cell] != natural[cell] || shore < ChunkWaterRaster.MAX_SHORE_DISTANCE;
|
||||
tierOut.set(index, tier[cell]);
|
||||
featureOut.set(index, feature[cell]);
|
||||
fluidOut.set(index, fluid[cell]);
|
||||
shoreOut[index] = (byte) shore(cell);
|
||||
}
|
||||
}
|
||||
return affected ? new ChunkWaterRaster(terrainOut, headOut, roleOut, tierOut, featureOut, fluidOut, caveOut, shoreOut)
|
||||
: ChunkWaterRaster.EMPTY;
|
||||
return new ChunkWaterRaster(terrainOut, headOut, roleOut, tierOut, featureOut, fluidOut, settings.deformation().caveMask(), shoreOut);
|
||||
}
|
||||
|
||||
private int shore(int cell) {
|
||||
|
||||
Reference in new issue
Block a user