瀏覽代碼

[c] 4.0 porting, skeleton binary complete.

badlogic 4 年之前
父節點
當前提交
090f317602

+ 1 - 1
spine-c/spine-c/include/spine/Animation.h

@@ -68,7 +68,7 @@ typedef enum {
 	SP_MIX_DIRECTION_OUT
 } spMixDirection;
 
-SP_API spAnimation* spAnimation_create (const char* name, spTimelineArray* timelines);
+SP_API spAnimation* spAnimation_create (const char* name, spTimelineArray* timelines, float duration);
 SP_API void spAnimation_dispose (spAnimation* self);
 SP_API int /*bool*/ spAnimation_hasTimeline(spAnimation* self, spPropertyId* ids, int idsCount);
 

+ 3 - 1
spine-c/spine-c/src/spine/Animation.c

@@ -35,13 +35,15 @@
 _SP_ARRAY_IMPLEMENT_TYPE(spPropertyIdArray, spPropertyId)
 _SP_ARRAY_IMPLEMENT_TYPE(spTimelineArray, spTimeline*)
 
-spAnimation* spAnimation_create (const char* name, spTimelineArray* timelines) {
+spAnimation* spAnimation_create (const char* name, spTimelineArray* timelines, float duration) {
     int i, n;
 	spAnimation* self = NEW(spAnimation);
 	MALLOC_STR(self->name, name);
+	self->timelines = timelines;
 	for (i = 0, n = timelines->size; i < n; i++) {
 	    spPropertyIdArray_addAllValues(self->timelineIds, timelines->items[i]->propertyIds, 0, timelines->items[i]->propertyIdsCount);
 	}
+	self->duration = duration;
 	return self;
 }
 

+ 1 - 1
spine-c/spine-c/src/spine/AnimationState.c

@@ -224,7 +224,7 @@ spAnimationState* spAnimationState_create (spAnimationStateData* data) {
 
 	if (!SP_EMPTY_ANIMATION) {
 		SP_EMPTY_ANIMATION = (spAnimation*)1; /* dirty trick so we can recursively call spAnimation_create */
-		SP_EMPTY_ANIMATION = spAnimation_create("<empty>", 0);
+		SP_EMPTY_ANIMATION = spAnimation_create("<empty>", NULL, 0);
 	}
 
 	internal = NEW(_spAnimationState);

+ 192 - 142
spine-c/spine-c/src/spine/SkeletonBinary.c

@@ -304,6 +304,7 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con
 	int frame, bezier;
 	int drawOrderCount, eventCount;
 	spAnimation* animation;
+	float scale = self->scale;
 
 	int numTimelines = readVarint(input, 1);
 	UNUSED(numTimelines);
@@ -479,7 +480,7 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con
 
                         switch (readSByte(input)) {
                             case CURVE_STEPPED:
-                                spCurveTimeline_setStepped(frame);
+                                spCurveTimeline_setStepped(SUPER(timeline), frame);
                                 break;
                             case CURVE_BEZIER:
                                 setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 0, time, time2, r, nr, 1);
@@ -537,100 +538,132 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con
 		for (ii = 0, nn = readVarint(input, 1); ii < nn; ++ii) {
 			unsigned char timelineType = readByte(input);
 			int frameCount = readVarint(input, 1);
+            int bezierCount = readVarint(input, 1);
+            spTimeline *timeline = NULL;
 			switch (timelineType) {
-			case BONE_ROTATE: {
-				spRotateTimeline *timeline = spRotateTimeline_create(frameCount);
-				timeline->boneIndex = boneIndex;
-				for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
-					float time = readFloat(input);
-					float degrees = readFloat(input);
-					spRotateTimeline_setFrame(timeline, frameIndex, time, degrees);
-					if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
-				}
-				spTimelineArray_add(timelines, (spTimeline*)timeline);
-				duration = MAX(duration, timeline->frames[(frameCount - 1) * ROTATE_ENTRIES]);
-				break;
-			}
-			case BONE_TRANSLATE:
-			case BONE_SCALE:
-			case BONE_SHEAR: {
-				float timelineScale = 1;
-				spTranslateTimeline *timeline = 0;
-				switch (timelineType) {
-					case BONE_SCALE:
-						timeline = spScaleTimeline_create(frameCount);
-						break;
-					case BONE_SHEAR:
-						timeline = spShearTimeline_create(frameCount);
-						break;
-					case BONE_TRANSLATE:
-						timeline = spTranslateTimeline_create(frameCount);
-						timelineScale = self->scale;
-						break;
-					default:
-						break;
-				}
-				timeline->boneIndex = boneIndex;
-				for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
-					float time = readFloat(input);
-					float x = readFloat(input) * timelineScale;
-					float y = readFloat(input) * timelineScale;
-					spTranslateTimeline_setFrame(timeline, frameIndex, time, x, y);
-					if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
-				}
-				spTimelineArray_add(timelines, (spTimeline*)timeline);
-				duration = MAX(duration, timeline->frames[(frameCount - 1) * TRANSLATE_ENTRIES]);
-				break;
-			}
-			default: {
-				for (iii = 0; iii < timelines->size; ++iii)
-					spTimeline_dispose(timelines->items[iii]);
-				spTimelineArray_dispose(timelines);
-				_spSkeletonBinary_setError(self, "Invalid timeline type for a bone: ", skeletonData->bones[boneIndex]->name);
-				return 0;
-			}
+                case BONE_ROTATE:
+                    timeline = readTimeline(input, SUPER(spRotateTimeline_create(frameCount, bezierCount, boneIndex)), 1);
+                    break;
+                case BONE_TRANSLATE:
+                    timeline = readTimeline2(input, SUPER(spTranslateTimeline_create(frameCount, bezierCount, boneIndex)), scale);
+                    break;
+                case BONE_TRANSLATEX:
+                    timeline = readTimeline(input, SUPER(spTranslateXTimeline_create(frameCount, bezierCount, boneIndex)), scale);
+                    break;
+                case BONE_TRANSLATEY:
+                    timeline = readTimeline(input, SUPER(spTranslateYTimeline_create(frameCount, bezierCount, boneIndex)), scale);
+                    break;
+                case BONE_SCALE:
+                    timeline = readTimeline2(input, SUPER(spScaleTimeline_create(frameCount, bezierCount, boneIndex)), 1);
+                    break;
+                case BONE_SCALEX:
+                    timeline = readTimeline(input, SUPER(spScaleXTimeline_create(frameCount, bezierCount, boneIndex)), 1);
+                    break;
+                case BONE_SCALEY:
+                    timeline = readTimeline(input, SUPER(spScaleYTimeline_create(frameCount, bezierCount, boneIndex)), 1);
+                    break;
+                case BONE_SHEAR:
+                    timeline = readTimeline2(input, SUPER(spShearTimeline_create(frameCount, bezierCount, boneIndex)), 1);
+                    break;
+                case BONE_SHEARX:
+                    timeline = readTimeline(input, SUPER(spShearXTimeline_create(frameCount, bezierCount, boneIndex)), 1);
+                    break;
+                case BONE_SHEARY:
+                    timeline = readTimeline(input, SUPER(spShearYTimeline_create(frameCount, bezierCount, boneIndex)), 1);
+                    break;
+                default: {
+                    for (iii = 0; iii < timelines->size; ++iii)
+                        spTimeline_dispose(timelines->items[iii]);
+                    spTimelineArray_dispose(timelines);
+                    _spSkeletonBinary_setError(self, "Invalid timeline type for a bone: ", skeletonData->bones[boneIndex]->name);
+                    return NULL;
+                }
 			}
+			spTimelineArray_add(timelines, timeline);
 		}
 	}
 
 	/* IK constraint timelines. */
 	for (i = 0, n = readVarint(input, 1); i < n; ++i) {
-		int index = readVarint(input, 1);
-		int frameCount = readVarint(input, 1);
-		spIkConstraintTimeline* timeline = spIkConstraintTimeline_create(frameCount);
-		timeline->ikConstraintIndex = index;
-		for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
-			float time = readFloat(input);
-			float mix = readFloat(input);
-			float softness = readFloat(input);
-			signed char bendDirection = readSByte(input);
-			int compress = readBoolean(input);
-			int stretch = readBoolean(input);
-			spIkConstraintTimeline_setFrame(timeline, frameIndex, time, mix, softness, bendDirection, compress, stretch);
-			if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
-		}
-		spTimelineArray_add(timelines, (spTimeline*)timeline);
-		duration = MAX(duration, timeline->frames[(frameCount - 1) * IKCONSTRAINT_ENTRIES]);
+        int index = readVarint(input, 1);
+        int frameCount = readVarint(input, 1);
+        int frameLast = frameCount - 1;
+        int bezierCount = readVarint(input, 1);
+        spIkConstraintTimeline *timeline = spIkConstraintTimeline_create(frameCount, bezierCount, index);
+        float time = readFloat(input);
+        float mix = readFloat(input);
+        float softness = readFloat(input) * scale;
+        for (frame = 0, bezier = 0;; frame++) {
+            float time2, mix2, softness2;
+            int bendDirection = readSByte(input);
+            int compress = readBoolean(input);
+            int stretch = readBoolean(input);
+            spIkConstraintTimeline_setFrame(timeline, frame, time, mix, softness, bendDirection, compress, stretch);
+            if (frame == frameLast) break;
+            time2 = readFloat(input);
+            mix2 = readFloat(input);
+            softness2 = readFloat(input) * scale;
+            switch (readSByte(input)) {
+                case CURVE_STEPPED:
+                    spCurveTimeline_setStepped(SUPER(timeline), frame);
+                    break;
+                case CURVE_BEZIER:
+                    setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 0, time, time2, mix, mix2, 1);
+                    setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 1, time, time2, softness, softness2, scale);
+            }
+            time = time2;
+            mix = mix2;
+            softness = softness2;
+        }
+        spTimelineArray_add(timelines, SUPER(SUPER(timeline)));
 	}
 
 	/* Transform constraint timelines. */
 	for (i = 0, n = readVarint(input, 1); i < n; ++i) {
-		int index = readVarint(input, 1);
-		int frameCount = readVarint(input, 1);
-		spTransformConstraintTimeline* timeline = spTransformConstraintTimeline_create(frameCount);
-		timeline->transformConstraintIndex = index;
-		for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
-			float time = readFloat(input);
-			float rotateMix = readFloat(input);
-			float translateMix = readFloat(input);
-			float scaleMix = readFloat(input);
-			float shearMix = readFloat(input);
-			spTransformConstraintTimeline_setFrame(timeline, frameIndex, time, rotateMix, translateMix,
-				scaleMix, shearMix);
-			if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
-		}
-		spTimelineArray_add(timelines, (spTimeline*)timeline);
-		duration = MAX(duration, timeline->frames[(frameCount - 1) * TRANSFORMCONSTRAINT_ENTRIES]);
+        int index = readVarint(input, 1);
+        int frameCount = readVarint(input, 1);
+        int frameLast = frameCount - 1;
+        int bezierCount = readVarint(input, 1);
+        spTransformConstraintTimeline *timeline = spTransformConstraintTimeline_create(frameCount, bezierCount, index);
+        float time = readFloat(input);
+        float mixRotate = readFloat(input);
+        float mixX = readFloat(input);
+        float mixY = readFloat(input);
+        float mixScaleX = readFloat(input);
+        float mixScaleY = readFloat(input);
+        float mixShearY = readFloat(input);
+        for (frame = 0, bezier = 0;; frame++) {
+            float time2, mixRotate2, mixX2, mixY2, mixScaleX2, mixScaleY2, mixShearY2;
+            spTransformConstraintTimeline_setFrame(timeline, frame, time, mixRotate, mixX, mixY, mixScaleX, mixScaleY, mixShearY);
+            if (frame == frameLast) break;
+            time2 = readFloat(input);
+            mixRotate2 = readFloat(input);
+            mixX2 = readFloat(input);
+            mixY2 = readFloat(input);
+            mixScaleX2 = readFloat(input);
+            mixScaleY2 = readFloat(input);
+            mixShearY2 = readFloat(input);
+            switch (readSByte(input)) {
+                case CURVE_STEPPED:
+                    spCurveTimeline_setStepped(SUPER(timeline), frame);
+                    break;
+                case CURVE_BEZIER:
+                    setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 0, time, time2, mixRotate, mixRotate2, 1);
+                    setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 1, time, time2, mixX, mixX2, 1);
+                    setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 2, time, time2, mixY, mixY2, 1);
+                    setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 3, time, time2, mixScaleX, mixScaleX2, 1);
+                    setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 4, time, time2, mixScaleY, mixScaleY2, 1);
+                    setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 5, time, time2, mixShearY, mixShearY2, 1);
+            }
+            time = time2;
+            mixRotate = mixRotate2;
+            mixX = mixX2;
+            mixY = mixY2;
+            mixScaleX = mixScaleX2;
+            mixScaleY = mixScaleY2;
+            mixShearY = mixShearY2;
+        }
+        spTimelineArray_add(timelines, SUPER(SUPER(timeline)));
 	}
 
 	/* Path constraint timelines. */
