mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-05 06:44:56 +08:00
[c] 4.0 port. refactor the way we handle animation and timeline data.
This commit is contained in:
parent
285da8c43f
commit
a4c5b9937f
@ -33,6 +33,7 @@
|
||||
#include <spine/dll.h>
|
||||
#include <spine/Event.h>
|
||||
#include <spine/Attachment.h>
|
||||
#include <spine/Array.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -40,13 +41,17 @@ extern "C" {
|
||||
|
||||
typedef struct spTimeline spTimeline;
|
||||
struct spSkeleton;
|
||||
typedef unsigned long long spPropertyId;
|
||||
|
||||
_SP_ARRAY_DECLARE_TYPE(spPropertyIdArray, spPropertyId)
|
||||
_SP_ARRAY_DECLARE_TYPE(spTimelineArray, spTimeline*)
|
||||
|
||||
typedef struct spAnimation {
|
||||
const char* const name;
|
||||
float duration;
|
||||
|
||||
int timelinesCount;
|
||||
spTimeline** timelines;
|
||||
spTimelineArray *timelines;
|
||||
spPropertyIdArray *timelineIds;
|
||||
} spAnimation;
|
||||
|
||||
typedef enum {
|
||||
@ -61,8 +66,9 @@ typedef enum {
|
||||
SP_MIX_DIRECTION_OUT
|
||||
} spMixDirection;
|
||||
|
||||
SP_API spAnimation* spAnimation_create (const char* name, int timelinesCount);
|
||||
SP_API spAnimation* spAnimation_create (const char* name, spTimelineArray* timelines);
|
||||
SP_API void spAnimation_dispose (spAnimation* self);
|
||||
SP_API int /*bool*/ spAnimation_hasTimeline(spAnimation* self, spPropertyId* ids, int idsCount);
|
||||
|
||||
/** Poses the skeleton at the specified time for this animation.
|
||||
* @param lastTime The last time the animation was applied.
|
||||
@ -73,32 +79,42 @@ SP_API void spAnimation_apply (const spAnimation* self, struct spSkeleton* skele
|
||||
/**/
|
||||
|
||||
typedef enum {
|
||||
SP_TIMELINE_ROTATE,
|
||||
SP_TIMELINE_TRANSLATE,
|
||||
SP_TIMELINE_SCALE,
|
||||
SP_TIMELINE_SHEAR,
|
||||
SP_TIMELINE_ATTACHMENT,
|
||||
SP_TIMELINE_COLOR,
|
||||
SP_TIMELINE_DEFORM,
|
||||
SP_TIMELINE_EVENT,
|
||||
SP_TIMELINE_DRAWORDER,
|
||||
SP_TIMELINE_IKCONSTRAINT,
|
||||
SP_TIMELINE_TRANSFORMCONSTRAINT,
|
||||
SP_TIMELINE_PATHCONSTRAINTPOSITION,
|
||||
SP_TIMELINE_PATHCONSTRAINTSPACING,
|
||||
SP_TIMELINE_PATHCONSTRAINTMIX,
|
||||
SP_TIMELINE_TWOCOLOR
|
||||
} spTimelineType;
|
||||
SP_PROPERTY_ROTATE = 1 << 0,
|
||||
SP_PROPERTY_X = 1 << 1,
|
||||
SP_PROPERTY_Y = 1 << 2,
|
||||
SP_PROPERTY_SCALEX = 1 << 3,
|
||||
SP_PROPERTY_SCALEY = 1 << 4,
|
||||
SP_PROPERTY_SHEARX = 1 << 5,
|
||||
SP_PROPERTY_SHEARY = 1 << 6,
|
||||
SP_PROPERTY_RGB = 1 << 7,
|
||||
SP_PROPERTY_ALPHA = 1 << 8,
|
||||
SP_PROPERTY_RGB2 = 1 << 9,
|
||||
SP_PROPERTY_ATTACHMENT = 1 << 10,
|
||||
SP_PROPERTY_DEFORM = 1 << 11,
|
||||
SP_PROPERTY_EVENT = 1 << 12,
|
||||
SP_PROPERTY_DRAWORDER = 1 << 13,
|
||||
SP_PROPERTY_IKCONSTRAINT = 1 << 14,
|
||||
SP_PROPERTY_TRANSFORMCONSTRAINT = 1 << 15,
|
||||
SP_PROPERTY_PATHCONSTRAINT_POSITION = 1 << 16,
|
||||
SP_PROPERTY_PATHCONSTRAINT_SPACING = 1 << 17,
|
||||
SP_PROPERTY_PATHCONSTRAINT_MIX = 1 << 18
|
||||
} spProperty;
|
||||
|
||||
#define SP_MAX_PROPERTY_IDS 2
|
||||
|
||||
struct spTimeline {
|
||||
const spTimelineType type;
|
||||
const void* const vtable;
|
||||
spPropertyId propertyIds[SP_MAX_PROPERTY_IDS];
|
||||
int propertyIdsCount;
|
||||
spFloatArray frames;
|
||||
};
|
||||
|
||||
SP_API void spTimeline_dispose (spTimeline* self);
|
||||
SP_API void spTimeline_apply (const spTimeline* self, struct spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
||||
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction);
|
||||
SP_API int spTimeline_getPropertyId (const spTimeline* self);
|
||||
SP_API int spTimeline_getFrameEntries (const spTimeline* self);
|
||||
SP_API int spTimeline_getFrameCount (const spTimeline* self);
|
||||
SP_API float spTimeline_getDuration (const spTimeline* self);
|
||||
|
||||
/**/
|
||||
|
||||
|
||||
@ -249,19 +249,21 @@ void _spVertexAttachment_deinit (spVertexAttachment* self);
|
||||
|
||||
/**/
|
||||
|
||||
void _spTimeline_init (spTimeline* self, spTimelineType type,
|
||||
void _spTimeline_init (spTimeline* self,
|
||||
void (*dispose) (spTimeline* self),
|
||||
void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
||||
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction),
|
||||
int (*getPropertyId) (const spTimeline* self));
|
||||
int (*getFrameEntries) (const spTimeline* self),
|
||||
spPropertyId* propertyIds, int propertyIdsCount);
|
||||
void _spTimeline_deinit (spTimeline* self);
|
||||
|
||||
/**/
|
||||
|
||||
void _spCurveTimeline_init (spCurveTimeline* self, spTimelineType type, int framesCount,
|
||||
void _spCurveTimeline_init (spCurveTimeline* self, int framesCount,
|
||||
void (*dispose) (spTimeline* self),
|
||||
void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction),
|
||||
int (*getPropertyId) (const spTimeline* self));
|
||||
int (*getPropertyId) (const spTimeline* self),
|
||||
spPropertyId* propertyIds, int propertyIdsCount);
|
||||
void _spCurveTimeline_deinit (spCurveTimeline* self);
|
||||
int _spCurveTimeline_binarySearch (float *values, int valuesLength, float target, int step);
|
||||
|
||||
|
||||
@ -32,27 +32,43 @@
|
||||
#include <limits.h>
|
||||
#include <spine/extension.h>
|
||||
|
||||
spAnimation* spAnimation_create (const char* name, int timelinesCount) {
|
||||
_SP_ARRAY_IMPLEMENT_TYPE(spPropertyIdArray, spPropertyId)
|
||||
_SP_ARRAY_IMPLEMENT_TYPE(spTimelineArray, spTimeline*)
|
||||
|
||||
spAnimation* spAnimation_create (const char* name, spTimelineArray* timelines) {
|
||||
int i, n;
|
||||
spAnimation* self = NEW(spAnimation);
|
||||
MALLOC_STR(self->name, name);
|
||||
self->timelinesCount = timelinesCount;
|
||||
self->timelines = MALLOC(spTimeline*, timelinesCount);
|
||||
for (i = 0, n = timelines->size; i < n; i++) {
|
||||
spPropertyIdArray_addAllValues(self->timelineIds, timelines->items[i]->propertyIds, 0, timelines->items[i]->propertyIdsCount);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
void spAnimation_dispose (spAnimation* self) {
|
||||
int i;
|
||||
for (i = 0; i < self->timelinesCount; ++i)
|
||||
spTimeline_dispose(self->timelines[i]);
|
||||
FREE(self->timelines);
|
||||
for (i = 0; i < self->timelines->size; ++i)
|
||||
spTimeline_dispose(self->timelines->items[i]);
|
||||
spTimelineArray_dispose(self->timelines);
|
||||
spPropertyIdArray_dispose(self->timelineIds);
|
||||
FREE(self->name);
|
||||
FREE(self);
|
||||
}
|
||||
|
||||
int /*bool*/ spAnimation_hasTimeline(spAnimation* self, spPropertyId* ids, int idsCount) {
|
||||
int i, n, ii, nn;
|
||||
for (i = 0, n = self->timelineIds->size; i < n; i++) {
|
||||
for (ii = 0, nn = idsCount; ii < nn; ii++) {
|
||||
if (self->timelineIds->items[i] == ids[ii]) return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spAnimation_apply (const spAnimation* self, spSkeleton* skeleton, float lastTime, float time, int loop, spEvent** events,
|
||||
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
|
||||
) {
|
||||
int i, n = self->timelinesCount;
|
||||
int i, n = self->timelines->size;
|
||||
|
||||
if (loop && self->duration) {
|
||||
time = FMOD(time, self->duration);
|
||||
@ -60,7 +76,7 @@ void spAnimation_apply (const spAnimation* self, spSkeleton* skeleton, float las
|
||||
}
|
||||
|
||||
for (i = 0; i < n; ++i)
|
||||
spTimeline_apply(self->timelines[i], skeleton, lastTime, time, events, eventsCount, alpha, blend, direction);
|
||||
spTimeline_apply(self->timelines->items[i], skeleton, lastTime, time, events, eventsCount, alpha, blend, direction);
|
||||
}
|
||||
|
||||
/**/
|
||||
@ -68,21 +84,25 @@ void spAnimation_apply (const spAnimation* self, spSkeleton* skeleton, float las
|
||||
typedef struct _spTimelineVtable {
|
||||
void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
||||
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction);
|
||||
int (*getPropertyId) (const spTimeline* self);
|
||||
int (*getFrameEntries) (const spTimeline* self);
|
||||
void (*dispose) (spTimeline* self);
|
||||
} _spTimelineVtable;
|
||||
|
||||
void _spTimeline_init (spTimeline* self, spTimelineType type, /**/
|
||||
void _spTimeline_init (spTimeline* self, /**/
|
||||
void (*dispose) (spTimeline* self), /**/
|
||||
void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
||||
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction),
|
||||
int (*getPropertyId) (const spTimeline* self)
|
||||
int (*getFrameEntries) (const spTimeline* self),
|
||||
spPropertyId* propertyIds,
|
||||
int propertyIdsCount
|
||||
) {
|
||||
CONST_CAST(spTimelineType, self->type) = type;
|
||||
int i, n;
|
||||
CONST_CAST(_spTimelineVtable*, self->vtable) = NEW(_spTimelineVtable);
|
||||
VTABLE(spTimeline, self)->dispose = dispose;
|
||||
VTABLE(spTimeline, self)->apply = apply;
|
||||
VTABLE(spTimeline, self)->getPropertyId = getPropertyId;
|
||||
VTABLE(spTimeline, self)->getFrameEntries = getFrameEntries;
|
||||
for (i = 0, n = propertyIdsCount; i < n; i++)
|
||||
self->propertyIds[i] = propertyIds[i];
|
||||
}
|
||||
|
||||
void _spTimeline_deinit (spTimeline* self) {
|
||||
@ -98,8 +118,17 @@ void spTimeline_apply (const spTimeline* self, spSkeleton* skeleton, float lastT
|
||||
VTABLE(spTimeline, self)->apply(self, skeleton, lastTime, time, firedEvents, eventsCount, alpha, blend, direction);
|
||||
}
|
||||
|
||||
int spTimeline_getPropertyId (const spTimeline* self) {
|
||||
return VTABLE(spTimeline, self)->getPropertyId(self);
|
||||
|
||||
int spTimeline_getFrameEntries (const spTimeline* self) {
|
||||
return VTABLE(spTimeline, self)->getFrameEntries(self);
|
||||
}
|
||||
|
||||
int spTimeline_getFrameCount (const spTimeline* self) {
|
||||
return self->frames.size / VTABLE(spTimeline, self)->getFrameEntries(self);
|
||||
}
|
||||
|
||||
float spTimeline_getDuration (const spTimeline* self) {
|
||||
return self->frames.items[self->frames.size - VTABLE(spTimeline, self)->getFrameEntries(self)];
|
||||
}
|
||||
|
||||
/**/
|
||||
|
||||
@ -245,9 +245,6 @@ static void _spSkeletonBinary_addLinkedMesh (spSkeletonBinary* self, spMeshAttac
|
||||
linkedMesh->inheritDeform = inheritDeform;
|
||||
}
|
||||
|
||||
_SP_ARRAY_DECLARE_TYPE(spTimelineArray, spTimeline*)
|
||||
_SP_ARRAY_IMPLEMENT_TYPE(spTimelineArray, spTimeline*)
|
||||
|
||||
static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, const char* name,
|
||||
_dataInput* input, spSkeletonData *skeletonData) {
|
||||
spTimelineArray* timelines = spTimelineArray_create(18);
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
static int nextID = 0;
|
||||
|
||||
void _spVertexAttachment_init (spVertexAttachment* attachment) {
|
||||
attachment->id = (nextID++ & 65535) << 11;
|
||||
attachment->id = nextID++;
|
||||
attachment->deformAttachment = attachment;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user