From 0d237b15293aaf0b28cd666f6a8ec9c203e90d64 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Fri, 4 Feb 2022 13:21:44 +0100 Subject: [PATCH] [c] Port sequence timeline loading to SkeletonBinary Deform timeline parsing not working. --- spine-c/spine-c/include/spine/Sequence.h | 2 +- spine-c/spine-c/src/spine/Sequence.c | 10 +- spine-c/spine-c/src/spine/SkeletonBinary.c | 234 ++++++++++++------ spine-c/spine-c/src/spine/SkeletonJson.c | 8 +- .../spine-cpp/src/spine/SkeletonBinary.cpp | 2 +- 5 files changed, 169 insertions(+), 87 deletions(-) diff --git a/spine-c/spine-c/include/spine/Sequence.h b/spine-c/spine-c/include/spine/Sequence.h index 2692ddc4f..8db01987b 100644 --- a/spine-c/spine-c/include/spine/Sequence.h +++ b/spine-c/spine-c/include/spine/Sequence.h @@ -50,7 +50,7 @@ typedef struct spSequence { spTextureRegionArray *regions; } spSequence; -SP_API spSequence *spSequence_create(int start, int digits, int setupIndex, int numRegions); +SP_API spSequence *spSequence_create(int numRegions); SP_API void spSequence_dispose(spSequence *self); diff --git a/spine-c/spine-c/src/spine/Sequence.c b/spine-c/spine-c/src/spine/Sequence.c index a611135ba..6467d2dda 100644 --- a/spine-c/spine-c/src/spine/Sequence.c +++ b/spine-c/spine-c/src/spine/Sequence.c @@ -34,12 +34,9 @@ _SP_ARRAY_IMPLEMENT_TYPE(spTextureRegionArray, spTextureRegion *) static int nextSequenceId = 0; -spSequence *spSequence_create(int start, int digits, int setupIndex, int numRegions) { +spSequence *spSequence_create(int numRegions) { spSequence *self = NEW(spSequence); self->id = nextSequenceId++; - self->start = start; - self->digits = digits; - self->setupIndex = setupIndex; self->regions = spTextureRegionArray_create(numRegions); spTextureRegionArray_setSize(self->regions, numRegions); return self; @@ -52,7 +49,10 @@ void spSequence_dispose(spSequence *self) { spSequence *spSequence_copy(spSequence *self) { int i = 0; - spSequence *copy = spSequence_create(self->start, self->digits, self->setupIndex, self->regions->size); + 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 b7d2b7b64..5d012d6d8 100644 --- a/spine-c/spine-c/src/spine/SkeletonBinary.c +++ b/spine-c/spine-c/src/spine/SkeletonBinary.c @@ -44,7 +44,7 @@ typedef struct { const char *skin; int slotIndex; spMeshAttachment *mesh; - int inheritDeform; + int inheritTimeline; } _spLinkedMesh; typedef struct { @@ -192,6 +192,9 @@ 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 PATH_POSITION 0 #define PATH_SPACING 1 #define PATH_MIX 2 @@ -211,6 +214,16 @@ static void readColor(_dataInput *input, float *r, float *g, float *b, float *a) #define PATH_ROTATE_CHAIN 1 #define PATH_ROTATE_CHAIN_SCALE 2 +static spSequence *readSequence(_dataInput *input) { + spSequence *sequence = NULL; + if (!readBoolean(input)) return NULL; + sequence = spSequence_create(readVarint(input, -1)); + sequence->start = readVarint(input, -1); + sequence->digits = readVarint(input, -1); + sequence->setupIndex = readVarint(input, -1); + return sequence; +} + static void setBezier(_dataInput *input, spTimeline *timeline, int bezier, int frame, int value, float time1, float time2, float value1, float value2, float scale) { @@ -293,7 +306,7 @@ static void _spSkeletonBinary_addLinkedMesh(spSkeletonBinary *self, spMeshAttach linkedMesh->skin = skin; linkedMesh->slotIndex = slotIndex; linkedMesh->parent = parent; - linkedMesh->inheritDeform = inheritDeform; + linkedMesh->inheritTimeline = inheritDeform; } static spAnimation *_spSkeletonBinary_readAnimation(spSkeletonBinary *self, const char *name, @@ -692,7 +705,8 @@ 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; @@ -703,9 +717,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: { @@ -917,20 +931,20 @@ static short *_readShortArray(_dataInput *input, int *length) { return array; } -static void _readVertices(spSkeletonBinary *self, _dataInput *input, spVertexAttachment *attachment, - int vertexCount) { +static void _readVertices(spSkeletonBinary *self, _dataInput *input, int *bonesCount, int **bones2, int *verticesCount, + float **vertices, int *worldVerticesLength, int vertexCount) { int i, ii; int verticesLength = vertexCount << 1; spFloatArray *weights = spFloatArray_create(8); spIntArray *bones = spIntArray_create(8); - attachment->worldVerticesLength = verticesLength; + *worldVerticesLength = verticesLength; if (!readBoolean(input)) { - attachment->verticesCount = verticesLength; - attachment->vertices = _readFloatArray(input, verticesLength, self->scale); - attachment->bonesCount = 0; - attachment->bones = 0; + *verticesCount = verticesLength; + *vertices = _readFloatArray(input, verticesLength, self->scale); + *bonesCount = 0; + *bones2 = NULL; spFloatArray_dispose(weights); spIntArray_dispose(bones); return; @@ -950,12 +964,12 @@ static void _readVertices(spSkeletonBinary *self, _dataInput *input, spVertexAtt } } - attachment->verticesCount = weights->size; - attachment->vertices = weights->items; + *verticesCount = weights->size; + *vertices = weights->items; FREE(weights); - attachment->bonesCount = bones->size; - attachment->bones = bones->items; + *bonesCount = bones->size; + *bones2 = bones->items; FREE(bones); } @@ -972,33 +986,52 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput switch (type) { case SP_ATTACHMENT_REGION: { const char *path = readStringRef(input, skeletonData); - spAttachment *attachment; - spRegionAttachment *region; + float rotation, x, y, scaleX, scaleY, width, height; + spColor color; + spSequence *sequence; if (!path) MALLOC_STR(path, name); else { const char *tmp = 0; MALLOC_STR(tmp, path); path = tmp; } - attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, path); - region = SUB_CAST(spRegionAttachment, attachment); - region->path = path; - region->rotation = readFloat(input); - region->x = readFloat(input) * self->scale; - region->y = readFloat(input) * self->scale; - region->scaleX = readFloat(input); - region->scaleY = readFloat(input); - region->width = readFloat(input) * self->scale; - region->height = readFloat(input) * self->scale; - readColor(input, ®ion->color.r, ®ion->color.g, ®ion->color.b, ®ion->color.a); - spRegionAttachment_updateRegion(region); - spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment); - return attachment; + + rotation = readFloat(input); + x = readFloat(input) * self->scale; + y = readFloat(input) * self->scale; + scaleX = readFloat(input); + scaleY = readFloat(input); + width = readFloat(input) * self->scale; + height = readFloat(input) * self->scale; + readColor(input, &color.r, &color.g, &color.b, &color.a); + sequence = readSequence(input); + { + spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, + path, sequence); + spRegionAttachment *region = SUB_CAST(spRegionAttachment, attachment); + region->path = path; + region->rotation = rotation; + region->x = x; + region->y = y; + region->scaleX = scaleX; + region->scaleY = scaleY; + region->width = width; + region->height = height; + spColor_setFromColor(®ion->color, &color); + region->sequence = sequence; + if (sequence == NULL) spRegionAttachment_updateRegion(region); + spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment); + return attachment; + } } case SP_ATTACHMENT_BOUNDING_BOX: { int vertexCount = readVarint(input, 1); - spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0, NULL); - _readVertices(self, input, SUB_CAST(spVertexAttachment, attachment), vertexCount); + spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0, + NULL); + spVertexAttachment *vertexAttachment = SUB_CAST(spVertexAttachment, attachment); + _readVertices(self, input, &vertexAttachment->bonesCount, &vertexAttachment->bones, + &vertexAttachment->verticesCount, &vertexAttachment->vertices, + &vertexAttachment->worldVerticesLength, vertexCount); if (nonessential) { spBoundingBoxAttachment *bbox = SUB_CAST(spBoundingBoxAttachment, attachment); readColor(input, &bbox->color.r, &bbox->color.g, &bbox->color.b, &bbox->color.a); @@ -1008,43 +1041,73 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput } case SP_ATTACHMENT_MESH: { int vertexCount; - spAttachment *attachment; - spMeshAttachment *mesh; const char *path = readStringRef(input, skeletonData); + spColor color; + float *regionUVs; + unsigned short *triangles; + int trianglesCount; + int *bones; + int bonesCount; + float *vertices; + int verticesCount; + int worldVerticesLength; + int hullLength; + spSequence *sequence; + int *edges = NULL; + int edgesCount = 0; + float width = 0; + float height = 0; if (!path) MALLOC_STR(path, name); else { const char *tmp = 0; MALLOC_STR(tmp, path); path = tmp; } - attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, path); - mesh = SUB_CAST(spMeshAttachment, attachment); - mesh->path = path; - readColor(input, &mesh->color.r, &mesh->color.g, &mesh->color.b, &mesh->color.a); + + readColor(input, &color.r, &color.g, &color.b, &color.a); vertexCount = readVarint(input, 1); - mesh->regionUVs = _readFloatArray(input, vertexCount << 1, 1); - mesh->triangles = (unsigned short *) _readShortArray(input, &mesh->trianglesCount); - _readVertices(self, input, SUPER(mesh), vertexCount); - spMeshAttachment_updateRegion(mesh); - mesh->hullLength = readVarint(input, 1) << 1; + regionUVs = _readFloatArray(input, vertexCount << 1, 1); + triangles = (unsigned short *) _readShortArray(input, &trianglesCount); + _readVertices(self, input, &bonesCount, &bones, &verticesCount, &vertices, &worldVerticesLength, vertexCount); + hullLength = readVarint(input, 1) << 1; + sequence = readSequence(input); if (nonessential) { - mesh->edges = (int *) _readShortArray(input, &mesh->edgesCount); - mesh->width = readFloat(input) * self->scale; - mesh->height = readFloat(input) * self->scale; - } else { - mesh->edges = 0; - mesh->width = 0; - mesh->height = 0; + edges = (int *) _readShortArray(input, &edgesCount); + width = readFloat(input) * self->scale; + height = readFloat(input) * self->scale; + } + + { + spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, path, sequence); + spMeshAttachment *mesh = SUB_CAST(spMeshAttachment, attachment); + mesh->path = path; + spColor_setFromColor(&mesh->color, &color); + mesh->regionUVs = regionUVs; + mesh->triangles = triangles; + mesh->trianglesCount = trianglesCount; + mesh->super.vertices = vertices; + mesh->super.verticesCount = verticesCount; + mesh->super.bones = bones; + mesh->super.bonesCount = bonesCount; + mesh->super.worldVerticesLength = worldVerticesLength; + mesh->hullLength = hullLength; + mesh->edges = edges; + mesh->edgesCount = edgesCount; + mesh->width = width; + mesh->height = height; + mesh->sequence = sequence; + if (sequence) spMeshAttachment_updateRegion(mesh); + spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment); + return attachment; } - spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment); - return attachment; } case SP_ATTACHMENT_LINKED_MESH: { + spColor color; + float width = 0, height = 0; const char *skinName; const char *parent; - spAttachment *attachment; - spMeshAttachment *mesh; - int inheritDeform; + int inheritTimeline; + spSequence *sequence; const char *path = readStringRef(input, skeletonData); if (!path) MALLOC_STR(path, name); else { @@ -1052,28 +1115,41 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput MALLOC_STR(tmp, path); path = tmp; } - attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, path); - mesh = SUB_CAST(spMeshAttachment, attachment); - mesh->path = path; - readColor(input, &mesh->color.r, &mesh->color.g, &mesh->color.b, &mesh->color.a); + + readColor(input, &color.r, &color.g, &color.b, &color.a); skinName = readStringRef(input, skeletonData); parent = readStringRef(input, skeletonData); - inheritDeform = readBoolean(input); + inheritTimeline = readBoolean(input); + sequence = readSequence(input); if (nonessential) { - mesh->width = readFloat(input) * self->scale; - mesh->height = readFloat(input) * self->scale; + width = readFloat(input) * self->scale; + height = readFloat(input) * self->scale; + } + + { + spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, path, sequence); + spMeshAttachment *mesh = SUB_CAST(spMeshAttachment, attachment); + mesh->path = path; + spColor_setFromColor(&mesh->color, &color); + mesh->sequence = sequence; + mesh->width = width; + mesh->height = height; + _spSkeletonBinary_addLinkedMesh(self, mesh, skinName, slotIndex, parent, inheritTimeline); + return attachment; } - _spSkeletonBinary_addLinkedMesh(self, mesh, skinName, slotIndex, parent, inheritDeform); - return attachment; } case SP_ATTACHMENT_PATH: { - spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0, NULL); + spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0, + NULL); spPathAttachment *path = SUB_CAST(spPathAttachment, attachment); + spVertexAttachment *vertexAttachment = SUPER(path); int vertexCount = 0; path->closed = readBoolean(input); path->constantSpeed = readBoolean(input); vertexCount = readVarint(input, 1); - _readVertices(self, input, SUPER(path), vertexCount); + _readVertices(self, input, &vertexAttachment->bonesCount, &vertexAttachment->bones, + &vertexAttachment->verticesCount, &vertexAttachment->vertices, + &vertexAttachment->worldVerticesLength, vertexCount); path->lengthsLength = vertexCount / 3; path->lengths = MALLOC(float, path->lengthsLength); for (i = 0; i < path->lengthsLength; ++i) { @@ -1086,7 +1162,8 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput return attachment; } case SP_ATTACHMENT_POINT: { - spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0, NULL); + spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0, + NULL); spPointAttachment *point = SUB_CAST(spPointAttachment, attachment); point->rotation = readFloat(input); point->x = readFloat(input) * self->scale; @@ -1101,9 +1178,13 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput case SP_ATTACHMENT_CLIPPING: { int endSlotIndex = readVarint(input, 1); int vertexCount = readVarint(input, 1); - spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0, NULL); + spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0, + NULL); spClippingAttachment *clip = SUB_CAST(spClippingAttachment, attachment); - _readVertices(self, input, SUB_CAST(spVertexAttachment, attachment), vertexCount); + spVertexAttachment *vertexAttachment = SUPER(clip); + _readVertices(self, input, &vertexAttachment->bonesCount, &vertexAttachment->bones, + &vertexAttachment->verticesCount, &vertexAttachment->vertices, + &vertexAttachment->worldVerticesLength, vertexCount); if (nonessential) { readColor(input, &clip->color.r, &clip->color.g, &clip->color.b, &clip->color.a); } @@ -1403,7 +1484,8 @@ 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); @@ -1418,10 +1500,10 @@ spSkeletonData *spSkeletonBinary_readSkeletonData(spSkeletonBinary *self, const _spSkeletonBinary_setError(self, "Parent mesh not found: ", linkedMesh->parent); return NULL; } - linkedMesh->mesh->super.timelineAttachment = linkedMesh->inheritDeform ? parent - : SUPER(SUPER(linkedMesh->mesh)); + 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) spMeshAttachment_updateRegion(linkedMesh->mesh); spAttachmentLoader_configureAttachment(self->attachmentLoader, SUPER(SUPER(linkedMesh->mesh))); } diff --git a/spine-c/spine-c/src/spine/SkeletonJson.c b/spine-c/spine-c/src/spine/SkeletonJson.c index a0a94ec1b..14fd1a1b1 100644 --- a/spine-c/spine-c/src/spine/SkeletonJson.c +++ b/spine-c/spine-c/src/spine/SkeletonJson.c @@ -43,7 +43,7 @@ typedef struct { const char *skin; int slotIndex; spMeshAttachment *mesh; - int inheritDeform; + int inheritTimeline; } _spLinkedMesh; typedef struct { @@ -208,7 +208,7 @@ static void _spSkeletonJson_addLinkedMesh(spSkeletonJson *self, spMeshAttachment linkedMesh->skin = skin; linkedMesh->slotIndex = slotIndex; linkedMesh->parent = parent; - linkedMesh->inheritDeform = inheritDeform; + linkedMesh->inheritTimeline = inheritDeform; } static void cleanUpTimelines(spTimelineArray *timelines) { @@ -1514,8 +1514,8 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char _spSkeletonJson_setError(self, 0, "Parent mesh not found: ", linkedMesh->parent); return NULL; } - linkedMesh->mesh->super.timelineAttachment = linkedMesh->inheritDeform ? parent - : SUPER(SUPER(linkedMesh->mesh)); + linkedMesh->mesh->super.timelineAttachment = linkedMesh->inheritTimeline ? parent + : SUPER(SUPER(linkedMesh->mesh)); spMeshAttachment_setParentMesh(linkedMesh->mesh, SUB_CAST(spMeshAttachment, parent)); spMeshAttachment_updateRegion(linkedMesh->mesh); spAttachmentLoader_configureAttachment(self->attachmentLoader, SUPER(SUPER(linkedMesh->mesh))); diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp index a2f636a8a..378e6f32c 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp @@ -598,7 +598,7 @@ Attachment *SkeletonBinary::readAttachment(DataInput *input, Skin *skin, int slo if (path.isEmpty()) path = name; Color color; - float width, height; + float width = 0, height = 0; readColor(input, color); String skinName(readStringRef(input, skeletonData)); String parent(readStringRef(input, skeletonData));