[c] Implement binary skeleton loader. (#680)

* [c] Implement binary skeleton loader.

* [sfml] Use skeleton binary loader in example.

* [c] Remove spAnimation_createWithTimelines.
This commit is contained in:
Pavel Platto 2016-08-24 10:42:08 +02:00 committed by Mario Zechner
parent 59872a1cb9
commit 278dfba922
12 changed files with 1325 additions and 173 deletions

View File

@ -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 <spine/Attachment.h>
#include <spine/AttachmentLoader.h>
#include <spine/SkeletonData.h>
#include <spine/Atlas.h>
#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_ */

View File

@ -48,6 +48,7 @@
#include <spine/Skeleton.h>
#include <spine/SkeletonBounds.h>
#include <spine/SkeletonData.h>
#include <spine/SkeletonBinary.h>
#include <spine/SkeletonJson.h>
#include <spine/Skin.h>
#include <spine/Slot.h>

File diff suppressed because it is too large Load Diff

92
spine-c/src/spine/kvec.h Normal file
View File

@ -0,0 +1,92 @@
/* The MIT License
Copyright (c) 2008, by Attractive Chaos <attractor@live.co.uk>
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 <stdlib.h>
#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

Binary file not shown.

BIN
spine-sfml/data/raptor.skel Normal file

Binary file not shown.

Binary file not shown.

BIN
spine-sfml/data/tank.skel Normal file

Binary file not shown.

View File

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

File diff suppressed because one or more lines are too long

BIN
spine-sfml/data/vine.skel Normal file

Binary file not shown.

View File

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