Zwischenstand - animationen passen weitesgehend
This commit is contained in:
@@ -258,6 +258,10 @@ public class AnimPreviewState extends BaseAppState {
|
||||
// Alle Clips in-place snappen (verhindert Drift im Preview)
|
||||
AnimComposer previewAC = findControl(model, AnimComposer.class);
|
||||
SkinningControl previewSC = findControl(model, SkinningControl.class);
|
||||
LOG.info("[AnimPreview] Modell-Controls: AnimComposer={}, SkinningControl={}, EmbeddedClips={}",
|
||||
previewAC != null ? "gefunden" : "NULL",
|
||||
previewSC != null ? "gefunden" : "NULL",
|
||||
previewAC != null ? previewAC.getAnimClips().size() : "n/a");
|
||||
if (previewAC != null && previewSC != null) {
|
||||
// Eingebettete Clips snappen
|
||||
for (AnimClip c : new java.util.ArrayList<>(previewAC.getAnimClips())) {
|
||||
@@ -275,29 +279,33 @@ public class AnimPreviewState extends BaseAppState {
|
||||
}
|
||||
saveModelStripped(model, assetPath, embedCount);
|
||||
}
|
||||
// T-Pose: AnimClip mit einem Einzel-Frame-Track für den Root-Joint.
|
||||
// T-Pose: AnimClip für alle Joints in Bind-Pose.
|
||||
// Leerer Clip → NPE in ClipAction.doInterpolate (JME3 erwartet tracks != null).
|
||||
// Ein Frame am Root-Joint in Bind-Pose → alle anderen Joints bleiben an
|
||||
// ihren lokalen Bind-Pose-Transforms → SC-Matrix = Bind × Bind⁻¹ = I
|
||||
// getInitialTransform() liefert die Bind-Pose → SC-Matrix = Bind × Bind⁻¹ = I
|
||||
// → Vertices in Y-up = stehender Charakter.
|
||||
AnimClip tpose = buildTPoseClip(previewSC.getArmature());
|
||||
LOG.info("[AnimPreview] T-Pose Clip: {}", tpose != null ? "erstellt" : "NULL (keine Root-Joints?)");
|
||||
if (tpose != null) {
|
||||
previewAC.addAnimClip(tpose);
|
||||
setSkinningEnabled(model, true);
|
||||
previewAC.setCurrentAction("__tpose__");
|
||||
LOG.info("[AnimPreview] T-Pose aktiviert");
|
||||
}
|
||||
} else {
|
||||
LOG.warn("[AnimPreview] T-Pose NICHT möglich: previewAC={}, previewSC={}",
|
||||
previewAC != null ? "ok" : "NULL",
|
||||
previewSC != null ? "ok" : "NULL");
|
||||
}
|
||||
|
||||
// Kamera auf Bounding Box ausrichten
|
||||
// Kamera: immer auf Hüfthöhe (0, 1, 0) zielen; Distanz aus BoundingBox
|
||||
model.updateGeometricState();
|
||||
if (model.getWorldBound() instanceof BoundingBox bb) {
|
||||
float ext = Math.max(bb.getXExtent(), Math.max(bb.getYExtent(), bb.getZExtent()));
|
||||
previewCamDist = ext * 2.8f;
|
||||
previewTarget.set(bb.getCenter());
|
||||
} else {
|
||||
previewCamDist = 3f;
|
||||
previewTarget.set(0, 1, 0);
|
||||
}
|
||||
previewTarget.set(0, 1, 0);
|
||||
input.animPreviewZoom = 1.0f;
|
||||
|
||||
// Clips sammeln und melden
|
||||
@@ -1002,18 +1010,20 @@ public class AnimPreviewState extends BaseAppState {
|
||||
* Gibt null zurück wenn das Armature keine Root-Joints hat.
|
||||
*/
|
||||
private static AnimClip buildTPoseClip(com.jme3.anim.Armature armature) {
|
||||
com.jme3.anim.Joint[] roots = armature.getRoots();
|
||||
if (roots == null || roots.length == 0) return null;
|
||||
int jointCount = armature.getJointCount();
|
||||
if (jointCount == 0) return null;
|
||||
AnimClip clip = new AnimClip("__tpose__");
|
||||
com.jme3.anim.AnimTrack[] tracks = new com.jme3.anim.AnimTrack[roots.length];
|
||||
for (int i = 0; i < roots.length; i++) {
|
||||
com.jme3.anim.Joint root = roots[i];
|
||||
com.jme3.anim.AnimTrack[] tracks = new com.jme3.anim.AnimTrack[jointCount];
|
||||
for (int i = 0; i < jointCount; i++) {
|
||||
com.jme3.anim.Joint joint = armature.getJoint(i);
|
||||
// getInitialTransform() liefert die echte Bind-Pose (nicht den aktuellen Zustand)
|
||||
com.jme3.math.Transform bt = joint.getInitialTransform();
|
||||
tracks[i] = new com.jme3.anim.TransformTrack(
|
||||
root,
|
||||
joint,
|
||||
new float[]{0f},
|
||||
new com.jme3.math.Vector3f[]{root.getLocalTranslation().clone()},
|
||||
new com.jme3.math.Quaternion[]{root.getLocalRotation().clone()},
|
||||
new com.jme3.math.Vector3f[]{root.getLocalScale().clone()});
|
||||
new com.jme3.math.Vector3f[]{bt.getTranslation().clone()},
|
||||
new com.jme3.math.Quaternion[]{bt.getRotation().clone()},
|
||||
new com.jme3.math.Vector3f[]{bt.getScale().clone()});
|
||||
}
|
||||
clip.setTracks(tracks);
|
||||
return clip;
|
||||
|
||||
Reference in New Issue
Block a user