mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-26 22:10:18 +00:00
Tightened mixed cave cells
- Classify mixed cells without fade, boost or protection through a branch-light column loop - Hoist the per-row bilinear terms shared by every column of a cell row - Mark open cells from the pass bitset when every pass column is active
This commit is contained in:
1 parent
7c4a5e1937
commit
65542be8d6
2 files changed
+57
-7
No files matched your search
@@ -76,6 +76,7 @@ final class CaveCarveScratch {
|
|||||||
final int[] cellBreakFloorMin = new int[4];
|
final int[] cellBreakFloorMin = new int[4];
|
||||||
final int[] cellCeilingFadeStart = new int[4];
|
final int[] cellCeilingFadeStart = new int[4];
|
||||||
final int[] cellTopY = new int[4];
|
final int[] cellTopY = new int[4];
|
||||||
|
final int[] cellMinTopY = new int[4];
|
||||||
final boolean[] cellProtected = new boolean[4];
|
final boolean[] cellProtected = new boolean[4];
|
||||||
final int[] columnProtectStartY = new int[256];
|
final int[] columnProtectStartY = new int[256];
|
||||||
final int[] columnProtectEndY = new int[256];
|
final int[] columnProtectEndY = new int[256];
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ public class IrisCaveCarver3D {
|
|||||||
private static final int[] LATTICE_TILE_OFFSETS = {0, 1, 16, 17};
|
private static final int[] LATTICE_TILE_OFFSETS = {0, 1, 16, 17};
|
||||||
private static final int STANDALONE_DENSITY_GRID_COLUMNS = 1024;
|
private static final int STANDALONE_DENSITY_GRID_COLUMNS = 1024;
|
||||||
private static final int[] CELL_CORNER_MASKS = {0b000011011, 0b000110110, 0b011011000, 0b110110000};
|
private static final int[] CELL_CORNER_MASKS = {0b000011011, 0b000110110, 0b011011000, 0b110110000};
|
||||||
|
private static final long[] CELL_Z_MASKS = {0x00FF00FF00FF00FFL, 0xFF00FF00FF00FF00L};
|
||||||
private static final LongAdder SOLID_CELLS = new LongAdder();
|
private static final LongAdder SOLID_CELLS = new LongAdder();
|
||||||
private static final LongAdder OPEN_CELLS = new LongAdder();
|
private static final LongAdder OPEN_CELLS = new LongAdder();
|
||||||
private static final LongAdder MIXED_CELLS = new LongAdder();
|
private static final LongAdder MIXED_CELLS = new LongAdder();
|
||||||
@@ -1128,6 +1129,7 @@ public class IrisCaveCarver3D {
|
|||||||
Arrays.fill(plan.cellBreakFloorMin, Integer.MAX_VALUE);
|
Arrays.fill(plan.cellBreakFloorMin, Integer.MAX_VALUE);
|
||||||
Arrays.fill(plan.cellCeilingFadeStart, Integer.MAX_VALUE);
|
Arrays.fill(plan.cellCeilingFadeStart, Integer.MAX_VALUE);
|
||||||
Arrays.fill(plan.cellTopY, Integer.MIN_VALUE);
|
Arrays.fill(plan.cellTopY, Integer.MIN_VALUE);
|
||||||
|
Arrays.fill(plan.cellMinTopY, Integer.MAX_VALUE);
|
||||||
Arrays.fill(plan.cellProtected, false);
|
Arrays.fill(plan.cellProtected, false);
|
||||||
prepareAdaptiveGeometry(plan, ADAPTIVE_DEEP_SAMPLE_STEP, 2, 3);
|
prepareAdaptiveGeometry(plan, ADAPTIVE_DEEP_SAMPLE_STEP, 2, 3);
|
||||||
double[] passThreshold = plan.passThreshold;
|
double[] passThreshold = plan.passThreshold;
|
||||||
@@ -1149,6 +1151,7 @@ public class IrisCaveCarver3D {
|
|||||||
plan.cellCeilingFadeStart[cell] = Math.min(plan.cellCeilingFadeStart[cell], top - SURFACE_CEILING_FADE_DEPTH + 1);
|
plan.cellCeilingFadeStart[cell] = Math.min(plan.cellCeilingFadeStart[cell], top - SURFACE_CEILING_FADE_DEPTH + 1);
|
||||||
}
|
}
|
||||||
plan.cellTopY[cell] = Math.max(plan.cellTopY[cell], top);
|
plan.cellTopY[cell] = Math.max(plan.cellTopY[cell], top);
|
||||||
|
plan.cellMinTopY[cell] = Math.min(plan.cellMinTopY[cell], top);
|
||||||
int protectStart = SurfaceFluidBoundaryPlan.NO_BOUNDARY;
|
int protectStart = SurfaceFluidBoundaryPlan.NO_BOUNDARY;
|
||||||
int protectEnd = Integer.MIN_VALUE;
|
int protectEnd = Integer.MIN_VALUE;
|
||||||
if (surfaceFluidBoundaries != null) {
|
if (surfaceFluidBoundaries != null) {
|
||||||
@@ -1389,14 +1392,26 @@ public class IrisCaveCarver3D {
|
|||||||
int decision = CaveCellKernel.decide(d00, d01, d10, d11,
|
int decision = CaveCellKernel.decide(d00, d01, d10, d11,
|
||||||
CaveCellKernel.threshold(low, normalizationFactor, inverseNormalization),
|
CaveCellKernel.threshold(low, normalizationFactor, inverseNormalization),
|
||||||
CaveCellKernel.threshold(high, normalizationFactor, inverseNormalization));
|
CaveCellKernel.threshold(high, normalizationFactor, inverseNormalization));
|
||||||
|
boolean uniform = !plan.cellProtected[cell] && y <= plan.cellMinTopY[cell];
|
||||||
if (decision == CaveCellKernel.NONE) {
|
if (decision == CaveCellKernel.NONE) {
|
||||||
scratch.solidCells++;
|
scratch.solidCells++;
|
||||||
} else if (decision == CaveCellKernel.ALL) {
|
} else if (decision == CaveCellKernel.ALL) {
|
||||||
scratch.openCells++;
|
scratch.openCells++;
|
||||||
markActiveCellColumns(plan, cell, y, rowBits);
|
if (uniform) {
|
||||||
|
int word = (cell >> 1) << 1;
|
||||||
|
long mask = CELL_Z_MASKS[cell & 1];
|
||||||
|
rowBits[word] |= plan.cellPassBits[word] & mask;
|
||||||
|
rowBits[word + 1] |= plan.cellPassBits[word + 1] & mask;
|
||||||
|
} else {
|
||||||
|
markActiveCellColumns(plan, cell, y, rowBits);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
scratch.mixedCells++;
|
scratch.mixedCells++;
|
||||||
classifyMixedCell(plan, cell, y, minY, surfaceBreakThresholdBoost, verticalEdgeFade, d00, d01, d10, d11, rowBits);
|
if (uniform && y < plan.cellCeilingFadeStart[cell] && y < plan.cellBreakFloorMin[cell]) {
|
||||||
|
classifyPlainMixedCell(plan, cell, fade, d00, d01, d10, d11, rowBits);
|
||||||
|
} else {
|
||||||
|
classifyMixedCell(plan, cell, y, minY, surfaceBreakThresholdBoost, verticalEdgeFade, d00, d01, d10, d11, rowBits);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1420,15 +1435,15 @@ public class IrisCaveCarver3D {
|
|||||||
int firstLocalZ = (cell & 1) << 3;
|
int firstLocalZ = (cell & 1) << 3;
|
||||||
for (int localX = firstLocalX; localX < firstLocalX + ADAPTIVE_DEEP_SAMPLE_STEP; localX++) {
|
for (int localX = firstLocalX; localX < firstLocalX + ADAPTIVE_DEEP_SAMPLE_STEP; localX++) {
|
||||||
int rowColumn = PowerOfTwoCoordinates.packLocal16(localX, firstLocalZ);
|
int rowColumn = PowerOfTwoCoordinates.packLocal16(localX, firstLocalZ);
|
||||||
|
double tx = adaptiveTx[rowColumn];
|
||||||
|
double dx0 = d00 + ((d10 - d00) * tx);
|
||||||
|
double dx1 = d01 + ((d11 - d01) * tx);
|
||||||
|
double slope = dx1 - dx0;
|
||||||
for (int column = rowColumn; column < rowColumn + ADAPTIVE_DEEP_SAMPLE_STEP; column++) {
|
for (int column = rowColumn; column < rowColumn + ADAPTIVE_DEEP_SAMPLE_STEP; column++) {
|
||||||
if (!isCellColumnActive(plan, column, y)) {
|
if (!isCellColumnActive(plan, column, y)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
double tx = adaptiveTx[column];
|
double predictedDensity = dx0 + (slope * adaptiveTz[column]);
|
||||||
double tz = adaptiveTz[column];
|
|
||||||
double dx0 = d00 + ((d10 - d00) * tx);
|
|
||||||
double dx1 = d01 + ((d11 - d01) * tx);
|
|
||||||
double predictedDensity = dx0 + ((dx1 - dx0) * tz);
|
|
||||||
if (predictedDensity <= cellThreshold(plan, column, y, minY, surfaceBreakThresholdBoost, verticalEdgeFade)) {
|
if (predictedDensity <= cellThreshold(plan, column, y, minY, surfaceBreakThresholdBoost, verticalEdgeFade)) {
|
||||||
rowBits[column >> 6] |= 1L << column;
|
rowBits[column >> 6] |= 1L << column;
|
||||||
}
|
}
|
||||||
@@ -1436,6 +1451,40 @@ public class IrisCaveCarver3D {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void classifyPlainMixedCell(
|
||||||
|
CaveCarveScratch plan,
|
||||||
|
int cell,
|
||||||
|
double fade,
|
||||||
|
double d00,
|
||||||
|
double d01,
|
||||||
|
double d10,
|
||||||
|
double d11,
|
||||||
|
long[] rowBits
|
||||||
|
) {
|
||||||
|
double[] passThreshold = plan.passThreshold;
|
||||||
|
double[] adaptiveTx = plan.adaptiveTx;
|
||||||
|
double[] adaptiveTz = plan.adaptiveTz;
|
||||||
|
int firstLocalX = (cell >> 1) << 3;
|
||||||
|
int firstLocalZ = (cell & 1) << 3;
|
||||||
|
for (int localX = firstLocalX; localX < firstLocalX + ADAPTIVE_DEEP_SAMPLE_STEP; localX++) {
|
||||||
|
int rowColumn = PowerOfTwoCoordinates.packLocal16(localX, firstLocalZ);
|
||||||
|
double tx = adaptiveTx[rowColumn];
|
||||||
|
double dx0 = d00 + ((d10 - d00) * tx);
|
||||||
|
double dx1 = d01 + ((d11 - d01) * tx);
|
||||||
|
double slope = dx1 - dx0;
|
||||||
|
long bits = 0L;
|
||||||
|
for (int offset = 0; offset < ADAPTIVE_DEEP_SAMPLE_STEP; offset++) {
|
||||||
|
int column = rowColumn + offset;
|
||||||
|
double predictedDensity = dx0 + (slope * adaptiveTz[column]);
|
||||||
|
if (predictedDensity <= CaveCellKernel.threshold(passThreshold[column] - fade, normalizationFactor,
|
||||||
|
inverseNormalization)) {
|
||||||
|
bits |= 1L << offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rowBits[rowColumn >> 6] |= bits << (rowColumn & 63);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void markActiveCellColumns(CaveCarveScratch plan, int cell, int y, long[] rowBits) {
|
private static void markActiveCellColumns(CaveCarveScratch plan, int cell, int y, long[] rowBits) {
|
||||||
int firstLocalX = (cell >> 1) << 3;
|
int firstLocalX = (cell >> 1) << 3;
|
||||||
int firstLocalZ = (cell & 1) << 3;
|
int firstLocalZ = (cell & 1) << 3;
|
||||||
|
|||||||
Reference in new issue
Block a user