[c] 4.0 porting, skeleton binary complete.

This commit is contained in:
badlogic 2021-05-20 11:30:34 +02:00
parent 7a7a69592a
commit 090f317602
4 changed files with 197 additions and 145 deletions

View File

@ -68,7 +68,7 @@ typedef enum {
SP_MIX_DIRECTION_OUT SP_MIX_DIRECTION_OUT
} spMixDirection; } 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 void spAnimation_dispose (spAnimation* self);
SP_API int /*bool*/ spAnimation_hasTimeline(spAnimation* self, spPropertyId* ids, int idsCount); SP_API int /*bool*/ spAnimation_hasTimeline(spAnimation* self, spPropertyId* ids, int idsCount);

View File

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

View File

@ -224,7 +224,7 @@ spAnimationState* spAnimationState_create (spAnimationStateData* data) {
if (!SP_EMPTY_ANIMATION) { if (!SP_EMPTY_ANIMATION) {
SP_EMPTY_ANIMATION = (spAnimation*)1; /* dirty trick so we can recursively call spAnimation_create */ 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); internal = NEW(_spAnimationState);

View File

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