mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 22:34:53 +08:00
[c] Ported Animation State changes, see #908
This commit is contained in:
parent
eb8cc49ed1
commit
7593da8cb8
@ -61,7 +61,7 @@ struct spTrackEntry {
|
||||
float eventThreshold, attachmentThreshold, drawOrderThreshold;
|
||||
float animationStart, animationEnd, animationLast, nextAnimationLast;
|
||||
float delay, trackTime, trackLast, nextTrackLast, trackEnd, timeScale;
|
||||
float alpha, mixTime, mixDuration, interruptAlpha;
|
||||
float alpha, mixTime, mixDuration, interruptAlpha, totalAlpha;
|
||||
spIntArray* timelineData;
|
||||
spTrackEntryArray* timelineDipMix;
|
||||
float* timelinesRotation;
|
||||
@ -79,7 +79,7 @@ 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), interruptAlpha(0),
|
||||
alpha(0), mixTime(0), mixDuration(0), interruptAlpha(0), totalAlpha(0),
|
||||
timelineData(0),
|
||||
timelineDipMix(0),
|
||||
timelinesRotation(0),
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
#define SUBSEQUENT 0
|
||||
#define FIRST 1
|
||||
#define DIP 2
|
||||
#define DIP_MIX 3
|
||||
|
||||
_SP_ARRAY_IMPLEMENT_TYPE(spTrackEntryArray, spTrackEntry*)
|
||||
|
||||
@ -48,7 +49,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);
|
||||
int /*boolean*/ _spAnimationState_updateMixingFrom (spAnimationState* self, spTrackEntry* entry, float delta, int animationCount);
|
||||
int /*boolean*/ _spAnimationState_updateMixingFrom (spAnimationState* self, spTrackEntry* entry, float delta);
|
||||
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);
|
||||
@ -285,7 +286,7 @@ void spAnimationState_update (spAnimationState* self, float delta) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (current->mixingFrom != 0 && _spAnimationState_updateMixingFrom(self, current, delta, 2)) {
|
||||
if (current->mixingFrom != 0 && _spAnimationState_updateMixingFrom(self, current, delta)) {
|
||||
/* End mixing from entries once all have completed. */
|
||||
spTrackEntry* from = current->mixingFrom;
|
||||
current->mixingFrom = 0;
|
||||
@ -301,23 +302,20 @@ void spAnimationState_update (spAnimationState* self, float delta) {
|
||||
_spEventQueue_drain(internal->queue);
|
||||
}
|
||||
|
||||
int /*boolean*/ _spAnimationState_updateMixingFrom (spAnimationState* self, spTrackEntry* entry, float delta, int animationCount) {
|
||||
spTrackEntry* from = entry->mixingFrom;
|
||||
int /*boolean*/ _spAnimationState_updateMixingFrom (spAnimationState* self, spTrackEntry* to, float delta) {
|
||||
spTrackEntry* from = to->mixingFrom;
|
||||
int finished;
|
||||
_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
|
||||
if (!from) return -1;
|
||||
|
||||
finished = _spAnimationState_updateMixingFrom(self, from, delta, animationCount + 1);
|
||||
finished = _spAnimationState_updateMixingFrom(self, 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 == 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);
|
||||
}
|
||||
if (to->mixTime > 0 && (to->mixTime >= to->mixDuration || to->timeScale == 0)) {
|
||||
if (from->totalAlpha == 0) {
|
||||
to->mixingFrom = from->mixingFrom;
|
||||
to->interruptAlpha = from->interruptAlpha;
|
||||
_spEventQueue_end(internal->queue, from);
|
||||
}
|
||||
return finished;
|
||||
}
|
||||
@ -325,7 +323,7 @@ int /*boolean*/ _spAnimationState_updateMixingFrom (spAnimationState* self, spTr
|
||||
from->animationLast = from->nextAnimationLast;
|
||||
from->trackLast = from->nextTrackLast;
|
||||
from->trackTime += delta * from->timeScale;
|
||||
entry->mixTime += delta * entry->timeScale;
|
||||
to->mixTime += delta * to->timeScale;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -371,9 +369,9 @@ void spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) {
|
||||
for (ii = 0; ii < timelineCount; ii++) {
|
||||
timeline = timelines[ii];
|
||||
if (timeline->type == SP_TIMELINE_ROTATE)
|
||||
_spAnimationState_applyRotateTimeline(self, timeline, skeleton, animationTime, mix, timelineData->items[ii] > 0, timelinesRotation, ii << 1, firstFrame);
|
||||
_spAnimationState_applyRotateTimeline(self, timeline, skeleton, animationTime, mix, timelineData->items[ii] >= FIRST, timelinesRotation, ii << 1, firstFrame);
|
||||
else
|
||||
spTimeline_apply(timeline, skeleton, animationLast, animationTime, internal->events, &internal->eventsCount, mix, timelineData->items[ii] > 0, 0);
|
||||
spTimeline_apply(timeline, skeleton, animationLast, animationTime, internal->events, &internal->eventsCount, mix, timelineData->items[ii] >= FIRST, 0);
|
||||
}
|
||||
}
|
||||
_spAnimationState_queueEvents(self, current, animationTime);
|
||||
@ -432,6 +430,7 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* t
|
||||
|
||||
first = 0;
|
||||
alphaDip = from->alpha * to->interruptAlpha; alphaMix = alphaDip * (1 - mix);
|
||||
from->totalAlpha = 0;
|
||||
for (i = 0; i < timelineCount; i++) {
|
||||
spTimeline* timeline = timelines[i];
|
||||
switch (timelineData->items[i]) {
|
||||
@ -443,13 +442,18 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* t
|
||||
first = 1;
|
||||
alpha = alphaMix;
|
||||
break;
|
||||
case DIP:
|
||||
first = 1;
|
||||
alpha = alphaDip;
|
||||
break;
|
||||
default:
|
||||
first = 1;
|
||||
alpha = alphaDip;
|
||||
dipMix = timelineDipMix->items[i];
|
||||
if (dipMix != 0) alpha *= MAX(0, 1 - dipMix->mixTime / dipMix->mixDuration);
|
||||
alpha *= MAX(0, 1 - dipMix->mixTime / dipMix->mixDuration);
|
||||
break;
|
||||
}
|
||||
from->totalAlpha += alpha;
|
||||
if (timeline->type == SP_TIMELINE_ROTATE)
|
||||
_spAnimationState_applyRotateTimeline(self, timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
|
||||
else {
|
||||
@ -892,6 +896,7 @@ spTrackEntry* _spTrackEntry_setTimelineData(spTrackEntry* self, spTrackEntry* to
|
||||
timelines = self->animation->timelines;
|
||||
timelinesCount = self->animation->timelinesCount;
|
||||
timelineData = spIntArray_setSize(self->timelineData, timelinesCount)->items;
|
||||
spTrackEntryArray_clear(self->timelineDipMix);
|
||||
timelineDipMix = spTrackEntryArray_setSize(self->timelineDipMix, timelinesCount)->items;
|
||||
|
||||
outer:
|
||||
@ -902,16 +907,19 @@ spTrackEntry* _spTrackEntry_setTimelineData(spTrackEntry* self, spTrackEntry* to
|
||||
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;
|
||||
if (entry->mixDuration > 0) {
|
||||
timelineData[i] = DIP_MIX;
|
||||
timelineDipMix[i] = entry;
|
||||
i++;
|
||||
goto outer;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
timelineDipMix[i] = 0;
|
||||
timelineData[i] = DIP;
|
||||
}
|
||||
}
|
||||
return lastEntry;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user