Bläddra i källkod

AnimEvent: solve bug where onStop() kills prior event on the same layer (#1537)

* AnimEvent: solve bug where onStop() kills prior event on the same layer

* AnimEvent: for clarity, use getAction() instead of action()

* AnimComposer: keep track of the manager for each layer

* AnimEvent: keep track of which event is managing each layer

* TestJaime: reset the model position each time the cinematic starts
Stephen Gold 4 år sedan
förälder
incheckning
cf0fae6bcf

+ 32 - 0
jme3-core/src/main/java/com/jme3/anim/AnimComposer.java

@@ -456,6 +456,37 @@ public class AnimComposer extends AbstractControl {
         this.globalSpeed = globalSpeed;
     }
 
+    /**
+     * Access the manager of the named layer.
+     *
+     * @param layerName the name of the layer to access
+     * @return the current manager (typically an AnimEvent) or null for none
+     */
+    public Object getLayerManager(String layerName) {
+        Layer layer = layers.get(layerName);
+        if (layer == null) {
+            throw new IllegalArgumentException("Unknown layer " + layerName);
+        }
+
+        return layer.manager;
+    }
+
+    /**
+     * Assign a manager to the named layer.
+     *
+     * @param layerName the name of the layer to modify
+     * @param manager the desired manager (typically an AnimEvent) or null for
+     * none
+     */
+    public void setLayerManager(String layerName, Object manager) {
+        Layer layer = layers.get(layerName);
+        if (layer == null) {
+            throw new IllegalArgumentException("Unknown layer " + layerName);
+        }
+
+        layer.manager = manager;
+    }
+
     /**
      * Create a shallow clone for the JME cloner.
      *
@@ -539,6 +570,7 @@ public class AnimComposer extends AbstractControl {
         private Action currentAction;
         private AnimationMask mask;
         private double time;
+        private Object manager;
 
         public Layer(AnimComposer ac) {
             this.ac = ac;

+ 12 - 3
jme3-core/src/main/java/com/jme3/cinematic/events/AnimEvent.java

@@ -121,8 +121,11 @@ public class AnimEvent extends AbstractCinematicEvent {
         logger.log(Level.INFO, "layer={0} action={1}",
                 new Object[]{layerName, actionName});
 
-        Action eventAction = composer.action(actionName);
-        eventAction.setSpeed(0f);
+        Object layerManager = composer.getLayerManager(layerName);
+        if (layerManager == this) {
+            Action eventAction = composer.action(actionName);
+            eventAction.setSpeed(0f);
+        }
     }
 
     /**
@@ -144,6 +147,7 @@ public class AnimEvent extends AbstractCinematicEvent {
             composer.setTime(layerName, 0.0);
         }
         eventAction.setSpeed(speed);
+        composer.setLayerManager(layerName, this);
     }
 
     /**
@@ -152,7 +156,12 @@ public class AnimEvent extends AbstractCinematicEvent {
     @Override
     public void onStop() {
         logger.log(Level.INFO, "");
-        composer.removeCurrentAction(layerName);
+
+        Object layerManager = composer.getLayerManager(layerName);
+        if (layerManager == this) {
+            composer.removeCurrentAction(layerName);
+            composer.setLayerManager(layerName, null);
+        }
     }
 
     /**

+ 9 - 0
jme3-examples/src/main/java/jme3test/animation/TestJaime.java

@@ -159,10 +159,19 @@ public class TestJaime  extends SimpleApplication {
         AnimClip forwardClip = af.buildAnimation(jaime);
         AnimComposer composer = jaime.getControl(AnimComposer.class);
         composer.addAnimClip(forwardClip);
+        /*
+         * Add a clip that warps the model to its starting position.
+         */
+        AnimFactory af2 = new AnimFactory(0.01f, "StartingPosition", 30f);
+        af2.addTimeTranslation(0f, new Vector3f(0f, 0f, -3f));
+        AnimClip startClip = af2.buildAnimation(jaime);
+        composer.addAnimClip(startClip);
 
         composer.makeLayer("SpatialLayer", null);
         String boneLayer = AnimComposer.DEFAULT_LAYER;
 
+        cinematic.addCinematicEvent(0f,
+                new AnimEvent(composer, "StartingPosition", "SpatialLayer"));
         cinematic.enqueueCinematicEvent(
                 new AnimEvent(composer, "Idle", boneLayer));
         float jumpStart = cinematic.enqueueCinematicEvent(