Fehler bei den Höhlen behoben
This commit is contained in:
@@ -1891,12 +1891,15 @@ public class TerrainEditorState extends BaseAppState {
|
||||
}
|
||||
camPos.y = FastMath.clamp(camPos.y, -200f, MAX_CAM_Y);
|
||||
|
||||
// Kamera nicht unter das Terrain oder gebackenes Voxel-Terrain fallen lassen
|
||||
// Kamera nicht unter Basis-Terrain oder gebackenes Voxel-Terrain fallen lassen.
|
||||
// Raycast von Kameraposition nach unten: findet Bergoberfläche, Tunnelboden oder nichts.
|
||||
float baseFloor = getTerrainHeightFast(camPos.x, camPos.z);
|
||||
VoxelEditorState ves = getStateManager().getState(VoxelEditorState.class);
|
||||
float floor = (ves != null)
|
||||
? Math.max(baseFloor, ves.columnTopWorldY(camPos.x, camPos.z))
|
||||
: baseFloor;
|
||||
float floor = baseFloor;
|
||||
if (ves != null) {
|
||||
float vf = ves.voxelFloorBelow(camPos.x, camPos.y, camPos.z, 4f);
|
||||
if (!Float.isNaN(vf)) floor = Math.max(baseFloor, vf);
|
||||
}
|
||||
if (camPos.y < floor + 2f) camPos.y = floor + 2f;
|
||||
|
||||
cam.setLocation(camPos);
|
||||
|
||||
@@ -1381,6 +1381,30 @@ public class VoxelEditorState extends BaseAppState {
|
||||
return terrainH(worldX, worldZ); // Kein Voxel → Terrain-Oberfläche als Basis
|
||||
}
|
||||
|
||||
/** Voxel-Dichte am Weltpunkt; >0 = solid, ≤0 = Luft/leer. */
|
||||
public float densityAt(float worldX, float worldY, float worldZ) {
|
||||
int cx = VoxelChunk.worldXToCx(worldX);
|
||||
int cy = VoxelChunk.worldYToCy(worldY);
|
||||
int cz = VoxelChunk.worldZToCz(worldZ);
|
||||
VoxelChunk chunk = chunks.get(chunkKey(cx, cy, cz));
|
||||
if (chunk == null || chunk.isEmpty()) return -1f;
|
||||
int lx = Math.max(0, Math.min(VoxelChunk.SIZE - 1, Math.round(VoxelChunk.worldXToLocal(worldX, cx))));
|
||||
int ly = Math.max(0, Math.min(VoxelChunk.SIZE - 1, Math.round(VoxelChunk.worldYToLocal(worldY, cy))));
|
||||
int lz = Math.max(0, Math.min(VoxelChunk.SIZE - 1, Math.round(VoxelChunk.worldZToLocal(worldZ, cz))));
|
||||
return chunk.getDensity(lx, ly, lz);
|
||||
}
|
||||
|
||||
/** Erste gebackene Voxel-Fläche unterhalb (wx,wy,wz) innerhalb maxDist Metern.
|
||||
* Gibt Float.NaN zurück wenn keine Fläche in Reichweite. */
|
||||
public float voxelFloorBelow(float wx, float wy, float wz, float maxDist) {
|
||||
if (voxelRoot == null) return Float.NaN;
|
||||
CollisionResults results = new CollisionResults();
|
||||
voxelRoot.collideWith(new Ray(new Vector3f(wx, wy, wz), new Vector3f(0f, -1f, 0f)), results);
|
||||
if (results.size() == 0) return Float.NaN;
|
||||
CollisionResult closest = results.getClosestCollision();
|
||||
return (closest.getDistance() <= maxDist) ? closest.getContactPoint().y : Float.NaN;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gemeinsamer Kern: iteriert über alle Spalten im Radius und bewegt sie
|
||||
* schrittweise auf die per Lambda berechnete Ziel-Welt-Y zu.
|
||||
@@ -2385,6 +2409,7 @@ public class VoxelEditorState extends BaseAppState {
|
||||
float[] next = Arrays.copyOf(cur, cur.length);
|
||||
int wiyBase = c.cy * C;
|
||||
|
||||
VoxelChunk origChunk = allOriginal.get(k);
|
||||
for (int bz = 0; bz < C; bz++) {
|
||||
int colZ = c.cz * C + bz;
|
||||
for (int bx = 0; bx < C; bx++) {
|
||||
@@ -2396,8 +2421,19 @@ public class VoxelEditorState extends BaseAppState {
|
||||
|
||||
// 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).
|
||||
if (d > 0f && origChunk.getDensity(bx, by, bz) < 0) {
|
||||
continue;
|
||||
}
|
||||
next[c.idx(bx, by, bz)] = Math.max(-128f, Math.min(127f, d));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user