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