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));
|
||||
}
|
||||
}
|
||||
|
||||
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