[c] Ported skin bones/constraints changes. See #1346.

This commit is contained in:
badlogic 2019-06-05 17:31:48 +02:00
parent 8cd53746ad
commit d9161d2020
15 changed files with 228 additions and 72 deletions

View File

@ -54,6 +54,7 @@ struct spBone {
float const c, d, worldY; float const c, d, worldY;
int/*bool*/ sorted; int/*bool*/ sorted;
int/*bool*/ active;
#ifdef __cplusplus #ifdef __cplusplus
spBone() : spBone() :
@ -68,7 +69,7 @@ struct spBone {
a(0), b(0), worldX(0), a(0), b(0), worldX(0),
c(0), d(0), worldY(0), c(0), d(0), worldY(0),
sorted(0) { sorted(0), active(0) {
} }
#endif #endif
}; };

View File

@ -52,6 +52,7 @@ struct spBoneData {
float length; float length;
float x, y, rotation, scaleX, scaleY, shearX, shearY; float x, y, rotation, scaleX, scaleY, shearX, shearY;
spTransformMode transformMode; spTransformMode transformMode;
int/*bool*/ skinRequired;
#ifdef __cplusplus #ifdef __cplusplus
spBoneData() : spBoneData() :
@ -63,7 +64,8 @@ struct spBoneData {
rotation(0), rotation(0),
scaleX(0), scaleY(0), scaleX(0), scaleY(0),
shearX(0), shearY(0), shearX(0), shearY(0),
transformMode(SP_TRANSFORMMODE_NORMAL) { transformMode(SP_TRANSFORMMODE_NORMAL),
skinRequired(0) {
} }
#endif #endif
}; };

View File

@ -52,6 +52,8 @@ typedef struct spIkConstraint {
int /*boolean*/ stretch; int /*boolean*/ stretch;
float mix; float mix;
int /*boolean*/ active;
#ifdef __cplusplus #ifdef __cplusplus
spIkConstraint() : spIkConstraint() :
data(0), data(0),
@ -60,7 +62,8 @@ typedef struct spIkConstraint {
target(0), target(0),
bendDirection(0), bendDirection(0),
stretch(0), stretch(0),
mix(0) { mix(0),
active(0) {
} }
#endif #endif
} spIkConstraint; } spIkConstraint;

View File

