Explorar o código

Fixes an issue with animation speed being wrongly applied

Nehon %!s(int64=7) %!d(string=hai) anos
pai
achega
3aeb7350ae

+ 16 - 4
jme3-core/src/main/java/com/jme3/anim/AnimComposer.java

@@ -144,10 +144,12 @@ public class AnimComposer extends AbstractControl {
             if (currentAction == null) {
                 continue;
             }
-            layer.time += tpf;
+            layer.advance(tpf);
+
             currentAction.setMask(layer.mask);
-            boolean running = currentAction.interpolate(layer.time * globalSpeed);
+            boolean running = currentAction.interpolate(layer.time);
             currentAction.setMask(null);
+
             if (!running) {
                 layer.time = 0;
             }
@@ -214,11 +216,21 @@ public class AnimComposer extends AbstractControl {
         oc.writeStringSavableMap(animClipMap, "animClipMap", new HashMap<String, AnimClip>());
     }
 
-    public static class Layer implements JmeCloneable {
+    private class Layer implements JmeCloneable {
         private Action currentAction;
         private AnimationMask mask;
         private float weight;
-        private float time;
+        private double time;
+
+        public void advance(float tpf) {
+            time += tpf * currentAction.getSpeed() * globalSpeed;
+            // make sure negative time is in [0, length] range
+            if (time < 0) {
+                double length = currentAction.getLength();
+                time = (time % length + length) % length;
+            }
+
+        }
 
         @Override
         public Object jmeClone() {

+ 21 - 10
jme3-core/src/main/java/com/jme3/anim/tween/action/Action.java

@@ -9,6 +9,7 @@ public abstract class Action implements Tween {
     private double length;
     private double speed = 1;
     private AnimationMask mask;
+    private boolean forward = true;
 
     protected Action(Tween... tweens) {
         this.actions = new Action[tweens.length];
@@ -22,16 +23,6 @@ public abstract class Action implements Tween {
         }
     }
 
-    @Override
-    public boolean interpolate(double t) {
-        t = t * speed;
-        // make sure negative time is in [0, length] range
-        t = (t % length + length) % length;
-        return subInterpolate(t);
-    }
-
-    public abstract boolean subInterpolate(double t);
-
     @Override
     public double getLength() {
         return length;
@@ -47,6 +38,11 @@ public abstract class Action implements Tween {
 
     public void setSpeed(double speed) {
         this.speed = speed;
+        if( speed < 0){
+            setForward(false);
+        } else {
+            setForward(true);
+        }
     }
 
     public AnimationMask getMask() {
@@ -56,4 +52,19 @@ public abstract class Action implements Tween {
     public void setMask(AnimationMask mask) {
         this.mask = mask;
     }
+
+    protected boolean isForward() {
+        return forward;
+    }
+
+    protected void setForward(boolean forward) {
+        if(this.forward == forward){
+            return;
+        }
+        this.forward = forward;
+        for (Action action : actions) {
+            action.setForward(forward);
+        }
+
+    }
 }

+ 10 - 5
jme3-core/src/main/java/com/jme3/anim/tween/action/BaseAction.java

@@ -4,30 +4,35 @@ import com.jme3.anim.tween.ContainsTweens;
 import com.jme3.anim.tween.Tween;
 import com.jme3.util.SafeArrayList;
 
+import java.util.Collections;
+import java.util.List;
+
 public class BaseAction extends Action {
 
     private Tween tween;
-    private SafeArrayList<Action> subActions = new SafeArrayList<>(Action.class);
 
     public BaseAction(Tween tween) {
         this.tween = tween;
         setLength(tween.getLength());
-        gatherActions(tween);
+        List<Action> subActions = new SafeArrayList<>(Action.class);
+        gatherActions(tween, subActions);
+        actions = new Action[subActions.size()];
+        subActions.toArray(actions);
     }
 
-    private void gatherActions(Tween tween) {
+    private void gatherActions(Tween tween, List<Action> subActions) {
         if (tween instanceof Action) {
             subActions.add((Action) tween);
         } else if (tween instanceof ContainsTweens) {
             Tween[] tweens = ((ContainsTweens) tween).getTweens();
             for (Tween t : tweens) {
-                gatherActions(t);
+                gatherActions(t, subActions);
             }
         }
     }
 
     @Override
-    public boolean subInterpolate(double t) {
+    public boolean interpolate(double t) {
         return tween.interpolate(t);
     }
 }

+ 8 - 3
jme3-core/src/main/java/com/jme3/anim/tween/action/BlendableAction.java

@@ -3,6 +3,7 @@ package com.jme3.anim.tween.action;
 import com.jme3.anim.tween.AbstractTween;
 import com.jme3.anim.tween.Tween;
 import com.jme3.anim.util.HasLocalTransform;
+import com.jme3.math.FastMath;
 import com.jme3.math.Transform;
 
 import java.util.Collection;
@@ -19,13 +20,12 @@ public abstract class BlendableAction extends Action {
         super(tweens);
     }
 
-
     public void setCollectTransformDelegate(BlendableAction delegate) {
         this.collectTransformDelegate = delegate;
     }
 
     @Override
-    public boolean subInterpolate(double t) {
+    public boolean interpolate(double t) {
         // Sanity check the inputs
         if (t < 0) {
             return true;
@@ -35,7 +35,12 @@ public abstract class BlendableAction extends Action {
             if (transition.getLength() > getLength()) {
                 transition.setLength(getLength());
             }
-            transition.interpolate(t);
+            if(isForward()) {
+                transition.interpolate(t);
+            } else {
+                float v = Math.max((float)(getLength() - t), 0f);
+                transition.interpolate(v);
+            }
         } else {
             transitionWeight = 1f;
         }

+ 10 - 4
jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java

@@ -153,7 +153,7 @@ public class TestAnimMigration extends SimpleApplication {
                     action.getBlendSpace().setValue(blendValue);
                     action.setSpeed(blendValue);
                 }
-                System.err.println(blendValue);
+                //System.err.println(blendValue);
             }
         }, "blendUp", "blendDown");
     }
@@ -172,10 +172,15 @@ public class TestAnimMigration extends SimpleApplication {
             for (String name : composer.getAnimClipsNames()) {
                 anims.add(name);
             }
-            composer.actionSequence("Sequence",
+            composer.actionSequence("Sequence1",
                     composer.makeAction("Walk"),
                     composer.makeAction("Run"),
-                    composer.makeAction("Jumping")).setSpeed(2);
+                    composer.makeAction("Jumping")).setSpeed(1);
+
+            composer.actionSequence("Sequence2",
+                    composer.makeAction("Walk"),
+                    composer.makeAction("Run"),
+                    composer.makeAction("Jumping")).setSpeed(-1);
 
             action = composer.actionBlended("Blend", new LinearBlendSpace(1, 4),
                     "Walk", "Run");
@@ -186,8 +191,9 @@ public class TestAnimMigration extends SimpleApplication {
 
             composer.makeLayer("LeftArm", ArmatureMask.createMask(sc.getArmature(), "shoulder.L"));
 
-            anims.addFirst("Sequence");
             anims.addFirst("Blend");
+            anims.addFirst("Sequence2");
+            anims.addFirst("Sequence1");
 
             if (anims.isEmpty()) {
                 return;