mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 22:34:53 +08:00
Minor AnimationState fixes.
- Added mixAlpha to keep it separate from alpha. - Stored mixAlpha on the "mixing to" entry (where mixTime, etc is stored), not the mixingFrom entry. - Fixed weirdness using TrackEntry alpha. - Removed clearing timelinesRotation to avoid rotations flipping to other side when a new animation is set. - Added TrackEntry#resetRotationDirections to give control over rotations when using alpha over long periods of time.
This commit is contained in:
parent
7ac77fb177
commit
fae60d8899
@ -163,7 +163,7 @@ public class AnimationState {
|
||||
|
||||
// Apply mixing from entries first.
|
||||
float mix = current.alpha;
|
||||
if (current.mixingFrom != null) mix = applyMixingFrom(current, skeleton, mix);
|
||||
if (current.mixingFrom != null) mix *= applyMixingFrom(current, skeleton);
|
||||
|
||||
// Apply current entry.
|
||||
float animationLast = current.animationLast, animationTime = current.getAnimationTime();
|
||||
@ -195,9 +195,9 @@ public class AnimationState {
|
||||
queue.drain();
|
||||
}
|
||||
|
||||
private float applyMixingFrom (TrackEntry entry, Skeleton skeleton, float alpha) {
|
||||
private float applyMixingFrom (TrackEntry entry, Skeleton skeleton) {
|
||||
TrackEntry from = entry.mixingFrom;
|
||||
if (from.mixingFrom != null) applyMixingFrom(from, skeleton, alpha);
|
||||
if (from.mixingFrom != null) applyMixingFrom(from, skeleton);
|
||||
|
||||
float mix;
|
||||
if (entry.mixDuration == 0) // Single frame mix to undo mixingFrom changes.
|
||||
@ -205,16 +205,15 @@ public class AnimationState {
|
||||
else {
|
||||
mix = entry.mixTime / entry.mixDuration;
|
||||
if (mix > 1) mix = 1;
|
||||
mix *= alpha;
|
||||
}
|
||||
|
||||
Array<Event> events = mix < from.eventThreshold ? this.events : null;
|
||||
boolean attachments = mix < from.attachmentThreshold, drawOrder = mix < from.drawOrderThreshold;
|
||||
float animationLast = from.animationLast, animationTime = from.getAnimationTime();
|
||||
alpha = from.alpha * (1 - mix);
|
||||
int timelineCount = from.animation.timelines.size;
|
||||
Object[] timelines = from.animation.timelines.items;
|
||||
boolean[] timelinesFirst = from.timelinesFirst.items;
|
||||
float alpha = from.alpha * entry.mixAlpha * (1 - mix);
|
||||
|
||||
boolean firstFrame = from.timelinesRotation.size == 0;
|
||||
if (firstFrame) from.timelinesRotation.setSize(timelineCount << 1);
|
||||
@ -385,10 +384,8 @@ public class AnimationState {
|
||||
current.mixingFrom = from;
|
||||
current.mixTime = 0;
|
||||
|
||||
from.timelinesRotation.clear();
|
||||
|
||||
// If not completely mixed in, set alpha so mixing out happens from current mix to zero.
|
||||
if (from.mixingFrom != null) from.alpha *= Math.min(from.mixTime / from.mixDuration, 1);
|
||||
// If not completely mixed in, set mixAlpha so mixing out happens from current mix to zero.
|
||||
if (from.mixingFrom != null) current.mixAlpha *= Math.min(from.mixTime / from.mixDuration, 1);
|
||||
}
|
||||
|
||||
queue.start(current);
|
||||
@ -544,6 +541,7 @@ public class AnimationState {
|
||||
entry.timeScale = 1;
|
||||
|
||||
entry.alpha = 1;
|
||||
entry.mixAlpha = 1;
|
||||
entry.mixTime = 0;
|
||||
entry.mixDuration = last == null ? 0 : data.getMix(last.animation, animation);
|
||||
return entry;
|
||||
@ -563,7 +561,7 @@ public class AnimationState {
|
||||
|
||||
IntSet propertyIDs = this.propertyIDs;
|
||||
|
||||
// Compute timelinesFirst from lowest to highest track entries.
|
||||
// Set timelinesFirst for all entries, from lowest track to highest.
|
||||
int i = 0, n = tracks.size;
|
||||
propertyIDs.clear();
|
||||
for (; i < n; i++) { // Find first non-null entry.
|
||||
@ -587,11 +585,11 @@ public class AnimationState {
|
||||
return;
|
||||
}
|
||||
IntSet propertyIDs = this.propertyIDs;
|
||||
Array<Timeline> timelines = entry.animation.timelines;
|
||||
int n = timelines.size;
|
||||
int n = entry.animation.timelines.size;
|
||||
Object[] timelines = entry.animation.timelines.items;
|
||||
boolean[] usage = entry.timelinesFirst.setSize(n);
|
||||
for (int i = 0; i < n; i++) {
|
||||
propertyIDs.add(timelines.get(i).getPropertyId());
|
||||
propertyIDs.add(((Timeline)timelines[i]).getPropertyId());
|
||||
usage[i] = true;
|
||||
}
|
||||
}
|
||||
@ -604,11 +602,11 @@ public class AnimationState {
|
||||
|
||||
private void checkTimelinesUsage (TrackEntry entry, BooleanArray usageArray) {
|
||||
IntSet propertyIDs = this.propertyIDs;
|
||||
Array<Timeline> timelines = entry.animation.timelines;
|
||||
int n = timelines.size;
|
||||
int n = entry.animation.timelines.size;
|
||||
Object[] timelines = entry.animation.timelines.items;
|
||||
boolean[] usage = usageArray.setSize(n);
|
||||
for (int i = 0; i < n; i++)
|
||||
usage[i] = propertyIDs.add(timelines.get(i).getPropertyId());
|
||||
usage[i] = propertyIDs.add(((Timeline)timelines[i]).getPropertyId());
|
||||
}
|
||||
|
||||
/** Returns the track entry for the animation currently playing on the track, or null if no animation is currently playing. */
|
||||
@ -924,6 +922,17 @@ public class AnimationState {
|
||||
return mixingFrom;
|
||||
}
|
||||
|
||||
/** Resets the rotation directions for mixing this entry's rotate timelines. This can be useful to avoid bones rotating the
|
||||
* long way around when using {@link #alpha} and starting animations on other tracks.
|
||||
* <p>
|
||||
* Mixing involves finding a rotation between two others, which has two possible solutions: the short way or the long way
|
||||
* around. The two rotations likely change over time, so which direction is the short or long way also changes. If the short
|
||||
* way was always chosen, bones would flip to the other side when that direction became the long way. TrackEntry chooses the
|
||||
* short way the first time it is applied and remembers that direction. */
|
||||
public void resetRotationDirections () {
|
||||
timelinesRotation.clear();
|
||||
}
|
||||
|
||||
public String toString () {
|
||||
return animation == null ? "<none>" : animation.name;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user