Voxel Umstellung vollendet
This commit is contained in:
@@ -74,73 +74,10 @@ public final class VoxelChunkIO {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Pre-Bake-Backups ──────────────────────────────────────────────────────
|
|
||||||
|
|
||||||
/** Backup-Pfad der .blvc-Datei (wird vor dem Bake angelegt). */
|
|
||||||
public static Path getPreBakePath(int cx, int cy, int cz) {
|
|
||||||
return getPath(cx, cy, cz).resolveSibling(
|
|
||||||
getPath(cx, cy, cz).getFileName() + ".prebake");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean preBakeExists(int cx, int cy, int cz) {
|
|
||||||
return Files.exists(getPreBakePath(cx, cy, cz));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Kopiert die aktuelle .blvc-Datei als Pre-Bake-Backup. */
|
|
||||||
public static void savePreBake(int cx, int cy, int cz) throws IOException {
|
|
||||||
Path src = getPath(cx, cy, cz);
|
|
||||||
if (!Files.exists(src)) return;
|
|
||||||
Files.copy(src, getPreBakePath(cx, cy, cz), StandardCopyOption.REPLACE_EXISTING);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void deletePreBake(int cx, int cy, int cz) throws IOException {
|
|
||||||
Files.deleteIfExists(getPreBakePath(cx, cy, cz));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Stellt die .blvc-Datei aus dem Backup wieder her. */
|
|
||||||
public static void restorePreBake(int cx, int cy, int cz) throws IOException {
|
|
||||||
Path backup = getPreBakePath(cx, cy, cz);
|
|
||||||
if (!Files.exists(backup)) return;
|
|
||||||
Files.copy(backup, getPath(cx, cy, cz), StandardCopyOption.REPLACE_EXISTING);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** true wenn mindestens ein Pre-Bake-Backup im Chunks-Verzeichnis existiert. */
|
|
||||||
public static boolean hasAnyPreBake() {
|
|
||||||
Path dir = ChunkTerrainIO.chunksDir();
|
|
||||||
if (!Files.isDirectory(dir)) return false;
|
|
||||||
try (DirectoryStream<Path> ds = Files.newDirectoryStream(dir, "voxel_*.blvc.prebake")) {
|
|
||||||
return ds.iterator().hasNext();
|
|
||||||
} catch (IOException e) { return false; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Alle Chunk-Koordinaten für die ein Pre-Bake-Backup existiert. */
|
|
||||||
public static List<int[]> listPreBakeCoords() {
|
|
||||||
List<int[]> result = new java.util.ArrayList<>();
|
|
||||||
Path dir = ChunkTerrainIO.chunksDir();
|
|
||||||
if (!Files.isDirectory(dir)) return result;
|
|
||||||
try (DirectoryStream<Path> ds = Files.newDirectoryStream(dir, "voxel_*.blvc.prebake")) {
|
|
||||||
for (Path p : ds) {
|
|
||||||
String name = p.getFileName().toString()
|
|
||||||
.replace("voxel_", "").replace(".blvc.prebake", "");
|
|
||||||
String[] parts = name.split("_");
|
|
||||||
if (parts.length != 3) continue;
|
|
||||||
try {
|
|
||||||
int cx = Integer.parseInt(parts[0]);
|
|
||||||
int cy = parts[1].startsWith("m")
|
|
||||||
? -Integer.parseInt(parts[1].substring(1))
|
|
||||||
: Integer.parseInt(parts[1]);
|
|
||||||
int cz = Integer.parseInt(parts[2]);
|
|
||||||
result.add(new int[]{cx, cy, cz});
|
|
||||||
} catch (NumberFormatException ignored) {}
|
|
||||||
}
|
|
||||||
} catch (IOException ignored) {}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Liest alle vorhandenen VoxelChunks aus dem Chunks-Verzeichnis.
|
* Liest alle vorhandenen VoxelChunks aus dem Chunks-Verzeichnis.
|
||||||
* Für Koordinaten, bei denen die .blvc nach dem Backen gelöscht wurde,
|
* Vorhandene .blvc.prebake-Dateien (Altbestand) werden einmalig als .blvc migriert
|
||||||
* wird automatisch die .blvc.prebake als Fallback herangezogen.
|
* und danach gelöscht.
|
||||||
* Gibt leere Liste zurück wenn kein Chunks-Verzeichnis existiert.
|
* Gibt leere Liste zurück wenn kein Chunks-Verzeichnis existiert.
|
||||||
*/
|
*/
|
||||||
public static List<VoxelChunk> loadAll() {
|
public static List<VoxelChunk> loadAll() {
|
||||||
@@ -148,7 +85,6 @@ public final class VoxelChunkIO {
|
|||||||
Path dir = ChunkTerrainIO.chunksDir();
|
Path dir = ChunkTerrainIO.chunksDir();
|
||||||
if (!Files.isDirectory(dir)) return result;
|
if (!Files.isDirectory(dir)) return result;
|
||||||
|
|
||||||
// Aktive .blvc-Dateien einlesen
|
|
||||||
Set<String> loaded = new java.util.HashSet<>();
|
Set<String> loaded = new java.util.HashSet<>();
|
||||||
try (DirectoryStream<Path> ds = Files.newDirectoryStream(dir, "voxel_*.blvc")) {
|
try (DirectoryStream<Path> ds = Files.newDirectoryStream(dir, "voxel_*.blvc")) {
|
||||||
for (Path p : ds) {
|
for (Path p : ds) {
|
||||||
@@ -168,12 +104,17 @@ public final class VoxelChunkIO {
|
|||||||
}
|
}
|
||||||
} catch (IOException ignored) {}
|
} catch (IOException ignored) {}
|
||||||
|
|
||||||
// Prebake-Fallback: Koordinaten die gebacken wurden haben keine .blvc mehr
|
// Einmalige Migration: .blvc.prebake → .blvc für Altbestand ohne aktive .blvc.
|
||||||
|
// Erst kopieren, dann löschen – umgekehrte Reihenfolge würde Daten vernichten.
|
||||||
|
List<Path> prebakeToDelete = new java.util.ArrayList<>();
|
||||||
try (DirectoryStream<Path> ds = Files.newDirectoryStream(dir, "voxel_*.blvc.prebake")) {
|
try (DirectoryStream<Path> ds = Files.newDirectoryStream(dir, "voxel_*.blvc.prebake")) {
|
||||||
for (Path p : ds) {
|
for (Path p : ds) {
|
||||||
String name = p.getFileName().toString()
|
String name = p.getFileName().toString()
|
||||||
.replace("voxel_", "").replace(".blvc.prebake", "");
|
.replace("voxel_", "").replace(".blvc.prebake", "");
|
||||||
if (loaded.contains(name)) continue; // aktive .blvc hat Vorrang
|
if (loaded.contains(name)) {
|
||||||
|
prebakeToDelete.add(p); // .blvc existiert bereits → nur löschen
|
||||||
|
continue;
|
||||||
|
}
|
||||||
String[] parts = name.split("_");
|
String[] parts = name.split("_");
|
||||||
if (parts.length != 3) continue;
|
if (parts.length != 3) continue;
|
||||||
try {
|
try {
|
||||||
@@ -182,10 +123,15 @@ public final class VoxelChunkIO {
|
|||||||
? -Integer.parseInt(parts[1].substring(1))
|
? -Integer.parseInt(parts[1].substring(1))
|
||||||
: Integer.parseInt(parts[1]);
|
: Integer.parseInt(parts[1]);
|
||||||
int cz = Integer.parseInt(parts[2]);
|
int cz = Integer.parseInt(parts[2]);
|
||||||
result.add(VoxelChunk.deserialize(Files.readAllBytes(p), cx, cy, cz));
|
Path blvc = getPath(cx, cy, cz);
|
||||||
|
Files.copy(p, blvc, StandardCopyOption.REPLACE_EXISTING); // erst kopieren
|
||||||
|
result.add(VoxelChunk.deserialize(Files.readAllBytes(blvc), cx, cy, cz));
|
||||||
|
loaded.add(name);
|
||||||
|
prebakeToDelete.add(p); // dann löschen
|
||||||
} catch (Exception ignored) {}
|
} catch (Exception ignored) {}
|
||||||
}
|
}
|
||||||
} catch (IOException ignored) {}
|
} catch (IOException ignored) {}
|
||||||
|
for (Path p : prebakeToDelete) { try { Files.deleteIfExists(p); } catch (IOException ignored) {} }
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -399,7 +399,7 @@ public class VoxelEditorState extends BaseAppState {
|
|||||||
// Verwaiste gebackene .j3o ohne zugehörige .blvc löschen
|
// Verwaiste gebackene .j3o ohne zugehörige .blvc löschen
|
||||||
for (int[] cxyz : SculptedMeshIO.findAllBakedChunks()) {
|
for (int[] cxyz : SculptedMeshIO.findAllBakedChunks()) {
|
||||||
int cx = cxyz[0], cy = cxyz[1], cz = cxyz[2];
|
int cx = cxyz[0], cy = cxyz[1], cz = cxyz[2];
|
||||||
if (!VoxelChunkIO.exists(cx, cy, cz) && !VoxelChunkIO.preBakeExists(cx, cy, cz)) {
|
if (!VoxelChunkIO.exists(cx, cy, cz)) {
|
||||||
for (int lod = 0; lod <= 3; lod++) {
|
for (int lod = 0; lod <= 3; lod++) {
|
||||||
try { Files.deleteIfExists(VoxelChunkIO.getBakedPath(cx, cy, cz, lod)); } catch (Exception ignored) {}
|
try { Files.deleteIfExists(VoxelChunkIO.getBakedPath(cx, cy, cz, lod)); } catch (Exception ignored) {}
|
||||||
}
|
}
|
||||||
@@ -422,7 +422,9 @@ public class VoxelEditorState extends BaseAppState {
|
|||||||
if (input.markAllChunksDirtyRequested) {
|
if (input.markAllChunksDirtyRequested) {
|
||||||
input.markAllChunksDirtyRequested = false;
|
input.markAllChunksDirtyRequested = false;
|
||||||
for (long key : chunks.keySet()) sessionDirtyChunks.add(key);
|
for (long key : chunks.keySet()) sessionDirtyChunks.add(key);
|
||||||
// Chunks die noch nicht geladen sind von Disk nachladen, damit der Bake sie kennt
|
// Sofort aktualisieren damit der Bake-on-Exit-Guard den neuen Wert sieht
|
||||||
|
input.sessionDirtyVoxelCount = sessionDirtyChunks.size();
|
||||||
|
// Chunks die noch nicht geladen sind von Disk nachladen, damit der Bake-on-Exit sie kennt
|
||||||
executor.submit(() -> {
|
executor.submit(() -> {
|
||||||
List<VoxelChunk> allDisk = VoxelChunkIO.loadAll();
|
List<VoxelChunk> allDisk = VoxelChunkIO.loadAll();
|
||||||
app.enqueue(() -> {
|
app.enqueue(() -> {
|
||||||
@@ -431,7 +433,22 @@ public class VoxelEditorState extends BaseAppState {
|
|||||||
if (!chunks.containsKey(key)) chunks.put(key, c);
|
if (!chunks.containsKey(key)) chunks.put(key, c);
|
||||||
sessionDirtyChunks.add(key);
|
sessionDirtyChunks.add(key);
|
||||||
}
|
}
|
||||||
|
// Leere Chunks: .blvc löschen (kein Mesh zu backen, kein Speicherbedarf)
|
||||||
|
List<Long> emptyKeys = new ArrayList<>();
|
||||||
|
for (long key : sessionDirtyChunks) {
|
||||||
|
VoxelChunk c = chunks.get(key);
|
||||||
|
if (c != null && c.isEmpty()) emptyKeys.add(key);
|
||||||
|
}
|
||||||
|
for (long key : emptyKeys) {
|
||||||
|
VoxelChunk c = chunks.remove(key);
|
||||||
|
sessionDirtyChunks.remove(key);
|
||||||
|
VoxelChunkNode node = nodes.remove(key);
|
||||||
|
if (node != null) node.removeFromParent();
|
||||||
|
try { VoxelChunkIO.delete(c.cx, c.cy, c.cz); } catch (Exception ignored) {}
|
||||||
|
}
|
||||||
input.sessionDirtyVoxelCount = sessionDirtyChunks.size();
|
input.sessionDirtyVoxelCount = sessionDirtyChunks.size();
|
||||||
|
log.info("Alle-dirty: {} Chunks geladen, {} leer gelöscht, {} dirty für Bake-on-Exit",
|
||||||
|
allDisk.size(), emptyKeys.size(), sessionDirtyChunks.size());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1970,20 +1987,27 @@ public class VoxelEditorState extends BaseAppState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bakeAll(List<VoxelChunk> toProcess) {
|
/** Gibt die Anzahl erfolgreich gebackener Chunks zurück (0 wenn nichts zu tun). */
|
||||||
|
private int bakeAll(List<VoxelChunk> toProcess) {
|
||||||
saveAll();
|
saveAll();
|
||||||
|
log.info("bakeAll: {} Chunks übergeben", toProcess.size());
|
||||||
List<VoxelChunk> nonEmpty = new java.util.ArrayList<>();
|
List<VoxelChunk> nonEmpty = new java.util.ArrayList<>();
|
||||||
for (VoxelChunk c : toProcess) { if (!c.isEmpty()) nonEmpty.add(c); }
|
for (VoxelChunk c : toProcess) { if (!c.isEmpty()) nonEmpty.add(c); }
|
||||||
|
log.info("bakeAll: nach isEmpty-Filter: {} verbleiben", nonEmpty.size());
|
||||||
|
|
||||||
// Chunks ohne .blvc-Datei überspringen (noch nie gespeichert).
|
// Chunks ohne .blvc-Datei überspringen (noch nie gespeichert).
|
||||||
nonEmpty.removeIf(c -> !VoxelChunkIO.exists(c.cx, c.cy, c.cz));
|
nonEmpty.removeIf(c -> !VoxelChunkIO.exists(c.cx, c.cy, c.cz));
|
||||||
|
log.info("bakeAll: nach exists-Filter: {} verbleiben", nonEmpty.size());
|
||||||
// Chunks ohne nennenswerte Geometrie überspringen (nur Brush-Randberührungen,
|
// Chunks ohne nennenswerte Geometrie überspringen (nur Brush-Randberührungen,
|
||||||
// solidYSpan < 2 → gleiche Schwelle wie der Game-Loader).
|
// solidYSpan < 2 → gleiche Schwelle wie der Game-Loader).
|
||||||
nonEmpty.removeIf(c -> c.solidYSpan() < 2);
|
nonEmpty.removeIf(c -> c.solidYSpan() < 2);
|
||||||
|
log.info("bakeAll: nach solidYSpan-Filter: {} verbleiben (→ diese werden gebacken)", nonEmpty.size());
|
||||||
|
|
||||||
if (nonEmpty.isEmpty()) {
|
if (nonEmpty.isEmpty()) {
|
||||||
input.bakeStatusMsg = "Nichts zu backen (keine nicht-leeren Chunks).";
|
input.bakeStatusMsg = "Nichts zu backen (keine nicht-leeren Chunks).";
|
||||||
return;
|
log.warn("bakeAll: kein Chunk überlebt alle Filter – übergebene Chunks: {}",
|
||||||
|
toProcess.stream().map(c -> c.cx+","+c.cy+","+c.cz).toList());
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bakeTotal sofort setzen, damit die Fortschrittsanzeige schon während des Blurs läuft
|
// bakeTotal sofort setzen, damit die Fortschrittsanzeige schon während des Blurs läuft
|
||||||
@@ -2236,8 +2260,12 @@ public class VoxelEditorState extends BaseAppState {
|
|||||||
// gebackene Terrain systematisch zu hoch machen.
|
// gebackene Terrain systematisch zu hoch machen.
|
||||||
smoothH = h0;
|
smoothH = h0;
|
||||||
} else {
|
} else {
|
||||||
float dDown = dDownRaw - 1;
|
// dDown = dDownRaw (kein -1): auch unmittelbar angrenzende Stufen
|
||||||
smoothH = (dDown <= 0f) ? h0 : (h0 * dUp + hUp * dDown) / (dUp + dDown);
|
// (dDownRaw=1) bekommen eine interpolierte Höhe statt h0 zurück.
|
||||||
|
// Die frühere "Trailing-Edge-Korrektur" (dDownRaw-1) ließ genau die
|
||||||
|
// Kanten-Spalten unberührt, die am meisten abfallen müssten.
|
||||||
|
float dDown = (float) dDownRaw;
|
||||||
|
smoothH = (h0 * dUp + hUp * dDown) / (dUp + dDown);
|
||||||
}
|
}
|
||||||
smoothMap.put(hk0, smoothH);
|
smoothMap.put(hk0, smoothH);
|
||||||
}
|
}
|
||||||
@@ -2291,7 +2319,9 @@ public class VoxelEditorState extends BaseAppState {
|
|||||||
final float RAMP_RATIO = 4.0f;
|
final float RAMP_RATIO = 4.0f;
|
||||||
final int MAX_RAMP_R = 20;
|
final int MAX_RAMP_R = 20;
|
||||||
final int MAX_RAMP_R_TERRAIN = 4;
|
final int MAX_RAMP_R_TERRAIN = 4;
|
||||||
final float MAX_TERRAIN_DIFF = 1.0f;
|
// Erhöht von 1.0 auf 3.0: unterste Voxel-Schicht liegt oft 2–3 m über dem
|
||||||
|
// Basisterrain – mit 1.0 wurde sie komplett übersprungen → senkrechte Klippe.
|
||||||
|
final float MAX_TERRAIN_DIFF = 3.0f;
|
||||||
final float MAX_VOXEL_DIFF = 1.05f;
|
final float MAX_VOXEL_DIFF = 1.05f;
|
||||||
|
|
||||||
Map<Long, Float> terrainCache2b = new HashMap<>();
|
Map<Long, Float> terrainCache2b = new HashMap<>();
|
||||||
@@ -2308,6 +2338,12 @@ public class VoxelEditorState extends BaseAppState {
|
|||||||
int colX2b = (int)(hk0 / 60001L) - 30000;
|
int colX2b = (int)(hk0 / 60001L) - 30000;
|
||||||
int colZ2b = (int)(hk0 % 60001L) - 30000;
|
int colZ2b = (int)(hk0 % 60001L) - 30000;
|
||||||
|
|
||||||
|
// Schritt 2 hat diese Spalte bereits auf eine Rampe gesetzt → Pass A
|
||||||
|
// nicht überschreiben, sonst entsteht ein Konflikt (Schritt-2-Steigung
|
||||||
|
// vs. terrain-basierter Rampenwert). Pass A nur für Spalten die Schritt 2
|
||||||
|
// unberührt gelassen hat (smoothH ≈ h0raw = Plateau oder unterste Schicht).
|
||||||
|
if (Math.abs(h0sm - h0raw) > 0.1f) continue;
|
||||||
|
|
||||||
float minRampH = h0sm;
|
float minRampH = h0sm;
|
||||||
float minRaiseH = Float.POSITIVE_INFINITY;
|
float minRaiseH = Float.POSITIVE_INFINITY;
|
||||||
float passA_maxThAbove = Float.NEGATIVE_INFINITY;
|
float passA_maxThAbove = Float.NEGATIVE_INFINITY;
|
||||||
@@ -2392,7 +2428,9 @@ public class VoxelEditorState extends BaseAppState {
|
|||||||
for (Map.Entry<Long, Float> entry : hfMap.entrySet()) {
|
for (Map.Entry<Long, Float> entry : hfMap.entrySet()) {
|
||||||
long hk0 = entry.getKey();
|
long hk0 = entry.getKey();
|
||||||
float h0raw = entry.getValue();
|
float h0raw = entry.getValue();
|
||||||
if (h0raw > 4.25f) continue;
|
// Kein Höhen-Cutoff hier – Pass B muss für alle Voxel-Säulen laufen.
|
||||||
|
// Der frühere "h0raw > 4.25f"-Guard hat Pass B für praktisch alle
|
||||||
|
// Terrain-Voxel (Welt-Y >> 4) komplett deaktiviert.
|
||||||
float h0sm = smoothMap.getOrDefault(hk0, h0raw);
|
float h0sm = smoothMap.getOrDefault(hk0, h0raw);
|
||||||
int colX2b = (int)(hk0 / 60001L) - 30000;
|
int colX2b = (int)(hk0 / 60001L) - 30000;
|
||||||
int colZ2b = (int)(hk0 % 60001L) - 30000;
|
int colZ2b = (int)(hk0 % 60001L) - 30000;
|
||||||
@@ -2717,14 +2755,11 @@ public class VoxelEditorState extends BaseAppState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pre-Bake-Backup anlegen (ermöglicht Revert nach dem Bake).
|
// .blvc sicherstellen bevor der Bake läuft (falls Auto-Save noch nicht lief)
|
||||||
// Wichtig: zuerst .blvc auf Disk speichern, falls Auto-Save noch nicht gelaufen ist,
|
|
||||||
// damit savePreBake() etwas zum Kopieren hat.
|
|
||||||
for (VoxelChunk chunk : nonEmpty) {
|
for (VoxelChunk chunk : nonEmpty) {
|
||||||
try {
|
try {
|
||||||
VoxelChunkIO.save(chunk);
|
VoxelChunkIO.save(chunk);
|
||||||
VoxelChunkIO.savePreBake(chunk.cx, chunk.cy, chunk.cz);
|
} catch (Exception e) { log.warn("Speichern vor Bake fehlgeschlagen ({},{},{}): {}",
|
||||||
} catch (Exception e) { log.warn("Pre-Bake-Backup fehlgeschlagen ({},{},{}): {}",
|
|
||||||
chunk.cx, chunk.cy, chunk.cz, e.getMessage()); }
|
chunk.cx, chunk.cy, chunk.cz, e.getMessage()); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2760,6 +2795,7 @@ public class VoxelEditorState extends BaseAppState {
|
|||||||
input.bakeStatusMsg = msg;
|
input.bakeStatusMsg = msg;
|
||||||
input.sculptRescanNeeded = true;
|
input.sculptRescanNeeded = true;
|
||||||
log.info("Voxel-Bake abgeschlossen – {}.", msg);
|
log.info("Voxel-Bake abgeschlossen – {}.", msg);
|
||||||
|
return successfullyBaked.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Bäckt einen einzelnen Chunk. Gibt true zurück wenn erfolgreich, false bei Fehler. */
|
/** Bäckt einen einzelnen Chunk. Gibt true zurück wenn erfolgreich, false bei Fehler. */
|
||||||
|
|||||||
@@ -1266,8 +1266,9 @@ public class TerrainPanelController {
|
|||||||
"wird alles neu gebacken – kann je nach Groesse der Karte sehr lange dauern.");
|
"wird alles neu gebacken – kann je nach Groesse der Karte sehr lange dauern.");
|
||||||
rebakeWarning.setStyle("-fx-text-fill: #b05000; -fx-font-size: 10;");
|
rebakeWarning.setStyle("-fx-text-fill: #b05000; -fx-font-size: 10;");
|
||||||
rebakeWarning.setWrapText(true);
|
rebakeWarning.setWrapText(true);
|
||||||
|
// visibleProperty binden – aber NICHT managedProperty: der Label belegt immer
|
||||||
|
// seinen Platz, damit sich das Layout nicht verschiebt und der OK-Button sichtbar bleibt.
|
||||||
rebakeWarning.visibleProperty().bind(cbRebakeAll.selectedProperty());
|
rebakeWarning.visibleProperty().bind(cbRebakeAll.selectedProperty());
|
||||||
rebakeWarning.managedProperty().bind(cbRebakeAll.selectedProperty());
|
|
||||||
|
|
||||||
javafx.scene.layout.VBox content = new javafx.scene.layout.VBox(8,
|
javafx.scene.layout.VBox content = new javafx.scene.layout.VBox(8,
|
||||||
cbUnderground, cbOrphaned,
|
cbUnderground, cbOrphaned,
|
||||||
@@ -1298,7 +1299,7 @@ public class TerrainPanelController {
|
|||||||
|
|
||||||
if (doRebakeAll) {
|
if (doRebakeAll) {
|
||||||
input.markAllChunksDirtyRequested = true;
|
input.markAllChunksDirtyRequested = true;
|
||||||
statusLbl.setText("Alle Chunks als dirty markiert.");
|
statusLbl.setText("Alle Chunks als dirty markiert – Bake beim Tab-Verlassen.");
|
||||||
}
|
}
|
||||||
if (doUnderground || doOrphaned) {
|
if (doUnderground || doOrphaned) {
|
||||||
input.cleanupUndergroundVoxels = doUnderground;
|
input.cleanupUndergroundVoxels = doUnderground;
|
||||||
|
|||||||
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.
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.
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.
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.
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.
Reference in New Issue
Block a user