Browse Source

[c] 4.0 porting, SRTS timelines.

badlogic 4 years ago
parent
commit
25f202abe0
2 changed files with 208 additions and 57 deletions
  1. 27 2
      spine-c/spine-c/include/spine/Animation.h
  2. 181 55
      spine-c/spine-c/src/spine/Animation.c

+ 27 - 2
spine-c/spine-c/include/spine/Animation.h

@@ -226,14 +226,39 @@ SP_API void spScaleYTimeline_setFrame (spScaleYTimeline* self, int frame, float
 
 /**/
 
-typedef struct spBaseTimeline spShearTimeline;
+typedef struct spShearTimeline {
+    spCurveTimeline2 super;
+    int boneIndex;
+} spShearTimeline;
 
-SP_API spShearTimeline* spShearTimeline_create (int framesCount);
+SP_API spShearTimeline* spShearTimeline_create (int frameCount, int bezierCount, int boneIndex);
 
 SP_API void spShearTimeline_setFrame (spShearTimeline* self, int frameIndex, float time, float x, float y);
 
 /**/
 
+typedef struct spShearXTimeline {
+    spCurveTimeline1 super;
+    int boneIndex;
+} spShearXTimeline;
+
+SP_API spShearXTimeline* spShearXTimeline_create (int frameCount, int bezierCount, int boneIndex);
+
+SP_API void spShearXTimeline_setFrame (spShearXTimeline* self, int frame, float time, float x);
+
+/**/
+
+typedef struct spShearYTimeline {
+    spCurveTimeline1 super;
+    int boneIndex;
+} spShearYTimeline;
+
+SP_API spShearYTimeline* spShearYTimeline_create (int frameCount, int bezierCount, int boneIndex);
+
+SP_API void spShearYTimeline_setFrame (spShearYTimeline* self, int frame, float time, float x);
+
+/**/
+
 static const int COLOR_ENTRIES = 5;
 
 typedef struct spColorTimeline {

+ 181 - 55
spine-c/spine-c/src/spine/Animation.c

@@ -833,61 +833,66 @@ void _spShearTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
 ) {
 	spBone *bone;
 	int frame;
-	float frameTime, percent, x, y;
-	float *frames;
-	int framesCount;
+	float x, y, t;
+	int i, curveType;
 
 	spShearTimeline* self = SUB_CAST(spShearTimeline, timeline);
+	float* frames = SUPER(self)->super.frames->items;
+	float* curves = SUPER(self)->curves->items;
 
 	bone = skeleton->bones[self->boneIndex];
 	if (!bone->active) return;
-	frames = self->frames;
-	framesCount = self->framesCount;
-	if (time < self->frames[0]) {
-		switch (blend) {
-		case SP_MIX_BLEND_SETUP:
-			bone->shearX = bone->data->shearX;
-			bone->shearY = bone->data->shearY;
-			return;
-		case SP_MIX_BLEND_FIRST:
-			bone->shearX += (bone->data->shearX - bone->shearX) * alpha;
-			bone->shearY += (bone->data->shearY - bone->shearY) * alpha;
-		case SP_MIX_BLEND_REPLACE:
-		case SP_MIX_BLEND_ADD:
-			; /* to appease compiler */
-		}
-		return;
-	}
-
-	if (time >= frames[framesCount - TRANSLATE_ENTRIES]) { /* Time is after last frame. */
-		x = frames[framesCount + TRANSLATE_PREV_X];
-		y = frames[framesCount + TRANSLATE_PREV_Y];
-	} else {
-		/* Interpolate between the previous frame and the current frame. */
-		frame = binarySearch(frames, framesCount, time, TRANSLATE_ENTRIES);
-		x = frames[frame + TRANSLATE_PREV_X];
-		y = frames[frame + TRANSLATE_PREV_Y];
-		frameTime = frames[frame];
-		percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TRANSLATE_ENTRIES - 1,
-			1 - (time - frameTime) / (frames[frame + TRANSLATE_PREV_TIME] - frameTime));
+    if (time < frames[0]) {
+        switch (blend) {
+            case SP_MIX_BLEND_SETUP:
+                bone->shearX = bone->data->shearX;
+                bone->shearY = bone->data->shearY;
+                return;
+            case SP_MIX_BLEND_FIRST:
+                bone->shearX += (bone->data->shearX - bone->shearX) * alpha;
+                bone->shearY += (bone->data->shearY - bone->shearY) * alpha;
+            default: {}
+        }
+        return;
+    }
+    
+    i = search(frames, time, CURVE2_ENTRIES);
+    curveType = (int)curves[i / CURVE2_ENTRIES];
+    switch (curveType) {
+        case CURVE_LINEAR: {
+            float before = frames[i];
+            x = frames[i + CURVE2_VALUE1];
+            y = frames[i + CURVE2_VALUE2];
+            t = (time - before) / (frames[i + CURVE2_ENTRIES] - before);
+            x += (frames[i + CURVE2_ENTRIES + CURVE2_VALUE1] - x) * t;
+            y += (frames[i + CURVE2_ENTRIES + CURVE2_VALUE2] - y) * t;
+            break;
+        }
+        case CURVE_STEPPED: {
+            x = frames[i + CURVE2_VALUE1];
+            y = frames[i + CURVE2_VALUE2];
+            break;
+        }
+        default: {
+            x = _spCurveTimeline_getBezierValue(SUPER(self), time, i, CURVE2_VALUE1, curveType - CURVE_BEZIER);
+            y = _spCurveTimeline_getBezierValue(SUPER(self), time, i, CURVE2_VALUE2, curveType + BEZIER_SIZE - CURVE_BEZIER);
+        }
+    }
 
-		x = x + (frames[frame + TRANSLATE_X] - x) * percent;
-		y = y + (frames[frame + TRANSLATE_Y] - y) * percent;
-	}
-	switch (blend) {
-	case SP_MIX_BLEND_SETUP:
-		bone->shearX = bone->data->shearX + x * alpha;
-		bone->shearY = bone->data->shearY + y * alpha;
-		break;
-	case SP_MIX_BLEND_FIRST:
-	case SP_MIX_BLEND_REPLACE:
-		bone->shearX += (bone->data->shearX + x - bone->shearX) * alpha;
-		bone->shearY += (bone->data->shearY + y - bone->shearY) * alpha;
-		break;
-	case SP_MIX_BLEND_ADD:
-		bone->shearX += x * alpha;
-		bone->shearY += y * alpha;
-	}
+    switch (blend) {
+        case SP_MIX_BLEND_SETUP:
+            bone->shearX = bone->data->shearX + x * alpha;
+            bone->shearY = bone->data->shearY + y * alpha;
+            break;
+        case SP_MIX_BLEND_FIRST:
+        case SP_MIX_BLEND_REPLACE:
+            bone->shearX += (bone->data->shearX + x - bone->shearX) * alpha;
+            bone->shearY += (bone->data->shearY + y - bone->shearY) * alpha;
+            break;
+        case SP_MIX_BLEND_ADD:
+            bone->shearX += x * alpha;
+            bone->shearY += y * alpha;
+    }
 
 	UNUSED(lastTime);
 	UNUSED(firedEvents);
@@ -895,16 +900,137 @@ void _spShearTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
 	UNUSED(direction);
 }
 
