[c] Port sequence timeline loading to SkeletonBinary

Deform timeline parsing not working.
This commit is contained in:
Mario Zechner 2022-02-04 13:21:44 +01:00
parent aced5aa489
commit 0d237b1529
5 changed files with 169 additions and 87 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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;
@ -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);
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 = 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, &region->color.r, &region->color.g, &region->color.b, &region->color.a);
spRegionAttachment_updateRegion(region);
region->rotation = rotation;
region->x = x;
region->y = y;
region->scaleX = scaleX;
region->scaleY = scaleY;
region->width = width;
region->height = height;
spColor_setFromColor(&region->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;
}
}
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;
}
_spSkeletonBinary_addLinkedMesh(self, mesh, skinName, slotIndex, parent, inheritDeform);
{
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;
}
}
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
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)));
}

View File

@ -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,7 +1514,7 @@ 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
linkedMesh->mesh->super.timelineAttachment = linkedMesh->inheritTimeline ? parent
: SUPER(SUPER(linkedMesh->mesh));
spMeshAttachment_setParentMesh(linkedMesh->mesh, SUB_CAST(spMeshAttachment, parent));
spMeshAttachment_updateRegion(linkedMesh->mesh);

View File

@ -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));