mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-05-19 16:10:42 +00:00
OptiPass3
This commit is contained in:
@@ -19,6 +19,7 @@
|
|||||||
package art.arcane.iris.engine.framework;
|
package art.arcane.iris.engine.framework;
|
||||||
|
|
||||||
import art.arcane.iris.core.tools.IrisToolbelt;
|
import art.arcane.iris.core.tools.IrisToolbelt;
|
||||||
|
import art.arcane.iris.core.gui.PregeneratorJob;
|
||||||
import art.arcane.iris.engine.IrisComplex;
|
import art.arcane.iris.engine.IrisComplex;
|
||||||
import art.arcane.iris.engine.mantle.EngineMantle;
|
import art.arcane.iris.engine.mantle.EngineMantle;
|
||||||
import art.arcane.iris.util.project.context.ChunkContext;
|
import art.arcane.iris.util.project.context.ChunkContext;
|
||||||
@@ -75,7 +76,7 @@ public interface EngineMode extends Staged {
|
|||||||
boolean cacheContext = true;
|
boolean cacheContext = true;
|
||||||
if (J.isFolia()) {
|
if (J.isFolia()) {
|
||||||
org.bukkit.World world = getEngine().getWorld().realWorld();
|
org.bukkit.World world = getEngine().getWorld().realWorld();
|
||||||
if (world != null && IrisToolbelt.isWorldMaintenanceActive(world)) {
|
if (world != null && shouldDisableContextCacheForMaintenance(world)) {
|
||||||
cacheContext = false;
|
cacheContext = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,4 +89,19 @@ public interface EngineMode extends Staged {
|
|||||||
i.generate(x, z, blocks, biomes, multicore, ctx);
|
i.generate(x, z, blocks, biomes, multicore, ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean shouldDisableContextCacheForMaintenance(boolean maintenanceActive, boolean pregeneratorTargetsWorld) {
|
||||||
|
return maintenanceActive && !pregeneratorTargetsWorld;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldDisableContextCacheForMaintenance(org.bukkit.World world) {
|
||||||
|
boolean maintenanceActive = IrisToolbelt.isWorldMaintenanceActive(world);
|
||||||
|
if (!maintenanceActive) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PregeneratorJob pregeneratorJob = PregeneratorJob.getInstance();
|
||||||
|
boolean pregeneratorTargetsWorld = pregeneratorJob != null && pregeneratorJob.targetsWorld(world);
|
||||||
|
return shouldDisableContextCacheForMaintenance(maintenanceActive, pregeneratorTargetsWorld);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+251
-10
@@ -1049,11 +1049,13 @@ public class IrisCaveCarver3D {
|
|||||||
double[] adaptivePlaneDensity = scratch.adaptivePlaneDensity;
|
double[] adaptivePlaneDensity = scratch.adaptivePlaneDensity;
|
||||||
int axisCells = (16 + adaptiveSampleStep - 1) / adaptiveSampleStep;
|
int axisCells = (16 + adaptiveSampleStep - 1) / adaptiveSampleStep;
|
||||||
int axisSamples = axisCells + 1;
|
int axisSamples = axisCells + 1;
|
||||||
for (int sampleXIndex = 0; sampleXIndex < axisSamples; sampleXIndex++) {
|
int[] adaptivePlaneSampleBounds = scratch.adaptivePlaneSampleBounds;
|
||||||
|
prepareAdaptivePlaneSampleBounds(planeColumnIndices, planeCount, adaptiveSampleStep, adaptivePlaneSampleBounds, axisCells);
|
||||||
|
for (int sampleXIndex = adaptivePlaneSampleBounds[0]; sampleXIndex <= adaptivePlaneSampleBounds[1]; sampleXIndex++) {
|
||||||
int sampleLocalX = Math.min(sampleXIndex * adaptiveSampleStep, 16);
|
int sampleLocalX = Math.min(sampleXIndex * adaptiveSampleStep, 16);
|
||||||
int x = x0 + sampleLocalX;
|
int x = x0 + sampleLocalX;
|
||||||
int rowOffset = sampleXIndex * axisSamples;
|
int rowOffset = sampleXIndex * axisSamples;
|
||||||
for (int sampleZIndex = 0; sampleZIndex < axisSamples; sampleZIndex++) {
|
for (int sampleZIndex = adaptivePlaneSampleBounds[2]; sampleZIndex <= adaptivePlaneSampleBounds[3]; sampleZIndex++) {
|
||||||
int sampleLocalZ = Math.min(sampleZIndex * adaptiveSampleStep, 16);
|
int sampleLocalZ = Math.min(sampleZIndex * adaptiveSampleStep, 16);
|
||||||
adaptivePlaneDensity[rowOffset + sampleZIndex] = sampleDensityNoWarpNoModules(x, y, z0 + sampleLocalZ);
|
adaptivePlaneDensity[rowOffset + sampleZIndex] = sampleDensityNoWarpNoModules(x, y, z0 + sampleLocalZ);
|
||||||
}
|
}
|
||||||
@@ -1099,11 +1101,13 @@ public class IrisCaveCarver3D {
|
|||||||
double[] adaptivePlaneDensity = scratch.adaptivePlaneDensity;
|
double[] adaptivePlaneDensity = scratch.adaptivePlaneDensity;
|
||||||
int axisCells = (16 + adaptiveSampleStep - 1) / adaptiveSampleStep;
|
int axisCells = (16 + adaptiveSampleStep - 1) / adaptiveSampleStep;
|
||||||
int axisSamples = axisCells + 1;
|
int axisSamples = axisCells + 1;
|
||||||
for (int sampleXIndex = 0; sampleXIndex < axisSamples; sampleXIndex++) {
|
int[] adaptivePlaneSampleBounds = scratch.adaptivePlaneSampleBounds;
|
||||||
|
prepareAdaptivePlaneSampleBounds(planeColumnIndices, planeCount, adaptiveSampleStep, adaptivePlaneSampleBounds, axisCells);
|
||||||
|
for (int sampleXIndex = adaptivePlaneSampleBounds[0]; sampleXIndex <= adaptivePlaneSampleBounds[1]; sampleXIndex++) {
|
||||||
int sampleLocalX = Math.min(sampleXIndex * adaptiveSampleStep, 16);
|
int sampleLocalX = Math.min(sampleXIndex * adaptiveSampleStep, 16);
|
||||||
int x = x0 + sampleLocalX;
|
int x = x0 + sampleLocalX;
|
||||||
int rowOffset = sampleXIndex * axisSamples;
|
int rowOffset = sampleXIndex * axisSamples;
|
||||||
for (int sampleZIndex = 0; sampleZIndex < axisSamples; sampleZIndex++) {
|
for (int sampleZIndex = adaptivePlaneSampleBounds[2]; sampleZIndex <= adaptivePlaneSampleBounds[3]; sampleZIndex++) {
|
||||||
int sampleLocalZ = Math.min(sampleZIndex * adaptiveSampleStep, 16);
|
int sampleLocalZ = Math.min(sampleZIndex * adaptiveSampleStep, 16);
|
||||||
adaptivePlaneDensity[rowOffset + sampleZIndex] = sampleDensityNoWarpNoModules(x, y, z0 + sampleLocalZ);
|
adaptivePlaneDensity[rowOffset + sampleZIndex] = sampleDensityNoWarpNoModules(x, y, z0 + sampleLocalZ);
|
||||||
}
|
}
|
||||||
@@ -1144,11 +1148,13 @@ public class IrisCaveCarver3D {
|
|||||||
double[] adaptivePlaneDensity = scratch.adaptivePlaneDensity;
|
double[] adaptivePlaneDensity = scratch.adaptivePlaneDensity;
|
||||||
int axisCells = (16 + adaptiveSampleStep - 1) / adaptiveSampleStep;
|
int axisCells = (16 + adaptiveSampleStep - 1) / adaptiveSampleStep;
|
||||||
int axisSamples = axisCells + 1;
|
int axisSamples = axisCells + 1;
|
||||||
for (int sampleXIndex = 0; sampleXIndex < axisSamples; sampleXIndex++) {
|
int[] adaptivePlaneSampleBounds = scratch.adaptivePlaneSampleBounds;
|
||||||
|
prepareAdaptivePlaneSampleBounds(planeColumnIndices, planeCount, adaptiveSampleStep, adaptivePlaneSampleBounds, axisCells);
|
||||||
|
for (int sampleXIndex = adaptivePlaneSampleBounds[0]; sampleXIndex <= adaptivePlaneSampleBounds[1]; sampleXIndex++) {
|
||||||
int sampleLocalX = Math.min(sampleXIndex * adaptiveSampleStep, 16);
|
int sampleLocalX = Math.min(sampleXIndex * adaptiveSampleStep, 16);
|
||||||
int x = x0 + sampleLocalX;
|
int x = x0 + sampleLocalX;
|
||||||
int rowOffset = sampleXIndex * axisSamples;
|
int rowOffset = sampleXIndex * axisSamples;
|
||||||
for (int sampleZIndex = 0; sampleZIndex < axisSamples; sampleZIndex++) {
|
for (int sampleZIndex = adaptivePlaneSampleBounds[2]; sampleZIndex <= adaptivePlaneSampleBounds[3]; sampleZIndex++) {
|
||||||
int sampleLocalZ = Math.min(sampleZIndex * adaptiveSampleStep, 16);
|
int sampleLocalZ = Math.min(sampleZIndex * adaptiveSampleStep, 16);
|
||||||
adaptivePlaneDensity[rowOffset + sampleZIndex] = sampleDensityWarpOnly(x, y, z0 + sampleLocalZ);
|
adaptivePlaneDensity[rowOffset + sampleZIndex] = sampleDensityWarpOnly(x, y, z0 + sampleLocalZ);
|
||||||
}
|
}
|
||||||
@@ -1194,17 +1200,25 @@ public class IrisCaveCarver3D {
|
|||||||
double[] adaptivePlaneDensity = scratch.adaptivePlaneDensity;
|
double[] adaptivePlaneDensity = scratch.adaptivePlaneDensity;
|
||||||
int axisCells = (16 + adaptiveSampleStep - 1) / adaptiveSampleStep;
|
int axisCells = (16 + adaptiveSampleStep - 1) / adaptiveSampleStep;
|
||||||
int axisSamples = axisCells + 1;
|
int axisSamples = axisCells + 1;
|
||||||
for (int sampleXIndex = 0; sampleXIndex < axisSamples; sampleXIndex++) {
|
int[] adaptivePlaneSampleBounds = scratch.adaptivePlaneSampleBounds;
|
||||||
|
prepareAdaptivePlaneSampleBounds(planeColumnIndices, planeCount, adaptiveSampleStep, adaptivePlaneSampleBounds, axisCells);
|
||||||
|
for (int sampleXIndex = adaptivePlaneSampleBounds[0]; sampleXIndex <= adaptivePlaneSampleBounds[1]; sampleXIndex++) {
|
||||||
int sampleLocalX = Math.min(sampleXIndex * adaptiveSampleStep, 16);
|
int sampleLocalX = Math.min(sampleXIndex * adaptiveSampleStep, 16);
|
||||||
int x = x0 + sampleLocalX;
|
int x = x0 + sampleLocalX;
|
||||||
int rowOffset = sampleXIndex * axisSamples;
|
int rowOffset = sampleXIndex * axisSamples;
|
||||||
for (int sampleZIndex = 0; sampleZIndex < axisSamples; sampleZIndex++) {
|
for (int sampleZIndex = adaptivePlaneSampleBounds[2]; sampleZIndex <= adaptivePlaneSampleBounds[3]; sampleZIndex++) {
|
||||||
int sampleLocalZ = Math.min(sampleZIndex * adaptiveSampleStep, 16);
|
int sampleLocalZ = Math.min(sampleZIndex * adaptiveSampleStep, 16);
|
||||||
adaptivePlaneDensity[rowOffset + sampleZIndex] = sampleDensityWarpOnly(x, y, z0 + sampleLocalZ);
|
adaptivePlaneDensity[rowOffset + sampleZIndex] = sampleDensityWarpModules(
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
z0 + sampleLocalZ,
|
||||||
|
localModules,
|
||||||
|
activeModuleCount
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
classifyAdaptivePlaneColumnsWarpModules(
|
classifyAdaptivePlaneColumnsWarpModulesSampled(
|
||||||
x0,
|
x0,
|
||||||
z0,
|
z0,
|
||||||
y,
|
y,
|
||||||
@@ -1259,6 +1273,10 @@ public class IrisCaveCarver3D {
|
|||||||
double threshold = planeThresholdLimit[planeIndex] * inverseNormalization;
|
double threshold = planeThresholdLimit[planeIndex] * inverseNormalization;
|
||||||
double predictedDensity = adaptivePlanePrediction[planeIndex];
|
double predictedDensity = adaptivePlanePrediction[planeIndex];
|
||||||
double ambiguityMargin = adaptivePlaneAmbiguity[planeIndex];
|
double ambiguityMargin = adaptivePlaneAmbiguity[planeIndex];
|
||||||
|
if (isAdaptivePlaneSampleAligned(localX, localZ, adaptiveSampleStep)) {
|
||||||
|
planeCarve[planeIndex] = predictedDensity <= threshold;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (predictedDensity <= threshold - ambiguityMargin) {
|
if (predictedDensity <= threshold - ambiguityMargin) {
|
||||||
planeCarve[planeIndex] = true;
|
planeCarve[planeIndex] = true;
|
||||||
continue;
|
continue;
|
||||||
@@ -1313,6 +1331,20 @@ public class IrisCaveCarver3D {
|
|||||||
double threshold = planeThresholdLimit[planeIndex] * inverseNormalization;
|
double threshold = planeThresholdLimit[planeIndex] * inverseNormalization;
|
||||||
double predictedDensity = adaptivePlanePrediction[planeIndex];
|
double predictedDensity = adaptivePlanePrediction[planeIndex];
|
||||||
double ambiguityMargin = adaptivePlaneAmbiguity[planeIndex];
|
double ambiguityMargin = adaptivePlaneAmbiguity[planeIndex];
|
||||||
|
if (isAdaptivePlaneSampleAligned(localX, localZ, adaptiveSampleStep)) {
|
||||||
|
planeCarve[planeIndex] = classifyDensityPointNoWarpModulesFromExactDensity(
|
||||||
|
x0 + localX,
|
||||||
|
y,
|
||||||
|
z0 + localZ,
|
||||||
|
threshold,
|
||||||
|
predictedDensity,
|
||||||
|
localModules,
|
||||||
|
activeModuleCount,
|
||||||
|
remainingMin,
|
||||||
|
remainingMax
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if ((predictedDensity + maxRemaining) <= threshold - ambiguityMargin) {
|
if ((predictedDensity + maxRemaining) <= threshold - ambiguityMargin) {
|
||||||
planeCarve[planeIndex] = true;
|
planeCarve[planeIndex] = true;
|
||||||
continue;
|
continue;
|
||||||
@@ -1370,6 +1402,10 @@ public class IrisCaveCarver3D {
|
|||||||
double threshold = planeThresholdLimit[planeIndex] * inverseNormalization;
|
double threshold = planeThresholdLimit[planeIndex] * inverseNormalization;
|
||||||
double predictedDensity = adaptivePlanePrediction[planeIndex];
|
double predictedDensity = adaptivePlanePrediction[planeIndex];
|
||||||
double ambiguityMargin = adaptivePlaneAmbiguity[planeIndex];
|
double ambiguityMargin = adaptivePlaneAmbiguity[planeIndex];
|
||||||
|
if (isAdaptivePlaneSampleAligned(localX, localZ, adaptiveSampleStep)) {
|
||||||
|
planeCarve[planeIndex] = predictedDensity <= threshold;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (predictedDensity <= threshold - ambiguityMargin) {
|
if (predictedDensity <= threshold - ambiguityMargin) {
|
||||||
planeCarve[planeIndex] = true;
|
planeCarve[planeIndex] = true;
|
||||||
continue;
|
continue;
|
||||||
@@ -1424,6 +1460,20 @@ public class IrisCaveCarver3D {
|
|||||||
double threshold = planeThresholdLimit[planeIndex] * inverseNormalization;
|
double threshold = planeThresholdLimit[planeIndex] * inverseNormalization;
|
||||||
double predictedDensity = adaptivePlanePrediction[planeIndex];
|
double predictedDensity = adaptivePlanePrediction[planeIndex];
|
||||||
double ambiguityMargin = adaptivePlaneAmbiguity[planeIndex];
|
double ambiguityMargin = adaptivePlaneAmbiguity[planeIndex];
|
||||||
|
if (isAdaptivePlaneSampleAligned(localX, localZ, adaptiveSampleStep)) {
|
||||||
|
planeCarve[planeIndex] = classifyDensityPointWarpModulesFromExactDensity(
|
||||||
|
x0 + localX,
|
||||||
|
y,
|
||||||
|
z0 + localZ,
|
||||||
|
threshold,
|
||||||
|
predictedDensity,
|
||||||
|
localModules,
|
||||||
|
activeModuleCount,
|
||||||
|
remainingMin,
|
||||||
|
remainingMax
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if ((predictedDensity + maxRemaining) <= threshold - ambiguityMargin) {
|
if ((predictedDensity + maxRemaining) <= threshold - ambiguityMargin) {
|
||||||
planeCarve[planeIndex] = true;
|
planeCarve[planeIndex] = true;
|
||||||
continue;
|
continue;
|
||||||
@@ -1446,6 +1496,71 @@ public class IrisCaveCarver3D {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void classifyAdaptivePlaneColumnsWarpModulesSampled(
|
||||||
|
int x0,
|
||||||
|
int z0,
|
||||||
|
int y,
|
||||||
|
int[] planeColumnIndices,
|
||||||
|
double[] planeThresholdLimit,
|
||||||
|
int planeCount,
|
||||||
|
boolean[] planeCarve,
|
||||||
|
int adaptiveSampleStep,
|
||||||
|
double adaptiveThresholdMargin,
|
||||||
|
double[] adaptivePlaneDensity,
|
||||||
|
int axisCells,
|
||||||
|
int axisSamples,
|
||||||
|
ModuleState[] localModules,
|
||||||
|
int activeModuleCount,
|
||||||
|
double[] remainingMin,
|
||||||
|
double[] remainingMax
|
||||||
|
) {
|
||||||
|
Scratch scratch = SCRATCH.get();
|
||||||
|
double[] adaptivePlanePrediction = scratch.adaptivePlanePrediction;
|
||||||
|
double[] adaptivePlaneAmbiguity = scratch.adaptivePlaneAmbiguity;
|
||||||
|
prepareAdaptivePlaneColumns(
|
||||||
|
planeColumnIndices,
|
||||||
|
planeCount,
|
||||||
|
adaptiveSampleStep,
|
||||||
|
adaptiveThresholdMargin,
|
||||||
|
adaptivePlaneDensity,
|
||||||
|
axisCells,
|
||||||
|
axisSamples,
|
||||||
|
adaptivePlanePrediction,
|
||||||
|
adaptivePlaneAmbiguity
|
||||||
|
);
|
||||||
|
for (int planeIndex = 0; planeIndex < planeCount; planeIndex++) {
|
||||||
|
int columnIndex = planeColumnIndices[planeIndex];
|
||||||
|
int localX = PowerOfTwoCoordinates.unpackLocal16X(columnIndex);
|
||||||
|
int localZ = columnIndex & 15;
|
||||||
|
double threshold = planeThresholdLimit[planeIndex] * inverseNormalization;
|
||||||
|
double predictedDensity = adaptivePlanePrediction[planeIndex];
|
||||||
|
double ambiguityMargin = adaptivePlaneAmbiguity[planeIndex];
|
||||||
|
if (isAdaptivePlaneSampleAligned(localX, localZ, adaptiveSampleStep)) {
|
||||||
|
planeCarve[planeIndex] = predictedDensity <= threshold;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (predictedDensity <= threshold - ambiguityMargin) {
|
||||||
|
planeCarve[planeIndex] = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (predictedDensity > threshold + ambiguityMargin) {
|
||||||
|
planeCarve[planeIndex] = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
planeCarve[planeIndex] = classifyDensityPointWarpModules(
|
||||||
|
x0 + localX,
|
||||||
|
y,
|
||||||
|
z0 + localZ,
|
||||||
|
planeThresholdLimit[planeIndex],
|
||||||
|
localModules,
|
||||||
|
activeModuleCount,
|
||||||
|
remainingMin,
|
||||||
|
remainingMax
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean classifyDensityPointNoWarpNoModules(int x, int y, int z, double thresholdLimit) {
|
private boolean classifyDensityPointNoWarpNoModules(int x, int y, int z, double thresholdLimit) {
|
||||||
double density = baseDensity.noiseFastSigned3D(x, y, z) * baseWeight;
|
double density = baseDensity.noiseFastSigned3D(x, y, z) * baseWeight;
|
||||||
if ((density + detailMinContribution) > thresholdLimit) {
|
if ((density + detailMinContribution) > thresholdLimit) {
|
||||||
@@ -1568,6 +1683,127 @@ public class IrisCaveCarver3D {
|
|||||||
return density <= thresholdLimit;
|
return density <= thresholdLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean classifyDensityPointNoWarpModulesFromExactDensity(
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int z,
|
||||||
|
double threshold,
|
||||||
|
double density,
|
||||||
|
ModuleState[] localModules,
|
||||||
|
int activeModuleCount,
|
||||||
|
double[] remainingMin,
|
||||||
|
double[] remainingMax
|
||||||
|
) {
|
||||||
|
if (activeModuleCount == 0) {
|
||||||
|
return density <= threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
double minRemaining = remainingMin[0] * inverseNormalization;
|
||||||
|
double maxRemaining = remainingMax[0] * inverseNormalization;
|
||||||
|
if ((density + minRemaining) > threshold) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((density + maxRemaining) <= threshold) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int moduleIndex = 0; moduleIndex < activeModuleCount; moduleIndex++) {
|
||||||
|
density += localModules[moduleIndex].sample(x, y, z) * inverseNormalization;
|
||||||
|
if ((density + (remainingMin[moduleIndex + 1] * inverseNormalization)) > threshold) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((density + (remainingMax[moduleIndex + 1] * inverseNormalization)) <= threshold) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return density <= threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean classifyDensityPointWarpModulesFromExactDensity(
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int z,
|
||||||
|
double threshold,
|
||||||
|
double density,
|
||||||
|
ModuleState[] localModules,
|
||||||
|
int activeModuleCount,
|
||||||
|
double[] remainingMin,
|
||||||
|
double[] remainingMax
|
||||||
|
) {
|
||||||
|
if (activeModuleCount == 0) {
|
||||||
|
return density <= threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
double minRemaining = remainingMin[0] * inverseNormalization;
|
||||||
|
double maxRemaining = remainingMax[0] * inverseNormalization;
|
||||||
|
if ((density + minRemaining) > threshold) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((density + maxRemaining) <= threshold) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
double warpA = warpDensity.noiseFastSigned3D(x, y, z);
|
||||||
|
double warpB = warpDensity.noiseFastSigned3D(x + 31.37D, y - 17.21D, z + 23.91D);
|
||||||
|
double warpedX = x + (warpA * warpStrength);
|
||||||
|
double warpedY = y + (warpB * warpStrength);
|
||||||
|
double warpedZ = z + ((warpA - warpB) * 0.5D * warpStrength);
|
||||||
|
for (int moduleIndex = 0; moduleIndex < activeModuleCount; moduleIndex++) {
|
||||||
|
density += localModules[moduleIndex].sample(warpedX, warpedY, warpedZ) * inverseNormalization;
|
||||||
|
if ((density + (remainingMin[moduleIndex + 1] * inverseNormalization)) > threshold) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((density + (remainingMax[moduleIndex + 1] * inverseNormalization)) <= threshold) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return density <= threshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAdaptivePlaneSampleAligned(int localX, int localZ, int adaptiveSampleStep) {
|
||||||
|
return localX % adaptiveSampleStep == 0 && localZ % adaptiveSampleStep == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareAdaptivePlaneSampleBounds(
|
||||||
|
int[] planeColumnIndices,
|
||||||
|
int planeCount,
|
||||||
|
int adaptiveSampleStep,
|
||||||
|
int[] adaptivePlaneSampleBounds,
|
||||||
|
int axisCells
|
||||||
|
) {
|
||||||
|
int minSampleX = axisCells;
|
||||||
|
int maxSampleX = 0;
|
||||||
|
int minSampleZ = axisCells;
|
||||||
|
int maxSampleZ = 0;
|
||||||
|
|
||||||
|
for (int planeIndex = 0; planeIndex < planeCount; planeIndex++) {
|
||||||
|
int columnIndex = planeColumnIndices[planeIndex];
|
||||||
|
int localX = PowerOfTwoCoordinates.unpackLocal16X(columnIndex);
|
||||||
|
int localZ = columnIndex & 15;
|
||||||
|
int sampleX = Math.min(localX / adaptiveSampleStep, axisCells - 1);
|
||||||
|
int sampleZ = Math.min(localZ / adaptiveSampleStep, axisCells - 1);
|
||||||
|
if (sampleX < minSampleX) {
|
||||||
|
minSampleX = sampleX;
|
||||||
|
}
|
||||||
|
if (sampleX + 1 > maxSampleX) {
|
||||||
|
maxSampleX = sampleX + 1;
|
||||||
|
}
|
||||||
|
if (sampleZ < minSampleZ) {
|
||||||
|
minSampleZ = sampleZ;
|
||||||
|
}
|
||||||
|
if (sampleZ + 1 > maxSampleZ) {
|
||||||
|
maxSampleZ = sampleZ + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
adaptivePlaneSampleBounds[0] = minSampleX;
|
||||||
|
adaptivePlaneSampleBounds[1] = maxSampleX;
|
||||||
|
adaptivePlaneSampleBounds[2] = minSampleZ;
|
||||||
|
adaptivePlaneSampleBounds[3] = maxSampleZ;
|
||||||
|
}
|
||||||
|
|
||||||
private void prepareAdaptivePlaneColumns(
|
private void prepareAdaptivePlaneColumns(
|
||||||
int[] planeColumnIndices,
|
int[] planeColumnIndices,
|
||||||
int planeCount,
|
int planeCount,
|
||||||
@@ -1654,6 +1890,10 @@ public class IrisCaveCarver3D {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ModuleState[] localModules = scratch.activeModules;
|
ModuleState[] localModules = scratch.activeModules;
|
||||||
|
return sampleDensityWarpModules(x, y, z, localModules, activeModuleCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double sampleDensityWarpModules(int x, int y, int z, ModuleState[] localModules, int activeModuleCount) {
|
||||||
double warpA = warpDensity.noiseFastSigned3D(x, y, z);
|
double warpA = warpDensity.noiseFastSigned3D(x, y, z);
|
||||||
double warpB = warpDensity.noiseFastSigned3D(x + 31.37D, y - 17.21D, z + 23.91D);
|
double warpB = warpDensity.noiseFastSigned3D(x + 31.37D, y - 17.21D, z + 23.91D);
|
||||||
double warpedX = x + (warpA * warpStrength);
|
double warpedX = x + (warpA * warpStrength);
|
||||||
@@ -1882,6 +2122,7 @@ public class IrisCaveCarver3D {
|
|||||||
private final double[] adaptivePlaneDensity = new double[81];
|
private final double[] adaptivePlaneDensity = new double[81];
|
||||||
private final double[] adaptivePlanePrediction = new double[256];
|
private final double[] adaptivePlanePrediction = new double[256];
|
||||||
private final double[] adaptivePlaneAmbiguity = new double[256];
|
private final double[] adaptivePlaneAmbiguity = new double[256];
|
||||||
|
private final int[] adaptivePlaneSampleBounds = new int[4];
|
||||||
private final int[] tileIndices = new int[4];
|
private final int[] tileIndices = new int[4];
|
||||||
private final int[] tileLocalX = new int[4];
|
private final int[] tileLocalX = new int[4];
|
||||||
private final int[] tileLocalZ = new int[4];
|
private final int[] tileLocalZ = new int[4];
|
||||||
|
|||||||
+95
-19
@@ -31,11 +31,12 @@ import art.arcane.iris.engine.object.IrisDimensionCarvingResolver;
|
|||||||
import art.arcane.iris.engine.object.IrisRegion;
|
import art.arcane.iris.engine.object.IrisRegion;
|
||||||
import art.arcane.iris.engine.object.IrisRange;
|
import art.arcane.iris.engine.object.IrisRange;
|
||||||
import art.arcane.iris.util.project.context.ChunkContext;
|
import art.arcane.iris.util.project.context.ChunkContext;
|
||||||
|
import art.arcane.iris.util.project.stream.ProceduralStream;
|
||||||
|
import art.arcane.iris.util.project.stream.utility.ChunkFillableDoubleStream2D;
|
||||||
import art.arcane.volmlib.util.documentation.ChunkCoordinates;
|
import art.arcane.volmlib.util.documentation.ChunkCoordinates;
|
||||||
import art.arcane.volmlib.util.mantle.flag.ReservedFlag;
|
import art.arcane.volmlib.util.mantle.flag.ReservedFlag;
|
||||||
import art.arcane.volmlib.util.math.PowerOfTwoCoordinates;
|
import art.arcane.volmlib.util.math.PowerOfTwoCoordinates;
|
||||||
import art.arcane.volmlib.util.scheduling.PrecisionStopwatch;
|
import art.arcane.volmlib.util.scheduling.PrecisionStopwatch;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -82,11 +83,10 @@ public class MantleCarvingComponent extends IrisMantleComponent {
|
|||||||
public void generateLayer(MantleWriter writer, int x, int z, ChunkContext context) {
|
public void generateLayer(MantleWriter writer, int x, int z, ChunkContext context) {
|
||||||
IrisComplex complex = context.getComplex();
|
IrisComplex complex = context.getComplex();
|
||||||
IrisDimensionCarvingResolver.State resolverState = new IrisDimensionCarvingResolver.State();
|
IrisDimensionCarvingResolver.State resolverState = new IrisDimensionCarvingResolver.State();
|
||||||
Long2ObjectOpenHashMap<IrisBiome> caveBiomeCache = new Long2ObjectOpenHashMap<>(FIELD_SIZE * FIELD_SIZE);
|
|
||||||
BlendScratch blendScratch = BLEND_SCRATCH.get();
|
BlendScratch blendScratch = BLEND_SCRATCH.get();
|
||||||
int[] chunkSurfaceHeights = prepareChunkSurfaceHeights(x, z, context, blendScratch.chunkSurfaceHeights);
|
int[] chunkSurfaceHeights = prepareChunkSurfaceHeights(x, z, context, blendScratch.chunkSurfaceHeights);
|
||||||
PrecisionStopwatch resolveStopwatch = PrecisionStopwatch.start();
|
PrecisionStopwatch resolveStopwatch = PrecisionStopwatch.start();
|
||||||
List<WeightedProfile> weightedProfiles = resolveWeightedProfiles(x, z, complex, resolverState, caveBiomeCache);
|
List<WeightedProfile> weightedProfiles = resolveWeightedProfiles(x, z, complex, resolverState);
|
||||||
getEngineMantle().getEngine().getMetrics().getCarveResolve().put(resolveStopwatch.getMilliseconds());
|
getEngineMantle().getEngine().getMetrics().getCarveResolve().put(resolveStopwatch.getMilliseconds());
|
||||||
for (WeightedProfile weightedProfile : weightedProfiles) {
|
for (WeightedProfile weightedProfile : weightedProfiles) {
|
||||||
carveProfile(weightedProfile, writer, x, z, chunkSurfaceHeights);
|
carveProfile(weightedProfile, writer, x, z, chunkSurfaceHeights);
|
||||||
@@ -99,7 +99,7 @@ public class MantleCarvingComponent extends IrisMantleComponent {
|
|||||||
carver.carve(writer, cx, cz, weightedProfile.columnWeights, MIN_WEIGHT, THRESHOLD_PENALTY, weightedProfile.worldYRange, chunkSurfaceHeights);
|
carver.carve(writer, cx, cz, weightedProfile.columnWeights, MIN_WEIGHT, THRESHOLD_PENALTY, weightedProfile.worldYRange, chunkSurfaceHeights);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<WeightedProfile> resolveWeightedProfiles(int chunkX, int chunkZ, IrisComplex complex, IrisDimensionCarvingResolver.State resolverState, Long2ObjectOpenHashMap<IrisBiome> caveBiomeCache) {
|
private List<WeightedProfile> resolveWeightedProfiles(int chunkX, int chunkZ, IrisComplex complex, IrisDimensionCarvingResolver.State resolverState) {
|
||||||
BlendScratch blendScratch = BLEND_SCRATCH.get();
|
BlendScratch blendScratch = BLEND_SCRATCH.get();
|
||||||
IrisCaveProfile[] profileField = blendScratch.profileField;
|
IrisCaveProfile[] profileField = blendScratch.profileField;
|
||||||
Map<IrisCaveProfile, double[]> columnProfileWeights = blendScratch.columnProfileWeights;
|
Map<IrisCaveProfile, double[]> columnProfileWeights = blendScratch.columnProfileWeights;
|
||||||
@@ -107,7 +107,7 @@ public class MantleCarvingComponent extends IrisMantleComponent {
|
|||||||
IrisCaveProfile[] kernelProfiles = blendScratch.kernelProfiles;
|
IrisCaveProfile[] kernelProfiles = blendScratch.kernelProfiles;
|
||||||
double[] kernelProfileWeights = blendScratch.kernelProfileWeights;
|
double[] kernelProfileWeights = blendScratch.kernelProfileWeights;
|
||||||
activeProfiles.clear();
|
activeProfiles.clear();
|
||||||
fillProfileField(profileField, chunkX, chunkZ, complex, resolverState, caveBiomeCache);
|
fillProfileField(profileField, chunkX, chunkZ, complex, resolverState, blendScratch);
|
||||||
|
|
||||||
for (int localX = 0; localX < CHUNK_SIZE; localX++) {
|
for (int localX = 0; localX < CHUNK_SIZE; localX++) {
|
||||||
for (int localZ = 0; localZ < CHUNK_SIZE; localZ++) {
|
for (int localZ = 0; localZ < CHUNK_SIZE; localZ++) {
|
||||||
@@ -268,15 +268,25 @@ public class MantleCarvingComponent extends IrisMantleComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillProfileField(IrisCaveProfile[] profileField, int chunkX, int chunkZ, IrisComplex complex, IrisDimensionCarvingResolver.State resolverState, Long2ObjectOpenHashMap<IrisBiome> caveBiomeCache) {
|
private void fillProfileField(IrisCaveProfile[] profileField, int chunkX, int chunkZ, IrisComplex complex, IrisDimensionCarvingResolver.State resolverState, BlendScratch blendScratch) {
|
||||||
int startX = PowerOfTwoCoordinates.chunkToBlock(chunkX) - BLEND_RADIUS;
|
int startX = PowerOfTwoCoordinates.chunkToBlock(chunkX) - BLEND_RADIUS;
|
||||||
int startZ = PowerOfTwoCoordinates.chunkToBlock(chunkZ) - BLEND_RADIUS;
|
int startZ = PowerOfTwoCoordinates.chunkToBlock(chunkZ) - BLEND_RADIUS;
|
||||||
|
prefillProfileFieldSamples(startX, startZ, complex, blendScratch);
|
||||||
|
|
||||||
for (int fieldX = 0; fieldX < FIELD_SIZE; fieldX++) {
|
for (int fieldX = 0; fieldX < FIELD_SIZE; fieldX++) {
|
||||||
int worldX = startX + fieldX;
|
int worldX = startX + fieldX;
|
||||||
for (int fieldZ = 0; fieldZ < FIELD_SIZE; fieldZ++) {
|
for (int fieldZ = 0; fieldZ < FIELD_SIZE; fieldZ++) {
|
||||||
int worldZ = startZ + fieldZ;
|
int worldZ = startZ + fieldZ;
|
||||||
profileField[(fieldX * FIELD_SIZE) + fieldZ] = resolveColumnProfile(worldX, worldZ, complex, resolverState, caveBiomeCache);
|
int fieldIndex = (fieldX * FIELD_SIZE) + fieldZ;
|
||||||
|
profileField[fieldIndex] = resolveColumnProfile(
|
||||||
|
worldX,
|
||||||
|
worldZ,
|
||||||
|
blendScratch.fieldSurfaceHeights[fieldIndex],
|
||||||
|
blendScratch.fieldRegions[fieldIndex],
|
||||||
|
blendScratch.fieldSurfaceBiomes[fieldIndex],
|
||||||
|
blendScratch.fieldCaveBiomes[fieldIndex],
|
||||||
|
resolverState
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -291,14 +301,21 @@ public class MantleCarvingComponent extends IrisMantleComponent {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IrisCaveProfile resolveColumnProfile(int worldX, int worldZ, IrisComplex complex, IrisDimensionCarvingResolver.State resolverState, Long2ObjectOpenHashMap<IrisBiome> caveBiomeCache) {
|
private IrisCaveProfile resolveColumnProfile(
|
||||||
|
int worldX,
|
||||||
|
int worldZ,
|
||||||
|
double surfaceHeight,
|
||||||
|
IrisRegion region,
|
||||||
|
IrisBiome surfaceBiome,
|
||||||
|
IrisBiome caveBiome,
|
||||||
|
IrisDimensionCarvingResolver.State resolverState
|
||||||
|
) {
|
||||||
IrisCaveProfile resolved = null;
|
IrisCaveProfile resolved = null;
|
||||||
IrisCaveProfile dimensionProfile = getDimension().getCaveProfile();
|
IrisCaveProfile dimensionProfile = getDimension().getCaveProfile();
|
||||||
if (isProfileEnabled(dimensionProfile)) {
|
if (isProfileEnabled(dimensionProfile)) {
|
||||||
resolved = dimensionProfile;
|
resolved = dimensionProfile;
|
||||||
}
|
}
|
||||||
|
|
||||||
IrisRegion region = complex.getRegionStream().get(worldX, worldZ);
|
|
||||||
if (region != null) {
|
if (region != null) {
|
||||||
IrisCaveProfile regionProfile = region.getCaveProfile();
|
IrisCaveProfile regionProfile = region.getCaveProfile();
|
||||||
if (isProfileEnabled(regionProfile)) {
|
if (isProfileEnabled(regionProfile)) {
|
||||||
@@ -306,7 +323,6 @@ public class MantleCarvingComponent extends IrisMantleComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IrisBiome surfaceBiome = complex.getTrueBiomeStream().get(worldX, worldZ);
|
|
||||||
if (surfaceBiome != null) {
|
if (surfaceBiome != null) {
|
||||||
IrisCaveProfile surfaceProfile = surfaceBiome.getCaveProfile();
|
IrisCaveProfile surfaceProfile = surfaceBiome.getCaveProfile();
|
||||||
if (isProfileEnabled(surfaceProfile)) {
|
if (isProfileEnabled(surfaceProfile)) {
|
||||||
@@ -314,18 +330,36 @@ public class MantleCarvingComponent extends IrisMantleComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int surfaceY = getEngineMantle().getEngine().getHeight(worldX, worldZ, true);
|
int roundedSurfaceY = (int) Math.round(surfaceHeight);
|
||||||
int sampleY = Math.max(1, surfaceY - 56);
|
int sampleY = Math.max(1, roundedSurfaceY - 56);
|
||||||
long cacheKey = Cache.key(worldX, worldZ);
|
int worldY = sampleY + getEngineMantle().getEngine().getWorld().minHeight();
|
||||||
IrisBiome caveBiome = caveBiomeCache.get(cacheKey);
|
IrisDimensionCarvingEntry rootCarvingEntry = IrisDimensionCarvingResolver.resolveRootEntry(getEngineMantle().getEngine(), worldY, resolverState);
|
||||||
if (caveBiome == null) {
|
IrisBiome resolvedCarvingBiome = null;
|
||||||
caveBiome = getEngineMantle().getEngine().getCaveBiome(worldX, sampleY, worldZ, resolverState);
|
if (rootCarvingEntry != null) {
|
||||||
if (caveBiome != null) {
|
IrisDimensionCarvingEntry resolvedCarvingEntry = IrisDimensionCarvingResolver.resolveFromRoot(getEngineMantle().getEngine(), rootCarvingEntry, worldX, worldZ, resolverState);
|
||||||
caveBiomeCache.put(cacheKey, caveBiome);
|
resolvedCarvingBiome = IrisDimensionCarvingResolver.resolveEntryBiome(getEngineMantle().getEngine(), resolvedCarvingEntry, resolverState);
|
||||||
|
if (resolvedCarvingBiome != null) {
|
||||||
|
caveBiome = resolvedCarvingBiome;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (caveBiome != null) {
|
if (caveBiome != null) {
|
||||||
IrisCaveProfile caveProfile = caveBiome.getCaveProfile();
|
IrisBiome effectiveCaveBiome = caveBiome;
|
||||||
|
if (resolvedCarvingBiome == null && surfaceBiome != null) {
|
||||||
|
if (surfaceBiome != null) {
|
||||||
|
int truncatedSurfaceY = (int) surfaceHeight;
|
||||||
|
int depthBelowSurface = truncatedSurfaceY - sampleY;
|
||||||
|
if (depthBelowSurface <= 0) {
|
||||||
|
effectiveCaveBiome = surfaceBiome;
|
||||||
|
} else {
|
||||||
|
int minDepth = Math.max(0, caveBiome.getCaveMinDepthBelowSurface());
|
||||||
|
if (depthBelowSurface < minDepth) {
|
||||||
|
effectiveCaveBiome = surfaceBiome;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IrisCaveProfile caveProfile = effectiveCaveBiome.getCaveProfile();
|
||||||
if (isProfileEnabled(caveProfile)) {
|
if (isProfileEnabled(caveProfile)) {
|
||||||
resolved = caveProfile;
|
resolved = caveProfile;
|
||||||
}
|
}
|
||||||
@@ -334,6 +368,31 @@ public class MantleCarvingComponent extends IrisMantleComponent {
|
|||||||
return resolved;
|
return resolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void prefillProfileFieldSamples(int startX, int startZ, IrisComplex complex, BlendScratch blendScratch) {
|
||||||
|
fillFieldHeights(complex.getHeightStream(), startX, startZ, blendScratch.fieldSurfaceHeights);
|
||||||
|
fillFieldObjects(complex.getRegionStream(), startX, startZ, blendScratch.fieldRegions);
|
||||||
|
fillFieldObjects(complex.getTrueBiomeStream(), startX, startZ, blendScratch.fieldSurfaceBiomes);
|
||||||
|
fillFieldObjects(complex.getCaveBiomeStream(), startX, startZ, blendScratch.fieldCaveBiomes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> void fillFieldObjects(ProceduralStream<T> stream, int startX, int startZ, T[] target) {
|
||||||
|
for (int fieldX = 0; fieldX < FIELD_SIZE; fieldX++) {
|
||||||
|
int worldX = startX + fieldX;
|
||||||
|
for (int fieldZ = 0; fieldZ < FIELD_SIZE; fieldZ++) {
|
||||||
|
target[(fieldX * FIELD_SIZE) + fieldZ] = stream.get(worldX, startZ + fieldZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fillFieldHeights(ProceduralStream<Double> stream, int startX, int startZ, double[] target) {
|
||||||
|
for (int fieldX = 0; fieldX < FIELD_SIZE; fieldX++) {
|
||||||
|
int worldX = startX + fieldX;
|
||||||
|
for (int fieldZ = 0; fieldZ < FIELD_SIZE; fieldZ++) {
|
||||||
|
target[(fieldX * FIELD_SIZE) + fieldZ] = stream.getDouble(worldX, startZ + fieldZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private IrisCaveCarver3D getCarver(IrisCaveProfile profile) {
|
private IrisCaveCarver3D getCarver(IrisCaveProfile profile) {
|
||||||
synchronized (profileCarvers) {
|
synchronized (profileCarvers) {
|
||||||
IrisCaveCarver3D carver = profileCarvers.get(profile);
|
IrisCaveCarver3D carver = profileCarvers.get(profile);
|
||||||
@@ -363,6 +422,14 @@ public class MantleCarvingComponent extends IrisMantleComponent {
|
|||||||
&& context.getHeight() != null
|
&& context.getHeight() != null
|
||||||
&& context.getX() == baseX
|
&& context.getX() == baseX
|
||||||
&& context.getZ() == baseZ;
|
&& context.getZ() == baseZ;
|
||||||
|
double[] cachedChunkHeights = null;
|
||||||
|
if (!useContextHeight && context != null) {
|
||||||
|
ProceduralStream<Double> heightStream = context.getComplex().getHeightStream();
|
||||||
|
if (heightStream instanceof ChunkFillableDoubleStream2D cachedHeightStream) {
|
||||||
|
cachedChunkHeights = BLEND_SCRATCH.get().chunkSurfaceHeightSamples;
|
||||||
|
cachedHeightStream.fillChunkDoubles(baseX, baseZ, cachedChunkHeights);
|
||||||
|
}
|
||||||
|
}
|
||||||
for (int localX = 0; localX < CHUNK_SIZE; localX++) {
|
for (int localX = 0; localX < CHUNK_SIZE; localX++) {
|
||||||
int worldX = baseX + localX;
|
int worldX = baseX + localX;
|
||||||
for (int localZ = 0; localZ < CHUNK_SIZE; localZ++) {
|
for (int localZ = 0; localZ < CHUNK_SIZE; localZ++) {
|
||||||
@@ -375,6 +442,10 @@ public class MantleCarvingComponent extends IrisMantleComponent {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (cachedChunkHeights != null) {
|
||||||
|
surfaceHeights[columnIndex] = (int) Math.round(cachedChunkHeights[columnIndex]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
surfaceHeights[columnIndex] = getEngineMantle().getEngine().getHeight(worldX, worldZ);
|
surfaceHeights[columnIndex] = getEngineMantle().getEngine().getHeight(worldX, worldZ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -510,6 +581,11 @@ public class MantleCarvingComponent extends IrisMantleComponent {
|
|||||||
private final IdentityHashMap<IrisCaveProfile, double[]> columnProfileWeights = new IdentityHashMap<>();
|
private final IdentityHashMap<IrisCaveProfile, double[]> columnProfileWeights = new IdentityHashMap<>();
|
||||||
private final IdentityHashMap<IrisDimensionCarvingEntry, IrisDimensionCarvingEntry[]> dimensionColumnPlans = new IdentityHashMap<>();
|
private final IdentityHashMap<IrisDimensionCarvingEntry, IrisDimensionCarvingEntry[]> dimensionColumnPlans = new IdentityHashMap<>();
|
||||||
private final IdentityHashMap<IrisCaveProfile, Boolean> activeProfiles = new IdentityHashMap<>();
|
private final IdentityHashMap<IrisCaveProfile, Boolean> activeProfiles = new IdentityHashMap<>();
|
||||||
|
private final double[] fieldSurfaceHeights = new double[FIELD_SIZE * FIELD_SIZE];
|
||||||
|
private final IrisRegion[] fieldRegions = new IrisRegion[FIELD_SIZE * FIELD_SIZE];
|
||||||
|
private final IrisBiome[] fieldSurfaceBiomes = new IrisBiome[FIELD_SIZE * FIELD_SIZE];
|
||||||
|
private final IrisBiome[] fieldCaveBiomes = new IrisBiome[FIELD_SIZE * FIELD_SIZE];
|
||||||
private final int[] chunkSurfaceHeights = new int[CHUNK_AREA];
|
private final int[] chunkSurfaceHeights = new int[CHUNK_AREA];
|
||||||
|
private final double[] chunkSurfaceHeightSamples = new double[CHUNK_AREA];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-1
@@ -9,7 +9,7 @@ import art.arcane.iris.util.project.stream.ProceduralStream;
|
|||||||
import art.arcane.volmlib.util.cache.WorldCache2DDouble;
|
import art.arcane.volmlib.util.cache.WorldCache2DDouble;
|
||||||
import art.arcane.volmlib.util.data.KCache;
|
import art.arcane.volmlib.util.data.KCache;
|
||||||
|
|
||||||
public class CachedDoubleStream2D extends BasicStream<Double> implements ProceduralStream<Double>, MeteredCache, ChunkFillableStream2D {
|
public class CachedDoubleStream2D extends BasicStream<Double> implements ProceduralStream<Double>, MeteredCache, ChunkFillableStream2D, ChunkFillableDoubleStream2D {
|
||||||
private final ProceduralStream<Double> stream;
|
private final ProceduralStream<Double> stream;
|
||||||
private final WorldCache2DDouble cache;
|
private final WorldCache2DDouble cache;
|
||||||
private final Engine engine;
|
private final Engine engine;
|
||||||
@@ -73,4 +73,11 @@ public class CachedDoubleStream2D extends BasicStream<Double> implements Procedu
|
|||||||
int chunkZ = worldZ >> 4;
|
int chunkZ = worldZ >> 4;
|
||||||
cache.fillChunk(chunkX, chunkZ, target);
|
cache.fillChunk(chunkX, chunkZ, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fillChunkDoubles(int worldX, int worldZ, double[] target) {
|
||||||
|
int chunkX = worldX >> 4;
|
||||||
|
int chunkZ = worldZ >> 4;
|
||||||
|
cache.fillChunk(chunkX, chunkZ, target);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package art.arcane.iris.util.project.stream.utility;
|
||||||
|
|
||||||
|
public interface ChunkFillableDoubleStream2D {
|
||||||
|
void fillChunkDoubles(int worldX, int worldZ, double[] target);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package art.arcane.iris.engine.framework;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class EngineModeMaintenanceTest {
|
||||||
|
@Test
|
||||||
|
public void maintenanceDisablesContextCacheWithoutActivePregen() {
|
||||||
|
assertTrue(EngineMode.shouldDisableContextCacheForMaintenance(true, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void maintenanceKeepsContextCacheForActivePregenWorld() {
|
||||||
|
assertFalse(EngineMode.shouldDisableContextCacheForMaintenance(true, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void noMaintenanceKeepsContextCacheEnabled() {
|
||||||
|
assertFalse(EngineMode.shouldDisableContextCacheForMaintenance(false, false));
|
||||||
|
assertFalse(EngineMode.shouldDisableContextCacheForMaintenance(false, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user