@ -40,6 +40,7 @@ extern "C" {
typedef struct spIkConstraintData { typedef struct spIkConstraintData {
const char* const name; const char* const name;
int order; int order;
int /*boolean*/ skinRequired;
int bonesCount; int bonesCount;
spBoneData** bones; spBoneData** bones;
@ -53,6 +54,8 @@ typedef struct spIkConstraintData {
#ifdef __cplusplus #ifdef __cplusplus
spIkConstraintData() : spIkConstraintData() :
name(0), name(0),
order(0),
skinRequired(0),
bonesCount(0), bonesCount(0),
bones(0), bones(0),
target(0), target(0),

View File

@ -66,6 +66,8 @@ typedef struct spPathConstraint {
float segments[10]; float segments[10];
int /*boolean*/ active;
#ifdef __cplusplus #ifdef __cplusplus
spPathConstraint() : spPathConstraint() :
data(0), data(0),
@ -85,7 +87,8 @@ typedef struct spPathConstraint {
curvesCount(0), curvesCount(0),
curves(0), curves(0),
lengthsCount(0), lengthsCount(0),
lengths(0) { lengths(0),
active(0) {
} }
#endif #endif
} spPathConstraint; } spPathConstraint;

View File

@ -53,6 +53,7 @@ typedef enum {
typedef struct spPathConstraintData { typedef struct spPathConstraintData {
const char* const name; const char* const name;
int order; int order;
int/*bool*/ skinRequired;
int bonesCount; int bonesCount;
spBoneData** const bones; spBoneData** const bones;
spSlotData* target; spSlotData* target;
@ -65,6 +66,8 @@ typedef struct spPathConstraintData {
#ifdef __cplusplus #ifdef __cplusplus
spPathConstraintData() : spPathConstraintData() :
name(0), name(0),
order(0),
skinRequired(0),
bonesCount(0), bonesCount(0),
bones(0), bones(0),
target(0), target(0),

View File

@ -49,6 +49,9 @@ typedef struct spSkeletonData {
const char* hash; const char* hash;
float x, y, width, height; float x, y, width, height;
int stringsCount;
char** strings;
int bonesCount; int bonesCount;
spBoneData** bones; spBoneData** bones;

View File

@ -46,6 +46,7 @@ typedef struct spTransformConstraint {
spBone** const bones; spBone** const bones;
spBone* target; spBone* target;
float rotateMix, translateMix, scaleMix, shearMix; float rotateMix, translateMix, scaleMix, shearMix;
int /*boolean*/ active;
#ifdef __cplusplus #ifdef __cplusplus
spTransformConstraint() : spTransformConstraint() :
@ -56,7 +57,8 @@ typedef struct spTransformConstraint {
rotateMix(0), rotateMix(0),
translateMix(0), translateMix(0),
scaleMix(0), scaleMix(0),
shearMix(0) { shearMix(0),
active(0) {
} }
#endif #endif
} spTransformConstraint; } spTransformConstraint;

View File

@ -40,6 +40,7 @@ extern "C" {
typedef struct spTransformConstraintData { typedef struct spTransformConstraintData {
const char* const name; const char* const name;
int order; int order;
int/*bool*/ skinRequired;
int bonesCount; int bonesCount;
spBoneData** const bones; spBoneData** const bones;
spBoneData* target; spBoneData* target;
@ -51,6 +52,8 @@ typedef struct spTransformConstraintData {
#ifdef __cplusplus #ifdef __cplusplus
spTransformConstraintData() : spTransformConstraintData() :
name(0), name(0),
order(0),
skinRequired(0),
bonesCount(0), bonesCount(0),
bones(0), bones(0),
target(0), target(0),

View File

@ -245,6 +245,7 @@ void _spRotateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
spRotateTimeline* self = SUB_CAST(spRotateTimeline, timeline); spRotateTimeline* self = SUB_CAST(spRotateTimeline, timeline);
bone = skeleton->bones[self->boneIndex]; bone = skeleton->bones[self->boneIndex];
if (!bone->active) return;
if (time < self->frames[0]) { if (time < self->frames[0]) {
switch (blend) { switch (blend) {
case SP_MIX_BLEND_SETUP: case SP_MIX_BLEND_SETUP:
@ -333,6 +334,7 @@ void _spTranslateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleto
spTranslateTimeline* self = SUB_CAST(spTranslateTimeline, timeline); spTranslateTimeline* self = SUB_CAST(spTranslateTimeline, timeline);
bone = skeleton->bones[self->boneIndex]; bone = skeleton->bones[self->boneIndex];
if (!bone->active) return;
if (time < self->frames[0]) { if (time < self->frames[0]) {
switch (blend) { switch (blend) {
case SP_MIX_BLEND_SETUP: case SP_MIX_BLEND_SETUP:
@ -415,6 +417,7 @@ void _spScaleTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
spScaleTimeline* self = SUB_CAST(spScaleTimeline, timeline); spScaleTimeline* self = SUB_CAST(spScaleTimeline, timeline);
bone = skeleton->bones[self->boneIndex]; bone = skeleton->bones[self->boneIndex];
if (!bone->active) return;
if (time < self->frames[0]) { if (time < self->frames[0]) {
switch (blend) { switch (blend) {
case SP_MIX_BLEND_SETUP: case SP_MIX_BLEND_SETUP:
@ -533,6 +536,7 @@ void _spShearTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
spShearTimeline* self = SUB_CAST(spShearTimeline, timeline); spShearTimeline* self = SUB_CAST(spShearTimeline, timeline);
bone = skeleton->bones[self->boneIndex]; bone = skeleton->bones[self->boneIndex];
if (!bone->active) return;
frames = self->frames; frames = self->frames;
framesCount = self->framesCount; framesCount = self->framesCount;
if (time < self->frames[0]) { if (time < self->frames[0]) {
@ -614,6 +618,7 @@ void _spColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
spColor* setup; spColor* setup;
spColorTimeline* self = (spColorTimeline*)timeline; spColorTimeline* self = (spColorTimeline*)timeline;
slot = skeleton->slots[self->slotIndex]; slot = skeleton->slots[self->slotIndex];
if (!slot->bone->active) return;
if (time < self->frames[0]) { if (time < self->frames[0]) {
switch (blend) { switch (blend) {
@ -706,6 +711,7 @@ void _spTwoColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton
spColor* setupDark; spColor* setupDark;
spColorTimeline* self = (spColorTimeline*)timeline; spColorTimeline* self = (spColorTimeline*)timeline;
slot = skeleton->slots[self->slotIndex]; slot = skeleton->slots[self->slotIndex];
if (!slot->bone->active) return;
if (time < self->frames[0]) { if (time < self->frames[0]) {
switch (blend) { switch (blend) {
@ -809,6 +815,7 @@ void _spAttachmentTimeline_apply (const spTimeline* timeline, spSkeleton* skelet
spAttachmentTimeline* self = (spAttachmentTimeline*)timeline; spAttachmentTimeline* self = (spAttachmentTimeline*)timeline;
int frameIndex; int frameIndex;
spSlot* slot = skeleton->slots[self->slotIndex]; spSlot* slot = skeleton->slots[self->slotIndex];
if (!slot->bone->active) return;
if (direction == SP_MIX_DIRECTION_OUT && blend == SP_MIX_BLEND_SETUP) { if (direction == SP_MIX_DIRECTION_OUT && blend == SP_MIX_BLEND_SETUP) {
attachmentName = slot->data->attachmentName; attachmentName = slot->data->attachmentName;
@ -893,6 +900,7 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
spDeformTimeline* self = (spDeformTimeline*)timeline; spDeformTimeline* self = (spDeformTimeline*)timeline;
spSlot *slot = skeleton->slots[self->slotIndex]; spSlot *slot = skeleton->slots[self->slotIndex];
if (!slot->bone->active) return;
if (!slot->attachment) return; if (!slot->attachment) return;
switch (slot->attachment->type) { switch (slot->attachment->type) {
@ -1295,6 +1303,7 @@ void _spIkConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skel
spIkConstraintTimeline* self = (spIkConstraintTimeline*)timeline; spIkConstraintTimeline* self = (spIkConstraintTimeline*)timeline;
constraint = skeleton->ikConstraints[self->ikConstraintIndex]; constraint = skeleton->ikConstraints[self->ikConstraintIndex];
if (!constraint->active) return;
if (time < self->frames[0]) { if (time < self->frames[0]) {
switch (blend) { switch (blend) {
@ -1410,6 +1419,8 @@ void _spTransformConstraintTimeline_apply (const spTimeline* timeline, spSkeleto
int framesCount; int framesCount;
constraint = skeleton->transformConstraints[self->transformConstraintIndex]; constraint = skeleton->transformConstraints[self->transformConstraintIndex];
if (!constraint->active) return;
if (time < self->frames[0]) { if (time < self->frames[0]) {
spTransformConstraintData* data = constraint->data; spTransformConstraintData* data = constraint->data;
switch (blend) { switch (blend) {
@ -1508,6 +1519,8 @@ void _spPathConstraintPositionTimeline_apply(const spTimeline* timeline, spSkele
int framesCount; int framesCount;
constraint = skeleton->pathConstraints[self->pathConstraintIndex]; constraint = skeleton->pathConstraints[self->pathConstraintIndex];
if (!constraint->active) return;
if (time < self->frames[0]) { if (time < self->frames[0]) {
switch (blend) { switch (blend) {
case SP_MIX_BLEND_SETUP: case SP_MIX_BLEND_SETUP:
@ -1576,6 +1589,8 @@ void _spPathConstraintSpacingTimeline_apply(const spTimeline* timeline, spSkelet
int framesCount; int framesCount;
constraint = skeleton->pathConstraints[self->pathConstraintIndex]; constraint = skeleton->pathConstraints[self->pathConstraintIndex];
if (!constraint->active) return;
if (time < self->frames[0]) { if (time < self->frames[0]) {
switch (blend) { switch (blend) {
case SP_MIX_BLEND_SETUP: case SP_MIX_BLEND_SETUP:
@ -1648,6 +1663,8 @@ void _spPathConstraintMixTimeline_apply(const spTimeline* timeline, spSkeleton*
int framesCount; int framesCount;
constraint = skeleton->pathConstraints[self->pathConstraintIndex]; constraint = skeleton->pathConstraints[self->pathConstraintIndex];
if (!constraint->active) return;
if (time < self->frames[0]) { if (time < self->frames[0]) {
switch (blend) { switch (blend) {
case SP_MIX_BLEND_SETUP: case SP_MIX_BLEND_SETUP:

View File

@ -541,6 +541,7 @@ void _spAnimationState_applyRotateTimeline (spAnimationState* self, spTimeline*
rotateTimeline = SUB_CAST(spRotateTimeline, timeline); rotateTimeline = SUB_CAST(spRotateTimeline, timeline);
frames = rotateTimeline->frames; frames = rotateTimeline->frames;
bone = skeleton->bones[rotateTimeline->boneIndex]; bone = skeleton->bones[rotateTimeline->boneIndex];
if (!bone->active) return;
if (time < frames[0]) { if (time < frames[0]) {
switch (blend) { switch (blend) {
case SP_MIX_BLEND_SETUP: case SP_MIX_BLEND_SETUP:

View File

@ -219,6 +219,7 @@ static void _sortReset(spBone** bones, int bonesCount) {
int i; int i;
for (i = 0; i < bonesCount; ++i) { for (i = 0; i < bonesCount; ++i) {
spBone* bone = bones[i]; spBone* bone = bones[i];
if (!bone->active) continue;
if (bone->sorted) _sortReset(bone->children, bone->childrenCount); if (bone->sorted) _sortReset(bone->children, bone->childrenCount);
bone->sorted = 0; bone->sorted = 0;
} }
@ -230,6 +231,10 @@ static void _sortIkConstraint (_spSkeleton* const internal, spIkConstraint* cons
spBone* target = constraint->target; spBone* target = constraint->target;
spBone** constrained; spBone** constrained;
spBone* parent; spBone* parent;
constraint->active = constraint->target->active && (!constraint->data->skinRequired || (internal->super.skin != 0 && spIkConstraintDataArray_contains(internal->super.skin->ikConstraints, constraint->data)));
if (!constraint->active) return;
_sortBone(internal, target); _sortBone(internal, target);
constrained = constraint->bones; constrained = constraint->bones;
@ -264,6 +269,10 @@ static void _sortPathConstraint(_spSkeleton* const internal, spPathConstraint* c
spAttachment* attachment; spAttachment* attachment;
spBone** constrained; spBone** constrained;
spSkeleton* skeleton = SUPER_CAST(spSkeleton, internal); spSkeleton* skeleton = SUPER_CAST(spSkeleton, internal);
constraint->active = constraint->target->bone->active && (!constraint->data->skinRequired || (internal->super.skin != 0 && spPathConstraintDataArray_contains(internal->super.skin->pathConstraints, constraint->data)));
if (!constraint->active) return;
if (skeleton->skin) _sortPathConstraintAttachment(internal, skeleton->skin, slotIndex, slotBone); if (skeleton->skin) _sortPathConstraintAttachment(internal, skeleton->skin, slotIndex, slotBone);
if (skeleton->data->defaultSkin && skeleton->data->defaultSkin != skeleton->skin) if (skeleton->data->defaultSkin && skeleton->data->defaultSkin != skeleton->skin)
_sortPathConstraintAttachment(internal, skeleton->data->defaultSkin, slotIndex, slotBone); _sortPathConstraintAttachment(internal, skeleton->data->defaultSkin, slotIndex, slotBone);
@ -291,6 +300,10 @@ static void _sortTransformConstraint(_spSkeleton* const internal, spTransformCon
spBone** constrained; spBone** constrained;
spBone* child; spBone* child;
int /*boolean*/ contains = 0; int /*boolean*/ contains = 0;
constraint->active = constraint->target->active && (!constraint->data->skinRequired || (internal->super.skin != 0 && spTransformConstraintDataArray_contains(internal->super.skin->transformConstraints, constraint->data)));
if (!constraint->active) return;
_sortBone(internal, constraint->target); _sortBone(internal, constraint->target);
constrained = constraint->bones; constrained = constraint->bones;
@ -342,8 +355,23 @@ void spSkeleton_updateCache (spSkeleton* self) {
internal->updateCacheResetCount = 0; internal->updateCacheResetCount = 0;
bones = self->bones; bones = self->bones;
for (i = 0; i < self->bonesCount; ++i) for (i = 0; i < self->bonesCount; ++i) {
bones[i]->sorted = 0; spBone* bone = bones[i];
bone->sorted = bone->data->skinRequired;
bone->active = !bone->sorted;
}
if (self->skin) {
spBoneDataArray* skinBones = self->skin->bones;
for(i = 0; i < skinBones->size; i++) {
spBone* bone = self->bones[skinBones->items[i]->index];
do {
bone->sorted = 0;
bone->active = -1;
bone = bone->parent;
} while (bone != 0);
}
}
/* IK first, lowest hierarchy depth first. */ /* IK first, lowest hierarchy depth first. */
ikConstraints = self->ikConstraints; ikConstraints = self->ikConstraints;

View File

@ -74,10 +74,6 @@ void spSkeletonBinary_dispose (spSkeletonBinary* self) {
int i; int i;
_spSkeletonBinary* internal = SUB_CAST(_spSkeletonBinary, self); _spSkeletonBinary* internal = SUB_CAST(_spSkeletonBinary, self);
if (internal->ownsLoader) spAttachmentLoader_dispose(self->attachmentLoader); if (internal->ownsLoader) spAttachmentLoader_dispose(self->attachmentLoader);
for (i = 0; i < internal->linkedMeshCount; ++i) {
FREE(internal->linkedMeshes[i].parent);
FREE(internal->linkedMeshes[i].skin);
}
FREE(internal->linkedMeshes); FREE(internal->linkedMeshes);
FREE(self->error); FREE(self->error);
FREE(self); FREE(self);
@ -147,7 +143,7 @@ float readFloat (_dataInput* input) {
char* readString (_dataInput* input) { char* readString (_dataInput* input) {
int length = readVarint(input, 1); int length = readVarint(input, 1);
char* string; char *string;
if (length == 0) { if (length == 0) {
return 0; return 0;
} }
@ -158,6 +154,11 @@ char* readString (_dataInput* input) {
return string; return string;
} }
static char* readStringRef(_dataInput* input, spSkeletonData* skeletonData) {
int index = readVarint(input, 1);
return index == 0 ? 0 : skeletonData->strings[index - 1];
}
static void readColor (_dataInput* input, float *r, float *g, float *b, float *a) { static void readColor (_dataInput* input, float *r, float *g, float *b, float *a) {
*r = readByte(input) / 255.0f; *r = readByte(input) / 255.0f;
*g = readByte(input) / 255.0f; *g = readByte(input) / 255.0f;
@ -269,10 +270,9 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con
timeline->slotIndex = slotIndex; timeline->slotIndex = slotIndex;
for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) { for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
float time = readFloat(input); float time = readFloat(input);
const char* attachmentName = readString(input); const char* attachmentName = readStringRef(input, skeletonData);
/* TODO Avoid copying of attachmentName inside */ /* TODO Avoid copying of attachmentName inside */
spAttachmentTimeline_setFrame(timeline, frameIndex, time, attachmentName); spAttachmentTimeline_setFrame(timeline, frameIndex, time, attachmentName);
FREE(attachmentName);
} }
spTimelineArray_add(timelines, (spTimeline*)timeline); spTimelineArray_add(timelines, (spTimeline*)timeline);
duration = MAX(duration, timeline->frames[frameCount - 1]); duration = MAX(duration, timeline->frames[frameCount - 1]);
@ -478,7 +478,7 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con
float* tempDeform; float* tempDeform;
spDeformTimeline *timeline; spDeformTimeline *timeline;
int weighted, deformLength; int weighted, deformLength;
const char* attachmentName = readString(input); const char* attachmentName = readStringRef(input, skeletonData);
int frameCount; int frameCount;
spVertexAttachment* attachment = SUB_CAST(spVertexAttachment, spVertexAttachment* attachment = SUB_CAST(spVertexAttachment,
@ -488,10 +488,8 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con
spTimeline_dispose(timelines->items[i]); spTimeline_dispose(timelines->items[i]);
spTimelineArray_dispose(timelines); spTimelineArray_dispose(timelines);
_spSkeletonBinary_setError(self, "Attachment not found: ", attachmentName); _spSkeletonBinary_setError(self, "Attachment not found: ", attachmentName);
FREE(attachmentName);
return 0; return 0;
} }
FREE(attachmentName);
weighted = attachment->bones != 0; weighted = attachment->bones != 0;
deformLength = weighted ? attachment->verticesCount / 3 * 2 : attachment->verticesCount; deformLength = weighted ? attachment->verticesCount / 3 * 2 : attachment->verticesCount;
@ -680,21 +678,22 @@ spAttachment* spSkeletonBinary_readAttachment(spSkeletonBinary* self, _dataInput
spSkin* skin, int slotIndex, const char* attachmentName, spSkeletonData* skeletonData, int/*bool*/ nonessential) { spSkin* skin, int slotIndex, const char* attachmentName, spSkeletonData* skeletonData, int/*bool*/ nonessential) {
int i; int i;
spAttachmentType type; spAttachmentType type;
const char* name = readString(input); const char* name = readStringRef(input, skeletonData);
int freeName = name != 0; if (!name) name = attachmentName;
if (!name) {
freeName = 0;
name = attachmentName;
}
type = (spAttachmentType)readByte(input); type = (spAttachmentType)readByte(input);
switch (type) { switch (type) {
case SP_ATTACHMENT_REGION: { case SP_ATTACHMENT_REGION: {
const char* path = readString(input); const char* path = readStringRef(input, skeletonData);
spAttachment* attachment; spAttachment* attachment;
spRegionAttachment* region; spRegionAttachment* region;
if (!path) MALLOC_STR(path, name); 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); attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, path);
region = SUB_CAST(spRegionAttachment, attachment); region = SUB_CAST(spRegionAttachment, attachment);
region->path = path; region->path = path;
@ -708,7 +707,6 @@ spAttachment* spSkeletonBinary_readAttachment(spSkeletonBinary* self, _dataInput
readColor(input, &region->color.r, &region->color.g, &region->color.b, &region->color.a); readColor(input, &region->color.r, &region->color.g, &region->color.b, &region->color.a);
spRegionAttachment_updateOffset(region); spRegionAttachment_updateOffset(region);
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment); spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
if (freeName) FREE(name);
return attachment; return attachment;
} }
case SP_ATTACHMENT_BOUNDING_BOX: { case SP_ATTACHMENT_BOUNDING_BOX: {
@ -717,15 +715,19 @@ spAttachment* spSkeletonBinary_readAttachment(spSkeletonBinary* self, _dataInput
_readVertices(self, input, SUB_CAST(spVertexAttachment, attachment), vertexCount); _readVertices(self, input, SUB_CAST(spVertexAttachment, attachment), vertexCount);
if (nonessential) readInt(input); /* Skip color. */ if (nonessential) readInt(input); /* Skip color. */
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment); spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
if (freeName) FREE(name);
return attachment; return attachment;
} }
case SP_ATTACHMENT_MESH: { case SP_ATTACHMENT_MESH: {
int vertexCount; int vertexCount;
spAttachment* attachment; spAttachment* attachment;
spMeshAttachment* mesh; spMeshAttachment* mesh;
const char* path = readString(input); const char* path = readStringRef(input, skeletonData);
if (!path) MALLOC_STR(path, name); 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); attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, path);
mesh = SUB_CAST(spMeshAttachment, attachment); mesh = SUB_CAST(spMeshAttachment, attachment);
mesh->path = path; mesh->path = path;
@ -746,7 +748,6 @@ spAttachment* spSkeletonBinary_readAttachment(spSkeletonBinary* self, _dataInput
mesh->height = 0; mesh->height = 0;
} }
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment); spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
if (freeName) FREE(name);
return attachment; return attachment;
} }
case SP_ATTACHMENT_LINKED_MESH: { case SP_ATTACHMENT_LINKED_MESH: {
@ -755,21 +756,25 @@ spAttachment* spSkeletonBinary_readAttachment(spSkeletonBinary* self, _dataInput
spAttachment* attachment; spAttachment* attachment;
spMeshAttachment* mesh; spMeshAttachment* mesh;
int inheritDeform; int inheritDeform;
const char* path = readString(input); const char* path = readStringRef(input, skeletonData);
if (!path) MALLOC_STR(path, name); 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); attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, path);
mesh = SUB_CAST(spMeshAttachment, attachment); mesh = SUB_CAST(spMeshAttachment, attachment);
mesh->path = path; mesh->path = path;
readColor(input, &mesh->color.r, &mesh->color.g, &mesh->color.b, &mesh->color.a); readColor(input, &mesh->color.r, &mesh->color.g, &mesh->color.b, &mesh->color.a);
skinName = readString(input); skinName = readStringRef(input, skeletonData);
parent = readString(input); parent = readStringRef(input, skeletonData);
inheritDeform = readBoolean(input); inheritDeform = readBoolean(input);
if (nonessential) { if (nonessential) {
mesh->width = readFloat(input) * self->scale; mesh->width = readFloat(input) * self->scale;
mesh->height = readFloat(input) * self->scale; mesh->height = readFloat(input) * self->scale;
} }
_spSkeletonBinary_addLinkedMesh(self, mesh, skinName, slotIndex, parent, inheritDeform); _spSkeletonBinary_addLinkedMesh(self, mesh, skinName, slotIndex, parent, inheritDeform);
if (freeName) FREE(name);
return attachment; return attachment;
} }
case SP_ATTACHMENT_PATH: { case SP_ATTACHMENT_PATH: {
@ -786,7 +791,6 @@ spAttachment* spSkeletonBinary_readAttachment(spSkeletonBinary* self, _dataInput
path->lengths[i] = readFloat(input) * self->scale; path->lengths[i] = readFloat(input) * self->scale;
} }
if (nonessential) readInt(input); /* Skip color. */ if (nonessential) readInt(input); /* Skip color. */
if (freeName) FREE(name);
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment); spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
return attachment; return attachment;
} }
@ -812,30 +816,40 @@ spAttachment* spSkeletonBinary_readAttachment(spSkeletonBinary* self, _dataInput
if (nonessential) readInt(input); /* Skip color. */ if (nonessential) readInt(input); /* Skip color. */
clip->endSlot = skeletonData->slots[endSlotIndex]; clip->endSlot = skeletonData->slots[endSlotIndex];
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment); spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
if (freeName) FREE(name);
return attachment; return attachment;
} }
} }
if (freeName) FREE(name);
return 0; return 0;
} }
spSkin* spSkeletonBinary_readSkin(spSkeletonBinary* self, _dataInput* input, spSkin* spSkeletonBinary_readSkin(spSkeletonBinary* self, _dataInput* input, int/*bool*/ defaultSkin,
const char* skinName, spSkeletonData* skeletonData, int/*bool*/ nonessential) { spSkeletonData* skeletonData, int/*bool*/ nonessential) {
spSkin* skin; spSkin* skin;
int slotCount = readVarint(input, 1); int i, n, ii, nn;
int i, ii, nn; const char* skinName = defaultSkin ? "default" : readStringRef(input, skeletonData);
if (slotCount == 0)
return 0;
skin = spSkin_create(skinName); skin = spSkin_create(skinName);
for (i = 0; i < slotCount; ++i) {
if (!defaultSkin) {
for (i = 0, n = readVarint(input, 1); i < n; i++)
spBoneDataArray_add(skin->bones, spSkeletonData_findBone(skeletonData, readVarint(input, 1)));
for (i = 0, n = readVarint(input, 1); i < n; i++)
spIkConstraintDataArray_add(skin->ikConstraints, spSkeletonData_findIkConstraint(skeletonData, readVarint(input, 1)));
for (i = 0, n = readVarint(input, 1); i < n; i++)
spTransformConstraintDataArray_add(skin->transformConstraints, spSkeletonData_findTransformConstraint(skeletonData, readVarint(input, 1)));
for (i = 0, n = readVarint(input, 1); i < n; i++)
spPathConstraintDataArray_add(skin->pathConstraints, spSkeletonData_findPathConstraint(skeletonData, readVarint(input, 1)));
}
for (i = 0, n = readVarint(input, 1); i < n; ++i) {
int slotIndex = readVarint(input, 1); int slotIndex = readVarint(input, 1);
for (ii = 0, nn = readVarint(input, 1); ii < nn; ++ii) { for (ii = 0, nn = readVarint(input, 1); ii < nn; ++ii) {
const char* name = readString(input); const char* name = readStringRef(input, skeletonData);
spAttachment* attachment = spSkeletonBinary_readAttachment(self, input, skin, slotIndex, name, skeletonData, nonessential); spAttachment* attachment = spSkeletonBinary_readAttachment(self, input, skin, slotIndex, name, skeletonData, nonessential);
if (attachment) spSkin_setAttachment(skin, slotIndex, name, attachment); if (attachment) spSkin_setAttachment(skin, slotIndex, name, attachment);
FREE(name);
} }
} }
return skin; return skin;
@ -856,7 +870,7 @@ spSkeletonData* spSkeletonBinary_readSkeletonDataFile (spSkeletonBinary* self, c
spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const unsigned char* binary, spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const unsigned char* binary,
const int length) { const int length) {
int i, ii, nonessential; int i, n, ii, nonessential;
spSkeletonData* skeletonData; spSkeletonData* skeletonData;
_spSkeletonBinary* internal = SUB_CAST(_spSkeletonBinary, self); _spSkeletonBinary* internal = SUB_CAST(_spSkeletonBinary, self);
@ -896,6 +910,12 @@ spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const
FREE(readString(input)); FREE(readString(input));
} }
skeletonData->stringsCount = n = readVarint(input, 1);
skeletonData->strings = MALLOC(char*, skeletonData->stringsCount);
for (i = 0; i < n; i++) {
skeletonData->strings[i] = readString(input);
}
/* Bones. */ /* Bones. */
skeletonData->bonesCount = readVarint(input, 1); skeletonData->bonesCount = readVarint(input, 1);
skeletonData->bones = MALLOC(spBoneData*, skeletonData->bonesCount); skeletonData->bones = MALLOC(spBoneData*, skeletonData->bonesCount);
@ -923,6 +943,7 @@ spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const
case 3: data->transformMode = SP_TRANSFORMMODE_NOSCALE; break; case 3: data->transformMode = SP_TRANSFORMMODE_NOSCALE; break;
case 4: data->transformMode = SP_TRANSFORMMODE_NOSCALEORREFLECTION; break; case 4: data->transformMode = SP_TRANSFORMMODE_NOSCALEORREFLECTION; break;
} }
data->skinRequired = readBoolean(input);
if (nonessential) readInt(input); /* Skip bone color. */ if (nonessential) readInt(input); /* Skip bone color. */
skeletonData->bones[i] = data; skeletonData->bones[i] = data;
} }
@ -932,6 +953,7 @@ spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const
skeletonData->slots = MALLOC(spSlotData*, skeletonData->slotsCount); skeletonData->slots = MALLOC(spSlotData*, skeletonData->slotsCount);
for (i = 0; i < skeletonData->slotsCount; ++i) { for (i = 0; i < skeletonData->slotsCount; ++i) {
int r, g, b, a; int r, g, b, a;
const char* attachmentName;
const char* slotName = readString(input); const char* slotName = readString(input);
spBoneData* boneData = skeletonData->bones[readVarint(input, 1)]; spBoneData* boneData = skeletonData->bones[readVarint(input, 1)];
/* TODO Avoid copying of slotName */ /* TODO Avoid copying of slotName */
@ -946,7 +968,9 @@ spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const
slotData->darkColor = spColor_create(); slotData->darkColor = spColor_create();
spColor_setFromFloats(slotData->darkColor, r / 255.0f, g / 255.0f, b / 255.0f, 1); spColor_setFromFloats(slotData->darkColor, r / 255.0f, g / 255.0f, b / 255.0f, 1);
} }
slotData->attachmentName = readString(input); attachmentName = readStringRef(input, skeletonData);
if (attachmentName) MALLOC_STR(slotData->attachmentName, attachmentName);
else slotData->attachmentName = 0;
slotData->blendMode = (spBlendMode)readVarint(input, 1); slotData->blendMode = (spBlendMode)readVarint(input, 1);
skeletonData->slots[i] = slotData; skeletonData->slots[i] = slotData;
} }
@ -959,6 +983,7 @@ spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const
/* TODO Avoid copying of name */ /* TODO Avoid copying of name */
spIkConstraintData* data = spIkConstraintData_create(name); spIkConstraintData* data = spIkConstraintData_create(name);
data->order = readVarint(input, 1); data->order = readVarint(input, 1);
data->skinRequired = readBoolean(input);
FREE(name); FREE(name);
data->bonesCount = readVarint(input, 1); data->bonesCount = readVarint(input, 1);
data->bones = MALLOC(spBoneData*, data->bonesCount); data->bones = MALLOC(spBoneData*, data->bonesCount);
@ -982,6 +1007,7 @@ spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const
/* TODO Avoid copying of name */ /* TODO Avoid copying of name */
spTransformConstraintData* data = spTransformConstraintData_create(name); spTransformConstraintData* data = spTransformConstraintData_create(name);
data->order = readVarint(input, 1); data->order = readVarint(input, 1);
data->skinRequired = readBoolean(input);
FREE(name); FREE(name);
data->bonesCount = readVarint(input, 1); data->bonesCount = readVarint(input, 1);
CONST_CAST(spBoneData**, data->bones) = MALLOC(spBoneData*, data->bonesCount); CONST_CAST(spBoneData**, data->bones) = MALLOC(spBoneData*, data->bonesCount);
@ -1011,6 +1037,7 @@ spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const
/* TODO Avoid copying of name */ /* TODO Avoid copying of name */
spPathConstraintData* data = spPathConstraintData_create(name); spPathConstraintData* data = spPathConstraintData_create(name);
data->order = readVarint(input, 1); data->order = readVarint(input, 1);
data->skinRequired = readBoolean(input);
FREE(name); FREE(name);
data->bonesCount = readVarint(input, 1); data->bonesCount = readVarint(input, 1);
CONST_CAST(spBoneData**, data->bones) = MALLOC(spBoneData*, data->bonesCount); CONST_CAST(spBoneData**, data->bones) = MALLOC(spBoneData*, data->bonesCount);
@ -1031,7 +1058,7 @@ spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const
} }
/* Default skin. */ /* Default skin. */
skeletonData->defaultSkin = spSkeletonBinary_readSkin(self, input, "default", skeletonData, nonessential); skeletonData->defaultSkin = spSkeletonBinary_readSkin(self, input, -1, skeletonData, nonessential);
skeletonData->skinsCount = readVarint(input, 1); skeletonData->skinsCount = readVarint(input, 1);
if (skeletonData->defaultSkin) if (skeletonData->defaultSkin)
@ -1044,10 +1071,7 @@ spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const
/* Skins. */ /* Skins. */
for (i = skeletonData->defaultSkin ? 1 : 0; i < skeletonData->skinsCount; ++i) { for (i = skeletonData->defaultSkin ? 1 : 0; i < skeletonData->skinsCount; ++i) {
const char* skinName = readString(input); skeletonData->skins[i] = spSkeletonBinary_readSkin(self, input, 0, skeletonData, nonessential);
/* TODO Avoid copying of skinName */
skeletonData->skins[i] = spSkeletonBinary_readSkin(self, input, skinName, skeletonData, nonessential);
FREE(skinName);
} }
/* Linked meshes. */ /* Linked meshes. */
@ -1078,10 +1102,8 @@ spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const
skeletonData->eventsCount = readVarint(input, 1); skeletonData->eventsCount = readVarint(input, 1);
skeletonData->events = MALLOC(spEventData*, skeletonData->eventsCount); skeletonData->events = MALLOC(spEventData*, skeletonData->eventsCount);
for (i = 0; i < skeletonData->eventsCount; ++i) { for (i = 0; i < skeletonData->eventsCount; ++i) {
const char* name = readString(input); const char* name = readStringRef(input, skeletonData);
/* TODO Avoid copying of skinName */
spEventData* eventData = spEventData_create(name); spEventData* eventData = spEventData_create(name);
FREE(name);
eventData->intValue = readVarint(input, 0); eventData->intValue = readVarint(input, 0);
eventData->floatValue = readFloat(input); eventData->floatValue = readFloat(input);
eventData->stringValue = readString(input); eventData->stringValue = readString(input);

View File

@ -37,6 +37,11 @@ spSkeletonData* spSkeletonData_create () {
void spSkeletonData_dispose (spSkeletonData* self) { void spSkeletonData_dispose (spSkeletonData* self) {
int i; int i;
for (i = 0; i < self->stringsCount; ++i)
FREE(self->strings[i]);
FREE(self->strings);
for (i = 0; i < self->bonesCount; ++i) for (i = 0; i < self->bonesCount; ++i)
spBoneData_dispose(self->bones[i]); spBoneData_dispose(self->bones[i]);
FREE(self->bones); FREE(self->bones);

View File

@ -110,13 +110,12 @@ static void readCurve (Json* frame, spCurveTimeline* timeline, int frameIndex) {
if (!curve) return; if (!curve) return;
if (curve->type == Json_String && strcmp(curve->valueString, "stepped") == 0) if (curve->type == Json_String && strcmp(curve->valueString, "stepped") == 0)
spCurveTimeline_setStepped(timeline, frameIndex); spCurveTimeline_setStepped(timeline, frameIndex);
else if (curve->type == Json_Array) { else {
Json* child0 = curve->child; float c1 = Json_getFloat(frame, "curve", 0);
Json* child1 = child0->next; float c2 = Json_getFloat(frame, "c2", 0);
Json* child2 = child1->next; float c3 = Json_getFloat(frame, "c3", 1);
Json* child3 = child2->next; float c4 = Json_getFloat(frame, "c4", 1);
spCurveTimeline_setCurve(timeline, frameIndex, child0->valueFloat, child1->valueFloat, child2->valueFloat, spCurveTimeline_setCurve(timeline, frameIndex, c1, c2, c3, c4);
child3->valueFloat);
} }
} }
@ -264,16 +263,20 @@ static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* r
int isTranslate = strcmp(timelineMap->name, "translate") == 0; int isTranslate = strcmp(timelineMap->name, "translate") == 0;
int isShear = strcmp(timelineMap->name, "shear") == 0; int isShear = strcmp(timelineMap->name, "shear") == 0;
if (isScale || isTranslate || isShear) { if (isScale || isTranslate || isShear) {
float defaultValue = 0;
float timelineScale = isTranslate ? self->scale: 1; float timelineScale = isTranslate ? self->scale: 1;
spTranslateTimeline *timeline = 0; spTranslateTimeline *timeline = 0;
if (isScale) timeline = spScaleTimeline_create(timelineMap->size); if (isScale) {
timeline = spScaleTimeline_create(timelineMap->size);
defaultValue = 1;
}
else if (isTranslate) timeline = spTranslateTimeline_create(timelineMap->size); else if (isTranslate) timeline = spTranslateTimeline_create(timelineMap->size);
else if (isShear) timeline = spShearTimeline_create(timelineMap->size); else if (isShear) timeline = spShearTimeline_create(timelineMap->size);
timeline->boneIndex = boneIndex; timeline->boneIndex = boneIndex;
for (valueMap = timelineMap->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) { for (valueMap = timelineMap->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) {
spTranslateTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0), Json_getFloat(valueMap, "x", 0) * timelineScale, spTranslateTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0), Json_getFloat(valueMap, "x", defaultValue) * timelineScale,
Json_getFloat(valueMap, "y", 0) * timelineScale); Json_getFloat(valueMap, "y", defaultValue) * timelineScale);
readCurve(valueMap, SUPER(timeline), frameIndex); readCurve(valueMap, SUPER(timeline), frameIndex);
} }
animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline); animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
@ -648,6 +651,7 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
data->transformMode = SP_TRANSFORMMODE_NOSCALE; data->transformMode = SP_TRANSFORMMODE_NOSCALE;
if (strcmp(transformMode, "noScaleOrReflection") == 0) if (strcmp(transformMode, "noScaleOrReflection") == 0)
data->transformMode = SP_TRANSFORMMODE_NOSCALEORREFLECTION; data->transformMode = SP_TRANSFORMMODE_NOSCALEORREFLECTION;
data->skinRequired = Json_getInt(boneMap, "skin", 0) ? 1 : 0;
skeletonData->bones[i] = data; skeletonData->bones[i] = data;
skeletonData->bonesCount++; skeletonData->bonesCount++;
@ -722,6 +726,7 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
spIkConstraintData* data = spIkConstraintData_create(Json_getString(constraintMap, "name", 0)); spIkConstraintData* data = spIkConstraintData_create(Json_getString(constraintMap, "name", 0));
data->order = Json_getInt(constraintMap, "order", 0); data->order = Json_getInt(constraintMap, "order", 0);
data->skinRequired = Json_getInt(constraintMap, "skin", 0) ? 1 : 0;
boneMap = Json_getItem(constraintMap, "bones"); boneMap = Json_getItem(constraintMap, "bones");
data->bonesCount = boneMap->size; data->bonesCount = boneMap->size;
@ -764,6 +769,7 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
spTransformConstraintData* data = spTransformConstraintData_create(Json_getString(constraintMap, "name", 0)); spTransformConstraintData* data = spTransformConstraintData_create(Json_getString(constraintMap, "name", 0));
data->order = Json_getInt(constraintMap, "order", 0); data->order = Json_getInt(constraintMap, "order", 0);
data->skinRequired = Json_getInt(constraintMap, "skin", 0) ? 1 : 0;
boneMap = Json_getItem(constraintMap, "bones"); boneMap = Json_getItem(constraintMap, "bones");
data->bonesCount = boneMap->size; data->bonesCount = boneMap->size;
@ -815,6 +821,7 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
spPathConstraintData* data = spPathConstraintData_create(Json_getString(constraintMap, "name", 0)); spPathConstraintData* data = spPathConstraintData_create(Json_getString(constraintMap, "name", 0));
data->order = Json_getInt(constraintMap, "order", 0); data->order = Json_getInt(constraintMap, "order", 0);
data->skinRequired = Json_getInt(constraintMap, "skin", 0) ? 1 : 0;
boneMap = Json_getItem(constraintMap, "bones"); boneMap = Json_getItem(constraintMap, "bones");
data->bonesCount = boneMap->size; data->bonesCount = boneMap->size;
@ -870,13 +877,66 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
for (skinMap = skins->child, i = 0; skinMap; skinMap = skinMap->next, ++i) { for (skinMap = skins->child, i = 0; skinMap; skinMap = skinMap->next, ++i) {
Json *attachmentsMap; Json *attachmentsMap;
Json *curves; Json *curves;
spSkin *skin = spSkin_create(skinMap->name); Json *skinPart;
spSkin *skin = spSkin_create(Json_getString(skinMap, "name", ""));
skinPart = Json_getItem(skinMap, "bones");
if (skinPart) {
for(skinPart = skinPart->child; skinPart; skinPart = skinPart->next) {
spBoneData* bone = spSkeletonData_findBone(skeletonData, skinPart->valueString);
if (!bone) {
spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, root, "Skin bone constraint not found: ", skinPart->valueString);
return 0;
}
spBoneDataArray_add(skin->bones, bone);
}
}
skinPart = Json_getItem(skinMap, "ik");
if (skinPart) {
for(skinPart = skinPart->child; skinPart; skinPart = skinPart->next) {
spIkConstraintData* constraint = spSkeletonData_findIkConstraint(skeletonData, skinPart->valueString);
if (!constraint) {
spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, root, "Skin IK constraint not found: ", skinPart->valueString);
return 0;
}
spIkConstraintDataArray_add(skin->ikConstraints, constraint);
}
}
skinPart = Json_getItem(skinMap, "path");
if (skinPart) {
for(skinPart = skinPart->child; skinPart; skinPart = skinPart->next) {
spPathConstraintData* constraint = spSkeletonData_findPathConstraint(skeletonData, skinPart->valueString);
if (!constraint) {
spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, root, "Skin path constraint not found: ", skinPart->valueString);
return 0;
}
spPathConstraintDataArray_add(skin->pathConstraints, constraint);
}
}
skinPart = Json_getItem(skinMap, "transform");
if (skinPart) {
for(skinPart = skinPart->child; skinPart; skinPart = skinPart->next) {
spTransformConstraintData* constraint = spSkeletonData_findTransformConstraint(skeletonData, skinPart->valueString);
if (!constraint) {
spSkeletonData_dispose(skeletonData);
_spSkeletonJson_setError(self, root, "Skin transform constraint not found: ", skinPart->valueString);
return 0;
}
spTransformConstraintDataArray_add(skin->transformConstraints, constraint);
}
}
skeletonData->skins[skeletonData->skinsCount++] = skin; skeletonData->skins[skeletonData->skinsCount++] = skin;
if (strcmp(skinMap->name, "default") == 0) skeletonData->defaultSkin = skin; if (strcmp(skin->name, "default") == 0) skeletonData->defaultSkin = skin;
for (attachmentsMap = skinMap->child; attachmentsMap; attachmentsMap = attachmentsMap->next) { for (attachmentsMap = Json_getItem(skinMap, "attachments")->child; attachmentsMap; attachmentsMap = attachmentsMap->next) {
int slotIndex = spSkeletonData_findSlotIndex(skeletonData, attachmentsMap->name); spSlotData* slot = spSkeletonData_findSlot(skeletonData, attachmentsMap->name);
Json *attachmentMap; Json *attachmentMap;
for (attachmentMap = attachmentsMap->child; attachmentMap; attachmentMap = attachmentMap->next) { for (attachmentMap = attachmentsMap->child; attachmentMap; attachmentMap = attachmentMap->next) {
@ -995,7 +1055,7 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment); spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
} else { } else {
int 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, _spSkeletonJson_addLinkedMesh(self, SUB_CAST(spMeshAttachment, attachment), Json_getString(attachmentMap, "skin", 0), slot->index,
entry->valueString, inheritDeform); entry->valueString, inheritDeform);
} }
break; break;
@ -1046,8 +1106,8 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
int vertexCount = 0; int vertexCount = 0;
const char* end = Json_getString(attachmentMap, "end", 0); const char* end = Json_getString(attachmentMap, "end", 0);
if (end) { if (end) {
spSlotData* slot = spSkeletonData_findSlot(skeletonData, end); spSlotData* endSlot = spSkeletonData_findSlot(skeletonData, end);
clip->endSlot = slot; clip->endSlot = endSlot;
} }
vertexCount = Json_getInt(attachmentMap, "vertexCount", 0) << 1; vertexCount = Json_getInt(attachmentMap, "vertexCount", 0) << 1;
_readVertices(self, attachmentMap, SUPER(clip), vertexCount); _readVertices(self, attachmentMap, SUPER(clip), vertexCount);
@ -1056,7 +1116,7 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
} }
} }
spSkin_setAttachment(skin, slotIndex, skinAttachmentName, attachment); spSkin_setAttachment(skin, slot->index, skinAttachmentName, attachment);
} }
} }
} }