[csharp] Ported AnimationState and Animation changes of commit a321aa7. See #1303.

This commit is contained in:
Harald Csaszar 2019-03-19 15:40:06 +01:00
parent 9229d93c8f
commit 18acce0354

View File

@ -67,6 +67,12 @@ namespace Spine {
/// (which affects B and C). Without using D to mix out, A would be applied fully until mixing completes, then snap into /// (which affects B and C). Without using D to mix out, A would be applied fully until mixing completes, then snap into
/// place. /// place.
internal const int HoldMix = 3; internal const int HoldMix = 3;
/// 1) An attachment timeline in a subsequent track entry sets the attachment for the same slot as this attachment
/// timeline.<para />
/// Result: This attachment timeline will not use MixDirection.out, which would otherwise show the setup mode attachment (or
/// none if not visible in setup mode). This allows deform timelines to be applied for the subsequent entry to mix from, rather
/// than mixing from the setup pose.
internal const int NotLast = 4;
protected AnimationStateData data; protected AnimationStateData data;
private readonly ExposedList<TrackEntry> tracks = new ExposedList<TrackEntry>(); private readonly ExposedList<TrackEntry> tracks = new ExposedList<TrackEntry>();
@ -234,7 +240,7 @@ namespace Spine {
for (int ii = 0; ii < timelineCount; ii++) { for (int ii = 0; ii < timelineCount; ii++) {
Timeline timeline = timelinesItems[ii]; Timeline timeline = timelinesItems[ii];
MixBlend timelineBlend = timelineMode[ii] == AnimationState.Subsequent ? blend : MixBlend.Setup; MixBlend timelineBlend = (timelineMode[ii] & AnimationState.NotLast - 1) == AnimationState.Subsequent ? blend : MixBlend.Setup;
var rotateTimeline = timeline as RotateTimeline; var rotateTimeline = timeline as RotateTimeline;
if (rotateTimeline != null) if (rotateTimeline != null)
ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1,
@ -292,7 +298,7 @@ namespace Spine {
MixDirection direction = MixDirection.Out; MixDirection direction = MixDirection.Out;
MixBlend timelineBlend; MixBlend timelineBlend;
float alpha; float alpha;
switch (timelineMode[i]) { switch (timelineMode[i] & AnimationState.NotLast - 1) {
case AnimationState.Subsequent: case AnimationState.Subsequent:
if (!attachments && timeline is AttachmentTimeline) continue; if (!attachments && timeline is AttachmentTimeline) continue;
if (!drawOrder && timeline is DrawOrderTimeline) continue; if (!drawOrder && timeline is DrawOrderTimeline) continue;
@ -322,7 +328,7 @@ namespace Spine {
} else { } else {
if (timelineBlend == MixBlend.Setup) { if (timelineBlend == MixBlend.Setup) {
if (timeline is AttachmentTimeline) { if (timeline is AttachmentTimeline) {
if (attachments) direction = MixDirection.In; if (attachments || (timelineMode[i] & AnimationState.NotLast) == AnimationState.NotLast) direction = MixDirection.In;
} else if (timeline is DrawOrderTimeline) { } else if (timeline is DrawOrderTimeline) {
if (drawOrder) { if (drawOrder) {
direction = MixDirection.In; direction = MixDirection.In;
@ -716,25 +722,34 @@ namespace Spine {
private void AnimationsChanged () { private void AnimationsChanged () {
animationsChanged = false; animationsChanged = false;
// Process in the order that animations are applied.
propertyIDs.Clear(); propertyIDs.Clear();
var tracksItems = tracks.Items; var tracksItems = tracks.Items;
for (int i = 0, n = tracks.Count; i < n; i++) { for (int i = 0, n = tracks.Count; i < n; i++) {
TrackEntry entry = tracksItems[i]; TrackEntry entry = tracksItems[i];
if (entry == null) continue; if (entry == null) continue;
// Move to last entry, then iterate in reverse (the order animations are applied). while (entry.mixingFrom != null) // Move to last entry, then iterate in reverse.
while (entry.mixingFrom != null)
entry = entry.mixingFrom; entry = entry.mixingFrom;
do { do {
if (entry.mixingTo == null || entry.mixBlend != MixBlend.Add) SetTimelineModes(entry); if (entry.mixingTo == null || entry.mixBlend != MixBlend.Add) ComputeHold(entry);
entry = entry.mixingTo; entry = entry.mixingTo;
} while (entry != null); } while (entry != null);
}
// Process in the reverse order that animations are applied.
propertyIDs.Clear();
for (int i = tracks.Count - 1; i >= 0; i--) {
TrackEntry entry = tracksItems[i];
do {
ComputeNotLast(entry);
entry = entry.mixingFrom;
} while (entry != null);
} }
} }
private void SetTimelineModes (TrackEntry entry) { private void ComputeHold (TrackEntry entry) {
TrackEntry to = entry.mixingTo; TrackEntry to = entry.mixingTo;
var timelines = entry.animation.timelines.Items; var timelines = entry.animation.timelines.Items;
int timelinesCount = entry.animation.timelines.Count; int timelinesCount = entry.animation.timelines.Count;
@ -753,12 +768,14 @@ namespace Spine {
// outer: // outer:
for (int i = 0; i < timelinesCount; i++) { for (int i = 0; i < timelinesCount; i++) {
int id = timelines[i].PropertyId; Timeline timeline = timelines[i];
int id = timeline.PropertyId;
if (!propertyIDs.Add(id)) if (!propertyIDs.Add(id))
timelineMode[i] = AnimationState.Subsequent; timelineMode[i] = AnimationState.Subsequent;
else if (to == null || !HasTimeline(to, id)) else if (to == null || timeline is AttachmentTimeline || timeline is DrawOrderTimeline
|| timeline is EventTimeline || !HasTimeline(to, id)) {
timelineMode[i] = AnimationState.First; timelineMode[i] = AnimationState.First;
else { } else {
for (TrackEntry next = to.mixingTo; next != null; next = next.mixingTo) { for (TrackEntry next = to.mixingTo; next != null; next = next.mixingTo) {
if (HasTimeline(next, id)) continue; if (HasTimeline(next, id)) continue;
if (next.mixDuration > 0) { if (next.mixDuration > 0) {
@ -774,6 +791,20 @@ namespace Spine {
} }
} }
private void ComputeNotLast (TrackEntry entry) {
var timelines = entry.animation.timelines.Items;
int timelinesCount = entry.animation.timelines.Count;
int[] timelineMode = entry.timelineMode.Items;
var propertyIDs = this.propertyIDs;
for (int i = 0; i < timelinesCount; i++) {
if (timelines[i] is AttachmentTimeline) {
AttachmentTimeline timeline = (AttachmentTimeline)timelines[i];
if (!propertyIDs.Add(timeline.slotIndex)) timelineMode[i] |= AnimationState.NotLast;
}
}
}
static bool HasTimeline (TrackEntry entry, int id) { static bool HasTimeline (TrackEntry entry, int id) {
var timelines = entry.animation.timelines.Items; var timelines = entry.animation.timelines.Items;
for (int i = 0, n = entry.animation.timelines.Count; i < n; i++) for (int i = 0, n = entry.animation.timelines.Count; i < n; i++)