[c] 4.0 porting, more timeline work.

This commit is contained in:
badlogic 2021-03-30 16:25:40 +02:00
parent 3753dd6077
commit 44b390cc0f
5 changed files with 414 additions and 206 deletions

View File

@ -34,6 +34,7 @@
#include <spine/Event.h> #include <spine/Event.h>
#include <spine/Attachment.h> #include <spine/Attachment.h>
#include <spine/Array.h> #include <spine/Array.h>
#include <stdint.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -41,7 +42,7 @@ extern "C" {
typedef struct spTimeline spTimeline; typedef struct spTimeline spTimeline;
struct spSkeleton; struct spSkeleton;
typedef unsigned long long spPropertyId; typedef uint64_t spPropertyId;
_SP_ARRAY_DECLARE_TYPE(spPropertyIdArray, spPropertyId) _SP_ARRAY_DECLARE_TYPE(spPropertyIdArray, spPropertyId)
_SP_ARRAY_DECLARE_TYPE(spTimelineArray, spTimeline*) _SP_ARRAY_DECLARE_TYPE(spTimelineArray, spTimeline*)
@ -100,10 +101,10 @@ typedef enum {
SP_PROPERTY_PATHCONSTRAINT_MIX = 1 << 18 SP_PROPERTY_PATHCONSTRAINT_MIX = 1 << 18
} spProperty; } spProperty;
#define SP_MAX_PROPERTY_IDS 2 #define SP_MAX_PROPERTY_IDS 3
typedef struct _spTimelineVtable { typedef struct _spTimelineVtable {
void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, void (*apply) (const spTimeline* self, struct spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction); int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction);
void (*dispose) (spTimeline* self); void (*dispose) (spTimeline* self);
} _spTimelineVtable; } _spTimelineVtable;
@ -281,36 +282,66 @@ SP_API void spRGBTimeline_setFrame (spRGBATimeline* self, int frameIndex, float
/**/ /**/
static const int TWOCOLOR_ENTRIES = 8; typedef struct spAlphaTimeline {
spCurveTimeline1 super;
int slotIndex;
} spAlphaTimeline;
typedef struct spTwoColorTimeline { SP_API spAlphaTimeline* spAlphaTimeline_create (int frameCount, int bezierCount, int slotIndex);
spCurveTimeline super;
int const framesCount;
float* const frames; /* time, r, g, b, a, ... */
int slotIndex;
} spTwoColorTimeline;
SP_API spTwoColorTimeline* spTwoColorTimeline_create (int framesCount); SP_API void spAlphaTimeline_setFrame (spAlphaTimeline* self, int frame, float time, float x);
SP_API void spTwoColorTimeline_setFrame (spTwoColorTimeline* self, int frameIndex, float time, float r, float g, float b, float a, float r2, float g2, float b2); /**/
typedef struct spRGBA2Timeline {
spCurveTimeline super;
int slotIndex;
} spRGBA2Timeline;
SP_API spRGBA2Timeline* spRGBA2Timeline_create (int framesCount, int bezierCount, int slotIndex);
SP_API void spRGBA2Timeline_setFrame (spRGBA2Timeline* self, int frameIndex, float time, float r, float g, float b, float a, float r2, float g2, float b2);
/**/
typedef struct spRGB2Timeline {
spCurveTimeline super;
int slotIndex;
} spRGB2Timeline;
SP_API spRGB2Timeline* spRGB2Timeline_create (int framesCount, int bezierCount, int slotIndex);
SP_API void spRGB2Timeline_setFrame (spRGB2Timeline* self, int frameIndex, float time, float r, float g, float b, float r2, float g2, float b2);
/**/ /**/
typedef struct spAttachmentTimeline { typedef struct spAttachmentTimeline {
spTimeline super; spTimeline super;
int const framesCount;
float* const frames; /* time, ... */
int slotIndex; int slotIndex;
const char** const attachmentNames; const char** const attachmentNames;
} spAttachmentTimeline; } spAttachmentTimeline;
SP_API spAttachmentTimeline* spAttachmentTimeline_create (int framesCount); SP_API spAttachmentTimeline* spAttachmentTimeline_create (int framesCount, int SlotIndex);
/* @param attachmentName May be 0. */ /* @param attachmentName May be 0. */
SP_API void spAttachmentTimeline_setFrame (spAttachmentTimeline* self, int frameIndex, float time, const char* attachmentName); SP_API void spAttachmentTimeline_setFrame (spAttachmentTimeline* self, int frameIndex, float time, const char* attachmentName);
/**/ /**/
typedef struct spDeformTimeline {
spCurveTimeline super;
int const frameVerticesCount;
const float** const frameVertices;
int slotIndex;
spAttachment* attachment;
} spDeformTimeline;
SP_API spDeformTimeline* spDeformTimeline_create (int framesCount, int frameVerticesCount);
SP_API void spDeformTimeline_setFrame (spDeformTimeline* self, int frameIndex, float time, float* vertices);
/**/
typedef struct spEventTimeline { typedef struct spEventTimeline {
spTimeline super; spTimeline super;
int const framesCount; int const framesCount;
@ -338,22 +369,6 @@ SP_API void spDrawOrderTimeline_setFrame (spDrawOrderTimeline* self, int frameIn
/**/ /**/
typedef struct spDeformTimeline {
spCurveTimeline super;
int const framesCount;
float* const frames; /* time, ... */
int const frameVerticesCount;
const float** const frameVertices;
int slotIndex;
spAttachment* attachment;
} spDeformTimeline;
SP_API spDeformTimeline* spDeformTimeline_create (int framesCount, int frameVerticesCount);
SP_API void spDeformTimeline_setFrame (spDeformTimeline* self, int frameIndex, float time, float* vertices);
/**/
static const int IKCONSTRAINT_ENTRIES = 6; static const int IKCONSTRAINT_ENTRIES = 6;
typedef struct spIkConstraintTimeline { typedef struct spIkConstraintTimeline {

View File

@ -44,8 +44,11 @@ typedef struct spColor {
SP_API spColor* spColor_create(); SP_API spColor* spColor_create();
SP_API void spColor_dispose(spColor* self); SP_API void spColor_dispose(spColor* self);
SP_API void spColor_setFromFloats(spColor* color, float r, float g, float b, float a); SP_API void spColor_setFromFloats(spColor* color, float r, float g, float b, float a);
SP_API void spColor_setFromFloats3(spColor* self, float r, float g, float b);
SP_API void spColor_setFromColor(spColor* color, spColor* otherColor); SP_API void spColor_setFromColor(spColor* color, spColor* otherColor);
SP_API void spColor_setFromColor3(spColor* self, spColor* otherColor);
SP_API void spColor_addFloats(spColor* color, float r, float g, float b, float a); SP_API void spColor_addFloats(spColor* color, float r, float g, float b, float a);
SP_API void spColor_addFloats3(spColor* color, float r, float g, float b);
SP_API void spColor_addColor(spColor* color, spColor* otherColor); SP_API void spColor_addColor(spColor* color, spColor* otherColor);
SP_API void spColor_clamp(spColor* color); SP_API void spColor_clamp(spColor* color);

View File

@ -406,12 +406,10 @@ void _spTranslateXTimeline_apply (const spTimeline* timeline, spSkeleton* skelet
spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
) { ) {
spBone *bone; spBone *bone;
float x, t; float x;
int i, curveType;
spTranslateXTimeline* self = SUB_CAST(spTranslateXTimeline, timeline); spTranslateXTimeline* self = SUB_CAST(spTranslateXTimeline, timeline);
float *frames = self->super.super.frames->items; float *frames = self->super.super.frames->items;
float *curves = self->super.curves->items;
bone = skeleton->bones[self->boneIndex]; bone = skeleton->bones[self->boneIndex];
if (!bone->active) return; if (!bone->active) return;
@ -466,13 +464,10 @@ void _spTranslateYTimeline_apply (const spTimeline* timeline, spSkeleton* skelet
spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
) { ) {
spBone *bone; spBone *bone;
int frame; float y;
float y, t;
int i, curveType;
spTranslateXTimeline* self = SUB_CAST(spTranslateXTimeline, timeline); spTranslateYTimeline* self = SUB_CAST(spTranslateYTimeline, timeline);
float *frames = self->super.super.frames->items; float *frames = self->super.super.frames->items;
float *curves = self->super.curves->items;
bone = skeleton->bones[self->boneIndex]; bone = skeleton->bones[self->boneIndex];
if (!bone->active) return; if (!bone->active) return;
@ -505,6 +500,7 @@ void _spTranslateYTimeline_apply (const spTimeline* timeline, spSkeleton* skelet
UNUSED(lastTime); UNUSED(lastTime);
UNUSED(firedEvents); UNUSED(firedEvents);
UNUSED(eventsCount); UNUSED(eventsCount);
UNUSED(direction);
} }
spTranslateYTimeline* spTranslateYTimeline_create (int frameCount, int bezierCount, int boneIndex) { spTranslateYTimeline* spTranslateYTimeline_create (int frameCount, int bezierCount, int boneIndex) {
@ -654,13 +650,10 @@ void _spScaleXTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
) { ) {
spBone *bone; spBone *bone;
int frame; float x;
float x, t;
int i, curveType;
spTranslateXTimeline* self = SUB_CAST(spTranslateXTimeline, timeline); spScaleXTimeline* self = SUB_CAST(spScaleXTimeline, timeline);
float *frames = self->super.super.frames->items; float *frames = self->super.super.frames->items;
float *curves = self->super.curves->items;
bone = skeleton->bones[self->boneIndex]; bone = skeleton->bones[self->boneIndex];
if (!bone->active) return; if (!bone->active) return;
@ -743,13 +736,10 @@ void _spScaleYTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
) { ) {
spBone *bone; spBone *bone;
int frame; float y;
float y, t;
int i, curveType;
spTranslateXTimeline* self = SUB_CAST(spTranslateXTimeline, timeline); spScaleYTimeline* self = SUB_CAST(spScaleYTimeline, timeline);
float *frames = self->super.super.frames->items; float *frames = self->super.super.frames->items;
float *curves = self->super.curves->items;
bone = skeleton->bones[self->boneIndex]; bone = skeleton->bones[self->boneIndex];
if (!bone->active) return; if (!bone->active) return;
@ -832,7 +822,6 @@ void _spShearTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
) { ) {
spBone *bone; spBone *bone;
int frame;
float x, y, t; float x, y, t;
int i, curveType; int i, curveType;
@ -920,13 +909,10 @@ void _spShearXTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
) { ) {
spBone *bone; spBone *bone;
int frame;
float x; float x;
int curveType;
spTranslateXTimeline* self = SUB_CAST(spTranslateXTimeline, timeline); spShearXTimeline* self = SUB_CAST(spShearXTimeline, timeline);
float *frames = self->super.super.frames->items; float *frames = self->super.super.frames->items;
float *curves = self->super.curves->items;
bone = skeleton->bones[self->boneIndex]; bone = skeleton->bones[self->boneIndex];
if (!bone->active) return; if (!bone->active) return;
@ -958,6 +944,7 @@ void _spShearXTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
UNUSED(lastTime); UNUSED(lastTime);
UNUSED(firedEvents); UNUSED(firedEvents);
UNUSED(eventsCount); UNUSED(eventsCount);
UNUSED(direction);
} }
spShearXTimeline* spShearXTimeline_create (int frameCount, int bezierCount, int boneIndex) { spShearXTimeline* spShearXTimeline_create (int frameCount, int bezierCount, int boneIndex) {
@ -979,13 +966,10 @@ void _spShearYTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
) { ) {
spBone *bone; spBone *bone;
int frame; float y;
float y, t;
int i, curveType;
spTranslateXTimeline* self = SUB_CAST(spTranslateXTimeline, timeline); spShearYTimeline* self = SUB_CAST(spShearYTimeline, timeline);
float *frames = self->super.super.frames->items; float *frames = self->super.super.frames->items;
float *curves = self->super.curves->items;
bone = skeleton->bones[self->boneIndex]; bone = skeleton->bones[self->boneIndex];
if (!bone->active) return; if (!bone->active) return;
@ -1018,6 +1002,7 @@ void _spShearYTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
UNUSED(lastTime); UNUSED(lastTime);
UNUSED(firedEvents); UNUSED(firedEvents);
UNUSED(eventsCount); UNUSED(eventsCount);
UNUSED(direction);
} }
spShearYTimeline* spShearYTimeline_create (int frameCount, int bezierCount, int boneIndex) { spShearYTimeline* spShearYTimeline_create (int frameCount, int bezierCount, int boneIndex) {
@ -1041,7 +1026,7 @@ void _spRGBATimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, fl
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
) { ) {
spSlot *slot; spSlot *slot;
int frame, i, curveType; int i, curveType;
float r, g, b, a, t; float r, g, b, a, t;
spColor* color; spColor* color;
spColor* setup; spColor* setup;
@ -1143,11 +1128,11 @@ void _spRGBTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, flo
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
) { ) {
spSlot *slot; spSlot *slot;
int frame, i, curveType; int i, curveType;
float r, g, b, t; float r, g, b, t;
spColor* color; spColor* color;
spColor* setup; spColor* setup;
spRGBATimeline* self = (spRGBATimeline*)timeline; spRGBTimeline* self = (spRGBTimeline*)timeline;
float *frames = self->super.super.frames->items; float *frames = self->super.super.frames->items;
float *curves = self->super.curves->items; float *curves = self->super.curves->items;
@ -1238,117 +1223,319 @@ void spRGBTimeline_setFrame (spRGBATimeline* self, int frameIndex, float time, f
/**/ /**/
static const int TWOCOLOR_PREV_TIME = -8, TWOCOLOR_PREV_R = -7, TWOCOLOR_PREV_G = -6, TWOCOLOR_PREV_B = -5, TWOCOLOR_PREV_A = -4; void _spAlphaTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
static const int TWOCOLOR_PREV_R2 = -3, TWOCOLOR_PREV_G2 = -2, TWOCOLOR_PREV_B2 = -1; spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
static const int TWOCOLOR_R = 1, TWOCOLOR_G = 2, TWOCOLOR_B = 3, TWOCOLOR_A = 4, TWOCOLOR_R2 = 5, TWOCOLOR_G2 = 6, TWOCOLOR_B2 = 7;
void _spTwoColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
) { ) {
spSlot *slot; spSlot *slot;
int frame; float a;
float percent, frameTime; spColor* color;
float r, g, b, a, r2, g2, b2; spColor* setup;
spColor* light; spAlphaTimeline* self = (spAlphaTimeline*)timeline;
spColor* dark; float *frames = self->super.super.frames->items;
spColor* setupLight;
spColor* setupDark;
spColorTimeline* self = (spColorTimeline*)timeline;
slot = skeleton->slots[self->slotIndex];
if (!slot->bone->active) return;
if (time < self->frames[0]) { slot = skeleton->slots[self->slotIndex];
switch (blend) { if (!slot->bone->active) return;
case SP_MIX_BLEND_SETUP:
spColor_setFromColor(&slot->color, &slot->data->color);
spColor_setFromColor(slot->darkColor, slot->data->darkColor);
return;
case SP_MIX_BLEND_FIRST:
light = &slot->color;
dark = slot->darkColor;
setupLight = &slot->data->color;
setupDark = slot->data->darkColor;
spColor_addFloats(light, (setupLight->r - light->r) * alpha, (setupLight->g - light->g) * alpha, (setupLight->b - light->b) * alpha,
(setupLight->a - light->a) * alpha);
spColor_addFloats(dark, (setupDark->r - dark->r) * alpha, (setupDark->g - dark->g) * alpha, (setupDark->b - dark->b) * alpha, 0);
case SP_MIX_BLEND_REPLACE:
case SP_MIX_BLEND_ADD:
; /* to appease compiler */
}
return;
}
if (time >= self->frames[self->framesCount - TWOCOLOR_ENTRIES]) { /* Time is after last frame */ if (time < frames[0]) { /* Time is before first frame-> */
int i = self->framesCount; color = &slot->color; setup = &slot->data->color;
r = self->frames[i + TWOCOLOR_PREV_R]; switch (blend) {
g = self->frames[i + TWOCOLOR_PREV_G]; case SP_MIX_BLEND_SETUP:
b = self->frames[i + TWOCOLOR_PREV_B]; color->a = setup->a;
a = self->frames[i + TWOCOLOR_PREV_A]; return;
r2 = self->frames[i + TWOCOLOR_PREV_R2]; case SP_MIX_BLEND_FIRST:
g2 = self->frames[i + TWOCOLOR_PREV_G2]; color->a += (setup->a - color->a) * alpha;
b2 = self->frames[i + TWOCOLOR_PREV_B2]; default: {
} else { }
/* Interpolate between the previous frame and the current frame. */ }
frame = binarySearch(self->frames, self->framesCount, time, TWOCOLOR_ENTRIES); return;
}
r = self->frames[frame + TWOCOLOR_PREV_R]; a = spCurveTimeline1_getCurveValue(SUPER(self), time);
g = self->frames[frame + TWOCOLOR_PREV_G]; if (alpha == 1)
b = self->frames[frame + TWOCOLOR_PREV_B]; slot->color.a = a;
a = self->frames[frame + TWOCOLOR_PREV_A]; else {
r2 = self->frames[frame + TWOCOLOR_PREV_R2]; if (blend == SP_MIX_BLEND_SETUP) slot->color.a = slot->data->color.a;
g2 = self->frames[frame + TWOCOLOR_PREV_G2]; slot->color.a += (a - slot->color.a) * alpha;
b2 = self->frames[frame + TWOCOLOR_PREV_B2]; }
frameTime = self->frames[frame]; UNUSED(lastTime);
percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TWOCOLOR_ENTRIES - 1, UNUSED(firedEvents);
1 - (time - frameTime) / (self->frames[frame + TWOCOLOR_PREV_TIME] - frameTime)); UNUSED(eventsCount);
UNUSED(direction);
r += (self->frames[frame + TWOCOLOR_R] - r) * percent;
g += (self->frames[frame + TWOCOLOR_G] - g) * percent;
b += (self->frames[frame + TWOCOLOR_B] - b) * percent;
a += (self->frames[frame + TWOCOLOR_A] - a) * percent;
r2 += (self->frames[frame + TWOCOLOR_R2] - r2) * percent;
g2 += (self->frames[frame + TWOCOLOR_G2] - g2) * percent;
b2 += (self->frames[frame + TWOCOLOR_B2] - b2) * percent;
}
if (alpha == 1) {
spColor_setFromFloats(&slot->color, r, g, b, a);
spColor_setFromFloats(slot->darkColor, r2, g2, b2, 1);
} else {
light = &slot->color;
dark = slot->darkColor;
if (blend == SP_MIX_BLEND_SETUP) {
spColor_setFromColor(light, &slot->data->color);
spColor_setFromColor(dark, slot->data->darkColor);
}
spColor_addFloats(light, (r - light->r) * alpha, (g - light->g) * alpha, (b - light->b) * alpha, (a - light->a) * alpha);
spColor_addFloats(dark, (r2 - dark->r) * alpha, (g2 - dark->g) * alpha, (b2 - dark->b) * alpha, 0);
}
UNUSED(lastTime);
UNUSED(firedEvents);
UNUSED(eventsCount);
UNUSED(direction);
} }
int _spTwoColorTimeline_getPropertyId (const spTimeline* timeline) { spAlphaTimeline* spAlphaTimeline_create (int frameCount, int bezierCount, int slotIndex) {
return (SP_TIMELINE_TWOCOLOR << 24) + SUB_CAST(spTwoColorTimeline, timeline)->slotIndex; spAlphaTimeline* timeline = NEW(spAlphaTimeline);
spPropertyId ids[1];
ids[0] = ((spPropertyId)SP_PROPERTY_ALPHA << 32) | slotIndex;
_spCurveTimeline_init(SUPER(timeline), frameCount, CURVE1_ENTRIES, bezierCount, ids, 1, _spCurveTimeline_dispose, _spAlphaTimeline_apply);
timeline->slotIndex = slotIndex;
return timeline;
} }
spTwoColorTimeline* spTwoColorTimeline_create (int framesCount) { void spAlphaTimeline_setFrame (spAlphaTimeline* self, int frame, float time, float alpha) {
return (spTwoColorTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_TWOCOLOR, TWOCOLOR_ENTRIES, _spTwoColorTimeline_apply, _spTwoColorTimeline_getPropertyId); spCurveTimeline1_setFrame(SUPER(self), frame, time, alpha);
} }
void spTwoColorTimeline_setFrame (spTwoColorTimeline* self, int frameIndex, float time, float r, float g, float b, float a, float r2, float g2, float b2) { /**/
frameIndex *= TWOCOLOR_ENTRIES;
self->frames[frameIndex] = time; static const int RGBA2_ENTRIES = 8, COLOR_R2 = 5, COLOR_G2 = 6, COLOR_B2 = 7;
self->frames[frameIndex + TWOCOLOR_R] = r;
self->frames[frameIndex + TWOCOLOR_G] = g; void _spRGBA2Timeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
self->frames[frameIndex + TWOCOLOR_B] = b; int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
self->frames[frameIndex + TWOCOLOR_A] = a; ) {
self->frames[frameIndex + TWOCOLOR_R2] = r2; spSlot *slot;
self->frames[frameIndex + TWOCOLOR_G2] = g2; int i, curveType;
self->frames[frameIndex + TWOCOLOR_B2] = b2; float r, g, b, a, r2, g2, b2, t;
spColor* light, *setupLight;
spColor* dark, *setupDark;
spRGBA2Timeline* self = (spRGBA2Timeline*)timeline;
float *frames = self->super.super.frames->items;
float *curves = self->super.curves->items;
slot = skeleton->slots[self->slotIndex];
if (!slot->bone->active) return;
if (time < frames[0]) {
light = &slot->color; dark = slot->darkColor; setupLight = &slot->data->color; setupDark = slot->data->darkColor;
switch (blend) {
case SP_MIX_BLEND_SETUP:
spColor_setFromColor(light, setupLight);
spColor_setFromFloats3(dark, setupDark->r, setupDark->g, setupDark->b);
return;
case SP_MIX_BLEND_FIRST:
spColor_addFloats(light, (setupLight->r - light->r) * alpha, (setupLight->g - light->g) * alpha,
(setupLight->b - light->b) * alpha,
(setupLight->a - light->a) * alpha);
dark->r += (setupDark->r - dark->r) * alpha;
dark->g += (setupDark->g - dark->g) * alpha;
dark->b += (setupDark->b - dark->b) * alpha;
default: {
}
}
return;
}
r = 0, g = 0, b = 0, a = 0, r2 = 0, g2 = 0, b2 = 0;
i = search(frames, time, RGBA2_ENTRIES);
curveType = (int) curves[i / RGBA2_ENTRIES];
switch (curveType) {
case CURVE_LINEAR: {
float before = frames[i];
r = frames[i + COLOR_R];
g = frames[i + COLOR_G];
b = frames[i + COLOR_B];
a = frames[i + COLOR_A];
r2 = frames[i + COLOR_R2];
g2 = frames[i + COLOR_G2];
b2 = frames[i + COLOR_B2];
t = (time - before) / (frames[i + RGBA2_ENTRIES] - before);
r += (frames[i + RGBA2_ENTRIES + COLOR_R] - r) * t;
g += (frames[i + RGBA2_ENTRIES + COLOR_G] - g) * t;
b += (frames[i + RGBA2_ENTRIES + COLOR_B] - b) * t;
a += (frames[i + RGBA2_ENTRIES + COLOR_A] - a) * t;
r2 += (frames[i + RGBA2_ENTRIES + COLOR_R2] - r2) * t;
g2 += (frames[i + RGBA2_ENTRIES + COLOR_G2] - g2) * t;
b2 += (frames[i + RGBA2_ENTRIES + COLOR_B2] - b2) * t;
break;
}
case CURVE_STEPPED: {
r = frames[i + COLOR_R];
g = frames[i + COLOR_G];
b = frames[i + COLOR_B];
a = frames[i + COLOR_A];
r2 = frames[i + COLOR_R2];
g2 = frames[i + COLOR_G2];
b2 = frames[i + COLOR_B2];
break;
}
default: {
r = _spCurveTimeline_getBezierValue(SUPER(self), time, i, COLOR_R, curveType - CURVE_BEZIER);
g = _spCurveTimeline_getBezierValue(SUPER(self), time, i, COLOR_G,
curveType + BEZIER_SIZE - CURVE_BEZIER);
b = _spCurveTimeline_getBezierValue(SUPER(self), time, i, COLOR_B,
curveType + BEZIER_SIZE * 2 - CURVE_BEZIER);
a = _spCurveTimeline_getBezierValue(SUPER(self), time, i, COLOR_A,
curveType + BEZIER_SIZE * 3 - CURVE_BEZIER);
r2 = _spCurveTimeline_getBezierValue(SUPER(self), time, i, COLOR_R2,
curveType + BEZIER_SIZE * 4 - CURVE_BEZIER);
g2 = _spCurveTimeline_getBezierValue(SUPER(self), time, i, COLOR_G2,
curveType + BEZIER_SIZE * 5 - CURVE_BEZIER);
b2 = _spCurveTimeline_getBezierValue(SUPER(self), time, i, COLOR_B2,
curveType + BEZIER_SIZE * 6 - CURVE_BEZIER);
}
}
light = &slot->color, dark = slot->darkColor;
if (alpha == 1) {
spColor_setFromFloats(light, r, g, b, a);
spColor_setFromFloats3(dark, r2, g2, b2);
} else {
if (blend == SP_MIX_BLEND_SETUP) {
spColor_setFromColor(light, &slot->data->color);
spColor_setFromColor(dark, slot->data->darkColor);
}
spColor_addFloats(light, (r - light->r) * alpha, (g - light->g) * alpha, (b - light->b) * alpha, (a - light->a) * alpha);
dark->r += (r2 - dark->r) * alpha;
dark->g += (g2 - dark->g) * alpha;
dark->b += (b2 - dark->b) * alpha;
}
UNUSED(lastTime);
UNUSED(firedEvents);
UNUSED(eventsCount);
UNUSED(direction);
}
spRGBA2Timeline* spRGBA2Timeline_create (int framesCount, int bezierCount, int slotIndex) {
spRGBA2Timeline* timeline = NEW(spRGBA2Timeline);
spPropertyId ids[3];
ids[0] = ((spPropertyId)SP_PROPERTY_RGB << 32) | slotIndex;
ids[1] = ((spPropertyId)SP_PROPERTY_ALPHA << 32) | slotIndex;
ids[2] = ((spPropertyId)SP_PROPERTY_RGB2 << 32) | slotIndex;
_spCurveTimeline_init(SUPER(timeline), framesCount, RGBA2_ENTRIES, bezierCount, ids, 3, _spCurveTimeline_dispose, _spRGBA2Timeline_apply);
timeline->slotIndex = slotIndex;
return timeline;
}
void spRGBA2Timeline_setFrame (spRGBA2Timeline* self, int frameIndex, float time, float r, float g, float b, float a, float r2, float g2, float b2) {
float *frames = self->super.super.frames->items;
frameIndex *= RGBA_ENTRIES;
frames[frameIndex] = time;
frames[frameIndex + COLOR_R] = r;
frames[frameIndex + COLOR_G] = g;
frames[frameIndex + COLOR_B] = b;
frames[frameIndex + COLOR_A] = a;
frames[frameIndex + COLOR_R2] = r2;
frames[frameIndex + COLOR_G2] = g2;
frames[frameIndex + COLOR_B2] = b2;
}
/**/
static const int RGB2_ENTRIES = 7, COLOR2_R2 = 5, COLOR2_G2 = 6, COLOR2_B2 = 7;
void _spRGB2Timeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
) {
spSlot *slot;
int i, curveType;
float r, g, b, r2, g2, b2, t;
spColor* light, *setupLight;
spColor* dark, *setupDark;
spRGB2Timeline* self = (spRGB2Timeline*)timeline;
float *frames = self->super.super.frames->items;
float *curves = self->super.curves->items;
slot = skeleton->slots[self->slotIndex];
if (!slot->bone->active) return;
if (time < frames[0]) {
light = &slot->color; dark = slot->darkColor; setupLight = &slot->data->color; setupDark = slot->data->darkColor;
switch (blend) {
case SP_MIX_BLEND_SETUP:
spColor_setFromColor3(light, setupLight);
spColor_setFromColor3(dark, setupDark);
return;
case SP_MIX_BLEND_FIRST:
spColor_addFloats3(light, (setupLight->r - light->r) * alpha, (setupLight->g - light->g) * alpha,
(setupLight->b - light->b) * alpha);
dark->r += (setupDark->r - dark->r) * alpha;
dark->g += (setupDark->g - dark->g) * alpha;
dark->b += (setupDark->b - dark->b) * alpha;
default: {
}
}
return;
}
r = 0, g = 0, b = 0, r2 = 0, g2 = 0, b2 = 0;
i = search(frames, time, RGB2_ENTRIES);
curveType = (int) curves[i / RGB2_ENTRIES];
switch (curveType) {
case CURVE_LINEAR: {
float before = frames[i];
r = frames[i + COLOR_R];
g = frames[i + COLOR_G];
b = frames[i + COLOR_B];
r2 = frames[i + COLOR2_R2];
g2 = frames[i + COLOR2_G2];
b2 = frames[i + COLOR2_B2];
t = (time - before) / (frames[i + RGB2_ENTRIES] - before);
r += (frames[i + RGBA2_ENTRIES + COLOR_R] - r) * t;
g += (frames[i + RGBA2_ENTRIES + COLOR_G] - g) * t;
b += (frames[i + RGBA2_ENTRIES + COLOR_B] - b) * t;
r2 += (frames[i + RGBA2_ENTRIES + COLOR2_R2] - r2) * t;
g2 += (frames[i + RGBA2_ENTRIES + COLOR2_G2] - g2) * t;
b2 += (frames[i + RGBA2_ENTRIES + COLOR2_B2] - b2) * t;
break;
}
case CURVE_STEPPED: {
r = frames[i + COLOR_R];
g = frames[i + COLOR_G];
b = frames[i + COLOR_B];
r2 = frames[i + COLOR2_R2];
g2 = frames[i + COLOR2_G2];
b2 = frames[i + COLOR2_B2];
break;
}
default: {
r = _spCurveTimeline_getBezierValue(SUPER(self), time, i, COLOR_R, curveType - CURVE_BEZIER);
g = _spCurveTimeline_getBezierValue(SUPER(self), time, i, COLOR_G,
curveType + BEZIER_SIZE - CURVE_BEZIER);
b = _spCurveTimeline_getBezierValue(SUPER(self), time, i, COLOR_B,
curveType + BEZIER_SIZE * 2 - CURVE_BEZIER);
r2 = _spCurveTimeline_getBezierValue(SUPER(self), time, i, COLOR2_R2,
curveType + BEZIER_SIZE * 3 - CURVE_BEZIER);
g2 = _spCurveTimeline_getBezierValue(SUPER(self), time, i, COLOR2_G2,
curveType + BEZIER_SIZE * 4 - CURVE_BEZIER);
b2 = _spCurveTimeline_getBezierValue(SUPER(self), time, i, COLOR2_B2,
curveType + BEZIER_SIZE * 5 - CURVE_BEZIER);
}
}
light = &slot->color, dark = slot->darkColor;
if (alpha == 1) {
spColor_setFromFloats3(light, r, g, b);
spColor_setFromFloats3(dark, r2, g2, b2);
} else {
if (blend == SP_MIX_BLEND_SETUP) {
spColor_setFromColor3(light, &slot->data->color);
spColor_setFromColor3(dark, slot->data->darkColor);
}
spColor_addFloats3(light, (r - light->r) * alpha, (g - light->g) * alpha, (b - light->b) * alpha);
dark->r += (r2 - dark->r) * alpha;
dark->g += (g2 - dark->g) * alpha;
dark->b += (b2 - dark->b) * alpha;
}
UNUSED(lastTime);
UNUSED(firedEvents);
UNUSED(eventsCount);
UNUSED(direction);
}
spRGB2Timeline* spRGB2Timeline_create (int framesCount, int bezierCount, int slotIndex) {
spRGB2Timeline* timeline = NEW(spRGB2Timeline);
spPropertyId ids[2];
ids[0] = ((spPropertyId)SP_PROPERTY_RGB << 32) | slotIndex;
ids[1] = ((spPropertyId)SP_PROPERTY_RGB2 << 32) | slotIndex;
_spCurveTimeline_init(SUPER(timeline), framesCount, RGB2_ENTRIES, bezierCount, ids, 2, _spCurveTimeline_dispose, _spRGB2Timeline_apply);
timeline->slotIndex = slotIndex;
return timeline;
}
void spRGB2Timeline_setFrame (spRGB2Timeline* self, int frameIndex, float time, float r, float g, float b, float r2, float g2, float b2) {
float *frames = self->super.super.frames->items;
frameIndex *= RGBA_ENTRIES;
frames[frameIndex] = time;
frames[frameIndex + COLOR_R] = r;
frames[frameIndex + COLOR_G] = g;
frames[frameIndex + COLOR_B] = b;
frames[frameIndex + COLOR2_R2] = r2;
frames[frameIndex + COLOR2_G2] = g2;
frames[frameIndex + COLOR2_B2] = b2;
} }
/**/ /**/
@ -1362,30 +1549,31 @@ void _spAttachmentTimeline_apply (const spTimeline* timeline, spSkeleton* skelet
const char* attachmentName; const char* attachmentName;
spAttachmentTimeline* self = (spAttachmentTimeline*)timeline; spAttachmentTimeline* self = (spAttachmentTimeline*)timeline;
int frameIndex; int frameIndex;
float* frames = self->super.frames->items;
spSlot* slot = skeleton->slots[self->slotIndex]; spSlot* slot = skeleton->slots[self->slotIndex];
if (!slot->bone->active) return; if (!slot->bone->active) return;
if (direction == SP_MIX_DIRECTION_OUT) { if (direction == SP_MIX_DIRECTION_OUT) {
if (blend == SP_MIX_BLEND_SETUP) if (blend == SP_MIX_BLEND_SETUP) {
_spSetAttachment(self, skeleton, slot, slot->data->attachmentName); _spSetAttachment(self, skeleton, slot, slot->data->attachmentName);
}
return; return;
} }
if (time < self->frames[0]) { if (time < frames[0]) {
if (blend == SP_MIX_BLEND_SETUP || blend == SP_MIX_BLEND_FIRST) { if (blend == SP_MIX_BLEND_SETUP || blend == SP_MIX_BLEND_FIRST) {
_spSetAttachment(self, skeleton, slot, slot->data->attachmentName); _spSetAttachment(self, skeleton, slot, slot->data->attachmentName);
} }
return; return;
} }
if (time >= self->frames[self->framesCount - 1]) if (time < frames[0]) {
frameIndex = self->framesCount - 1; if (blend == SP_MIX_BLEND_SETUP || blend == SP_MIX_BLEND_FIRST) _spSetAttachment(self, skeleton, slot, slot->data->attachmentName);
else return;
frameIndex = binarySearch1(self->frames, self->framesCount, time) - 1; }
attachmentName = self->attachmentNames[frameIndex]; attachmentName = self->attachmentNames[search(frames, self->super.frames->size, time)];
spSlot_setAttachment(skeleton->slots[self->slotIndex], _spSetAttachment(self, skeleton, slot, attachmentName);
attachmentName ? spSkeleton_getAttachmentForSlotIndex(skeleton, self->slotIndex, attachmentName) : 0);
UNUSED(lastTime); UNUSED(lastTime);
UNUSED(firedEvents); UNUSED(firedEvents);
@ -1393,36 +1581,25 @@ void _spAttachmentTimeline_apply (const spTimeline* timeline, spSkeleton* skelet
UNUSED(alpha); UNUSED(alpha);
} }
int _spAttachmentTimeline_getPropertyId (const spTimeline* timeline) {
return (SP_TIMELINE_ATTACHMENT << 24) + SUB_CAST(spAttachmentTimeline, timeline)->slotIndex;
}
void _spAttachmentTimeline_dispose (spTimeline* timeline) { void _spAttachmentTimeline_dispose (spTimeline* timeline) {
spAttachmentTimeline* self = SUB_CAST(spAttachmentTimeline, timeline); spAttachmentTimeline* self = SUB_CAST(spAttachmentTimeline, timeline);
int i; int i;
for (i = 0; i < self->super.frames->size; ++i)
_spTimeline_deinit(timeline); FREE(self->attachmentNames[i]);
FREE(self->attachmentNames);
for (i = 0; i < self->framesCount; ++i)
FREE(self->attachmentNames[i]);
FREE(self->attachmentNames);
FREE(self->frames);
FREE(self);
} }
spAttachmentTimeline* spAttachmentTimeline_create (int framesCount) { spAttachmentTimeline* spAttachmentTimeline_create (int framesCount, int slotIndex) {
spAttachmentTimeline* self = NEW(spAttachmentTimeline); spAttachmentTimeline* self = NEW(spAttachmentTimeline);
_spTimeline_init(SUPER(self), SP_TIMELINE_ATTACHMENT, _spAttachmentTimeline_dispose, _spAttachmentTimeline_apply, _spAttachmentTimeline_getPropertyId); spPropertyId ids[1];
ids[0] = ((spPropertyId)SP_PROPERTY_ATTACHMENT << 32) | slotIndex;
CONST_CAST(int, self->framesCount) = framesCount; _spTimeline_init(SUPER(self), framesCount, 1, ids, 1, _spAttachmentTimeline_dispose, _spAttachmentTimeline_apply);
CONST_CAST(float*, self->frames) = CALLOC(float, framesCount); CONST_CAST(char**, self->attachmentNames) = CALLOC(char*, framesCount);
CONST_CAST(char**, self->attachmentNames) = CALLOC(char*, framesCount);
return self; return self;
} }
void spAttachmentTimeline_setFrame (spAttachmentTimeline* self, int frameIndex, float time, const char* attachmentName) { void spAttachmentTimeline_setFrame (spAttachmentTimeline* self, int frameIndex, float time, const char* attachmentName) {
self->frames[frameIndex] = time; self->super.frames->items[frameIndex] = time;
FREE(self->attachmentNames[frameIndex]); FREE(self->attachmentNames[frameIndex]);
if (attachmentName) if (attachmentName)
@ -1463,8 +1640,8 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
return; return;
} }
frames = self->frames; frames = self->super.super.frames->items;
framesCount = self->framesCount; framesCount = self->super.super.frames->size;
vertexCount = self->frameVerticesCount; vertexCount = self->frameVerticesCount;
if (slot->deformCount < vertexCount) { if (slot->deformCount < vertexCount) {
if (slot->deformCapacity < vertexCount) { if (slot->deformCapacity < vertexCount) {
@ -1570,7 +1747,7 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
} }
/* Interpolate between the previous frame and the current frame. */ /* Interpolate between the previous frame and the current frame. */
frame = binarySearch(frames, framesCount, time, 1); frame = search2(frames, framesCount, time, 1);
prevVertices = frameVertices[frame - 1]; prevVertices = frameVertices[frame - 1];
nextVertices = frameVertices[frame]; nextVertices = frameVertices[frame];
frameTime = frames[frame]; frameTime = frames[frame];
@ -1645,10 +1822,6 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
UNUSED(direction); UNUSED(direction);
} }
int _spDeformTimeline_getPropertyId (const spTimeline* timeline) {
return (SP_TIMELINE_DEFORM << 27) + SUB_CAST(spVertexAttachment, SUB_CAST(spDeformTimeline, timeline)->attachment)->id + SUB_CAST(spDeformTimeline, timeline)->slotIndex;
}
void _spDeformTimeline_dispose (spTimeline* timeline) { void _spDeformTimeline_dispose (spTimeline* timeline) {
spDeformTimeline* self = SUB_CAST(spDeformTimeline, timeline); spDeformTimeline* self = SUB_CAST(spDeformTimeline, timeline);
int i; int i;

View File

@ -46,6 +46,13 @@ void spColor_setFromFloats(spColor* self, float r, float g, float b, float a) {
spColor_clamp(self); spColor_clamp(self);
} }
void spColor_setFromFloats3(spColor* self, float r, float g, float b) {
self->r = r;
self->g = g;
self->b = b;
spColor_clamp(self);
}
void spColor_setFromColor(spColor* self, spColor* otherColor) { void spColor_setFromColor(spColor* self, spColor* otherColor) {
self->r = otherColor->r; self->r = otherColor->r;
self->g = otherColor->g; self->g = otherColor->g;
@ -53,6 +60,12 @@ void spColor_setFromColor(spColor* self, spColor* otherColor) {
self->a = otherColor->a; self->a = otherColor->a;
} }
void spColor_setFromColor3(spColor* self, spColor* otherColor) {
self->r = otherColor->r;
self->g = otherColor->g;
self->b = otherColor->b;
}
void spColor_addColor(spColor* self, spColor* otherColor) { void spColor_addColor(spColor* self, spColor* otherColor) {
self->r += otherColor->r; self->r += otherColor->r;
self->g += otherColor->g; self->g += otherColor->g;
@ -69,6 +82,13 @@ void spColor_addFloats(spColor* self, float r, float g, float b, float a) {
spColor_clamp(self); spColor_clamp(self);
} }
void spColor_addFloats3(spColor* self, float r, float g, float b) {
self->r += r;
self->g += g;
self->b += b;
spColor_clamp(self);
}
void spColor_clamp(spColor* self) { void spColor_clamp(spColor* self) {
if (self->r < 0) self->r = 0; if (self->r < 0) self->r = 0;
else if (self->r > 1) self->r = 1; else if (self->r > 1) self->r = 1;

View File

@ -214,8 +214,6 @@ static void _sortReset(spBone** bones, int bonesCount) {
} }
static void _sortIkConstraint (_spSkeleton* const internal, spIkConstraint* constraint) { static void _sortIkConstraint (_spSkeleton* const internal, spIkConstraint* constraint) {
int /*bool*/ contains = 0;
int i;
spBone* target = constraint->target; spBone* target = constraint->target;
spBone** constrained; spBone** constrained;
spBone* parent; spBone* parent;
@ -281,7 +279,6 @@ static void _sortTransformConstraint(_spSkeleton* const internal, spTransformCon
int i, boneCount; int i, boneCount;
spBone** constrained; spBone** constrained;
spBone* child; spBone* child;
int /*boolean*/ contains = 0;
constraint->active = constraint->target->active && (!constraint->data->skinRequired || (internal->super.skin != 0 && spTransformConstraintDataArray_contains(internal->super.skin->transformConstraints, constraint->data))); constraint->active = constraint->target->active && (!constraint->data->skinRequired || (internal->super.skin != 0 && spTransformConstraintDataArray_contains(internal->super.skin->transformConstraints, constraint->data)));
if (!constraint->active) return; if (!constraint->active) return;
@ -408,7 +405,7 @@ void spSkeleton_updateWorldTransform (const spSkeleton* self) {
void spSkeleton_updateWorldTransformWith (const spSkeleton* self, const spBone *parent) { void spSkeleton_updateWorldTransformWith (const spSkeleton* self, const spBone *parent) {
/* Apply the parent bone transform to the root bone. The root bone always inherits scale, rotation and reflection. */ /* Apply the parent bone transform to the root bone. The root bone always inherits scale, rotation and reflection. */
int i, n; int i;
float rotationY, la, lb, lc, ld; float rotationY, la, lb, lc, ld;
_spUpdate *updateCache; _spUpdate *updateCache;
_spSkeleton* internal = SUB_CAST(_spSkeleton, self); _spSkeleton* internal = SUB_CAST(_spSkeleton, self);