Weltkarte: Wald-Linien Z-Flip fix + korrekte Layer-Reihenfolge
- buildForestOutlinePaths: Density-Map hat Z invertiert (Nord=mz=0) gegenüber Marching-Squares-Koordinaten (Süd=mz=0) → gespiegelte Konturen landeten off-screen, kein sichtbarer Wald-Rand. Fix: dz = fdSize-1-mz beim Samplen. - Render-Reihenfolge korrigiert: Klippen → Wald → Wasser → Areas (Wald war über Wasser, sollte darunter liegen) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -456,12 +456,12 @@ public class WorldMapView extends VBox {
|
||||
} else {
|
||||
gc.drawImage(mapFxImage, panX, panY, mapFxImage.getWidth() * scale, mapFxImage.getHeight() * scale);
|
||||
}
|
||||
// Layer 2: Klippen (Grau-Füllung + Vektor-Kontur)
|
||||
// Layer 2: Klippen (Grau-Füllung + Schraffierung + Vektor-Kontur)
|
||||
if (cbCliffs.isSelected()) drawCliffOverlay(gc);
|
||||
// Layer 3: Küstenlinie (Vektor)
|
||||
if (cbWater.isSelected()) drawWaterOverlay(gc);
|
||||
// Layer 4: Wald (Füllung + Vektor-Kontur)
|
||||
// Layer 3: Wald (Füllung + Vektor-Kontur) – unter Wasser
|
||||
if (cbForest.isSelected()) drawForestOverlay(gc);
|
||||
// Layer 4: Küstenlinie + Wasser (Vektor) – deckt Terrain-Features ab
|
||||
if (cbWater.isSelected()) drawWaterOverlay(gc);
|
||||
// Layer 5: Areas (Vektoren)
|
||||
if (cbAreas.isSelected()) drawAreasOverlay(gc);
|
||||
if (!isFullscreen) drawCameraIndicator(gc);
|
||||
@@ -1117,21 +1117,17 @@ public class WorldMapView extends VBox {
|
||||
|
||||
/** Extrahiert Wald-Konturen aus der Tree-Density-Map als geglättete Weltkoordinaten-Pfade. */
|
||||
private static List<float[][]> buildForestOutlinePaths(float[] density, int fdSize, float threshold) {
|
||||
final int SIZE = SEA_MASK_SIZE;
|
||||
float[] mask = new float[SIZE * SIZE];
|
||||
for (int py = 0; py < SIZE; py++) {
|
||||
for (int px = 0; px < SIZE; px++) {
|
||||
float fx = (float) px / (SIZE - 1) * (fdSize - 1);
|
||||
float fz = (float) py / (SIZE - 1) * (fdSize - 1);
|
||||
int sx = Math.min(fdSize - 1, (int) fx), sz = Math.min(fdSize - 1, (int) fz);
|
||||
float d = density[sz * fdSize + sx];
|
||||
// Wald-Bereich = "inside" (< threshold 0.5): -1; Nicht-Wald = 1
|
||||
mask[py * SIZE + px] = d >= threshold ? -1f : 1f;
|
||||
// Density-Map: mz=0 = Norden (WH-pm.z()=0 → pm.z()=+WH), mz=fdSize-1 = Süden.
|
||||
// Marching Squares: mz=0 → msW=-WH (Süden). → Z muss gespiegelt werden.
|
||||
float[] mask = new float[fdSize * fdSize];
|
||||
for (int mz = 0; mz < fdSize; mz++) {
|
||||
int dz = fdSize - 1 - mz; // Süden im MS ↔ Süden in der Density-Map
|
||||
for (int mx = 0; mx < fdSize; mx++) {
|
||||
mask[mz * fdSize + mx] = density[dz * fdSize + mx] >= threshold ? -1f : 1f;
|
||||
}
|
||||
}
|
||||
|
||||
List<float[]> segs = new ArrayList<>();
|
||||
marchingSquares(mask, SIZE, 0.5f, null, null, segs);
|
||||
marchingSquares(mask, fdSize, 0.5f, null, null, segs);
|
||||
return buildSeaCoastPaths(segs.toArray(new float[0][]));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user