From 3aeb7350ae860356b73305bdf1aaf4d93335a016 Mon Sep 17 00:00:00 2001 From: Nehon Date: Thu, 19 Apr 2018 08:00:38 +0200 Subject: [PATCH] Fixes an issue with animation speed being wrongly applied --- .../main/java/com/jme3/anim/AnimComposer.java | 20 +++++++++--- .../com/jme3/anim/tween/action/Action.java | 31 +++++++++++++------ .../jme3/anim/tween/action/BaseAction.java | 15 ++++++--- .../anim/tween/action/BlendableAction.java | 11 +++++-- .../model/anim/TestAnimMigration.java | 14 ++++++--- 5 files changed, 65 insertions(+), 26 deletions(-) diff --git a/jme3-core/src/main/java/com/jme3/anim/AnimComposer.java b/jme3-core/src/main/java/com/jme3/anim/AnimComposer.java index 4b115037b..646289367 100644 --- a/jme3-core/src/main/java/com/jme3/anim/AnimComposer.java +++ b/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()); } - 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() { diff --git a/jme3-core/src/main/java/com/jme3/anim/tween/action/Action.java b/jme3-core/src/main/java/com/jme3/anim/tween/action/Action.java index 85bd9ae01..e4038caff 100644 --- a/jme3-core/src/main/java/com/jme3/anim/tween/action/Action.java +++ b/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); + } + + } } diff --git a/jme3-core/src/main/java/com/jme3/anim/tween/action/BaseAction.java b/jme3-core/src/main/java/com/jme3/anim/tween/action/BaseAction.java index c3c021530..d2e891343 100644 --- a/jme3-core/src/main/java/com/jme3/anim/tween/action/BaseAction.java +++ b/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 subActions = new SafeArrayList<>(Action.class); public BaseAction(Tween tween) { this.tween = tween; setLength(tween.getLength()); - gatherActions(tween); + List 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 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); } } diff --git a/jme3-core/src/main/java/com/jme3/anim/tween/action/BlendableAction.java b/jme3-core/src/main/java/com/jme3/anim/tween/action/BlendableAction.java index f1bcef9f2..0ba79d841 100644 --- a/jme3-core/src/main/java/com/jme3/anim/tween/action/BlendableAction.java +++ b/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; } diff --git a/jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java b/jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java index df19c652e..18cbb0275 100644 --- a/jme3-examples/src/main/java/jme3test/model/anim/TestAnimMigration.java +++ b/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;