mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-05-19 16:10:42 +00:00
d
This commit is contained in:
Vendored
+1
-1
@@ -1 +1 @@
|
||||
-1511497018
|
||||
1982643195
|
||||
@@ -201,9 +201,9 @@ public class IrisComplex implements DataProvider {
|
||||
IrisBiome b = focusBiome != null ? focusBiome : baseBiomeStream.get(x, z);
|
||||
return getHeight(engine, b, x, z, engine.getSeedManager().getHeight());
|
||||
}, Interpolated.DOUBLE).cache2DDouble("heightStream", engine, cacheSize).waste("Height Stream");
|
||||
roundedHeighteightStream = heightStream.contextInjecting((c, x, z) -> IrisContext.getOr(engine).getChunkContext().getHeight().get(x, z))
|
||||
roundedHeighteightStream = heightStream.contextInjecting((c, x, z) -> IrisContext.getOr(engine).getChunkContext().getHeight().getDouble(x, z))
|
||||
.round().waste("Rounded Height Stream");
|
||||
slopeStream = heightStream.contextInjecting((c, x, z) -> IrisContext.getOr(engine).getChunkContext().getHeight().get(x, z))
|
||||
slopeStream = heightStream.contextInjecting((c, x, z) -> IrisContext.getOr(engine).getChunkContext().getHeight().getDouble(x, z))
|
||||
.slope(3).cache2DDouble("slopeStream", engine, cacheSize).waste("Slope Stream");
|
||||
trueBiomeStream = focusBiome != null ? ProceduralStream.of((x, y) -> focusBiome, Interpolated.of(a -> 0D,
|
||||
b -> focusBiome))
|
||||
@@ -214,7 +214,7 @@ public class IrisComplex implements DataProvider {
|
||||
.cache2D("trueBiomeStream", engine, cacheSize).waste("True Biome Stream");
|
||||
trueBiomeDerivativeStream = trueBiomeStream.contextInjecting((c, x, z) -> IrisContext.getOr(engine).getChunkContext().getBiome().get(x, z))
|
||||
.convert(IrisBiome::getDerivative).cache2D("trueBiomeDerivativeStream", engine, cacheSize).waste("True Biome Derivative Stream");
|
||||
heightFluidStream = heightStream.contextInjecting((c, x, z) -> IrisContext.getOr(engine).getChunkContext().getHeight().get(x, z))
|
||||
heightFluidStream = heightStream.contextInjecting((c, x, z) -> IrisContext.getOr(engine).getChunkContext().getHeight().getDouble(x, z))
|
||||
.max(fluidHeight).cache2DDouble("heightFluidStream", engine, cacheSize).waste("Height Fluid Stream");
|
||||
maxHeightStream = ProceduralStream.ofDouble((x, z) -> height).waste("Max Height Stream");
|
||||
terrainSurfaceDecoration = trueBiomeStream.contextInjecting((c, x, z) -> IrisContext.getOr(engine).getChunkContext().getBiome().get(x, z))
|
||||
|
||||
@@ -79,7 +79,7 @@ public class IrisDecorantActuator extends EngineAssignedActuator<BlockData> {
|
||||
int emptyFor = 0;
|
||||
int lastSolid = 0;
|
||||
realZ = Math.round(z + j);
|
||||
height = (int) Math.round(context.getHeight().get(i, j));
|
||||
height = context.getRoundedHeight(i, j);
|
||||
biome = context.getBiome().get(i, j);
|
||||
cave = shouldRay ? context.getCave().get(i, j) : null;
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import art.arcane.iris.engine.object.IrisRegion;
|
||||
import art.arcane.volmlib.util.collection.KList;
|
||||
import art.arcane.iris.util.project.context.ChunkedDataCache;
|
||||
import art.arcane.iris.util.project.context.ChunkContext;
|
||||
import art.arcane.iris.util.project.context.ChunkedDoubleDataCache;
|
||||
import art.arcane.volmlib.util.documentation.BlockCoordinates;
|
||||
import art.arcane.iris.util.project.hunk.Hunk;
|
||||
import art.arcane.volmlib.util.math.RNG;
|
||||
@@ -89,7 +90,7 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator<BlockData>
|
||||
realZ = zf + z;
|
||||
biome = context.getBiome().get(xf, zf);
|
||||
region = context.getRegion().get(xf, zf);
|
||||
he = (int) Math.round(Math.min(h.getHeight(), context.getHeight().get(xf, zf)));
|
||||
he = Math.min(h.getHeight(), context.getRoundedHeight(xf, zf));
|
||||
hf = Math.round(Math.max(Math.min(h.getHeight(), getDimension().getFluidHeight()), he));
|
||||
|
||||
if (hf < 0) {
|
||||
@@ -174,7 +175,7 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator<BlockData>
|
||||
boolean bedrockEnabled = getDimension().isBedrock();
|
||||
ChunkedDataCache<IrisBiome> biomeCache = context.getBiome();
|
||||
ChunkedDataCache<IrisRegion> regionCache = context.getRegion();
|
||||
ChunkedDataCache<Double> heightCache = context.getHeight();
|
||||
ChunkedDoubleDataCache heightCache = context.getHeight();
|
||||
ChunkedDataCache<BlockData> fluidCache = context.getFluid();
|
||||
ChunkedDataCache<BlockData> rockCache = context.getRock();
|
||||
int realX = xf + x;
|
||||
@@ -183,7 +184,7 @@ public class IrisTerrainNormalActuator extends EngineAssignedActuator<BlockData>
|
||||
int realZ = zf + z;
|
||||
IrisBiome biome = biomeCache.get(xf, zf);
|
||||
IrisRegion region = regionCache.get(xf, zf);
|
||||
int he = (int) Math.round(Math.min(chunkHeight, heightCache.get(xf, zf)));
|
||||
int he = Math.min(chunkHeight, context.getRoundedHeight(xf, zf));
|
||||
int hf = Math.round(Math.max(Math.min(chunkHeight, fluidHeight), he));
|
||||
if (hf < 0) {
|
||||
continue;
|
||||
|
||||
@@ -59,6 +59,7 @@ public interface MatterGenerator {
|
||||
boolean optimizedRegen = forceRegen && !IrisSettings.get().getGeneral().isDebug() && regenPassKey != null;
|
||||
int writeRadius = optimizedRegen ? Math.min(getRadius(), getRealRadius()) : getRadius();
|
||||
Set<Long> clearedChunks = optimizedRegen ? getRegenPassSet(REGEN_CLEARED_CHUNKS_BY_PASS, regenPassKey) : new HashSet<>();
|
||||
Set<Long> partialChunks = forceRegen ? null : new HashSet<>();
|
||||
Set<Long> plannedChunks = optimizedRegen ? getRegenPassSet(REGEN_PLANNED_CHUNKS_BY_PASS, regenPassKey) : null;
|
||||
|
||||
if (optimizedRegen) {
|
||||
@@ -131,10 +132,22 @@ public interface MatterGenerator {
|
||||
}
|
||||
|
||||
for (MantleComponent component : pair.getA()) {
|
||||
if (!forceRegen && chunk.isFlagged(component.getFlag())) {
|
||||
if (!component.isEnabled()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean componentAlreadyGenerated = !forceRegen && chunk.isFlagged(component.getFlag());
|
||||
if (componentAlreadyGenerated) {
|
||||
componentSkipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
int componentPassRadius = Math.ceilDiv(component.getRadius(), 16);
|
||||
if (Math.abs(i) > componentPassRadius || Math.abs(j) > componentPassRadius) {
|
||||
partialChunks.add(passKey);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (forceRegen && chunk.isFlagged(component.getFlag())) {
|
||||
chunk.flag(component.getFlag(), false);
|
||||
componentForcedReset++;
|
||||
@@ -186,6 +199,9 @@ public interface MatterGenerator {
|
||||
if (plannedChunks != null && !plannedChunks.add(realKey)) {
|
||||
continue;
|
||||
}
|
||||
if (partialChunks != null && partialChunks.contains(realKey)) {
|
||||
continue;
|
||||
}
|
||||
writer.acquireChunk(realX, realZ).flag(MantleFlag.PLANNED, true);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-5
@@ -436,11 +436,8 @@ public class MantleCarvingComponent extends IrisMantleComponent {
|
||||
int worldZ = baseZ + localZ;
|
||||
int columnIndex = PowerOfTwoCoordinates.packLocal16(localX, localZ);
|
||||
if (useContextHeight) {
|
||||
Double cachedHeight = context.getHeight().get(localX, localZ);
|
||||
if (cachedHeight != null) {
|
||||
surfaceHeights[columnIndex] = (int) Math.round(cachedHeight);
|
||||
continue;
|
||||
}
|
||||
surfaceHeights[columnIndex] = context.getRoundedHeight(localX, localZ);
|
||||
continue;
|
||||
}
|
||||
if (cachedChunkHeights != null) {
|
||||
surfaceHeights[columnIndex] = (int) Math.round(cachedChunkHeights[columnIndex]);
|
||||
|
||||
@@ -75,7 +75,13 @@ public class IrisCarveModifier extends EngineAssignedModifier<BlockData> {
|
||||
scratch.reset();
|
||||
PackedWallBuffer walls = scratch.walls;
|
||||
ColumnMask[] columnMasks = scratch.columnMasks;
|
||||
int[] surfaceHeights = scratch.surfaceHeights;
|
||||
Map<String, IrisBiome> customBiomeCache = scratch.customBiomeCache;
|
||||
for (int columnIndex = 0; columnIndex < 256; columnIndex++) {
|
||||
int localX = PowerOfTwoCoordinates.unpackLocal16X(columnIndex);
|
||||
int localZ = columnIndex & 15;
|
||||
surfaceHeights[columnIndex] = context.getRoundedHeight(localX, localZ);
|
||||
}
|
||||
|
||||
try {
|
||||
PrecisionStopwatch resolveStopwatch = PrecisionStopwatch.start();
|
||||
@@ -146,8 +152,9 @@ public class IrisCarveModifier extends EngineAssignedModifier<BlockData> {
|
||||
if (biome != null) {
|
||||
biome.setInferredType(InferredType.CAVE);
|
||||
BlockData data = biome.getWall().get(rng, worldX, yy, worldZ, getData());
|
||||
int columnIndex = PowerOfTwoCoordinates.packLocal16(rx, rz);
|
||||
|
||||
if (data != null && B.isSolid(output.get(rx, yy, rz)) && yy <= context.getHeight().get(rx, rz)) {
|
||||
if (data != null && B.isSolid(output.get(rx, yy, rz)) && yy <= surfaceHeights[columnIndex]) {
|
||||
output.set(rx, yy, rz, data);
|
||||
}
|
||||
}
|
||||
@@ -471,6 +478,7 @@ public class IrisCarveModifier extends EngineAssignedModifier<BlockData> {
|
||||
|
||||
private static final class CarveScratch {
|
||||
private final ColumnMask[] columnMasks = new ColumnMask[256];
|
||||
private final int[] surfaceHeights = new int[256];
|
||||
private final PackedWallBuffer walls = new PackedWallBuffer(512);
|
||||
private final Map<String, IrisBiome> customBiomeCache = new HashMap<>();
|
||||
|
||||
|
||||
@@ -100,9 +100,7 @@ public class IrisDepositModifier extends EngineAssignedModifier<BlockData> {
|
||||
|
||||
int x = rng.i(min, max + 1);
|
||||
int z = rng.i(min, max + 1);
|
||||
int height = (he != null ? he.getHeight((cx << 4) + x, (cz << 4) + z) : (int) (Math.round(
|
||||
context.getHeight().get(x, z)
|
||||
))) - 7;
|
||||
int height = (he != null ? he.getHeight((cx << 4) + x, (cz << 4) + z) : context.getRoundedHeight(x, z)) - 7;
|
||||
|
||||
if (height <= 0)
|
||||
continue;
|
||||
|
||||
@@ -74,6 +74,8 @@ public class IrisBiome extends IrisRegistrant implements IRare {
|
||||
private final transient AtomicCache<KList<IrisBiome>> realChildren = new AtomicCache<>();
|
||||
private final transient AtomicCache<KList<CNG>> layerHeightGenerators = new AtomicCache<>();
|
||||
private final transient AtomicCache<KList<CNG>> layerSeaHeightGenerators = new AtomicCache<>();
|
||||
private final transient AtomicCache<KList<IrisOreGenerator>> surfaceOreCache = new AtomicCache<>();
|
||||
private final transient AtomicCache<KList<IrisOreGenerator>> undergroundOreCache = new AtomicCache<>();
|
||||
@MinNumber(2)
|
||||
@Required
|
||||
@Desc("This is the human readable name for this biome. This can and should be different than the file name. This is not used for loading biomes in other objects.")
|
||||
@@ -176,17 +178,14 @@ public class IrisBiome extends IrisRegistrant implements IRare {
|
||||
private KList<IrisOreGenerator> ores = new KList<>();
|
||||
|
||||
public BlockData generateOres(int x, int y, int z, RNG rng, IrisData data, boolean surface) {
|
||||
if (ores.isEmpty()) {
|
||||
KList<IrisOreGenerator> localOres = getOres(surface);
|
||||
if (localOres.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
KList<IrisOreGenerator> localOres = ores;
|
||||
|
||||
int oreCount = localOres.size();
|
||||
for (int oreIndex = 0; oreIndex < oreCount; oreIndex++) {
|
||||
IrisOreGenerator oreGenerator = localOres.get(oreIndex);
|
||||
if (oreGenerator.isGenerateSurface() != surface) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BlockData ore = oreGenerator.generate(x, y, z, rng, data);
|
||||
if (ore != null) {
|
||||
return ore;
|
||||
@@ -195,6 +194,29 @@ public class IrisBiome extends IrisRegistrant implements IRare {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setOres(KList<IrisOreGenerator> ores) {
|
||||
this.ores = ores == null ? new KList<>() : ores;
|
||||
surfaceOreCache.reset();
|
||||
undergroundOreCache.reset();
|
||||
}
|
||||
|
||||
private KList<IrisOreGenerator> getOres(boolean surface) {
|
||||
AtomicCache<KList<IrisOreGenerator>> oreCache = surface ? surfaceOreCache : undergroundOreCache;
|
||||
return oreCache.aquire(() -> {
|
||||
KList<IrisOreGenerator> filtered = new KList<>();
|
||||
KList<IrisOreGenerator> localOres = ores;
|
||||
int oreCount = localOres.size();
|
||||
for (int oreIndex = 0; oreIndex < oreCount; oreIndex++) {
|
||||
IrisOreGenerator oreGenerator = localOres.get(oreIndex);
|
||||
if (oreGenerator.isGenerateSurface() == surface) {
|
||||
filtered.add(oreGenerator);
|
||||
}
|
||||
}
|
||||
|
||||
return filtered;
|
||||
});
|
||||
}
|
||||
|
||||
public Biome getVanillaDerivative() {
|
||||
return vanillaDerivative == null ? derivative : vanillaDerivative;
|
||||
}
|
||||
|
||||
@@ -79,6 +79,8 @@ public class IrisDimension extends IrisRegistrant {
|
||||
private final transient AtomicCache<Double> rad = new AtomicCache<>();
|
||||
private final transient AtomicCache<Boolean> featuresUsed = new AtomicCache<>();
|
||||
private final transient AtomicCache<Map<String, IrisDimensionCarvingEntry>> carvingEntryIndex = new AtomicCache<>();
|
||||
private final transient AtomicCache<KList<IrisOreGenerator>> surfaceOreCache = new AtomicCache<>();
|
||||
private final transient AtomicCache<KList<IrisOreGenerator>> undergroundOreCache = new AtomicCache<>();
|
||||
@MinNumber(2)
|
||||
@Required
|
||||
@Desc("The human readable name of this dimension")
|
||||
@@ -291,17 +293,14 @@ public class IrisDimension extends IrisRegistrant {
|
||||
}
|
||||
|
||||
public BlockData generateOres(int x, int y, int z, RNG rng, IrisData data, boolean surface) {
|
||||
if (ores.isEmpty()) {
|
||||
KList<IrisOreGenerator> localOres = getOres(surface);
|
||||
if (localOres.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
KList<IrisOreGenerator> localOres = ores;
|
||||
|
||||
int oreCount = localOres.size();
|
||||
for (int oreIndex = 0; oreIndex < oreCount; oreIndex++) {
|
||||
IrisOreGenerator oreGenerator = localOres.get(oreIndex);
|
||||
if (oreGenerator.isGenerateSurface() != surface) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BlockData ore = oreGenerator.generate(x, y, z, rng, data);
|
||||
if (ore != null) {
|
||||
return ore;
|
||||
@@ -310,6 +309,29 @@ public class IrisDimension extends IrisRegistrant {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setOres(KList<IrisOreGenerator> ores) {
|
||||
this.ores = ores == null ? new KList<>() : ores;
|
||||
surfaceOreCache.reset();
|
||||
undergroundOreCache.reset();
|
||||
}
|
||||
|
||||
private KList<IrisOreGenerator> getOres(boolean surface) {
|
||||
AtomicCache<KList<IrisOreGenerator>> oreCache = surface ? surfaceOreCache : undergroundOreCache;
|
||||
return oreCache.aquire(() -> {
|
||||
KList<IrisOreGenerator> filtered = new KList<>();
|
||||
KList<IrisOreGenerator> localOres = ores;
|
||||
int oreCount = localOres.size();
|
||||
for (int oreIndex = 0; oreIndex < oreCount; oreIndex++) {
|
||||
IrisOreGenerator oreGenerator = localOres.get(oreIndex);
|
||||
if (oreGenerator.isGenerateSurface() == surface) {
|
||||
filtered.add(oreGenerator);
|
||||
}
|
||||
}
|
||||
|
||||
return filtered;
|
||||
});
|
||||
}
|
||||
|
||||
public int getFluidHeight() {
|
||||
return fluidHeight - (int) dimensionHeight.getMin();
|
||||
}
|
||||
|
||||
@@ -67,6 +67,8 @@ public class IrisRegion extends IrisRegistrant implements IRare {
|
||||
private final transient AtomicCache<CNG> riverGen = new AtomicCache<>();
|
||||
private final transient AtomicCache<CNG> riverChanceGen = new AtomicCache<>();
|
||||
private final transient AtomicCache<Color> cacheColor = new AtomicCache<>();
|
||||
private final transient AtomicCache<KList<IrisOreGenerator>> surfaceOreCache = new AtomicCache<>();
|
||||
private final transient AtomicCache<KList<IrisOreGenerator>> undergroundOreCache = new AtomicCache<>();
|
||||
@MinNumber(2)
|
||||
@Required
|
||||
@Desc("The name of the region")
|
||||
@@ -152,17 +154,14 @@ public class IrisRegion extends IrisRegistrant implements IRare {
|
||||
private KList<IrisOreGenerator> ores = new KList<>();
|
||||
|
||||
public BlockData generateOres(int x, int y, int z, RNG rng, IrisData data, boolean surface) {
|
||||
if (ores.isEmpty()) {
|
||||
KList<IrisOreGenerator> localOres = getOres(surface);
|
||||
if (localOres.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
KList<IrisOreGenerator> localOres = ores;
|
||||
|
||||
int oreCount = localOres.size();
|
||||
for (int oreIndex = 0; oreIndex < oreCount; oreIndex++) {
|
||||
IrisOreGenerator oreGenerator = localOres.get(oreIndex);
|
||||
if (oreGenerator.isGenerateSurface() != surface) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BlockData ore = oreGenerator.generate(x, y, z, rng, data);
|
||||
if (ore != null) {
|
||||
return ore;
|
||||
@@ -171,6 +170,29 @@ public class IrisRegion extends IrisRegistrant implements IRare {
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setOres(KList<IrisOreGenerator> ores) {
|
||||
this.ores = ores == null ? new KList<>() : ores;
|
||||
surfaceOreCache.reset();
|
||||
undergroundOreCache.reset();
|
||||
}
|
||||
|
||||
private KList<IrisOreGenerator> getOres(boolean surface) {
|
||||
AtomicCache<KList<IrisOreGenerator>> oreCache = surface ? surfaceOreCache : undergroundOreCache;
|
||||
return oreCache.aquire(() -> {
|
||||
KList<IrisOreGenerator> filtered = new KList<>();
|
||||
KList<IrisOreGenerator> localOres = ores;
|
||||
int oreCount = localOres.size();
|
||||
for (int oreIndex = 0; oreIndex < oreCount; oreIndex++) {
|
||||
IrisOreGenerator oreGenerator = localOres.get(oreIndex);
|
||||
if (oreGenerator.isGenerateSurface() == surface) {
|
||||
filtered.add(oreGenerator);
|
||||
}
|
||||
}
|
||||
|
||||
return filtered;
|
||||
});
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@ public class ChunkContext {
|
||||
private final int z;
|
||||
private final IrisComplex complex;
|
||||
private final long generationSessionId;
|
||||
private final ChunkedDataCache<Double> height;
|
||||
private final ChunkedDoubleDataCache height;
|
||||
private final int[] roundedHeight;
|
||||
private final ChunkedDataCache<IrisBiome> biome;
|
||||
private final ChunkedDataCache<IrisBiome> cave;
|
||||
private final ChunkedDataCache<BlockData> rock;
|
||||
@@ -45,7 +46,8 @@ public class ChunkContext {
|
||||
this.z = z;
|
||||
this.complex = complex;
|
||||
this.generationSessionId = generationSessionId;
|
||||
this.height = new ChunkedDataCache<>(complex.getHeightStream(), x, z, cache);
|
||||
this.height = new ChunkedDoubleDataCache(complex.getHeightStream(), x, z, cache);
|
||||
this.roundedHeight = new int[cache ? 256 : 0];
|
||||
this.biome = new ChunkedDataCache<>(complex.getTrueBiomeStream(), x, z, cache);
|
||||
this.cave = new ChunkedDataCache<>(complex.getCaveBiomeStream(), x, z, cache);
|
||||
this.rock = new ChunkedDataCache<>(complex.getRockStream(), x, z, cache);
|
||||
@@ -56,9 +58,9 @@ public class ChunkContext {
|
||||
PrefillPlan resolvedPlan = prefillPlan == null ? PrefillPlan.NO_CAVE : prefillPlan;
|
||||
boolean capturePrefillMetric = metrics != null;
|
||||
long totalStartNanos = capturePrefillMetric ? System.nanoTime() : 0L;
|
||||
List<PrefillFillTask> fillTasks = new ArrayList<>(6);
|
||||
List<Runnable> fillTasks = new ArrayList<>(6);
|
||||
if (resolvedPlan.height) {
|
||||
fillTasks.add(new PrefillFillTask(height));
|
||||
fillTasks.add(height::fill);
|
||||
}
|
||||
if (resolvedPlan.biome) {
|
||||
fillTasks.add(new PrefillFillTask(biome));
|
||||
@@ -77,12 +79,12 @@ public class ChunkContext {
|
||||
}
|
||||
|
||||
if (!shouldPrefillAsync(fillTasks.size())) {
|
||||
for (PrefillFillTask fillTask : fillTasks) {
|
||||
for (Runnable fillTask : fillTasks) {
|
||||
fillTask.run();
|
||||
}
|
||||
} else {
|
||||
List<CompletableFuture<Void>> futures = new ArrayList<>(fillTasks.size());
|
||||
for (PrefillFillTask fillTask : fillTasks) {
|
||||
for (Runnable fillTask : fillTasks) {
|
||||
futures.add(CompletableFuture.runAsync(fillTask, MultiBurst.burst));
|
||||
}
|
||||
for (CompletableFuture<Void> future : futures) {
|
||||
@@ -93,6 +95,10 @@ public class ChunkContext {
|
||||
if (capturePrefillMetric) {
|
||||
metrics.getContextPrefill().put((System.nanoTime() - totalStartNanos) / 1_000_000D);
|
||||
}
|
||||
|
||||
if (resolvedPlan.height) {
|
||||
fillRoundedHeight();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,10 +123,18 @@ public class ChunkContext {
|
||||
return complex;
|
||||
}
|
||||
|
||||
public ChunkedDataCache<Double> getHeight() {
|
||||
public ChunkedDoubleDataCache getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public int getRoundedHeight(int x, int z) {
|
||||
if (roundedHeight.length == 0) {
|
||||
return (int) Math.round(height.getDouble(x, z));
|
||||
}
|
||||
|
||||
return roundedHeight[(z << 4) + x];
|
||||
}
|
||||
|
||||
public ChunkedDataCache<IrisBiome> getBiome() {
|
||||
return biome;
|
||||
}
|
||||
@@ -175,4 +189,13 @@ public class ChunkContext {
|
||||
dataCache.fill();
|
||||
}
|
||||
}
|
||||
|
||||
private void fillRoundedHeight() {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int rowOffset = z << 4;
|
||||
for (int x = 0; x < 16; x++) {
|
||||
roundedHeight[rowOffset + x] = (int) Math.round(height.getDouble(x, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
package art.arcane.iris.util.project.context;
|
||||
|
||||
import art.arcane.iris.util.project.stream.ProceduralStream;
|
||||
import art.arcane.iris.util.project.stream.utility.ChunkFillableDoubleStream2D;
|
||||
import art.arcane.volmlib.util.documentation.BlockCoordinates;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
public class ChunkedDoubleDataCache {
|
||||
private final int x;
|
||||
private final int z;
|
||||
private final ProceduralStream<Double> stream;
|
||||
private final boolean cache;
|
||||
private final double[] data;
|
||||
|
||||
@BlockCoordinates
|
||||
public ChunkedDoubleDataCache(ProceduralStream<Double> stream, int x, int z) {
|
||||
this(stream, x, z, true);
|
||||
}
|
||||
|
||||
@BlockCoordinates
|
||||
public ChunkedDoubleDataCache(ProceduralStream<Double> stream, int x, int z, boolean cache) {
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
this.stream = stream;
|
||||
this.cache = cache;
|
||||
this.data = new double[cache ? 256 : 0];
|
||||
if (cache) {
|
||||
Arrays.fill(this.data, Double.NaN);
|
||||
}
|
||||
}
|
||||
|
||||
public void fill() {
|
||||
fill(null);
|
||||
}
|
||||
|
||||
public void fill(Executor executor) {
|
||||
if (!cache) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (stream instanceof ChunkFillableDoubleStream2D cachedStream) {
|
||||
cachedStream.fillChunkDoubles(x, z, data);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int row = 0; row < 16; row++) {
|
||||
int rowOffset = row << 4;
|
||||
int worldZ = z + row;
|
||||
for (int column = 0; column < 16; column++) {
|
||||
data[rowOffset + column] = stream.getDouble(x + column, worldZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@BlockCoordinates
|
||||
public double getDouble(int x, int z) {
|
||||
if (!cache) {
|
||||
return stream.getDouble(this.x + x, this.z + z);
|
||||
}
|
||||
|
||||
int index = (z << 4) + x;
|
||||
double value = data[index];
|
||||
if (!Double.isNaN(value)) {
|
||||
return value;
|
||||
}
|
||||
|
||||
double sampled = stream.getDouble(this.x + x, this.z + z);
|
||||
data[index] = sampled;
|
||||
return sampled;
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -49,7 +49,7 @@ public class ChunkContextPrefillPlanTest {
|
||||
assertEquals(256, regionCalls.get());
|
||||
assertEquals(0, caveCalls.get());
|
||||
|
||||
assertEquals(34051D, context.getHeight().get(2, 3), 0D);
|
||||
assertEquals(34051D, context.getHeight().getDouble(2, 3), 0D);
|
||||
context.getCave().get(2, 3);
|
||||
context.getCave().get(2, 3);
|
||||
assertEquals(1, caveCalls.get());
|
||||
@@ -112,7 +112,7 @@ public class ChunkContextPrefillPlanTest {
|
||||
double worldX = invocation.getArgument(0);
|
||||
double worldZ = invocation.getArgument(1);
|
||||
return (worldX * 1000D) + worldZ;
|
||||
}).when(heightStream).get(anyDouble(), anyDouble());
|
||||
}).when(heightStream).getDouble(anyDouble(), anyDouble());
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
ProceduralStream<IrisBiome> biomeStream = mock(ProceduralStream.class);
|
||||
|
||||
Reference in New Issue
Block a user