Forráskód Böngészése

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.
Ali-RS 4 éve
szülő
commit
6644cca83f
1 módosított fájl, 29 hozzáadás és 15 törlés
  1. 29 15
      jme3-core/src/main/java/com/jme3/anim/MorphControl.java

+ 29 - 15
jme3-core/src/main/java/com/jme3/anim/MorphControl.java

@@ -31,12 +31,10 @@
  */
 package com.jme3.anim;
 
-import com.jme3.export.InputCapsule;
-import com.jme3.export.JmeExporter;
-import com.jme3.export.JmeImporter;
-import com.jme3.export.OutputCapsule;
-import com.jme3.export.Savable;
-import com.jme3.material.*;
+import com.jme3.export.*;
+import com.jme3.material.MatParam;
+import com.jme3.material.MatParamOverride;
+import com.jme3.material.Material;
 import com.jme3.renderer.*;
 import com.jme3.scene.*;
 import com.jme3.scene.control.AbstractControl;
@@ -47,6 +45,7 @@ import com.jme3.util.SafeArrayList;
 import com.jme3.util.clone.Cloner;
 import java.io.IOException;
 import java.nio.FloatBuffer;
+import java.util.ArrayList;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -55,6 +54,9 @@ import java.util.logging.Logger;
  * All stock shaders only support morphing these 3 buffers, but note that MorphTargets can have any type of buffers.
  * If you want to use other types of buffers you will need a custom MorphControl and a custom shader.
  *
+ * Note that if morphed children are attached to or detached from the sub graph after the MorphControl is added to
+ * spatial, you must detach and attach the control again for the changes to get reflected.
+ *
  * @author Rémy Bouquet
  */
 public class MorphControl extends AbstractControl implements Savable {
@@ -65,6 +67,7 @@ public class MorphControl extends AbstractControl implements Savable {
     private final static float MIN_WEIGHT = 0.005f;
 
     private static final String TAG_APPROXIMATE = "approximateTangents";
+    private static final String TAG_TARGETS = "targets";
 
     private SafeArrayList<Geometry> targets = new SafeArrayList<>(Geometry.class);
     private TargetLocator targetLocator = new TargetLocator();
@@ -79,22 +82,31 @@ public class MorphControl extends AbstractControl implements Savable {
     private static final VertexBuffer.Type bufferTypes[] = VertexBuffer.Type.values();
 
     @Override
-    protected void controlUpdate(float tpf) {
-        if (!enabled) {
-            return;
+    public void setSpatial(Spatial spatial) {
+        super.setSpatial(spatial);
+
+        // Remove matparam override from the old targets
+        for (Geometry target : targets.getArray()) {
+            target.removeMatParamOverride(nullNumberOfBones);
         }
+
         // gathering geometries in the sub graph.
-        // This must be done in the update phase as the gathering might add a matparam override
+        // This must not be done in the render phase as the gathering might add a matparam override
+        // which then will throw an IllegalStateException if done in the render phase.
         targets.clear();
-        this.spatial.depthFirstTraversal(targetLocator);
+        if (spatial != null) {
+            spatial.depthFirstTraversal(targetLocator);
+        }
+    }
+
+    @Override
+    protected void controlUpdate(float tpf) {
+
     }
 
     @Override
     protected void controlRender(RenderManager rm, ViewPort vp) {
-        if (!enabled) {
-            return;
-        }
-        for (Geometry geom : targets) {
+        for (Geometry geom : targets.getArray()) {
             Mesh mesh = geom.getMesh();
             if (!geom.isDirtyMorph()) {
                 continue;
@@ -428,6 +440,7 @@ public class MorphControl extends AbstractControl implements Savable {
         super.read(importer);
         InputCapsule capsule = importer.getCapsule(this);
         approximateTangents = capsule.readBoolean(TAG_APPROXIMATE, true);
+        targets.addAll(capsule.readSavableArrayList(TAG_TARGETS, null));
     }
 
     /**
@@ -442,6 +455,7 @@ public class MorphControl extends AbstractControl implements Savable {
         super.write(exporter);
         OutputCapsule capsule = exporter.getCapsule(this);
         capsule.write(approximateTangents, TAG_APPROXIMATE, true);
+        capsule.writeSavableArrayList(new ArrayList(targets), TAG_TARGETS, null);
     }
 
     private class TargetLocator extends SceneGraphVisitorAdapter {