-int _spShearTimeline_getPropertyId (const spTimeline* timeline) {
-	return (SP_TIMELINE_SHEAR << 24) + SUB_CAST(spShearTimeline, timeline)->boneIndex;
+spShearTimeline* spShearTimeline_create (int frameCount, int bezierCount, int boneIndex) {
+    spShearTimeline* timeline = NEW(spShearTimeline);
+    spPropertyId ids[2];
+    ids[0] = ((spPropertyId)SP_PROPERTY_SHEARX << 32) | boneIndex;
+    ids[1] = ((spPropertyId)SP_PROPERTY_SHEARY << 32) | boneIndex;
+    _spCurveTimeline_init(SUPER(timeline), frameCount, CURVE2_ENTRIES, bezierCount, ids, 2, _spCurveTimeline_dispose, _spShearTimeline_apply);
+    timeline->boneIndex = boneIndex;
+    return timeline;
 }
 
-spShearTimeline* spShearTimeline_create (int framesCount) {
-	return (spShearTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_SHEAR, 3, _spShearTimeline_apply, _spShearTimeline_getPropertyId);
+void spShearTimeline_setFrame (spShearTimeline* self, int frameIndex, float time, float x, float y) {
+    spCurveTimeline2_setFrame(SUPER(self), frameIndex, time, x, y);
 }
 
-void spShearTimeline_setFrame (spShearTimeline* self, int frameIndex, float time, float x, float y) {
-	spTranslateTimeline_setFrame(self, frameIndex, time, x, y);
+/**/
+
+void _spShearXTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
+                              spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
+) {
+    spBone *bone;
+    int frame;
+    float x;
+    int curveType;
+
+    spTranslateXTimeline* self = SUB_CAST(spTranslateXTimeline, timeline);
+    float *frames = self->super.super.frames->items;
+    float *curves = self->super.curves->items;
+
+    bone = skeleton->bones[self->boneIndex];
+    if (!bone->active) return;
+
+    if (time < frames[0]) {
+        switch (blend) {
+            case SP_MIX_BLEND_SETUP:
+                bone->shearX = bone->data->shearX;
+                return;
+            case SP_MIX_BLEND_FIRST:
+                bone->shearX += (bone->data->shearX - bone->shearX) * alpha;
+            default: {}
+        }
+        return;
+    }
+
+    x = spCurveTimeline1_getCurveValue(SUPER(self), time);
+    switch (blend) {
+        case SP_MIX_BLEND_SETUP:
+            bone->shearX = bone->data->shearX + x * alpha;
+            break;
+        case SP_MIX_BLEND_FIRST:
+        case SP_MIX_BLEND_REPLACE:
+            bone->shearX += (bone->data->shearX + x - bone->shearX) * alpha;
+            break;
+        case SP_MIX_BLEND_ADD:
+            bone->shearX += x * alpha;
+    }
+    UNUSED(lastTime);
+    UNUSED(firedEvents);
+    UNUSED(eventsCount);
+}
+
+spShearXTimeline* spShearXTimeline_create (int frameCount, int bezierCount, int boneIndex) {
+    spShearXTimeline* timeline = NEW(spShearXTimeline);
+    spPropertyId ids[1];
+    ids[0] = ((spPropertyId)SP_PROPERTY_SHEARX << 32) | boneIndex;
+    _spCurveTimeline_init(SUPER(timeline), frameCount, CURVE1_ENTRIES, bezierCount, ids, 1, _spCurveTimeline_dispose, _spShearXTimeline_apply);
+    timeline->boneIndex = boneIndex;
+    return timeline;
+}
+
+void spShearXTimeline_setFrame (spShearXTimeline* self, int frame, float time, float x) {
+    spCurveTimeline1_setFrame(SUPER(self), frame, time, x);
+}
+
+/**/
+
+void _spShearYTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
+                              spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
+) {
+    spBone *bone;
+    int frame;
+    float y, t;
+    int i, curveType;
+
+    spTranslateXTimeline* self = SUB_CAST(spTranslateXTimeline, timeline);
+    float *frames = self->super.super.frames->items;
+    float *curves = self->super.curves->items;
+
+    bone = skeleton->bones[self->boneIndex];
+    if (!bone->active) return;
+
+    if (time < frames[0]) {
+        switch (blend) {
+            case SP_MIX_BLEND_SETUP:
+                bone->shearY = bone->data->shearY;
+                return;
+            case SP_MIX_BLEND_FIRST:
+                bone->shearY += (bone->data->shearY - bone->shearY) * alpha;
+            default: {}
+        }
+        return;
+    }
+
+    y = spCurveTimeline1_getCurveValue(SUPER(self), time);
+    switch (blend) {
+        case SP_MIX_BLEND_SETUP:
+            bone->shearY = bone->data->shearY + y * alpha;
+            break;
+        case SP_MIX_BLEND_FIRST:
+        case SP_MIX_BLEND_REPLACE:
+            bone->shearY += (bone->data->shearY + y - bone->shearY) * alpha;
+            break;
+        case SP_MIX_BLEND_ADD:
+            bone->shearY += y * alpha;
+    }
+    
+    UNUSED(lastTime);
+    UNUSED(firedEvents);
+    UNUSED(eventsCount);
+}
+
+spShearYTimeline* spShearYTimeline_create (int frameCount, int bezierCount, int boneIndex) {
+    spShearYTimeline* timeline = NEW(spShearYTimeline);
+    spPropertyId ids[1];
+    ids[0] = ((spPropertyId)SP_PROPERTY_SHEARY << 32) | boneIndex;
+    _spCurveTimeline_init(SUPER(timeline), frameCount, CURVE1_ENTRIES, bezierCount, ids, 1, _spCurveTimeline_dispose, _spShearYTimeline_apply);
+    timeline->boneIndex = boneIndex;
+    return timeline;
+}
+
+void spShearYTimeline_setFrame (spShearYTimeline* self, int frame, float time, float y) {
+    spCurveTimeline1_setFrame(SUPER(self), frame, time, y);
 }
 
 /**/