From aa3969f147e0e03d22a31646db2a34fba6652025 Mon Sep 17 00:00:00 2001 From: John Date: Wed, 24 May 2017 14:57:55 +0800 Subject: [PATCH] [csharp] Remove mixing from limit, dispose track entries ASAP. https://github.com/EsotericSoftware/spine-runtimes/commit/a69f9d579f33134659ecd8b7f36a443f6648fb08 https://github.com/EsotericSoftware/spine-runtimes/issues/899 --- spine-csharp/src/AnimationState.cs | 57 ++++++++++++++++-------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/spine-csharp/src/AnimationState.cs b/spine-csharp/src/AnimationState.cs index 1e9ec088b..fb3efebb4 100644 --- a/spine-csharp/src/AnimationState.cs +++ b/spine-csharp/src/AnimationState.cs @@ -34,7 +34,7 @@ using System.Collections.Generic; namespace Spine { public class AnimationState { static readonly Animation EmptyAnimation = new Animation("", new ExposedList(), 0); - internal const int SUBSEQUENT = 0, FIRST = 1, DIP = 2; + internal const int SUBSEQUENT = 0, FIRST = 1, DIP = 2, DIP_MIX = 3; private AnimationStateData data; private readonly ExposedList tracks = new ExposedList(); @@ -115,7 +115,7 @@ namespace Spine { DisposeNext(current); continue; } - if (current.mixingFrom != null && UpdateMixingFrom(current, delta, 2)) { + if (current.mixingFrom != null && UpdateMixingFrom(current, delta)) { // End mixing from entries once all have completed. var from = current.mixingFrom; current.mixingFrom = null; @@ -132,21 +132,18 @@ namespace Spine { } /// Returns true when all mixing from entries are complete. - private bool UpdateMixingFrom (TrackEntry entry, float delta, int animationCount) { - TrackEntry from = entry.mixingFrom; + private bool UpdateMixingFrom (TrackEntry to, float delta) { + TrackEntry from = to.mixingFrom; if (from == null) return true; - bool finished = UpdateMixingFrom(from, delta, animationCount + 1); + bool finished = UpdateMixingFrom(from, delta); // Require mixTime > 0 to ensure the mixing from entry was applied at least once. - if (entry.mixTime > 0 && (entry.mixTime >= entry.mixDuration || entry.timeScale == 0)) { - if (animationCount > 5 && from.mixingFrom == null) { - // Limit linked list by speeding up and removing old entries. - entry.interruptAlpha = Math.Max(0, entry.interruptAlpha - delta * 0.66f); - if (entry.interruptAlpha <= 0) { - entry.mixingFrom = null; - queue.End(from); - } + if (to.mixTime > 0 && (to.mixTime >= to.mixDuration || to.timeScale == 0)) { + if (from.totalAlpha == 0) { + to.mixingFrom = from.mixingFrom; + to.interruptAlpha = from.interruptAlpha; + queue.End(from); } return finished; } @@ -154,7 +151,7 @@ namespace Spine { from.animationLast = from.nextAnimationLast; from.trackLast = from.nextTrackLast; from.trackTime += delta * from.timeScale; - entry.mixTime += delta * entry.timeScale; + to.mixTime += delta * to.timeScale; return false; } @@ -199,10 +196,10 @@ namespace Spine { Timeline timeline = timelinesItems[ii]; var rotateTimeline = timeline as RotateTimeline; if (rotateTimeline != null) { - ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, mix, timelineData[ii] > 0, timelinesRotation, ii << 1, - firstFrame); + ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, mix, timelineData[ii] >= FIRST, timelinesRotation, + ii << 1, firstFrame); } else { - timeline.Apply(skeleton, animationLast, animationTime, events, mix, timelineData[ii] > 0, false); + timeline.Apply(skeleton, animationLast, animationTime, events, mix, timelineData[ii] > FIRST, false); } } } @@ -242,6 +239,7 @@ namespace Spine { bool first; float alphaDip = from.alpha * to.interruptAlpha, alphaMix = alphaDip * (1 - mix), alpha; + from.totalAlpha = 0; for (int i = 0; i < timelineCount; i++) { Timeline timeline = timelinesItems[i]; switch (timelineData[i]) { @@ -253,14 +251,18 @@ namespace Spine { first = true; alpha = alphaMix; break; + case DIP: + first = true; + alpha = alphaDip; + break; default: first = true; alpha = alphaDip; var dipMix = timelineDipMix[i]; - if (dipMix != null) alpha *= Math.Max(0, 1 - dipMix.mixTime / dipMix.mixDuration); + alpha *= Math.Max(0, 1 - dipMix.mixTime / dipMix.mixDuration); break; } - + from.totalAlpha += alpha; var rotateTimeline = timeline as RotateTimeline; if (rotateTimeline != null) { ApplyRotateTimeline(rotateTimeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame); @@ -659,7 +661,7 @@ namespace Spine { internal float eventThreshold, attachmentThreshold, drawOrderThreshold; internal float animationStart, animationEnd, animationLast, nextAnimationLast; internal float delay, trackTime, trackLast, nextTrackLast, trackEnd, timeScale = 1f; - internal float alpha, mixTime, mixDuration, interruptAlpha; + internal float alpha, mixTime, mixDuration, interruptAlpha, totalAlpha; internal readonly ExposedList timelineData = new ExposedList(); internal readonly ExposedList timelineDipMix = new ExposedList(); internal readonly ExposedList timelinesRotation = new ExposedList(); @@ -691,8 +693,9 @@ namespace Spine { int mixingToLast = mixingToArray.Count - 1; var timelines = animation.timelines.Items; int timelinesCount = animation.timelines.Count; - var timelineDataItems = this.timelineData.Resize(timelinesCount).Items; // timelineData.setSize(timelinesCount); - var timelineDipMixItems = this.timelineDipMix.Resize(timelinesCount).Items; //timelineDipMix.setSize(timelinesCount); + var timelineDataItems = timelineData.Resize(timelinesCount).Items; // timelineData.setSize(timelinesCount); + timelineDipMix.Clear(); + var timelineDipMixItems = timelineDipMix.Resize(timelinesCount).Items; //timelineDipMix.setSize(timelinesCount); // outer: for (int i = 0; i < timelinesCount; i++) { @@ -702,15 +705,17 @@ namespace Spine { } else if (to == null || !to.HasTimeline(id)) { timelineDataItems[i] = AnimationState.FIRST; } else { - timelineDataItems[i] = AnimationState.DIP; for (int ii = mixingToLast; ii >= 0; ii--) { var entry = mixingTo[ii]; if (!entry.HasTimeline(id)) { - if (entry.mixDuration > 0) timelineDipMixItems[i] = entry; - goto outer; // continue outer; + if (entry.mixDuration > 0) { + timelineData[i] = AnimationState.DIP_MIX; + timelineDipMix[i] = entry; + goto outer; // continue outer; + } } } - timelineDipMixItems[i] = null; + timelineData[i] = AnimationState.DIP; } outer: {} }