@@ -638,47 +671,58 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con
 		int index = readVarint(input, 1);
 		spPathConstraintData* data = skeletonData->pathConstraints[index];
 		for (ii = 0, nn = readVarint(input, 1); ii < nn; ++ii) {
-			unsigned char timelineType = readByte(input);
-			int frameCount = readVarint(input, 1);
-			switch (timelineType) {
-			case PATH_POSITION:
-			case PATH_SPACING: {
-				spPathConstraintPositionTimeline* timeline = 0;
-				float timelineScale = 1;
-				if (timelineType == PATH_SPACING) {
-					timeline = (spPathConstraintPositionTimeline*)spPathConstraintSpacingTimeline_create(frameCount);
-					if (data->spacingMode == SP_SPACING_MODE_LENGTH || data->spacingMode == SP_SPACING_MODE_FIXED)
-						timelineScale = self->scale;
-				} else {
-					timeline = spPathConstraintPositionTimeline_create(frameCount);
-					if (data->positionMode == SP_POSITION_MODE_FIXED)
-						timelineScale = self->scale;
-				}
-				timeline->pathConstraintIndex = index;
-				for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
-					float time = readFloat(input);
-					float value = readFloat(input) * timelineScale;
-					spPathConstraintPositionTimeline_setFrame(timeline, frameIndex, time, value);
-					if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
-				}
-				spTimelineArray_add(timelines, (spTimeline*)timeline);
-				duration = MAX(duration, timeline->frames[(frameCount - 1) * PATHCONSTRAINTPOSITION_ENTRIES]);
-				break;
-			}
-			case PATH_MIX: {
-				spPathConstraintMixTimeline* timeline = spPathConstraintMixTimeline_create(frameCount);
-				timeline->pathConstraintIndex = index;
-				for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
-					float time = readFloat(input);
-					float rotateMix = readFloat(input);
-					float translateMix = readFloat(input);
-					spPathConstraintMixTimeline_setFrame(timeline, frameIndex, time, rotateMix, translateMix);
-					if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
-				}
-				spTimelineArray_add(timelines, (spTimeline*)timeline);
-				duration = MAX(duration, timeline->frames[(frameCount - 1) * PATHCONSTRAINTMIX_ENTRIES]);
-			}
-			}
+            int type = readSByte(input);
+            int frameCount = readVarint(input, 1);
+            int bezierCount = readVarint(input, 1);
+            switch (type) {
+                case PATH_POSITION: {
+                    spTimelineArray_add(timelines, readTimeline(input, SUPER(spPathConstraintPositionTimeline_create(frameCount, bezierCount, index)),
+                            data->positionMode == SP_POSITION_MODE_FIXED ? scale : 1));
+                    break;
+                }
+                case PATH_SPACING: {
+                    spTimelineArray_add(timelines, readTimeline(input,
+                                              SUPER(spPathConstraintSpacingTimeline_create(frameCount,
+                                                                                bezierCount,
+                                                                                index)),
+                            data->spacingMode == SP_SPACING_MODE_LENGTH ||
+                            data->spacingMode == SP_SPACING_MODE_FIXED ? scale : 1));
+                    break;
+                }
+                case PATH_MIX: {
+                    float time, mixRotate, mixX, mixY;
+                    int frameLast;
+                    spPathConstraintMixTimeline *timeline = spPathConstraintMixTimeline_create(frameCount, bezierCount, index);
+                    time = readFloat(input);
+                    mixRotate = readFloat(input);
+                    mixX = readFloat(input);
+                    mixY = readFloat(input);
+                    for (frame = 0, bezier = 0, frameLast = spTimeline_getFrameCount(SUPER(SUPER(timeline))) - 1;; frame++) {
+                        float time2, mixRotate2, mixX2, mixY2;
+                        spPathConstraintMixTimeline_setFrame(timeline, frame, time, mixRotate, mixX, mixY);
+                        if (frame == frameLast) break;
+                        time2 = readFloat(input);
+                        mixRotate2 = readFloat(input);
+                        mixX2 = readFloat(input);
+                        mixY2 = readFloat(input);
+                        switch (readSByte(input)) {
+                            case CURVE_STEPPED:
+                                spCurveTimeline_setStepped(SUPER(timeline), frame);
+                                break;
+                            case CURVE_BEZIER:
+                                setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 0, time, time2, mixRotate, mixRotate2, 1);
+                                setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 1, time, time2, mixX, mixX2, 1);
+                                setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 2, time, time2, mixY, mixY2, 1);
+
+                        }
+                        time = time2;
+                        mixRotate = mixRotate2;
+                        mixX = mixX2;
+                        mixY = mixY2;
+                    }
+                    spTimelineArray_add(timelines, SUPER(SUPER(timeline)));
+                }
+            }
 		}
 	}
 
