2
0
Эх сурвалжийг харах

Add support for gltf morph names. (#1100)

* Add support for gltf morph names.

* Fix formatting stuff

* Add morph name to be saved

* Testing changes to gltf plugin

* Review changes

* Fix comments

* Fixes for review

* Remove getMorphNames from Geometry class
Trevor Flynn 6 жил өмнө
parent
commit
57db8f618f

+ 30 - 0
jme3-core/src/main/java/com/jme3/scene/Geometry.java

@@ -601,6 +601,22 @@ public class Geometry extends Spatial {
         this.dirtyMorph = true;
     }
 
+    /**
+     * Set the state of the morph with the given name.
+     * 
+     * If the name of the morph is not found, no state will be set.
+     * 
+     * @param morphTarget The name of the morph to set the state of
+     * @param state The state to set the morph to
+     */
+    public void setMorphState(String morphTarget, float state) {
+        int index = mesh.getMorphIndex(morphTarget);
+        if (index >= 0) {
+            morphState[index] = state;
+            this.dirtyMorph = true;
+        }
+    }
+
     /**
      * returns true if the morph state has changed on the last frame.
      * @return true if changed, otherwise false
@@ -629,6 +645,20 @@ public class Geometry extends Spatial {
         }
         return morphState;
     }
+    
+    /**
+     * Get the state of a morph
+     * @param morphTarget the name of the morph to get the state of
+     * @return the state of the morph, or -1 if the morph is not found
+     */
+    public float getMorphState(String morphTarget) {
+        int index = mesh.getMorphIndex(morphTarget);
+        if (index < 0) {
+            return -1;
+        } else  {
+            return morphState[index];
+        }
+    }
 
     /**
      * Return the number of morph targets that can be handled on the GPU simultaneously for this geometry.

+ 36 - 0
jme3-core/src/main/java/com/jme3/scene/Mesh.java

@@ -1529,10 +1529,46 @@ public class Mesh implements Savable, Cloneable, JmeCloneable {
     public MorphTarget[] getMorphTargets() {
         return morphTargets.getArray();
     }
+    
+    /**
+     * Get the name of all morphs in order.
+     * Morphs without names will be null
+     * @return an array
+     */
+    public String[] getMorphTargetNames() {
+        
+        MorphTarget[] nbMorphTargets = getMorphTargets();
+        if (nbMorphTargets.length == 0) {
+            return new String[0];
+        }
+        String[] targets = new String[nbMorphTargets.length];
+
+        for (int index = 0; index < nbMorphTargets.length; index++) {
+            targets[index] = nbMorphTargets[index].getName();
+        }
+        return targets;
+    }
 
     public boolean hasMorphTargets() {
         return morphTargets != null && !morphTargets.isEmpty();
     }
+    
+    /**
+     * Get the index of the morph that has the given name.
+     * @param morphName The name of the morph to search for
+     * @return The index of the morph, or -1 if not found. 
+     */
+    public int getMorphIndex(String morphName) {
+        int index = -1;
+        MorphTarget[] nbMorphTargets = getMorphTargets();
+        for (int i = 0; i < nbMorphTargets.length; i++) {
+            if (nbMorphTargets[i].getName().equals(morphName)) {
+                index = i;
+                break;
+            }
+        }
+        return index;
+    }
 
     @Override
     public void write(JmeExporter ex) throws IOException {

+ 19 - 1
jme3-core/src/main/java/com/jme3/scene/mesh/MorphTarget.java

@@ -11,6 +11,23 @@ import java.util.Map;
 
 public class MorphTarget implements Savable {
     private EnumMap<VertexBuffer.Type, FloatBuffer> buffers = new EnumMap<>(VertexBuffer.Type.class);
+    private String name = null;
+    
+    public MorphTarget() {
+        
+    }
+    
+    public MorphTarget(String name) {
+        this.name = name;
+    }
+    
+    public void setName(String name) {
+        this.name = name;
+    }
+    
+    public String getName() {
+        return name;
+    }
 
     public void setBuffer(VertexBuffer.Type type, FloatBuffer buffer) {
         buffers.put(type, buffer);
@@ -35,6 +52,7 @@ public class MorphTarget implements Savable {
             Buffer roData = entry.getValue().asReadOnlyBuffer();
             oc.write((FloatBuffer) roData, entry.getKey().name(),null);
         }
+        oc.write(name, "morphName", null);
     }
 
     @Override
@@ -46,6 +64,6 @@ public class MorphTarget implements Savable {
                 setBuffer(type, b);
             }
         }
-
+        name = ic.readString("morphName", null);
     }
 }

+ 15 - 1
jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java

@@ -397,10 +397,23 @@ public class GltfLoader implements AssetLoader {
                 mesh.generateBindPose();
             }
 
+            //Read morph target names
+            LinkedList<String> targetNames = new LinkedList<>();
+            if (meshData.has("extras") && meshData.getAsJsonObject("extras").has("targetNames")) {
+                JsonArray targetNamesJson = meshData.getAsJsonObject("extras").getAsJsonArray("targetNames");
+                for (JsonElement target : targetNamesJson) {
+                    targetNames.add(target.getAsString());
+                }
+            }
+            
+            //Read morph targets
             JsonArray targets = meshObject.getAsJsonArray("targets");
             if(targets != null){
                 for (JsonElement target : targets) {
                     MorphTarget morphTarget = new MorphTarget();
+                    if (targetNames.size() > 0) {
+                        morphTarget.setName(targetNames.pop());
+                    }
                     for (Map.Entry<String, JsonElement> entry : target.getAsJsonObject().entrySet()) {
                         String bufferType = entry.getKey();
                         VertexBuffer.Type type = getVertexBufferType(bufferType);
@@ -412,7 +425,8 @@ public class GltfLoader implements AssetLoader {
                     mesh.addMorphTarget(morphTarget);
                 }
             }
-
+        
+            //Read mesh extras
             mesh = customContentManager.readExtensionAndExtras("primitive", meshObject, mesh);
 
             Geometry geom = new Geometry(null, mesh);