فهرست منبع

Model can now be loaded keeping the specific pose of the skeleton in the file.

Nehon 8 سال پیش
والد
کامیت
94277ac286

+ 27 - 20
jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java

@@ -156,17 +156,6 @@ public class GltfLoader implements AssetLoader {
             }
         }
 
-        //update skeletons
-        if (skins != null) {
-            for (int i = 0; i < skins.size(); i++) {
-                SkinData sd = fetchFromCache("skins", i, SkinData.class);
-                //reset to bind pose and update model transforms of each bones.
-                sd.skeletonControl.getSkeleton().resetAndUpdate();
-                //Compute sthe inverse bind transforms needed for skinning.
-                sd.skeletonControl.getSkeleton().setBindingPose();
-            }
-        }
-
         //Setting the default scene cul hint to inherit.
         int activeChild = 0;
         if (defaultScene != null) {
@@ -515,10 +504,8 @@ public class GltfLoader implements AssetLoader {
             logger.log(Level.WARNING, "Unable to find any pbrMetallicRoughness material entry in material " + materialIndex + ". Only PBR material is supported for now");
             return defaultMat;
         }
-        MaterialAdapter adapter = null;
-        if (info.getKey() instanceof GltfModelKey) {
-            adapter = ((GltfModelKey) info.getKey()).getAdapterForMaterial("pbrMetallicRoughness");
-        }
+
+        MaterialAdapter adapter = getAdapterForMaterial(info, "pbrMetallicRoughness");
         if (adapter == null) {
             adapter = defaultMaterialAdapters.get("pbrMetallicRoughness");
         }
@@ -820,11 +807,20 @@ public class GltfLoader implements AssetLoader {
 
             Skeleton skeleton = new Skeleton(bones);
 
+            //Compute bind transforms. We need to do it from root bone to leaves bone.
             for (Bone bone : skeleton.getRoots()) {
                 BoneWrapper bw = findBoneWrapper(bone);
                 computeBindTransforms(bw, skeleton);
             }
 
+            if (isKeepSkeletonPose(info)) {
+                //Set local transforms. The skeleton may come in a given pose, that is not the rest pose, so let's apply it.
+                for (int i = 0; i < joints.size(); i++) {
+                    applyPose(joints.get(i).getAsInt());
+                }
+                skeleton.updateWorldVectors();
+            }
+
             SkinData skinData = new SkinData();
             skinData.skeletonControl = new SkeletonControl(skeleton);
             addToCache("skins", index, skinData, nodes.size());
@@ -832,6 +828,14 @@ public class GltfLoader implements AssetLoader {
         }
     }
 
+    private void applyPose(int index) {
+        BoneWrapper bw = fetchFromCache("nodes", index, BoneWrapper.class);
+        bw.bone.setUserControl(true);
+        bw.bone.setLocalTranslation(bw.localTransform.getTranslation());
+        bw.bone.setLocalRotation(bw.localTransform.getRotation());
+        bw.bone.setLocalScale(bw.localTransform.getScale());
+    }
+
     private void computeBindTransforms(BoneWrapper boneWrapper, Skeleton skeleton) {
         Bone bone = boneWrapper.bone;
         tmpTransforms.fromTransformMatrix(boneWrapper.modelBindMatrix);
@@ -880,10 +884,11 @@ public class GltfLoader implements AssetLoader {
             name = "Bone_" + nodeIndex;
         }
         Bone bone = new Bone(name);
-        Transform boneTransforms = readTransforms(nodeData);
-        bone.setBindTransforms(boneTransforms.getTranslation(), boneTransforms.getRotation(), boneTransforms.getScale());
-
-        addToCache("nodes", nodeIndex, new BoneWrapper(bone, boneIndex, skinIndex, modelBindMatrix), nodes.size());
+        Transform boneTransforms = null;
+        if (isKeepSkeletonPose(info)) {
+            boneTransforms = readTransforms(nodeData);
+        }
+        addToCache("nodes", nodeIndex, new BoneWrapper(bone, boneIndex, skinIndex, modelBindMatrix, boneTransforms), nodes.size());
 
         return bone;
     }
@@ -965,15 +970,17 @@ public class GltfLoader implements AssetLoader {
         Bone bone;
         int boneIndex;
         int skinIndex;
+        Transform localTransform;
         Matrix4f modelBindMatrix;
         boolean isRoot = false;
         List<Integer> children = new ArrayList<>();
 
-        public BoneWrapper(Bone bone, int boneIndex, int skinIndex, Matrix4f modelBindMatrix) {
+        public BoneWrapper(Bone bone, int boneIndex, int skinIndex, Matrix4f modelBindMatrix, Transform localTransform) {
             this.bone = bone;
             this.boneIndex = boneIndex;
             this.skinIndex = skinIndex;
             this.modelBindMatrix = modelBindMatrix;
+            this.localTransform = localTransform;
         }
 
         /**

+ 9 - 0
jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfModelKey.java

@@ -11,6 +11,7 @@ import java.util.Map;
 public class GltfModelKey extends ModelKey {
 
     private Map<String, MaterialAdapter> materialAdapters = new HashMap<>();
+    private boolean keepSkeletonPose = false;
 
     public GltfModelKey(String name) {
         super(name);
@@ -26,4 +27,12 @@ public class GltfModelKey extends ModelKey {
     public MaterialAdapter getAdapterForMaterial(String gltfMaterialName) {
         return materialAdapters.get(gltfMaterialName);
     }
+
+    public boolean isKeepSkeletonPose() {
+        return keepSkeletonPose;
+    }
+
+    public void setKeepSkeletonPose(boolean keepSkeletonPose) {
+        this.keepSkeletonPose = keepSkeletonPose;
+    }
 }

+ 24 - 0
jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfUtils.java

@@ -1,6 +1,7 @@
 package com.jme3.scene.plugins.gltf;
 
 import com.google.gson.*;
+import com.jme3.asset.AssetInfo;
 import com.jme3.asset.AssetLoadException;
 import com.jme3.math.ColorRGBA;
 import com.jme3.math.Matrix4f;
@@ -495,6 +496,29 @@ public class GltfUtils {
         return new Matrix4f(m00, m10, m20, m30, m01, m11, m21, m31, m02, m12, m22, m32, m03, m13, m23, m33);
     }
 
+    public static GltfModelKey getKey(AssetInfo info) {
+        if (info.getKey() instanceof GltfModelKey) {
+            return (GltfModelKey) info.getKey();
+        }
+        return null;
+    }
+
+    public static MaterialAdapter getAdapterForMaterial(AssetInfo info, String defName) {
+        GltfModelKey key = getKey(info);
+        if (key == null) {
+            return null;
+        }
+        return key.getAdapterForMaterial(defName);
+    }
+
+    public static boolean isKeepSkeletonPose(AssetInfo info) {
+        GltfModelKey key = getKey(info);
+        if (key == null) {
+            return false;
+        }
+        return key.isKeepSkeletonPose();
+    }
+
     private static LittleEndien getStream(byte[] buffer) {
         return new LittleEndien(new DataInputStream(new ByteArrayInputStream(buffer)));
     }