Skip to content

Commit 6644cca

Browse files
Ali-RSstephengold
authored andcommitted
MorphControl: serialize target list & add minor cleanups (#1553)
* MorphControl: move target locating out of update loop into setSpatial() & add minor cleanups. * Serialize target list * Add javadoc * Fix comment.
1 parent 70e1749 commit 6644cca

File tree

1 file changed

+29
-15
lines changed

1 file changed

+29
-15
lines changed

jme3-core/src/main/java/com/jme3/anim/MorphControl.java

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,10 @@
3131
*/
3232
package com.jme3.anim;
3333

34-
import com.jme3.export.InputCapsule;
35-
import com.jme3.export.JmeExporter;
36-
import com.jme3.export.JmeImporter;
37-
import com.jme3.export.OutputCapsule;
38-
import com.jme3.export.Savable;
39-
import com.jme3.material.*;
34+
import com.jme3.export.*;
35+
import com.jme3.material.MatParam;
36+
import com.jme3.material.MatParamOverride;
37+
import com.jme3.material.Material;
4038
import com.jme3.renderer.*;
4139
import com.jme3.scene.*;
4240
import com.jme3.scene.control.AbstractControl;
@@ -47,6 +45,7 @@
4745
import com.jme3.util.clone.Cloner;
4846
import java.io.IOException;
4947
import java.nio.FloatBuffer;
48+
import java.util.ArrayList;
5049
import java.util.logging.Level;
5150
import java.util.logging.Logger;
5251

@@ -55,6 +54,9 @@
5554
* All stock shaders only support morphing these 3 buffers, but note that MorphTargets can have any type of buffers.
5655
* If you want to use other types of buffers you will need a custom MorphControl and a custom shader.
5756
*
57+
* Note that if morphed children are attached to or detached from the sub graph after the MorphControl is added to
58+
* spatial, you must detach and attach the control again for the changes to get reflected.
59+
*
5860
* @author Rémy Bouquet
5961
*/
6062
public class MorphControl extends AbstractControl implements Savable {
@@ -65,6 +67,7 @@ public class MorphControl extends AbstractControl implements Savable {
6567
private final static float MIN_WEIGHT = 0.005f;
6668

6769
private static final String TAG_APPROXIMATE = "approximateTangents";
70+
private static final String TAG_TARGETS = "targets";
6871

6972
private SafeArrayList<Geometry> targets = new SafeArrayList<>(Geometry.class);
7073
private TargetLocator targetLocator = new TargetLocator();
@@ -79,22 +82,31 @@ public class MorphControl extends AbstractControl implements Savable {
7982
private static final VertexBuffer.Type bufferTypes[] = VertexBuffer.Type.values();
8083

8184
@Override
82-
protected void controlUpdate(float tpf) {
83-
if (!enabled) {
84-
return;
85+
public void setSpatial(Spatial spatial) {
86+
super.setSpatial(spatial);
87+
88+
// Remove matparam override from the old targets
89+
for (Geometry target : targets.getArray()) {
90+
target.removeMatParamOverride(nullNumberOfBones);
8591
}
92+
8693
// gathering geometries in the sub graph.
87-
// This must be done in the update phase as the gathering might add a matparam override
94+
// This must not be done in the render phase as the gathering might add a matparam override
95+
// which then will throw an IllegalStateException if done in the render phase.
8896
targets.clear();
89-
this.spatial.depthFirstTraversal(targetLocator);
97+
if (spatial != null) {
98+
spatial.depthFirstTraversal(targetLocator);
99+
}
100+
}
101+
102+
@Override
103+
protected void controlUpdate(float tpf) {
104+
90105
}
91106

92107
@Override
93108
protected void controlRender(RenderManager rm, ViewPort vp) {
94-
if (!enabled) {
95-
return;
96-
}
97-
for (Geometry geom : targets) {
109+
for (Geometry geom : targets.getArray()) {
98110
Mesh mesh = geom.getMesh();
99111
if (!geom.isDirtyMorph()) {
100112
continue;
@@ -428,6 +440,7 @@ public void read(JmeImporter importer) throws IOException {
428440
super.read(importer);
429441
InputCapsule capsule = importer.getCapsule(this);
430442
approximateTangents = capsule.readBoolean(TAG_APPROXIMATE, true);
443+
targets.addAll(capsule.readSavableArrayList(TAG_TARGETS, null));
431444
}
432445

433446
/**
@@ -442,6 +455,7 @@ public void write(JmeExporter exporter) throws IOException {
442455
super.write(exporter);
443456
OutputCapsule capsule = exporter.getCapsule(this);
444457
capsule.write(approximateTangents, TAG_APPROXIMATE, true);
458+
capsule.writeSavableArrayList(new ArrayList(targets), TAG_TARGETS, null);
445459
}
446460

447461
private class TargetLocator extends SceneGraphVisitorAdapter {

0 commit comments

Comments
 (0)