Added mixDuration resetTrack, added set/addEmptyAnimation methods.

This commit is contained in:
NathanSweet 2016-08-23 18:08:49 +02:00
parent fd81d31278
commit c9fdfdf501
3 changed files with 57 additions and 38 deletions

View File

@ -665,7 +665,7 @@ public class AnimationStateTest {
state.addAnimation(0, "events1", false, 0);
run(0.1f, 10, new TestListener() {
public void frame (float time) {
if (MathUtils.isEqual(time, 0.7f)) state.resetTrack(0);
if (MathUtils.isEqual(time, 0.7f)) state.resetTrack(0, 0);
}
});

View File

@ -240,11 +240,11 @@ public class AnimationState {
/** Removes all animations from all tracks, leaving skeletons in their last pose. */
public void clearTracks () {
for (int i = 0, n = tracks.size; i < n; i++) {
TrackEntry current = tracks.get(i);
if (current != null) clearTrack(current);
}
queue.drainDisabled = true;
for (int i = 0, n = tracks.size; i < n; i++)
clearTrack(i);
tracks.clear();
queue.drainDisabled = false;
queue.drain();
}
@ -253,11 +253,7 @@ public class AnimationState {
if (trackIndex >= tracks.size) return;
TrackEntry current = tracks.get(trackIndex);
if (current == null) return;
clearTrack(current);
queue.drain();
}
private void clearTrack (TrackEntry current) {
queue.end(current);
disposeNext(current);
@ -269,35 +265,30 @@ public class AnimationState {
}
tracks.set(current.trackIndex, null);
}
/** Removes all queued animations for all tracks and sets track entries which mix out the current animations, so any changes
* the animations have made to skeletons are reverted to the setup pose. */
public void resetTracks () {
for (int i = 0, n = tracks.size; i < n; i++) {
TrackEntry current = tracks.get(i);
if (current != null) resetTrack(current);
}
queue.drain();
}
/** Removes all queued animations and sets a track entry which mixes out the current animation, so any changes the animation
* has made to skeletons are reverted to the setup pose. */
public void resetTrack (int trackIndex) {
/** Removes all queued animations for all tracks and sets empty animations to mix out the current animations, so any changes
* the current animations have made to skeletons are reverted to the setup pose. */
public void resetTracks (float mixDuration) {
queue.drainDisabled = true;
for (int i = 0, n = tracks.size; i < n; i++)
resetTrack(i, mixDuration);
queue.drainDisabled = false;
queue.drain();
}
/** Removes all queued animations and sets an empty animation to mix out the current animation, so any changes the current
* animation has made to skeletons are reverted to the setup pose. */
public void resetTrack (int trackIndex, float mixDuration) {
if (trackIndex >= tracks.size) return;
TrackEntry current = tracks.get(trackIndex);
if (current == null) return;
resetTrack(current);
setEmptyAnimation(current.trackIndex, mixDuration);
queue.drain();
}
private void resetTrack (TrackEntry current) {
TrackEntry entry = trackEntry(current.trackIndex, emptyAnimation, false, current);
entry.mixDuration = 0;
current.trackTime = 0;
setCurrent(current.trackIndex, entry);
}
/** @param entry May be null. */
private void disposeNext (TrackEntry entry) {
TrackEntry next = entry.next;
@ -395,7 +386,6 @@ public class AnimationState {
* after {@link AnimationStateListener#end(TrackEntry)}. */
public TrackEntry setAnimation (int trackIndex, Animation animation, boolean loop) {
if (animation == null) throw new IllegalArgumentException("animation cannot be null.");
// if (animation == null) animation = emptyAnimation; // BOZO - Test.
TrackEntry current = expandToIndex(trackIndex);
if (current != null) {
if (current.nextTrackLast == -1) {
@ -455,6 +445,20 @@ public class AnimationState {
return entry;
}
public TrackEntry setEmptyAnimation (int trackIndex, float mixDuration) {
TrackEntry entry = setAnimation(trackIndex, emptyAnimation, false);
entry.mixDuration = mixDuration;
entry.trackEnd = mixDuration;
return entry;
}
public TrackEntry addEmptyAnimation (int trackIndex, float mixDuration, float delay) {
TrackEntry entry = addAnimation(trackIndex, emptyAnimation, false, delay);
entry.mixDuration = mixDuration;
entry.trackEnd = mixDuration;
return entry;
}
/** @param last May be null. */
private TrackEntry trackEntry (int trackIndex, Animation animation, boolean loop, TrackEntry last) {
TrackEntry entry = trackEntryPool.obtain();
@ -783,7 +787,7 @@ public class AnimationState {
private final Pool<TrackEntry> trackEntryPool;
private final Array objects = new Array();
private final IntArray eventTypes = new IntArray(); // If > 0 it's loop count for a complete event.
private boolean draining;
boolean drainDisabled;
public EventQueue (Array<AnimationStateListener> listeners, Pool<TrackEntry> trackEntryPool) {
this.listeners = listeners;
@ -822,8 +826,8 @@ public class AnimationState {
}
public void drain () {
if (draining) return; // Not reentrant.
draining = true;
if (drainDisabled) return; // Not reentrant.
drainDisabled = true;
Array objects = this.objects;
IntArray eventTypes = this.eventTypes;
@ -867,7 +871,7 @@ public class AnimationState {
}
clear();
draining = false;
drainDisabled = false;
}
public void clear () {

View File

@ -211,8 +211,16 @@ public class SkeletonViewer extends ApplicationAdapter {
}
void setAnimation () {
TrackEntry entry = state.setAnimation(0, ui.animationList.getSelected(), ui.loopCheckbox.isChecked());
entry.setTrackEnd(Integer.MAX_VALUE);
TrackEntry current = state.getCurrent(0);
if (current == null) {
state.setEmptyAnimation(0, 0);
TrackEntry entry = state.addAnimation(0, ui.animationList.getSelected(), ui.loopCheckbox.isChecked(), 0);
entry.setMixDuration(ui.mixSlider.getValue());
entry.setTrackEnd(Integer.MAX_VALUE);
} else {
TrackEntry entry = state.setAnimation(0, ui.animationList.getSelected(), ui.loopCheckbox.isChecked());
entry.setTrackEnd(Integer.MAX_VALUE);
}
}
public void render () {
@ -263,16 +271,23 @@ public class SkeletonViewer extends ApplicationAdapter {
ui.stage.act();
ui.stage.draw();
// Draw indicator for timeline position.
// Draw indicator lines for animation and mix times.
if (state != null) {
ShapeRenderer shapes = debugRenderer.getShapeRenderer();
TrackEntry entry = state.getCurrent(0);
if (entry != null) {
shapes.begin(ShapeType.Line);
float percent = entry.getAnimationTime() / entry.getAnimationEnd();
float x = ui.window.getRight() + (Gdx.graphics.getWidth() - ui.window.getRight()) * percent;
shapes.setColor(Color.CYAN);
shapes.begin(ShapeType.Line);
shapes.line(x, 0, x, 20);
percent = entry.getMixTime() / entry.getMixDuration();
x = ui.window.getRight() + (Gdx.graphics.getWidth() - ui.window.getRight()) * percent;
shapes.setColor(Color.RED);
shapes.line(x, 0, x, 20);
shapes.end();
}
}
@ -488,7 +503,7 @@ public class SkeletonViewer extends ApplicationAdapter {
if (state != null) {
String name = animationList.getSelected();
if (name == null)
state.resetTrack(0);
state.resetTrack(0, ui.mixSlider.getValue());
else
setAnimation();
}