[c][sfml] Ported all skin API changes, see #841.

This commit is contained in:
badlogic 2019-06-03 15:39:11 +02:00
parent a5dedaac4f
commit 40e6b026bd
15 changed files with 191 additions and 28 deletions

View File

@ -67,6 +67,8 @@ typedef struct spAttachment {
void spAttachment_dispose (spAttachment* self);
spAttachment* spAttachment_copy (spAttachment* self);
#ifdef SPINE_SHORT_NAMES
typedef spAttachmentType AttachmentType;
#define ATTACHMENT_REGION SP_ATTACHMENT_REGION

View File

@ -65,7 +65,6 @@ struct spMeshAttachment {
int hullLength;
spMeshAttachment* const parentMesh;
int/*bool*/inheritDeform;
/* Nonessential. */
int edgesCount;
@ -76,6 +75,7 @@ struct spMeshAttachment {
SP_API spMeshAttachment* spMeshAttachment_create (const char* name);
SP_API void spMeshAttachment_updateUVs (spMeshAttachment* self);
SP_API void spMeshAttachment_setParentMesh (spMeshAttachment* self, spMeshAttachment* parentMesh);
SP_API spMeshAttachment* spMeshAttachment_newLinkedMesh (spMeshAttachment* self);
#ifdef SPINE_SHORT_NAMES
typedef spMeshAttachment MeshAttachment;

View File

@ -109,6 +109,9 @@ SP_API void spSkin_attachAll (const spSkin* self, struct spSkeleton* skeleton, c
/** Adds all attachments, bones, and constraints from the specified skin to this skin. */
SP_API void spSkin_addSkin(spSkin* self, const spSkin* other);
/** Adds all attachments, bones, and constraints from the specified skin to this skin. Attachments are deep copied. */
SP_API void spSkin_copySkin(spSkin* self, const spSkin* other);
/** Returns all attachments in this skin. */
SP_API spSkinEntry* spSkin_getAttachments(const spSkin* self);

View File

@ -50,11 +50,15 @@ struct spVertexAttachment {
int worldVerticesLength;
spVertexAttachment* deformAttachment;
int id;
};
SP_API void spVertexAttachment_computeWorldVertices (spVertexAttachment* self, spSlot* slot, int start, int count, float* worldVertices, int offset, int stride);
void spVertexAttachment_copyTo(spVertexAttachment* self, spVertexAttachment* other);
#ifdef SPINE_SHORT_NAMES
typedef spVertexAttachment VertexAttachment;
#define VertexAttachment_computeWorldVertices(...) spVertexAttachment_computeWorldVertices(__VA_ARGS__)

View File

@ -894,18 +894,19 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
spSlot *slot = skeleton->slots[self->slotIndex];
if (slot->attachment != self->attachment) {
if (!slot->attachment) return;
switch (slot->attachment->type) {
case SP_ATTACHMENT_MESH: {
spMeshAttachment* mesh = SUB_CAST(spMeshAttachment, slot->attachment);
if (!mesh->inheritDeform || mesh->parentMesh != (void*)self->attachment) return;
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->deformAttachment != SUB_CAST(spVertexAttachment, self->attachment)) return;
break;
}
default:
return;
}
}
frames = self->frames;
framesCount = self->framesCount;

View File

@ -39,7 +39,10 @@ void _spBoundingBoxAttachment_dispose (spAttachment* attachment) {
}
spAttachment* _spBoundingBoxAttachment_copy (spAttachment* attachment) {
spBoundingBoxAttachment* copy = spBoundingBoxAttachment_create(attachment->name);
spBoundingBoxAttachment* self = SUB_CAST(spBoundingBoxAttachment, attachment);
spVertexAttachment_copyTo(SUPER(self), SUPER(copy));
return SUPER(SUPER(copy));
}
spBoundingBoxAttachment* spBoundingBoxAttachment_create (const char* name) {

View File

@ -39,7 +39,11 @@ void _spClippingAttachment_dispose (spAttachment* attachment) {
}
spAttachment* _spClippingAttachment_copy (spAttachment* attachment) {
spClippingAttachment* copy = spClippingAttachment_create(attachment->name);
spClippingAttachment* self = SUB_CAST(spClippingAttachment, attachment);
spVertexAttachment_copyTo(SUPER(self), SUPER(copy));
copy->endSlot = self->endSlot;
return SUPER(SUPER(copy));
}
spClippingAttachment* spClippingAttachment_create (const char* name) {

View File

@ -29,6 +29,7 @@
#include <spine/MeshAttachment.h>
#include <spine/extension.h>
#include <stdio.h>
void _spMeshAttachment_dispose (spAttachment* attachment) {
spMeshAttachment* self = SUB_CAST(spMeshAttachment, attachment);
@ -45,7 +46,69 @@ void _spMeshAttachment_dispose (spAttachment* attachment) {
}
spAttachment* _spMeshAttachment_copy (spAttachment* attachment) {
spMeshAttachment* copy;
spMeshAttachment* self = SUB_CAST(spMeshAttachment, attachment);
if (self->parentMesh)
return SUPER(SUPER(spMeshAttachment_newLinkedMesh(self)));
copy = spMeshAttachment_create(attachment->name);
copy->rendererObject = self->rendererObject;
copy->regionU = self->regionU;
copy->regionV = self->regionV;
copy->regionU2 = self->regionU2;
copy->regionV2 = self->regionV2;
copy->regionRotate = self->regionRotate;
copy->regionDegrees = self->regionDegrees;
copy->regionOffsetX = self->regionOffsetX;
copy->regionOffsetY = self->regionOffsetY;
copy->regionWidth = self->regionWidth;
copy->regionHeight = self->regionHeight;
copy->regionOriginalWidth = self->regionOriginalWidth;
copy->regionOriginalHeight = self->regionOriginalHeight;
MALLOC_STR(copy->path, self->path);
spColor_setFromColor(&copy->color, &self->color);
spVertexAttachment_copyTo(SUPER(self), SUPER(copy));
copy->regionUVs = MALLOC(float, SUPER(self)->worldVerticesLength);
memcpy(copy->regionUVs, self->regionUVs, SUPER(self)->worldVerticesLength * sizeof(float));
copy->uvs = MALLOC(float, SUPER(self)->worldVerticesLength);
memcpy(copy->uvs, self->uvs, SUPER(self)->worldVerticesLength * sizeof(float));
copy->trianglesCount = self->trianglesCount;
copy->triangles = MALLOC(unsigned short, self->trianglesCount);
memcpy(copy->triangles, self->triangles, self->trianglesCount * sizeof(short));
copy->hullLength = self->hullLength;
if (self->edgesCount > 0) {
copy->edgesCount = self->edgesCount;
copy->edges = MALLOC(int, self->edgesCount);
memcpy(copy->edges, self->edges, self->edgesCount * sizeof(int));
}
copy->width = self->width;
copy->height = self->height;
return SUPER(SUPER(copy));
}
spMeshAttachment* spMeshAttachment_newLinkedMesh (spMeshAttachment* self) {
spMeshAttachment* copy = spMeshAttachment_create(self->super.super.name);
copy->rendererObject = self->rendererObject;
copy->regionU = self->regionU;
copy->regionV = self->regionV;
copy->regionU2 = self->regionU2;
copy->regionV2 = self->regionV2;
copy->regionRotate = self->regionRotate;
copy->regionDegrees = self->regionDegrees;
copy->regionOffsetX = self->regionOffsetX;
copy->regionOffsetY = self->regionOffsetY;
copy->regionWidth = self->regionWidth;
copy->regionHeight = self->regionHeight;
copy->regionOriginalWidth = self->regionOriginalWidth;
copy->regionOriginalHeight = self->regionOriginalHeight;
MALLOC_STR(copy->path, self->path);
spColor_setFromColor(&copy->color, &self->color);
copy->super.deformAttachment = self->super.deformAttachment;
spMeshAttachment_setParentMesh(copy, self->parentMesh ? self->parentMesh : self);
spMeshAttachment_updateUVs(copy);
return copy;
}
spMeshAttachment* spMeshAttachment_create (const char* name) {
@ -59,12 +122,12 @@ spMeshAttachment* spMeshAttachment_create (const char* name) {
void spMeshAttachment_updateUVs (spMeshAttachment* self) {
int i, n;
float* uvs;
float u, v, width, height;
int verticesLength = SUPER(self)->worldVerticesLength;
FREE(self->uvs);
uvs = self->uvs = MALLOC(float, verticesLength);
n = verticesLength;
float u = self->regionU, v = self->regionV;
float width = 0, height = 0;
u = self->regionU; v = self->regionV;
switch (self->regionDegrees) {
case 90: {

View File

@ -40,7 +40,15 @@ void _spPathAttachment_dispose (spAttachment* attachment) {
}
spAttachment* _spPathAttachment_copy (spAttachment* attachment) {
spPathAttachment* copy = spPathAttachment_create(attachment->name);
spPathAttachment* self = SUB_CAST(spPathAttachment, attachment);
spVertexAttachment_copyTo(SUPER(self), SUPER(copy));
copy->lengthsLength = self->lengthsLength;
copy->lengths = MALLOC(float, self->lengthsLength);
memcpy(copy->lengths, self->lengths, self->lengthsLength * sizeof(float));
copy->closed = self->closed;
copy->constantSpeed = self->constantSpeed;
return SUPER(SUPER(copy));
}
spPathAttachment* spPathAttachment_create (const char* name) {

View File

@ -44,6 +44,7 @@ typedef struct {
const char* skin;
int slotIndex;
spMeshAttachment* mesh;
int inheritDeform;
} _spLinkedMesh;
typedef struct {
@ -221,7 +222,7 @@ static void readCurve (_dataInput* input, spCurveTimeline* timeline, int frameIn
}
static void _spSkeletonBinary_addLinkedMesh (spSkeletonBinary* self, spMeshAttachment* mesh,
const char* skin, int slotIndex, const char* parent) {
const char* skin, int slotIndex, const char* parent, int inheritDeform) {
_spLinkedMesh* linkedMesh;
_spSkeletonBinary* internal = SUB_CAST(_spSkeletonBinary, self);
@ -241,6 +242,7 @@ static void _spSkeletonBinary_addLinkedMesh (spSkeletonBinary* self, spMeshAttac
linkedMesh->skin = skin;
linkedMesh->slotIndex = slotIndex;
linkedMesh->parent = parent;
linkedMesh->inheritDeform = inheritDeform;
}
_SP_ARRAY_DECLARE_TYPE(spTimelineArray, spTimeline*)
@ -752,6 +754,7 @@ spAttachment* spSkeletonBinary_readAttachment(spSkeletonBinary* self, _dataInput
const char* parent;
spAttachment* attachment;
spMeshAttachment* mesh;
int inheritDeform;
const char* path = readString(input);
if (!path) MALLOC_STR(path, name);
attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, path);
@ -760,12 +763,12 @@ spAttachment* spSkeletonBinary_readAttachment(spSkeletonBinary* self, _dataInput
readColor(input, &mesh->color.r, &mesh->color.g, &mesh->color.b, &mesh->color.a);
skinName = readString(input);
parent = readString(input);
mesh->inheritDeform = readBoolean(input);
inheritDeform = readBoolean(input);
if (nonessential) {
mesh->width = readFloat(input) * self->scale;
mesh->height = readFloat(input) * self->scale;
}
_spSkeletonBinary_addLinkedMesh(self, mesh, skinName, slotIndex, parent);
_spSkeletonBinary_addLinkedMesh(self, mesh, skinName, slotIndex, parent, inheritDeform);
if (freeName) FREE(name);
return attachment;
}
@ -1065,6 +1068,7 @@ spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const
_spSkeletonBinary_setError(self, "Parent mesh not found: ", linkedMesh->parent);
return 0;
}
linkedMesh->mesh->super.deformAttachment = linkedMesh->inheritDeform ? SUB_CAST(spVertexAttachment, parent) : SUB_CAST(spVertexAttachment, linkedMesh->mesh);
spMeshAttachment_setParentMesh(linkedMesh->mesh, SUB_CAST(spMeshAttachment, parent));
spMeshAttachment_updateUVs(linkedMesh->mesh);
spAttachmentLoader_configureAttachment(self->attachmentLoader, SUPER(SUPER(linkedMesh->mesh)));

View File

@ -43,6 +43,7 @@ typedef struct {
const char* skin;
int slotIndex;
spMeshAttachment* mesh;
int inheritDeform;
} _spLinkedMesh;
typedef struct {
@ -120,7 +121,7 @@ static void readCurve (Json* frame, spCurveTimeline* timeline, int frameIndex) {
}
static void _spSkeletonJson_addLinkedMesh (spSkeletonJson* self, spMeshAttachment* mesh, const char* skin, int slotIndex,
const char* parent) {
const char* parent, int inheritDeform) {
_spLinkedMesh* linkedMesh;
_spSkeletonJson* internal = SUB_CAST(_spSkeletonJson, self);
@ -139,6 +140,7 @@ static void _spSkeletonJson_addLinkedMesh (spSkeletonJson* self, spMeshAttachmen
linkedMesh->skin = skin;
linkedMesh->slotIndex = slotIndex;
linkedMesh->parent = parent;
linkedMesh->inheritDeform = inheritDeform;
}
static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* root, spSkeletonData *skeletonData) {
@ -992,9 +994,9 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
} else {
mesh->inheritDeform = Json_getInt(attachmentMap, "deform", 1);
int inheritDeform = Json_getInt(attachmentMap, "deform", 1);
_spSkeletonJson_addLinkedMesh(self, SUB_CAST(spMeshAttachment, attachment), Json_getString(attachmentMap, "skin", 0), slotIndex,
entry->valueString);
entry->valueString, inheritDeform);
}
break;
}
@ -1076,6 +1078,7 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
_spSkeletonJson_setError(self, 0, "Parent mesh not found: ", linkedMesh->parent);
return 0;
}
linkedMesh->mesh->super.deformAttachment = linkedMesh->inheritDeform ? SUB_CAST(spVertexAttachment, parent) : SUB_CAST(spVertexAttachment, linkedMesh->mesh);
spMeshAttachment_setParentMesh(linkedMesh->mesh, SUB_CAST(spMeshAttachment, parent));
spMeshAttachment_updateUVs(linkedMesh->mesh);
spAttachmentLoader_configureAttachment(self->attachmentLoader, SUPER(SUPER(linkedMesh->mesh)));

View File

@ -29,6 +29,7 @@
#include <spine/Skin.h>
#include <spine/extension.h>
#include <stdio.h>
_SP_ARRAY_IMPLEMENT_TYPE(spBoneDataArray, spBoneData*)
_SP_ARRAY_IMPLEMENT_TYPE(spIkConstraintDataArray, spIkConstraintData*)
@ -105,7 +106,7 @@ void spSkin_dispose (spSkin* self) {
void spSkin_setAttachment (spSkin* self, int slotIndex, const char* name, spAttachment* attachment) {
_SkinHashTableEntry* existingEntry = 0;
const _SkinHashTableEntry* hashEntry = SUB_CAST(_spSkin, self)->entriesHashTable[(unsigned int)slotIndex % SKIN_ENTRIES_HASH_TABLE_SIZE];
_SkinHashTableEntry* hashEntry = SUB_CAST(_spSkin, self)->entriesHashTable[(unsigned int)slotIndex % SKIN_ENTRIES_HASH_TABLE_SIZE];
while (hashEntry) {
if (hashEntry->entry->slotIndex == slotIndex && strcmp(hashEntry->entry->name, name) == 0) {
existingEntry = hashEntry;
@ -170,6 +171,7 @@ void spSkin_attachAll (const spSkin* self, spSkeleton* skeleton, const spSkin* o
void spSkin_addSkin(spSkin* self, const spSkin* other) {
int i = 0;
spSkinEntry* entry;
for (i = 0; i < other->bones->size; i++) {
if (!spBoneDataArray_contains(self->bones, other->bones->items[i]))
@ -191,13 +193,50 @@ void spSkin_addSkin(spSkin* self, const spSkin* other) {
spPathConstraintDataArray_add(self->pathConstraints, other->pathConstraints->items[i]);
}
spSkinEntry* entry = spSkin_getAttachments(other);
entry = spSkin_getAttachments(other);
while (entry) {
spSkin_setAttachment(self, entry->slotIndex, entry->name, entry->attachment);
entry = entry->next;
}
}
void spSkin_copySkin(spSkin* self, const spSkin* other) {
int i = 0;
spSkinEntry* entry;
for (i = 0; i < other->bones->size; i++) {
if (!spBoneDataArray_contains(self->bones, other->bones->items[i]))
spBoneDataArray_add(self->bones, other->bones->items[i]);
}
for (i = 0; i < other->ikConstraints->size; i++) {
if (!spIkConstraintDataArray_contains(self->ikConstraints, other->ikConstraints->items[i]))
spIkConstraintDataArray_add(self->ikConstraints, other->ikConstraints->items[i]);
}
for (i = 0; i < other->transformConstraints->size; i++) {
if (!spTransformConstraintDataArray_contains(self->transformConstraints, other->transformConstraints->items[i]))
spTransformConstraintDataArray_add(self->transformConstraints, other->transformConstraints->items[i]);
}
for (i = 0; i < other->pathConstraints->size; i++) {
if (!spPathConstraintDataArray_contains(self->pathConstraints, other->pathConstraints->items[i]))
spPathConstraintDataArray_add(self->pathConstraints, other->pathConstraints->items[i]);
}
entry = spSkin_getAttachments(other);
while (entry) {
if (entry->attachment->type == SP_ATTACHMENT_MESH) {
spMeshAttachment* attachment = spMeshAttachment_newLinkedMesh(SUB_CAST(spMeshAttachment, entry->attachment));
spSkin_setAttachment(self, entry->slotIndex, entry->name, SUPER(SUPER(attachment)));
} else {
spAttachment* attachment = entry->attachment ? spAttachment_copy(entry->attachment) : 0;
spSkin_setAttachment(self, entry->slotIndex, entry->name, attachment);
}
entry = entry->next;
}
}
spSkinEntry* spSkin_getAttachments(const spSkin* self) {
return SUB_CAST(_spSkin, self)->entries;
}

View File

@ -35,6 +35,7 @@ static int nextID = 0;
void _spVertexAttachment_init (spVertexAttachment* attachment) {
attachment->id = (nextID++ & 65535) << 11;
attachment->deformAttachment = attachment;
}
void _spVertexAttachment_deinit (spVertexAttachment* attachment) {
@ -111,3 +112,30 @@ void spVertexAttachment_computeWorldVertices (spVertexAttachment* self, spSlot*
}
}
}
void spVertexAttachment_copyTo(spVertexAttachment* from, spVertexAttachment* to) {
if (from->bonesCount) {
to->bonesCount = from->bonesCount;
to->bones = MALLOC(int, from->bonesCount);
memcpy(to->bones, from->bones, from->bonesCount * sizeof(int));
} else {
to->bonesCount = 0;
if (to->bones) {
FREE(to->bones);
to->bones = 0;
}
}
if (from->verticesCount) {
to->verticesCount = from->verticesCount;
to->vertices = MALLOC(float, from->verticesCount);
memcpy(to->vertices, from->vertices, from->verticesCount * sizeof(float));
} else {
to->verticesCount = 0;
if (to->vertices) {
FREE(to->vertices);
to->vertices = 0;
}
}
to->worldVerticesLength = from->worldVerticesLength;
}

View File

@ -61,8 +61,8 @@ namespace spine {
/// Abstract class to inherit from to create a callback object
class SP_API AnimationStateListenerObject {
public:
AnimationStateListenerObject() = default;
virtual ~AnimationStateListenerObject() = default;
AnimationStateListenerObject() { };
virtual ~AnimationStateListenerObject() { };
public:
/// The callback function to be called
virtual void callback(AnimationState* state, EventType type, TrackEntry* entry, Event* event) = 0;

View File

@ -454,7 +454,8 @@ void testSkinsApi(SkeletonData* skeletonData, Atlas* atlas) {
Skeleton* skeleton = drawable->skeleton;
spSkin* skin = spSkin_create("test-skin");
spSkin_addSkin(skin, spSkeletonData_findSkin(skeletonData, "goblingirl"));
spSkin_copySkin(skin, spSkeletonData_findSkin(skeletonData, "goblingirl"));
// spSkin_addSkin(skin, spSkeletonData_findSkin(skeletonData, "goblingirl"));
spSkeleton_setSkin(skeleton, skin);
spSkeleton_setSlotsToSetupPose(skeleton);
@ -488,6 +489,7 @@ void testSkinsApi(SkeletonData* skeletonData, Atlas* atlas) {
int main () {
testcase(testSkinsApi, "data/goblins-pro.json", "data/goblins-pro.skel", "data/goblins-pma.atlas", 1.4f);
testcase(goblins, "data/goblins-pro.json", "data/goblins-pro.skel", "data/goblins-pma.atlas", 1.4f);
testcase(test, "data/tank-pro.json", "data/tank-pro.skel", "data/tank-pma.atlas", 1.0f);
testcase(spineboy, "data/spineboy-pro.json", "data/spineboy-pro.skel", "data/spineboy-pma.atlas", 0.6f);
testcase(stretchyman, "data/stretchyman-stretchy-ik-pro.json", "data/stretchyman-stretchy-ik-pro.skel", "data/stretchyman-pma.atlas", 0.6f);
@ -496,7 +498,6 @@ int main () {
testcase(vine, "data/vine-pro.json", "data/vine-pro.skel", "data/vine-pma.atlas", 0.5f);
testcase(tank, "data/tank-pro.json", "data/tank-pro.skel", "data/tank-pma.atlas", 0.2f);
testcase(raptor, "data/raptor-pro.json", "data/raptor-pro.skel", "data/raptor-pma.atlas", 0.5f);
testcase(goblins, "data/goblins-pro.json", "data/goblins-pro.skel", "data/goblins-pma.atlas", 1.4f);
testcase(stretchyman, "data/stretchyman-pro.json", "data/stretchyman-pro.skel", "data/stretchyman-pma.atlas", 0.6f);
return 0;
}