From 4735f3e118c431079ff9ee1ca0951bfab4210573 Mon Sep 17 00:00:00 2001 From: badlogic Date: Tue, 13 Jun 2017 00:53:00 +0200 Subject: [PATCH 1/2] [c] Preparation work for animation/timeline changes. --- spine-c/spine-c/include/spine/Animation.h | 15 +++++- .../spine-c/include/spine/VertexAttachment.h | 2 + spine-c/spine-c/include/spine/extension.h | 5 +- spine-c/spine-c/src/spine/Animation.c | 46 +++++++++---------- .../spine-c/src/spine/BoundingBoxAttachment.c | 1 + .../spine-c/src/spine/ClippingAttachment.c | 1 + spine-c/spine-c/src/spine/MeshAttachment.c | 1 + spine-c/spine-c/src/spine/PathAttachment.c | 1 + spine-c/spine-c/src/spine/PointAttachment.c | 1 + spine-c/spine-c/src/spine/VertexAttachment.c | 7 +++ 10 files changed, 53 insertions(+), 27 deletions(-) diff --git a/spine-c/spine-c/include/spine/Animation.h b/spine-c/spine-c/include/spine/Animation.h index b697181ac..b0de4a9bc 100644 --- a/spine-c/spine-c/include/spine/Animation.h +++ b/spine-c/spine-c/include/spine/Animation.h @@ -58,6 +58,17 @@ typedef struct spAnimation { #endif } spAnimation; +typedef enum { + SP_MIX_POSE_SETUP, + SP_MIX_POSE_CURRENT, + SP_MIX_POSE_CURRENT_LAYERED +} spMixPose; + +typedef enum { + SP_MIX_DIRECTION_IN, + SP_MIX_DIRECTION_OUT +} spMixDirection; + spAnimation* spAnimation_create (const char* name, int timelinesCount); void spAnimation_dispose (spAnimation* self); @@ -65,7 +76,7 @@ void spAnimation_dispose (spAnimation* self); * @param lastTime The last time the animation was applied. * @param events Any triggered events are added. May be null.*/ void spAnimation_apply (const spAnimation* self, struct spSkeleton* skeleton, float lastTime, float time, int loop, - spEvent** events, int* eventsCount, float alpha, int /*boolean*/ setupPose, int /*boolean*/ mixingOut); + spEvent** events, int* eventsCount, float alpha, spMixPose pose, spMixDirection direction); #ifdef SPINE_SHORT_NAMES typedef spAnimation Animation; @@ -108,7 +119,7 @@ struct spTimeline { void spTimeline_dispose (spTimeline* self); void spTimeline_apply (const spTimeline* self, struct spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, - int* eventsCount, float alpha, int /*boolean*/ setupPose, int /*boolean*/ mixingOut); + int* eventsCount, float alpha, spMixPose pose, spMixDirection direction); int spTimeline_getPropertyId (const spTimeline* self); #ifdef SPINE_SHORT_NAMES diff --git a/spine-c/spine-c/include/spine/VertexAttachment.h b/spine-c/spine-c/include/spine/VertexAttachment.h index 07ddcbd91..759921a39 100644 --- a/spine-c/spine-c/include/spine/VertexAttachment.h +++ b/spine-c/spine-c/include/spine/VertexAttachment.h @@ -49,6 +49,8 @@ struct spVertexAttachment { float* vertices; int worldVerticesLength; + + int id; }; void spVertexAttachment_computeWorldVertices (spVertexAttachment* self, spSlot* slot, int start, int count, float* worldVertices, int offset, int stride); diff --git a/spine-c/spine-c/include/spine/extension.h b/spine-c/spine-c/include/spine/extension.h index 71eba269d..79155ee8b 100644 --- a/spine-c/spine-c/include/spine/extension.h +++ b/spine-c/spine-c/include/spine/extension.h @@ -258,6 +258,7 @@ void _spAttachmentLoader_setUnknownTypeError (spAttachmentLoader* self, spAttach void _spAttachment_init (spAttachment* self, const char* name, spAttachmentType type, void (*dispose) (spAttachment* self)); void _spAttachment_deinit (spAttachment* self); +void _spVertexAttachment_init (spVertexAttachment* self); void _spVertexAttachment_deinit (spVertexAttachment* self); #ifdef SPINE_SHORT_NAMES @@ -271,7 +272,7 @@ void _spVertexAttachment_deinit (spVertexAttachment* self); void _spTimeline_init (spTimeline* self, spTimelineType type, void (*dispose) (spTimeline* self), void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, - int* eventsCount, float alpha, int setupPose, int mixingOut), + int* eventsCount, float alpha, spMixPose pose, spMixDirection direction), int (*getPropertyId) (const spTimeline* self)); void _spTimeline_deinit (spTimeline* self); @@ -284,7 +285,7 @@ void _spTimeline_deinit (spTimeline* self); void _spCurveTimeline_init (spCurveTimeline* self, spTimelineType type, int framesCount, void (*dispose) (spTimeline* self), - void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, int* eventsCount, float alpha, int setupPose, int mixingOut), + void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, int* eventsCount, float alpha, spMixPose pose, spMixDirection direction), int (*getPropertyId) (const spTimeline* self)); void _spCurveTimeline_deinit (spCurveTimeline* self); int _spCurveTimeline_binarySearch (float *values, int valuesLength, float target, int step); diff --git a/spine-c/spine-c/src/spine/Animation.c b/spine-c/spine-c/src/spine/Animation.c index 3f3fd80a1..19112e842 100644 --- a/spine-c/spine-c/src/spine/Animation.c +++ b/spine-c/spine-c/src/spine/Animation.c @@ -51,7 +51,7 @@ void spAnimation_dispose (spAnimation* self) { } void spAnimation_apply (const spAnimation* self, spSkeleton* skeleton, float lastTime, float time, int loop, spEvent** events, - int* eventsCount, float alpha, int setupPose, int mixingOut) { + int* eventsCount, float alpha, spMixPose pose, spMixDirection direction) { int i, n = self->timelinesCount; if (loop && self->duration) { @@ -60,21 +60,21 @@ void spAnimation_apply (const spAnimation* self, spSkeleton* skeleton, float las } for (i = 0; i < n; ++i) - spTimeline_apply(self->timelines[i], skeleton, lastTime, time, events, eventsCount, alpha, setupPose, mixingOut); + spTimeline_apply(self->timelines[i], skeleton, lastTime, time, events, eventsCount, alpha, pose, direction); } /**/ typedef struct _spTimelineVtable { void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, - int* eventsCount, float alpha, int setupPose, int mixingOut); + int* eventsCount, float alpha, spMixPose pose, spMixDirection direction); int (*getPropertyId) (const spTimeline* self); void (*dispose) (spTimeline* self); } _spTimelineVtable; void _spTimeline_init (spTimeline* self, spTimelineType type, /**/ void (*dispose) (spTimeline* self), /**/ - void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, int* eventsCount, float alpha, int setupPose, int mixingOut), + void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, int* eventsCount, float alpha, spMixPose pose, spMixDirection direction), int (*getPropertyId) (const spTimeline* self)) { CONST_CAST(spTimelineType, self->type) = type; CONST_CAST(_spTimelineVtable*, self->vtable) = NEW(_spTimelineVtable); @@ -92,8 +92,8 @@ void spTimeline_dispose (spTimeline* self) { } void spTimeline_apply (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, - int* eventsCount, float alpha, int /*boolean*/ setupPose, int /*boolean*/ mixingOut) { - VTABLE(spTimeline, self)->apply(self, skeleton, lastTime, time, firedEvents, eventsCount, alpha, setupPose, mixingOut); + int* eventsCount, float alpha, spMixPose pose, spMixDirection direction) { + VTABLE(spTimeline, self)->apply(self, skeleton, lastTime, time, firedEvents, eventsCount, alpha, pose, direction); } int spTimeline_getPropertyId (const spTimeline* self) { @@ -107,7 +107,7 @@ static const int BEZIER_SIZE = 10 * 2 - 1; void _spCurveTimeline_init (spCurveTimeline* self, spTimelineType type, int framesCount, /**/ void (*dispose) (spTimeline* self), /**/ - void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, int* eventsCount, float alpha, int setupPose, int mixingOut), + void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, int* eventsCount, float alpha, spMixPose pose, spMixDirection direction), int (*getPropertyId)(const spTimeline* self)) { _spTimeline_init(SUPER(self), type, dispose, apply, getPropertyId); self->curves = CALLOC(float, (framesCount - 1) * BEZIER_SIZE); @@ -225,7 +225,7 @@ void _spBaseTimeline_dispose (spTimeline* timeline) { /* Many timelines have structure identical to struct spBaseTimeline and extend spCurveTimeline. **/ struct spBaseTimeline* _spBaseTimeline_create (int framesCount, spTimelineType type, int frameSize, /**/ void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, - int* eventsCount, float alpha, int setupPose, int mixingOut), + int* eventsCount, float alpha, spMixPose pose, spMixDirection direction), int (*getPropertyId) (const spTimeline* self)) { struct spBaseTimeline* self = NEW(struct spBaseTimeline); _spCurveTimeline_init(SUPER(self), type, framesCount, _spBaseTimeline_dispose, apply, getPropertyId); @@ -239,7 +239,7 @@ struct spBaseTimeline* _spBaseTimeline_create (int framesCount, spTimelineType t /**/ void _spRotateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, - int* eventsCount, float alpha, int setupPose, int mixingOut) { + int* eventsCount, float alpha, spMixPose pose, spMixDirection direction) { spBone *bone; int frame; float prevRotation, frameTime, percent, r; @@ -306,7 +306,7 @@ static const int TRANSLATE_PREV_TIME = -3, TRANSLATE_PREV_X = -2, TRANSLATE_PREV static const int TRANSLATE_X = 1, TRANSLATE_Y = 2; void _spTranslateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, - spEvent** firedEvents, int* eventsCount, float alpha, int setupPose, int mixingOut) { + spEvent** firedEvents, int* eventsCount, float alpha, spMixPose pose, spMixDirection direction) { spBone *bone; int frame; float frameTime, percent; @@ -373,7 +373,7 @@ void spTranslateTimeline_setFrame (spTranslateTimeline* self, int frameIndex, fl /**/ void _spScaleTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, - int* eventsCount, float alpha, int setupPose, int mixingOut) { + int* eventsCount, float alpha, spMixPose pose, spMixDirection direction) { spBone *bone; int frame; float frameTime, percent, x, y; @@ -452,7 +452,7 @@ void spScaleTimeline_setFrame (spScaleTimeline* self, int frameIndex, float time /**/ void _spShearTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, - int* eventsCount, float alpha, int setupPose, int mixingOut) { + int* eventsCount, float alpha, spMixPose pose, spMixDirection direction) { spBone *bone; int frame; float frameTime, percent, x, y; @@ -518,7 +518,7 @@ static const int COLOR_PREV_TIME = -5, COLOR_PREV_R = -4, COLOR_PREV_G = -3, COL static const int COLOR_R = 1, COLOR_G = 2, COLOR_B = 3, COLOR_A = 4; void _spColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, - int* eventsCount, float alpha, int setupPose, int mixingOut) { + int* eventsCount, float alpha, spMixPose pose, spMixDirection direction) { spSlot *slot; int frame; float percent, frameTime; @@ -595,7 +595,7 @@ static const int TWOCOLOR_PREV_R2 = -3, TWOCOLOR_PREV_G2 = -2, TWOCOLOR_PREV_B2 static const int TWOCOLOR_R = 1, TWOCOLOR_G = 2, TWOCOLOR_B = 3, TWOCOLOR_A = 4, TWOCOLOR_R2 = 5, TWOCOLOR_G2 = 6, TWOCOLOR_B2 = 7; void _spTwoColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, - int* eventsCount, float alpha, int setupPose, int mixingOut) { + int* eventsCount, float alpha, spMixPose pose, spMixDirection direction) { spSlot *slot; int frame; float percent, frameTime; @@ -688,7 +688,7 @@ void spTwoColorTimeline_setFrame (spTwoColorTimeline* self, int frameIndex, floa /**/ void _spAttachmentTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, - spEvent** firedEvents, int* eventsCount, float alpha, int setupPose, int mixingOut) { + spEvent** firedEvents, int* eventsCount, float alpha, spMixPose pose, spMixDirection direction) { const char* attachmentName; spAttachmentTimeline* self = (spAttachmentTimeline*)timeline; int frameIndex; @@ -765,7 +765,7 @@ void spAttachmentTimeline_setFrame (spAttachmentTimeline* self, int frameIndex, /**/ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, - int* eventsCount, float alpha, int setupPose, int mixingOut) { + int* eventsCount, float alpha, spMixPose pose, spMixDirection direction) { int frame, i, vertexCount; float percent, frameTime; const float* prevVertices; @@ -925,7 +925,7 @@ void spDeformTimeline_setFrame (spDeformTimeline* self, int frameIndex, float ti /** Fires events for frames > lastTime and <= time. */ void _spEventTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, - int* eventsCount, float alpha, int setupPose, int mixingOut) { + int* eventsCount, float alpha, spMixPose pose, spMixDirection direction) { spEventTimeline* self = (spEventTimeline*)timeline; int frame; if (!firedEvents) return; @@ -992,7 +992,7 @@ void spEventTimeline_setFrame (spEventTimeline* self, int frameIndex, spEvent* e /**/ void _spDrawOrderTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, - spEvent** firedEvents, int* eventsCount, float alpha, int setupPose, int mixingOut) { + spEvent** firedEvents, int* eventsCount, float alpha, spMixPose pose, spMixDirection direction) { int i; int frame; const int* drawOrderToSetupIndex; @@ -1074,7 +1074,7 @@ static const int IKCONSTRAINT_PREV_TIME = -3, IKCONSTRAINT_PREV_MIX = -2, IKCONS static const int IKCONSTRAINT_MIX = 1, IKCONSTRAINT_BEND_DIRECTION = 2; void _spIkConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, - spEvent** firedEvents, int* eventsCount, float alpha, int setupPose, int mixingOut) { + spEvent** firedEvents, int* eventsCount, float alpha, spMixPose pose, spMixDirection direction) { int frame; float frameTime, percent, mix; float *frames; @@ -1152,7 +1152,7 @@ static const int TRANSFORMCONSTRAINT_SCALE = 3; static const int TRANSFORMCONSTRAINT_SHEAR = 4; void _spTransformConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, - spEvent** firedEvents, int* eventsCount, float alpha, int setupPose, int mixingOut) { + spEvent** firedEvents, int* eventsCount, float alpha, spMixPose pose, spMixDirection direction) { int frame; float frameTime, percent, rotate, translate, scale, shear; spTransformConstraint* constraint; @@ -1238,7 +1238,7 @@ static const int PATHCONSTRAINTPOSITION_PREV_VALUE = -1; static const int PATHCONSTRAINTPOSITION_VALUE = 1; void _spPathConstraintPositionTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, - spEvent** firedEvents, int* eventsCount, float alpha, int setupPose, int mixingOut) { + spEvent** firedEvents, int* eventsCount, float alpha, spMixPose pose, spMixDirection direction) { int frame; float frameTime, percent, position; spPathConstraint* constraint; @@ -1298,7 +1298,7 @@ static const int PATHCONSTRAINTSPACING_PREV_VALUE = -1; static const int PATHCONSTRAINTSPACING_VALUE = 1; void _spPathConstraintSpacingTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, - spEvent** firedEvents, int* eventsCount, float alpha, int setupPose, int mixingOut) { + spEvent** firedEvents, int* eventsCount, float alpha, spMixPose pose, spMixDirection direction) { int frame; float frameTime, percent, spacing; spPathConstraint* constraint; @@ -1362,7 +1362,7 @@ static const int PATHCONSTRAINTMIX_ROTATE = 1; static const int PATHCONSTRAINTMIX_TRANSLATE = 2; void _spPathConstraintMixTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, - spEvent** firedEvents, int* eventsCount, float alpha, int setupPose, int mixingOut) { + spEvent** firedEvents, int* eventsCount, float alpha, spMixPose pose, spMixDirection direction) { int frame; float frameTime, percent, rotate, translate; spPathConstraint* constraint; diff --git a/spine-c/spine-c/src/spine/BoundingBoxAttachment.c b/spine-c/spine-c/src/spine/BoundingBoxAttachment.c index 55f2f5701..f8b45f5c7 100644 --- a/spine-c/spine-c/src/spine/BoundingBoxAttachment.c +++ b/spine-c/spine-c/src/spine/BoundingBoxAttachment.c @@ -41,6 +41,7 @@ void _spBoundingBoxAttachment_dispose (spAttachment* attachment) { spBoundingBoxAttachment* spBoundingBoxAttachment_create (const char* name) { spBoundingBoxAttachment* self = NEW(spBoundingBoxAttachment); + _spVertexAttachment_init(SUPER(self)); _spAttachment_init(SUPER(SUPER(self)), name, SP_ATTACHMENT_BOUNDING_BOX, _spBoundingBoxAttachment_dispose); return self; } diff --git a/spine-c/spine-c/src/spine/ClippingAttachment.c b/spine-c/spine-c/src/spine/ClippingAttachment.c index 42bc998e3..38ea8dd31 100644 --- a/spine-c/spine-c/src/spine/ClippingAttachment.c +++ b/spine-c/spine-c/src/spine/ClippingAttachment.c @@ -41,6 +41,7 @@ void _spClippingAttachment_dispose (spAttachment* attachment) { spClippingAttachment* spClippingAttachment_create (const char* name) { spClippingAttachment* self = NEW(spClippingAttachment); + _spVertexAttachment_init(SUPER(self)); _spAttachment_init(SUPER(SUPER(self)), name, SP_ATTACHMENT_CLIPPING, _spClippingAttachment_dispose); self->endSlot = 0; return self; diff --git a/spine-c/spine-c/src/spine/MeshAttachment.c b/spine-c/spine-c/src/spine/MeshAttachment.c index 50a507c16..b7a49bfdc 100644 --- a/spine-c/spine-c/src/spine/MeshAttachment.c +++ b/spine-c/spine-c/src/spine/MeshAttachment.c @@ -47,6 +47,7 @@ void _spMeshAttachment_dispose (spAttachment* attachment) { spMeshAttachment* spMeshAttachment_create (const char* name) { spMeshAttachment* self = NEW(spMeshAttachment); + _spVertexAttachment_init(SUPER(self)); spColor_setFromFloats(&self->color, 1, 1, 1, 1); _spAttachment_init(SUPER(SUPER(self)), name, SP_ATTACHMENT_MESH, _spMeshAttachment_dispose); return self; diff --git a/spine-c/spine-c/src/spine/PathAttachment.c b/spine-c/spine-c/src/spine/PathAttachment.c index 98d1c35bf..f81b3fd1c 100644 --- a/spine-c/spine-c/src/spine/PathAttachment.c +++ b/spine-c/spine-c/src/spine/PathAttachment.c @@ -42,6 +42,7 @@ void _spPathAttachment_dispose (spAttachment* attachment) { spPathAttachment* spPathAttachment_create (const char* name) { spPathAttachment* self = NEW(spPathAttachment); + _spVertexAttachment_init(SUPER(self)); _spAttachment_init(SUPER(SUPER(self)), name, SP_ATTACHMENT_PATH, _spPathAttachment_dispose); return self; } diff --git a/spine-c/spine-c/src/spine/PointAttachment.c b/spine-c/spine-c/src/spine/PointAttachment.c index 3faf66f0c..9a0139663 100644 --- a/spine-c/spine-c/src/spine/PointAttachment.c +++ b/spine-c/spine-c/src/spine/PointAttachment.c @@ -41,6 +41,7 @@ void _spPointAttachment_dispose (spAttachment* attachment) { spPointAttachment* spPointAttachment_create (const char* name) { spPointAttachment* self = NEW(spPointAttachment); + _spVertexAttachment_init(SUPER(self)); _spAttachment_init(SUPER(SUPER(self)), name, SP_ATTACHMENT_POINT, _spPointAttachment_dispose); return self; } diff --git a/spine-c/spine-c/src/spine/VertexAttachment.c b/spine-c/spine-c/src/spine/VertexAttachment.c index 286f0473e..fd2bbe1b3 100644 --- a/spine-c/spine-c/src/spine/VertexAttachment.c +++ b/spine-c/spine-c/src/spine/VertexAttachment.c @@ -31,6 +31,13 @@ #include #include +// FIXME this is not thread-safe +static int nextID = 0; + +void _spVertexAttachment_init (spVertexAttachment* attachment) { + attachment->id = (nextID++ & 65535) << 11; +} + void _spVertexAttachment_deinit (spVertexAttachment* attachment) { _spAttachment_deinit(SUPER(attachment)); FREE(attachment->bones); From 1772e32a6ce4491de520d6a23c8448e1746586a4 Mon Sep 17 00:00:00 2001 From: badlogic Date: Wed, 14 Jun 2017 13:02:59 +0200 Subject: [PATCH 2/2] [c] Ported changes to Animation/Timeline. --- spine-c/spine-c/src/spine/Animation.c | 216 +++++++++++++------ spine-c/spine-c/src/spine/AnimationState.c | 49 ++--- spine-c/spine-c/src/spine/VertexAttachment.c | 2 +- 3 files changed, 179 insertions(+), 88 deletions(-) diff --git a/spine-c/spine-c/src/spine/Animation.c b/spine-c/spine-c/src/spine/Animation.c index 19112e842..51771caeb 100644 --- a/spine-c/spine-c/src/spine/Animation.c +++ b/spine-c/spine-c/src/spine/Animation.c @@ -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) { - bone->x = bone->data->x; - bone->y = bone->data->y; + 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) { - bone->scaleX = bone->data->scaleX; - bone->scaleY = bone->data->scaleY; + 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) { - bone->shearX = bone->data->shearX; - bone->shearY = bone->data->shearY; + 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) { - spColor_setFromColor(&slot->color, &slot->data->color); + 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) { - spColor_setFromColor(&slot->color, &slot->data->color); - spColor_setFromColor(slot->darkColor, slot->data->darkColor); + 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) { - constraint->mix = constraint->data->mix; - constraint->bendDirection = constraint->data->bendDirection; + 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; - constraint->rotateMix = data->rotateMix; - constraint->translateMix = data->translateMix; - constraint->scaleMix = data->scaleMix; - constraint->shearMix = data->shearMix; + 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) { - constraint->position = constraint->data->position; + 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) { - constraint->spacing = constraint->data->spacing; + 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) { - constraint->rotateMix = constraint->data->rotateMix; - constraint->translateMix = constraint->data->translateMix; + 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 { diff --git a/spine-c/spine-c/src/spine/AnimationState.c b/spine-c/spine-c/src/spine/AnimationState.c index 0e1f8a481..6cb060827 100644 --- a/spine-c/spine-c/src/spine/AnimationState.c +++ b/spine-c/spine-c/src/spine/AnimationState.c @@ -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]; diff --git a/spine-c/spine-c/src/spine/VertexAttachment.c b/spine-c/spine-c/src/spine/VertexAttachment.c index fd2bbe1b3..8b6dfea36 100644 --- a/spine-c/spine-c/src/spine/VertexAttachment.c +++ b/spine-c/spine-c/src/spine/VertexAttachment.c @@ -31,7 +31,7 @@ #include #include -// FIXME this is not thread-safe +/* FIXME this is not thread-safe */ static int nextID = 0; void _spVertexAttachment_init (spVertexAttachment* attachment) {