[c] Ported changes to Animation/Timeline.

This commit is contained in:
badlogic 2017-06-14 13:02:59 +02:00
parent 4735f3e118
commit 1772e32a6c
3 changed files with 179 additions and 88 deletions

View File

@ -248,12 +248,21 @@ void _spRotateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
bone = skeleton->bones[self->boneIndex];
if (time < self->frames[0]) {
if (setupPose) bone->rotation = bone->data->rotation;
switch (pose) {
case SP_MIX_POSE_SETUP:
bone->rotation = bone->data->rotation;
return;
case SP_MIX_POSE_CURRENT:
case SP_MIX_POSE_CURRENT_LAYERED: /* to appease compiler */
r = bone->data->rotation - bone->rotation;
r -= (16384 - (int)(16384.499999999996 - r / 360)) * 360;
bone->rotation += r * alpha;
}
return;
}
if (time >= self->frames[self->framesCount - ROTATE_ENTRIES]) { /* Time is after last frame. */
if (setupPose)
if (pose == SP_MIX_POSE_SETUP)
bone->rotation = bone->data->rotation + self->frames[self->framesCount + ROTATE_PREV_ROTATION] * alpha;
else {
r = bone->data->rotation + self->frames[self->framesCount + ROTATE_PREV_ROTATION] - bone->rotation;
@ -272,7 +281,7 @@ void _spRotateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
r = self->frames[frame + ROTATE_ROTATION] - prevRotation;
r -= (16384 - (int)(16384.499999999996 - r / 360)) * 360;
r = prevRotation + r * percent;
if (setupPose) {
if (pose == SP_MIX_POSE_SETUP) {
r -= (16384 - (int)(16384.499999999996 - r / 360)) * 360;
bone->rotation = bone->data->rotation + r * alpha;
} else {
@ -318,9 +327,15 @@ void _spTranslateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleto
bone = skeleton->bones[self->boneIndex];
if (time < self->frames[0]) {
if (setupPose) {
switch (pose) {
case SP_MIX_POSE_SETUP:
bone->x = bone->data->x;
bone->y = bone->data->y;
return;
case SP_MIX_POSE_CURRENT:
case SP_MIX_POSE_CURRENT_LAYERED: /* to appease compiler */
bone->x += (bone->data->x - bone->x) * alpha;
bone->y += (bone->data->y - bone->y) * alpha;
}
return;
}
@ -342,7 +357,7 @@ void _spTranslateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleto
x += (frames[frame + TRANSLATE_X] - x) * percent;
y += (frames[frame + TRANSLATE_Y] - y) * percent;
}
if (setupPose) {
if (pose == SP_MIX_POSE_SETUP) {
bone->x = bone->data->x + x * alpha;
bone->y = bone->data->y + y * alpha;
} else {
@ -384,9 +399,15 @@ void _spScaleTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
bone = skeleton->bones[self->boneIndex];
if (time < self->frames[0]) {
if (setupPose) {
switch (pose) {
case SP_MIX_POSE_SETUP:
bone->scaleX = bone->data->scaleX;
bone->scaleY = bone->data->scaleY;
return;
case SP_MIX_POSE_CURRENT:
case SP_MIX_POSE_CURRENT_LAYERED: /* to appease compiler */
bone->scaleX += (bone->data->scaleX - bone->scaleX) * alpha;
bone->scaleY += (bone->data->scaleY - bone->scaleY) * alpha;
}
return;
}
@ -413,7 +434,7 @@ void _spScaleTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
bone->scaleY = y;
} else {
float bx, by;
if (setupPose) {
if (pose == SP_MIX_POSE_SETUP) {
bx = bone->data->scaleX;
by = bone->data->scaleY;
} else {
@ -421,7 +442,7 @@ void _spScaleTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
by = bone->scaleY;
}
/* Mixing out uses sign of setup or current pose, else use sign of key. */
if (mixingOut) {
if (direction == SP_MIX_DIRECTION_OUT) {
x = ABS(x) * SIGNUM(bx);
y = ABS(y) * SIGNUM(by);
} else {
@ -465,9 +486,15 @@ void _spShearTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
frames = self->frames;
framesCount = self->framesCount;
if (time < self->frames[0]) {
if (setupPose) {
switch (pose) {
case SP_MIX_POSE_SETUP:
bone->shearX = bone->data->shearX;
bone->shearY = bone->data->shearY;
return;
case SP_MIX_POSE_CURRENT:
case SP_MIX_POSE_CURRENT_LAYERED: /* to appease compiler */
bone->shearX += (bone->data->shearX - bone->shearX) * alpha;
bone->shearY += (bone->data->shearY - bone->shearY) * alpha;
}
return;
}
@ -487,7 +514,7 @@ void _spShearTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
x = x + (frames[frame + TRANSLATE_X] - x) * percent;
y = y + (frames[frame + TRANSLATE_Y] - y) * percent;
}
if (setupPose) {
if (pose == SP_MIX_POSE_SETUP) {
bone->shearX = bone->data->shearX + x * alpha;
bone->shearY = bone->data->shearY + y * alpha;
} else {
@ -523,12 +550,22 @@ void _spColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
int frame;
float percent, frameTime;
float r, g, b, a;
spColor* color;
spColor* setup;
spColorTimeline* self = (spColorTimeline*)timeline;
slot = skeleton->slots[self->slotIndex];
if (time < self->frames[0]) {
if (setupPose) {
switch (pose) {
case SP_MIX_POSE_SETUP:
spColor_setFromColor(&slot->color, &slot->data->color);
return;
case SP_MIX_POSE_CURRENT:
case SP_MIX_POSE_CURRENT_LAYERED: /* to appease compiler */
color = &slot->color;
setup = &slot->data->color;
spColor_addFloats(color, (setup->r - color->r) * alpha, (setup->g - color->g) * alpha, (setup->b - color->b) * alpha,
(setup->a - color->a) * alpha);
}
return;
}
@ -560,7 +597,7 @@ void _spColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
if (alpha == 1) {
spColor_setFromFloats(&slot->color, r, g, b, a);
} else {
if (setupPose) {
if (pose == SP_MIX_POSE_SETUP) {
spColor_setFromColor(&slot->color, &slot->data->color);
}
spColor_addFloats(&slot->color, (r - slot->color.r) * alpha, (g - slot->color.g) * alpha, (b - slot->color.b) * alpha, (a - slot->color.a) * alpha);
@ -602,13 +639,26 @@ void _spTwoColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton
float r, g, b, a, r2, g2, b2;
spColor* light;
spColor* dark;
spColor* setupLight;
spColor* setupDark;
spColorTimeline* self = (spColorTimeline*)timeline;
slot = skeleton->slots[self->slotIndex];
if (time < self->frames[0]) {
if (setupPose) {
switch (pose) {
case SP_MIX_POSE_SETUP:
spColor_setFromColor(&slot->color, &slot->data->color);
spColor_setFromColor(slot->darkColor, slot->data->darkColor);
return;
case SP_MIX_POSE_CURRENT:
case SP_MIX_POSE_CURRENT_LAYERED: /* to appease compiler */
light = &slot->color;
dark = slot->darkColor;
setupLight = &slot->data->color;
setupDark = slot->data->darkColor;
spColor_addFloats(light, (setupLight->r - light->r) * alpha, (setupLight->g - light->g) * alpha, (setupLight->b - light->b) * alpha,
(setupLight->a - light->a) * alpha);
spColor_addFloats(dark, (setupDark->r - dark->r) * alpha, (setupDark->g - dark->g) * alpha, (setupDark->b - dark->b) * alpha, 0);
}
return;
}
@ -652,7 +702,7 @@ void _spTwoColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton
} else {
light = &slot->color;
dark = slot->darkColor;
if (setupPose) {
if (pose == SP_MIX_POSE_SETUP) {
spColor_setFromColor(light, &slot->data->color);
spColor_setFromColor(dark, slot->data->darkColor);
}
@ -694,14 +744,14 @@ void _spAttachmentTimeline_apply (const spTimeline* timeline, spSkeleton* skelet
int frameIndex;
spSlot* slot = skeleton->slots[self->slotIndex];
if (mixingOut && setupPose) {
if (direction == SP_MIX_DIRECTION_OUT && pose == SP_MIX_POSE_SETUP) {
const char* attachmentName = slot->data->attachmentName;
spSlot_setAttachment(slot, attachmentName ? spSkeleton_getAttachmentForSlotIndex(skeleton, self->slotIndex, attachmentName) : 0);
return;
}
if (time < self->frames[0]) {
if (setupPose) {
if (pose == SP_MIX_POSE_SETUP) {
attachmentName = slot->data->attachmentName;
spSlot_setAttachment(skeleton->slots[self->slotIndex],
attachmentName ? spSkeleton_getAttachmentForSlotIndex(skeleton, self->slotIndex, attachmentName) : 0);
@ -793,11 +843,6 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
frames = self->frames;
framesCount = self->framesCount;
if (time < frames[0]) { /* Time is before first frame. */
if (setupPose) slot->attachmentVerticesCount = 0;
return;
}
vertexCount = self->frameVerticesCount;
if (slot->attachmentVerticesCount < vertexCount) {
if (slot->attachmentVerticesCapacity < vertexCount) {
@ -806,18 +851,32 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
slot->attachmentVerticesCapacity = vertexCount;
}
}
if (slot->attachmentVerticesCount != vertexCount && !setupPose) alpha = 1; /* Don't mix from uninitialized slot vertices. */
if (slot->attachmentVerticesCount != vertexCount && pose != SP_MIX_POSE_SETUP) alpha = 1; /* Don't mix from uninitialized slot vertices. */
slot->attachmentVerticesCount = vertexCount;
frameVertices = self->frameVertices;
vertices = slot->attachmentVertices;
if (time < frames[0]) { /* Time is before first frame. */
switch (pose) {
case SP_MIX_POSE_SETUP:
slot->attachmentVerticesCount = 0;
return;
case SP_MIX_POSE_CURRENT:
case SP_MIX_POSE_CURRENT_LAYERED: /* to appease compiler */
alpha = 1 - alpha;
for (i = 0; i < vertexCount; i++)
vertices[i] *= alpha;
}
return;
}
if (time >= frames[framesCount - 1]) { /* Time is after last frame. */
const float* lastVertices = self->frameVertices[framesCount - 1];
if (alpha == 1) {
/* Vertex positions or deform offsets, no alpha. */
memcpy(vertices, lastVertices, vertexCount * sizeof(float));
} else if (setupPose) {
} else if (pose == SP_MIX_POSE_SETUP) {
spVertexAttachment* vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment);
if (!vertexAttachment->bones) {
/* Unweighted vertex positions, with alpha. */
@ -852,7 +911,7 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
float prev = prevVertices[i];
vertices[i] = prev + (nextVertices[i] - prev) * percent;
}
} else if (setupPose) {
} else if (pose == SP_MIX_POSE_SETUP) {
spVertexAttachment* vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment);
if (!vertexAttachment->bones) {
/* Unweighted vertex positions, with alpha. */
@ -882,7 +941,7 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
}
int _spDeformTimeline_getPropertyId (const spTimeline* timeline) {
return (SP_TIMELINE_DEFORM << 24) + SUB_CAST(spDeformTimeline, timeline)->slotIndex;
return (SP_TIMELINE_DEFORM << 27) + SUB_CAST(spVertexAttachment, SUB_CAST(spDeformTimeline, timeline)->attachment)->id + SUB_CAST(spDeformTimeline, timeline)->slotIndex;
}
void _spDeformTimeline_dispose (spTimeline* timeline) {
@ -931,7 +990,7 @@ void _spEventTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
if (!firedEvents) return;
if (lastTime > time) { /* Fire events after last time for looped animations. */
_spEventTimeline_apply(timeline, skeleton, lastTime, (float)INT_MAX, firedEvents, eventsCount, alpha, setupPose, mixingOut);
_spEventTimeline_apply(timeline, skeleton, lastTime, (float)INT_MAX, firedEvents, eventsCount, alpha, pose, direction);
lastTime = -1;
} else if (lastTime >= self->frames[self->framesCount - 1]) /* Last time is after last frame. */
return;
@ -998,13 +1057,13 @@ void _spDrawOrderTimeline_apply (const spTimeline* timeline, spSkeleton* skeleto
const int* drawOrderToSetupIndex;
spDrawOrderTimeline* self = (spDrawOrderTimeline*)timeline;
if (mixingOut && setupPose) {
if (direction == SP_MIX_DIRECTION_OUT && pose == SP_MIX_POSE_SETUP) {
memcpy(skeleton->drawOrder, skeleton->slots, self->slotsCount * sizeof(spSlot*));
return;
}
if (time < self->frames[0]) {
if (setupPose) memcpy(skeleton->drawOrder, skeleton->slots, self->slotsCount * sizeof(spSlot*));
if (pose == SP_MIX_POSE_SETUP) memcpy(skeleton->drawOrder, skeleton->slots, self->slotsCount * sizeof(spSlot*));
return;
}
@ -1085,9 +1144,15 @@ void _spIkConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skel
constraint = skeleton->ikConstraints[self->ikConstraintIndex];
if (time < self->frames[0]) {
if (setupPose) {
switch (pose) {
case SP_MIX_POSE_SETUP:
constraint->mix = constraint->data->mix;
constraint->bendDirection = constraint->data->bendDirection;
return;
case SP_MIX_POSE_CURRENT:
case SP_MIX_POSE_CURRENT_LAYERED: /* to appease compiler */
constraint->mix += (constraint->data->mix - constraint->mix) * alpha;
constraint->bendDirection = constraint->data->bendDirection;
}
return;
}
@ -1095,13 +1160,13 @@ void _spIkConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skel
frames = self->frames;
framesCount = self->framesCount;
if (time >= frames[framesCount - IKCONSTRAINT_ENTRIES]) { /* Time is after last frame. */
if (setupPose) {
if (pose == SP_MIX_POSE_SETUP) {
constraint->mix = constraint->data->mix + (frames[framesCount + IKCONSTRAINT_PREV_MIX] - constraint->data->mix) * alpha;
constraint->bendDirection = mixingOut ? constraint->data->bendDirection
constraint->bendDirection = direction == SP_MIX_DIRECTION_OUT ? constraint->data->bendDirection
: (int)frames[framesCount + IKCONSTRAINT_PREV_BEND_DIRECTION];
} else {
constraint->mix += (frames[framesCount + IKCONSTRAINT_PREV_MIX] - constraint->mix) * alpha;
if (!mixingOut) constraint->bendDirection = (int)frames[framesCount + IKCONSTRAINT_PREV_BEND_DIRECTION];
if (direction == SP_MIX_DIRECTION_IN) constraint->bendDirection = (int)frames[framesCount + IKCONSTRAINT_PREV_BEND_DIRECTION];
}
return;
}
@ -1112,12 +1177,12 @@ void _spIkConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skel
frameTime = self->frames[frame];
percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / IKCONSTRAINT_ENTRIES - 1, 1 - (time - frameTime) / (self->frames[frame + IKCONSTRAINT_PREV_TIME] - frameTime));
if (setupPose) {
if (pose == SP_MIX_POSE_SETUP) {
constraint->mix = constraint->data->mix + (mix + (frames[frame + IKCONSTRAINT_MIX] - mix) * percent - constraint->data->mix) * alpha;
constraint->bendDirection = mixingOut ? constraint->data->bendDirection : (int)frames[frame + IKCONSTRAINT_PREV_BEND_DIRECTION];
constraint->bendDirection = direction == SP_MIX_DIRECTION_OUT ? constraint->data->bendDirection : (int)frames[frame + IKCONSTRAINT_PREV_BEND_DIRECTION];
} else {
constraint->mix += (mix + (frames[frame + IKCONSTRAINT_MIX] - mix) * percent - constraint->mix) * alpha;
if (!mixingOut) constraint->bendDirection = (int)frames[frame + IKCONSTRAINT_PREV_BEND_DIRECTION];
if (direction == SP_MIX_DIRECTION_IN) constraint->bendDirection = (int)frames[frame + IKCONSTRAINT_PREV_BEND_DIRECTION];
}
UNUSED(lastTime);
@ -1162,14 +1227,23 @@ void _spTransformConstraintTimeline_apply (const spTimeline* timeline, spSkeleto
constraint = skeleton->transformConstraints[self->transformConstraintIndex];
if (time < self->frames[0]) {
if (setupPose) {
spTransformConstraintData* data = constraint->data;
switch (pose) {
case SP_MIX_POSE_SETUP:
constraint->rotateMix = data->rotateMix;
constraint->translateMix = data->translateMix;
constraint->scaleMix = data->scaleMix;
constraint->shearMix = data->shearMix;
return;
case SP_MIX_POSE_CURRENT:
case SP_MIX_POSE_CURRENT_LAYERED: /* to appease compiler */
constraint->rotateMix += (data->rotateMix - constraint->rotateMix) * alpha;
constraint->translateMix += (data->translateMix - constraint->translateMix) * alpha;
constraint->scaleMix += (data->scaleMix - constraint->scaleMix) * alpha;
constraint->shearMix += (data->shearMix - constraint->shearMix) * alpha;
}
return;
return;
}
frames = self->frames;
@ -1196,7 +1270,7 @@ void _spTransformConstraintTimeline_apply (const spTimeline* timeline, spSkeleto
scale += (frames[frame + TRANSFORMCONSTRAINT_SCALE] - scale) * percent;
shear += (frames[frame + TRANSFORMCONSTRAINT_SHEAR] - shear) * percent;
}
if (setupPose) {
if (pose == SP_MIX_POSE_SETUP) {
spTransformConstraintData* data = constraint->data;
constraint->rotateMix = data->rotateMix + (rotate - data->rotateMix) * alpha;
constraint->translateMix = data->translateMix + (translate - data->translateMix) * alpha;
@ -1248,8 +1322,13 @@ void _spPathConstraintPositionTimeline_apply(const spTimeline* timeline, spSkele
constraint = skeleton->pathConstraints[self->pathConstraintIndex];
if (time < self->frames[0]) {
if (setupPose) {
switch (pose) {
case SP_MIX_POSE_SETUP:
constraint->position = constraint->data->position;
return;
case SP_MIX_POSE_CURRENT:
case SP_MIX_POSE_CURRENT_LAYERED: /* to appease compiler */
constraint->position += (constraint->data->position - constraint->position) * alpha;
}
return;
}
@ -1268,7 +1347,7 @@ void _spPathConstraintPositionTimeline_apply(const spTimeline* timeline, spSkele
position += (frames[frame + PATHCONSTRAINTPOSITION_VALUE] - position) * percent;
}
if (setupPose)
if (pose == SP_MIX_POSE_SETUP)
constraint->position = constraint->data->position + (position - constraint->data->position) * alpha;
else
constraint->position += (position - constraint->position) * alpha;
@ -1308,8 +1387,13 @@ void _spPathConstraintSpacingTimeline_apply(const spTimeline* timeline, spSkelet
constraint = skeleton->pathConstraints[self->pathConstraintIndex];
if (time < self->frames[0]) {
if (setupPose) {
switch (pose) {
case SP_MIX_POSE_SETUP:
constraint->spacing = constraint->data->spacing;
return;
case SP_MIX_POSE_CURRENT:
case SP_MIX_POSE_CURRENT_LAYERED: /* to appease compiler */
constraint->spacing += (constraint->data->spacing - constraint->spacing) * alpha;
}
return;
}
@ -1329,7 +1413,7 @@ void _spPathConstraintSpacingTimeline_apply(const spTimeline* timeline, spSkelet
spacing += (frames[frame + PATHCONSTRAINTSPACING_VALUE] - spacing) * percent;
}
if (setupPose)
if (pose == SP_MIX_POSE_SETUP)
constraint->spacing = constraint->data->spacing + (spacing - constraint->data->spacing) * alpha;
else
constraint->spacing += (spacing - constraint->spacing) * alpha;
@ -1372,9 +1456,15 @@ void _spPathConstraintMixTimeline_apply(const spTimeline* timeline, spSkeleton*
constraint = skeleton->pathConstraints[self->pathConstraintIndex];
if (time < self->frames[0]) {
if (setupPose) {
switch (pose) {
case SP_MIX_POSE_SETUP:
constraint->rotateMix = constraint->data->rotateMix;
constraint->translateMix = constraint->data->translateMix;
return;
case SP_MIX_POSE_CURRENT:
case SP_MIX_POSE_CURRENT_LAYERED: /* to appease compiler */
constraint->rotateMix += (constraint->data->rotateMix - constraint->rotateMix) * alpha;
constraint->translateMix += (constraint->data->translateMix - constraint->translateMix) * alpha;
}
return;
}
@ -1397,7 +1487,7 @@ void _spPathConstraintMixTimeline_apply(const spTimeline* timeline, spSkeleton*
translate += (frames[frame + PATHCONSTRAINTMIX_TRANSLATE] - translate) * percent;
}
if (setupPose) {
if (pose == SP_MIX_POSE_SETUP) {
constraint->rotateMix = constraint->data->rotateMix + (rotate - constraint->data->rotateMix) * alpha;
constraint->translateMix = constraint->data->translateMix + (translate - constraint->data->translateMix) * alpha;
} else {

View File

@ -50,8 +50,8 @@ void spAnimationState_disposeStatics () {
void _spAnimationState_disposeTrackEntry (spTrackEntry* entry);
void _spAnimationState_disposeTrackEntries (spAnimationState* state, spTrackEntry* entry);
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);
float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* entry, spSkeleton* skeleton, spMixPose currentPose);
void _spAnimationState_applyRotateTimeline (spAnimationState* self, spTimeline* timeline, spSkeleton* skeleton, float time, float alpha, spMixPose pose, float* timelinesRotation, int i, int /*boolean*/ firstFrame);
void _spAnimationState_queueEvents (spAnimationState* self, spTrackEntry* entry, float animationTime);
void _spAnimationState_setCurrent (spAnimationState* self, int index, spTrackEntry* current, int /*boolean*/ interrupt);
spTrackEntry* _spAnimationState_expandToIndex (spAnimationState* self, int index);
@ -338,6 +338,8 @@ int spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) {
float* timelinesRotation;
spTimeline* timeline;
int applied = 0;
spMixPose currentPose;
spMixPose pose;
if (internal->animationsChanged) _spAnimationState_animationsChanged(self);
@ -346,11 +348,12 @@ int spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) {
current = self->tracks[i];
if (!current || current->delay > 0) continue;
applied = -1;
currentPose = i == 0 ? SP_MIX_POSE_CURRENT : SP_MIX_POSE_CURRENT_LAYERED;
/* Apply mixing from entries first. */
mix = current->alpha;
if (current->mixingFrom)
mix *= _spAnimationState_applyMixingFrom(self, current, skeleton);
mix *= _spAnimationState_applyMixingFrom(self, current, skeleton, currentPose);
else if (current->trackTime >= current->trackEnd && current->next == 0)
mix = 0;
@ -360,7 +363,7 @@ int spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) {
timelines = current->animation->timelines;
if (mix == 1) {
for (ii = 0; ii < timelineCount; ii++)
spTimeline_apply(timelines[ii], skeleton, animationLast, animationTime, internal->events, &internal->eventsCount, 1, 1, 0);
spTimeline_apply(timelines[ii], skeleton, animationLast, animationTime, internal->events, &internal->eventsCount, 1, SP_MIX_POSE_SETUP, SP_MIX_DIRECTION_IN);
} else {
spIntArray* timelineData = current->timelineData;
@ -370,10 +373,11 @@ int spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) {
for (ii = 0; ii < timelineCount; ii++) {
timeline = timelines[ii];
pose = timelineData->items[ii] >= FIRST ? SP_MIX_POSE_SETUP : currentPose;
if (timeline->type == SP_TIMELINE_ROTATE)
_spAnimationState_applyRotateTimeline(self, timeline, skeleton, animationTime, mix, timelineData->items[ii] >= FIRST, timelinesRotation, ii << 1, firstFrame);
_spAnimationState_applyRotateTimeline(self, timeline, skeleton, animationTime, mix, pose, timelinesRotation, ii << 1, firstFrame);
else
spTimeline_apply(timeline, skeleton, animationLast, animationTime, internal->events, &internal->eventsCount, mix, timelineData->items[ii] >= FIRST, 0);
spTimeline_apply(timeline, skeleton, animationLast, animationTime, internal->events, &internal->eventsCount, mix, pose, SP_MIX_DIRECTION_IN);
}
}
_spAnimationState_queueEvents(self, current, animationTime);
@ -386,7 +390,7 @@ int spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) {
return applied;
}
float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* to, spSkeleton* skeleton) {
float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* to, spSkeleton* skeleton, spMixPose currentPose) {
_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
float mix;
spEvent** events;
@ -403,12 +407,12 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* t
float alpha;
int /*boolean*/ firstFrame;
float* timelinesRotation;
int /*boolean*/ first;
spMixPose pose;
int i;
spTrackEntry* dipMix;
spTrackEntry* from = to->mixingFrom;
if (from->mixingFrom) _spAnimationState_applyMixingFrom(self, from, skeleton);
if (from->mixingFrom) _spAnimationState_applyMixingFrom(self, from, skeleton, currentPose);
if (to->mixDuration == 0) /* Single frame mix to undo mixingFrom changes. */
mix = 1;
@ -431,26 +435,27 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* t
if (firstFrame) _spAnimationState_resizeTimelinesRotation(from, timelineCount << 1);
timelinesRotation = from->timelinesRotation;
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]) {
case SUBSEQUENT:
first = 0;
if (!attachments && timeline->type == SP_TIMELINE_ATTACHMENT) continue;
if (!drawOrder && timeline->type == SP_TIMELINE_DRAWORDER) continue;
pose = currentPose;
alpha = alphaMix;
break;
case FIRST:
first = 1;
pose = SP_MIX_POSE_SETUP;
alpha = alphaMix;
break;
case DIP:
first = 1;
pose = SP_MIX_POSE_SETUP;
alpha = alphaDip;
break;
default:
first = 1;
pose = SP_MIX_POSE_SETUP;
alpha = alphaDip;
dipMix = timelineDipMix->items[i];
alpha *= MAX(0, 1 - dipMix->mixTime / dipMix->mixDuration);
@ -458,13 +463,9 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* t
}
from->totalAlpha += alpha;
if (timeline->type == SP_TIMELINE_ROTATE)
_spAnimationState_applyRotateTimeline(self, timeline, skeleton, animationTime, alpha, first, timelinesRotation, i << 1, firstFrame);
_spAnimationState_applyRotateTimeline(self, timeline, skeleton, animationTime, alpha, pose, timelinesRotation, i << 1, firstFrame);
else {
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, first, 1);
spTimeline_apply(timeline, skeleton, animationLast, animationTime, events, &internal->eventsCount, alpha, pose, SP_MIX_DIRECTION_OUT);
}
}
@ -477,7 +478,7 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* t
return mix;
}
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_applyRotateTimeline (spAnimationState* self, spTimeline* timeline, spSkeleton* skeleton, float time, float alpha, spMixPose pose, float* timelinesRotation, int i, int /*boolean*/ firstFrame) {
spRotateTimeline *rotateTimeline;
float *frames;
spBone* bone;
@ -492,7 +493,7 @@ void _spAnimationState_applyRotateTimeline (spAnimationState* self, spTimeline*
if (firstFrame) timelinesRotation[i] = 0;
if (alpha == 1) {
spTimeline_apply(timeline, skeleton, 0, time, 0, 0, 1, setupPose, 0);
spTimeline_apply(timeline, skeleton, 0, time, 0, 0, 1, pose, SP_MIX_DIRECTION_IN);
return;
}
@ -500,7 +501,7 @@ void _spAnimationState_applyRotateTimeline (spAnimationState* self, spTimeline*
frames = rotateTimeline->frames;
bone = skeleton->bones[rotateTimeline->boneIndex];
if (time < frames[0]) {
if (setupPose) {
if (pose == SP_MIX_POSE_SETUP) {
bone->rotation = bone->data->rotation;
}
return; /* Time is before first frame. */
@ -523,7 +524,7 @@ void _spAnimationState_applyRotateTimeline (spAnimationState* self, spTimeline*
}
/* Mix between rotations using the direction of the shortest route on the first frame while detecting crosses. */
r1 = setupPose ? bone->data->rotation : bone->rotation;
r1 = pose == SP_MIX_POSE_SETUP ? bone->data->rotation : bone->rotation;
diff = r2 - r1;
if (diff == 0) {
total = timelinesRotation[i];

View File

@ -31,7 +31,7 @@
#include <spine/VertexAttachment.h>
#include <spine/extension.h>
// FIXME this is not thread-safe
/* FIXME this is not thread-safe */
static int nextID = 0;
void _spVertexAttachment_init (spVertexAttachment* attachment) {