From 4785ad656ddbc8d39977738eb241b7781ca39a06 Mon Sep 17 00:00:00 2001 From: badlogic Date: Mon, 25 Mar 2019 14:55:34 +0100 Subject: [PATCH] [c] Ported AniamtionState and Animation changes. See #1303. --- spine-c/spine-c/include/spine/Slot.h | 12 ++-- spine-c/spine-c/src/spine/Animation.c | 60 ++++++++++---------- spine-c/spine-c/src/spine/AnimationState.c | 51 ++++++++++++++--- spine-c/spine-c/src/spine/Slot.c | 4 +- spine-c/spine-c/src/spine/VertexAttachment.c | 10 ++-- 5 files changed, 85 insertions(+), 52 deletions(-) diff --git a/spine-c/spine-c/include/spine/Slot.h b/spine-c/spine-c/include/spine/Slot.h index 04647689a..0a78393d8 100644 --- a/spine-c/spine-c/include/spine/Slot.h +++ b/spine-c/spine-c/include/spine/Slot.h @@ -47,9 +47,9 @@ typedef struct spSlot { spColor* darkColor; spAttachment* const attachment; - int attachmentVerticesCapacity; - int attachmentVerticesCount; - float* attachmentVertices; + int deformCapacity; + int deformCount; + float* deform; #ifdef __cplusplus spSlot() : @@ -58,9 +58,9 @@ typedef struct spSlot { color(), darkColor(0), attachment(0), - attachmentVerticesCapacity(0), - attachmentVerticesCount(0), - attachmentVertices(0) { + deformCapacity(0), + deformCount(0), + deform(0) { } #endif } spSlot; diff --git a/spine-c/spine-c/src/spine/Animation.c b/spine-c/spine-c/src/spine/Animation.c index eb236a3c4..573226992 100644 --- a/spine-c/spine-c/src/spine/Animation.c +++ b/spine-c/spine-c/src/spine/Animation.c @@ -890,7 +890,7 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float* frames; int framesCount; const float** frameVertices; - float* vertices; + float* deformArray; spDeformTimeline* self = (spDeformTimeline*)timeline; spSlot *slot = skeleton->slots[self->slotIndex]; @@ -911,39 +911,39 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, frames = self->frames; framesCount = self->framesCount; vertexCount = self->frameVerticesCount; - if (slot->attachmentVerticesCount < vertexCount) { - if (slot->attachmentVerticesCapacity < vertexCount) { - FREE(slot->attachmentVertices); - slot->attachmentVertices = MALLOC(float, vertexCount); - slot->attachmentVerticesCapacity = vertexCount; + if (slot->deformCount < vertexCount) { + if (slot->deformCapacity < vertexCount) { + FREE(slot->deform); + slot->deform = MALLOC(float, vertexCount); + slot->deformCapacity = vertexCount; } } - if (slot->attachmentVerticesCount == 0) blend = SP_MIX_BLEND_SETUP; + if (slot->deformCount == 0) blend = SP_MIX_BLEND_SETUP; frameVertices = self->frameVertices; - vertices = slot->attachmentVertices; + deformArray = slot->deform; if (time < frames[0]) { /* Time is before first frame. */ spVertexAttachment* vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment); switch (blend) { case SP_MIX_BLEND_SETUP: - slot->attachmentVerticesCount = 0; + slot->deformCount = 0; return; case SP_MIX_BLEND_FIRST: if (alpha == 1) { - slot->attachmentVerticesCount = 0; + slot->deformCount = 0; return; } - slot->attachmentVerticesCount = vertexCount; + slot->deformCount = vertexCount; if (!vertexAttachment->bones) { float* setupVertices = vertexAttachment->vertices; for (i = 0; i < vertexCount; i++) { - vertices[i] += (setupVertices[i] - vertices[i]) * alpha; + deformArray[i] += (setupVertices[i] - deformArray[i]) * alpha; } } else { alpha = 1 - alpha; for (i = 0; i < vertexCount; i++) { - vertices[i] *= alpha; + deformArray[i] *= alpha; } } case SP_MIX_BLEND_REPLACE: @@ -953,7 +953,7 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, return; } - slot->attachmentVerticesCount = vertexCount; + slot->deformCount = vertexCount; if (time >= frames[framesCount - 1]) { /* Time is after last frame. */ const float* lastVertices = self->frameVertices[framesCount - 1]; if (alpha == 1) { @@ -963,16 +963,16 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, /* Unweighted vertex positions, with alpha. */ float* setupVertices = vertexAttachment->vertices; for (i = 0; i < vertexCount; i++) { - vertices[i] += lastVertices[i] - setupVertices[i]; + deformArray[i] += lastVertices[i] - setupVertices[i]; } } else { /* Weighted deform offsets, with alpha. */ for (i = 0; i < vertexCount; i++) - vertices[i] += lastVertices[i]; + deformArray[i] += lastVertices[i]; } } else { /* Vertex positions or deform offsets, no alpha. */ - memcpy(vertices, lastVertices, vertexCount * sizeof(float)); + memcpy(deformArray, lastVertices, vertexCount * sizeof(float)); } } else { spVertexAttachment* vertexAttachment; @@ -984,30 +984,30 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float* setupVertices = vertexAttachment->vertices; for (i = 0; i < vertexCount; i++) { float setup = setupVertices[i]; - vertices[i] = setup + (lastVertices[i] - setup) * alpha; + deformArray[i] = setup + (lastVertices[i] - setup) * alpha; } } else { /* Weighted deform offsets, with alpha. */ for (i = 0; i < vertexCount; i++) - vertices[i] = lastVertices[i] * alpha; + deformArray[i] = lastVertices[i] * alpha; } break; case SP_MIX_BLEND_FIRST: case SP_MIX_BLEND_REPLACE: /* Vertex positions or deform offsets, with alpha. */ for (i = 0; i < vertexCount; i++) - vertices[i] += (lastVertices[i] - vertices[i]) * alpha; + deformArray[i] += (lastVertices[i] - deformArray[i]) * alpha; case SP_MIX_BLEND_ADD: vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment); if (!vertexAttachment->bones) { /* Unweighted vertex positions, with alpha. */ float* setupVertices = vertexAttachment->vertices; for (i = 0; i < vertexCount; i++) { - vertices[i] += (lastVertices[i] - setupVertices[i]) * alpha; + deformArray[i] += (lastVertices[i] - setupVertices[i]) * alpha; } } else { for (i = 0; i < vertexCount; i++) - vertices[i] += lastVertices[i] * alpha; + deformArray[i] += lastVertices[i] * alpha; } } } @@ -1028,18 +1028,18 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float* setupVertices = vertexAttachment->vertices; for (i = 0; i < vertexCount; i++) { float prev = prevVertices[i]; - vertices[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i]; + deformArray[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i]; } } else { for (i = 0; i < vertexCount; i++) { float prev = prevVertices[i]; - vertices[i] += prev + (nextVertices[i] - prev) * percent; + deformArray[i] += prev + (nextVertices[i] - prev) * percent; } } } else { for (i = 0; i < vertexCount; i++) { float prev = prevVertices[i]; - vertices[i] = prev + (nextVertices[i] - prev) * percent; + deformArray[i] = prev + (nextVertices[i] - prev) * percent; } } } else { @@ -1051,12 +1051,12 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float *setupVertices = vertexAttachment->vertices; for (i = 0; i < vertexCount; i++) { float prev = prevVertices[i], setup = setupVertices[i]; - vertices[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha; + deformArray[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha; } } else { for (i = 0; i < vertexCount; i++) { float prev = prevVertices[i]; - vertices[i] = (prev + (nextVertices[i] - prev) * percent) * alpha; + deformArray[i] = (prev + (nextVertices[i] - prev) * percent) * alpha; } } break; @@ -1064,7 +1064,7 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, case SP_MIX_BLEND_REPLACE: for (i = 0; i < vertexCount; i++) { float prev = prevVertices[i]; - vertices[i] += (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha; + deformArray[i] += (prev + (nextVertices[i] - prev) * percent - deformArray[i]) * alpha; } break; case SP_MIX_BLEND_ADD: @@ -1073,12 +1073,12 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float *setupVertices = vertexAttachment->vertices; for (i = 0; i < vertexCount; i++) { float prev = prevVertices[i]; - vertices[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha; + deformArray[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha; } } else { for (i = 0; i < vertexCount; i++) { float prev = prevVertices[i]; - vertices[i] += (prev + (nextVertices[i] - prev) * percent) * alpha; + deformArray[i] += (prev + (nextVertices[i] - prev) * percent) * alpha; } } } diff --git a/spine-c/spine-c/src/spine/AnimationState.c b/spine-c/spine-c/src/spine/AnimationState.c index ca3abe557..756fb3a26 100644 --- a/spine-c/spine-c/src/spine/AnimationState.c +++ b/spine-c/spine-c/src/spine/AnimationState.c @@ -36,6 +36,7 @@ #define FIRST 1 #define HOLD 2 #define HOLD_MIX 3 +#define NOT_LAST 4 _SP_ARRAY_IMPLEMENT_TYPE(spTrackEntryArray, spTrackEntry*) @@ -62,7 +63,8 @@ float* _spAnimationState_resizeTimelinesRotation(spTrackEntry* entry, int newSiz int* _spAnimationState_resizeTimelinesFirst(spTrackEntry* entry, int newSize); void _spAnimationState_ensureCapacityPropertyIDs(spAnimationState* self, int capacity); int _spAnimationState_addPropertyID(spAnimationState* self, int id); -void _spTrackEntry_setTimelineData(spTrackEntry* self, spAnimationState* state); +void _spTrackEntry_computeHold(spTrackEntry* self, spAnimationState* state); +void _spTrackEntry_computeNotLast(spTrackEntry* self, spAnimationState* state); _spEventQueue* _spEventQueue_create (_spAnimationState* state) { @@ -389,7 +391,7 @@ 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; + timelineBlend = (timelineMode->items[ii] & (NOT_LAST - 1)) == 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 @@ -465,7 +467,7 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* t spMixDirection direction = SP_MIX_DIRECTION_OUT; spTimeline *timeline = timelines[i]; - switch (timelineMode->items[i]) { + switch (timelineMode->items[i] & (NOT_LAST - 1)) { case SUBSEQUENT: if (!attachments && timeline->type == SP_TIMELINE_ATTACHMENT) continue; if (!drawOrder && timeline->type == SP_TIMELINE_DRAWORDER) continue; @@ -493,7 +495,7 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* t else { if (timelineBlend == SP_MIX_BLEND_SETUP) { if (timeline->type == SP_TIMELINE_ATTACHMENT) { - if (attachments) direction = SP_MIX_DIRECTION_IN; + if (attachments || (timelineMode->items[i] & NOT_LAST) == NOT_LAST) direction = SP_MIX_DIRECTION_IN; } else if (timeline->type == SP_TIMELINE_DRAWORDER) { if (drawOrder) direction = SP_MIX_DIRECTION_IN; } @@ -866,10 +868,20 @@ void _spAnimationState_animationsChanged (spAnimationState* self) { while (entry->mixingFrom != 0) entry = entry->mixingFrom; do { - if (entry->mixingTo == 0 || entry->mixBlend != SP_MIX_BLEND_ADD) _spTrackEntry_setTimelineData(entry, self); + if (entry->mixingTo == 0 || entry->mixBlend != SP_MIX_BLEND_ADD) _spTrackEntry_computeHold(entry, self); entry = entry->mixingTo; } while (entry != 0); } + + internal->propertyIDsCount = 0; + i = self->tracksCount - 1; + for (; i >= 0; i--) { + entry = self->tracks[i]; + while (entry != 0) { + _spTrackEntry_computeNotLast(entry, self); + entry = entry->mixingFrom; + } + } } float* _spAnimationState_resizeTimelinesRotation(spTrackEntry* entry, int newSize) { @@ -934,7 +946,7 @@ int /*boolean*/ _spTrackEntry_hasTimeline(spTrackEntry* self, int id) { return 0; } -void _spTrackEntry_setTimelineData(spTrackEntry* entry, spAnimationState* state) { +void _spTrackEntry_computeHold(spTrackEntry* entry, spAnimationState* state) { spTrackEntry* to; spTimeline** timelines; int timelinesCount; @@ -962,12 +974,14 @@ void _spTrackEntry_setTimelineData(spTrackEntry* entry, spAnimationState* state) i = 0; continue_outer: for (; i < timelinesCount; i++) { - int id = spTimeline_getPropertyId(timelines[i]); + spTimeline* timeline = timelines[i]; + int id = spTimeline_getPropertyId(timeline); if (!_spAnimationState_addPropertyID(state, id)) timelineMode[i] = SUBSEQUENT; - else if (to == 0 || !_spTrackEntry_hasTimeline(to, id)) + else if (to == 0 || timeline->type == SP_TIMELINE_ATTACHMENT || timeline->type == SP_TIMELINE_DRAWORDER || + timeline->type == SP_TIMELINE_EVENT || !_spTrackEntry_hasTimeline(to, id)) { timelineMode[i] = FIRST; - else { + } else { for (next = to->mixingTo; next != 0; next = next->mixingTo) { if (_spTrackEntry_hasTimeline(next, id)) continue; if (next->mixDuration > 0) { @@ -982,3 +996,22 @@ void _spTrackEntry_setTimelineData(spTrackEntry* entry, spAnimationState* state) } } } + +void _spTrackEntry_computeNotLast(spTrackEntry* entry, spAnimationState* state) { + spTimeline** timelines ; + int timelinesCount; + int* timelineMode; + int i, n; + + timelines = entry->animation->timelines; + timelinesCount = entry->animation->timelinesCount; + timelineMode = entry->timelineMode->items; + + i = 0; + for (; i < timelinesCount; i++) { + if (timelines[i]->type == SP_TIMELINE_ATTACHMENT) { + spAttachmentTimeline* timeline = SUB_CAST(spAttachmentTimeline, timelines[i]); + if (!_spAnimationState_addPropertyID(state, timeline->slotIndex)) timelineMode[i] |= NOT_LAST; + } + } +} diff --git a/spine-c/spine-c/src/spine/Slot.c b/spine-c/spine-c/src/spine/Slot.c index eded60cff..abefc1dfb 100644 --- a/spine-c/spine-c/src/spine/Slot.c +++ b/spine-c/spine-c/src/spine/Slot.c @@ -47,7 +47,7 @@ spSlot* spSlot_create (spSlotData* data, spBone* bone) { } void spSlot_dispose (spSlot* self) { - FREE(self->attachmentVertices); + FREE(self->deform); FREE(self->darkColor); FREE(self); } @@ -56,7 +56,7 @@ void spSlot_setAttachment (spSlot* self, spAttachment* attachment) { if (attachment == self->attachment) return; CONST_CAST(spAttachment*, self->attachment) = attachment; SUB_CAST(_spSlot, self)->attachmentTime = self->bone->skeleton->time; - self->attachmentVerticesCount = 0; + self->deformCount = 0; } void spSlot_setAttachmentTime (spSlot* self, float time) { diff --git a/spine-c/spine-c/src/spine/VertexAttachment.c b/spine-c/spine-c/src/spine/VertexAttachment.c index 14087815e..e2466313f 100644 --- a/spine-c/spine-c/src/spine/VertexAttachment.c +++ b/spine-c/spine-c/src/spine/VertexAttachment.c @@ -47,21 +47,21 @@ void _spVertexAttachment_deinit (spVertexAttachment* attachment) { void spVertexAttachment_computeWorldVertices (spVertexAttachment* self, spSlot* slot, int start, int count, float* worldVertices, int offset, int stride) { spSkeleton* skeleton; int deformLength; - float* deform; + float* deformArray; float* vertices; int* bones; count = offset + (count >> 1) * stride; skeleton = slot->bone->skeleton; - deformLength = slot->attachmentVerticesCount; - deform = slot->attachmentVertices; + deformLength = slot->deformCount; + deformArray = slot->deform; vertices = self->vertices; bones = self->bones; if (!bones) { spBone* bone; int v, w; float x, y; - if (deformLength > 0) vertices = deform; + if (deformLength > 0) vertices = deformArray; bone = slot->bone; x = bone->worldX; y = bone->worldY; @@ -102,7 +102,7 @@ void spVertexAttachment_computeWorldVertices (spVertexAttachment* self, spSlot* n += v; for (; v < n; v++, b += 3, f += 2) { spBone* bone = skeletonBones[bones[v]]; - float vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2]; + float vx = vertices[b] + deformArray[f], vy = vertices[b + 1] + deformArray[f + 1], weight = vertices[b + 2]; wx += (vx * bone->a + vy * bone->b + bone->worldX) * weight; wy += (vx * bone->c + vy * bone->d + bone->worldY) * weight; }