Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for gltf morph names. #1100

Merged
merged 11 commits into from Jul 11, 2019
30 changes: 30 additions & 0 deletions jme3-core/src/main/java/com/jme3/scene/Geometry.java
Expand Up @@ -601,6 +601,22 @@ public void setMorphState(float[] state) {
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
Expand Down Expand Up @@ -629,6 +645,20 @@ public float[] getMorphState() {
}
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.
Expand Down
36 changes: 36 additions & 0 deletions jme3-core/src/main/java/com/jme3/scene/Mesh.java
Expand Up @@ -1529,10 +1529,46 @@ public void addMorphTarget(MorphTarget target) {
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() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why getMorphTargetNames() is needed?
We can already access morph names using getMorphTargets().


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;
Ali-RS marked this conversation as resolved.
Show resolved Hide resolved
break;
}
}
return index;
}

@Override
public void write(JmeExporter ex) throws IOException {
Expand Down
20 changes: 19 additions & 1 deletion jme3-core/src/main/java/com/jme3/scene/mesh/MorphTarget.java
Expand Up @@ -11,6 +11,23 @@

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);
Expand All @@ -35,6 +52,7 @@ public void write(JmeExporter ex) throws IOException {
Buffer roData = entry.getValue().asReadOnlyBuffer();
oc.write((FloatBuffer) roData, entry.getKey().name(),null);
}
oc.write(name, "morphName", null);
}

@Override
Expand All @@ -46,6 +64,6 @@ public void read(JmeImporter im) throws IOException {
setBuffer(type, b);
}
}

name = ic.readString("morphName", null);
}
}
Expand Up @@ -397,10 +397,23 @@ public Geometry[] readMeshPrimitives(int meshIndex) throws IOException {
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);
Expand All @@ -412,7 +425,8 @@ public Geometry[] readMeshPrimitives(int meshIndex) throws IOException {
mesh.addMorphTarget(morphTarget);
}
}


//Read mesh extras
mesh = customContentManager.readExtensionAndExtras("primitive", meshObject, mesh);

Geometry geom = new Geometry(null, mesh);
Expand Down