|
@@ -1,8 +1,41 @@
|
|
|
|
+/*
|
|
|
|
+ * Copyright (c) 2009-2022 jMonkeyEngine
|
|
|
|
+ * All rights reserved.
|
|
|
|
+ *
|
|
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
|
|
+ * modification, are permitted provided that the following conditions are
|
|
|
|
+ * met:
|
|
|
|
+ *
|
|
|
|
+ * * Redistributions of source code must retain the above copyright
|
|
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
|
|
+ *
|
|
|
|
+ * * Redistributions in binary form must reproduce the above copyright
|
|
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
|
|
+ *
|
|
|
|
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
|
|
|
+ * may be used to endorse or promote products derived from this software
|
|
|
|
+ * without specific prior written permission.
|
|
|
|
+ *
|
|
|
|
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
|
|
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
|
|
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
|
|
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
|
|
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
|
|
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
|
|
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
|
|
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
|
|
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
|
|
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
+ */
|
|
package com.jme3.anim.tween.action;
|
|
package com.jme3.anim.tween.action;
|
|
|
|
|
|
import com.jme3.anim.util.HasLocalTransform;
|
|
import com.jme3.anim.util.HasLocalTransform;
|
|
|
|
+import com.jme3.math.FastMath;
|
|
import com.jme3.math.Transform;
|
|
import com.jme3.math.Transform;
|
|
|
|
|
|
|
|
+import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.Collection;
|
|
import java.util.HashMap;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import java.util.Map;
|
|
@@ -14,6 +47,7 @@ public class BlendAction extends BlendableAction {
|
|
final private BlendSpace blendSpace;
|
|
final private BlendSpace blendSpace;
|
|
private float blendWeight;
|
|
private float blendWeight;
|
|
final private double[] timeFactor;
|
|
final private double[] timeFactor;
|
|
|
|
+ private double[] speedFactors;
|
|
final private Map<HasLocalTransform, Transform> targetMap = new HashMap<>();
|
|
final private Map<HasLocalTransform, Transform> targetMap = new HashMap<>();
|
|
|
|
|
|
public BlendAction(BlendSpace blendSpace, BlendableAction... actions) {
|
|
public BlendAction(BlendSpace blendSpace, BlendableAction... actions) {
|
|
@@ -47,6 +81,10 @@ public class BlendAction extends BlendableAction {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ // Calculate default factors that dynamically adjust speed to resolve
|
|
|
|
+ // slow motion effect on stretched actions.
|
|
|
|
+ applyDefaultSpeedFactors();
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -85,6 +123,58 @@ public class BlendAction extends BlendableAction {
|
|
return blendSpace;
|
|
return blendSpace;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
+ public double getSpeed() {
|
|
|
|
+ if (speedFactors != null) {
|
|
|
|
+ return super.getSpeed() * FastMath.interpolateLinear(blendWeight,
|
|
|
|
+ (float) speedFactors[firstActiveIndex],
|
|
|
|
+ (float) speedFactors[secondActiveIndex]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return super.getSpeed();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * @return The speed factor or null if there is none
|
|
|
|
+ */
|
|
|
|
+ public double[] getSpeedFactors() {
|
|
|
|
+ return speedFactors;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Used to resolve the slow motion side effect caused by stretching actions that
|
|
|
|
+ * doesn't have the same length.
|
|
|
|
+ *
|
|
|
|
+ * @param speedFactors The speed factors for each child action. BlendAction will
|
|
|
|
+ * interpolate factor for current frame based on blend weight
|
|
|
|
+ * and will multiply it to speed.
|
|
|
|
+ */
|
|
|
|
+ public void setSpeedFactors(double... speedFactors) {
|
|
|
|
+ if (speedFactors.length != actions.length) {
|
|
|
|
+ throw new IllegalArgumentException("Array length must be " + actions.length);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ this.speedFactors = speedFactors;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void clearSpeedFactors() {
|
|
|
|
+ this.speedFactors = null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * BlendAction will stretch it's child actions if they don't have the same length.
|
|
|
|
+ * This might cause stretched animations to run slowly. This method generates factors
|
|
|
|
+ * based on how much actions are stretched. Multiplying this factor to base speed will
|
|
|
|
+ * resolve the slow-motion side effect caused by stretching. BlendAction will use the
|
|
|
|
+ * blend weight taken from BlendSpace to interpolate the speed factor for current frame.
|
|
|
|
+ */
|
|
|
|
+ public void applyDefaultSpeedFactors() {
|
|
|
|
+ double[] factors = Arrays.stream(getActions())
|
|
|
|
+ .mapToDouble(action -> getLength() / action.getLength())
|
|
|
|
+ .toArray();
|
|
|
|
+ setSpeedFactors(factors);
|
|
|
|
+ }
|
|
|
|
+
|
|
protected void setFirstActiveIndex(int index) {
|
|
protected void setFirstActiveIndex(int index) {
|
|
this.firstActiveIndex = index;
|
|
this.firstActiveIndex = index;
|
|
}
|
|
}
|