[c] More porting of sequences.

This commit is contained in:
Mario Zechner 2021-12-29 22:26:34 +01:00
parent 83c0b0c559
commit 65a12c6f8e
21 changed files with 116 additions and 86 deletions

View File

@ -101,7 +101,6 @@ struct spAtlasRegion {
const char *name;
int x, y;
int index;
int degrees;
int *splits;
int *pads;
spKeyValueArray *keyValues;

View File

@ -33,6 +33,7 @@
#include <spine/dll.h>
#include <spine/Attachment.h>
#include <spine/Skin.h>
#include <spine/Sequence.h>
#ifdef __cplusplus
extern "C" {
@ -51,7 +52,7 @@ SP_API void spAttachmentLoader_dispose(spAttachmentLoader *self);
* called, an error occurred. */
SP_API spAttachment *
spAttachmentLoader_createAttachment(spAttachmentLoader *self, spSkin *skin, spAttachmentType type, const char *name,
const char *path);
const char *path, spSequence *sequence);
/* Called after the attachment has been fully configured. */
SP_API void spAttachmentLoader_configureAttachment(spAttachmentLoader *self, spAttachment *attachment);
/* Called just before the attachment is disposed. This can release allocations made in spAttachmentLoader_configureAttachment. */

View File

@ -47,6 +47,7 @@ struct spMeshAttachment {
void *rendererObject;
spTextureRegion *region;
spSequence *sequence;
const char *path;
@ -62,8 +63,6 @@ struct spMeshAttachment {
spMeshAttachment *const parentMesh;
spSequence *sequence;
/* Nonessential. */
int edgesCount;
int *edges;

View File

@ -48,17 +48,14 @@ typedef struct spRegionAttachment {
void *rendererObject;
spTextureRegion *region;
spSequence *sequence;
float offset[8];
float uvs[8];
spSequence *sequence;
} spRegionAttachment;
SP_API spRegionAttachment *spRegionAttachment_create(const char *name);
SP_API void spRegionAttachment_setUVs(spRegionAttachment *self, float u, float v, float u2, float v2, float degrees);
SP_API void spRegionAttachment_updateRegion(spRegionAttachment *self);
SP_API void spRegionAttachment_computeWorldVertices(spRegionAttachment *self, spSlot *slot, float *vertices, int offset,

View File

@ -58,7 +58,15 @@ SP_API spSequence *spSequence_copy(spSequence *self);
SP_API void spSequence_apply(spSequence *self, spSlot *slot, spAttachment *attachment);
SP_API char *spSequence_getPath(const char* basePath, int index);
SP_API void spSequence_getPath(const char* basePath, int index, char *path);
#define SP_SEQUENCE_MODE_HOLD 0
#define SP_SEQUENCE_MODE_ONCE 1
#define SP_SEQUENCE_MODE_LOOP 2
#define SP_SEQUENCE_MODE_PINGPONG 3
#define SP_SEQUENCE_MODE_ONCEREVERSE 4
#define SP_SEQUENCE_MODE_LOOPREVERSE 5
#define SP_SEQUENCE_MODE_PINGPONGREVERSE 6
#ifdef __cplusplus
}

View File

@ -64,7 +64,6 @@ typedef struct spSkeleton {
spSkin *const skin;
spColor color;
float time;
float scaleX, scaleY;
float x, y;
} spSkeleton;
@ -120,8 +119,6 @@ SP_API spTransformConstraint *spSkeleton_findTransformConstraint(const spSkeleto
/* Returns 0 if the path constraint was not found. */
SP_API spPathConstraint *spSkeleton_findPathConstraint(const spSkeleton *self, const char *constraintName);
SP_API void spSkeleton_update(spSkeleton *self, float deltaTime);
#ifdef __cplusplus
}
#endif

View File

@ -50,7 +50,7 @@ struct spVertexAttachment {
int worldVerticesLength;
spVertexAttachment *timelineAttachment;
spAttachment *timelineAttachment;
int id;
};

View File

@ -246,7 +246,7 @@ void _spAttachmentLoader_init(spAttachmentLoader *self,
void (*dispose)(spAttachmentLoader *self),
spAttachment *(*createAttachment)(spAttachmentLoader *self, spSkin *skin,
spAttachmentType type, const char *name,
const char *path),
const char *path, spSequence *sequence),
void (*configureAttachment)(spAttachmentLoader *self, spAttachment *),
void (*disposeAttachment)(spAttachmentLoader *self, spAttachment *)
);

View File

@ -1775,7 +1775,7 @@ void _spDeformTimeline_apply(
case SP_ATTACHMENT_MESH:
case SP_ATTACHMENT_PATH: {
spVertexAttachment *vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment);
if (vertexAttachment->timelineAttachment != SUB_CAST(spVertexAttachment, self->attachment)) return;
if (vertexAttachment->timelineAttachment != self->attachment) return;
break;
}
default:

View File

@ -376,9 +376,9 @@ spAtlas *spAtlas_create(const char *begin, int length, const char *dir, void *re
region->super.originalHeight = ss_toInt(&entry[4]);
} else if (ss_equals(&entry[0], "rotate")) {
if (ss_equals(&entry[1], "true")) {
region->degrees = 90;
region->super.degrees = 90;
} else if (!ss_equals(&entry[1], "false")) {
region->degrees = ss_toInt(&entry[1]);
region->super.degrees = ss_toInt(&entry[1]);
}
} else if (ss_equals(&entry[0], "index")) {
region->index = ss_toInt(&entry[1]);
@ -399,7 +399,7 @@ spAtlas *spAtlas_create(const char *begin, int length, const char *dir, void *re
region->super.u = (float) region->x / page->width;
region->super.v = (float) region->y / page->height;
if (region->degrees == 90) {
if (region->super.degrees == 90) {
region->super.u2 = (float) (region->x + region->super.height) / page->width;
region->super.v2 = (float) (region->y + region->super.width) / page->height;
} else {

View File

@ -29,35 +29,68 @@
#include <spine/AtlasAttachmentLoader.h>
#include <spine/extension.h>
#include <spine/Sequence.h>
static int /*bool*/ loadSequence(spAtlas *atlas, const char *basePath, spSequence *sequence) {
spTextureRegionArray *regions = sequence->regions;
char *path = CALLOC(char, strlen(basePath) + sequence->digits + 1);
int i ;
for (i = 0; i < regions->size; i++) {
spSequence_getPath(basePath, i, path);
regions->items[i] = SUPER(spAtlas_findRegion(atlas, path));
if (!regions->items[i]) {
FREE(path);
return 0;
}
regions->items[i]->rendererObject = regions->items[i];
}
FREE(path);
return -1;
}
spAttachment *_spAtlasAttachmentLoader_createAttachment(spAttachmentLoader *loader, spSkin *skin, spAttachmentType type,
const char *name, const char *path) {
const char *name, const char *path, spSequence *sequence) {
spAtlasAttachmentLoader *self = SUB_CAST(spAtlasAttachmentLoader, loader);
switch (type) {
case SP_ATTACHMENT_REGION: {
spRegionAttachment *attachment;
spAtlasRegion *region = spAtlas_findRegion(self->atlas, path);
if (!region) {
_spAttachmentLoader_setError(loader, "Region not found: ", path);
return 0;
spRegionAttachment *attachment = spRegionAttachment_create(name);
if (sequence) {
if (!loadSequence(self->atlas, path, sequence)) {
spAttachment_dispose(SUPER(attachment));
_spAttachmentLoader_setError(loader, "Couldn't load sequence for region attachment: ", path);
return 0;
}
} else {
spAtlasRegion *region = spAtlas_findRegion(self->atlas, path);
if (!region) {
spAttachment_dispose(SUPER(attachment));
_spAttachmentLoader_setError(loader, "Region not found: ", path);
return 0;
}
attachment->rendererObject = region;
attachment->region = SUPER(region);
}
attachment = spRegionAttachment_create(name);
attachment->rendererObject = region;
spRegionAttachment_setUVs(attachment, region->super.u, region->super.v, region->super.u2, region->super.v2, region->degrees);
attachment->region = SUPER(region);
return SUPER(attachment);
}
case SP_ATTACHMENT_MESH:
case SP_ATTACHMENT_LINKED_MESH: {
spMeshAttachment *attachment;
spAtlasRegion *region = spAtlas_findRegion(self->atlas, path);
if (!region) {
_spAttachmentLoader_setError(loader, "Region not found: ", path);
return 0;
spMeshAttachment *attachment = spMeshAttachment_create(name);
if (sequence) {
if (!loadSequence(self->atlas, path, sequence)) {
spAttachment_dispose(SUPER(SUPER(attachment)));
_spAttachmentLoader_setError(loader, "Couldn't load sequence for mesh attachment: ", path);
return 0;
}
} else {
spAtlasRegion *region = spAtlas_findRegion(self->atlas, path);
if (!region) {
_spAttachmentLoader_setError(loader, "Region not found: ", path);
return 0;
}
attachment->rendererObject = region;
attachment->region = SUPER(region);
}
attachment = spMeshAttachment_create(name);
attachment->rendererObject = region;
attachment->region = SUPER(region);
return SUPER(SUPER(attachment));
}
case SP_ATTACHMENT_BOUNDING_BOX:

View File

@ -33,7 +33,7 @@
typedef struct _spAttachmentLoaderVtable {
spAttachment *(*createAttachment)(spAttachmentLoader *self, spSkin *skin, spAttachmentType type, const char *name,
const char *path);
const char *path, spSequence *sequence);
void (*configureAttachment)(spAttachmentLoader *self, spAttachment *);
@ -46,7 +46,7 @@ void _spAttachmentLoader_init(spAttachmentLoader *self,
void (*dispose)(spAttachmentLoader *self),
spAttachment *(*createAttachment)(spAttachmentLoader *self, spSkin *skin,
spAttachmentType type, const char *name,
const char *path),
const char *path, spSequence *sequence),
void (*configureAttachment)(spAttachmentLoader *self, spAttachment *),
void (*disposeAttachment)(spAttachmentLoader *self, spAttachment *)) {
CONST_CAST(_spAttachmentLoaderVtable *, self->vtable) = NEW(_spAttachmentLoaderVtable);
@ -69,12 +69,12 @@ void spAttachmentLoader_dispose(spAttachmentLoader *self) {
spAttachment *
spAttachmentLoader_createAttachment(spAttachmentLoader *self, spSkin *skin, spAttachmentType type, const char *name,
const char *path) {
const char *path, spSequence *sequence) {
FREE(self->error1);
FREE(self->error2);
self->error1 = 0;
self->error2 = 0;
return VTABLE(spAttachmentLoader, self)->createAttachment(self, skin, type, name, path);
return VTABLE(spAttachmentLoader, self)->createAttachment(self, skin, type, name, path, sequence);
}
void spAttachmentLoader_configureAttachment(spAttachmentLoader *self, spAttachment *attachment) {

View File

@ -87,7 +87,7 @@ spMeshAttachment *spMeshAttachment_newLinkedMesh(spMeshAttachment *self) {
spColor_setFromColor(&copy->color, &self->color);
copy->super.timelineAttachment = self->super.timelineAttachment;
spMeshAttachment_setParentMesh(copy, self->parentMesh ? self->parentMesh : self);
spMeshAttachment_updateRegion(copy);
if (copy->region) spMeshAttachment_updateRegion(copy);
return copy;
}

View File

@ -51,12 +51,7 @@ void _spRegionAttachment_dispose(spAttachment *attachment) {
spAttachment *_spRegionAttachment_copy(spAttachment *attachment) {
spRegionAttachment *self = SUB_CAST(spRegionAttachment, attachment);
spRegionAttachment *copy = spRegionAttachment_create(attachment->name);
copy->region->width = self->region->width;
copy->region->height = self->region->height;
copy->region->offsetX = self->region->offsetX;
copy->region->offsetY = self->region->offsetY;
copy->region->originalWidth = self->region->originalWidth;
copy->region->originalHeight = self->region->originalHeight;
copy->region = self->region;
copy->rendererObject = self->rendererObject;
MALLOC_STR(copy->path, self->path);
copy->x = self->x;
@ -69,6 +64,7 @@ spAttachment *_spRegionAttachment_copy(spAttachment *attachment) {
memcpy(copy->uvs, self->uvs, sizeof(float) * 8);
memcpy(copy->offset, self->offset, sizeof(float) * 8);
spColor_setFromColor(&copy->color, &self->color);
copy->sequence = self->sequence ? spSequence_copy(self->sequence) : NULL;
return SUPER(copy);
}
@ -81,28 +77,6 @@ spRegionAttachment *spRegionAttachment_create(const char *name) {
return self;
}
void spRegionAttachment_setUVs(spRegionAttachment *self, float u, float v, float u2, float v2, float degrees) {
if (degrees == 90) {
self->uvs[URX] = u;
self->uvs[URY] = v2;
self->uvs[BRX] = u;
self->uvs[BRY] = v;
self->uvs[BLX] = u2;
self->uvs[BLY] = v;
self->uvs[ULX] = u2;
self->uvs[ULY] = v2;
} else {
self->uvs[ULX] = u;
self->uvs[ULY] = v2;
self->uvs[URX] = u;
self->uvs[URY] = v;
self->uvs[BRX] = u2;
self->uvs[BRY] = v;
self->uvs[BLX] = u2;
self->uvs[BLY] = v2;
}
}
void spRegionAttachment_updateRegion(spRegionAttachment *self) {
float regionScaleX = self->width / self->region->originalWidth * self->scaleX;
float regionScaleY = self->height / self->region->originalHeight * self->scaleY;
@ -128,6 +102,26 @@ void spRegionAttachment_updateRegion(spRegionAttachment *self) {
self->offset[URY] = localY2Cos + localX2Sin;
self->offset[BRX] = localX2Cos - localYSin;
self->offset[BRY] = localYCos + localX2Sin;
if (self->region->degrees == 90) {
self->uvs[URX] = self->region->u;
self->uvs[URY] = self->region->v2;
self->uvs[BRX] = self->region->u;
self->uvs[BRY] = self->region->v;
self->uvs[BLX] = self->region->u2;
self->uvs[BLY] = self->region->v;
self->uvs[ULX] = self->region->u2;
self->uvs[ULY] = self->region->v2;
} else {
self->uvs[ULX] = self->region->u;
self->uvs[ULY] = self->region->v2;
self->uvs[URX] = self->region->u;
self->uvs[URY] = self->region->v;
self->uvs[BRX] = self->region->u2;
self->uvs[BRY] = self->region->v;
self->uvs[BLX] = self->region->u2;
self->uvs[BLY] = self->region->v2;
}
}
void spRegionAttachment_computeWorldVertices(spRegionAttachment *self, spSlot *slot, float *vertices, int offset,
@ -137,6 +131,8 @@ void spRegionAttachment_computeWorldVertices(spRegionAttachment *self, spSlot *s
float x = bone->worldX, y = bone->worldY;
float offsetX, offsetY;
if (self->sequence) spSequence_apply(self->sequence, slot, SUPER(self));
offsetX = offsets[BRX];
offsetY = offsets[BRY];
vertices[offset] = offsetX * bone->a + offsetY * bone->b + x; /* br */

View File

@ -87,6 +87,6 @@ void spSequence_apply(spSequence *self, spSlot *slot, spAttachment *attachment)
}
}
char *spSequence_getPath(const char* basePath, int index) {
void spSequence_getPath(const char* basePath, int index, char* path) {
fix me
}

View File

@ -629,7 +629,3 @@ spPathConstraint *spSkeleton_findPathConstraint(const spSkeleton *self, const ch
if (strcmp(self->pathConstraints[i]->data->name, constraintName) == 0) return self->pathConstraints[i];
return 0;
}
void spSkeleton_update(spSkeleton *self, float deltaTime) {
self->time += deltaTime;
}

View File

@ -991,13 +991,13 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput
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_updateOffset(region);
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);
spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0, NULL);
_readVertices(self, input, SUB_CAST(spVertexAttachment, attachment), vertexCount);
if (nonessential) {
spBoundingBoxAttachment *bbox = SUB_CAST(spBoundingBoxAttachment, attachment);
@ -1025,7 +1025,7 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput
mesh->regionUVs = _readFloatArray(input, vertexCount << 1, 1);
mesh->triangles = (unsigned short *) _readShortArray(input, &mesh->trianglesCount);
_readVertices(self, input, SUPER(mesh), vertexCount);
spMeshAttachment_updateUVs(mesh);
spMeshAttachment_updateRegion(mesh);
mesh->hullLength = readVarint(input, 1) << 1;
if (nonessential) {
mesh->edges = (int *) _readShortArray(input, &mesh->edgesCount);
@ -1067,7 +1067,7 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput
return attachment;
}
case SP_ATTACHMENT_PATH: {
spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0);
spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0, NULL);
spPathAttachment *path = SUB_CAST(spPathAttachment, attachment);
int vertexCount = 0;
path->closed = readBoolean(input);
@ -1086,7 +1086,7 @@ spAttachment *spSkeletonBinary_readAttachment(spSkeletonBinary *self, _dataInput
return attachment;
}
case SP_ATTACHMENT_POINT: {
spAttachment *attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0);
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,7 +1101,7 @@ 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);
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);
if (nonessential) {
@ -1422,7 +1422,7 @@ spSkeletonData *spSkeletonBinary_readSkeletonData(spSkeletonBinary *self, const
: SUB_CAST(spVertexAttachment,
linkedMesh->mesh);
spMeshAttachment_setParentMesh(linkedMesh->mesh, SUB_CAST(spMeshAttachment, parent));
spMeshAttachment_updateUVs(linkedMesh->mesh);
spMeshAttachment_updateRegion(linkedMesh->mesh);
spAttachmentLoader_configureAttachment(self->attachmentLoader, SUPER(SUPER(linkedMesh->mesh)));
}

View File

@ -1352,7 +1352,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
toColor(color, 3));
}
spRegionAttachment_updateOffset(region);
spRegionAttachment_updateRegion(region);
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
break;
@ -1392,7 +1392,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
_readVertices(self, attachmentMap, SUPER(mesh), verticesLength);
spMeshAttachment_updateUVs(mesh);
spMeshAttachment_updateRegion(mesh);
mesh->hullLength = Json_getInt(attachmentMap, "hull", 0);
@ -1518,7 +1518,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
: SUB_CAST(spVertexAttachment,
linkedMesh->mesh);
spMeshAttachment_setParentMesh(linkedMesh->mesh, SUB_CAST(spMeshAttachment, parent));
spMeshAttachment_updateUVs(linkedMesh->mesh);
spMeshAttachment_updateRegion(linkedMesh->mesh);
spAttachmentLoader_configureAttachment(self->attachmentLoader, SUPER(SUPER(linkedMesh->mesh)));
}

View File

@ -68,6 +68,7 @@ void spSlot_setAttachment(spSlot *self, spAttachment *attachment) {
}
CONST_CAST(spAttachment *, self->attachment) = attachment;
self->sequenceIndex = -1;
}
void spSlot_setToSetupPose(spSlot *self) {

View File

@ -52,6 +52,11 @@ void spVertexAttachment_computeWorldVertices(spVertexAttachment *self, spSlot *s
float *vertices;
int *bones;
if (self->super.type == SP_ATTACHMENT_MESH || self->super.type == SP_ATTACHMENT_LINKED_MESH) {
spMeshAttachment *mesh = SUB_CAST(spMeshAttachment, self);
if (mesh->sequence) spSequence_apply(mesh->sequence, slot, SUPER(self));
}
count = offset + (count >> 1) * stride;
skeleton = slot->bone->skeleton;
deformLength = slot->deformCount;

View File

@ -60,8 +60,6 @@ namespace spine {
void updateRegion();
void setUVs(float u, float v, float u2, float v2, float degrees);
/// Transforms the attachment's four vertices to world coordinates.
/// @param bone The parent bone.
/// @param worldVertices The output world vertices. Must have a length greater than or equal to offset + 8.