@@ -692,7 +736,8 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con
 				spDeformTimeline *timeline;
 				int weighted, deformLength;
 				const char* attachmentName = readStringRef(input, skeletonData);
-				int frameCount;
+				int frameCount, frameLast, bezierCount;
+				float time, time2;
 
 				spVertexAttachment* attachment = SUB_CAST(spVertexAttachment,
 					spSkin_getAttachment(skin, slotIndex, attachmentName));
@@ -709,12 +754,12 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con
 				tempDeform = MALLOC(float, deformLength);
 
 				frameCount = readVarint(input, 1);
-				timeline = spDeformTimeline_create(frameCount, deformLength);
-				timeline->slotIndex = slotIndex;
-				timeline->attachment = SUPER(attachment);
+				frameLast = frameCount - 1;
+				bezierCount = readVarint(input, 1);
+				timeline = spDeformTimeline_create(frameCount, deformLength, bezierCount, slotIndex, attachment);
 
-				for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
-					float time = readFloat(input);
+                time = readFloat(input);
+                for (frame = 0, bezier = 0;; ++frame) {
 					float* deform;
 					int end = readVarint(input, 1);
 					if (!end) {
@@ -742,13 +787,21 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con
 								deform[v] += vertices[v];
 						}
 					}
-					spDeformTimeline_setFrame(timeline, frameIndex, time, deform);
-					if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
+                    spDeformTimeline_setFrame(timeline, frame, time, deform);
+                    if (frame == frameLast) break;
+                    time2 = readFloat(input);
+                    switch(readSByte(input)) {
+                        case CURVE_STEPPED:
+                            spCurveTimeline_setStepped(SUPER(timeline), frame);
+                            break;
+                        case CURVE_BEZIER:
+                            setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 0, time, time2, 0, 1, 1);
+                    }
+                    time = time2;
 				}
 				FREE(tempDeform);
 
 				spTimelineArray_add(timelines, (spTimeline*)timeline);
-				duration = MAX(duration, timeline->frames[frameCount - 1]);
 			}
 		}
 	}
@@ -785,7 +838,6 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con
 			FREE(drawOrder);
 		}
 		spTimelineArray_add(timelines, (spTimeline*)timeline);
-		duration = MAX(duration, timeline->frames[drawOrderCount - 1]);
 	}
 
 	/* Event timeline. */
@@ -809,15 +861,13 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con
 			spEventTimeline_setFrame(timeline, i, event);
 		}
 		spTimelineArray_add(timelines, (spTimeline*)timeline);
-		duration = MAX(duration, timeline->frames[eventCount - 1]);
 	}
 
-	animation = spAnimation_create(name, 0);
-	FREE(animation->timelines);
-	animation->duration = duration;
-	animation->timelinesCount = timelines->size;
-	animation->timelines = timelines->items;
-	FREE(timelines);
+    duration = 0;
+    for (i = 0, n = timelines->size; i < n; i++) {
+        duration = MAX(duration, spTimeline_getDuration(timelines->items[i]));
+    }
+	animation = spAnimation_create(name, timelines, duration);
 	return animation;
 }