|
@@ -42,8 +42,6 @@ import com.jme3.renderer.RenderManager;
|
|
|
import com.jme3.renderer.ViewPort;
|
|
|
import com.jme3.scene.control.AbstractControl;
|
|
|
import com.jme3.util.clone.Cloner;
|
|
|
-import com.jme3.util.clone.JmeCloneable;
|
|
|
-
|
|
|
import java.io.IOException;
|
|
|
import java.util.*;
|
|
|
|
|
@@ -63,13 +61,13 @@ public class AnimComposer extends AbstractControl {
|
|
|
|
|
|
private Map<String, Action> actions = new HashMap<>();
|
|
|
private float globalSpeed = 1f;
|
|
|
- private Map<String, Layer> layers = new LinkedHashMap<>();
|
|
|
+ private Map<String, AnimLayer> layers = new LinkedHashMap<>(4);
|
|
|
|
|
|
/**
|
|
|
* Instantiate a composer with a single layer, no actions, and no clips.
|
|
|
*/
|
|
|
public AnimComposer() {
|
|
|
- layers.put(DEFAULT_LAYER, new Layer(this));
|
|
|
+ layers.put(DEFAULT_LAYER, new AnimLayer(this, DEFAULT_LAYER, null));
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -135,14 +133,10 @@ public class AnimComposer extends AbstractControl {
|
|
|
* @return The action corresponding to the given name.
|
|
|
*/
|
|
|
public Action setCurrentAction(String actionName, String layerName) {
|
|
|
- Layer l = layers.get(layerName);
|
|
|
- if (l == null) {
|
|
|
- throw new IllegalArgumentException("Unknown layer " + layerName);
|
|
|
- }
|
|
|
-
|
|
|
+ AnimLayer l = getLayer(layerName);
|
|
|
Action currentAction = action(actionName);
|
|
|
- l.time = 0;
|
|
|
- l.currentAction = currentAction;
|
|
|
+ l.setCurrentAction(currentAction);
|
|
|
+
|
|
|
return currentAction;
|
|
|
}
|
|
|
|
|
@@ -162,12 +156,10 @@ public class AnimComposer extends AbstractControl {
|
|
|
* @return The action corresponding to the given name.
|
|
|
*/
|
|
|
public Action getCurrentAction(String layerName) {
|
|
|
- Layer l = layers.get(layerName);
|
|
|
- if (l == null) {
|
|
|
- throw new IllegalArgumentException("Unknown layer " + layerName);
|
|
|
- }
|
|
|
-
|
|
|
- return l.currentAction;
|
|
|
+ AnimLayer l = getLayer(layerName);
|
|
|
+ Action result = l.getCurrentAction();
|
|
|
+
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -183,13 +175,8 @@ public class AnimComposer extends AbstractControl {
|
|
|
* @param layerName The name of the layer we want to remove its action.
|
|
|
*/
|
|
|
public void removeCurrentAction(String layerName) {
|
|
|
- Layer l = layers.get(layerName);
|
|
|
- if (l == null) {
|
|
|
- throw new IllegalArgumentException("Unknown layer " + layerName);
|
|
|
- }
|
|
|
-
|
|
|
- l.time = 0;
|
|
|
- l.currentAction = null;
|
|
|
+ AnimLayer l = getLayer(layerName);
|
|
|
+ l.setCurrentAction(null);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -208,11 +195,10 @@ public class AnimComposer extends AbstractControl {
|
|
|
* @return the time (in seconds)
|
|
|
*/
|
|
|
public double getTime(String layerName) {
|
|
|
- Layer l = layers.get(layerName);
|
|
|
- if (l == null) {
|
|
|
- throw new IllegalArgumentException("Unknown layer " + layerName);
|
|
|
- }
|
|
|
- return l.time;
|
|
|
+ AnimLayer l = getLayer(layerName);
|
|
|
+ double result = l.getTime();
|
|
|
+
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -231,19 +217,12 @@ public class AnimComposer extends AbstractControl {
|
|
|
* @param time the desired time (in seconds)
|
|
|
*/
|
|
|
public void setTime(String layerName, double time) {
|
|
|
- Layer l = layers.get(layerName);
|
|
|
- if (l == null) {
|
|
|
- throw new IllegalArgumentException("Unknown layer " + layerName);
|
|
|
- }
|
|
|
- if (l.currentAction == null) {
|
|
|
+ AnimLayer l = getLayer(layerName);
|
|
|
+ if (l.getCurrentAction() == null) {
|
|
|
throw new RuntimeException("There is no action running in layer " + layerName);
|
|
|
}
|
|
|
- double length = l.currentAction.getLength();
|
|
|
- if (time >= 0) {
|
|
|
- l.time = time % length;
|
|
|
- } else {
|
|
|
- l.time = time % length + length;
|
|
|
- }
|
|
|
+
|
|
|
+ l.setTime(time);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -324,8 +303,7 @@ public class AnimComposer extends AbstractControl {
|
|
|
* @param mask the desired mask for the new layer (alias created)
|
|
|
*/
|
|
|
public void makeLayer(String name, AnimationMask mask) {
|
|
|
- Layer l = new Layer(this);
|
|
|
- l.mask = mask;
|
|
|
+ AnimLayer l = new AnimLayer(this, name, mask);
|
|
|
layers.put(name, l);
|
|
|
}
|
|
|
|
|
@@ -376,9 +354,8 @@ public class AnimComposer extends AbstractControl {
|
|
|
* Reset all layers to t=0 with no current action.
|
|
|
*/
|
|
|
public void reset() {
|
|
|
- for (Layer layer : layers.values()) {
|
|
|
- layer.currentAction = null;
|
|
|
- layer.time = 0;
|
|
|
+ for (AnimLayer layer : layers.values()) {
|
|
|
+ layer.setCurrentAction(null);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -410,20 +387,8 @@ public class AnimComposer extends AbstractControl {
|
|
|
*/
|
|
|
@Override
|
|
|
protected void controlUpdate(float tpf) {
|
|
|
- for (Layer layer : layers.values()) {
|
|
|
- Action currentAction = layer.currentAction;
|
|
|
- if (currentAction == null) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- layer.advance(tpf);
|
|
|
-
|
|
|
- currentAction.setMask(layer.mask);
|
|
|
- boolean running = currentAction.interpolate(layer.time);
|
|
|
- currentAction.setMask(null);
|
|
|
-
|
|
|
- if (!running) {
|
|
|
- layer.time = 0;
|
|
|
- }
|
|
|
+ for (AnimLayer layer : layers.values()) {
|
|
|
+ layer.update(tpf);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -456,6 +421,20 @@ public class AnimComposer extends AbstractControl {
|
|
|
this.globalSpeed = globalSpeed;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Provides access to the named layer.
|
|
|
+ *
|
|
|
+ * @param layerName the name of the layer to access
|
|
|
+ * @return the pre-existing instance
|
|
|
+ */
|
|
|
+ public AnimLayer getLayer(String layerName) {
|
|
|
+ AnimLayer result = layers.get(layerName);
|
|
|
+ if (result == null) {
|
|
|
+ throw new IllegalArgumentException("Unknown layer " + layerName);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Access the manager of the named layer.
|
|
|
*
|
|
@@ -463,12 +442,20 @@ public class AnimComposer extends AbstractControl {
|
|
|
* @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);
|
|
|
- }
|
|
|
+ AnimLayer layer = getLayer(layerName);
|
|
|
+ Object result = layer.getManager();
|
|
|
|
|
|
- return layer.manager;
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Enumerates the names of all layers.
|
|
|
+ *
|
|
|
+ * @return an unmodifiable set of names
|
|
|
+ */
|
|
|
+ public Set<String> getLayerNames() {
|
|
|
+ Set<String> result = Collections.unmodifiableSet(layers.keySet());
|
|
|
+ return result;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -479,12 +466,8 @@ public class AnimComposer extends AbstractControl {
|
|
|
* 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;
|
|
|
+ AnimLayer layer = getLayer(layerName);
|
|
|
+ layer.setManager(manager);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -525,7 +508,7 @@ public class AnimComposer extends AbstractControl {
|
|
|
actions = act;
|
|
|
animClipMap = clips;
|
|
|
|
|
|
- Map<String, Layer> newLayers = new LinkedHashMap<>();
|
|
|
+ Map<String, AnimLayer> newLayers = new LinkedHashMap<>();
|
|
|
for (String key : layers.keySet()) {
|
|
|
newLayers.put(key, cloner.clone(layers.get(key)));
|
|
|
}
|
|
@@ -564,42 +547,4 @@ public class AnimComposer extends AbstractControl {
|
|
|
oc.writeStringSavableMap(animClipMap, "animClipMap", new HashMap<String, AnimClip>());
|
|
|
oc.write(globalSpeed, "globalSpeed", 1f);
|
|
|
}
|
|
|
-
|
|
|
- private static class Layer implements JmeCloneable {
|
|
|
- private AnimComposer ac;
|
|
|
- private Action currentAction;
|
|
|
- private AnimationMask mask;
|
|
|
- private double time;
|
|
|
- private Object manager;
|
|
|
-
|
|
|
- public Layer(AnimComposer ac) {
|
|
|
- this.ac = ac;
|
|
|
- }
|
|
|
-
|
|
|
- public void advance(float tpf) {
|
|
|
- time += tpf * currentAction.getSpeed() * ac.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() {
|
|
|
- try {
|
|
|
- Layer clone = (Layer) super.clone();
|
|
|
- return clone;
|
|
|
- } catch (CloneNotSupportedException ex) {
|
|
|
- throw new AssertionError();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void cloneFields(Cloner cloner, Object original) {
|
|
|
- ac = cloner.clone(ac);
|
|
|
- currentAction = null;
|
|
|
- }
|
|
|
- }
|
|
|
}
|