update spine runtime to v2.1.25

This commit is contained in:
minggo 2015-04-14 15:23:16 +08:00
parent 4aaa494be7
commit c62b34ac01
34 changed files with 512 additions and 98 deletions

View File

@ -602,7 +602,7 @@ void _spDrawOrderTimeline_apply (const spTimeline* timeline, spSkeleton* skeleto
drawOrderToSetupIndex = self->drawOrders[frameIndex];
if (!drawOrderToSetupIndex)
memcpy(skeleton->drawOrder, skeleton->slots, self->slotsCount * sizeof(int));
memcpy(skeleton->drawOrder, skeleton->slots, self->slotsCount * sizeof(spSlot*));
else {
for (i = 0; i < self->slotsCount; ++i)
skeleton->drawOrder[i] = skeleton->slots[drawOrderToSetupIndex[i]];
@ -659,12 +659,8 @@ void _spFFDTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, flo
spSlot *slot = skeleton->slots[self->slotIndex];
if (slot->attachment != self->attachment) return;
if (time < self->frames[0]) {
slot->attachmentVerticesCount = 0;
return; /* Time is before first frame. */
}
if (time < self->frames[0]) return; /* Time is before first frame. */
if (slot->attachmentVerticesCount != self->frameVerticesCount) alpha = 1; // Don't mix from uninitialized slot vertices.
if (slot->attachmentVerticesCount < self->frameVerticesCount) {
if (slot->attachmentVerticesCapacity < self->frameVerticesCount) {
FREE(slot->attachmentVertices);
@ -672,6 +668,7 @@ void _spFFDTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, flo
slot->attachmentVerticesCapacity = self->frameVerticesCount;
}
}
if (slot->attachmentVerticesCount != self->frameVerticesCount) alpha = 1; /* Don't mix from uninitialized slot vertices. */
slot->attachmentVerticesCount = self->frameVerticesCount;
if (time >= self->frames[self->framesCount - 1]) {
@ -789,3 +786,51 @@ void spIkConstraintTimeline_setFrame (spIkConstraintTimeline* self, int frameInd
self->frames[frameIndex + 1] = mix;
self->frames[frameIndex + 2] = (float)bendDirection;
}
/**/
void _spFlipTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
spEvent** firedEvents, int* eventsCount, float alpha) {
int frameIndex;
spFlipTimeline* self = (spFlipTimeline*)timeline;
if (time < self->frames[0]) {
if (lastTime > time) _spFlipTimeline_apply(timeline, skeleton, lastTime, (float)INT_MAX, 0, 0, 0);
return;
} else if (lastTime > time) /**/
lastTime = -1;
frameIndex = (time >= self->frames[self->framesCount - 2] ?
self->framesCount : binarySearch(self->frames, self->framesCount, time, 2)) - 2;
if (self->frames[frameIndex] < lastTime) return;
if (self->x)
skeleton->bones[self->boneIndex]->flipX = (int)self->frames[frameIndex + 1];
else
skeleton->bones[self->boneIndex]->flipY = (int)self->frames[frameIndex + 1];
}
void _spFlipTimeline_dispose (spTimeline* timeline) {
spFlipTimeline* self = SUB_CAST(spFlipTimeline, timeline);
_spTimeline_deinit(SUPER(self));
FREE(self->frames);
FREE(self);
}
spFlipTimeline* spFlipTimeline_create (int framesCount, int/*bool*/x) {
spFlipTimeline* self = NEW(spFlipTimeline);
_spTimeline_init(SUPER(self), x ? SP_TIMELINE_FLIPX : SP_TIMELINE_FLIPY, _spFlipTimeline_dispose, _spFlipTimeline_apply);
CONST_CAST(int, self->x) = x;
CONST_CAST(int, self->framesCount) = framesCount << 1;
CONST_CAST(float*, self->frames) = CALLOC(float, self->framesCount);
return self;
}
void spFlipTimeline_setFrame (spFlipTimeline* self, int frameIndex, float time, int/*bool*/flip) {
frameIndex <<= 1;
self->frames[frameIndex] = time;
self->frames[frameIndex + 1] = (float)flip;
}
/**/

View File

@ -41,12 +41,21 @@ extern "C" {
typedef struct spTimeline spTimeline;
struct spSkeleton;
typedef struct {
typedef struct spAnimation {
const char* const name;
float duration;
int timelinesCount;
spTimeline** timelines;
#ifdef __cplusplus
spAnimation() :
name(0),
duration(0),
timelinesCount(0),
timelines(0) {
}
#endif
} spAnimation;
spAnimation* spAnimation_create (const char* name, int timelinesCount);
@ -84,13 +93,21 @@ typedef enum {
SP_TIMELINE_EVENT,
SP_TIMELINE_DRAWORDER,
SP_TIMELINE_FFD,
SP_TIMELINE_IKCONSTRAINT
SP_TIMELINE_IKCONSTRAINT,
SP_TIMELINE_FLIPX,
SP_TIMELINE_FLIPY
} spTimelineType;
struct spTimeline {
const spTimelineType type;
const void* const vtable;
#ifdef __cplusplus
spTimeline() :
type(SP_TIMELINE_SCALE),
vtable(0) {
}
#endif
};
void spTimeline_dispose (spTimeline* self);
@ -112,9 +129,16 @@ typedef spTimeline Timeline;
/**/
typedef struct {
typedef struct spCurveTimeline {
spTimeline super;
float* curves; /* type, x, y, ... */
#ifdef __cplusplus
spCurveTimeline() :
super(),
curves(0) {
}
#endif
} spCurveTimeline;
void spCurveTimeline_setLinear (spCurveTimeline* self, int frameIndex);
@ -141,7 +165,20 @@ typedef struct spBaseTimeline {
int const framesCount;
float* const frames; /* time, angle, ... for rotate. time, x, y, ... for translate and scale. */
int boneIndex;
} spRotateTimeline;
#ifdef __cplusplus
spBaseTimeline() :
super(),
framesCount(0),
frames(0),
boneIndex(0) {
}
#endif
} spBaseTimeline;
/**/
typedef struct spBaseTimeline spRotateTimeline;
spRotateTimeline* spRotateTimeline_create (int framesCount);
@ -183,11 +220,20 @@ typedef spScaleTimeline ScaleTimeline;
/**/
typedef struct {
typedef struct spColorTimeline {
spCurveTimeline super;
int const framesCount;
float* const frames; /* time, r, g, b, a, ... */
int slotIndex;
#ifdef __cplusplus
spColorTimeline() :
super(),
framesCount(0),
frames(0),
slotIndex(0) {
}
#endif
} spColorTimeline;
spColorTimeline* spColorTimeline_create (int framesCount);
@ -202,12 +248,22 @@ typedef spColorTimeline ColorTimeline;
/**/
typedef struct {
typedef struct spAttachmentTimeline {
spTimeline super;
int const framesCount;
float* const frames; /* time, ... */
int slotIndex;
const char** const attachmentNames;
#ifdef __cplusplus
spAttachmentTimeline() :
super(),
framesCount(0),
frames(0),
slotIndex(0),
attachmentNames(0) {
}
#endif
} spAttachmentTimeline;
spAttachmentTimeline* spAttachmentTimeline_create (int framesCount);
@ -223,11 +279,20 @@ typedef spAttachmentTimeline AttachmentTimeline;
/**/
typedef struct {
typedef struct spEventTimeline {
spTimeline super;
int const framesCount;
float* const frames; /* time, ... */
spEvent** const events;
#ifdef __cplusplus
spEventTimeline() :
super(),
framesCount(0),
frames(0),
events(0) {
}
#endif
} spEventTimeline;
spEventTimeline* spEventTimeline_create (int framesCount);
@ -242,12 +307,22 @@ typedef spEventTimeline EventTimeline;
/**/
typedef struct {
typedef struct spDrawOrderTimeline {
spTimeline super;
int const framesCount;
float* const frames; /* time, ... */
const int** const drawOrders;
int const slotsCount;
#ifdef __cplusplus
spDrawOrderTimeline() :
super(),
framesCount(0),
frames(0),
drawOrders(0),
slotsCount(0) {
}
#endif
} spDrawOrderTimeline;
spDrawOrderTimeline* spDrawOrderTimeline_create (int framesCount, int slotsCount);
@ -262,7 +337,7 @@ typedef spDrawOrderTimeline DrawOrderTimeline;
/**/
typedef struct {
typedef struct spFFDTimeline {
spCurveTimeline super;
int const framesCount;
float* const frames; /* time, ... */
@ -270,6 +345,17 @@ typedef struct {
const float** const frameVertices;
int slotIndex;
spAttachment* attachment;
#ifdef __cplusplus
spFFDTimeline() :
super(),
framesCount(0),
frames(0),
frameVerticesCount(0),
frameVertices(0),
slotIndex(0) {
}
#endif
} spFFDTimeline;
spFFDTimeline* spFFDTimeline_create (int framesCount, int frameVerticesCount);
@ -284,11 +370,20 @@ typedef spFFDTimeline FFDTimeline;
/**/
typedef struct {
typedef struct spIkConstraintTimeline {
spCurveTimeline super;
int const framesCount;
float* const frames; /* time, mix, bendDirection, ... */
int ikConstraintIndex;
#ifdef __cplusplus
spIkConstraintTimeline() :
super(),
framesCount(0),
frames(0),
ikConstraintIndex(0) {
}
#endif
} spIkConstraintTimeline;
spIkConstraintTimeline* spIkConstraintTimeline_create (int framesCount);
@ -304,6 +399,36 @@ typedef spIkConstraintTimeline IkConstraintTimeline;
/**/
typedef struct spFlipTimeline {
spTimeline super;
int const x;
int const framesCount;
float* const frames; /* time, flip, ... */
int boneIndex;
#ifdef __cplusplus
spFlipTimeline() :
super(),
x(0),
framesCount(0),
frames(0),
boneIndex(0) {
}
#endif
} spFlipTimeline;
spFlipTimeline* spFlipTimeline_create (int framesCount, int/*bool*/x);
void spFlipTimeline_setFrame (spFlipTimeline* self, int frameIndex, float time, int/*bool*/flip);
#ifdef SPINE_SHORT_NAMES
typedef spFlipTimeline FlipTimeline;
#define FlipTimeline_create(...) spFlipTimeline_create(__VA_ARGS__)
#define FlipTimeline_setFrame(...) spFlipTimeline_setFrame(__VA_ARGS__)
#endif
/**/
#ifdef __cplusplus
}
#endif

View File

@ -60,6 +60,20 @@ struct spTrackEntry {
float mixTime, mixDuration, mix;
void* rendererObject;
#ifdef __cplusplus
spTrackEntry() :
state(0),
next(0),
previous(0),
animation(0),
loop(0),
delay(0), time(0), lastTime(0), endTime(0), timeScale(0),
listener(0),
mixTime(0), mixDuration(0), mix(0),
rendererObject(0) {
}
#endif
};
struct spAnimationState {
@ -71,6 +85,17 @@ struct spAnimationState {
spTrackEntry** tracks;
void* rendererObject;
#ifdef __cplusplus
spAnimationState() :
data(0),
timeScale(0),
listener(0),
tracksCount(0),
tracks(0),
rendererObject(0) {
}
#endif
};
/* @param data May be 0 for no mixing. */

View File

@ -38,10 +38,18 @@
extern "C" {
#endif
typedef struct {
typedef struct spAnimationStateData {
spSkeletonData* const skeletonData;
float defaultMix;
const void* const entries;
#ifdef __cplusplus
spAnimationStateData() :
skeletonData(0),
defaultMix(0),
entries(0) {
}
#endif
} spAnimationStateData;
spAnimationStateData* spAnimationStateData_create (spSkeletonData* skeletonData);

View File

@ -120,7 +120,7 @@ static int readValue (const char* end, Str* str) {
/* Returns the number of tuple values read (1, 2, 4, or 0 for failure). */
static int readTuple (const char* end, Str tuple[]) {
int i;
Str str;
Str str = {NULL, NULL};
readLine(0, end, &str);
if (!beginPast(&str, ':')) return 0;

View File

@ -38,7 +38,7 @@
extern "C" {
#endif
typedef struct {
typedef struct spAtlasAttachmentLoader {
spAttachmentLoader super;
spAtlas* atlas;
} spAtlasAttachmentLoader;

View File

@ -35,19 +35,23 @@
extern "C" {
#endif
struct spSlot;
typedef enum {
SP_ATTACHMENT_REGION, SP_ATTACHMENT_BOUNDING_BOX, SP_ATTACHMENT_MESH, SP_ATTACHMENT_SKINNED_MESH
} spAttachmentType;
typedef struct spAttachment spAttachment;
struct spAttachment {
typedef struct spAttachment {
const char* const name;
const spAttachmentType type;
const void* const vtable;
};
#ifdef __cplusplus
spAttachment() :
name(0),
type(SP_ATTACHMENT_REGION),
vtable(0) {
}
#endif
} spAttachment;
void spAttachment_dispose (spAttachment* self);

View File

@ -38,8 +38,7 @@
extern "C" {
#endif
typedef struct spAttachmentLoader spAttachmentLoader;
struct spAttachmentLoader {
typedef struct spAttachmentLoader {
const char* error1;
const char* error2;
@ -51,7 +50,7 @@ struct spAttachmentLoader {
vtable(0) {
}
#endif
};
} spAttachmentLoader;
void spAttachmentLoader_dispose (spAttachmentLoader* self);

View File

@ -37,6 +37,10 @@ void spBone_setYDown (int value) {
yDown = value;
}
int spBone_isYDown () {
return yDown;
}
spBone* spBone_create (spBoneData* data, spSkeleton* skeleton, spBone* parent) {
spBone* self = NEW(spBone);
CONST_CAST(spBoneData*, self->data) = data;
@ -64,24 +68,29 @@ void spBone_updateWorldTransform (spBone* self) {
}
CONST_CAST(float, self->worldRotation) =
self->data->inheritRotation ? self->parent->worldRotation + self->rotationIK : self->rotationIK;
CONST_CAST(int, self->worldFlipX) = self->parent->worldFlipX ^ self->flipX;
CONST_CAST(int, self->worldFlipY) = self->parent->worldFlipY ^ self->flipY;
} else {
int skeletonFlipX = self->skeleton->flipX, skeletonFlipY = self->skeleton->flipY;
CONST_CAST(float, self->worldX) = self->skeleton->flipX ? -self->x : self->x;
CONST_CAST(float, self->worldY) = self->skeleton->flipY != yDown ? -self->y : self->y;
CONST_CAST(float, self->worldScaleX) = self->scaleX;
CONST_CAST(float, self->worldScaleY) = self->scaleY;
CONST_CAST(float, self->worldRotation) = self->rotationIK;
CONST_CAST(int, self->worldFlipX) = skeletonFlipX ^ self->flipX;
CONST_CAST(int, self->worldFlipY) = skeletonFlipY ^ self->flipY;
}
radians = self->worldRotation * DEG_RAD;
cosine = COS(radians);
sine = SIN(radians);
if (self->skeleton->flipX) {
if (self->worldFlipX) {
CONST_CAST(float, self->m00) = -cosine * self->worldScaleX;
CONST_CAST(float, self->m01) = sine * self->worldScaleY;
} else {
CONST_CAST(float, self->m00) = cosine * self->worldScaleX;
CONST_CAST(float, self->m01) = -sine * self->worldScaleY;
}
if (self->skeleton->flipY != yDown) {
if (self->worldFlipY != yDown) {
CONST_CAST(float, self->m10) = -sine * self->worldScaleX;
CONST_CAST(float, self->m11) = -cosine * self->worldScaleY;
} else {
@ -97,13 +106,15 @@ void spBone_setToSetupPose (spBone* self) {
self->rotationIK = self->rotation;
self->scaleX = self->data->scaleX;
self->scaleY = self->data->scaleY;
self->flipX = self->data->flipX;
self->flipY = self->data->flipY;
}
void spBone_worldToLocal (spBone* self, float worldX, float worldY, float* localX, float* localY) {
float invDet;
float dx = worldX - self->worldX, dy = worldY - self->worldY;
float m00 = self->m00, m11 = self->m11;
if (self->skeleton->flipX != (self->skeleton->flipY != yDown)) {
if (self->worldFlipX != (self->worldFlipY != yDown)) {
m00 *= -1;
m11 *= -1;
}

View File

@ -47,14 +47,35 @@ struct spBone {
float x, y;
float rotation, rotationIK;
float scaleX, scaleY;
int/*bool*/flipX, flipY;
float const m00, m01, worldX; /* a b x */
float const m10, m11, worldY; /* c d y */
float const worldRotation;
float const worldScaleX, worldScaleY;
int/*bool*/const worldFlipX, worldFlipY;
#ifdef __cplusplus
spBone() :
data(0),
skeleton(0),
parent(0),
x(0), y(0),
rotation(0), rotationIK(0),
scaleX(0), scaleY(0),
flipX(0), flipY(0),
m00(0), m01(0), worldX(0),
m10(0), m11(0), worldY(0),
worldRotation(0),
worldScaleX(0), worldScaleY(0),
worldFlipX(0), worldFlipY(0) {
}
#endif
};
void spBone_setYDown (int/*bool*/yDown);
int/*bool*/spBone_isYDown ();
/* @param parent May be 0. */
spBone* spBone_create (spBoneData* data, struct spSkeleton* skeleton, spBone* parent);
@ -70,6 +91,7 @@ void spBone_localToWorld (spBone* self, float localX, float localY, float* world
#ifdef SPINE_SHORT_NAMES
typedef spBone Bone;
#define Bone_setYDown(...) spBone_setYDown(__VA_ARGS__)
#define Bone_isYDown() spBone_isYDown()
#define Bone_create(...) spBone_create(__VA_ARGS__)
#define Bone_dispose(...) spBone_dispose(__VA_ARGS__)
#define Bone_setToSetupPose(...) spBone_setToSetupPose(__VA_ARGS__)

View File

@ -43,7 +43,21 @@ struct spBoneData {
float x, y;
float rotation;
float scaleX, scaleY;
int/*bool*/flipX, flipY;
int/*bool*/inheritScale, inheritRotation;
#ifdef __cplusplus
spBoneData() :
name(0),
parent(0),
length(0),
x(0), y(0),
rotation(0),
scaleX(0), scaleY(0),
flipX(0), flipY(0),
inheritScale(0), inheritRotation(0) {
}
#endif
};
spBoneData* spBoneData_create (const char* name, spBoneData* parent);

View File

@ -39,12 +39,11 @@
extern "C" {
#endif
typedef struct spBoundingBoxAttachment spBoundingBoxAttachment;
struct spBoundingBoxAttachment {
typedef struct spBoundingBoxAttachment {
spAttachment super;
int verticesCount;
float* vertices;
};
} spBoundingBoxAttachment;
spBoundingBoxAttachment* spBoundingBoxAttachment_create (const char* name);
void spBoundingBoxAttachment_computeWorldVertices (spBoundingBoxAttachment* self, spBone* bone, float* vertices);

View File

@ -37,13 +37,21 @@
extern "C" {
#endif
typedef struct spEvent spEvent;
struct spEvent {
typedef struct spEvent {
spEventData* const data;
int intValue;
float floatValue;
const char* stringValue;
};
#ifdef __cplusplus
spEvent() :
data(0),
intValue(0),
floatValue(0),
stringValue(0) {
}
#endif
} spEvent;
spEvent* spEvent_create (spEventData* data);
void spEvent_dispose (spEvent* self);

View File

@ -35,13 +35,21 @@
extern "C" {
#endif
typedef struct spEventData spEventData;
struct spEventData {
typedef struct spEventData {
const char* const name;
int intValue;
float floatValue;
const char* stringValue;
};
#ifdef __cplusplus
spEventData() :
name(0),
intValue(0),
floatValue(0),
stringValue(0) {
}
#endif
} spEventData;
spEventData* spEventData_create (const char* name);
void spEventData_dispose (spEventData* self);

View File

@ -69,7 +69,9 @@ void spIkConstraint_apply (spIkConstraint* self) {
void spIkConstraint_apply1 (spBone* bone, float targetX, float targetY, float alpha) {
float parentRotation = (!bone->data->inheritRotation || !bone->parent) ? 0 : bone->parent->worldRotation;
float rotation = bone->rotation;
float rotationIK = ATAN2(targetY - bone->worldY, targetX - bone->worldX) * RAD_DEG - parentRotation;
float rotationIK = ATAN2(targetY - bone->worldY, targetX - bone->worldX) * RAD_DEG;
if (bone->worldFlipX != (bone->worldFlipY != spBone_isYDown())) rotationIK = -rotationIK;
rotationIK -= parentRotation;
bone->rotationIK = rotation + (rotationIK - rotation) * alpha;
}

View File

@ -40,8 +40,7 @@ extern "C" {
struct spSkeleton;
typedef struct spIkConstraint spIkConstraint;
struct spIkConstraint {
typedef struct spIkConstraint {
spIkConstraintData* const data;
int bonesCount;
@ -50,7 +49,18 @@ struct spIkConstraint {
spBone* target;
int bendDirection;
float mix;
};
#ifdef __cplusplus
spIkConstraint() :
data(0),
bonesCount(0),
bones(0),
target(0),
bendDirection(0),
mix(0) {
}
#endif
} spIkConstraint;
spIkConstraint* spIkConstraint_create (spIkConstraintData* data, const struct spSkeleton* skeleton);
void spIkConstraint_dispose (spIkConstraint* self);

View File

@ -37,8 +37,7 @@
extern "C" {
#endif
typedef struct spIkConstraintData spIkConstraintData;
struct spIkConstraintData {
typedef struct spIkConstraintData {
const char* const name;
int bonesCount;
@ -47,7 +46,18 @@ struct spIkConstraintData {
spBoneData* target;
int bendDirection;
float mix;
};
#ifdef __cplusplus
spIkConstraintData() :
name(0),
bonesCount(0),
bones(0),
target(0),
bendDirection(0),
mix(0) {
}
#endif
} spIkConstraintData;
spIkConstraintData* spIkConstraintData_create (const char* name);
void spIkConstraintData_dispose (spIkConstraintData* self);

View File

@ -39,8 +39,7 @@
extern "C" {
#endif
typedef struct spMeshAttachment spMeshAttachment;
struct spMeshAttachment {
typedef struct spMeshAttachment {
spAttachment super;
const char* path;
@ -67,7 +66,7 @@ struct spMeshAttachment {
int edgesCount;
int* edges;
float width, height;
};
} spMeshAttachment;
spMeshAttachment* spMeshAttachment_create (const char* name);
void spMeshAttachment_updateUVs (spMeshAttachment* self);

View File

@ -43,8 +43,7 @@ typedef enum {
SP_VERTEX_X1 = 0, SP_VERTEX_Y1, SP_VERTEX_X2, SP_VERTEX_Y2, SP_VERTEX_X3, SP_VERTEX_Y3, SP_VERTEX_X4, SP_VERTEX_Y4
} spVertexIndex;
typedef struct spRegionAttachment spRegionAttachment;
struct spRegionAttachment {
typedef struct spRegionAttachment {
spAttachment super;
const char* path;
float x, y, scaleX, scaleY, rotation, width, height;
@ -57,7 +56,7 @@ struct spRegionAttachment {
float offset[8];
float uvs[8];
};
} spRegionAttachment;
spRegionAttachment* spRegionAttachment_create (const char* name);
void spRegionAttachment_setUVs (spRegionAttachment* self, float u, float v, float u2, float v2, int/*bool*/rotate);

View File

@ -40,8 +40,7 @@
extern "C" {
#endif
typedef struct spSkeleton spSkeleton;
struct spSkeleton {
typedef struct spSkeleton {
spSkeletonData* const data;
int bonesCount;
@ -60,7 +59,29 @@ struct spSkeleton {
float time;
int/*bool*/flipX, flipY;
float x, y;
};
#ifdef __cplusplus
spSkeleton() :
data(0),
bonesCount(0),
bones(0),
root(0),
slotsCount(0),
slots(0),
drawOrder(0),
ikConstraintsCount(0),
ikConstraints(0),
skin(0),
r(0), g(0), b(0), a(0),
time(0),
flipX(0),
flipY(0),
x(0), y(0) {
}
#endif
} spSkeleton;
spSkeleton* spSkeleton_create (spSkeletonData* data);
void spSkeleton_dispose (spSkeleton* self);
@ -83,8 +104,9 @@ spSlot* spSkeleton_findSlot (const spSkeleton* self, const char* slotName);
/* Returns -1 if the slot was not found. */
int spSkeleton_findSlotIndex (const spSkeleton* self, const char* slotName);
/* Sets the skin used to look up attachments not found in the SkeletonData defaultSkin. Attachments from the new skin are
* attached if the corresponding attachment from the old skin was attached.
/* Sets the skin used to look up attachments before looking in the SkeletonData defaultSkin. Attachments from the new skin are
* attached if the corresponding attachment from the old skin was attached. If there was no old skin, each slot's setup mode
* attachment is attached from the new skin.
* @param skin May be 0.*/
void spSkeleton_setSkin (spSkeleton* self, spSkin* skin);
/* Returns 0 if the skin was not found. See spSkeleton_setSkin.
@ -95,7 +117,8 @@ int spSkeleton_setSkinByName (spSkeleton* self, const char* skinName);
spAttachment* spSkeleton_getAttachmentForSlotName (const spSkeleton* self, const char* slotName, const char* attachmentName);
/* Returns 0 if the slot or attachment was not found. */
spAttachment* spSkeleton_getAttachmentForSlotIndex (const spSkeleton* self, int slotIndex, const char* attachmentName);
/* Returns 0 if the slot or attachment was not found. */
/* Returns 0 if the slot or attachment was not found.
* @param attachmentName May be 0. */
int spSkeleton_setAttachment (spSkeleton* self, const char* slotName, const char* attachmentName);
/* Returns 0 if the IK constraint was not found. */

View File

@ -98,6 +98,10 @@ void SkeletonAnimation::initialize () {
stateInternal->disposeTrackEntry = disposeTrackEntry;
}
SkeletonAnimation::SkeletonAnimation ()
: SkeletonRenderer() {
}
SkeletonAnimation::SkeletonAnimation (spSkeletonData *skeletonData)
: SkeletonRenderer(skeletonData) {
initialize();

View File

@ -76,7 +76,7 @@ public:
spAnimationState* getState() const;
protected:
CC_CONSTRUCTOR_ACCESS:
SkeletonAnimation ();
SkeletonAnimation (spSkeletonData* skeletonData);
SkeletonAnimation (const std::string&skeletonDataFile, spAtlas* atlas, float scale = 1);
@ -84,6 +84,7 @@ protected:
virtual ~SkeletonAnimation ();
void initialize ();
protected:
spAnimationState* _state;
bool _ownsAnimationStateData;

View File

@ -38,7 +38,7 @@
extern "C" {
#endif
typedef struct {
typedef struct spPolygon {
float* const vertices;
int count;
int capacity;
@ -60,7 +60,7 @@ typedef spPolygon Polygon;
/**/
typedef struct {
typedef struct spSkeletonBounds {
int count;
spBoundingBoxAttachment** boundingBoxes;
spPolygon** polygons;

View File

@ -62,6 +62,9 @@ void spSkeletonData_dispose (spSkeletonData* self) {
spIkConstraintData_dispose(self->ikConstraints[i]);
FREE(self->ikConstraints);
FREE(self->hash);
FREE(self->version);
FREE(self);
}

View File

@ -42,7 +42,7 @@
extern "C" {
#endif
typedef struct {
typedef struct spSkeletonData {
const char* version;
const char* hash;
float width, height;

View File

@ -65,7 +65,7 @@ void _spSkeletonJson_setError (spSkeletonJson* self, Json* root, const char* val
FREE(self->error);
strcpy(message, value1);
length = (int)strlen(value1);
if (value2) strncat(message + length, value2, 256 - length);
if (value2) strncat(message + length, value2, 255 - length);
MALLOC_STR(self->error, message);
if (root) Json_dispose(root);
}
@ -106,16 +106,19 @@ static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* r
spAnimation* animation;
Json* frame;
float duration;
int timelinesCount = 0;
Json* bones = Json_getItem(root, "bones");
Json* slots = Json_getItem(root, "slots");
Json* ik = Json_getItem(root, "ik");
Json* ffd = Json_getItem(root, "ffd");
Json* drawOrder = Json_getItem(root, "draworder");
Json* drawOrder = Json_getItem(root, "drawOrder");
Json* events = Json_getItem(root, "events");
Json* flipX = Json_getItem(root, "flipx");
Json* flipY = Json_getItem(root, "flipy");
Json *boneMap, *slotMap, *ikMap, *ffdMap;
if (!drawOrder) drawOrder = Json_getItem(root, "draworder");
int timelinesCount = 0;
for (boneMap = bones ? bones->child : 0; boneMap; boneMap = boneMap->next)
timelinesCount += boneMap->size;
for (slotMap = slots ? slots->child : 0; slotMap; slotMap = slotMap->next)
@ -124,8 +127,10 @@ static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* r
for (ffdMap = ffd ? ffd->child : 0; ffdMap; ffdMap = ffdMap->next)
for (slotMap = ffdMap->child; slotMap; slotMap = slotMap->next)
timelinesCount += slotMap->size;
if (events) ++timelinesCount;
if (drawOrder) ++timelinesCount;
if (events) ++timelinesCount;
if (flipX) ++timelinesCount;
if (flipY) ++timelinesCount;
animation = spAnimation_create(root->name, timelinesCount);
animation->timelinesCount = 0;
@ -214,6 +219,17 @@ static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* r
animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
duration = timeline->frames[timelineArray->size * 3 - 3];
if (duration > animation->duration) animation->duration = duration;
} else if (strcmp(timelineArray->name, "flipX") == 0 || strcmp(timelineArray->name, "flipY") == 0) {
int x = strcmp(timelineArray->name, "flipX") == 0;
const char* field = x ? "x" : "y";
spFlipTimeline *timeline = spFlipTimeline_create(timelineArray->size, x);
timeline->boneIndex = boneIndex;
for (frame = timelineArray->child, i = 0; frame; frame = frame->next, ++i)
spFlipTimeline_setFrame(timeline, i, Json_getFloat(frame, "time", 0), Json_getInt(frame, field, 0));
animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
duration = timeline->frames[timelineArray->size * 2 - 2];
if (duration > animation->duration) animation->duration = duration;
} else {
spAnimation_dispose(animation);
_spSkeletonJson_setError(self, 0, "Invalid timeline type for a bone: ", timelineArray->name);
@ -418,8 +434,8 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
skeleton = Json_getItem(root, "skeleton");
if (skeleton) {
skeletonData->hash = Json_getString(skeleton, "hash", 0);
skeletonData->version = Json_getString(skeleton, "spine", 0);
MALLOC_STR(skeletonData->hash, Json_getString(skeleton, "hash", 0));
MALLOC_STR(skeletonData->version, Json_getString(skeleton, "spine", 0));
skeletonData->width = Json_getFloat(skeleton, "width", 0);
skeletonData->height = Json_getFloat(skeleton, "height", 0);
}
@ -450,6 +466,8 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
boneData->scaleY = Json_getFloat(boneMap, "scaleY", 1);
boneData->inheritScale = Json_getInt(boneMap, "inheritScale", 1);
boneData->inheritRotation = Json_getInt(boneMap, "inheritRotation", 1);
boneData->flipX = Json_getInt(boneMap, "flipX", 0);
boneData->flipY = Json_getInt(boneMap, "flipY", 0);
skeletonData->bones[i] = boneData;
skeletonData->bonesCount++;

View File

@ -41,7 +41,7 @@
extern "C" {
#endif
typedef struct {
typedef struct spSkeletonJson {
float scale;
spAttachmentLoader* attachmentLoader;
const char* const error;

View File

@ -75,7 +75,6 @@ void SkeletonRenderer::initialize () {
setOpacityModifyRGB(true);
setGLProgram(ShaderCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR));
scheduleUpdate();
}
void SkeletonRenderer::setSkeletonData (spSkeletonData *skeletonData, bool ownsSkeletonData) {
@ -84,18 +83,35 @@ void SkeletonRenderer::setSkeletonData (spSkeletonData *skeletonData, bool ownsS
}
SkeletonRenderer::SkeletonRenderer () {
initialize();
}
SkeletonRenderer::SkeletonRenderer (spSkeletonData *skeletonData, bool ownsSkeletonData) {
initialize();
setSkeletonData(skeletonData, ownsSkeletonData);
initWithData(skeletonData, ownsSkeletonData);
}
SkeletonRenderer::SkeletonRenderer (const std::string& skeletonDataFile, spAtlas* atlas, float scale) {
initialize();
initWithFile(skeletonDataFile, atlas, scale);
}
SkeletonRenderer::SkeletonRenderer (const std::string& skeletonDataFile, const std::string& atlasFile, float scale) {
initWithFile(skeletonDataFile, atlasFile, scale);
}
SkeletonRenderer::~SkeletonRenderer () {
if (_ownsSkeletonData) spSkeletonData_dispose(_skeleton->data);
if (_atlas) spAtlas_dispose(_atlas);
spSkeleton_dispose(_skeleton);
_batch->release();
FREE(_worldVertices);
}
void SkeletonRenderer::initWithData (spSkeletonData* skeletonData, bool ownsSkeletonData) {
setSkeletonData(skeletonData, ownsSkeletonData);
initialize();
}
void SkeletonRenderer::initWithFile (const std::string& skeletonDataFile, spAtlas* atlas, float scale) {
spSkeletonJson* json = spSkeletonJson_create(atlas);
json->scale = scale;
spSkeletonData* skeletonData = spSkeletonJson_readSkeletonDataFile(json, skeletonDataFile.c_str());
@ -103,11 +119,11 @@ SkeletonRenderer::SkeletonRenderer (const std::string& skeletonDataFile, spAtlas
spSkeletonJson_dispose(json);
setSkeletonData(skeletonData, true);
initialize();
}
SkeletonRenderer::SkeletonRenderer (const std::string& skeletonDataFile, const std::string& atlasFile, float scale) {
initialize();
void SkeletonRenderer::initWithFile (const std::string& skeletonDataFile, const std::string& atlasFile, float scale) {
_atlas = spAtlas_createFromFile(atlasFile.c_str(), 0);
CCASSERT(_atlas, "Error reading atlas file.");
@ -118,15 +134,10 @@ SkeletonRenderer::SkeletonRenderer (const std::string& skeletonDataFile, const s
spSkeletonJson_dispose(json);
setSkeletonData(skeletonData, true);
initialize();
}
SkeletonRenderer::~SkeletonRenderer () {
if (_ownsSkeletonData) spSkeletonData_dispose(_skeleton->data);
if (_atlas) spAtlas_dispose(_atlas);
spSkeleton_dispose(_skeleton);
_batch->release();
FREE(_worldVertices);
}
void SkeletonRenderer::update (float deltaTime) {
spSkeleton_update(_skeleton, deltaTime * _timeScale);
@ -335,14 +346,20 @@ spSlot* SkeletonRenderer::findSlot (const std::string& slotName) const {
}
bool SkeletonRenderer::setSkin (const std::string& skinName) {
return spSkeleton_setSkinByName(_skeleton, skinName.c_str()) ? true : false;
return spSkeleton_setSkinByName(_skeleton, skinName.empty() ? 0 : skinName.c_str()) ? true : false;
}
bool SkeletonRenderer::setSkin (const char* skinName) {
return spSkeleton_setSkinByName(_skeleton, skinName) ? true : false;
}
spAttachment* SkeletonRenderer::getAttachment (const std::string& slotName, const std::string& attachmentName) const {
return spSkeleton_getAttachmentForSlotName(_skeleton, slotName.c_str(), attachmentName.c_str());
}
bool SkeletonRenderer::setAttachment (const std::string& slotName, const std::string& attachmentName) {
return spSkeleton_setAttachment(_skeleton, slotName.c_str(), attachmentName.c_str()) ? true : false;
return spSkeleton_setAttachment(_skeleton, slotName.c_str(), attachmentName.empty() ? 0 : attachmentName.c_str()) ? true : false;
}
bool SkeletonRenderer::setAttachment (const std::string& slotName, const char* attachmentName) {
return spSkeleton_setAttachment(_skeleton, slotName.c_str(), attachmentName) ? true : false;
}
spSkeleton* SkeletonRenderer::getSkeleton () {
@ -370,6 +387,16 @@ bool SkeletonRenderer::getDebugBonesEnabled () const {
return _debugBones;
}
void SkeletonRenderer::onEnter () {
Node::onEnter();
scheduleUpdate();
}
void SkeletonRenderer::onExit () {
Node::onExit();
unscheduleUpdate();
}
// --- CCBlendProtocol
const BlendFunc& SkeletonRenderer::getBlendFunc () const {

View File

@ -49,6 +49,8 @@ public:
virtual void draw (cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t transformFlags) override;
virtual void drawSkeleton (const cocos2d::Mat4& transform, uint32_t transformFlags);
virtual cocos2d::Rect getBoundingBox () const override;
virtual void onEnter () override;
virtual void onExit () override;
spSkeleton* getSkeleton();
@ -75,13 +77,18 @@ public:
/* Sets the skin used to look up attachments not found in the SkeletonData defaultSkin. Attachments from the new skin are
* attached if the corresponding attachment from the old skin was attached. Returns false if the skin was not found.
* @param skin May be 0.*/
* @param skin May be empty string ("") for no skin.*/
bool setSkin (const std::string& skinName);
/** @param skin May be 0 for no skin.*/
bool setSkin (const char* skinName);
/* Returns 0 if the slot or attachment was not found. */
spAttachment* getAttachment (const std::string& slotName, const std::string& attachmentName) const;
/* Returns false if the slot or attachment was not found. */
/* Returns false if the slot or attachment was not found.
* @param attachmentName May be empty string ("") for no attachment. */
bool setAttachment (const std::string& slotName, const std::string& attachmentName);
/* @param attachmentName May be 0 for no attachment. */
bool setAttachment (const std::string& slotName, const char* attachmentName);
// --- BlendProtocol
virtual void setBlendFunc (const cocos2d::BlendFunc& blendFunc);
@ -89,14 +96,21 @@ public:
virtual void setOpacityModifyRGB (bool value);
virtual bool isOpacityModifyRGB () const;
protected:
CC_CONSTRUCTOR_ACCESS:
SkeletonRenderer ();
SkeletonRenderer (spSkeletonData* skeletonData, bool ownsSkeletonData = false);
SkeletonRenderer (const std::string& skeletonDataFile, spAtlas* atlas, float scale = 1);
SkeletonRenderer (const std::string& skeletonDataFile, const std::string& atlasFile, float scale = 1);
virtual ~SkeletonRenderer ();
void initWithData (spSkeletonData* skeletonData, bool ownsSkeletonData = false);
void initWithFile (const std::string& skeletonDataFile, spAtlas* atlas, float scale = 1);
void initWithFile (const std::string& skeletonDataFile, const std::string& atlasFile, float scale = 1);
void initialize ();
protected:
void setSkeletonData (spSkeletonData* skeletonData, bool ownsSkeletonData);
virtual cocos2d::Texture2D* getTexture (spRegionAttachment* attachment) const;
virtual cocos2d::Texture2D* getTexture (spMeshAttachment* attachment) const;

View File

@ -39,8 +39,14 @@ extern "C" {
struct spSkeleton;
typedef struct {
typedef struct spSkin {
const char* const name;
#ifdef __cplusplus
spSkin() :
name(0) {
}
#endif
} spSkin;
spSkin* spSkin_create (const char* name);

View File

@ -38,8 +38,7 @@
extern "C" {
#endif
typedef struct spSkinnedMeshAttachment spSkinnedMeshAttachment;
struct spSkinnedMeshAttachment {
typedef struct spSkinnedMeshAttachment {
spAttachment super;
const char* path;
@ -70,7 +69,7 @@ struct spSkinnedMeshAttachment {
int edgesCount;
int* edges;
float width, height;
};
} spSkinnedMeshAttachment;
spSkinnedMeshAttachment* spSkinnedMeshAttachment_create (const char* name);
void spSkinnedMeshAttachment_updateUVs (spSkinnedMeshAttachment* self);

View File

@ -48,6 +48,18 @@ typedef struct spSlot {
int attachmentVerticesCapacity;
int attachmentVerticesCount;
float* attachmentVertices;
#ifdef __cplusplus
spSlot() :
data(0),
bone(0),
r(0), b(0), g(0), a(0),
attachment(0),
attachmentVerticesCapacity(0),
attachmentVerticesCount(0),
attachmentVertices(0) {
}
#endif
} spSlot;
spSlot* spSlot_create (spSlotData* data, spBone* bone);

View File

@ -37,12 +37,22 @@
extern "C" {
#endif
typedef struct {
typedef struct spSlotData {
const char* const name;
const spBoneData* const boneData;
const char* attachmentName;
float r, g, b, a;
int/*bool*/additiveBlending;
#ifdef __cplusplus
spSlotData() :
name(0),
boneData(0),
attachmentName(0),
r(0), g(0), b(0), a(0),
additiveBlending(0) {
}
#endif
} spSlotData;
spSlotData* spSlotData_create (const char* name, spBoneData* boneData);

View File

@ -124,12 +124,21 @@ char* _readFile (const char* path, int* length);
/**/
typedef struct {
typedef struct _spAnimationState {
spAnimationState super;
spEvent** events;
spTrackEntry* (*createTrackEntry) (spAnimationState* self);
void (*disposeTrackEntry) (spTrackEntry* entry);
#ifdef __cplusplus
_spAnimationState() :
super(),
events(0),
createTrackEntry(0),
disposeTrackEntry(0) {
}
#endif
} _spAnimationState;
spTrackEntry* _spTrackEntry_create (spAnimationState* self);