Gras (Textur) Pinsel Bugs behoben
This commit is contained in:
@@ -147,6 +147,33 @@ public class PlacedObjectState extends BaseAppState {
|
||||
grassNode = new Node("grassNode");
|
||||
((SimpleApplication) app).getRootNode().attachChild(grassNode);
|
||||
applyAllSlotMaterials();
|
||||
initAspectRatios();
|
||||
}
|
||||
|
||||
private void initAspectRatios() {
|
||||
String[] allPaths = new String[8];
|
||||
allPaths[0] = input.grassTexturePath != null ? input.grassTexturePath : "";
|
||||
String[] slots = input.grassTextureSlots;
|
||||
for (int i = 0; i < 7; i++) {
|
||||
allPaths[i + 1] = (i < slots.length && slots[i] != null) ? slots[i] : "";
|
||||
}
|
||||
float[] ars = input.grassAspectRatios.clone();
|
||||
for (int s = 0; s < 8; s++) {
|
||||
String p = allPaths[s];
|
||||
if (p == null || p.isEmpty()) continue;
|
||||
try {
|
||||
com.jme3.texture.Texture tex = assetManager.loadTexture(
|
||||
new com.jme3.asset.TextureKey(p, false));
|
||||
if (tex != null && tex.getImage() != null) {
|
||||
int w = tex.getImage().getWidth();
|
||||
int h = tex.getImage().getHeight();
|
||||
if (w > 0 && h > 0) ars[s] = (float) w / h;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug("[PlacedObjectState] Aspect-Ratio nicht lesbar für Slot {}: {}", s, e.getMessage());
|
||||
}
|
||||
}
|
||||
input.grassAspectRatios = ars;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -36,18 +36,18 @@ public class GrassState extends BaseAppState
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(GrassState.class);
|
||||
|
||||
private static final int TERRAIN_HALF = 2048;
|
||||
private static final int CHUNK_SIZE = 128;
|
||||
private static final int CHUNKS_PER_AXIS = (TERRAIN_HALF * 2) / CHUNK_SIZE; // 32
|
||||
private static final int CHUNK_COUNT = CHUNKS_PER_AXIS * CHUNKS_PER_AXIS; // 1024
|
||||
private static final int CHUNK_SIZE = de.blight.common.ChunkTerrainIO.CHUNK_SIZE; // 128
|
||||
private static final int TERRAIN_HALF = de.blight.common.ChunkTerrainIO.WORLD_SIZE / 2; // 1024
|
||||
private static final int CHUNKS_PER_AXIS = de.blight.common.ChunkTerrainIO.CHUNKS_PER_AXIS; // 16
|
||||
private static final int CHUNK_COUNT = de.blight.common.ChunkTerrainIO.CHUNK_COUNT; // 256
|
||||
private static final int BLADES_PER_TUFT = 4;
|
||||
private static final float TUFT_SPREAD = 0.5f;
|
||||
private static final float BLADE_WIDTH = 0.18f;
|
||||
private static final int INIT_PER_FRAME = 4;
|
||||
|
||||
private final TerrainChunkState terrainChunkState;
|
||||
|
||||
private Node grassNode;
|
||||
private Node grassNode;
|
||||
private float[] slotAspectRatios = new float[8];
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
private final List<GrassTuft>[] chunkTufts = new List[CHUNK_COUNT];
|
||||
@@ -69,8 +69,9 @@ public class GrassState extends BaseAppState
|
||||
|
||||
for (int i = 0; i < CHUNK_COUNT; i++) chunkTufts[i] = new ArrayList<>();
|
||||
|
||||
GrassTuftIO.GrassData data = null;
|
||||
try {
|
||||
GrassTuftIO.GrassData data = GrassTuftIO.load();
|
||||
data = GrassTuftIO.load();
|
||||
if (data != null) {
|
||||
initSlotMaterials(app.getAssetManager(), data.slotPaths());
|
||||
for (GrassTuft t : data.tufts()) {
|
||||
@@ -85,6 +86,28 @@ public class GrassState extends BaseAppState
|
||||
if (slotMaterials.isEmpty()) {
|
||||
slotMaterials.put(0, buildGrassMat(app.getAssetManager(), ""));
|
||||
}
|
||||
initAspectRatios(app.getAssetManager(),
|
||||
data != null ? data.slotPaths() : null);
|
||||
}
|
||||
|
||||
private void initAspectRatios(AssetManager assets, String[] slotPaths) {
|
||||
java.util.Arrays.fill(slotAspectRatios, 1f);
|
||||
if (slotPaths == null) return;
|
||||
for (int s = 0; s < Math.min(slotAspectRatios.length, slotPaths.length); s++) {
|
||||
String p = slotPaths[s];
|
||||
if (p == null || p.isEmpty()) continue;
|
||||
try {
|
||||
com.jme3.texture.Texture tex = assets.loadTexture(
|
||||
new com.jme3.asset.TextureKey(p, false));
|
||||
if (tex != null && tex.getImage() != null) {
|
||||
int w = tex.getImage().getWidth();
|
||||
int h = tex.getImage().getHeight();
|
||||
if (w > 0 && h > 0) slotAspectRatios[s] = (float) w / h;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug("[GrassState] Aspect-Ratio nicht lesbar Slot {}: {}", s, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -228,8 +251,10 @@ public class GrassState extends BaseAppState
|
||||
if (entry.getValue().isEmpty()) continue;
|
||||
Material mat = getSlotMaterial(entry.getKey());
|
||||
if (mat == null) continue;
|
||||
Geometry geo = new Geometry("grass_" + idx + "_s" + entry.getKey(),
|
||||
buildGrassMesh(entry.getValue()));
|
||||
int slot = entry.getKey();
|
||||
float ar = (slot < slotAspectRatios.length) ? slotAspectRatios[slot] : 1f;
|
||||
Geometry geo = new Geometry("grass_" + idx + "_s" + slot,
|
||||
buildGrassMesh(entry.getValue(), ar));
|
||||
geo.setMaterial(mat);
|
||||
node.attachChild(geo);
|
||||
}
|
||||
@@ -288,7 +313,7 @@ public class GrassState extends BaseAppState
|
||||
|
||||
// ── Mesh: Kreuz-Quad mit UV ───────────────────────────────────────────────
|
||||
|
||||
private static Mesh buildGrassMesh(List<float[]> blades) {
|
||||
private static Mesh buildGrassMesh(List<float[]> blades, float ar) {
|
||||
int n = blades.size();
|
||||
FloatBuffer pos = BufferUtils.createFloatBuffer(n * 8 * 3);
|
||||
FloatBuffer uv = BufferUtils.createFloatBuffer(n * 8 * 2);
|
||||
@@ -298,7 +323,7 @@ public class GrassState extends BaseAppState
|
||||
int vi = 0;
|
||||
for (float[] blade : blades) {
|
||||
float x = blade[0], y = blade[1], z = blade[2], h = blade[3];
|
||||
float w = Math.max(0.05f, h * BLADE_WIDTH);
|
||||
float w = Math.max(0.05f, h * ar * 0.5f);
|
||||
|
||||
pos.put(x-w).put(y ).put(z); uv.put(0).put(0); nrm.put(0).put(1).put(0);
|
||||
pos.put(x+w).put(y ).put(z); uv.put(1).put(0); nrm.put(0).put(1).put(0);
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user