From e324c05bfa669bf855e3522cb5afa094606e8964 Mon Sep 17 00:00:00 2001 From: badlogic Date: Thu, 18 May 2017 13:10:07 +0200 Subject: [PATCH] [c] Ported latest anim state changes. --- .../spine-c/include/spine/AnimationState.h | 23 +- spine-c/spine-c/include/spine/Array.h | 1 - spine-c/spine-c/src/spine/AnimationState.c | 304 +++++++++--------- spine-sfml/example/main.cpp | 1 - 4 files changed, 160 insertions(+), 169 deletions(-) diff --git a/spine-c/spine-c/include/spine/AnimationState.h b/spine-c/spine-c/include/spine/AnimationState.h index 7104e0a4a..f39e20a4f 100644 --- a/spine-c/spine-c/include/spine/AnimationState.h +++ b/spine-c/spine-c/include/spine/AnimationState.h @@ -34,6 +34,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -48,6 +49,8 @@ typedef struct spTrackEntry spTrackEntry; typedef void (*spAnimationStateListener) (spAnimationState* state, spEventType type, spTrackEntry* entry, spEvent* event); +_SP_ARRAY_DECLARE_TYPE(spTrackEntryArray, spTrackEntry*) + struct spTrackEntry { spAnimation* animation; spTrackEntry* next; @@ -58,11 +61,9 @@ struct spTrackEntry { float eventThreshold, attachmentThreshold, drawOrderThreshold; float animationStart, animationEnd, animationLast, nextAnimationLast; float delay, trackTime, trackLast, nextTrackLast, trackEnd, timeScale; - float alpha, mixTime, mixDuration, mixAlpha; - int* /*boolean*/ timelinesFirst; - int timelinesFirstCount; - int* /*boolean*/ timelinesLast; - int timelinesLastCount; + float alpha, mixTime, mixDuration, interruptAlpha; + spIntArray* timelineData; + spTrackEntryArray* timelineDipMix; float* timelinesRotation; int timelinesRotationCount; void* rendererObject; @@ -78,11 +79,9 @@ struct spTrackEntry { eventThreshold(0), attachmentThreshold(0), drawOrderThreshold(0), animationStart(0), animationEnd(0), animationLast(0), nextAnimationLast(0), delay(0), trackTime(0), trackLast(0), nextTrackLast(0), trackEnd(0), timeScale(0), - alpha(0), mixTime(0), mixDuration(0), mixAlpha(0), - timelinesFirst(0), - timelinesFirstCount(0), - timelinesLast(0), - timelinesLastCount(0), + alpha(0), mixTime(0), mixDuration(0), interruptAlpha(0), + timelineData(0), + timelineDipMix(0), timelinesRotation(0), timelinesRotationCount(0) { } @@ -99,7 +98,7 @@ struct spAnimationState { float timeScale; - int /*boolean*/ multipleMixing; + spTrackEntryArray* mixingTo; void* rendererObject; @@ -110,7 +109,7 @@ struct spAnimationState { tracks(0), listener(0), timeScale(0), - multipleMixing(0), + mixingTo(0), rendererObject(0) { } #endif diff --git a/spine-c/spine-c/include/spine/Array.h b/spine-c/spine-c/include/spine/Array.h index ce8c2bea1..161741a95 100644 --- a/spine-c/spine-c/include/spine/Array.h +++ b/spine-c/spine-c/include/spine/Array.h @@ -126,7 +126,6 @@ _SP_ARRAY_DECLARE_TYPE(spUnsignedShortArray, unsigned short) _SP_ARRAY_DECLARE_TYPE(spArrayFloatArray, spFloatArray*) _SP_ARRAY_DECLARE_TYPE(spArrayShortArray, spShortArray*) - #ifdef __cplusplus } #endif diff --git a/spine-c/spine-c/src/spine/AnimationState.c b/spine-c/spine-c/src/spine/AnimationState.c index 48f9268cd..fa58b4d01 100644 --- a/spine-c/spine-c/src/spine/AnimationState.c +++ b/spine-c/spine-c/src/spine/AnimationState.c @@ -32,6 +32,12 @@ #include #include +#define SUBSEQUENT 0 +#define FIRST 1 +#define DIP 2 + +_SP_ARRAY_IMPLEMENT_TYPE(spTrackEntryArray, spTrackEntry*) + static spAnimation* SP_EMPTY_ANIMATION = 0; void spAnimationState_disposeStatics () { if (SP_EMPTY_ANIMATION) spAnimation_dispose(SP_EMPTY_ANIMATION); @@ -42,7 +48,7 @@ void spAnimationState_disposeStatics () { the same function order in C as we have method order in Java */ void _spAnimationState_disposeTrackEntry (spTrackEntry* entry); void _spAnimationState_disposeTrackEntries (spAnimationState* state, spTrackEntry* entry); -void _spAnimationState_updateMixingFrom (spAnimationState* self, spTrackEntry* entry, float delta); +int /*boolean*/ _spAnimationState_updateMixingFrom (spAnimationState* self, spTrackEntry* entry, float delta, int animationCount); float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* entry, spSkeleton* skeleton); void _spAnimationState_applyRotateTimeline (spAnimationState* self, spTimeline* timeline, spSkeleton* skeleton, float time, float alpha, int /*boolean*/ setupPose, float* timelinesRotation, int i, int /*boolean*/ firstFrame); void _spAnimationState_queueEvents (spAnimationState* self, spTrackEntry* entry, float animationTime); @@ -55,9 +61,8 @@ float* _spAnimationState_resizeTimelinesRotation(spTrackEntry* entry, int newSiz int* _spAnimationState_resizeTimelinesFirst(spTrackEntry* entry, int newSize); void _spAnimationState_ensureCapacityPropertyIDs(spAnimationState* self, int capacity); int _spAnimationState_addPropertyID(spAnimationState* self, int id); -void _spAnimationState_setTimelinesFirst (spAnimationState* self, spTrackEntry* entry); -void _spAnimationState_checkTimelinesFirst (spAnimationState* self, spTrackEntry* entry); -void _spAnimationState_checkTimelinesUsage (spAnimationState* self, spTrackEntry* entry, int /*boolean*/ useTimelinesFirst); +spTrackEntry* _spTrackEntry_setTimelineData(spTrackEntry* self, spTrackEntry* to, spTrackEntryArray* mixingToArray, spAnimationState* state); + _spEventQueue* _spEventQueue_create (_spAnimationState* state) { _spEventQueue *self = CALLOC(_spEventQueue, 1); @@ -175,8 +180,8 @@ void _spEventQueue_drain (_spEventQueue* self) { } void _spAnimationState_disposeTrackEntry (spTrackEntry* entry) { - FREE(entry->timelinesFirst); - FREE(entry->timelinesLast); + spIntArray_dispose(entry->timelineData); + spTrackEntryArray_dispose(entry->timelineDipMix); FREE(entry->timelinesRotation); FREE(entry); } @@ -216,6 +221,8 @@ spAnimationState* spAnimationState_create (spAnimationStateData* data) { internal->propertyIDs = CALLOC(int, 128); internal->propertyIDsCapacity = 128; + self->mixingTo = spTrackEntryArray_create(16); + return self; } @@ -229,6 +236,7 @@ void spAnimationState_dispose (spAnimationState* self) { FREE(internal->events); FREE(internal->propertyIDs); FREE(internal); + spTrackEntryArray_dispose(self->mixingTo); } void spAnimationState_update (spAnimationState* self, float delta) { @@ -277,7 +285,15 @@ void spAnimationState_update (spAnimationState* self, float delta) { continue; } } - _spAnimationState_updateMixingFrom(self, current, delta); + if (current->mixingFrom != 0 && _spAnimationState_updateMixingFrom(self, current, delta, 2)) { + /* End mixing from entries once all have completed. */ + spTrackEntry* from = current->mixingFrom; + current->mixingFrom = 0; + while (from != 0) { + _spEventQueue_end(internal->queue, from); + from = from->mixingFrom; + } + } current->trackTime += currentDelta; } @@ -285,23 +301,32 @@ void spAnimationState_update (spAnimationState* self, float delta) { _spEventQueue_drain(internal->queue); } -void _spAnimationState_updateMixingFrom (spAnimationState* self, spTrackEntry* entry, float delta) { - spTrackEntry* from = entry->mixingFrom; +int /*boolean*/ _spAnimationState_updateMixingFrom (spAnimationState* self, spTrackEntry* entry, float delta, int animationCount) { + spTrackEntry* from = entry->mixingFrom; + int finished; _spAnimationState* internal = SUB_CAST(_spAnimationState, self); - if (!from) return; - - _spAnimationState_updateMixingFrom(self, from, delta); + if (!from) return -1; - if (entry->mixTime >= entry->mixDuration && from->mixingFrom == 0 && entry->mixTime > 0) { - entry->mixingFrom = 0; - _spEventQueue_end(internal->queue, from); - return; + finished = _spAnimationState_updateMixingFrom(self, from, delta, animationCount + 1); + + /* 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 == 0) { + /* Limit linked list by speeding up and removing old entries. */ + entry->interruptAlpha = MAX(0, entry->interruptAlpha - delta * 0.66f); + if (entry->interruptAlpha <= 0) { + entry->mixingFrom = 0; + _spEventQueue_end(internal->queue, from); + } + } + return finished; } from->animationLast = from->nextAnimationLast; from->trackLast = from->nextTrackLast; from->trackTime += delta * from->timeScale; entry->mixTime += delta * entry->timeScale; + return 0; } void spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) { @@ -313,7 +338,6 @@ void spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) { spTimeline** timelines; int /*boolean*/ firstFrame; float* timelinesRotation; - int* timelinesFirst; spTimeline* timeline; if (internal->animationsChanged) _spAnimationState_animationsChanged(self); @@ -338,17 +362,18 @@ void spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) { for (ii = 0; ii < timelineCount; ii++) spTimeline_apply(timelines[ii], skeleton, animationLast, animationTime, internal->events, &internal->eventsCount, 1, 1, 0); } else { + spIntArray* timelineData = current->timelineData; + firstFrame = current->timelinesRotationCount == 0; if (firstFrame) _spAnimationState_resizeTimelinesRotation(current, timelineCount << 1); timelinesRotation = current->timelinesRotation; - timelinesFirst = current->timelinesFirst; for (ii = 0; ii < timelineCount; ii++) { timeline = timelines[ii]; if (timeline->type == SP_TIMELINE_ROTATE) - _spAnimationState_applyRotateTimeline(self, timeline, skeleton, animationTime, mix, timelinesFirst[ii], timelinesRotation, ii << 1, firstFrame); + _spAnimationState_applyRotateTimeline(self, timeline, skeleton, animationTime, mix, timelineData->items[ii] > 0, timelinesRotation, ii << 1, firstFrame); else - spTimeline_apply(timeline, skeleton, animationLast, animationTime, internal->events, &internal->eventsCount, mix, timelinesFirst[ii], 0); + spTimeline_apply(timeline, skeleton, animationLast, animationTime, internal->events, &internal->eventsCount, mix, timelineData->items[ii] > 0, 0); } } _spAnimationState_queueEvents(self, current, animationTime); @@ -360,7 +385,7 @@ void spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) { _spEventQueue_drain(internal->queue); } -float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* entry, spSkeleton* skeleton) { +float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* to, spSkeleton* skeleton) { _spAnimationState* internal = SUB_CAST(_spAnimationState, self); float mix; spEvent** events; @@ -370,24 +395,24 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* e float animationTime; int timelineCount; spTimeline** timelines; - int* timelinesFirst; - int* timelinesLast; - float alphaBase; + spIntArray* timelineData; + spTrackEntryArray* timelineDipMix; + float alphaDip; float alphaMix; float alpha; int /*boolean*/ firstFrame; float* timelinesRotation; - spTimeline* timeline; - int /*boolean*/ setupPose; + int /*boolean*/ first; int i; + spTrackEntry* dipMix; - spTrackEntry* from = entry->mixingFrom; + spTrackEntry* from = to->mixingFrom; if (from->mixingFrom) _spAnimationState_applyMixingFrom(self, from, skeleton); - if (entry->mixDuration == 0) /* Single frame mix to undo mixingFrom changes. */ + if (to->mixDuration == 0) /* Single frame mix to undo mixingFrom changes. */ mix = 1; else { - mix = entry->mixTime / entry->mixDuration; + mix = to->mixTime / to->mixDuration; if (mix > 1) mix = 1; } @@ -398,31 +423,46 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* e animationTime = spTrackEntry_getAnimationTime(from); timelineCount = from->animation->timelinesCount; timelines = from->animation->timelines; - timelinesFirst = from->timelinesFirst; - timelinesLast = self->multipleMixing ? 0 : from->timelinesLast; - alphaBase = from->alpha * entry->mixAlpha; - alphaMix = alphaBase * (1 - mix); + timelineData = from->timelineData; + timelineDipMix = from->timelineDipMix; firstFrame = from->timelinesRotationCount == 0; if (firstFrame) _spAnimationState_resizeTimelinesRotation(from, timelineCount << 1); timelinesRotation = from->timelinesRotation; + first = 0; + alphaDip = from->alpha * to->interruptAlpha; alphaMix = alphaDip * (1 - mix); for (i = 0; i < timelineCount; i++) { - timeline = timelines[i]; - setupPose = timelinesFirst[i]; - alpha = timelinesLast != 0 && setupPose && !timelinesLast[i] ? alphaBase : alphaMix; + spTimeline* timeline = timelines[i]; + switch (timelineData->items[i]) { + case SUBSEQUENT: + first = 0; + alpha = alphaMix; + break; + case FIRST: + first = 1; + alpha = alphaMix; + break; + default: + first = 1; + alpha = alphaDip; + dipMix = timelineDipMix->items[i]; + if (dipMix != 0) alpha *= MAX(0, 1 - dipMix->mixTime / dipMix->mixDuration); + break; + } if (timeline->type == SP_TIMELINE_ROTATE) - _spAnimationState_applyRotateTimeline(self, timeline, skeleton, animationTime, alpha, setupPose, timelinesRotation, i << 1, firstFrame); + _spAnimationState_applyRotateTimeline(self, timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame); else { - if (!setupPose) { + if (!first) { if (!attachments && timeline->type == SP_TIMELINE_ATTACHMENT) continue; if (!drawOrder && timeline->type == SP_TIMELINE_DRAWORDER) continue; } - spTimeline_apply(timeline, skeleton, animationLast, animationTime, events, &internal->eventsCount, alpha, setupPose, 1); + spTimeline_apply(timeline, skeleton, animationLast, animationTime, events, &internal->eventsCount, alpha, first, 1); } } - if (entry->mixDuration > 0) _spAnimationState_queueEvents(self, from, animationTime); + + if (to->mixDuration > 0) _spAnimationState_queueEvents(self, from, animationTime); internal->eventsCount = 0; from->nextAnimationLast = animationTime; from->nextTrackLast = from->trackTime; @@ -581,7 +621,6 @@ void spAnimationState_clearTrack (spAnimationState* self, int trackIndex) { void _spAnimationState_setCurrent (spAnimationState* self, int index, spTrackEntry* current, int /*boolean*/ interrupt) { _spAnimationState* internal = SUB_CAST(_spAnimationState, self); spTrackEntry* from = _spAnimationState_expandToIndex(self, index); - spTrackEntry* mixingFrom = 0; self->tracks[index] = current; if (from) { @@ -589,25 +628,9 @@ void _spAnimationState_setCurrent (spAnimationState* self, int index, spTrackEnt current->mixingFrom = from; current->mixTime = 0; - mixingFrom = from->mixingFrom; - if (mixingFrom != 0 && from->mixDuration > 0) { - if (self->multipleMixing) { - current->mixAlpha *= MIN(from->mixTime / from->mixDuration, 1); - } else { - if (from->mixTime / from->mixDuration < 0.5 && mixingFrom->animation != SP_EMPTY_ANIMATION) { - current->mixingFrom = mixingFrom; - mixingFrom->mixingFrom = from; - mixingFrom->mixTime = from->mixDuration - from->mixTime; - mixingFrom->mixDuration = from->mixDuration; - from->mixingFrom = 0; - from = mixingFrom; - } - - from->mixAlpha = 0; - from->mixTime = 0; - from->mixDuration = 0; - } - } + /* Store the interrupted mix percentage. */ + if (from->mixingFrom != 0 && from->mixDuration > 0) + current->interruptAlpha *= MIN(1, from->mixTime / from->mixDuration); from->timelinesRotationCount = 0; } @@ -747,9 +770,12 @@ spTrackEntry* _spAnimationState_trackEntry (spAnimationState* self, int trackInd entry->timeScale = 1; entry->alpha = 1; - entry->mixAlpha = 1; + entry->interruptAlpha = 1; entry->mixTime = 0; entry->mixDuration = !last ? 0 : spAnimationStateData_getMix(self->data, last->animation, animation); + + entry->timelineData = spIntArray_create(16); + entry->timelineDipMix = spTrackEntryArray_create(16); return entry; } @@ -765,48 +791,22 @@ void _spAnimationState_disposeNext (spAnimationState* self, spTrackEntry* entry) void _spAnimationState_animationsChanged (spAnimationState* self) { _spAnimationState* internal = SUB_CAST(_spAnimationState, self); - int i, n, ii, nn, lowestMixingFrom; + int i, n; spTrackEntry* entry; - spTimeline** timelines; + spTrackEntry* lastEntry = 0; + spTrackEntryArray* mixingTo; internal->animationsChanged = 0; + internal->propertyIDsCount = 0; i = 0; n = self->tracksCount; - internal->propertyIDsCount = 0; - for (; i < n; i++) { + mixingTo = self->mixingTo; + + for (;i < n; i++) { entry = self->tracks[i]; - if (!entry) continue; - _spAnimationState_setTimelinesFirst(self, entry); - i++; - break; - } - for (; i < n; i++) { - entry = self->tracks[i]; - if (entry) _spAnimationState_checkTimelinesFirst(self, entry); - } - - if (self->multipleMixing) return; - - internal->propertyIDsCount = 0; - lowestMixingFrom = n; - for (i = 0; i < n; i++) { - entry = self->tracks[i]; - if (entry == 0 || entry->mixingFrom == 0) continue; - lowestMixingFrom = i; - break; - } - for (i = n - 1; i >= lowestMixingFrom; i--) { - entry = self->tracks[i]; - if (entry == 0) continue; - - timelines = entry->animation->timelines; - for (ii = 0, nn = entry->animation->timelinesCount; ii < nn; ii++) - _spAnimationState_addPropertyID(self, spTimeline_getPropertyId(timelines[ii])); - - entry = entry->mixingFrom; - while (entry != 0) { - _spAnimationState_checkTimelinesUsage(self, entry, 0); - entry = entry->mixingFrom; + if (entry != 0) { + _spTrackEntry_setTimelineData(entry, lastEntry, mixingTo, self); + lastEntry = entry; } } } @@ -821,28 +821,6 @@ float* _spAnimationState_resizeTimelinesRotation(spTrackEntry* entry, int newSiz return entry->timelinesRotation; } -int* _spAnimationState_resizeTimelinesFirst(spTrackEntry* entry, int newSize) { - if (entry->timelinesFirstCount != newSize) { - int* newTimelinesFirst = CALLOC(int, newSize); - FREE(entry->timelinesFirst); - entry->timelinesFirst = newTimelinesFirst; - entry->timelinesFirstCount = newSize; - } - - return entry->timelinesFirst; -} - -int* _spAnimationState_resizeTimelinesLast(spTrackEntry* entry, int newSize) { - if (entry->timelinesLastCount != newSize) { - int* newTimelinesLast = CALLOC(int, newSize); - FREE(entry->timelinesLast); - entry->timelinesLast = newTimelinesLast; - entry->timelinesLastCount = newSize; - } - - return entry->timelinesLast; -} - void _spAnimationState_ensureCapacityPropertyIDs(spAnimationState* self, int capacity) { _spAnimationState* internal = SUB_CAST(_spAnimationState, self); if (internal->propertyIDsCapacity < capacity) { @@ -868,42 +846,6 @@ int _spAnimationState_addPropertyID(spAnimationState* self, int id) { return 1; } -void _spAnimationState_setTimelinesFirst (spAnimationState* self, spTrackEntry* entry) { - int i, n; - int* usage; - spTimeline** timelines; - - if (entry->mixingFrom) { - _spAnimationState_setTimelinesFirst(self, entry->mixingFrom); - _spAnimationState_checkTimelinesUsage(self, entry, -1); - return; - } - - n = entry->animation->timelinesCount; - timelines = entry->animation->timelines; - usage = _spAnimationState_resizeTimelinesFirst(entry, n); - for (i = 0; i < n; i++) { - _spAnimationState_addPropertyID(self, spTimeline_getPropertyId(timelines[i])); - usage[i] = 1; - } -} - -void _spAnimationState_checkTimelinesFirst (spAnimationState* self, spTrackEntry* entry) { - if (entry->mixingFrom) _spAnimationState_checkTimelinesFirst(self, entry->mixingFrom); - _spAnimationState_checkTimelinesUsage(self, entry, -1); -} - -void _spAnimationState_checkTimelinesUsage (spAnimationState* self, spTrackEntry* entry, int /*boolean*/ useTimelinesFirst) { - int i, n; - int* usage; - spTimeline** timelines; - n = entry->animation->timelinesCount; - timelines = entry->animation->timelines; - usage = useTimelinesFirst ? _spAnimationState_resizeTimelinesFirst(entry, n) : _spAnimationState_resizeTimelinesLast(entry, n); - for (i = 0; i < n; i++) - usage[i] = _spAnimationState_addPropertyID(self, spTimeline_getPropertyId(timelines[i])); -} - spTrackEntry* spAnimationState_getCurrent (spAnimationState* self, int trackIndex) { if (trackIndex >= self->tracksCount) return 0; return self->tracks[trackIndex]; @@ -922,3 +864,55 @@ float spTrackEntry_getAnimationTime (spTrackEntry* entry) { } return MIN(entry->trackTime + entry->animationStart, entry->animationEnd); } + +int /*boolean*/ _spTrackEntry_hasTimeline(spTrackEntry* self, int id) { + spTimeline** timelines = self->animation->timelines; + int i, n; + for (i = 0, n = self->animation->timelinesCount; i < n; i++) + if (spTimeline_getPropertyId(timelines[i]) == id) return 1; + return 0; +} + +spTrackEntry* _spTrackEntry_setTimelineData(spTrackEntry* self, spTrackEntry* to, spTrackEntryArray* mixingToArray, spAnimationState* state) { + spTrackEntry* lastEntry; + spTrackEntry** mixingTo; + int mixingToLast; + spTimeline** timelines; + int timelinesCount; + int* timelineData; + spTrackEntry** timelineDipMix; + int i, ii; + + if (to != 0) spTrackEntryArray_add(mixingToArray, to); + lastEntry = self->mixingFrom != 0 ? _spTrackEntry_setTimelineData(self->mixingFrom, self, mixingToArray, state) : self; + if (to != 0) spTrackEntryArray_pop(mixingToArray); + + mixingTo = mixingToArray->items; + mixingToLast = mixingToArray->size - 1; + timelines = self->animation->timelines; + timelinesCount = self->animation->timelinesCount; + timelineData = spIntArray_setSize(self->timelineData, timelinesCount)->items; + timelineDipMix = spTrackEntryArray_setSize(self->timelineDipMix, timelinesCount)->items; + + outer: + for (i = 0; i < timelinesCount; i++) { + int id = spTimeline_getPropertyId(timelines[i]); + if (!_spAnimationState_addPropertyID(state, id)) + timelineData[i] = SUBSEQUENT; + else if (to == 0 || !_spTrackEntry_hasTimeline(to, id)) + timelineData[i] = FIRST; + else { + timelineData[i] = DIP; + for (ii = mixingToLast; ii >= 0; ii--) { + spTrackEntry* entry = mixingTo[ii]; + if (!_spTrackEntry_hasTimeline(entry, id)) { + if (entry->mixDuration > 0) timelineDipMix[i] = entry; + i++; + goto outer; + } + } + timelineDipMix[i] = 0; + } + } + return lastEntry; +} diff --git a/spine-sfml/example/main.cpp b/spine-sfml/example/main.cpp index 0e29588c9..b481ce087 100644 --- a/spine-sfml/example/main.cpp +++ b/spine-sfml/example/main.cpp @@ -116,7 +116,6 @@ void spineboy (SkeletonData* skeletonData, Atlas* atlas) { SkeletonDrawable* drawable = new SkeletonDrawable(skeletonData, stateData); drawable->timeScale = 1; - drawable->state->multipleMixing = -1; Skeleton* skeleton = drawable->skeleton; skeleton->flipX = false;