[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;
int/*bool*/ sorted;
int/*bool*/ active;
#ifdef __cplusplus
spBone() :
@ -68,7 +69,7 @@ struct spBone {
a(0), b(0), worldX(0),
c(0), d(0), worldY(0),
sorted(0) {
sorted(0), active(0) {
}
#endif
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -219,6 +219,7 @@ static void _sortReset(spBone** bones, int bonesCount) {
int i;
for (i = 0; i < bonesCount; ++i) {
spBone* bone = bones[i];
if (!bone->active) continue;
if (bone->sorted) _sortReset(bone->children, bone->childrenCount);
bone->sorted = 0;
}
@ -230,6 +231,10 @@ static void _sortIkConstraint (_spSkeleton* const internal, spIkConstraint* cons
spBone* target = constraint->target;
spBone** constrained;
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);
constrained = constraint->bones;
@ -264,6 +269,10 @@ static void _sortPathConstraint(_spSkeleton* const internal, spPathConstraint* c
spAttachment* attachment;
spBone** constrained;
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->data->defaultSkin && skeleton->data->defaultSkin != skeleton->skin)
_sortPathConstraintAttachment(internal, skeleton->data->defaultSkin, slotIndex, slotBone);
@ -291,6 +300,10 @@ static void _sortTransformConstraint(_spSkeleton* const internal, spTransformCon
spBone** constrained;
spBone* child;
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);
constrained = constraint->bones;
@ -342,8 +355,23 @@ void spSkeleton_updateCache (spSkeleton* self) {
internal->updateCacheResetCount = 0;
bones = self->bones;
for (i = 0; i < self->bonesCount; ++i)
bones[i]->sorted = 0;
for (i = 0; i < self->bonesCount; ++i) {
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. */
ikConstraints = self->ikConstraints;

View File

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

View File

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

View File

@ -110,13 +110,12 @@ static void readCurve (Json* frame, spCurveTimeline* timeline, int frameIndex) {
if (!curve) return;
if (curve->type == Json_String && strcmp(curve->valueString, "stepped") == 0)
spCurveTimeline_setStepped(timeline, frameIndex);
else if (curve->type == Json_Array) {
Json* child0 = curve->child;
Json* child1 = child0->next;
Json* child2 = child1->next;
Json* child3 = child2->next;
spCurveTimeline_setCurve(timeline, frameIndex, child0->valueFloat, child1->valueFloat, child2->valueFloat,
child3->valueFloat);
else {
float c1 = Json_getFloat(frame, "curve", 0);
float c2 = Json_getFloat(frame, "c2", 0);
float c3 = Json_getFloat(frame, "c3", 1);
float c4 = Json_getFloat(frame, "c4", 1);
spCurveTimeline_setCurve(timeline, frameIndex, c1, c2, c3, c4);
}
}
@ -264,16 +263,20 @@ static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* r
int isTranslate = strcmp(timelineMap->name, "translate") == 0;
int isShear = strcmp(timelineMap->name, "shear") == 0;
if (isScale || isTranslate || isShear) {
float defaultValue = 0;
float timelineScale = isTranslate ? self->scale: 1;
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 (isShear) timeline = spShearTimeline_create(timelineMap->size);
timeline->boneIndex = boneIndex;
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,
Json_getFloat(valueMap, "y", 0) * timelineScale);
spTranslateTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0), Json_getFloat(valueMap, "x", defaultValue) * timelineScale,
Json_getFloat(valueMap, "y", defaultValue) * timelineScale);
readCurve(valueMap, SUPER(timeline), frameIndex);
}
animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
@ -648,6 +651,7 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
data->transformMode = SP_TRANSFORMMODE_NOSCALE;
if (strcmp(transformMode, "noScaleOrReflection") == 0)
data->transformMode = SP_TRANSFORMMODE_NOSCALEORREFLECTION;
data->skinRequired = Json_getInt(boneMap, "skin", 0) ? 1 : 0;
skeletonData->bones[i] = data;
skeletonData->bonesCount++;
@ -722,6 +726,7 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
spIkConstraintData* data = spIkConstraintData_create(Json_getString(constraintMap, "name", 0));
data->order = Json_getInt(constraintMap, "order", 0);
data->skinRequired = Json_getInt(constraintMap, "skin", 0) ? 1 : 0;
boneMap = Json_getItem(constraintMap, "bones");
data->bonesCount = boneMap->size;
@ -764,6 +769,7 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
spTransformConstraintData* data = spTransformConstraintData_create(Json_getString(constraintMap, "name", 0));
data->order = Json_getInt(constraintMap, "order", 0);
data->skinRequired = Json_getInt(constraintMap, "skin", 0) ? 1 : 0;
boneMap = Json_getItem(constraintMap, "bones");
data->bonesCount = boneMap->size;
@ -815,6 +821,7 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
spPathConstraintData* data = spPathConstraintData_create(Json_getString(constraintMap, "name", 0));
data->order = Json_getInt(constraintMap, "order", 0);
data->skinRequired = Json_getInt(constraintMap, "skin", 0) ? 1 : 0;
boneMap = Json_getItem(constraintMap, "bones");
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) {
Json *attachmentsMap;
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;
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) {
int slotIndex = spSkeletonData_findSlotIndex(skeletonData, attachmentsMap->name);
for (attachmentsMap = Json_getItem(skinMap, "attachments")->child; attachmentsMap; attachmentsMap = attachmentsMap->next) {
spSlotData* slot = spSkeletonData_findSlot(skeletonData, attachmentsMap->name);
Json *attachmentMap;
for (attachmentMap = attachmentsMap->child; attachmentMap; attachmentMap = attachmentMap->next) {
@ -995,7 +1055,7 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
} else {
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);
}
break;
@ -1046,8 +1106,8 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
int vertexCount = 0;
const char* end = Json_getString(attachmentMap, "end", 0);
if (end) {
spSlotData* slot = spSkeletonData_findSlot(skeletonData, end);
clip->endSlot = slot;
spSlotData* endSlot = spSkeletonData_findSlot(skeletonData, end);
clip->endSlot = endSlot;
}
vertexCount = Json_getInt(attachmentMap, "vertexCount", 0) << 1;
_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);
}
}
}