|
@@ -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);
|