From 9319029763248ef6be5beb76778190fcbe402129 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Thu, 10 Feb 2022 16:00:53 +0100 Subject: [PATCH] [c] Sequence support in SkeletonBinary and SkeletonJson. --- spine-c/spine-c/include/spine/Animation.h | 19 +- spine-c/spine-c/src/spine/Animation.c | 116 +++++++++++ spine-c/spine-c/src/spine/Debug.c | 4 + spine-c/spine-c/src/spine/MeshAttachment.c | 1 + spine-c/spine-c/src/spine/RegionAttachment.c | 1 + spine-c/spine-c/src/spine/Sequence.c | 3 - spine-c/spine-c/src/spine/SkeletonBinary.c | 140 ++++++++------ spine-c/spine-c/src/spine/SkeletonJson.c | 192 ++++++++++++------- spine-sfml/c/example/main.cpp | 1 - spine-sfml/c/src/spine/spine-sfml.cpp | 3 +- 10 files changed, 340 insertions(+), 140 deletions(-) diff --git a/spine-c/spine-c/include/spine/Animation.h b/spine-c/spine-c/include/spine/Animation.h index 2a768c388..26aa66b8f 100644 --- a/spine-c/spine-c/include/spine/Animation.h +++ b/spine-c/spine-c/include/spine/Animation.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -99,6 +100,7 @@ typedef enum { SP_TIMELINE_SHEAR, SP_TIMELINE_TRANSLATE, SP_TIMELINE_DEFORM, + SP_TIMELINE_SEQUENCE, SP_TIMELINE_IKCONSTRAINT, SP_TIMELINE_PATHCONSTRAINTMIX, SP_TIMELINE_RGB2, @@ -131,7 +133,8 @@ typedef enum { SP_PROPERTY_TRANSFORMCONSTRAINT = 1 << 15, SP_PROPERTY_PATHCONSTRAINT_POSITION = 1 << 16, SP_PROPERTY_PATHCONSTRAINT_SPACING = 1 << 17, - SP_PROPERTY_PATHCONSTRAINT_MIX = 1 << 18 + SP_PROPERTY_PATHCONSTRAINT_MIX = 1 << 18, + SP_PROPERTY_SEQUENCE = 1 << 19 } spProperty; #define SP_MAX_PROPERTY_IDS 3 @@ -399,6 +402,20 @@ SP_API void spDeformTimeline_setFrame(spDeformTimeline *self, int frameIndex, fl /**/ +typedef struct spSequenceTimeline { + spTimeline super; + int slotIndex; + spAttachment *attachment; +} spSequenceTimeline; + +SP_API spSequenceTimeline *spSequenceTimeline_create(int framesCount, int slotIndex, spAttachment *attachment); + +SP_API void spSequenceTimeline_setFrame(spSequenceTimeline *self, int frameIndex, float time, int mode, int index, float delay); + +/**/ + +/**/ + typedef struct spEventTimeline { spTimeline super; spEvent **const events; diff --git a/spine-c/spine-c/src/spine/Animation.c b/spine-c/spine-c/src/spine/Animation.c index b2700e014..d5e8d3f4f 100644 --- a/spine-c/spine-c/src/spine/Animation.c +++ b/spine-c/spine-c/src/spine/Animation.c @@ -1999,6 +1999,122 @@ void spDeformTimeline_setFrame(spDeformTimeline *self, int frame, float time, fl /**/ +static const int SEQUENCE_ENTRIES = 3, MODE = 1, DELAY = 2; + +void _spSequenceTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time, spEvent **firedEvents, + int *eventsCount, float alpha, spMixBlend blend, spMixDirection direction) { + spSequenceTimeline *self = (spSequenceTimeline *) timeline; + spSlot *slot = skeleton->slots[self->slotIndex]; + spAttachment *slotAttachment; + float *frames; + int i, modeAndIndex, count, index, mode; + float before, delay; + spSequence *sequence = NULL; + + if (!slot->bone->active) return; + + slotAttachment = slot->attachment; + if (slotAttachment != self->attachment) { + switch (slot->attachment->type) { + case SP_ATTACHMENT_BOUNDING_BOX: + case SP_ATTACHMENT_CLIPPING: + case SP_ATTACHMENT_MESH: + case SP_ATTACHMENT_PATH: { + spVertexAttachment *vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment); + if (vertexAttachment->timelineAttachment != self->attachment) return; + break; + } + default: + return; + } + } + + frames = self->super.frames->items; + if (time < frames[0]) { /* Time is before first frame. */ + if (blend == SP_MIX_BLEND_SETUP || blend == SP_MIX_BLEND_FIRST) slot->sequenceIndex = -1; + return; + } + + i = search2(self->super.frames, time, SEQUENCE_ENTRIES); + before = frames[i]; + modeAndIndex = (int) frames[i + MODE]; + delay = frames[i + DELAY]; + + if (self->attachment->type == SP_ATTACHMENT_REGION) sequence = ((spRegionAttachment *) self->attachment)->sequence; + if (self->attachment->type == SP_ATTACHMENT_MESH) sequence = ((spMeshAttachment *) self->attachment)->sequence; + index = modeAndIndex >> 4; + count = sequence->regions->size; + mode = modeAndIndex & 0xf; + if (mode != SP_SEQUENCE_MODE_HOLD) { + index += (int) (((time - before) / delay + 0.00001)); + switch (mode) { + case SP_SEQUENCE_MODE_ONCE: + index = MIN(count - 1, index); + break; + case SP_SEQUENCE_MODE_LOOP: + index %= count; + break; + case SP_SEQUENCE_MODE_PINGPONG: { + int n = (count << 1) - 2; + index %= n; + if (index >= count) index = n - index; + break; + } + case SP_SEQUENCE_MODE_ONCEREVERSE: + index = MAX(count - 1 - index, 0); + break; + case SP_SEQUENCE_MODE_LOOPREVERSE: + index = count - 1 - (index % count); + break; + case SP_SEQUENCE_MODE_PINGPONGREVERSE: { + int n = (count << 1) - 2; + index = (index + count - 1) % n; + if (index >= count) index = n - index; + } + } + } + slot->sequenceIndex = index; + + UNUSED(lastTime); + UNUSED(firedEvents); + UNUSED(eventsCount); + UNUSED(alpha); + UNUSED(direction); +} + +void _spSequenceTimeline_dispose(spTimeline *timeline) { + spEventTimeline *self = SUB_CAST(spEventTimeline, timeline); + int i; + + for (i = 0; i < self->super.frames->size; ++i) + spEvent_dispose(self->events[i]); + FREE(self->events); +} + +spSequenceTimeline *spSequenceTimeline_create(int framesCount, int slotIndex, spAttachment *attachment) { + int sequenceId = 0; + spSequenceTimeline *self = NEW(spSequenceTimeline); + spPropertyId ids[1]; + if (attachment->type == SP_ATTACHMENT_REGION) sequenceId = ((spRegionAttachment *) attachment)->sequence->id; + if (attachment->type == SP_ATTACHMENT_MESH) sequenceId = ((spMeshAttachment *) attachment)->sequence->id; + ids[0] = (spPropertyId) SP_PROPERTY_SEQUENCE << 32 | ((slotIndex << 16 | sequenceId) & 0xffffffff); + _spTimeline_init(SUPER(self), framesCount, SEQUENCE_ENTRIES, ids, 1, SP_TIMELINE_SEQUENCE, _spSequenceTimeline_dispose, + _spSequenceTimeline_apply, 0); + self->slotIndex = slotIndex; + self->attachment = attachment; + return self; +} + +void spSequenceTimeline_setFrame(spSequenceTimeline *self, int frame, float time, int mode, int index, float delay) { + float *frames = self->super.frames->items; + frame *= SEQUENCE_ENTRIES; + frames[frame] = time; + frames[frame + MODE] = mode | (index << 4); + frames[frame + DELAY] = delay; +} + +/**/ + /** Fires events for frames > lastTime and <= time. */ void _spEventTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time, spEvent **firedEvents, int *eventsCount, float alpha, spMixBlend blend, spMixDirection direction) { diff --git a/spine-c/spine-c/src/spine/Debug.c b/spine-c/spine-c/src/spine/Debug.c index 1e66ff700..8a854a54d 100644 --- a/spine-c/spine-c/src/spine/Debug.c +++ b/spine-c/spine-c/src/spine/Debug.c @@ -205,6 +205,10 @@ void spDebug_printTimeline(spTimeline *timeline) { _spDebug_printTimelineBase(&t->super); break; } + case SP_TIMELINE_SEQUENCE: { + spSequenceTimeline *t = (spSequenceTimeline *) timeline; + _spDebug_printTimelineBase(&t->super); + } } } diff --git a/spine-c/spine-c/src/spine/MeshAttachment.c b/spine-c/spine-c/src/spine/MeshAttachment.c index 718909e04..ab5f448f5 100644 --- a/spine-c/spine-c/src/spine/MeshAttachment.c +++ b/spine-c/spine-c/src/spine/MeshAttachment.c @@ -33,6 +33,7 @@ void _spMeshAttachment_dispose(spAttachment *attachment) { spMeshAttachment *self = SUB_CAST(spMeshAttachment, attachment); + if (self->sequence) spSequence_dispose(self->sequence); FREE(self->path); FREE(self->uvs); if (!self->parentMesh) { diff --git a/spine-c/spine-c/src/spine/RegionAttachment.c b/spine-c/spine-c/src/spine/RegionAttachment.c index ba5f89536..f888d6100 100644 --- a/spine-c/spine-c/src/spine/RegionAttachment.c +++ b/spine-c/spine-c/src/spine/RegionAttachment.c @@ -43,6 +43,7 @@ typedef enum { void _spRegionAttachment_dispose(spAttachment *attachment) { spRegionAttachment *self = SUB_CAST(spRegionAttachment, attachment); + if (self->sequence) spSequence_dispose(self->sequence); _spAttachment_deinit(attachment); FREE(self->path); FREE(self); diff --git a/spine-c/spine-c/src/spine/Sequence.c b/spine-c/spine-c/src/spine/Sequence.c index 6467d2dda..f9858dbf5 100644 --- a/spine-c/spine-c/src/spine/Sequence.c +++ b/spine-c/spine-c/src/spine/Sequence.c @@ -50,9 +50,6 @@ void spSequence_dispose(spSequence *self) { spSequence *spSequence_copy(spSequence *self) { int i = 0; spSequence *copy = spSequence_create(self->regions->size); - copy->start = self->start; - copy->digits = self->digits; - copy->setupIndex = self->setupIndex; for (; i < self->regions->size; i++) copy->regions->items[i] = self->regions->items[i]; copy->start = self->start; diff --git a/spine-c/spine-c/src/spine/SkeletonBinary.c b/spine-c/spine-c/src/spine/SkeletonBinary.c index 5d012d6d8..959e90632 100644 --- a/spine-c/spine-c/src/spine/SkeletonBinary.c +++ b/spine-c/spine-c/src/spine/SkeletonBinary.c @@ -192,8 +192,8 @@ static void readColor(_dataInput *input, float *r, float *g, float *b, float *a) #define SLOT_RGB2 4 #define SLOT_ALPHA 5 -#define ATTACHMENT_DEFORM = 0 -#define ATTACHMENT_SEQUENCE = 1 +#define ATTACHMENT_DEFORM 0 +#define ATTACHMENT_SEQUENCE 1 #define PATH_POSITION 0 #define PATH_SPACING 1 @@ -705,8 +705,7 @@ static spAnimation *_spSkeletonBinary_readAnimation(spSkeletonBinary *self, cons int bezierCount = readVarint(input, 1); switch (type) { case PATH_POSITION: { - spTimelineArray_add(timelines, readTimeline(input, SUPER(spPathConstraintPositionTimeline_create( - frameCount, bezierCount, index)), + spTimelineArray_add(timelines, readTimeline(input, SUPER(spPathConstraintPositionTimeline_create(frameCount, bezierCount, index)), data->positionMode == SP_POSITION_MODE_FIXED ? scale : 1)); break; @@ -717,9 +716,9 @@ static spAnimation *_spSkeletonBinary_readAnimation(spSkeletonBinary *self, cons bezierCount, index)), data->spacingMode == SP_SPACING_MODE_LENGTH || - data->spacingMode == SP_SPACING_MODE_FIXED - ? scale - : 1)); + data->spacingMode == SP_SPACING_MODE_FIXED + ? scale + : 1)); break; } case PATH_MIX: { @@ -762,19 +761,17 @@ static spAnimation *_spSkeletonBinary_readAnimation(spSkeletonBinary *self, cons } } - /* Deform timelines. */ + /* Attachment timelines. */ for (i = 0, n = readVarint(input, 1); i < n; ++i) { spSkin *skin = skeletonData->skins[readVarint(input, 1)]; for (ii = 0, nn = readVarint(input, 1); ii < nn; ++ii) { int slotIndex = readVarint(input, 1); for (iii = 0, nnn = readVarint(input, 1); iii < nnn; ++iii) { - float *tempDeform; - spDeformTimeline *timeline; - int weighted, deformLength; - const char *attachmentName = readStringRef(input, skeletonData); int frameCount, frameLast, bezierCount; float time, time2; + unsigned int timelineType; + const char *attachmentName = readStringRef(input, skeletonData); spVertexAttachment *attachment = SUB_CAST(spVertexAttachment, spSkin_getAttachment(skin, slotIndex, attachmentName)); if (!attachment) { @@ -785,59 +782,83 @@ static spAnimation *_spSkeletonBinary_readAnimation(spSkeletonBinary *self, cons return NULL; } - weighted = attachment->bones != 0; - deformLength = weighted ? attachment->verticesCount / 3 * 2 : attachment->verticesCount; - tempDeform = MALLOC(float, deformLength); - + timelineType = readByte(input); frameCount = readVarint(input, 1); frameLast = frameCount - 1; - bezierCount = readVarint(input, 1); - timeline = spDeformTimeline_create(frameCount, deformLength, bezierCount, slotIndex, attachment); - time = readFloat(input); - for (frame = 0, bezier = 0;; ++frame) { - float *deform; - int end = readVarint(input, 1); - if (!end) { - if (weighted) { - deform = tempDeform; - memset(deform, 0, sizeof(float) * deformLength); - } else - deform = attachment->vertices; - } else { - int v, start = readVarint(input, 1); - deform = tempDeform; - memset(deform, 0, sizeof(float) * start); - end += start; - if (self->scale == 1) { - for (v = start; v < end; ++v) - deform[v] = readFloat(input); - } else { - for (v = start; v < end; ++v) - deform[v] = readFloat(input) * self->scale; + switch (timelineType) { + case ATTACHMENT_DEFORM: { + float *tempDeform; + int weighted, deformLength; + spDeformTimeline *timeline; + weighted = attachment->bones != 0; + deformLength = weighted ? attachment->verticesCount / 3 * 2 : attachment->verticesCount; + tempDeform = MALLOC(float, deformLength); + + bezierCount = readVarint(input, 1); + timeline = spDeformTimeline_create(frameCount, deformLength, bezierCount, slotIndex, + attachment); + + time = readFloat(input); + for (frame = 0, bezier = 0;; ++frame) { + float *deform; + int end = readVarint(input, 1); + if (!end) { + if (weighted) { + deform = tempDeform; + memset(deform, 0, sizeof(float) * deformLength); + } else + deform = attachment->vertices; + } else { + int v, start = readVarint(input, 1); + deform = tempDeform; + memset(deform, 0, sizeof(float) * start); + end += start; + if (self->scale == 1) { + for (v = start; v < end; ++v) + deform[v] = readFloat(input); + } else { + for (v = start; v < end; ++v) + deform[v] = readFloat(input) * self->scale; + } + memset(deform + v, 0, sizeof(float) * (deformLength - v)); + if (!weighted) { + float *vertices = attachment->vertices; + for (v = 0; v < deformLength; ++v) + deform[v] += vertices[v]; + } + } + spDeformTimeline_setFrame(timeline, frame, time, deform); + if (frame == frameLast) break; + time2 = readFloat(input); + switch (readSByte(input)) { + case CURVE_STEPPED: + spCurveTimeline_setStepped(SUPER(timeline), frame); + break; + case CURVE_BEZIER: + setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 0, time, time2, 0, 1, 1); + } + time = time2; } - memset(deform + v, 0, sizeof(float) * (deformLength - v)); - if (!weighted) { - float *vertices = attachment->vertices; - for (v = 0; v < deformLength; ++v) - deform[v] += vertices[v]; + FREE(tempDeform); + + spTimelineArray_add(timelines, (spTimeline *) timeline); + break; + } + case ATTACHMENT_SEQUENCE: { + int modeAndIndex; + float delay; + spSequenceTimeline *timeline = spSequenceTimeline_create(frameCount, slotIndex, (spAttachment *) attachment); + for (frame = 0; frame < frameCount; frame++) { + time = readFloat(input); + modeAndIndex = readInt(input); + delay = readFloat(input); + spSequenceTimeline_setFrame(timeline, frame, time, modeAndIndex & 0xf, modeAndIndex >> 4, delay); } + spTimelineArray_add(timelines, (spTimeline *) timeline); + break; } - spDeformTimeline_setFrame(timeline, frame, time, deform); - if (frame == frameLast) break; - time2 = readFloat(input); - switch (readSByte(input)) { - case CURVE_STEPPED: - spCurveTimeline_setStepped(SUPER(timeline), frame); - break; - case CURVE_BEZIER: - setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 0, time, time2, 0, 1, 1); - } - time = time2; } - FREE(tempDeform); - - spTimelineArray_add(timelines, (spTimeline *) timeline); } } } @@ -1484,8 +1505,7 @@ spSkeletonData *spSkeletonBinary_readSkeletonData(spSkeletonBinary *self, const /* Linked meshes. */ for (i = 0; i < internal->linkedMeshCount; ++i) { _spLinkedMesh *linkedMesh = internal->linkedMeshes + i; - spSkin *skin = !linkedMesh->skin ? skeletonData->defaultSkin : spSkeletonData_findSkin(skeletonData, - linkedMesh->skin); + spSkin *skin = !linkedMesh->skin ? skeletonData->defaultSkin : spSkeletonData_findSkin(skeletonData, linkedMesh->skin); spAttachment *parent; if (!skin) { FREE(input); diff --git a/spine-c/spine-c/src/spine/SkeletonJson.c b/spine-c/spine-c/src/spine/SkeletonJson.c index 14fd1a1b1..965aff619 100644 --- a/spine-c/spine-c/src/spine/SkeletonJson.c +++ b/spine-c/spine-c/src/spine/SkeletonJson.c @@ -188,6 +188,16 @@ readTimeline2(Json *keyMap, spCurveTimeline2 *timeline, const char *name1, const return SUPER(timeline); } +static spSequence *readSequence(Json *item) { + spSequence *sequence; + if (item == NULL) return NULL; + sequence = spSequence_create(Json_getInt(item, "count", 0)); + sequence->start = Json_getInt(item, "start", 1); + sequence->digits = Json_getInt(item, "digits", 0); + sequence->setupIndex = Json_getInt(item, "setupIndex", 0); + return sequence; +} + static void _spSkeletonJson_addLinkedMesh(spSkeletonJson *self, spMeshAttachment *mesh, const char *skin, int slotIndex, const char *parent, int inheritDeform) { _spLinkedMesh *linkedMesh; @@ -268,10 +278,11 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro Json *ik = Json_getItem(root, "ik"); Json *transform = Json_getItem(root, "transform"); Json *paths = Json_getItem(root, "path"); - Json *deformJson = Json_getItem(root, "deform"); + Json *attachmentsJson = Json_getItem(root, "attachments"); Json *drawOrderJson = Json_getItem(root, "drawOrder"); Json *events = Json_getItem(root, "events"); - Json *boneMap, *slotMap, *constraintMap, *keyMap, *nextMap, *curve, *timelineMap; + Json *boneMap, *slotMap, *keyMap, *nextMap, *curve, *timelineMap; + Json *attachmentsMap, *constraintMap; int frame, bezier, i, n; spColor color, color2, newColor, newColor2; @@ -286,7 +297,7 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro spAttachmentTimeline *timeline = spAttachmentTimeline_create(frames, slotIndex); for (keyMap = timelineMap->child, frame = 0; keyMap; keyMap = keyMap->next, ++frame) { spAttachmentTimeline_setFrame(timeline, frame, Json_getFloat(keyMap, "time", 0), - Json_getItem(keyMap, "name")->valueString); + Json_getItem(keyMap, "name") ? Json_getItem(keyMap, "name")->valueString : NULL); } spTimelineArray_add(timelines, SUPER(timeline)); @@ -691,82 +702,113 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro } } - /* Deform timelines. */ - for (constraintMap = deformJson ? deformJson->child : 0; constraintMap; constraintMap = constraintMap->next) { - spSkin *skin = spSkeletonData_findSkin(skeletonData, constraintMap->name); - for (slotMap = constraintMap->child; slotMap; slotMap = slotMap->next) { + /* Attachment timelines. */ + for (attachmentsMap = attachmentsJson ? attachmentsJson->child : 0; attachmentsMap; attachmentsMap = attachmentsMap->next) { + spSkin *skin = spSkeletonData_findSkin(skeletonData, attachmentsMap->name); + for (slotMap = attachmentsMap->child; slotMap; slotMap = slotMap->next) { + Json *attachmentMap; int slotIndex = findSlotIndex(self, skeletonData, slotMap->name, timelines); if (slotIndex == -1) return NULL; - for (timelineMap = slotMap->child; timelineMap; timelineMap = timelineMap->next) { - float *tempDeform; - spVertexAttachment *attachment; - int weighted, deformLength; - spDeformTimeline *timeline; - float time; - keyMap = timelineMap->child; - if (keyMap == NULL) continue; - - attachment = SUB_CAST(spVertexAttachment, spSkin_getAttachment(skin, slotIndex, timelineMap->name)); - if (!attachment) { + for (attachmentMap = slotMap->child; attachmentMap; attachmentMap = attachmentMap->next) { + spAttachment *baseAttachment = spSkin_getAttachment(skin, slotIndex, attachmentMap->name); + if (!baseAttachment) { cleanUpTimelines(timelines); - _spSkeletonJson_setError(self, 0, "Attachment not found: ", timelineMap->name); + _spSkeletonJson_setError(self, 0, "Attachment not found: ", attachmentMap->name); return NULL; } - weighted = attachment->bones != 0; - deformLength = weighted ? attachment->verticesCount / 3 * 2 : attachment->verticesCount; - tempDeform = MALLOC(float, deformLength); - timeline = spDeformTimeline_create(timelineMap->size, deformLength, timelineMap->size, slotIndex, - attachment); - time = Json_getFloat(keyMap, "time", 0); - for (frame = 0, bezier = 0;; ++frame) { - Json *vertices = Json_getItem(keyMap, "vertices"); - float *deform; - float time2; + for (timelineMap = attachmentMap->child; timelineMap; timelineMap = timelineMap->next) { + int frames; + const char *timelineName; + keyMap = timelineMap->child; + if (keyMap == NULL) continue; + frames = timelineMap->size; + timelineName = timelineMap->name; + if (!strcmp("deform", timelineName)) { + float *tempDeform; + spVertexAttachment *vertexAttachment; + int weighted, deformLength; + spDeformTimeline *timeline; + float time; - if (!vertices) { - if (weighted) { - deform = tempDeform; - memset(deform, 0, sizeof(float) * deformLength); - } else - deform = attachment->vertices; - } else { - int v, start = Json_getInt(keyMap, "offset", 0); - Json *vertex; - deform = tempDeform; - memset(deform, 0, sizeof(float) * start); - if (self->scale == 1) { - for (vertex = vertices->child, v = start; vertex; vertex = vertex->next, ++v) - deform[v] = vertex->valueFloat; - } else { - for (vertex = vertices->child, v = start; vertex; vertex = vertex->next, ++v) - deform[v] = vertex->valueFloat * self->scale; + vertexAttachment = SUB_CAST(spVertexAttachment, baseAttachment); + weighted = vertexAttachment->bones != 0; + deformLength = weighted ? vertexAttachment->verticesCount / 3 * 2 : vertexAttachment->verticesCount; + tempDeform = MALLOC(float, deformLength); + + timeline = spDeformTimeline_create(timelineMap->size, deformLength, timelineMap->size, + slotIndex, + vertexAttachment); + + time = Json_getFloat(keyMap, "time", 0); + for (frame = 0, bezier = 0;; ++frame) { + Json *vertices = Json_getItem(keyMap, "vertices"); + float *deform; + float time2; + + if (!vertices) { + if (weighted) { + deform = tempDeform; + memset(deform, 0, sizeof(float) * deformLength); + } else + deform = vertexAttachment->vertices; + } else { + int v, start = Json_getInt(keyMap, "offset", 0); + Json *vertex; + deform = tempDeform; + memset(deform, 0, sizeof(float) * start); + if (self->scale == 1) { + for (vertex = vertices->child, v = start; vertex; vertex = vertex->next, ++v) + deform[v] = vertex->valueFloat; + } else { + for (vertex = vertices->child, v = start; vertex; vertex = vertex->next, ++v) + deform[v] = vertex->valueFloat * self->scale; + } + memset(deform + v, 0, sizeof(float) * (deformLength - v)); + if (!weighted) { + float *verticesValues = vertexAttachment->vertices; + for (v = 0; v < deformLength; ++v) + deform[v] += verticesValues[v]; + } + } + spDeformTimeline_setFrame(timeline, frame, time, deform); + nextMap = keyMap->next; + if (!nextMap) { + /* timeline.shrink(); // BOZO */ + break; + } + time2 = Json_getFloat(nextMap, "time", 0); + curve = Json_getItem(keyMap, "curve"); + if (curve) { + bezier = readCurve(curve, SUPER(timeline), bezier, frame, 0, time, time2, 0, 1, 1); + } + time = time2; + keyMap = nextMap; } - memset(deform + v, 0, sizeof(float) * (deformLength - v)); - if (!weighted) { - float *verticesValues = attachment->vertices; - for (v = 0; v < deformLength; ++v) - deform[v] += verticesValues[v]; + FREE(tempDeform); + + spTimelineArray_add(timelines, SUPER(SUPER(timeline))); + } else if (!strcmp(timelineName, "sequence")) { + spSequenceTimeline *timeline = spSequenceTimeline_create(frames, slotIndex, baseAttachment); + float lastDelay = 0; + for (frame = 0; keyMap != NULL; keyMap = keyMap->next, frame++) { + float delay = Json_getFloat(keyMap, "delay", lastDelay); + float time = Json_getFloat(keyMap, "time", 0); + const char *modeString = Json_getString(keyMap, "mode", "hold"); + int index = Json_getInt(keyMap, "index", 0); + int mode = SP_SEQUENCE_MODE_HOLD; + if (!strcmp(modeString, "once")) mode = SP_SEQUENCE_MODE_ONCE; + if (!strcmp(modeString, "loop")) mode = SP_SEQUENCE_MODE_LOOP; + if (!strcmp(modeString, "pingpong")) mode = SP_SEQUENCE_MODE_PINGPONG; + if (!strcmp(modeString, "onceReverse")) mode = SP_SEQUENCE_MODE_ONCEREVERSE; + if (!strcmp(modeString, "loopReverse")) mode = SP_SEQUENCE_MODE_LOOPREVERSE; + if (!strcmp(modeString, "pingpongReverse")) mode = SP_SEQUENCE_MODE_PINGPONGREVERSE; + spSequenceTimeline_setFrame(timeline, frame, time, mode, index, delay); } + spTimelineArray_add(timelines, SUPER(timeline)); } - spDeformTimeline_setFrame(timeline, frame, time, deform); - nextMap = keyMap->next; - if (!nextMap) { - /* timeline.shrink(); // BOZO */ - break; - } - time2 = Json_getFloat(nextMap, "time", 0); - curve = Json_getItem(keyMap, "curve"); - if (curve) { - bezier = readCurve(curve, SUPER(timeline), bezier, frame, 0, time, time2, 0, 1, 1); - } - time = time2; - keyMap = nextMap; } - FREE(tempDeform); - - spTimelineArray_add(timelines, SUPER(SUPER(timeline))); } } } @@ -1297,6 +1339,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char const char *path = Json_getString(attachmentMap, "path", attachmentName); const char *color; Json *entry; + spSequence *sequence; const char *typeString = Json_getString(attachmentMap, "type", "region"); spAttachmentType type; @@ -1319,8 +1362,9 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char return NULL; } + sequence = readSequence(attachmentMap); attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, attachmentName, - path); + path, sequence); if (!attachment) { if (self->attachmentLoader->error1) { spSkeletonData_dispose(skeletonData); @@ -1342,6 +1386,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char region->rotation = Json_getFloat(attachmentMap, "rotation", 0); region->width = Json_getFloat(attachmentMap, "width", 32) * self->scale; region->height = Json_getFloat(attachmentMap, "height", 32) * self->scale; + region->sequence = sequence; color = Json_getString(attachmentMap, "color", 0); if (color) { @@ -1352,7 +1397,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char toColor(color, 3)); } - spRegionAttachment_updateRegion(region); + if (region->region != NULL) spRegionAttachment_updateRegion(region); spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment); break; @@ -1374,6 +1419,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char mesh->width = Json_getFloat(attachmentMap, "width", 32) * self->scale; mesh->height = Json_getFloat(attachmentMap, "height", 32) * self->scale; + mesh->sequence = sequence; entry = Json_getItem(attachmentMap, "parent"); if (!entry) { @@ -1392,7 +1438,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char _readVertices(self, attachmentMap, SUPER(mesh), verticesLength); - spMeshAttachment_updateRegion(mesh); + if (mesh->region != NULL) spMeshAttachment_updateRegion(mesh); mesh->hullLength = Json_getInt(attachmentMap, "hull", 0); @@ -1406,10 +1452,10 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment); } else { - int inheritDeform = Json_getInt(attachmentMap, "deform", 1); + int inheritTimelines = Json_getInt(attachmentMap, "timelines", 1); _spSkeletonJson_addLinkedMesh(self, SUB_CAST(spMeshAttachment, attachment), Json_getString(attachmentMap, "skin", 0), slot->index, - entry->valueString, inheritDeform); + entry->valueString, inheritTimelines); } break; } @@ -1517,7 +1563,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char linkedMesh->mesh->super.timelineAttachment = linkedMesh->inheritTimeline ? parent : SUPER(SUPER(linkedMesh->mesh)); spMeshAttachment_setParentMesh(linkedMesh->mesh, SUB_CAST(spMeshAttachment, parent)); - spMeshAttachment_updateRegion(linkedMesh->mesh); + if (linkedMesh->mesh->region != NULL) spMeshAttachment_updateRegion(linkedMesh->mesh); spAttachmentLoader_configureAttachment(self->attachmentLoader, SUPER(SUPER(linkedMesh->mesh))); } diff --git a/spine-sfml/c/example/main.cpp b/spine-sfml/c/example/main.cpp index 6831d0a32..922d14924 100644 --- a/spine-sfml/c/example/main.cpp +++ b/spine-sfml/c/example/main.cpp @@ -513,7 +513,6 @@ void test(spSkeletonData *skeletonData, spAtlas *atlas) { float d = 3; for (int i = 0; i < 1; i++) { - spSkeleton_update(skeleton, d); spAnimationState_update(animState, d); spAnimationState_apply(animState, skeleton); spSkeleton_updateWorldTransform(skeleton); diff --git a/spine-sfml/c/src/spine/spine-sfml.cpp b/spine-sfml/c/src/spine/spine-sfml.cpp index 875584030..cbaeeb82a 100644 --- a/spine-sfml/c/src/spine/spine-sfml.cpp +++ b/spine-sfml/c/src/spine/spine-sfml.cpp @@ -151,7 +151,6 @@ namespace spine { } void SkeletonDrawable::update(float deltaTime) { - spSkeleton_update(skeleton, deltaTime); spAnimationState_update(state, deltaTime * timeScale); spAnimationState_apply(state, skeleton); spSkeleton_updateWorldTransform(skeleton); @@ -197,7 +196,7 @@ namespace spine { continue; } - spRegionAttachment_computeWorldVertices(regionAttachment, slot->bone, vertices, 0, 2); + spRegionAttachment_computeWorldVertices(regionAttachment, slot, vertices, 0, 2); verticesCount = 4; uvs = regionAttachment->uvs; indices = quadIndices;