Weiter an der Karte gearbeitet - hier Höhlen und Tunnel
This commit is contained in:
@@ -150,6 +150,13 @@ public class MinimapState extends BaseAppState {
|
||||
private Geometry fogFullGeo;
|
||||
private Geometry playerDotFull;
|
||||
|
||||
// ── Höhlen-Karte ──────────────────────────────────────────────────────────
|
||||
private Geometry caveGeoMini = null; // Höhlenkarte über Minimap
|
||||
private Geometry caveGeoFull = null; // Höhlenkarte über Vollkarte
|
||||
private float caveBlend = 0f; // 0 = Außen, 1 = Höhle
|
||||
/** upperHole-Maske der geladenen Karte für Laufzeit-Erkennung; null = nicht verfügbar. */
|
||||
private byte[] upperHoleMask = null;
|
||||
|
||||
private float fmMapSize;
|
||||
private float fmMapOriginX;
|
||||
private float fmMapOriginY;
|
||||
@@ -212,8 +219,12 @@ public class MinimapState extends BaseAppState {
|
||||
}
|
||||
|
||||
float px = playerNode.getWorldTranslation().x;
|
||||
float py = playerNode.getWorldTranslation().y;
|
||||
float pz = playerNode.getWorldTranslation().z;
|
||||
|
||||
// Höhlen-Erkennung: upperHole-Zelle am Spieler-XZ
|
||||
tickCaveBlend(px, py, pz, tpf);
|
||||
|
||||
// Erkundung markieren + Nebel animieren
|
||||
tickExploration(px, pz, tpf);
|
||||
fogTime += tpf;
|
||||
@@ -267,6 +278,22 @@ public class MinimapState extends BaseAppState {
|
||||
}
|
||||
}
|
||||
|
||||
private void tickCaveBlend(float px, float py, float pz, float tpf) {
|
||||
if (upperHoleMask == null || caveGeoMini == null) return;
|
||||
int C = MapData.UPPER_CELLS;
|
||||
int cx = Math.max(0, Math.min(C-1, (int)((px + WORLD_HALF) / WORLD_SIZE * C)));
|
||||
int cz = Math.max(0, Math.min(C-1, (int)((pz + WORLD_HALF) / WORLD_SIZE * C)));
|
||||
boolean inHole = upperHoleMask[cz * C + cx] != 0;
|
||||
float target = inHole ? 1f : 0f;
|
||||
if (caveBlend != target) {
|
||||
float speed = 1.5f; // blend completes in ~0.67s
|
||||
caveBlend += (target - caveBlend) * Math.min(tpf * speed, 1f);
|
||||
if (Math.abs(caveBlend - target) < 0.005f) caveBlend = target;
|
||||
ColorRGBA col = new ColorRGBA(1f, 1f, 1f, caveBlend);
|
||||
caveGeoMini.getMaterial().setColor("Color", col);
|
||||
}
|
||||
}
|
||||
|
||||
private static float distSq(float x1, float z1, float x2, float z2) {
|
||||
float dx = x2 - x1, dz = z2 - z1;
|
||||
return dx * dx + dz * dz;
|
||||
@@ -551,10 +578,11 @@ public class MinimapState extends BaseAppState {
|
||||
List<PlacedWaterfall> waterfalls = WaterfallIO.load();
|
||||
int[] slotColors = computeSlotColors(mapData, root);
|
||||
int[][] tilePixels = WorldMapRenderer.loadMapTiles(root);
|
||||
float[] voxelSurface = WorldMapRenderer.bakeVoxelSurface(mapData);
|
||||
renderInput = new RenderInput(mapData, areas, zones, locs, waters, models, slotColors);
|
||||
de.blight.common.map.WorldMapRenderModel renderModel = new de.blight.common.map.WorldMapRenderModel(
|
||||
mapData, areas, zones, locs, waters, models, waterfalls,
|
||||
slotColors, null, null, null, null, null, tilePixels, null);
|
||||
slotColors, null, voxelSurface, null, null, null, tilePixels, null);
|
||||
log.debug("[Minimap] Render-Modell bereit – {} Areas, {} Orte, {} Wasser ({} ms)",
|
||||
areas.size(), locs.size(), waters.size(), System.currentTimeMillis() - t0);
|
||||
|
||||
@@ -565,6 +593,13 @@ public class MinimapState extends BaseAppState {
|
||||
log.debug("[Minimap] Weltkarte gerendert und gespeichert ({} ms): {}",
|
||||
System.currentTimeMillis() - t1, png);
|
||||
|
||||
BufferedImage caveBi = WorldMapRenderer.buildCaveMap(mapData, TEXTURE_SIZE);
|
||||
ImageIO.write(caveBi, "PNG", dir.resolve("minimap_cave.png").toFile());
|
||||
// Verwende Voxel-basierten Tunnel-Maske für Laufzeit-Erkennung (UPPER_CELLS Auflösung)
|
||||
boolean[] tunnelMask256 = WorldMapRenderer.buildCaveTunnelMask(mapData, MapData.UPPER_CELLS);
|
||||
upperHoleMask = new byte[tunnelMask256.length];
|
||||
for (int i = 0; i < tunnelMask256.length; i++) upperHoleMask[i] = tunnelMask256[i] ? (byte)1 : 0;
|
||||
|
||||
app.enqueue(() -> { onTextureReady(); return null; });
|
||||
} catch (Exception e) {
|
||||
log.error("[Minimap] Render-Fehler: {}", e.getMessage(), e);
|
||||
@@ -621,10 +656,16 @@ public class MinimapState extends BaseAppState {
|
||||
MINIMAP_SIZE / 2f - DOT_SIZE / 2f,
|
||||
MINIMAP_SIZE / 2f - DOT_SIZE / 2f, 2f);
|
||||
|
||||
caveGeoMini = new Geometry("minimap_cave", minimapMesh);
|
||||
caveGeoMini.setMaterial(buildCaveTexMat());
|
||||
caveGeoMini.setQueueBucket(RenderQueue.Bucket.Gui);
|
||||
caveGeoMini.setLocalTranslation(0f, 0f, 0.5f); // between world map and fog
|
||||
|
||||
minimapNode = new Node("minimap");
|
||||
minimapNode.setLocalTranslation(x, y, 48f);
|
||||
minimapNode.attachChild(border);
|
||||
minimapNode.attachChild(minimapGeo);
|
||||
minimapNode.attachChild(caveGeoMini);
|
||||
minimapNode.attachChild(fogMiniGeo);
|
||||
minimapNode.attachChild(playerDotMini);
|
||||
|
||||
@@ -634,6 +675,21 @@ public class MinimapState extends BaseAppState {
|
||||
}
|
||||
}
|
||||
|
||||
/** Erstellt das Material für die Höhlenkarte mit Alpha-Blending (initial unsichtbar). */
|
||||
private Material buildCaveTexMat() {
|
||||
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
||||
mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
|
||||
try {
|
||||
Texture tex = app.getAssetManager().loadTexture("Textures/hud/minimap_cave.png");
|
||||
tex.setWrap(Texture.WrapMode.EdgeClamp);
|
||||
mat.setTexture("ColorMap", tex);
|
||||
} catch (Exception e) {
|
||||
log.warn("[Minimap] Höhlenkarten-Textur nicht ladbar");
|
||||
}
|
||||
mat.setColor("Color", new ColorRGBA(1f, 1f, 1f, 0f)); // zunächst unsichtbar
|
||||
return mat;
|
||||
}
|
||||
|
||||
// ── Vektor-Layer ──────────────────────────────────────────────────────────
|
||||
|
||||
private void scheduleVectorRedraw() {
|
||||
|
||||
Reference in New Issue
Block a user