Voxel-Backen: Tunnel- und Höhlen-Support
Tunnel-Spalten werden im Gradientenschreiben jetzt vollständig geschützt: Pre-Scan erkennt echte Tunnel (void ≥ Terrain-Höhe mit festem Voxel darüber) und überspringt dann sämtliche negativen Zellen in dieser Spalte – auch unter-terrain-liegende. Damit erzeugt MC keinen Plateau-Boden mehr am Tunnel-Eingang. Terrain-Übergang-Extrapolation bekommt zusätzlich einen hasVoidBelow-Check: existieren leere Zellen unterhalb von yBot im geblurrten Chunk, wird die Extrapolation übersprungen, statt den Hohlraum zuzuschütten. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -597,6 +597,11 @@ public class VoxelEditorState extends BaseAppState {
|
||||
return (h & 0x7FFFFFFF) / (float) 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
/** Gibt eine Momentaufnahme aller aktuell geladenen Chunks zurück (thread-safe). */
|
||||
public List<VoxelChunk> getChunksSnapshot() {
|
||||
return new java.util.ArrayList<>(chunks.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert alle dirty Chunks synchron.
|
||||
* Kann von außen aufgerufen werden (z.B. beim globalen Speichern).
|
||||
@@ -2476,20 +2481,45 @@ public class VoxelEditorState extends BaseAppState {
|
||||
Float smoothH = smoothMap.get(hk0);
|
||||
if (h0 == null || smoothH == null) continue;
|
||||
|
||||
// Wichtig: colX ist chunk-global (cx*CELLS+bx), kein World-X.
|
||||
// World-X = colX - 2048 (VoxelChunk.toWorldX-Konvention).
|
||||
float th = terrainH((float)(colX - 2048), (float)(colZ - 2048));
|
||||
|
||||
// Pre-Scan: hat diese Spalte einen echten Tunnel?
|
||||
// (negative Zelle auf/über Terrain-Höhe mit festem Voxel darüber)
|
||||
// Tunnel-Spalten bekommen gar keinen positiven Gradienten in
|
||||
// negative Zellen – weder Tunnel-Void noch Unter-Terrain-Cells –
|
||||
// damit kein Plateau auf dem Tunnelboden entsteht.
|
||||
boolean hasTunnelVoid = false;
|
||||
outer:
|
||||
for (int ly = 0; ly < blurN; ly++) {
|
||||
if ((wiyBase + ly) >= th
|
||||
&& origChunk.getDensity(bx, ly, bz) < 0) {
|
||||
for (int ly2 = ly + 1; ly2 < blurN; ly2++) {
|
||||
if (origChunk.getDensity(bx, ly2, bz) > 0) {
|
||||
hasTunnelVoid = true; break outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sub-voxel-genauen Dichte-Gradienten schreiben, damit MC die
|
||||
// Isofläche auf die exakte smoothH-Höhe interpoliert.
|
||||
// Ausnahme: manuell ausgegrabene Voxel (Tunnel/Höhlen) behalten
|
||||
// ihren MIN_VALUE – erkennbar daran dass Gradient solid will (d>0)
|
||||
// aber die Original-Dichte bereits Luft ist (MIN_VALUE).
|
||||
for (int by = 0; by < blurN; by++) {
|
||||
float d = (smoothH - (wiyBase + by)) * 127f;
|
||||
// Tunnel/Höhlen-Voxel schützen: Gradient will Solid (d>0),
|
||||
// aber der Voxel wurde ausgegraben (Dichte negativ) →
|
||||
// nicht mit Solid-Gradient überschreiben.
|
||||
// Gilt sowohl für Byte.MIN_VALUE (setDensity) als auch für
|
||||
// partiell-reduzierte Werte (reduceDensity im Cave-Modus).
|
||||
float worldY = wiyBase + by;
|
||||
float d = (smoothH - worldY) * 127f;
|
||||
if (d > 0f && origChunk.getDensity(bx, by, bz) < 0) {
|
||||
continue;
|
||||
if (hasTunnelVoid) continue; // Tunnel-Spalte: alle negativen Zellen schützen
|
||||
if (worldY >= th) {
|
||||
// Über Terrain, kein Tunnel-Flag → offene Höhle prüfen
|
||||
boolean solidAbove = false;
|
||||
for (int ly = by + 1; ly < blurN; ly++) {
|
||||
if (origChunk.getDensity(bx, ly, bz) > 0) {
|
||||
solidAbove = true; break;
|
||||
}
|
||||
}
|
||||
if (solidAbove) continue;
|
||||
}
|
||||
}
|
||||
next[c.idx(bx, by, bz)] = Math.max(-128f, Math.min(127f, d));
|
||||
}
|
||||
@@ -2604,6 +2634,15 @@ public class VoxelEditorState extends BaseAppState {
|
||||
}
|
||||
if (hasVoid) continue;
|
||||
|
||||
// Tunnel-Check: gibt es negative (leere) Zellen UNTERHALB von yBot?
|
||||
// Das passiert bei Tunneln/Höhlen, deren Decke yBot ist, aber das
|
||||
// Innere darunter liegt. Extrapolation würde den Hohlraum zuschütten.
|
||||
boolean hasVoidBelow = false;
|
||||
for (int ly = 0; ly < yBot; ly++) {
|
||||
if (blurred.getDensity(lx, ly, lz) < 0) { hasVoidBelow = true; break; }
|
||||
}
|
||||
if (hasVoidBelow) continue;
|
||||
|
||||
// Steigung aus den zwei Voxeln darüber bestimmen.
|
||||
// slope < 0: Dichte nimmt nach unten ab (typisch für eine Oberfläche).
|
||||
float d1 = blurred.getDensity(lx, yBot + 1, lz);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
blight-map/src/main/map/chunks/voxel_17_0_08_baked_lod2.j3o
Normal file
BIN
blight-map/src/main/map/chunks/voxel_17_0_08_baked_lod2.j3o
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
blight-map/src/main/map/chunks/voxel_18_0_10.blvc.prebake
Normal file
BIN
blight-map/src/main/map/chunks/voxel_18_0_10.blvc.prebake
Normal file
Binary file not shown.
BIN
blight-map/src/main/map/chunks/voxel_18_0_10_baked_lod0.j3o
Normal file
BIN
blight-map/src/main/map/chunks/voxel_18_0_10_baked_lod0.j3o
Normal file
Binary file not shown.
BIN
blight-map/src/main/map/chunks/voxel_18_0_10_baked_lod1.j3o
Normal file
BIN
blight-map/src/main/map/chunks/voxel_18_0_10_baked_lod1.j3o
Normal file
Binary file not shown.
BIN
blight-map/src/main/map/chunks/voxel_18_0_10_baked_lod2.j3o
Normal file
BIN
blight-map/src/main/map/chunks/voxel_18_0_10_baked_lod2.j3o
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
blight-map/src/main/map/chunks/voxel_18_m1_09_baked_lod0.j3o
Normal file
BIN
blight-map/src/main/map/chunks/voxel_18_m1_09_baked_lod0.j3o
Normal file
Binary file not shown.
BIN
blight-map/src/main/map/chunks/voxel_18_m1_09_baked_lod1.j3o
Normal file
BIN
blight-map/src/main/map/chunks/voxel_18_m1_09_baked_lod1.j3o
Normal file
Binary file not shown.
BIN
blight-map/src/main/map/chunks/voxel_18_m1_09_baked_lod2.j3o
Normal file
BIN
blight-map/src/main/map/chunks/voxel_18_m1_09_baked_lod2.j3o
Normal file
Binary file not shown.
BIN
blight-map/src/main/map/chunks/voxel_18_m1_10.blvc.prebake
Normal file
BIN
blight-map/src/main/map/chunks/voxel_18_m1_10.blvc.prebake
Normal file
Binary file not shown.
BIN
blight-map/src/main/map/chunks/voxel_18_m1_10_baked_lod0.j3o
Normal file
BIN
blight-map/src/main/map/chunks/voxel_18_m1_10_baked_lod0.j3o
Normal file
Binary file not shown.
BIN
blight-map/src/main/map/chunks/voxel_18_m1_10_baked_lod1.j3o
Normal file
BIN
blight-map/src/main/map/chunks/voxel_18_m1_10_baked_lod1.j3o
Normal file
Binary file not shown.
BIN
blight-map/src/main/map/chunks/voxel_18_m1_10_baked_lod2.j3o
Normal file
BIN
blight-map/src/main/map/chunks/voxel_18_m1_10_baked_lod2.j3o
Normal file
Binary file not shown.
BIN
blight-map/src/main/map/chunks/voxel_19_0_09.blvc
Normal file
BIN
blight-map/src/main/map/chunks/voxel_19_0_09.blvc
Normal file
Binary file not shown.
BIN
blight-map/src/main/map/chunks/voxel_19_0_10.blvc
Normal file
BIN
blight-map/src/main/map/chunks/voxel_19_0_10.blvc
Normal file
Binary file not shown.
BIN
blight-map/src/main/map/chunks/voxel_19_m1_09.blvc
Normal file
BIN
blight-map/src/main/map/chunks/voxel_19_m1_09.blvc
Normal file
Binary file not shown.
BIN
blight-map/src/main/map/chunks/voxel_19_m1_10.blvc
Normal file
BIN
blight-map/src/main/map/chunks/voxel_19_m1_10.blvc
Normal file
Binary file not shown.
Reference in New Issue
Block a user