mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 22:34:53 +08:00
[c] 4.0 porting, AnimationState
This commit is contained in:
parent
3f9577b5ac
commit
f74e80ae89
@ -53,6 +53,7 @@ _SP_ARRAY_DECLARE_TYPE(spTrackEntryArray, spTrackEntry*)
|
||||
|
||||
struct spTrackEntry {
|
||||
spAnimation* animation;
|
||||
spTrackEntry* previous;
|
||||
spTrackEntry* next;
|
||||
spTrackEntry* mixingFrom;
|
||||
spTrackEntry* mixingTo;
|
||||
@ -60,6 +61,7 @@ struct spTrackEntry {
|
||||
int trackIndex;
|
||||
int /*boolean*/ loop;
|
||||
int /*boolean*/ holdPrevious;
|
||||
int /*boolean*/ reverse;
|
||||
float eventThreshold, attachmentThreshold, drawOrderThreshold;
|
||||
float animationStart, animationEnd, animationLast, nextAnimationLast;
|
||||
float delay, trackTime, trackLast, nextTrackLast, trackEnd, timeScale;
|
||||
@ -120,6 +122,8 @@ SP_API void spAnimationState_clearListenerNotifications(spAnimationState* self);
|
||||
|
||||
SP_API float spTrackEntry_getAnimationTime (spTrackEntry* entry);
|
||||
|
||||
SP_API float spTrackEntry_getTrackComplete(spTrackEntry* entry);
|
||||
|
||||
/** Use this to dispose static memory before your app exits to appease your memory leak detector*/
|
||||
SP_API void spAnimationState_disposeStatics ();
|
||||
|
||||
|
||||
@ -216,7 +216,7 @@ struct _spAnimationState {
|
||||
|
||||
_spEventQueue* queue;
|
||||
|
||||
int* propertyIDs;
|
||||
spPropertyId* propertyIDs;
|
||||
int propertyIDsCount;
|
||||
int propertyIDsCapacity;
|
||||
|
||||
|
||||
@ -63,9 +63,8 @@ spTrackEntry* _spAnimationState_trackEntry (spAnimationState* self, int trackInd
|
||||
void _spAnimationState_disposeNext (spAnimationState* self, spTrackEntry* entry);
|
||||
void _spAnimationState_animationsChanged (spAnimationState* self);
|
||||
float* _spAnimationState_resizeTimelinesRotation(spTrackEntry* entry, int newSize);
|
||||
int* _spAnimationState_resizeTimelinesFirst(spTrackEntry* entry, int newSize);
|
||||
void _spAnimationState_ensureCapacityPropertyIDs(spAnimationState* self, int capacity);
|
||||
int _spAnimationState_addPropertyID(spAnimationState* self, int id);
|
||||
int _spAnimationState_addPropertyID(spAnimationState* self, spPropertyId id);
|
||||
void _spTrackEntry_computeHold(spTrackEntry* self, spAnimationState* state);
|
||||
|
||||
_spEventQueue* _spEventQueue_create (_spAnimationState* state) {
|
||||
@ -237,7 +236,7 @@ spAnimationState* spAnimationState_create (spAnimationStateData* data) {
|
||||
internal->queue = _spEventQueue_create(internal);
|
||||
internal->events = CALLOC(spEvent*, 128);
|
||||
|
||||
internal->propertyIDs = CALLOC(int, 128);
|
||||
internal->propertyIDs = CALLOC(spPropertyId, 128);
|
||||
internal->propertyIDsCapacity = 128;
|
||||
|
||||
return self;
|
||||
@ -363,6 +362,8 @@ int spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) {
|
||||
spSlot** slots = NULL;
|
||||
spSlot* slot = NULL;
|
||||
const char* attachmentName = NULL;
|
||||
spEvent** applyEvents = NULL;
|
||||
float applyTime;
|
||||
|
||||
if (internal->animationsChanged) _spAnimationState_animationsChanged(self);
|
||||
|
||||
@ -382,15 +383,21 @@ int spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) {
|
||||
|
||||
/* Apply current entry. */
|
||||
animationLast = current->animationLast; animationTime = spTrackEntry_getAnimationTime(current);
|
||||
timelineCount = current->animation->timelinesCount;
|
||||
timelines = current->animation->timelines;
|
||||
timelineCount = current->animation->timelines->size;
|
||||
applyEvents = internal->events;
|
||||
applyTime = animationTime;
|
||||
if (current->reverse) {
|
||||
applyTime = current->animation->duration - applyTime;
|
||||
applyEvents = NULL;
|
||||
}
|
||||
timelines = current->animation->timelines->items;
|
||||
if ((i == 0 && mix == 1) || blend == SP_MIX_BLEND_ADD) {
|
||||
for (ii = 0; ii < timelineCount; ii++) {
|
||||
timeline = timelines[ii];
|
||||
if (timeline->type == SP_TIMELINE_ATTACHMENT) {
|
||||
_spAnimationState_applyAttachmentTimeline(self, timeline, skeleton, animationTime, blend, -1);
|
||||
if (timeline->propertyIds[0] == SP_PROPERTY_ATTACHMENT) {
|
||||
_spAnimationState_applyAttachmentTimeline(self, timeline, skeleton, applyTime, blend, -1);
|
||||
} else {
|
||||
spTimeline_apply(timelines[ii], skeleton, animationLast, animationTime, internal->events,
|
||||
spTimeline_apply(timelines[ii], skeleton, animationLast, applyTime, applyEvents,
|
||||
&internal->eventsCount, mix, blend, SP_MIX_DIRECTION_IN);
|
||||
}
|
||||
}
|
||||
@ -404,12 +411,12 @@ int spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) {
|
||||
for (ii = 0; ii < timelineCount; ii++) {
|
||||
timeline = timelines[ii];
|
||||
timelineBlend = timelineMode->items[ii] == SUBSEQUENT ? blend : SP_MIX_BLEND_SETUP;
|
||||
if (timeline->type == SP_TIMELINE_ROTATE)
|
||||
_spAnimationState_applyRotateTimeline(self, timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame);
|
||||
else if (timeline->type == SP_TIMELINE_ATTACHMENT)
|
||||
_spAnimationState_applyAttachmentTimeline(self, timeline, skeleton, animationTime, timelineBlend, -1);
|
||||
if (timeline->propertyIds[0] == SP_PROPERTY_ROTATE)
|
||||
_spAnimationState_applyRotateTimeline(self, timeline, skeleton, applyTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame);
|
||||
else if (timeline->propertyIds[0] == SP_PROPERTY_ATTACHMENT)
|
||||
_spAnimationState_applyAttachmentTimeline(self, timeline, skeleton, applyTime, timelineBlend, -1);
|
||||
else
|
||||
spTimeline_apply(timeline, skeleton, animationLast, animationTime, internal->events, &internal->eventsCount, mix, timelineBlend, SP_MIX_DIRECTION_IN);
|
||||
spTimeline_apply(timeline, skeleton, animationLast, applyTime, applyEvents, &internal->eventsCount, mix, timelineBlend, SP_MIX_DIRECTION_IN);
|
||||
}
|
||||
}
|
||||
_spAnimationState_queueEvents(self, current, animationTime);
|
||||
@ -453,6 +460,7 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* t
|
||||
float* timelinesRotation;
|
||||
int i;
|
||||
spTrackEntry* holdMix;
|
||||
float applyTime;
|
||||
|
||||
spTrackEntry* from = to->mixingFrom;
|
||||
if (from->mixingFrom) _spAnimationState_applyMixingFrom(self, from, skeleton, blend);
|
||||
@ -466,18 +474,25 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* t
|
||||
if (blend != SP_MIX_BLEND_FIRST) blend = from->mixBlend;
|
||||
}
|
||||
|
||||
events = mix < from->eventThreshold ? internal->events : 0;
|
||||
attachments = mix < from->attachmentThreshold;
|
||||
drawOrder = mix < from->drawOrderThreshold;
|
||||
timelineCount = from->animation->timelines->size;
|
||||
timelines = from->animation->timelines->items;
|
||||
alphaHold = from->alpha * to->interruptAlpha; alphaMix = alphaHold * (1 - mix);
|
||||
animationLast = from->animationLast;
|
||||
animationTime = spTrackEntry_getAnimationTime(from);
|
||||
timelineCount = from->animation->timelinesCount;
|
||||
timelines = from->animation->timelines;
|
||||
alphaHold = from->alpha * to->interruptAlpha; alphaMix = alphaHold * (1 - mix);
|
||||
applyTime = animationTime;
|
||||
events = NULL;
|
||||
if (from->reverse) {
|
||||
applyTime = from->animation->duration - applyTime;
|
||||
} else {
|
||||
if (mix < from->eventThreshold) events = internal->events;
|
||||
}
|
||||
|
||||
if (blend == SP_MIX_BLEND_ADD) {
|
||||
for (i = 0; i < timelineCount; i++) {
|
||||
spTimeline *timeline = timelines[i];
|
||||
spTimeline_apply(timeline, skeleton, animationLast, animationTime, events, &internal->eventsCount, alphaMix, blend, SP_MIX_DIRECTION_OUT);
|
||||
spTimeline_apply(timeline, skeleton, animationLast, applyTime, events, &internal->eventsCount, alphaMix, blend, SP_MIX_DIRECTION_OUT);
|
||||
}
|
||||
} else {
|
||||
timelineMode = from->timelineMode;
|
||||
@ -494,7 +509,7 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* t
|
||||
|
||||
switch (timelineMode->items[i]) {
|
||||
case SUBSEQUENT:
|
||||
if (!drawOrder && timeline->type == SP_TIMELINE_DRAWORDER) continue;
|
||||
if (!drawOrder && timeline->propertyIds[0] == SP_PROPERTY_DRAWORDER) continue;
|
||||
timelineBlend = blend;
|
||||
alpha = alphaMix;
|
||||
break;
|
||||
@ -517,15 +532,15 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* t
|
||||
break;
|
||||
}
|
||||
from->totalAlpha += alpha;
|
||||
if (timeline->type == SP_TIMELINE_ROTATE)
|
||||
_spAnimationState_applyRotateTimeline(self, timeline, skeleton, animationTime, alpha, timelineBlend,
|
||||
if (timeline->propertyIds[0] == SP_PROPERTY_ROTATE)
|
||||
_spAnimationState_applyRotateTimeline(self, timeline, skeleton, applyTime, alpha, timelineBlend,
|
||||
timelinesRotation, i << 1, firstFrame);
|
||||
else if (timeline->type == SP_TIMELINE_ATTACHMENT)
|
||||
_spAnimationState_applyAttachmentTimeline(self, timeline, skeleton, animationTime, timelineBlend, attachments);
|
||||
else if (timeline->propertyIds[0] == SP_PROPERTY_ATTACHMENT)
|
||||
_spAnimationState_applyAttachmentTimeline(self, timeline, skeleton, applyTime, timelineBlend, attachments);
|
||||
else {
|
||||
if (drawOrder && timeline->type == SP_TIMELINE_DRAWORDER && timelineBlend == SP_MIX_BLEND_SETUP)
|
||||
if (drawOrder && timeline->propertyIds[0] == SP_PROPERTY_DRAWORDER && timelineBlend == SP_MIX_BLEND_SETUP)
|
||||
direction = SP_MIX_DIRECTION_IN;
|
||||
spTimeline_apply(timeline, skeleton, animationLast, animationTime, events, &internal->eventsCount,
|
||||
spTimeline_apply(timeline, skeleton, animationLast, applyTime, events, &internal->eventsCount,
|
||||
alpha, timelineBlend, direction);
|
||||
}
|
||||
}
|
||||
@ -572,17 +587,12 @@ void _spAnimationState_applyAttachmentTimeline(spAnimationState* self, spTimelin
|
||||
slot = skeleton->slots[attachmentTimeline->slotIndex];
|
||||
if (!slot->bone->active) return;
|
||||
|
||||
frames = attachmentTimeline->frames;
|
||||
frames = attachmentTimeline->super.frames->items;
|
||||
if (time < frames[0]) {
|
||||
if (blend == SP_MIX_BLEND_SETUP || blend == SP_MIX_BLEND_FIRST)
|
||||
_spAnimationState_setAttachment(self, skeleton, slot, slot->data->attachmentName, attachments);
|
||||
}
|
||||
else {
|
||||
if (time >= frames[attachmentTimeline->framesCount - 1])
|
||||
frameIndex = attachmentTimeline->framesCount - 1;
|
||||
else
|
||||
frameIndex = binarySearch1(frames, attachmentTimeline->framesCount, time) - 1;
|
||||
_spAnimationState_setAttachment(self, skeleton, slot, attachmentTimeline->attachmentNames[frameIndex], attachments);
|
||||
} else {
|
||||
_spAnimationState_setAttachment(self, skeleton, slot, attachmentTimeline->attachmentNames[binarySearch1(frames, attachmentTimeline->super.frames->size, time)], attachments);
|
||||
}
|
||||
|
||||
/* If an attachment wasn't set (ie before the first frame or attachments is false), set the setup attachment later.*/
|
||||
@ -612,7 +622,7 @@ void _spAnimationState_applyRotateTimeline (spAnimationState* self, spTimeline*
|
||||
}
|
||||
|
||||
rotateTimeline = SUB_CAST(spRotateTimeline, timeline);
|
||||
frames = rotateTimeline->frames;
|
||||
frames = rotateTimeline->super.super.frames->items;
|
||||
bone = skeleton->bones[rotateTimeline->boneIndex];
|
||||
if (!bone->active) return;
|
||||
if (time < frames[0]) {
|
||||
@ -627,21 +637,7 @@ void _spAnimationState_applyRotateTimeline (spAnimationState* self, spTimeline*
|
||||
}
|
||||
} else {
|
||||
r1 = blend == SP_MIX_BLEND_SETUP ? bone->data->rotation : bone->rotation;
|
||||
if (time >= frames[rotateTimeline->framesCount - ROTATE_ENTRIES]) /* Time is after last frame. */
|
||||
r2 = bone->data->rotation + frames[rotateTimeline->framesCount + ROTATE_PREV_ROTATION];
|
||||
else {
|
||||
/* Interpolate between the previous frame and the current frame. */
|
||||
frame = _spCurveTimeline_binarySearch(frames, rotateTimeline->framesCount, time, ROTATE_ENTRIES);
|
||||
prevRotation = frames[frame + ROTATE_PREV_ROTATION];
|
||||
frameTime = frames[frame];
|
||||
percent = spCurveTimeline_getCurvePercent(SUPER(rotateTimeline), (frame >> 1) - 1,
|
||||
1 - (time - frameTime) / (frames[frame + ROTATE_PREV_TIME] - frameTime));
|
||||
|
||||
r2 = frames[frame + ROTATE_ROTATION] - prevRotation;
|
||||
r2 -= (16384 - (int) (16384.499999999996 - r2 / 360)) * 360;
|
||||
r2 = prevRotation + r2 * percent + bone->data->rotation;
|
||||
r2 -= (16384 - (int) (16384.499999999996 - r2 / 360)) * 360;
|
||||
}
|
||||
r2 = bone->data->rotation + spCurveTimeline1_getCurveValue(&rotateTimeline->super, time);
|
||||
}
|
||||
|
||||
/* Mix between rotations using the direction of the shortest route on the first frame while detecting crosses. */
|
||||
@ -671,8 +667,7 @@ void _spAnimationState_applyRotateTimeline (spAnimationState* self, spTimeline*
|
||||
timelinesRotation[i] = total;
|
||||
}
|
||||
timelinesRotation[i + 1] = diff;
|
||||
r1 += total * alpha;
|
||||
bone->rotation = r1 - (16384 - (int)(16384.499999999996 - r1 / 360)) * 360;
|
||||
bone->rotation = r1 + total * alpha;
|
||||
}
|
||||
|
||||
void _spAnimationState_queueEvents (spAnimationState* self, spTrackEntry* entry, float animationTime) {
|
||||
@ -708,6 +703,10 @@ void _spAnimationState_queueEvents (spAnimationState* self, spTrackEntry* entry,
|
||||
}
|
||||
}
|
||||
|
||||
void spAnimationState_clearNext(spTrackEntry* entry) {
|
||||
_spAnimationState_disposeTrackEntry(entry);
|
||||
}
|
||||
|
||||
void spAnimationState_clearTracks (spAnimationState* self) {
|
||||
_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
|
||||
int i, n, oldDrainDisabled;
|
||||
@ -752,6 +751,7 @@ void _spAnimationState_setCurrent (spAnimationState* self, int index, spTrackEnt
|
||||
_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
|
||||
spTrackEntry* from = _spAnimationState_expandToIndex(self, index);
|
||||
self->tracks[index] = current;
|
||||
current->previous = NULL;
|
||||
|
||||
if (from) {
|
||||
if (interrupt) _spEventQueue_interrupt(internal->queue, from);
|
||||
@ -823,18 +823,8 @@ spTrackEntry* spAnimationState_addAnimation (spAnimationState* self, int trackIn
|
||||
_spEventQueue_drain(internal->queue);
|
||||
} else {
|
||||
last->next = entry;
|
||||
if (delay <= 0) {
|
||||
float duration = last->animationEnd - last->animationStart;
|
||||
if (duration != 0) {
|
||||
if (last->loop) {
|
||||
delay += duration * (1 + (int) (last->trackTime / duration));
|
||||
} else {
|
||||
delay += MAX(duration, last->trackTime);
|
||||
}
|
||||
delay -= spAnimationStateData_getMix(self->data, last->animation, animation);
|
||||
} else
|
||||
delay = last->trackTime;
|
||||
}
|
||||
entry->previous = last;
|
||||
if (delay <= 0) delay += spTrackEntry_getTrackComplete(last) - entry->mixDuration;
|
||||
}
|
||||
|
||||
entry->delay = delay;
|
||||
@ -850,10 +840,10 @@ spTrackEntry* spAnimationState_setEmptyAnimation(spAnimationState* self, int tra
|
||||
|
||||
spTrackEntry* spAnimationState_addEmptyAnimation(spAnimationState* self, int trackIndex, float mixDuration, float delay) {
|
||||
spTrackEntry* entry;
|
||||
if (delay <= 0) delay -= mixDuration;
|
||||
entry = spAnimationState_addAnimation(self, trackIndex, SP_EMPTY_ANIMATION, 0, delay);
|
||||
entry = spAnimationState_addAnimation(self, trackIndex, SP_EMPTY_ANIMATION, 0, delay <= 0 ? 1 : delay);
|
||||
entry->mixDuration = mixDuration;
|
||||
entry->trackEnd = mixDuration;
|
||||
if (delay <= 0 && entry->previous != NULL) entry->delay = spTrackEntry_getTrackComplete(entry->previous) - entry->mixDuration;
|
||||
return entry;
|
||||
}
|
||||
|
||||
@ -888,6 +878,9 @@ spTrackEntry* _spAnimationState_trackEntry (spAnimationState* self, int trackInd
|
||||
entry->animation = animation;
|
||||
entry->loop = loop;
|
||||
entry->holdPrevious = 0;
|
||||
entry->reverse = 0;
|
||||
entry->previous = 0;
|
||||
entry->next = 0;
|
||||
|
||||
entry->eventThreshold = 0;
|
||||
entry->attachmentThreshold = 0;
|
||||
@ -961,15 +954,15 @@ float* _spAnimationState_resizeTimelinesRotation(spTrackEntry* entry, int newSiz
|
||||
void _spAnimationState_ensureCapacityPropertyIDs(spAnimationState* self, int capacity) {
|
||||
_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
|
||||
if (internal->propertyIDsCapacity < capacity) {
|
||||
int *newPropertyIDs = CALLOC(int, capacity << 1);
|
||||
memcpy(newPropertyIDs, internal->propertyIDs, sizeof(int) * internal->propertyIDsCount);
|
||||
spPropertyId *newPropertyIDs = CALLOC(spPropertyId, capacity << 1);
|
||||
memcpy(newPropertyIDs, internal->propertyIDs, sizeof(spPropertyId) * internal->propertyIDsCount);
|
||||
FREE(internal->propertyIDs);
|
||||
internal->propertyIDs = newPropertyIDs;
|
||||
internal->propertyIDsCapacity = capacity << 1;
|
||||
}
|
||||
}
|
||||
|
||||
int _spAnimationState_addPropertyID(spAnimationState* self, int id) {
|
||||
int _spAnimationState_addPropertyID(spAnimationState* self, spPropertyId id) {
|
||||
int i, n;
|
||||
_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
|
||||
|
||||
@ -983,6 +976,18 @@ int _spAnimationState_addPropertyID(spAnimationState* self, int id) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _spAnimationState_addPropertyIDs(spAnimationState* self, spPropertyId *ids, int numIds) {
|
||||
int i, n;
|
||||
_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
|
||||
int oldSize = internal->propertyIDsCount;
|
||||
|
||||
for (i = 0, n = numIds; i < n; i++) {
|
||||
_spAnimationState_addPropertyID(self, ids[i]);
|
||||
}
|
||||
|
||||
return internal->propertyIDsCount != oldSize;
|
||||
}
|
||||
|
||||
spTrackEntry* spAnimationState_getCurrent (spAnimationState* self, int trackIndex) {
|
||||
if (trackIndex >= self->tracksCount) return 0;
|
||||
return self->tracks[trackIndex];
|
||||
@ -1002,12 +1007,13 @@ 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;
|
||||
float spTrackEntry_getTrackComplete(spTrackEntry* entry) {
|
||||
float duration = entry->animationEnd - entry->animationStart;
|
||||
if (duration != 0) {
|
||||
if (entry->loop) return duration * (1 + (int)(entry->trackTime / duration)); /* Completion of next loop. */
|
||||
if (entry->trackTime < duration) return duration; /* Before duration. */
|
||||
}
|
||||
return entry->trackTime; /* Next update. */
|
||||
}
|
||||
|
||||
void _spTrackEntry_computeHold(spTrackEntry* entry, spAnimationState* state) {
|
||||
@ -1020,16 +1026,17 @@ void _spTrackEntry_computeHold(spTrackEntry* entry, spAnimationState* state) {
|
||||
int i;
|
||||
|
||||
to = entry->mixingTo;
|
||||
timelines = entry->animation->timelines;
|
||||
timelinesCount = entry->animation->timelinesCount;
|
||||
timelines = entry->animation->timelines->items;
|
||||
timelinesCount = entry->animation->timelines->size;
|
||||
timelineMode = spIntArray_setSize(entry->timelineMode, timelinesCount)->items;
|
||||
spTrackEntryArray_clear(entry->timelineHoldMix);
|
||||
timelineHoldMix = spTrackEntryArray_setSize(entry->timelineHoldMix, timelinesCount)->items;
|
||||
|
||||
if (to != 0 && to->holdPrevious) {
|
||||
for (i = 0; i < timelinesCount; i++) {
|
||||
int id = spTimeline_getPropertyId(timelines[i]);
|
||||
timelineMode[i] = _spAnimationState_addPropertyID(state, id) ? HOLD_FIRST : HOLD_SUBSEQUENT;
|
||||
spPropertyId* ids = timelines[i]->propertyIds;
|
||||
int numIds = timelines[i]->propertyIdsCount;
|
||||
timelineMode[i] = _spAnimationState_addPropertyIDs(state, ids, numIds) ? HOLD_FIRST : HOLD_SUBSEQUENT;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -1038,15 +1045,16 @@ void _spTrackEntry_computeHold(spTrackEntry* entry, spAnimationState* state) {
|
||||
continue_outer:
|
||||
for (; i < timelinesCount; i++) {
|
||||
spTimeline* timeline = timelines[i];
|
||||
int id = spTimeline_getPropertyId(timeline);
|
||||
if (!_spAnimationState_addPropertyID(state, id))
|
||||
spPropertyId *ids = timeline->propertyIds;
|
||||
int numIds = timeline->propertyIdsCount;
|
||||
if (!_spAnimationState_addPropertyIDs(state, ids, numIds))
|
||||
timelineMode[i] = SUBSEQUENT;
|
||||
else if (to == 0 || timeline->type == SP_TIMELINE_ATTACHMENT || timeline->type == SP_TIMELINE_DRAWORDER ||
|
||||
timeline->type == SP_TIMELINE_EVENT || !_spTrackEntry_hasTimeline(to, id)) {
|
||||
else if (to == 0 || timeline->propertyIds[0] == SP_PROPERTY_ATTACHMENT || timeline->propertyIds[0] == SP_PROPERTY_DRAWORDER ||
|
||||
timeline->propertyIds[0] == SP_PROPERTY_EVENT || !spAnimation_hasTimeline(to->animation, ids, numIds)) {
|
||||
timelineMode[i] = FIRST;
|
||||
} else {
|
||||
for (next = to->mixingTo; next != 0; next = next->mixingTo) {
|
||||
if (_spTrackEntry_hasTimeline(next, id)) continue;
|
||||
if (spAnimation_hasTimeline(next->animation, ids, numIds)) continue;
|
||||
if (next->mixDuration > 0) {
|
||||
timelineMode[i] = HOLD_MIX;
|
||||
timelineHoldMix[i] = next;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user