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
This commit is contained in:
		
							parent
							
								
									7058439e7d
								
							
						
					
					
						commit
						57db8f618f
					
				| @ -601,6 +601,22 @@ public class Geometry extends Spatial { | |||||||
|         this.dirtyMorph = true; |         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. |      * returns true if the morph state has changed on the last frame. | ||||||
|      * @return true if changed, otherwise false |      * @return true if changed, otherwise false | ||||||
| @ -629,6 +645,20 @@ public class Geometry extends Spatial { | |||||||
|         } |         } | ||||||
|         return morphState; |         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. |      * Return the number of morph targets that can be handled on the GPU simultaneously for this geometry. | ||||||
|  | |||||||
| @ -1529,10 +1529,46 @@ public class Mesh implements Savable, Cloneable, JmeCloneable { | |||||||
|     public MorphTarget[] getMorphTargets() { |     public MorphTarget[] getMorphTargets() { | ||||||
|         return morphTargets.getArray(); |         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() { |     public boolean hasMorphTargets() { | ||||||
|         return morphTargets != null && !morphTargets.isEmpty(); |         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 |     @Override | ||||||
|     public void write(JmeExporter ex) throws IOException { |     public void write(JmeExporter ex) throws IOException { | ||||||
|  | |||||||
| @ -11,6 +11,23 @@ import java.util.Map; | |||||||
| 
 | 
 | ||||||
| public class MorphTarget implements Savable { | public class MorphTarget implements Savable { | ||||||
|     private EnumMap<VertexBuffer.Type, FloatBuffer> buffers = new EnumMap<>(VertexBuffer.Type.class); |     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) { |     public void setBuffer(VertexBuffer.Type type, FloatBuffer buffer) { | ||||||
|         buffers.put(type, buffer); |         buffers.put(type, buffer); | ||||||
| @ -35,6 +52,7 @@ public class MorphTarget implements Savable { | |||||||
|             Buffer roData = entry.getValue().asReadOnlyBuffer(); |             Buffer roData = entry.getValue().asReadOnlyBuffer(); | ||||||
|             oc.write((FloatBuffer) roData, entry.getKey().name(),null); |             oc.write((FloatBuffer) roData, entry.getKey().name(),null); | ||||||
|         } |         } | ||||||
|  |         oc.write(name, "morphName", null); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
| @ -46,6 +64,6 @@ public class MorphTarget implements Savable { | |||||||
|                 setBuffer(type, b); |                 setBuffer(type, b); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 |         name = ic.readString("morphName", null); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -397,10 +397,23 @@ public class GltfLoader implements AssetLoader { | |||||||
|                 mesh.generateBindPose(); |                 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"); |             JsonArray targets = meshObject.getAsJsonArray("targets"); | ||||||
|             if(targets != null){ |             if(targets != null){ | ||||||
|                 for (JsonElement target : targets) { |                 for (JsonElement target : targets) { | ||||||
|                     MorphTarget morphTarget = new MorphTarget(); |                     MorphTarget morphTarget = new MorphTarget(); | ||||||
|  |                     if (targetNames.size() > 0) { | ||||||
|  |                         morphTarget.setName(targetNames.pop()); | ||||||
|  |                     } | ||||||
|                     for (Map.Entry<String, JsonElement> entry : target.getAsJsonObject().entrySet()) { |                     for (Map.Entry<String, JsonElement> entry : target.getAsJsonObject().entrySet()) { | ||||||
|                         String bufferType = entry.getKey(); |                         String bufferType = entry.getKey(); | ||||||
|                         VertexBuffer.Type type = getVertexBufferType(bufferType); |                         VertexBuffer.Type type = getVertexBufferType(bufferType); | ||||||
| @ -412,7 +425,8 @@ public class GltfLoader implements AssetLoader { | |||||||
|                     mesh.addMorphTarget(morphTarget); |                     mesh.addMorphTarget(morphTarget); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 
 |          | ||||||
|  |             //Read mesh extras | ||||||
|             mesh = customContentManager.readExtensionAndExtras("primitive", meshObject, mesh); |             mesh = customContentManager.readExtensionAndExtras("primitive", meshObject, mesh); | ||||||
| 
 | 
 | ||||||
|             Geometry geom = new Geometry(null, mesh); |             Geometry geom = new Geometry(null, mesh); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user