Weiter gebastelt

This commit is contained in:
2026-06-09 19:25:30 +02:00
parent 5e85051716
commit edb9cfc946
54 changed files with 1088 additions and 356 deletions

View File

@@ -1,16 +1,25 @@
package de.blight.game.animation;
import com.jme3.anim.*;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.*;
import com.jme3.anim.AnimClip;
import com.jme3.anim.AnimComposer;
import com.jme3.anim.AnimTrack;
import com.jme3.anim.Armature;
import com.jme3.anim.Joint;
import com.jme3.anim.SkinningControl;
import com.jme3.anim.TransformTrack;
import com.jme3.math.Quaternion;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.Control;
/**
* Model-space retargeting with correct parent-chain propagation.
@@ -406,7 +415,6 @@ public final class RetargetingSystem {
return findControl(s, SkinningControl.class);
}
@SuppressWarnings("unchecked")
static <T extends Control> T findControl(Spatial s, Class<T> type) {
T c = s.getControl(type);
if (c != null) return c;

View File

@@ -108,6 +108,12 @@ public class WorldScene extends BaseAppState {
@Override
protected void onEnable() {
try {
assetManager.registerLocator(
AnimationLibrary.findAssetRoot().toAbsolutePath().toString(),
com.jme3.asset.plugins.FileLocator.class);
} catch (Exception ignored) {}
BlightGame.status("Baue Beleuchtung und Himmel...");
buildLighting();
@@ -529,6 +535,7 @@ public class WorldScene extends BaseAppState {
String[] mapTex = map.terrainTextures;
String[] matParams = {"DiffuseMap","DiffuseMap_1","DiffuseMap_2","DiffuseMap_3"};
String[] scaleP = {"DiffuseMap_0_scale","DiffuseMap_1_scale","DiffuseMap_2_scale","DiffuseMap_3_scale"};
String[] nmParams = {"NormalMap","NormalMap_1","NormalMap_2","NormalMap_3"};
for (int i = 0; i < 4; i++) {
String path = (mapTex[i] != null && !mapTex[i].isEmpty()) ? mapTex[i] : DEF_TEX[i];
if (path == null || path.isEmpty()) continue;
@@ -536,6 +543,18 @@ public class WorldScene extends BaseAppState {
tex.setWrap(Texture.WrapMode.Repeat);
mat.setTexture(matParams[i], tex);
mat.setFloat(scaleP[i], 512f);
String nmp = map.terrainNormalMaps[i];
System.out.println("[WorldScene] Slot " + i + " NormalMap: '" + nmp + "'");
if (nmp != null && !nmp.isEmpty()) {
try {
Texture nm = assetManager.loadTexture(nmp);
nm.setWrap(Texture.WrapMode.Repeat);
mat.setTexture(nmParams[i], nm);
System.out.println("[WorldScene] Slot " + i + " NormalMap geladen OK");
} catch (Exception e) {
System.err.println("[WorldScene] NormalMap nicht ladbar: " + nmp + " " + e.getMessage());
}
}
}
// Ältere Maps haben splatR=0 → Gras (Slot 0) wäre unsichtbar; auf 255 setzen.

View File

@@ -282,6 +282,7 @@ public class TerrainChunkState extends BaseAppState {
float[] positions = new float[vertCount * 3];
float[] normals = new float[vertCount * 3];
float[] tangents = new float[vertCount * 4];
float[] texCoords = new float[vertCount * 2];
int[] indices = new int[indexCount];
@@ -307,12 +308,23 @@ public class TerrainChunkState extends BaseAppState {
if (nLen > 1e-6f) { nx /= nLen; ny /= nLen; nz /= nLen; }
normals[pi] = nx; normals[pi+1] = ny; normals[pi+2] = nz;
// Welt-Raum UV (01 über 4096 m) für globale Splat-Map
// Tangente: Projektion der +X-Achse auf die Oberfläche (Gram-Schmidt)
// U wächst mit worldX → Tangente zeigt in +X-Richtung
float dotX = nx; // dot((1,0,0), N)
float tx = 1f - dotX * nx;
float ty = -dotX * ny;
float tz = -dotX * nz;
float tLen = (float) Math.sqrt(tx*tx + ty*ty + tz*tz);
if (tLen > 1e-6f) { tx /= tLen; ty /= tLen; tz /= tLen; }
int gi = vi * 4;
tangents[gi] = tx; tangents[gi+1] = ty; tangents[gi+2] = tz; tangents[gi+3] = 1f;
// Welt-Raum UV für Splat-Map: JME3-TerrainQuad-Konvention V=0 → worldZ=+2048
float worldX = chunkCX + lx;
float worldZ = chunkCZ + lz;
int ti = vi * 2;
texCoords[ti] = (worldX + 2048f) / 4096f;
texCoords[ti+1] = (worldZ + 2048f) / 4096f;
texCoords[ti+1] = 1f - (worldZ + 2048f) / 4096f;
}
}
@@ -331,6 +343,7 @@ public class TerrainChunkState extends BaseAppState {
Mesh mesh = new Mesh();
mesh.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(positions));
mesh.setBuffer(VertexBuffer.Type.Normal, 3, BufferUtils.createFloatBuffer(normals));
mesh.setBuffer(VertexBuffer.Type.Tangent, 4, BufferUtils.createFloatBuffer(tangents));
mesh.setBuffer(VertexBuffer.Type.TexCoord, 2, BufferUtils.createFloatBuffer(texCoords));
mesh.setBuffer(VertexBuffer.Type.Index, 3, BufferUtils.createIntBuffer(indices));
mesh.updateBound();

View File

@@ -11,8 +11,6 @@ import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
@@ -64,9 +62,6 @@ public class WorldItemsState extends BaseAppState {
private final List<Spatial> visuals = new ArrayList<>();
private final Map<String, Item> itemDefs = new HashMap<>();
private final Quaternion rotQuat = new Quaternion();
private float rotAccum = 0f;
public WorldItemsState(KeyBindings keyBindings, CharacterControl physicsChar,
MainCharacter mainCharacter, PlayerInputControl playerInput) {
this.keyBindings = keyBindings;
@@ -136,12 +131,7 @@ public class WorldItemsState extends BaseAppState {
protected void cleanup(Application app) {}
@Override
public void update(float tpf) {
if (visuals.isEmpty()) return;
rotAccum += tpf * 60f;
rotQuat.fromAngles(0f, rotAccum * FastMath.DEG_TO_RAD, 0f);
for (Spatial s : visuals) s.setLocalRotation(rotQuat);
}
public void update(float tpf) {}
// ── Interaktion ───────────────────────────────────────────────────────────