[c] 4.0 port. refactor the way we handle animation and timeline data.

This commit is contained in:
badlogic 2021-03-22 15:21:14 +01:00
parent 285da8c43f
commit a4c5b9937f
5 changed files with 88 additions and 44 deletions

View File

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

View File

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

View File

@ -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)];
}
/**/

View File

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

View File

@ -34,7 +34,7 @@
static int nextID = 0;
void _spVertexAttachment_init (spVertexAttachment* attachment) {
attachment->id = (nextID++ & 65535) << 11;
attachment->id = nextID++;
attachment->deformAttachment = attachment;
}