Zwischenstand gesichert bei den voxel poxoxeln
This commit is contained in:
@@ -2133,6 +2133,11 @@ public class VoxelEditorState extends BaseAppState {
|
|||||||
|
|
||||||
Map<Long, Float> terrainCache2b = new HashMap<>();
|
Map<Long, Float> terrainCache2b = new HashMap<>();
|
||||||
|
|
||||||
|
// ── Loop 1: Pass A – Basisterrain (LOWER + RAISE) ───────────────────
|
||||||
|
// Muss als eigenständiger Loop VOR Pass B laufen: Pass B liest smoothMap
|
||||||
|
// der Nachbarn. Wären beide Passes im selben Loop, sähe Pass B manchmal
|
||||||
|
// noch den vergrabenen h0raw einer Nachbarzelle, die von PassA-RAISE noch
|
||||||
|
// nicht angehoben wurde (HashMap-Reihenfolge unbestimmt) → Graben.
|
||||||
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();
|
||||||
@@ -2141,15 +2146,9 @@ public class VoxelEditorState extends BaseAppState {
|
|||||||
int colZ2b = (int)(hk0 % 60001L) - 30000;
|
int colZ2b = (int)(hk0 % 60001L) - 30000;
|
||||||
|
|
||||||
float minRampH = h0sm;
|
float minRampH = h0sm;
|
||||||
// Terrain ÜBER dem Voxel: Voxel nach oben auf Terrain-Niveau heben.
|
|
||||||
// Kein +0.1f-Offset an Ring-1 → Ring-1-Oberfläche liegt exakt auf Terrain
|
|
||||||
// (nahtloser Übergang). Innere Ringe steigen per 4:1-Rampe weiter an.
|
|
||||||
float minRaiseH = Float.POSITIVE_INFINITY;
|
float minRaiseH = Float.POSITIVE_INFINITY;
|
||||||
|
float passA_maxThAbove = Float.NEGATIVE_INFINITY;
|
||||||
|
|
||||||
// ── Pass A: Basisterrain ──────────────────────────────────────────
|
|
||||||
// Pro Ring: höchstes qualifizierendes th (maxThAtR) → Abwärts-Kandidat.
|
|
||||||
// Gegenfall: Terrain ÜBER h0sm (maxThAboveAtR) → Aufwärts-Kandidat.
|
|
||||||
float passA_maxThAbove = Float.NEGATIVE_INFINITY; // Terrain ÜBER h0sm (r=1, Diagnose)
|
|
||||||
for (int r = 1; r <= MAX_RAMP_R_TERRAIN; r++) {
|
for (int r = 1; r <= MAX_RAMP_R_TERRAIN; r++) {
|
||||||
float maxThAtR = Float.NEGATIVE_INFINITY;
|
float maxThAtR = Float.NEGATIVE_INFINITY;
|
||||||
float maxThAboveAtR = Float.NEGATIVE_INFINITY;
|
float maxThAboveAtR = Float.NEGATIVE_INFINITY;
|
||||||
@@ -2188,7 +2187,6 @@ public class VoxelEditorState extends BaseAppState {
|
|||||||
minRampH = candidate;
|
minRampH = candidate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Aufwärts-Kandidat: gleiche Formel wie Abwärts (symmetrisch)
|
|
||||||
if (maxThAboveAtR > Float.NEGATIVE_INFINITY) {
|
if (maxThAboveAtR > Float.NEGATIVE_INFINITY) {
|
||||||
float raiseCandidate = maxThAboveAtR + (r - 1) / RAMP_RATIO;
|
float raiseCandidate = maxThAboveAtR + (r - 1) / RAMP_RATIO;
|
||||||
if (raiseCandidate < minRaiseH) {
|
if (raiseCandidate < minRaiseH) {
|
||||||
@@ -2196,7 +2194,6 @@ public class VoxelEditorState extends BaseAppState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Diagnose
|
|
||||||
if (log.isTraceEnabled() && passA_maxThAbove > Float.NEGATIVE_INFINITY
|
if (log.isTraceEnabled() && passA_maxThAbove > Float.NEGATIVE_INFINITY
|
||||||
&& minRampH >= h0sm) {
|
&& minRampH >= h0sm) {
|
||||||
if (minRaiseH < Float.POSITIVE_INFINITY) {
|
if (minRaiseH < Float.POSITIVE_INFINITY) {
|
||||||
@@ -2205,19 +2202,39 @@ public class VoxelEditorState extends BaseAppState {
|
|||||||
colX2b, colZ2b, h0sm, minRaiseH, passA_maxThAbove));
|
colX2b, colZ2b, h0sm, minRaiseH, passA_maxThAbove));
|
||||||
} else {
|
} else {
|
||||||
log.trace(String.format(
|
log.trace(String.format(
|
||||||
"PassA-UNTEN (%d,%d) h0sm=%.3f h0raw=%.3f terrainR1=%.3f – Terrain zu weit oben (>MAX_TERRAIN_DIFF), kein Kandidat",
|
"PassA-UNTEN (%d,%d) h0sm=%.3f h0raw=%.3f terrainR1=%.3f",
|
||||||
colX2b, colZ2b, h0sm, h0raw, passA_maxThAbove));
|
colX2b, colZ2b, h0sm, h0raw, passA_maxThAbove));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (minRampH < h0sm) {
|
||||||
|
if (log.isTraceEnabled()) {
|
||||||
|
log.trace(String.format("Schritt2b-A (%d,%d) h=%.2f → %.2f",
|
||||||
|
colX2b, colZ2b, h0sm, minRampH));
|
||||||
|
}
|
||||||
|
smoothMap.put(hk0, minRampH);
|
||||||
|
} else if (minRaiseH > h0sm && minRaiseH < Float.POSITIVE_INFINITY) {
|
||||||
|
if (log.isTraceEnabled()) {
|
||||||
|
log.trace(String.format("Schritt2b-RAISE (%d,%d) h=%.2f → %.2f",
|
||||||
|
colX2b, colZ2b, h0sm, minRaiseH));
|
||||||
|
}
|
||||||
|
smoothMap.put(hk0, minRaiseH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ── Pass B: Voxel-zu-Voxel ────────────────────────────────────────
|
// ── Loop 2: Pass B – Voxel-zu-Voxel ─────────────────────────────────
|
||||||
// Nur Terrassen-Zellen (h0raw ≤ 4.25m) – Bergterrain wird nicht angefasst.
|
// Liest smoothMap aus Loop 1 → RAISE-Zellen haben ihre angehobene Höhe.
|
||||||
// Pass B als if-Block (kein continue): smoothMap.put() am Ende bleibt für
|
// Effektive Nachbarhöhe: max(raw, smooth).
|
||||||
// Pass-A-Ergebnisse aller Zellen erreichbar.
|
// RAISE-Nachbar (smooth > raw): smooth gewinnt → kein Kandidat unter Terrain.
|
||||||
// Cascade-Schutz: alle Vergleiche ausschließlich mit RAW-Höhen (hN, h0raw),
|
// LOWER-Nachbar (smooth < raw): raw gewinnt → Kaskaden-Schutz bleibt.
|
||||||
// nie mit smoothMap – gerampte Kliffränder behalten raw ihre Originalhöhe
|
for (Map.Entry<Long, Float> entry : hfMap.entrySet()) {
|
||||||
// und werden nicht fälschlicherweise als niedrigere Nachbarn erkannt.
|
long hk0 = entry.getKey();
|
||||||
if (h0raw <= 4.25f) {
|
float h0raw = entry.getValue();
|
||||||
|
if (h0raw > 4.25f) continue;
|
||||||
|
float h0sm = smoothMap.getOrDefault(hk0, h0raw);
|
||||||
|
int colX2b = (int)(hk0 / 60001L) - 30000;
|
||||||
|
int colZ2b = (int)(hk0 % 60001L) - 30000;
|
||||||
|
|
||||||
|
float minRampH = h0sm;
|
||||||
boolean hadAnyLower = false;
|
boolean hadAnyLower = false;
|
||||||
boolean hadNonVoxelR1R3 = false;
|
boolean hadNonVoxelR1R3 = false;
|
||||||
voxelPassB:
|
voxelPassB:
|
||||||
@@ -2227,11 +2244,12 @@ public class VoxelEditorState extends BaseAppState {
|
|||||||
if (Math.max(Math.abs(dx2b), Math.abs(dz2b)) != r) continue;
|
if (Math.max(Math.abs(dx2b), Math.abs(dz2b)) != r) continue;
|
||||||
long hkN = (long)(colX2b + dx2b + 30000) * 60001L
|
long hkN = (long)(colX2b + dx2b + 30000) * 60001L
|
||||||
+ (colZ2b + dz2b + 30000);
|
+ (colZ2b + dz2b + 30000);
|
||||||
Float hN = hfMap.get(hkN);
|
Float hNraw = hfMap.get(hkN);
|
||||||
if (hN == null) {
|
if (hNraw == null) {
|
||||||
if (r <= 3) { hadNonVoxelR1R3 = true; }
|
if (r <= 3) { hadNonVoxelR1R3 = true; }
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
float hN = Math.max(hNraw, smoothMap.getOrDefault(hkN, hNraw));
|
||||||
if (hN >= h0raw) continue;
|
if (hN >= h0raw) continue;
|
||||||
if ((h0raw - hN) >= MAX_VOXEL_DIFF) continue;
|
if ((h0raw - hN) >= MAX_VOXEL_DIFF) continue;
|
||||||
hadAnyLower = true;
|
hadAnyLower = true;
|
||||||
@@ -2242,7 +2260,6 @@ public class VoxelEditorState extends BaseAppState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Nach Ring-3: kein gültiger niedrigerer Voxel + kein Terrain → Plateau-Innenzelle
|
|
||||||
if (r == 3 && !hadAnyLower && !hadNonVoxelR1R3) {
|
if (r == 3 && !hadAnyLower && !hadNonVoxelR1R3) {
|
||||||
break voxelPassB;
|
break voxelPassB;
|
||||||
}
|
}
|
||||||
@@ -2250,21 +2267,12 @@ public class VoxelEditorState extends BaseAppState {
|
|||||||
break voxelPassB;
|
break voxelPassB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (minRampH < h0sm) {
|
if (minRampH < h0sm) {
|
||||||
if (log.isTraceEnabled()) {
|
if (log.isTraceEnabled()) {
|
||||||
log.trace(String.format("Schritt2b (%d,%d) h=%.2f → %.2f",
|
log.trace(String.format("Schritt2b-B (%d,%d) h=%.2f → %.2f",
|
||||||
colX2b, colZ2b, h0sm, minRampH));
|
colX2b, colZ2b, h0sm, minRampH));
|
||||||
}
|
}
|
||||||
smoothMap.put(hk0, minRampH);
|
smoothMap.put(hk0, minRampH);
|
||||||
} else if (minRaiseH > h0sm && minRaiseH < Float.POSITIVE_INFINITY) {
|
|
||||||
// Voxel lag unter dem Terrain → auf Terrain-Niveau anheben
|
|
||||||
if (log.isTraceEnabled()) {
|
|
||||||
log.trace(String.format("Schritt2b-RAISE (%d,%d) h=%.2f → %.2f",
|
|
||||||
colX2b, colZ2b, h0sm, minRaiseH));
|
|
||||||
}
|
|
||||||
smoothMap.put(hk0, minRaiseH);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
blight-map/src/main/map/blight_map.blm.tmp
Normal file
BIN
blight-map/src/main/map/blight_map.blm.tmp
Normal file
Binary file not shown.
BIN
blight-map/src/main/map/chunks/voxel_16_0_07_baked_lod0.j3o
Normal file
BIN
blight-map/src/main/map/chunks/voxel_16_0_07_baked_lod0.j3o
Normal file
Binary file not shown.
BIN
blight-map/src/main/map/chunks/voxel_16_0_07_baked_lod1.j3o
Normal file
BIN
blight-map/src/main/map/chunks/voxel_16_0_07_baked_lod1.j3o
Normal file
Binary file not shown.
BIN
blight-map/src/main/map/chunks/voxel_16_0_07_baked_lod2.j3o
Normal file
BIN
blight-map/src/main/map/chunks/voxel_16_0_07_baked_lod2.j3o
Normal file
Binary file not shown.
Reference in New Issue
Block a user