diff --git a/spine-c/include/spine/SkeletonBinary.h b/spine-c/include/spine/SkeletonBinary.h new file mode 100644 index 000000000..cbdf1f0f4 --- /dev/null +++ b/spine-c/include/spine/SkeletonBinary.h @@ -0,0 +1,72 @@ +/****************************************************************************** + * Spine Runtimes Software License + * Version 2.3 + * + * Copyright (c) 2013-2016, Esoteric Software + * All rights reserved. + * + * You are granted a perpetual, non-exclusive, non-sublicensable and + * non-transferable license to use, install, execute and perform the Spine + * Runtimes Software (the "Software") and derivative works solely for personal + * or internal use. Without the written permission of Esoteric Software (see + * Section 2 of the Spine Software License Agreement), you may not (a) modify, + * translate, adapt or otherwise create derivative works, improvements of the + * Software or develop new applications using the Software or (b) remove, + * delete, alter or obscure any trademarks or any copyright, trademark, patent + * or other intellectual property or proprietary rights notices on or in the + * Software, including any copy thereof. Redistributions in binary or source + * form must include this license and terms. + * + * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#ifndef SPINE_SKELETONBINARY_H_ +#define SPINE_SKELETONBINARY_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct spAtlasAttachmentLoader; + +typedef struct spSkeletonBinary { + float scale; + spAttachmentLoader* attachmentLoader; + const char* const error; +} spSkeletonBinary; + +spSkeletonBinary* spSkeletonBinary_createWithLoader (spAttachmentLoader* attachmentLoader); +spSkeletonBinary* spSkeletonBinary_create (spAtlas* atlas); +void spSkeletonBinary_dispose (spSkeletonBinary* self); + +spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const unsigned char* binary, const int length); +spSkeletonData* spSkeletonBinary_readSkeletonDataFile (spSkeletonBinary* self, const char* path); + +#ifdef SPINE_SHORT_NAMES +typedef spSkeletonBinary SkeletonBinary; +#define SkeletonBinary_createWithLoader(...) spSkeletonBinary_createWithLoader(__VA_ARGS__) +#define SkeletonBinary_create(...) spSkeletonBinary_create(__VA_ARGS__) +#define SkeletonBinary_dispose(...) spSkeletonBinary_dispose(__VA_ARGS__) +#define SkeletonBinary_readSkeletonData(...) spSkeletonBinary_readSkeletonData(__VA_ARGS__) +#define SkeletonBinary_readSkeletonDataFile(...) spSkeletonBinary_readSkeletonDataFile(__VA_ARGS__) +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SPINE_SKELETONBINARY_H_ */ diff --git a/spine-c/include/spine/spine.h b/spine-c/include/spine/spine.h index c5ff57434..704e89407 100644 --- a/spine-c/include/spine/spine.h +++ b/spine-c/include/spine/spine.h @@ -48,6 +48,7 @@ #include #include #include +#include #include #include #include diff --git a/spine-c/src/spine/SkeletonBinary.c b/spine-c/src/spine/SkeletonBinary.c new file mode 100644 index 000000000..c8161ec8d --- /dev/null +++ b/spine-c/src/spine/SkeletonBinary.c @@ -0,0 +1,1014 @@ +/****************************************************************************** + * Spine Runtimes Software License + * Version 2.3 + * + * Copyright (c) 2013-2015, Esoteric Software + * All rights reserved. + * + * You are granted a perpetual, non-exclusive, non-sublicensable and + * non-transferable license to use, install, execute and perform the Spine + * Runtimes Software (the "Software") and derivative works solely for personal + * or internal use. Without the written permission of Esoteric Software (see + * Section 2 of the Spine Software License Agreement), you may not (a) modify, + * translate, adapt or otherwise create derivative works, improvements of the + * Software or develop new applications using the Software or (b) remove, + * delete, alter or obscure any trademarks or any copyright, trademark, patent + * or other intellectual property or proprietary rights notices on or in the + * Software, including any copy thereof. Redistributions in binary or source + * form must include this license and terms. + * + * THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include "kvec.h" + +typedef struct { + const unsigned char* cursor; + const unsigned char* end; +} _dataInput; + +typedef struct { + const char* parent; + const char* skin; + int slotIndex; + spMeshAttachment* mesh; +} _spLinkedMesh; + +typedef struct { + spSkeletonBinary super; + int ownsLoader; + + int linkedMeshCount; + int linkedMeshCapacity; + _spLinkedMesh* linkedMeshes; +} _spSkeletonBinary; + +spSkeletonBinary* spSkeletonBinary_createWithLoader (spAttachmentLoader* attachmentLoader) { + spSkeletonBinary* self = SUPER(NEW(_spSkeletonBinary)); + self->scale = 1; + self->attachmentLoader = attachmentLoader; + return self; +} + +spSkeletonBinary* spSkeletonBinary_create (spAtlas* atlas) { + spAtlasAttachmentLoader* attachmentLoader = spAtlasAttachmentLoader_create(atlas); + spSkeletonBinary* self = spSkeletonBinary_createWithLoader(SUPER(attachmentLoader)); + SUB_CAST(_spSkeletonBinary, self)->ownsLoader = 1; + return self; +} + +void spSkeletonBinary_dispose (spSkeletonBinary* self) { + _spSkeletonBinary* internal = SUB_CAST(_spSkeletonBinary, self); + if (internal->ownsLoader) spAttachmentLoader_dispose(self->attachmentLoader); + FREE(internal->linkedMeshes); + FREE(self->error); + FREE(self); +} + +void _spSkeletonBinary_setError (spSkeletonBinary* self, const char* value1, const char* value2) { + char message[256]; + int length; + FREE(self->error); + strcpy(message, value1); + length = (int)strlen(value1); + if (value2) strncat(message + length, value2, 255 - length); + MALLOC_STR(self->error, message); +} + +static unsigned char readByte (_dataInput* input) { + return *input->cursor++; +} + +static char readSByte (_dataInput* input) { + return (char)readByte(input); +} + +static int readBoolean (_dataInput* input) { + return readByte(input) != 0; +} + +static int readInt (_dataInput* input) { + int result = readByte(input); + result <<= 8; + result |= readByte(input); + result <<= 8; + result |= readByte(input); + result <<= 8; + result |= readByte(input); + return result; +} + +static int readVarint (_dataInput* input, int/*bool*/optimizePositive) { + unsigned char b = readByte(input); + int value = b & 0x7F; + if (b & 0x80) { + b = readByte(input); + value |= (b & 0x7F) << 7; + if (b & 0x80) { + b = readByte(input); + value |= (b & 0x7F) << 14; + if (b & 0x80) { + b = readByte(input); + value |= (b & 0x7F) << 21; + if (b & 0x80) value |= (readByte(input) & 0x7F) << 28; + } + } + } + if (!optimizePositive) value = (((unsigned int)value >> 1) ^ -(value & 1)); + return value; +} + +float readFloat (_dataInput* input) { + union { + int intValue; + float floatValue; + } intToFloat; + intToFloat.intValue = readInt(input); + return intToFloat.floatValue; +} + +char* readString (_dataInput* input) { + int length = readVarint(input, 1); + char* string; + if (length == 0) { + return 0; + } + string = MALLOC(char, length); + memcpy(string, input->cursor, length - 1); + input->cursor += length - 1; + string[length - 1] = '\0'; + return string; +} + +static void readColor (_dataInput* input, float *r, float *g, float *b, float *a) { + *r = readByte(input) / 255.0f; + *g = readByte(input) / 255.0f; + *b = readByte(input) / 255.0f; + *a = readByte(input) / 255.0f; +} + +#define ATTACHMENT_REGION 0 +#define ATTACHMENT_BOUNDING_BOX 1 +#define ATTACHMENT_MESH 2 +#define ATTACHMENT_LINKED_MESH 3 +#define ATTACHMENT_PATH 4 + +#define BLEND_MODE_NORMAL 0 +#define BLEND_MODE_ADDITIVE 1 +#define BLEND_MODE_MULTIPLY 2 +#define BLEND_MODE_SCREEN 3 + +#define CURVE_LINEAR 0 +#define CURVE_STEPPED 1 +#define CURVE_BEZIER 2 + +#define BONE_ROTATE 0 +#define BONE_TRANSLATE 1 +#define BONE_SCALE 2 +#define BONE_SHEAR 3 + +#define SLOT_ATTACHMENT 0 +#define SLOT_COLOR 1 + +#define PATH_POSITION 0 +#define PATH_SPACING 1 +#define PATH_MIX 2 + +#define PATH_POSITION_FIXED 0 +#define PATH_POSITION_PERCENT 1 + +#define PATH_SPACING_LENGTH 0 +#define PATH_SPACING_FIXED 1 +#define PATH_SPACING_PERCENT 2 + +#define PATH_ROTATE_TANGENT 0 +#define PATH_ROTATE_CHAIN 1 +#define PATH_ROTATE_CHAIN_SCALE 2 + +static void readCurve (_dataInput* input, spCurveTimeline* timeline, int frameIndex) { + switch (readByte(input)) { + case CURVE_STEPPED: { + spCurveTimeline_setStepped(timeline, frameIndex); + break; + } + case CURVE_BEZIER: { + float cx1 = readFloat(input); + float cy1 = readFloat(input); + float cx2 = readFloat(input); + float cy2 = readFloat(input); + spCurveTimeline_setCurve(timeline, frameIndex, cx1, cy1, cx2, cy2); + break; + } + } +} + +static void _spSkeletonBinary_addLinkedMesh (spSkeletonBinary* self, spMeshAttachment* mesh, + const char* skin, int slotIndex, const char* parent) { + _spLinkedMesh* linkedMesh; + _spSkeletonBinary* internal = SUB_CAST(_spSkeletonBinary, self); + + if (internal->linkedMeshCount == internal->linkedMeshCapacity) { + _spLinkedMesh* linkedMeshes; + internal->linkedMeshCapacity *= 2; + if (internal->linkedMeshCapacity < 8) internal->linkedMeshCapacity = 8; + /* TODO Why not realloc? */ + linkedMeshes = MALLOC(_spLinkedMesh, internal->linkedMeshCapacity); + memcpy(linkedMeshes, internal->linkedMeshes, sizeof(_spLinkedMesh) * internal->linkedMeshCount); + FREE(internal->linkedMeshes); + internal->linkedMeshes = linkedMeshes; + } + + linkedMesh = internal->linkedMeshes + internal->linkedMeshCount++; + linkedMesh->mesh = mesh; + linkedMesh->skin = skin; + linkedMesh->slotIndex = slotIndex; + linkedMesh->parent = parent; +} + +static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, const char* name, + _dataInput* input, spSkeletonData *skeletonData) { + kvec_t(spTimeline*) timelines; + float duration = 0; + int i, n, ii, nn, iii, nnn; + int frameIndex; + int drawOrderCount, eventCount; + spAnimation* animation; + + kv_init(timelines); + + /* Slot timelines. */ + 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) { + unsigned char timelineType = readByte(input); + int frameCount = readVarint(input, 1); + switch (timelineType) { + case SLOT_COLOR: { + spColorTimeline* timeline = spColorTimeline_create(frameCount); + timeline->slotIndex = slotIndex; + for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) { + float time = readFloat(input); + float r, g, b, a; + readColor(input, &r, &g, &b, &a); + spColorTimeline_setFrame(timeline, frameIndex, time, r, g, b, a); + if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex); + } + kv_push(spTimeline*, timelines, SUPER(SUPER(timeline))); + duration = MAX(duration, timeline->frames[(frameCount - 1) * COLOR_ENTRIES]); + break; + } + case SLOT_ATTACHMENT: { + spAttachmentTimeline* timeline = spAttachmentTimeline_create(frameCount); + timeline->slotIndex = slotIndex; + for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) { + float time = readFloat(input); + const char* attachmentName = readString(input); + /* TODO Avoid copying of attachmentName inside */ + spAttachmentTimeline_setFrame(timeline, frameIndex, time, attachmentName); + FREE(attachmentName); + } + kv_push(spTimeline*, timelines, SUPER(timeline)); + duration = MAX(duration, timeline->frames[frameCount - 1]); + break; + } + default: { + int i; + for (i = 0; i < kv_size(timelines); ++i) + spTimeline_dispose(kv_A(timelines, i)); + kv_destroy(timelines); + _spSkeletonBinary_setError(self, "Invalid timeline type for a slot: ", skeletonData->slots[slotIndex]->name); + return 0; + } + } + } + } + + /* Bone timelines. */ + for (i = 0, n = readVarint(input, 1); i < n; ++i) { + int boneIndex = readVarint(input, 1); + for (ii = 0, nn = readVarint(input, 1); ii < nn; ++ii) { + unsigned char timelineType = readByte(input); + int frameCount = readVarint(input, 1); + switch (timelineType) { + case BONE_ROTATE: { + spRotateTimeline *timeline = spRotateTimeline_create(frameCount); + timeline->boneIndex = boneIndex; + for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) { + float time = readFloat(input); + float degrees = readFloat(input); + spRotateTimeline_setFrame(timeline, frameIndex, time, degrees); + if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex); + } + kv_push(spTimeline*, timelines, SUPER(SUPER(timeline))); + duration = MAX(duration, timeline->frames[(frameCount - 1) * ROTATE_ENTRIES]); + break; + } + case BONE_TRANSLATE: + case BONE_SCALE: + case BONE_SHEAR: { + float timelineScale = 1; + spTranslateTimeline *timeline = 0; + switch (timelineType) { + case BONE_SCALE: + timeline = spScaleTimeline_create(frameCount); + break; + case BONE_SHEAR: + timeline = spShearTimeline_create(frameCount); + break; + case BONE_TRANSLATE: + timeline = spTranslateTimeline_create(frameCount); + timelineScale = self->scale; + break; + default: + break; + } + timeline->boneIndex = boneIndex; + for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) { + float time = readFloat(input); + float x = readFloat(input) * timelineScale; + float y = readFloat(input) * timelineScale; + spTranslateTimeline_setFrame(timeline, frameIndex, time, x, y); + if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex); + } + kv_push(spTimeline*, timelines, SUPER_CAST(spTimeline, timeline)); + duration = MAX(duration, timeline->frames[(frameCount - 1) * TRANSLATE_ENTRIES]); + break; + } + default: { + int i; + for (i = 0; i < kv_size(timelines); ++i) + spTimeline_dispose(kv_A(timelines, i)); + kv_destroy(timelines); + _spSkeletonBinary_setError(self, "Invalid timeline type for a bone: ", skeletonData->bones[boneIndex]->name); + return 0; + } + } + } + } + + /* IK constraint timelines. */ + for (i = 0, n = readVarint(input, 1); i < n; ++i) { + int index = readVarint(input, 1); + int frameCount = readVarint(input, 1); + spIkConstraintTimeline* timeline = spIkConstraintTimeline_create(frameCount); + timeline->ikConstraintIndex = index; + for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) { + float time = readFloat(input); + float mix = readFloat(input); + char bendDirection = readSByte(input); + spIkConstraintTimeline_setFrame(timeline, frameIndex, time, mix, bendDirection); + if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex); + } + kv_push(spTimeline*, timelines, SUPER(SUPER(timeline))); + duration = MAX(duration, timeline->frames[(frameCount - 1) * IKCONSTRAINT_ENTRIES]); + } + + /* Transform constraint timelines. */ + for (i = 0, n = readVarint(input, 1); i < n; ++i) { + int index = readVarint(input, 1); + int frameCount = readVarint(input, 1); + spTransformConstraintTimeline* timeline = spTransformConstraintTimeline_create(frameCount); + timeline->transformConstraintIndex = index; + for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) { + float time = readFloat(input); + float rotateMix = readFloat(input); + float translateMix = readFloat(input); + float scaleMix = readFloat(input); + float shearMix = readFloat(input); + spTransformConstraintTimeline_setFrame(timeline, frameIndex, time, rotateMix, translateMix, + scaleMix, shearMix); + if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex); + } + kv_push(spTimeline*, timelines, SUPER(SUPER(timeline))); + duration = MAX(duration, timeline->frames[(frameCount - 1) * TRANSFORMCONSTRAINT_ENTRIES]); + } + + /* Path constraint timelines. */ + for (i = 0, n = readVarint(input, 1); i < n; ++i) { + int index = readVarint(input, 1); + spPathConstraintData* data = skeletonData->pathConstraints[index]; + for (ii = 0, nn = readVarint(input, 1); ii < nn; ++ii) { + unsigned char timelineType = readByte(input); + int frameCount = readVarint(input, 1); + switch (timelineType) { + case PATH_POSITION: + case PATH_SPACING: { + spPathConstraintPositionTimeline* timeline = 0; + float timelineScale = 1; + if (timelineType == PATH_SPACING) { + timeline = (spPathConstraintPositionTimeline*)spPathConstraintSpacingTimeline_create(frameCount); + if (data->spacingMode == SP_SPACING_MODE_LENGTH || data->spacingMode == SP_SPACING_MODE_FIXED) + timelineScale = self->scale; + } else { + timeline = spPathConstraintPositionTimeline_create(frameCount); + if (data->positionMode == SP_POSITION_MODE_FIXED) + timelineScale = self->scale; + } + timeline->pathConstraintIndex = index; + for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) { + float time = readFloat(input); + float value = readFloat(input) * timelineScale; + spPathConstraintPositionTimeline_setFrame(timeline, frameIndex, time, value); + if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex); + } + kv_push(spTimeline*, timelines, SUPER(SUPER(timeline))); + duration = MAX(duration, timeline->frames[(frameCount - 1) * PATHCONSTRAINTPOSITION_ENTRIES]); + break; + } + case PATH_MIX: { + spPathConstraintMixTimeline* timeline = spPathConstraintMixTimeline_create(frameCount); + timeline->pathConstraintIndex = index; + for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) { + float time = readFloat(input); + float rotateMix = readFloat(input); + float translateMix = readFloat(input); + spPathConstraintMixTimeline_setFrame(timeline, frameIndex, time, rotateMix, translateMix); + if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex); + } + kv_push(spTimeline*, timelines, SUPER(SUPER(timeline))); + duration = MAX(duration, timeline->frames[(frameCount - 1) * PATHCONSTRAINTMIX_ENTRIES]); + } + } + } + } + + /* Deform timelines. */ + for (i = 0, n = readVarint(input, 1); i < n; ++i) { + spSkin* skin = skeletonData->skins[readVarint(input, 1)]; + for (ii = 0, nn = readVarint(input, 1); ii < nn; ++ii) { + int slotIndex = readVarint(input, 1); + for (iii = 0, nnn = readVarint(input, 1); iii < nnn; ++iii) { + float* tempDeform; + spDeformTimeline *timeline; + int weighted, deformLength; + const char* attachmentName = readString(input); + int frameCount; + + spVertexAttachment* attachment = SUB_CAST(spVertexAttachment, + spSkin_getAttachment(skin, slotIndex, attachmentName)); + if (!attachment) { + int i; + for (i = 0; i < kv_size(timelines); ++i) + spTimeline_dispose(kv_A(timelines, i)); + kv_destroy(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; + tempDeform = MALLOC(float, deformLength); + + frameCount = readVarint(input, 1); + timeline = spDeformTimeline_create(frameCount, deformLength); + timeline->slotIndex = slotIndex; + timeline->attachment = SUPER(attachment); + + for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) { + float time = readFloat(input); + float* deform; + int end = readVarint(input, 1); + if (!end) { + if (weighted) { + deform = tempDeform; + memset(deform, 0, sizeof(float) * deformLength); + } else + deform = attachment->vertices; + } else { + int v, start = readVarint(input, 1); + deform = tempDeform; + memset(deform, 0, sizeof(float) * start); + end += start; + if (self->scale == 1) { + for (v = start; v < end; ++v) + deform[v] = readFloat(input); + } else { + for (v = start; v < end; ++v) + deform[v] = readFloat(input) * self->scale; + } + memset(deform + v, 0, sizeof(float) * (deformLength - v)); + if (!weighted) { + float* vertices = attachment->vertices; + for (v = 0; v < deformLength; ++v) + deform[v] += vertices[v]; + } + } + spDeformTimeline_setFrame(timeline, frameIndex, time, deform); + if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex); + } + FREE(tempDeform); + + kv_push(spTimeline*, timelines, SUPER(SUPER(timeline))); + duration = MAX(duration, timeline->frames[frameCount - 1]); + } + } + } + + /* Draw order timeline. */ + drawOrderCount = readVarint(input, 1); + if (drawOrderCount) { + spDrawOrderTimeline* timeline = spDrawOrderTimeline_create(drawOrderCount, skeletonData->slotsCount); + for (i = 0; i < drawOrderCount; ++i) { + float time = readFloat(input); + int offsetCount = readVarint(input, 1); + int* drawOrder = MALLOC(int, skeletonData->slotsCount); + int* unchanged = MALLOC(int, skeletonData->slotsCount - offsetCount); + int originalIndex = 0, unchangedIndex = 0; + memset(drawOrder, -1, sizeof(int) * skeletonData->slotsCount); + for (ii = 0; ii < offsetCount; ++ii) { + int slotIndex = readVarint(input, 1); + /* Collect unchanged items. */ + while (originalIndex != slotIndex) + unchanged[unchangedIndex++] = originalIndex++; + /* Set changed items. */ + drawOrder[originalIndex + readVarint(input, 1)] = originalIndex; + ++originalIndex; + } + /* Collect remaining unchanged items. */ + while (originalIndex < skeletonData->slotsCount) + unchanged[unchangedIndex++] = originalIndex++; + /* Fill in unchanged items. */ + for (ii = skeletonData->slotsCount - 1; ii >= 0; ii--) + if (drawOrder[ii] == -1) drawOrder[ii] = unchanged[--unchangedIndex]; + FREE(unchanged); + /* TODO Avoid copying of drawOrder inside */ + spDrawOrderTimeline_setFrame(timeline, i, time, drawOrder); + FREE(drawOrder); + } + kv_push(spTimeline*, timelines, SUPER(timeline)); + duration = MAX(duration, timeline->frames[drawOrderCount - 1]); + } + + /* Event timeline. */ + eventCount = readVarint(input, 1); + if (eventCount) { + spEventTimeline* timeline = spEventTimeline_create(eventCount); + for (i = 0; i < eventCount; ++i) { + float time = readFloat(input); + spEventData* eventData = skeletonData->events[readVarint(input, 1)]; + spEvent* event = spEvent_create(time, eventData); + event->intValue = readVarint(input, 0); + event->floatValue = readFloat(input); + if (readBoolean(input)) + event->stringValue = readString(input); + else + MALLOC_STR(event->stringValue, eventData->stringValue); + spEventTimeline_setFrame(timeline, i, event); + } + kv_push(spTimeline*, timelines, SUPER(timeline)); + duration = MAX(duration, timeline->frames[eventCount - 1]); + } + + kv_trim(spTimeline*, timelines); + + animation = spAnimation_create(name, 0); + animation->duration = duration; + animation->timelinesCount = kv_size(timelines); + animation->timelines = kv_array(timelines); + return animation; +} + +static float* _readFloatArray(_dataInput *input, int n, float scale) { + float* array = MALLOC(float, n); + int i; + if (scale == 1) + for (i = 0; i < n; ++i) + array[i] = readFloat(input); + else + for (i = 0; i < n; ++i) + array[i] = readFloat(input) * scale; + return array; +} + +static short* _readShortArray(_dataInput *input, int *length) { + int n = readVarint(input, 1); + short* array = MALLOC(short, n); + int i; + *length = n; + for (i = 0; i < n; ++i) { + array[i] = readByte(input) << 8; + array[i] |= readByte(input); + } + return array; +} + +static void _readVertices(spSkeletonBinary* self, _dataInput* input, spVertexAttachment* attachment, + int vertexCount) { + int i, ii; + int verticesLength = vertexCount << 1; + kvec_t(float) weights; + kvec_t(int) bones; + + attachment->worldVerticesLength = verticesLength; + + if (!readBoolean(input)) { + attachment->verticesCount = verticesLength; + attachment->vertices = _readFloatArray(input, verticesLength, self->scale); + attachment->bonesCount = 0; + attachment->bones = 0; + return; + } + + kv_init(weights); + kv_resize(float, weights, verticesLength * 3 * 3); + + kv_init(bones); + kv_resize(int, bones, verticesLength * 3); + + for (i = 0; i < vertexCount; ++i) { + int boneCount = readVarint(input, 1); + kv_push(int, bones, boneCount); + for (ii = 0; ii < boneCount; ++ii) { + kv_push(int, bones, readVarint(input, 1)); + kv_push(float, weights, readFloat(input) * self->scale); + kv_push(float, weights, readFloat(input) * self->scale); + kv_push(float, weights, readFloat(input)); + } + } + + kv_trim(float, weights); + attachment->verticesCount = kv_size(weights); + attachment->vertices = kv_array(weights); + + kv_trim(int, bones); + attachment->bonesCount = kv_size(bones); + attachment->bones = kv_array(bones); +} + +spAttachment* spSkeletonBinary_readAttachment(spSkeletonBinary* self, _dataInput* input, + spSkin* skin, int slotIndex, const char* attachmentName, int/*bool*/ nonessential) { + int i; + spAttachmentType type; + const char* name = readString(input); + if (!name) MALLOC_STR(name, attachmentName); + + type = (spAttachmentType)readByte(input); + + switch (type) { + case SP_ATTACHMENT_REGION: { + const char* path = readString(input); + spAttachment* attachment; + spRegionAttachment* region; + if (!path) MALLOC_STR(path, name); + attachment = spAttachmentLoader_createAttachment( + self->attachmentLoader, skin, type, name, path); + region = SUB_CAST(spRegionAttachment, attachment); + region->path = path; + region->rotation = readFloat(input); + region->x = readFloat(input) * self->scale; + region->y = readFloat(input) * self->scale; + region->scaleX = readFloat(input); + region->scaleY = readFloat(input); + region->width = readFloat(input) * self->scale; + region->height = readFloat(input) * self->scale; + readColor(input, ®ion->r, ®ion->g, ®ion->b, ®ion->a); + spRegionAttachment_updateOffset(region); + spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment); + return attachment; + } + case SP_ATTACHMENT_BOUNDING_BOX: { + int vertexCount = readVarint(input, 1); + spAttachment* attachment = spAttachmentLoader_createAttachment( + self->attachmentLoader, skin, type, name, 0); + _readVertices(self, input, SUB_CAST(spVertexAttachment, attachment), vertexCount); + if (nonessential) readInt(input); /* Skip color. */ + spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment); + return attachment; + } + case SP_ATTACHMENT_MESH: { + int vertexCount; + spAttachment* attachment; + spMeshAttachment* mesh; + const char* path = readString(input); + if (!path) MALLOC_STR(path, name); + attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, path); + mesh = SUB_CAST(spMeshAttachment, attachment); + mesh->path = path; + readColor(input, &mesh->r, &mesh->g, &mesh->b, &mesh->a); + vertexCount = readVarint(input, 1); + mesh->regionUVs = _readFloatArray(input, vertexCount << 1, 1); + mesh->triangles = (unsigned short*)_readShortArray(input, &mesh->trianglesCount); + _readVertices(self, input, SUPER(mesh), vertexCount); + spMeshAttachment_updateUVs(mesh); + mesh->hullLength = readVarint(input, 1) << 1; + if (nonessential) { + mesh->edges = (int*)_readShortArray(input, &mesh->edgesCount); + mesh->width = readFloat(input) * self->scale; + mesh->height = readFloat(input) * self->scale; + } else { + mesh->edges = 0; + mesh->width = 0; + mesh->height = 0; + } + return attachment; + } + case SP_ATTACHMENT_LINKED_MESH: { + const char* skinName; + const char* parent; + spAttachment* attachment; + spMeshAttachment* mesh; + const char* path = readString(input); + if (!path) MALLOC_STR(path, name); + attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, path); + mesh = SUB_CAST(spMeshAttachment, attachment); + mesh->path = path; + readColor(input, &mesh->r, &mesh->g, &mesh->b, &mesh->a); + skinName = readString(input); + parent = readString(input); + mesh->inheritDeform = readBoolean(input); + if (nonessential) { + mesh->width = readFloat(input) * self->scale; + mesh->height = readFloat(input) * self->scale; + } + _spSkeletonBinary_addLinkedMesh(self, mesh, skinName, slotIndex, parent); + return attachment; + } + case SP_ATTACHMENT_PATH: { + spAttachment* attachment = spAttachmentLoader_createAttachment( + self->attachmentLoader, skin, type, name, 0); + spPathAttachment* path = SUB_CAST(spPathAttachment, attachment); + int vertexCount = 0; + path->closed = readBoolean(input); + path->constantSpeed = readBoolean(input); + vertexCount = readVarint(input, 1); + _readVertices(self, input, SUPER(path), vertexCount); + path->lengthsLength = vertexCount / 3; + path->lengths = MALLOC(float, path->lengthsLength); + for (i = 0; i < path->lengthsLength; ++i) { + path->lengths[i] = readFloat(input) * self->scale; + } + if (nonessential) readInt(input); /* Skip color. */ + return attachment; + } + } + + return 0; +} + +spSkin* spSkeletonBinary_readSkin(spSkeletonBinary* self, _dataInput* input, + const char* skinName, int/*bool*/ nonessential) { + spSkin* skin; + int slotCount = readVarint(input, 1); + int i, ii, nn; + if (slotCount == 0) + return 0; + skin = spSkin_create(skinName); + for (i = 0; i < slotCount; ++i) { + int slotIndex = readVarint(input, 1); + for (ii = 0, nn = readVarint(input, 1); ii < nn; ++ii) { + const char* name = readString(input); + spSkin_addAttachment(skin, slotIndex, name, + spSkeletonBinary_readAttachment(self, input, skin, slotIndex, name, nonessential)); + FREE(name); + } + } + return skin; +} + +spSkeletonData* spSkeletonBinary_readSkeletonDataFile (spSkeletonBinary* self, const char* path) { + int length; + spSkeletonData* skeletonData; + const char* binary = _spUtil_readFile(path, &length); + if (length == 0 || !binary) { + _spSkeletonBinary_setError(self, "Unable to read skeleton file: ", path); + return 0; + } + skeletonData = spSkeletonBinary_readSkeletonData(self, (unsigned char*)binary, length); + FREE(binary); + return skeletonData; +} + +spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const unsigned char* binary, + const int length) { + int i, ii, nonessential; + spSkeletonData* skeletonData; + _spSkeletonBinary* internal = SUB_CAST(_spSkeletonBinary, self); + + _dataInput* input = NEW(_dataInput); + input->cursor = binary; + input->end = binary + length; + + FREE(self->error); + CONST_CAST(char*, self->error) = 0; + internal->linkedMeshCount = 0; + + skeletonData = spSkeletonData_create(); + + skeletonData->hash = readString(input); + if (!strlen(skeletonData->hash)) { + FREE(skeletonData->hash); + skeletonData->hash = 0; + } + + skeletonData->version = readString(input); + if (!strlen(skeletonData->version)) { + FREE(skeletonData->version); + skeletonData->version = 0; + } + + skeletonData->width = readFloat(input); + skeletonData->height = readFloat(input); + + nonessential = readBoolean(input); + + if (nonessential) FREE(readString(input)); /* Skip images path. */ + + /* Bones. */ + skeletonData->bonesCount = readVarint(input, 1); + skeletonData->bones = MALLOC(spBoneData*, skeletonData->bonesCount); + for (i = 0; i < skeletonData->bonesCount; ++i) { + spBoneData* data; + const char* name = readString(input); + spBoneData* parent = i == 0 ? 0 : skeletonData->bones[readVarint(input, 1)]; + /* TODO Avoid copying of name */ + data = spBoneData_create(i, name, parent); + FREE(name); + data->rotation = readFloat(input); + data->x = readFloat(input) * self->scale; + data->y = readFloat(input) * self->scale; + data->scaleX = readFloat(input); + data->scaleY = readFloat(input); + data->shearX = readFloat(input); + data->shearY = readFloat(input); + data->length = readFloat(input) * self->scale; + data->inheritRotation = readBoolean(input); + data->inheritScale = readBoolean(input); + if (nonessential) readInt(input); /* Skip bone color. */ + skeletonData->bones[i] = data; + } + + /* Slots. */ + skeletonData->slotsCount = readVarint(input, 1); + skeletonData->slots = MALLOC(spSlotData*, skeletonData->slotsCount); + for (i = 0; i < skeletonData->slotsCount; ++i) { + const char* slotName = readString(input); + spBoneData* boneData = skeletonData->bones[readVarint(input, 1)]; + /* TODO Avoid copying of slotName */ + spSlotData* slotData = spSlotData_create(i, slotName, boneData); + FREE(slotName); + readColor(input, &slotData->r, &slotData->g, &slotData->b, &slotData->a); + slotData->attachmentName = readString(input); + slotData->blendMode = (spBlendMode)readVarint(input, 1); + skeletonData->slots[i] = slotData; + } + + /* IK constraints. */ + skeletonData->ikConstraintsCount = readVarint(input, 1); + skeletonData->ikConstraints = MALLOC(spIkConstraintData*, skeletonData->ikConstraintsCount); + for (i = 0; i < skeletonData->ikConstraintsCount; ++i) { + const char* name = readString(input); + /* TODO Avoid copying of name */ + spIkConstraintData* data = spIkConstraintData_create(name); + FREE(name); + data->bonesCount = readVarint(input, 1); + data->bones = MALLOC(spBoneData*, data->bonesCount); + for (ii = 0; ii < data->bonesCount; ++ii) + data->bones[ii] = skeletonData->bones[readVarint(input, 1)]; + data->target = skeletonData->bones[readVarint(input, 1)]; + data->mix = readFloat(input); + data->bendDirection = readSByte(input); + skeletonData->ikConstraints[i] = data; + } + + /* Transform constraints. */ + skeletonData->transformConstraintsCount = readVarint(input, 1); + skeletonData->transformConstraints = MALLOC( + spTransformConstraintData*, skeletonData->transformConstraintsCount); + for (i = 0; i < skeletonData->transformConstraintsCount; ++i) { + const char* name = readString(input); + /* TODO Avoid copying of name */ + spTransformConstraintData* data = spTransformConstraintData_create(name); + FREE(name); + data->bonesCount = readVarint(input, 1); + CONST_CAST(spBoneData**, data->bones) = MALLOC(spBoneData*, data->bonesCount); + for (ii = 0; ii < data->bonesCount; ++ii) + data->bones[ii] = skeletonData->bones[readVarint(input, 1)]; + data->target = skeletonData->bones[readVarint(input, 1)]; + data->offsetRotation = readFloat(input); + data->offsetX = readFloat(input) * self->scale; + data->offsetY = readFloat(input) * self->scale; + data->offsetScaleX = readFloat(input); + data->offsetScaleY = readFloat(input); + data->offsetShearY = readFloat(input); + data->rotateMix = readFloat(input); + data->translateMix = readFloat(input); + data->scaleMix = readFloat(input); + data->shearMix = readFloat(input); + skeletonData->transformConstraints[i] = data; + } + + /* Path constraints */ + skeletonData->pathConstraintsCount = readVarint(input, 1); + skeletonData->pathConstraints = MALLOC(spPathConstraintData*, skeletonData->pathConstraintsCount); + for (i = 0; i < skeletonData->pathConstraintsCount; ++i) { + const char* name = readString(input); + /* TODO Avoid copying of name */ + spPathConstraintData* data = spPathConstraintData_create(name); + FREE(name); + data->bonesCount = readVarint(input, 1); + CONST_CAST(spBoneData**, data->bones) = MALLOC(spBoneData*, data->bonesCount); + for (ii = 0; ii < data->bonesCount; ++ii) + data->bones[ii] = skeletonData->bones[readVarint(input, 1)]; + data->target = skeletonData->slots[readVarint(input, 1)]; + data->positionMode = (spPositionMode)readVarint(input, 1); + data->spacingMode = (spSpacingMode)readVarint(input, 1); + data->rotateMode = (spRotateMode)readVarint(input, 1); + data->offsetRotation = readFloat(input); + data->position = readFloat(input); + if (data->positionMode == SP_POSITION_MODE_FIXED) data->position *= self->scale; + data->spacing = readFloat(input); + if (data->spacingMode == SP_SPACING_MODE_LENGTH || data->spacingMode == SP_SPACING_MODE_FIXED) data->spacing *= self->scale; + data->rotateMix = readFloat(input); + data->translateMix = readFloat(input); + skeletonData->pathConstraints[i] = data; + } + + /* Default skin. */ + skeletonData->defaultSkin = spSkeletonBinary_readSkin(self, input, "default", nonessential); + skeletonData->skinsCount = readVarint(input, 1); + + if (skeletonData->defaultSkin) + ++skeletonData->skinsCount; + + skeletonData->skins = MALLOC(spSkin*, skeletonData->skinsCount); + + if (skeletonData->defaultSkin) + skeletonData->skins[0] = skeletonData->defaultSkin; + + /* 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, nonessential); + FREE(skinName); + } + + /* Linked meshes. */ + for (i = 0; i < internal->linkedMeshCount; ++i) { + _spLinkedMesh* linkedMesh = internal->linkedMeshes + i; + spSkin* skin = !linkedMesh->skin ? skeletonData->defaultSkin : spSkeletonData_findSkin(skeletonData, linkedMesh->skin); + spAttachment* parent; + if (!skin) { + FREE(input); + spSkeletonData_dispose(skeletonData); + _spSkeletonBinary_setError(self, "Skin not found: ", linkedMesh->skin); + return 0; + } + parent = spSkin_getAttachment(skin, linkedMesh->slotIndex, linkedMesh->parent); + if (!parent) { + FREE(input); + spSkeletonData_dispose(skeletonData); + _spSkeletonBinary_setError(self, "Parent mesh not found: ", linkedMesh->parent); + return 0; + } + spMeshAttachment_setParentMesh(linkedMesh->mesh, SUB_CAST(spMeshAttachment, parent)); + spMeshAttachment_updateUVs(linkedMesh->mesh); + spAttachmentLoader_configureAttachment(self->attachmentLoader, SUPER(SUPER(linkedMesh->mesh))); + } + + /* Events. */ + 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 */ + spEventData* eventData = spEventData_create(name); + FREE(name); + eventData->intValue = readVarint(input, 0); + eventData->floatValue = readFloat(input); + eventData->stringValue = readString(input); + skeletonData->events[i] = eventData; + } + + /* Animations. */ + skeletonData->animationsCount = readVarint(input, 1); + skeletonData->animations = MALLOC(spAnimation*, skeletonData->animationsCount); + for (i = 0; i < skeletonData->animationsCount; ++i) { + spAnimation* animation = _spSkeletonBinary_readAnimation(self, readString(input), input, skeletonData); + if (!animation) { + FREE(input); + spSkeletonData_dispose(skeletonData); + return 0; + } + skeletonData->animations[i] = animation; + } + + FREE(input); + return skeletonData; +} diff --git a/spine-c/src/spine/kvec.h b/spine-c/src/spine/kvec.h new file mode 100644 index 000000000..99f49ccb1 --- /dev/null +++ b/spine-c/src/spine/kvec.h @@ -0,0 +1,92 @@ +/* The MIT License + + Copyright (c) 2008, by Attractive Chaos + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* + An example: + +#include "kvec.h" +int main() { + kvec_t(int) array; + kv_init(array); + kv_push(int, array, 10); // append + kv_a(int, array, 20) = 5; // dynamic + kv_A(array, 20) = 4; // static + kv_destroy(array); + return 0; +} +*/ + +/* + 2008-09-22 (0.1.0): + + * The initial version. + +*/ + +#ifndef AC_KVEC_H +#define AC_KVEC_H + +#include + +#define kv_roundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) + +#define kvec_t(type) struct { size_t n, m; type *a; } +#define kv_init(v) ((v).n = (v).m = 0, (v).a = 0) +#define kv_destroy(v) free((v).a) +#define kv_A(v, i) ((v).a[(i)]) +#define kv_array(v) ((v).a) +#define kv_pop(v) ((v).a[--(v).n]) +#define kv_size(v) ((v).n) +#define kv_max(v) ((v).m) + +#define kv_resize(type, v, s) ((v).m = (s), (v).a = (type*)realloc((v).a, sizeof(type) * (v).m)) +#define kv_trim(type, v) (kv_resize(type, (v), kv_size(v))) + +#define kv_copy(type, v1, v0) do { \ + if ((v1).m < (v0).n) kv_resize(type, v1, (v0).n); \ + (v1).n = (v0).n; \ + memcpy((v1).a, (v0).a, sizeof(type) * (v0).n); \ + } while (0) \ + +#define kv_push(type, v, x) do { \ + if ((v).n == (v).m) { \ + (v).m = (v).m? (v).m<<1 : 2; \ + (v).a = (type*)realloc((v).a, sizeof(type) * (v).m); \ + } \ + (v).a[(v).n++] = (x); \ + } while (0) + +#define kv_pushp(type, v) (((v).n == (v).m)? \ + ((v).m = ((v).m? (v).m<<1 : 2), \ + (v).a = (type*)realloc((v).a, sizeof(type) * (v).m), 0) \ + : 0), ((v).a + ((v).n++)) + +#define kv_a(type, v, i) (((v).m <= (size_t)(i)? \ + ((v).m = (v).n = (i) + 1, kv_roundup32((v).m), \ + (v).a = (type*)realloc((v).a, sizeof(type) * (v).m), 0) \ + : (v).n <= (size_t)(i)? (v).n = (i) + 1 \ + : 0), (v).a[(i)]) + +#endif diff --git a/spine-sfml/data/goblins-mesh.skel b/spine-sfml/data/goblins-mesh.skel new file mode 100644 index 000000000..98dd16a04 Binary files /dev/null and b/spine-sfml/data/goblins-mesh.skel differ diff --git a/spine-sfml/data/raptor.skel b/spine-sfml/data/raptor.skel new file mode 100644 index 000000000..e70312f37 Binary files /dev/null and b/spine-sfml/data/raptor.skel differ diff --git a/spine-sfml/data/spineboy.skel b/spine-sfml/data/spineboy.skel new file mode 100644 index 000000000..20f970670 Binary files /dev/null and b/spine-sfml/data/spineboy.skel differ diff --git a/spine-sfml/data/tank.skel b/spine-sfml/data/tank.skel new file mode 100644 index 000000000..b14a91777 Binary files /dev/null and b/spine-sfml/data/tank.skel differ diff --git a/spine-sfml/data/vine.atlas b/spine-sfml/data/vine.atlas index 313213413..019a92d01 100644 --- a/spine-sfml/data/vine.atlas +++ b/spine-sfml/data/vine.atlas @@ -4,7 +4,7 @@ size: 128,1024 format: RGBA8888 filter: Linear,Linear repeat: none -images/vine +vine rotate: false xy: 2, 2 size: 68, 962 diff --git a/spine-sfml/data/vine.json b/spine-sfml/data/vine.json index a08c20022..6fc78dc14 100644 --- a/spine-sfml/data/vine.json +++ b/spine-sfml/data/vine.json @@ -1,20 +1,20 @@ { -"skeleton": { "hash": "Ww/IgnvLkO+Bc7+ljr0JS3OTq8Q", "spine": "3.4.00", "width": 227.35, "height": 841.02, "images": "" }, +"skeleton": { "hash": "OTxn8PebJnSmjY8665bH7m360tk", "spine": "3.4.02", "width": 227.32, "height": 841.06, "images": "./images/" }, "bones": [ { "name": "root" }, { "name": "vine1", "parent": "root", "length": 74, "rotation": 90, "x": 339.09, "y": -467.15, "color": "f700ffff" }, { "name": "vine2", "parent": "vine1", "length": 74, "x": 74, "color": "f700ffff" }, - { "name": "vine3", "parent": "vine2", "length": 74, "x": 74, "color": "f700ffff" }, - { "name": "vine4", "parent": "vine3", "length": 74, "x": 74, "color": "f700ffff" }, - { "name": "vine5", "parent": "vine4", "length": 74, "x": 74, "color": "f700ffff" }, - { "name": "vine6", "parent": "vine5", "length": 74, "x": 74, "color": "f700ffff" }, - { "name": "vine7", "parent": "vine6", "length": 74, "x": 74, "color": "f700ffff" }, - { "name": "vine8", "parent": "vine7", "length": 74, "x": 74, "color": "f700ffff" }, - { "name": "vine9", "parent": "vine8", "length": 74, "x": 74, "color": "f700ffff" }, - { "name": "vine10", "parent": "vine9", "length": 74, "x": 74, "color": "f700ffff" }, - { "name": "vine11", "parent": "vine10", "length": 74, "x": 74, "color": "f700ffff" }, - { "name": "vine12", "parent": "vine11", "length": 74, "x": 74, "color": "f700ffff" }, - { "name": "vine13", "parent": "vine12", "length": 74, "x": 74, "color": "f700ffff" }, + { "name": "vine3", "parent": "vine1", "length": 74, "rotation": 38.94, "x": 137.97, "y": 47.51, "color": "f700ffff" }, + { "name": "vine4", "parent": "vine1", "length": 74, "rotation": 16.67, "x": 214.29, "y": 68.52, "color": "f700ffff" }, + { "name": "vine5", "parent": "vine1", "length": 74, "rotation": -21.73, "x": 289.61, "y": 40.92, "color": "f700ffff" }, + { "name": "vine6", "parent": "vine1", "length": 74, "rotation": -50.04, "x": 341.12, "y": -15.58, "color": "f700ffff" }, + { "name": "vine7", "parent": "vine1", "length": 74, "rotation": -39.25, "x": 402.7, "y": -61.82, "color": "f700ffff" }, + { "name": "vine8", "parent": "vine1", "length": 74, "rotation": -6.18, "x": 483.27, "y": -69.84, "color": "f700ffff" }, + { "name": "vine9", "parent": "vine1", "length": 74, "rotation": 27.11, "x": 554.25, "y": -36.44, "color": "f700ffff" }, + { "name": "vine10", "parent": "vine1", "length": 74, "rotation": 48, "x": 608.62, "y": 19.05, "color": "f700ffff" }, + { "name": "vine11", "parent": "vine1", "length": 74, "rotation": 39.7, "x": 670.66, "y": 66.39, "color": "f700ffff" }, + { "name": "vine12", "parent": "vine1", "length": 74, "rotation": 10.72, "x": 750.09, "y": 80.23, "color": "f700ffff" }, + { "name": "vine13", "parent": "vine1", "length": 74, "rotation": -18.44, "x": 826.06, "y": 56.95, "color": "f700ffff" }, { "name": "vine-control1", "parent": "root", "length": 296.68, "rotation": 88.64, "x": -2.5, "y": 2.55, "color": "ff0004ff" }, { "name": "vine-control2", "parent": "vine-control1", "length": 292.59, "rotation": 0.96, "x": 296.68, "color": "ff0004ff" }, { "name": "vine-control3", "parent": "vine-control2", "length": 247.5, "rotation": 0.16, "x": 292.59, "color": "ff0004ff" }, @@ -22,7 +22,7 @@ ], "slots": [ { "name": "vine-path", "bone": "root", "attachment": "vine-path" }, - { "name": "vine", "bone": "vine1", "attachment": "images/vine" } + { "name": "vine", "bone": "vine1", "attachment": "vine" } ], "path": [ { @@ -35,10 +35,10 @@ "skins": { "default": { "vine": { - "images/vine": { + "vine": { "type": "mesh", "uvs": [ 0, 0, 0.5, 0, 1, 0, 1, 0.03846, 1, 0.07692, 1, 0.11538, 1, 0.15384, 1, 0.1923, 1, 0.23076, 1, 0.26923, 1, 0.30769, 1, 0.34615, 1, 0.38461, 1, 0.42307, 1, 0.46153, 1, 0.5, 1, 0.53846, 1, 0.57692, 1, 0.61538, 1, 0.65384, 1, 0.6923, 1, 0.73076, 1, 0.76923, 1, 0.80769, 1, 0.84615, 1, 0.88461, 1, 0.92307, 1, 0.96153, 1, 1, 0.5, 1, 0, 1, 0, 0.96153, 0, 0.92307, 0, 0.88461, 0, 0.84615, 0, 0.80769, 0, 0.76923, 0, 0.73076, 0, 0.6923, 0, 0.65384, 0, 0.61538, 0, 0.57692, 0, 0.53846, 0, 0.5, 0, 0.46153, 0, 0.42307, 0, 0.38461, 0, 0.34615, 0, 0.30769, 0, 0.26923, 0, 0.23076, 0, 0.1923, 0, 0.15384, 0, 0.11538, 0, 0.07692, 0, 0.03846, 0.5, 0.03846, 0.5, 0.07692, 0.5, 0.11538, 0.5, 0.15384, 0.5, 0.1923, 0.5, 0.23076, 0.5, 0.26923, 0.5, 0.30769, 0.5, 0.34615, 0.5, 0.38461, 0.5, 0.42307, 0.5, 0.46153, 0.5, 0.5, 0.5, 0.53846, 0.5, 0.57692, 0.5, 0.61538, 0.5, 0.65384, 0.5, 0.6923, 0.5, 0.73076, 0.5, 0.76923, 0.5, 0.80769, 0.5, 0.84615, 0.5, 0.88461, 0.5, 0.92307, 0.5, 0.96153 ], - "triangles": [ 57, 56, 3, 54, 55, 56, 56, 2, 3, 55, 1, 56, 56, 1, 2, 55, 0, 1, 54, 56, 57, 59, 58, 5, 52, 53, 58, 58, 4, 5, 53, 57, 58, 58, 57, 4, 53, 54, 57, 57, 3, 4, 61, 60, 7, 50, 51, 60, 60, 6, 7, 51, 59, 60, 60, 59, 6, 51, 52, 59, 59, 5, 6, 52, 58, 59, 63, 62, 9, 48, 49, 62, 62, 8, 9, 49, 61, 62, 62, 61, 8, 49, 50, 61, 61, 7, 8, 50, 60, 61, 65, 64, 11, 46, 47, 64, 64, 10, 11, 47, 63, 64, 64, 63, 10, 47, 48, 63, 63, 9, 10, 48, 62, 63, 67, 66, 13, 44, 45, 66, 66, 12, 13, 45, 65, 66, 66, 65, 12, 45, 46, 65, 65, 11, 12, 46, 64, 65, 69, 68, 15, 42, 43, 68, 68, 14, 15, 43, 67, 68, 68, 67, 14, 43, 44, 67, 67, 13, 14, 44, 66, 67, 71, 70, 17, 40, 41, 70, 70, 16, 17, 41, 69, 70, 70, 69, 16, 41, 42, 69, 69, 15, 16, 42, 68, 69, 73, 72, 19, 38, 39, 72, 72, 18, 19, 39, 71, 72, 72, 71, 18, 39, 40, 71, 71, 17, 18, 40, 70, 71, 75, 74, 21, 36, 37, 74, 74, 20, 21, 37, 73, 74, 74, 73, 20, 37, 38, 73, 73, 19, 20, 38, 72, 73, 77, 76, 23, 34, 35, 76, 76, 22, 23, 35, 75, 76, 76, 75, 22, 35, 36, 75, 75, 21, 22, 36, 74, 75, 78, 77, 24, 33, 34, 77, 32, 78, 79, 79, 78, 25, 32, 33, 78, 78, 24, 25, 33, 77, 78, 77, 23, 24, 34, 76, 77, 79, 25, 26, 29, 27, 28, 30, 80, 29, 29, 80, 27, 30, 31, 80, 80, 26, 27, 31, 79, 80, 80, 79, 26, 31, 32, 79 ], + "triangles": [ 55, 0, 1, 56, 1, 2, 55, 1, 56, 56, 2, 3, 54, 55, 56, 57, 56, 3, 57, 3, 4, 53, 54, 57, 58, 57, 4, 53, 57, 58, 58, 4, 5, 52, 53, 58, 59, 58, 5, 54, 56, 57, 52, 58, 59, 59, 5, 6, 51, 52, 59, 60, 59, 6, 51, 59, 60, 60, 6, 7, 50, 51, 60, 61, 60, 7, 50, 60, 61, 61, 7, 8, 49, 50, 61, 62, 61, 8, 49, 61, 62, 62, 8, 9, 48, 49, 62, 63, 62, 9, 48, 62, 63, 63, 9, 10, 47, 48, 63, 64, 63, 10, 47, 63, 64, 64, 10, 11, 46, 47, 64, 65, 64, 11, 46, 64, 65, 65, 11, 12, 45, 46, 65, 66, 65, 12, 45, 65, 66, 66, 12, 13, 44, 45, 66, 67, 66, 13, 44, 66, 67, 67, 13, 14, 43, 44, 67, 68, 67, 14, 43, 67, 68, 68, 14, 15, 42, 43, 68, 69, 68, 15, 42, 68, 69, 69, 15, 16, 41, 42, 69, 70, 69, 16, 41, 69, 70, 70, 16, 17, 40, 41, 70, 71, 70, 17, 40, 70, 71, 71, 17, 18, 39, 40, 71, 72, 71, 18, 39, 71, 72, 72, 18, 19, 38, 39, 72, 73, 72, 19, 38, 72, 73, 73, 19, 20, 37, 38, 73, 74, 73, 20, 37, 73, 74, 74, 20, 21, 36, 37, 74, 75, 74, 21, 36, 74, 75, 75, 21, 22, 35, 36, 75, 76, 75, 22, 35, 75, 76, 76, 22, 23, 34, 35, 76, 77, 76, 23, 34, 76, 77, 77, 23, 24, 33, 77, 78, 78, 24, 25, 32, 33, 78, 79, 78, 25, 32, 78, 79, 33, 34, 77, 78, 77, 24, 31, 32, 79, 80, 79, 26, 31, 79, 80, 80, 26, 27, 30, 31, 80, 29, 80, 27, 30, 80, 29, 29, 27, 28, 79, 25, 26 ], "vertices": [ 4, 10, 294, 33.89, 3.2E-4, 11, 220, 33.89, 0.01648, 12, 146, 33.89, 0.21526, 13, 72, 33.89, 0.76791, 3, 11, 220, -0.1, 0.00752, 12, 146, -0.1, 0.16869, 13, 72, -0.1, 0.82378, 4, 10, 294, -34.09999, 3.2E-4, 11, 220, -34.09999, 0.01648, 12, 146, -34.09999, 0.21526, 13, 72, -34.09999, 0.76791, 4, 10, 257, -34.09999, 0.00195, 11, 183, -34.09999, 0.04739, 12, 109, -34.09999, 0.33351, 13, 35, -34.09999, 0.61714, 5, 9, 294, -34.09999, 2.4E-4, 10, 220, -34.09999, 0.01163, 11, 146, -34.09999, 0.14109, 12, 72, -34.09999, 0.49171, 13, -1.99, -34.09999, 0.35531, 5, 9, 257, -34.09999, 0.00195, 10, 183, -34.09999, 0.04663, 11, 109, -34.09999, 0.31166, 12, 35, -34.09999, 0.48761, 13, -38.99, -34.09999, 0.15212, 6, 8, 294, -34.09999, 2.4E-4, 9, 220, -34.09999, 0.01163, 10, 146, -34.09999, 0.14101, 11, 72, -34.09999, 0.48685, 12, -1.99, -34.09999, 0.31174, 13, -75.99, -34.09999, 0.0485, 6, 8, 257, -34.09999, 0.00195, 9, 183, -34.09999, 0.04663, 10, 109, -34.09999, 0.31166, 11, 35, -34.09999, 0.48685, 12, -38.99, -34.09999, 0.14101, 13, -112.99, -34.09999, 0.01188, 7, 7, 294, -34.09999, 2.4E-4, 8, 220, -34.09999, 0.01163, 9, 146, -34.09999, 0.14101, 10, 72, -34.09999, 0.48685, 11, -1.99, -34.09999, 0.31166, 12, -75.99, -34.09999, 0.04663, 13, -149.99, -34.09999, 0.00195, 7, 7, 257, -34.09999, 0.00195, 8, 183, -34.09999, 0.04663, 9, 109, -34.09999, 0.31166, 10, 35, -34.09999, 0.48685, 11, -38.99, -34.09999, 0.14101, 12, -112.99, -34.09999, 0.01163, 13, -186.99, -34.09999, 2.4E-4, 7, 6, 294, -34.09999, 2.4E-4, 7, 220, -34.09999, 0.01163, 8, 146, -34.09999, 0.14101, 9, 72, -34.09999, 0.48685, 10, -1.99, -34.09999, 0.31166, 11, -75.99, -34.09999, 0.04663, 12, -149.99, -34.09999, 0.00195, 7, 6, 257, -34.09999, 0.00195, 7, 183, -34.09999, 0.04663, 8, 109, -34.09999, 0.31166, 9, 35, -34.09999, 0.48685, 10, -38.99, -34.09999, 0.14101, 11, -112.99, -34.09999, 0.01163, 12, -186.99, -34.09999, 2.4E-4, 7, 5, 294, -34.09999, 2.4E-4, 6, 220, -34.09999, 0.01163, 7, 146, -34.09999, 0.14101, 8, 72, -34.09999, 0.48685, 9, -1.99, -34.09999, 0.31166, 10, -75.99, -34.09999, 0.04663, 11, -149.99, -34.09999, 0.00195, 7, 5, 257, -34.09999, 0.00195, 6, 183, -34.09999, 0.04663, 7, 109, -34.09999, 0.31166, 8, 35, -34.09999, 0.48685, 9, -38.99, -34.09999, 0.14101, 10, -112.99, -34.09999, 0.01163, 11, -186.99, -34.09999, 2.4E-4, 7, 4, 294, -34.09999, 2.4E-4, 5, 220, -34.09999, 0.01163, 6, 146, -34.09999, 0.14101, 7, 72, -34.09999, 0.48685, 8, -1.99, -34.09999, 0.31166, 9, -75.99, -34.09999, 0.04663, 10, -149.99, -34.09999, 0.00195, 7, 4, 257, -34.09999, 0.00195, 5, 183, -34.09999, 0.04663, 6, 109, -34.09999, 0.31166, 7, 35, -34.09999, 0.48685, 8, -38.99, -34.09999, 0.14101, 9, -112.99, -34.09999, 0.01163, 10, -186.99, -34.09999, 2.4E-4, 7, 3, 294, -34.09999, 2.4E-4, 4, 220, -34.09999, 0.01163, 5, 146, -34.09999, 0.14101, 6, 72, -34.09999, 0.48685, 7, -1.99, -34.09999, 0.31166, 8, -75.99, -34.09999, 0.04663, 9, -149.99, -34.09999, 0.00195, 7, 3, 257, -34.09999, 0.00195, 4, 183, -34.09999, 0.04663, 5, 109, -34.09999, 0.31166, 6, 35, -34.09999, 0.48685, 7, -38.99, -34.09999, 0.14101, 8, -112.99, -34.09999, 0.01163, 9, -186.99, -34.09999, 2.4E-4, 7, 2, 294, -34.09999, 2.4E-4, 3, 220, -34.09999, 0.01163, 4, 146, -34.09999, 0.14101, 5, 72, -34.09999, 0.48685, 6, -1.99, -34.09999, 0.31166, 7, -75.99, -34.09999, 0.04663, 8, -149.99, -34.09999, 0.00195, 7, 2, 257, -34.09999, 0.00195, 3, 183, -34.09999, 0.04663, 4, 109, -34.09999, 0.31166, 5, 35, -34.09999, 0.48685, 6, -38.99, -34.09999, 0.14101, 7, -112.99, -34.09999, 0.01163, 8, -186.99, -34.09999, 2.4E-4, 7, 1, 294, -34.09999, 2.4E-4, 2, 220, -34.09999, 0.01163, 3, 146, -34.09999, 0.14101, 4, 72, -34.09999, 0.48685, 5, -1.99, -34.09999, 0.31166, 6, -75.99, -34.09999, 0.04663, 7, -149.99, -34.09999, 0.00195, 7, 1, 257, -34.09999, 0.0017, 2, 183, -34.09999, 0.04687, 3, 109, -34.09999, 0.31166, 4, 35, -34.09999, 0.48685, 5, -38.99, -34.09999, 0.14101, 6, -112.99, -34.09999, 0.01163, 7, -186.99, -34.09999, 2.4E-4, 6, 1, 220, -34.09999, 0.01033, 2, 146, -34.09999, 0.14256, 3, 72, -34.09999, 0.48685, 4, -1.99, -34.09999, 0.31166, 5, -75.99, -34.09999, 0.04663, 6, -149.99, -34.09999, 0.00195, 6, 1, 183, -34.09999, 0.04058, 2, 109, -34.09999, 0.31966, 3, 35, -34.09999, 0.48685, 4, -38.99, -34.09999, 0.14101, 5, -112.99, -34.09999, 0.01163, 6, -186.99, -34.09999, 2.4E-4, 5, 1, 146, -34.09999, 0.1274, 2, 72, -34.09999, 0.51233, 3, -1.99, -34.09999, 0.31166, 4, -75.99, -34.09999, 0.04663, 5, -149.99, -34.09999, 0.00195, 5, 1, 109, -34.09999, 0.30116, 2, 35, -34.09999, 0.54594, 3, -38.99, -34.09999, 0.14101, 4, -112.99, -34.09999, 0.01163, 5, -186.99, -34.09999, 2.4E-4, 4, 1, 72, -34.09999, 0.55403, 2, -1.99, -34.09999, 0.39738, 3, -75.99, -34.09999, 0.04663, 4, -149.99, -34.09999, 0.00195, 4, 1, 35, -34.09999, 0.77978, 2, -38.99, -34.09999, 0.20825, 3, -112.99, -34.09999, 0.01171, 4, -186.99, -34.09999, 2.4E-4, 3, 1, -1.99, -34.09999, 0.89032, 2, -75.99, -34.09999, 0.10696, 3, -149.99, -34.09999, 0.00271, 3, 1, -1.99, -0.1, 0.9264, 2, -75.99, -0.1, 0.07272, 3, -149.99, -0.1, 8.6E-4, 3, 1, -1.99, 33.89, 0.89032, 2, -75.99, 33.89, 0.10696, 3, -149.99, 33.89, 0.00271, 4, 1, 35, 33.89, 0.77978, 2, -38.99, 33.89, 0.20825, 3, -112.99, 33.89, 0.01171, 4, -186.99, 33.89, 2.4E-4, 4, 1, 72, 33.89, 0.55403, 2, -1.99, 33.89, 0.39738, 3, -75.99, 33.89, 0.04663, 4, -149.99, 33.89, 0.00195, 5, 1, 109, 33.89, 0.30116, 2, 35, 33.89, 0.54594, 3, -38.99, 33.89, 0.14101, 4, -112.99, 33.89, 0.01163, 5, -186.99, 33.89, 2.4E-4, 5, 1, 146, 33.89, 0.1274, 2, 72, 33.89, 0.51233, 3, -1.99, 33.89, 0.31166, 4, -75.99, 33.89, 0.04663, 5, -149.99, 33.89, 0.00195, 6, 1, 183, 33.89, 0.04058, 2, 109, 33.89, 0.31966, 3, 35, 33.89, 0.48685, 4, -38.99, 33.89, 0.14101, 5, -112.99, 33.89, 0.01163, 6, -186.99, 33.89, 2.4E-4, 6, 1, 220, 33.89, 0.01033, 2, 146, 33.89, 0.14256, 3, 72, 33.89, 0.48685, 4, -1.99, 33.89, 0.31166, 5, -75.99, 33.89, 0.04663, 6, -149.99, 33.89, 0.00195, 7, 1, 257, 33.89, 0.0017, 2, 183, 33.89, 0.04687, 3, 109, 33.89, 0.31166, 4, 35, 33.89, 0.48685, 5, -38.99, 33.89, 0.14101, 6, -112.99, 33.89, 0.01163, 7, -186.99, 33.89, 2.4E-4, 7, 1, 294, 33.89, 2.4E-4, 2, 220, 33.89, 0.01163, 3, 146, 33.89, 0.14101, 4, 72, 33.89, 0.48685, 5, -1.99, 33.89, 0.31166, 6, -75.99, 33.89, 0.04663, 7, -149.99, 33.89, 0.00195, 7, 2, 257, 33.89, 0.00195, 3, 183, 33.89, 0.04663, 4, 109, 33.89, 0.31166, 5, 35, 33.89, 0.48685, 6, -38.99, 33.89, 0.14101, 7, -112.99, 33.89, 0.01163, 8, -186.99, 33.89, 2.4E-4, 7, 2, 294, 33.89, 2.4E-4, 3, 220, 33.89, 0.01163, 4, 146, 33.89, 0.14101, 5, 72, 33.89, 0.48685, 6, -1.99, 33.89, 0.31166, 7, -75.99, 33.89, 0.04663, 8, -149.99, 33.89, 0.00195, 7, 3, 257, 33.89, 0.00195, 4, 183, 33.89, 0.04663, 5, 109, 33.89, 0.31166, 6, 35, 33.89, 0.48685, 7, -38.99, 33.89, 0.14101, 8, -112.99, 33.89, 0.01163, 9, -186.99, 33.89, 2.4E-4, 7, 3, 294, 33.89, 2.4E-4, 4, 220, 33.89, 0.01163, 5, 146, 33.89, 0.14101, 6, 72, 33.89, 0.48685, 7, -1.99, 33.89, 0.31166, 8, -75.99, 33.89, 0.04663, 9, -149.99, 33.89, 0.00195, 7, 4, 257, 33.89, 0.00195, 5, 183, 33.89, 0.04663, 6, 109, 33.89, 0.31166, 7, 35, 33.89, 0.48685, 8, -38.99, 33.89, 0.14101, 9, -112.99, 33.89, 0.01163, 10, -186.99, 33.89, 2.4E-4, 7, 4, 294, 33.89, 2.4E-4, 5, 220, 33.89, 0.01163, 6, 146, 33.89, 0.14101, 7, 72, 33.89, 0.48685, 8, -1.99, 33.89, 0.31166, 9, -75.99, 33.89, 0.04663, 10, -149.99, 33.89, 0.00195, 7, 5, 257, 33.89, 0.00195, 6, 183, 33.89, 0.04663, 7, 109, 33.89, 0.31166, 8, 35, 33.89, 0.48685, 9, -38.99, 33.89, 0.14101, 10, -112.99, 33.89, 0.01163, 11, -186.99, 33.89, 2.4E-4, 7, 5, 294, 33.89, 2.4E-4, 6, 220, 33.89, 0.01163, 7, 146, 33.89, 0.14101, 8, 72, 33.89, 0.48685, 9, -1.99, 33.89, 0.31166, 10, -75.99, 33.89, 0.04663, 11, -149.99, 33.89, 0.00195, 7, 6, 257, 33.89, 0.00195, 7, 183, 33.89, 0.04663, 8, 109, 33.89, 0.31166, 9, 35, 33.89, 0.48685, 10, -38.99, 33.89, 0.14101, 11, -112.99, 33.89, 0.01163, 12, -186.99, 33.89, 2.4E-4, 7, 6, 294, 33.89, 2.4E-4, 7, 220, 33.89, 0.01163, 8, 146, 33.89, 0.14101, 9, 72, 33.89, 0.48685, 10, -1.99, 33.89, 0.31166, 11, -75.99, 33.89, 0.04663, 12, -149.99, 33.89, 0.00195, 7, 7, 257, 33.89, 0.00195, 8, 183, 33.89, 0.04663, 9, 109, 33.89, 0.31166, 10, 35, 33.89, 0.48685, 11, -38.99, 33.89, 0.14101, 12, -112.99, 33.89, 0.01163, 13, -186.99, 33.89, 2.4E-4, 7, 7, 294, 33.89, 2.4E-4, 8, 220, 33.89, 0.01163, 9, 146, 33.89, 0.14101, 10, 72, 33.89, 0.48685, 11, -1.99, 33.89, 0.31166, 12, -75.99, 33.89, 0.04663, 13, -149.99, 33.89, 0.00195, 6, 8, 257, 33.89, 0.00195, 9, 183, 33.89, 0.04663, 10, 109, 33.89, 0.31166, 11, 35, 33.89, 0.48685, 12, -38.99, 33.89, 0.14101, 13, -112.99, 33.89, 0.01188, 6, 8, 294, 33.89, 2.4E-4, 9, 220, 33.89, 0.01163, 10, 146, 33.89, 0.14101, 11, 72, 33.89, 0.48685, 12, -1.99, 33.89, 0.31174, 13, -75.99, 33.89, 0.0485, 5, 9, 257, 33.89, 0.00195, 10, 183, 33.89, 0.04663, 11, 109, 33.89, 0.31166, 12, 35, 33.89, 0.48761, 13, -38.99, 33.89, 0.15212, 5, 9, 294, 33.89, 2.4E-4, 10, 220, 33.89, 0.01163, 11, 146, 33.89, 0.14109, 12, 72, 33.89, 0.49171, 13, -1.99, 33.89, 0.35531, 4, 10, 257, 33.89, 0.00195, 11, 183, 33.89, 0.04739, 12, 109, 33.89, 0.33351, 13, 35, 33.89, 0.61714, 4, 10, 257, -0.1, 6.5E-4, 11, 183, -0.1, 0.03067, 12, 109, -0.1, 0.31658, 13, 35, -0.1, 0.65209, 4, 10, 220, -0.1, 0.00542, 11, 146, -0.1, 0.11402, 12, 72, -0.1, 0.5478, 13, -1.99, -0.1, 0.33273, 5, 9, 257, -0.1, 6.5E-4, 10, 183, -0.1, 0.03045, 11, 109, -0.1, 0.30373, 12, 35, -0.1, 0.54592, 13, -38.99, -0.1, 0.11923, 5, 9, 220, -0.1, 0.00542, 10, 146, -0.1, 0.11402, 11, 72, -0.1, 0.5457, 12, -1.99, -0.1, 0.30373, 13, -75.99, -0.1, 0.0311, 6, 8, 257, -0.1, 6.5E-4, 9, 183, -0.1, 0.03045, 10, 109, -0.1, 0.30373, 11, 35, -0.1, 0.5457, 12, -38.99, -0.1, 0.11402, 13, -112.99, -0.1, 0.00542, 6, 8, 220, -0.1, 0.00542, 9, 146, -0.1, 0.11402, 10, 72, -0.1, 0.5457, 11, -1.99, -0.1, 0.30373, 12, -75.99, -0.1, 0.03045, 13, -149.99, -0.1, 6.5E-4, 6, 7, 257, -0.1, 6.5E-4, 8, 183, -0.1, 0.03045, 9, 109, -0.1, 0.30373, 10, 35, -0.1, 0.5457, 11, -38.99, -0.1, 0.11402, 12, -112.99, -0.1, 0.00542, 6, 7, 220, -0.1, 0.00542, 8, 146, -0.1, 0.11402, 9, 72, -0.1, 0.5457, 10, -1.99, -0.1, 0.30373, 11, -75.99, -0.1, 0.03045, 12, -149.99, -0.1, 6.5E-4, 6, 6, 257, -0.1, 6.5E-4, 7, 183, -0.1, 0.03045, 8, 109, -0.1, 0.30373, 9, 35, -0.1, 0.5457, 10, -38.99, -0.1, 0.11402, 11, -112.99, -0.1, 0.00542, 6, 6, 220, -0.1, 0.00542, 7, 146, -0.1, 0.11402, 8, 72, -0.1, 0.5457, 9, -1.99, -0.1, 0.30373, 10, -75.99, -0.1, 0.03045, 11, -149.99, -0.1, 6.5E-4, 6, 5, 257, -0.1, 6.5E-4, 6, 183, -0.1, 0.03045, 7, 109, -0.1, 0.30373, 8, 35, -0.1, 0.5457, 9, -38.99, -0.1, 0.11402, 10, -112.99, -0.1, 0.00542, 6, 5, 220, -0.1, 0.00542, 6, 146, -0.1, 0.11402, 7, 72, -0.1, 0.5457, 8, -1.99, -0.1, 0.30373, 9, -75.99, -0.1, 0.03045, 10, -149.99, -0.1, 6.5E-4, 6, 4, 257, -0.1, 6.5E-4, 5, 183, -0.1, 0.03045, 6, 109, -0.1, 0.30373, 7, 35, -0.1, 0.5457, 8, -38.99, -0.1, 0.11402, 9, -112.99, -0.1, 0.00542, 6, 4, 220, -0.1, 0.00542, 5, 146, -0.1, 0.11402, 6, 72, -0.1, 0.5457, 7, -1.99, -0.1, 0.30373, 8, -75.99, -0.1, 0.03045, 9, -149.99, -0.1, 6.5E-4, 6, 3, 257, -0.1, 6.5E-4, 4, 183, -0.1, 0.03045, 5, 109, -0.1, 0.30373, 6, 35, -0.1, 0.5457, 7, -38.99, -0.1, 0.11402, 8, -112.99, -0.1, 0.00542, 6, 3, 220, -0.1, 0.00542, 4, 146, -0.1, 0.11402, 5, 72, -0.1, 0.5457, 6, -1.99, -0.1, 0.30373, 7, -75.99, -0.1, 0.03045, 8, -149.99, -0.1, 6.5E-4, 6, 2, 257, -0.1, 6.5E-4, 3, 183, -0.1, 0.03045, 4, 109, -0.1, 0.30373, 5, 35, -0.1, 0.5457, 6, -38.99, -0.1, 0.11402, 7, -112.99, -0.1, 0.00542, 6, 2, 220, -0.1, 0.00542, 3, 146, -0.1, 0.11402, 4, 72, -0.1, 0.5457, 5, -1.99, -0.1, 0.30373, 6, -75.99, -0.1, 0.03045, 7, -149.99, -0.1, 6.5E-4, 6, 1, 257, -0.1, 6.5E-4, 2, 183, -0.1, 0.03045, 3, 109, -0.1, 0.30373, 4, 35, -0.1, 0.5457, 5, -38.99, -0.1, 0.11402, 6, -112.99, -0.1, 0.00542, 6, 1, 220, -0.1, 0.00477, 2, 146, -0.1, 0.11467, 3, 72, -0.1, 0.5457, 4, -1.99, -0.1, 0.30373, 5, -75.99, -0.1, 0.03045, 6, -149.99, -0.1, 6.5E-4, 5, 1, 183, -0.1, 0.02676, 2, 109, -0.1, 0.30807, 3, 35, -0.1, 0.5457, 4, -38.99, -0.1, 0.11402, 5, -112.99, -0.1, 0.00542, 5, 1, 146, -0.1, 0.09905, 2, 72, -0.1, 0.5661, 3, -1.99, -0.1, 0.30373, 4, -75.99, -0.1, 0.03045, 5, -149.99, -0.1, 6.5E-4, 4, 1, 109, -0.1, 0.27658, 2, 35, -0.1, 0.60395, 3, -38.99, -0.1, 0.11402, 4, -112.99, -0.1, 0.00542, 4, 1, 72, -0.1, 0.55929, 2, -1.99, -0.1, 0.40959, 3, -75.99, -0.1, 0.03045, 4, -149.99, -0.1, 6.5E-4, 3, 1, 35, -0.1, 0.81845, 2, -38.99, -0.1, 0.17611, 3, -112.99, -0.1, 0.00542 ], "hull": 56, "edges": [ 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 16, 18, 18, 20, 20, 22, 22, 24, 24, 26, 26, 28, 28, 30, 30, 32, 32, 34, 34, 36, 36, 38, 38, 40, 40, 42, 42, 44, 44, 46, 46, 48, 48, 50, 50, 52, 52, 54, 54, 56, 60, 62, 62, 64, 64, 66, 66, 68, 68, 70, 70, 72, 72, 74, 74, 76, 76, 78, 78, 80, 80, 82, 82, 84, 84, 86, 86, 88, 88, 90, 90, 92, 92, 94, 94, 96, 96, 98, 98, 100, 100, 102, 102, 104, 104, 106, 106, 108, 108, 110, 110, 0, 0, 2, 58, 60, 2, 4, 56, 58, 62, 160, 160, 54, 64, 158, 158, 52, 66, 156, 156, 50, 68, 154, 154, 48, 46, 152, 152, 70, 72, 150, 150, 44, 42, 148, 148, 74, 76, 146, 146, 40, 38, 144, 144, 78, 80, 142, 142, 36, 34, 140, 140, 82, 84, 138, 138, 32, 30, 136, 136, 86, 88, 134, 134, 28, 26, 132, 132, 90, 92, 130, 130, 24, 22, 128, 128, 94, 96, 126, 126, 20, 18, 124, 124, 98, 100, 122, 122, 16, 14, 120, 120, 102, 12, 118, 118, 104, 106, 116, 116, 10, 8, 114, 114, 108, 110, 112, 112, 6 ], @@ -49,7 +49,7 @@ "vine-path": { "vine-path": { "type": "path", - "lengths": [ 223.68, 474.79, 780.31, 992.69, 1196.42, 2277.75 ], + "lengths": [ 223.68, 474.79, 780.31, 992.69, 1196.43, 2277.75 ], "vertexCount": 18, "vertices": [ 1, 14, -31.64, 22.49, 1, 1, 14, -2.73, -6.56, 1, 1, 14, 56.89, -69, 1, 1, 14, 115.57, 75.01, 1, 1, 14, 198.6, 53.37, 1, 2, 14, 332.76, 19.74, 0.8, 15, 36.41, 19.12999, 0.19999, 2, 14, 276.72, -68.37, 0.232, 15, -21.1, -68.01999, 0.76799, 1, 15, 96.09, -93.88, 1, 2, 15, 229.75, -122.63, 0.664, 16, -63.18, -122.45, 0.33599, 2, 15, 242.53, 29.31, 0.52, 16, -49.97, 29.45, 0.47999, 1, 16, 66.72, 38.65, 1, 2, 16, 183.42, 47.85, 0.80799, 17, -63.65, 48.41, 0.192, 2, 16, 177.29, -41.22, 0.77599, 17, -70.56, -40.61, 0.224, 2, 16, 265.5, -16.18, 0.488, 17, 17.86, -16.34, 0.51199, 2, 16, 343.25, 7.25, 0.21599, 17, 95.81, 6.41, 0.784, 1, 17, 138.78, 45.72, 1, 1, 17, 212.86, 5.44, 1, 1, 14, 1094.34, -1.02, 1 ] } @@ -75,15 +75,15 @@ "scale": [ { "time": 0, - "x": 1, + "x": 0, "y": 0.183, - "curve": [ 0.166, 0.22, 0.598, 0.99 ] + "curve": [ 0.302, 0.57, 0.549, 0.82 ] }, { - "time": 3.6333, - "x": 1, - "y": 1, - "curve": [ 0.25, 0, 0.75, 1 ] + "time": 3.2333, + "x": 1.218, + "y": 1.1, + "curve": [ 0.481, 0.24, 0.708, 0.46 ] }, { "time": 11.4333, "x": 1, "y": 1.438 } ] @@ -92,25 +92,25 @@ "rotate": [ { "time": 0, - "angle": 0, + "angle": 39.68, "curve": [ 0.25, 0, 0.75, 1 ] }, { - "time": 2.5666, - "angle": 2.86, + "time": 1.2, + "angle": 0.89, "curve": [ 0.25, 0, 0.75, 1 ] }, { - "time": 4.7, - "angle": -0.13, - "curve": [ 0.505, 0, 0.75, 1 ] - }, - { - "time": 6.4333, - "angle": 0.68, + "time": 2.1666, + "angle": 5.56, "curve": [ 0.25, 0, 0.75, 1 ] }, - { "time": 9.6, "angle": 0.68 } + { + "time": 3.4, + "angle": 5.65, + "curve": [ 0.25, 0, 0.75, 1 ] + }, + { "time": 7.6, "angle": 1.35 } ], "scale": [ { @@ -138,25 +138,20 @@ "rotate": [ { "time": 0, - "angle": 0, + "angle": -39.68, "curve": [ 0.25, 0, 0.75, 1 ] }, { - "time": 2.5666, - "angle": 2.86, + "time": 1.2, + "angle": -20.6, "curve": [ 0.25, 0, 0.75, 1 ] }, { - "time": 4.7, - "angle": -0.13, - "curve": [ 0.505, 0, 0.75, 1 ] - }, - { - "time": 6.4333, - "angle": 0.68, + "time": 3.4, + "angle": -8.18, "curve": [ 0.25, 0, 0.75, 1 ] }, - { "time": 9.6, "angle": 0.68 } + { "time": 7.6, "angle": -0.96 } ], "scale": [ { @@ -188,21 +183,21 @@ "curve": [ 0.25, 0, 0.75, 1 ] }, { - "time": 2.5666, - "angle": 10.88, + "time": 1.2, + "angle": 27.36, "curve": [ 0.25, 0, 0.75, 1 ] }, { - "time": 4.7, - "angle": -11.18, - "curve": [ 0.505, 0, 0.75, 1 ] - }, - { - "time": 6.4333, - "angle": -0.47, + "time": 2.1666, + "angle": 14.82, "curve": [ 0.25, 0, 0.75, 1 ] }, - { "time": 9.6, "angle": -5.23 } + { + "time": 3.4, + "angle": -15.24, + "curve": [ 0.25, 0, 0.75, 1 ] + }, + { "time": 7.6, "angle": -0.16 } ], "scale": [ { @@ -234,21 +229,21 @@ "curve": [ 0.25, 0, 0.75, 1 ] }, { - "time": 2.5666, - "angle": 10.88, + "time": 2.1666, + "angle": -11.88, "curve": [ 0.25, 0, 0.75, 1 ] }, { - "time": 4.7, - "angle": -11.18, - "curve": [ 0.505, 0, 0.75, 1 ] - }, - { - "time": 6.4333, - "angle": 7.47, + "time": 3.4, + "angle": 7.56, "curve": [ 0.25, 0, 0.75, 1 ] }, - { "time": 9.6, "angle": 2.71 } + { + "time": 6.4, + "angle": 15.02, + "curve": [ 0.25, 0, 0.75, 1 ] + }, + { "time": 7.6, "angle": -0.5 } ], "scale": [ { @@ -271,27 +266,45 @@ }, { "time": 11.4333, "x": 1, "y": 0.923 } ] - } - }, - "paths": { - "vine-path": { - "position": [ - { "time": 0, "position": -0.1 }, - { "time": 0.3333, "position": -0.025 } - ], - "spacing": [ - { "time": 0, "spacing": -100 }, - { - "time": 0.3333, - "spacing": -71.8, - "curve": [ 0.32, 0.18, 0.624, 0.6 ] - }, - { - "time": 3.1333, - "spacing": -13.199, - "curve": [ 0.251, 0.5, 0.557, 0.98 ] - }, - { "time": 6.7333, "spacing": 20.9 } + }, + "vine6": { + "rotate": [ + { "time": 0, "angle": 0 } + ] + }, + "vine7": { + "rotate": [ + { "time": 0, "angle": 0 } + ] + }, + "vine8": { + "rotate": [ + { "time": 0, "angle": 0 } + ] + }, + "vine9": { + "rotate": [ + { "time": 0, "angle": 0 } + ] + }, + "vine10": { + "rotate": [ + { "time": 0, "angle": 0 } + ] + }, + "vine11": { + "rotate": [ + { "time": 0, "angle": 0 } + ] + }, + "vine12": { + "rotate": [ + { "time": 0, "angle": 0 } + ] + }, + "vine13": { + "rotate": [ + { "time": 0, "angle": 0 } ] } } diff --git a/spine-sfml/data/vine.skel b/spine-sfml/data/vine.skel new file mode 100644 index 000000000..18d4e53dc Binary files /dev/null and b/spine-sfml/data/vine.skel differ diff --git a/spine-sfml/example/main.cpp b/spine-sfml/example/main.cpp index 50f414788..618be0052 100644 --- a/spine-sfml/example/main.cpp +++ b/spine-sfml/example/main.cpp @@ -62,17 +62,47 @@ void callback (AnimationState* state, int trackIndex, EventType type, Event* eve fflush(stdout); } -void spineboy () { - // Load atlas, skeleton, and animations. - Atlas* atlas = Atlas_createFromFile("data/spineboy.atlas", 0); +SkeletonData* readSkeletonJsonData (const char* filename, Atlas* atlas, float scale) { SkeletonJson* json = SkeletonJson_create(atlas); - json->scale = 0.6f; - SkeletonData *skeletonData = SkeletonJson_readSkeletonDataFile(json, "data/spineboy.json"); + json->scale = scale; + SkeletonData* skeletonData = SkeletonJson_readSkeletonDataFile(json, filename); if (!skeletonData) { printf("%s\n", json->error); exit(0); } SkeletonJson_dispose(json); + return skeletonData; +} + +SkeletonData* readSkeletonBinaryData (const char* filename, Atlas* atlas, float scale) { + SkeletonBinary* binary = SkeletonBinary_create(atlas); + binary->scale = scale; + SkeletonData *skeletonData = SkeletonBinary_readSkeletonDataFile(binary, filename); + if (!skeletonData) { + printf("%s\n", binary->error); + exit(0); + } + SkeletonBinary_dispose(binary); + return skeletonData; +} + +void testcase (void func(SkeletonData* skeletonData, Atlas* atlas), + const char* jsonName, const char* binaryName, const char* atlasName, + float scale) { + Atlas* atlas = Atlas_createFromFile(atlasName, 0); + + SkeletonData* skeletonData = readSkeletonJsonData(jsonName, atlas, scale); + func(skeletonData, atlas); + SkeletonData_dispose(skeletonData); + + skeletonData = readSkeletonBinaryData(binaryName, atlas, scale); + func(skeletonData, atlas); + SkeletonData_dispose(skeletonData); + + Atlas_dispose(atlas); +} + +void spineboy (SkeletonData* skeletonData, Atlas* atlas) { SkeletonBounds* bounds = SkeletonBounds_create(); // Configure mixing. @@ -128,23 +158,10 @@ void spineboy () { window.display(); } - SkeletonData_dispose(skeletonData); SkeletonBounds_dispose(bounds); - Atlas_dispose(atlas); } -void goblins () { - // Load atlas, skeleton, and animations. - Atlas* atlas = Atlas_createFromFile("data/goblins-mesh.atlas", 0); - SkeletonJson* json = SkeletonJson_create(atlas); - json->scale = 1.4f; - SkeletonData *skeletonData = SkeletonJson_readSkeletonDataFile(json, "data/goblins-mesh.json"); - if (!skeletonData) { - printf("Error: %s\n", json->error); - exit(0); - } - SkeletonJson_dispose(json); - +void goblins (SkeletonData* skeletonData, Atlas* atlas) { SkeletonDrawable* drawable = new SkeletonDrawable(skeletonData); drawable->timeScale = 1; @@ -178,23 +195,9 @@ void goblins () { window.draw(*drawable); window.display(); } - - SkeletonData_dispose(skeletonData); - Atlas_dispose(atlas); } -void raptor () { - // Load atlas, skeleton, and animations. - Atlas* atlas = Atlas_createFromFile("data/raptor.atlas", 0); - SkeletonJson* json = SkeletonJson_create(atlas); - json->scale = 0.5f; - SkeletonData *skeletonData = SkeletonJson_readSkeletonDataFile(json, "data/raptor.json"); - if (!skeletonData) { - printf("Error: %s\n", json->error); - exit(0); - } - SkeletonJson_dispose(json); - +void raptor (SkeletonData* skeletonData, Atlas* atlas) { SkeletonDrawable* drawable = new SkeletonDrawable(skeletonData); drawable->timeScale = 1; @@ -223,23 +226,9 @@ void raptor () { window.draw(*drawable); window.display(); } - - SkeletonData_dispose(skeletonData); - Atlas_dispose(atlas); } -void tank () { - // Load atlas, skeleton, and animations. - Atlas* atlas = Atlas_createFromFile("data/tank.atlas", 0); - SkeletonJson* json = SkeletonJson_create(atlas); - json->scale = 0.2f; - SkeletonData *skeletonData = SkeletonJson_readSkeletonDataFile(json, "data/tank.json"); - if (!skeletonData) { - printf("Error: %s\n", json->error); - exit(0); - } - SkeletonJson_dispose(json); - +void tank (SkeletonData* skeletonData, Atlas* atlas) { SkeletonDrawable* drawable = new SkeletonDrawable(skeletonData); drawable->timeScale = 1; @@ -266,23 +255,9 @@ void tank () { window.draw(*drawable); window.display(); } - - SkeletonData_dispose(skeletonData); - Atlas_dispose(atlas); } -void vine () { - // Load atlas, skeleton, and animations. - Atlas* atlas = Atlas_createFromFile("data/vine.atlas", 0); - SkeletonJson* json = SkeletonJson_create(atlas); - json->scale = 0.5f; - SkeletonData *skeletonData = SkeletonJson_readSkeletonDataFile(json, "data/vine.json"); - if (!skeletonData) { - printf("Error: %s\n", json->error); - exit(0); - } - SkeletonJson_dispose(json); - +void vine (SkeletonData* skeletonData, Atlas* atlas) { SkeletonDrawable* drawable = new SkeletonDrawable(skeletonData); drawable->timeScale = 1; @@ -310,26 +285,12 @@ void vine () { window.draw(*drawable); window.display(); } - - SkeletonData_dispose(skeletonData); - Atlas_dispose(atlas); } /** * Used for debugging purposes during runtime development */ -void test () { - // Load atlas, skeleton, and animations. - Atlas* atlas = Atlas_createFromFile("data/tank.atlas", 0); - SkeletonJson* json = SkeletonJson_create(atlas); - json->scale = 1; - SkeletonData *skeletonData = SkeletonJson_readSkeletonDataFile(json, "data/tank.json"); - if (!skeletonData) { - printf("Error: %s\n", json->error); - exit(0); - } - SkeletonJson_dispose(json); - +void test (SkeletonData* skeletonData, Atlas* atlas) { spSkeleton* skeleton = Skeleton_create(skeletonData); spAnimationStateData* animData = spAnimationStateData_create(skeletonData); spAnimationState* animState = spAnimationState_create(animData); @@ -350,16 +311,15 @@ void test () { d += 0.1f; } - SkeletonData_dispose(skeletonData); Skeleton_dispose(skeleton); - Atlas_dispose(atlas); } int main () { - test(); - vine(); - tank(); - raptor(); - spineboy(); - goblins(); + testcase(test, "data/tank.json", "data/tank.skel", "data/tank.atlas", 1.0f); + testcase(vine, "data/vine.json", "data/vine.skel", "data/vine.atlas", 0.5f); + testcase(tank, "data/tank.json", "data/tank.skel", "data/tank.atlas", 0.2f); + testcase(raptor, "data/raptor.json", "data/raptor.skel", "data/raptor.atlas", 0.5f); + testcase(spineboy, "data/spineboy.json", "data/spineboy.skel", "data/spineboy.atlas", 0.6f); + testcase(goblins, "data/goblins-mesh.json", "data/goblins-mesh.skel", "data/goblins-mesh.atlas", 1.4f); + return 0; }