mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-09 08:38:43 +08:00
[c] Ported skin bones/constraints changes. See #1346.
This commit is contained in:
parent
8cd53746ad
commit
d9161d2020
@ -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
|
||||
};
|
||||
|
||||
@ -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
|
||||
};
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -49,6 +49,9 @@ typedef struct spSkeletonData {
|
||||
const char* hash;
|
||||
float x, y, width, height;
|
||||
|
||||
int stringsCount;
|
||||
char** strings;
|
||||
|
||||
int bonesCount;
|
||||
spBoneData** bones;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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, ®ion->color.r, ®ion->color.g, ®ion->color.b, ®ion->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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user