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
|
||||||
@ -630,6 +646,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.
|
||||||
* Note that it depends on the material set on this geometry.
|
* Note that it depends on the material set on this geometry.
|
||||||
|
@ -1530,10 +1530,46 @@ public class Mesh implements Savable, Cloneable, JmeCloneable {
|
|||||||
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 {
|
||||||
OutputCapsule out = ex.getCapsule(this);
|
OutputCapsule out = ex.getCapsule(this);
|
||||||
|
@ -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);
|
||||||
@ -413,6 +426,7 @@ public class GltfLoader implements AssetLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//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