[c] 4.0 porting, skeleton binary.

This commit is contained in:
badlogic 2021-05-19 12:31:40 +02:00
parent 34ccbce8fd
commit 7a7a69592a
8 changed files with 319 additions and 102 deletions

View File

@ -123,6 +123,7 @@ struct spTimeline {
SP_API void spTimeline_dispose (spTimeline* self);
SP_API void spTimeline_apply (spTimeline* self, struct spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction);
SP_API void spTimeline_setBezier(spTimeline* self, int bezier, int frame, float value, float time1, float value1, float cx1, float cy1, float cx2, float cy2, float time2, float value2);
SP_API int spTimeline_getFrameCount (const spTimeline* self);
SP_API float spTimeline_getDuration (const spTimeline* self);
@ -281,7 +282,7 @@ typedef struct spRGBTimeline {
SP_API spRGBTimeline* spRGBTimeline_create (int framesCount, int bezierCount, int slotIndex);
SP_API void spRGBTimeline_setFrame (spRGBATimeline* self, int frameIndex, float time, float r, float g, float b);
SP_API void spRGBTimeline_setFrame (spRGBTimeline* self, int frameIndex, float time, float r, float g, float b);
/**/

View File

@ -49,7 +49,6 @@ struct spMeshAttachment {
int regionWidth, regionHeight; /* Unrotated, stripped pixel size. */
int regionOriginalWidth, regionOriginalHeight; /* Unrotated, unstripped pixel size. */
float regionU, regionV, regionU2, regionV2;
int/*bool*/regionRotate;
int regionDegrees;
const char* path;

View File

@ -55,7 +55,7 @@ typedef struct spRegionAttachment {
} spRegionAttachment;
SP_API spRegionAttachment* spRegionAttachment_create (const char* name);
SP_API void spRegionAttachment_setUVs (spRegionAttachment* self, float u, float v, float u2, float v2, int/*bool*/rotate);
SP_API void spRegionAttachment_setUVs (spRegionAttachment* self, float u, float v, float u2, float v2, float degrees);
SP_API void spRegionAttachment_updateOffset (spRegionAttachment* self);
SP_API void spRegionAttachment_computeWorldVertices (spRegionAttachment* self, spBone* bone, float* vertices, int offset, int stride);

View File

@ -128,6 +128,11 @@ void spTimeline_apply (spTimeline* self, spSkeleton* skeleton, float lastTime, f
self->vtable.apply(self, skeleton, lastTime, time, firedEvents, eventsCount, alpha, blend, direction);
}
void spTimeline_setBezier(spTimeline* self, int bezier, int frame, float value, float time1, float value1, float cx1, float cy1, float cx2, float cy2, float time2, float value2) {
if (self->vtable.setBezier)
self->vtable.setBezier(self, bezier, frame, value, time1, value1, cx1, cy1, cx2, cy2, time2, value2);
}
int spTimeline_getFrameCount (const spTimeline* self) {
return self->frames->size / self->frameEntries;
}
@ -1217,7 +1222,7 @@ spRGBTimeline* spRGBTimeline_create (int framesCount, int bezierCount, int slotI
return timeline;
}
void spRGBTimeline_setFrame (spRGBATimeline* self, int frameIndex, float time, float r, float g, float b) {
void spRGBTimeline_setFrame (spRGBTimeline* self, int frameIndex, float time, float r, float g, float b) {
float *frames = self->super.super.frames->items;
frameIndex *= RGB_ENTRIES;
frames[frameIndex] = time;

View File

@ -43,7 +43,7 @@ spAttachment* _spAtlasAttachmentLoader_createAttachment (spAttachmentLoader* loa
}
attachment = spRegionAttachment_create(name);
attachment->rendererObject = region;
spRegionAttachment_setUVs(attachment, region->u, region->v, region->u2, region->v2, region->rotate);
spRegionAttachment_setUVs(attachment, region->u, region->v, region->u2, region->v2, region->degrees);
attachment->regionOffsetX = region->offsetX;
attachment->regionOffsetY = region->offsetY;
attachment->regionWidth = region->width;
@ -66,7 +66,6 @@ spAttachment* _spAtlasAttachmentLoader_createAttachment (spAttachmentLoader* loa
attachment->regionV = region->v;
attachment->regionU2 = region->u2;
attachment->regionV2 = region->v2;
attachment->regionRotate = region->rotate;
attachment->regionDegrees = region->degrees;
attachment->regionOffsetX = region->offsetX;
attachment->regionOffsetY = region->offsetY;

View File

@ -56,7 +56,6 @@ spAttachment* _spMeshAttachment_copy (spAttachment* attachment) {
copy->regionV = self->regionV;
copy->regionU2 = self->regionU2;
copy->regionV2 = self->regionV2;
copy->regionRotate = self->regionRotate;
copy->regionDegrees = self->regionDegrees;
copy->regionOffsetX = self->regionOffsetX;
copy->regionOffsetY = self->regionOffsetY;
@ -95,7 +94,6 @@ spMeshAttachment* spMeshAttachment_newLinkedMesh (spMeshAttachment* self) {
copy->regionV = self->regionV;
copy->regionU2 = self->regionU2;
copy->regionV2 = self->regionV2;
copy->regionRotate = self->regionRotate;
copy->regionDegrees = self->regionDegrees;
copy->regionOffsetX = self->regionOffsetX;
copy->regionOffsetY = self->regionOffsetY;

View File

@ -74,8 +74,8 @@ spRegionAttachment* spRegionAttachment_create (const char* name) {
return self;
}
void spRegionAttachment_setUVs (spRegionAttachment* self, float u, float v, float u2, float v2, int/*bool*/rotate) {
if (rotate) {
void spRegionAttachment_setUVs (spRegionAttachment* self, float u, float v, float u2, float v2, float degrees) {
if (degrees == 90) {
self->uvs[URX] = u;
self->uvs[URY] = v2;
self->uvs[BRX] = u;

View File

@ -176,23 +176,32 @@ static void readColor (_dataInput* input, float *r, float *g, float *b, float *a
#define BLEND_MODE_MULTIPLY 2
#define BLEND_MODE_SCREEN 3
#define CURVE_LINEAR 0
#define CURVE_STEPPED 1
#define CURVE_BEZIER 2
#define BONE_ROTATE 0
#define BONE_TRANSLATE 1
#define BONE_SCALE 2
#define BONE_SHEAR 3
#define BONE_TRANSLATEX 2
#define BONE_TRANSLATEY 3
#define BONE_SCALE 4
#define BONE_SCALEX 5
#define BONE_SCALEY 6
#define BONE_SHEAR 7
#define BONE_SHEARX 8
#define BONE_SHEARY 9
#define SLOT_ATTACHMENT 0
#define SLOT_COLOR 1
#define SLOT_TWO_COLOR 2
#define SLOT_RGBA 1
#define SLOT_RGB 2
#define SLOT_RGBA2 3
#define SLOT_RGB2 4
#define SLOT_ALPHA 5
#define PATH_POSITION 0
#define PATH_SPACING 1
#define PATH_MIX 2
#define CURVE_LINEAR 0
#define CURVE_STEPPED 1
#define CURVE_BEZIER 2
#define PATH_POSITION_FIXED 0
#define PATH_POSITION_PERCENT 1
@ -204,21 +213,63 @@ static void readColor (_dataInput* input, float *r, float *g, float *b, float *a
#define PATH_ROTATE_CHAIN 1
#define PATH_ROTATE_CHAIN_SCALE 2
static void readCurve (_dataInput* input, spCurveTimeline* timeline, int frameIndex) {
switch (readByte(input)) {
case CURVE_STEPPED: {
spCurveTimeline_setStepped(timeline, frameIndex);
break;
}
case CURVE_BEZIER: {
float cx1 = readFloat(input);
float cy1 = readFloat(input);
float cx2 = readFloat(input);
float cy2 = readFloat(input);
spCurveTimeline_setCurve(timeline, frameIndex, cx1, cy1, cx2, cy2);
break;
}
}
static void setBezier(_dataInput* input, spTimeline* timeline, int bezier, int frame, int value, float time1, float time2,
float value1, float value2, float scale) {
float cx1 = readFloat(input);
float cy1 = readFloat(input);
float cx2 = readFloat(input);
float cy2 = readFloat(input);
spTimeline_setBezier(timeline, bezier, frame, value, time1, value1, cx1, cy1 * scale, cx2, cy2 * scale, time2, value2);
}
static spTimeline* readTimeline (_dataInput *input, spCurveTimeline1 *timeline, float scale) {
int frame, bezier, frameLast;
float time2, value2;
float time = readFloat(input);
float value = readFloat(input) * scale;
for (frame = 0, bezier = 0, frameLast = spTimeline_getFrameCount(SUPER(timeline)) - 1;; frame++) {
spCurveTimeline1_setFrame(timeline, frame, time, value);
if (frame == frameLast) break;
time2 = readFloat(input);
value2 = readFloat(input) * scale;
switch (readSByte(input)) {
case CURVE_STEPPED:
spCurveTimeline_setStepped(timeline, frame);
break;
case CURVE_BEZIER:
setBezier(input, SUPER(timeline), bezier++, frame, 0, time, time2, value, value2, 1);
}
time = time2;
value = value2;
}
return SUPER(timeline);
}
static spTimeline* readTimeline2 (_dataInput *input, spCurveTimeline2 *timeline, float scale) {
int frame, bezier, frameLast;
float time2, nvalue1, nvalue2;
float time = readFloat(input);
float value1 = readFloat(input) * scale;
float value2 = readFloat(input) * scale;
for (frame = 0, bezier = 0, frameLast = spTimeline_getFrameCount(SUPER(timeline)) - 1;; frame++) {
spCurveTimeline2_setFrame(timeline, frame, time, value1, value2);
if (frame == frameLast) break;
time2 = readFloat(input);
nvalue1 = readFloat(input) * scale;
nvalue2 = readFloat(input) * scale;
switch (readSByte(input)) {
case CURVE_STEPPED:
spCurveTimeline_setStepped(timeline, frame);
break;
case CURVE_BEZIER:
setBezier(input, SUPER(timeline), bezier++, frame, 0, time, time2, value1, nvalue1, scale);
setBezier(input, SUPER(timeline), bezier++, frame, 1, time, time2, value2, nvalue2, scale);
}
time = time2;
value1 = nvalue1;
value2 = nvalue2;
}
return SUPER(timeline);
}
static void _spSkeletonBinary_addLinkedMesh (spSkeletonBinary* self, spMeshAttachment* mesh,
@ -250,67 +301,232 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con
spTimelineArray* timelines = spTimelineArray_create(18);
float duration = 0;
int i, n, ii, nn, iii, nnn;
int frameIndex;
int frame, bezier;
int drawOrderCount, eventCount;
spAnimation* animation;
int numTimelines = readVarint(input, 1);
UNUSED(numTimelines);
/* Slot timelines. */
for (i = 0, n = readVarint(input, 1); i < n; ++i) {
int slotIndex = readVarint(input, 1);
for (ii = 0, nn = readVarint(input, 1); ii < nn; ++ii) {
unsigned char timelineType = readByte(input);
int frameCount = readVarint(input, 1);
int frameLast = frameCount - 1;
switch (timelineType) {
case SLOT_ATTACHMENT: {
spAttachmentTimeline* timeline = spAttachmentTimeline_create(frameCount);
timeline->slotIndex = slotIndex;
for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
float time = readFloat(input);
const char* attachmentName = readStringRef(input, skeletonData);
/* TODO Avoid copying of attachmentName inside */
spAttachmentTimeline_setFrame(timeline, frameIndex, time, attachmentName);
}
spTimelineArray_add(timelines, (spTimeline*)timeline);
duration = MAX(duration, timeline->frames[frameCount - 1]);
break;
}
case SLOT_COLOR: {
spColorTimeline* timeline = spColorTimeline_create(frameCount);
timeline->slotIndex = slotIndex;
for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
float time = readFloat(input);
float r, g, b, a;
readColor(input, &r, &g, &b, &a);
spColorTimeline_setFrame(timeline, frameIndex, time, r, g, b, a);
if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
}
spTimelineArray_add(timelines, (spTimeline*)timeline);
duration = MAX(duration, timeline->frames[(frameCount - 1) * COLOR_ENTRIES]);
break;
}
case SLOT_TWO_COLOR: {
spTwoColorTimeline* timeline = spTwoColorTimeline_create(frameCount);
timeline->slotIndex = slotIndex;
for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
float time = readFloat(input);
float r, g, b, a;
float r2, g2, b2, a2;
readColor(input, &r, &g, &b, &a);
readColor(input, &a2, &r2, &g2, &b2);
spTwoColorTimeline_setFrame(timeline, frameIndex, time, r, g, b, a, r2, g2, b2);
if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
}
spTimelineArray_add(timelines, (spTimeline*)timeline);
duration = MAX(duration, timeline->frames[(frameCount - 1) * TWOCOLOR_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 slot: ", skeletonData->slots[slotIndex]->name);
return 0;
}
case SLOT_ATTACHMENT: {
spAttachmentTimeline *timeline = spAttachmentTimeline_create(frameCount, slotIndex);
for (frame = 0; frame < frameCount; ++frame) {
float time = readFloat(input);
const char *attachmentName = readStringRef(input, skeletonData);
spAttachmentTimeline_setFrame(timeline, frame, time, attachmentName);
}
spTimelineArray_add(timelines, SUPER(timeline));
break;
}
case SLOT_RGBA: {
int bezierCount = readVarint(input, 1);
spRGBATimeline *timeline = spRGBATimeline_create(frameCount, bezierCount, slotIndex);
float time = readFloat(input);
float r = readByte(input) / 255.0;
float g = readByte(input) / 255.0;
float b = readByte(input) / 255.0;
float a = readByte(input) / 255.0;
for (frame = 0, bezier = 0;; frame++) {
float time2, r2, g2, b2, a2;
spRGBATimeline_setFrame(timeline, frame, time, r, g, b, a);
if (frame == frameLast) break;
time2 = readFloat(input);
r2 = readByte(input) / 255.0;
g2 = readByte(input) / 255.0;
b2 = readByte(input) / 255.0;
a2 = readByte(input) / 255.0;
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, r, r2, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 1, time, time2, g, g2, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 2, time, time2, b, b2, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 3, time, time2, a, a2, 1);
}
time = time2;
r = r2;
g = g2;
b = b2;
a = a2;
}
spTimelineArray_add(timelines, SUPER(SUPER(timeline)));
break;
}
case SLOT_RGB: {
int bezierCount = readVarint(input, 1);
spRGBTimeline *timeline = spRGBTimeline_create(frameCount, bezierCount, slotIndex);
float time = readFloat(input);
float r = readByte(input) / 255.0;
float g = readByte(input) / 255.0;
float b = readByte(input) / 255.0;
for (frame = 0, bezier = 0;; frame++) {
float time2, r2, g2, b2;
spRGBTimeline_setFrame(timeline, frame, time, r, g, b);
if (frame == frameLast) break;
time2 = readFloat(input);
r2 = readByte(input) / 255.0;
g2 = readByte(input) / 255.0;
b2 = readByte(input) / 255.0;
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, r, r2, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 1, time, time2, g, g2, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 2, time, time2, b, b2, 1);
}
time = time2;
r = r2;
g = g2;
b = b2;
}
spTimelineArray_add(timelines, SUPER(SUPER(timeline)));
break;
}
case SLOT_RGBA2: {
int bezierCount = readVarint(input, 1);
spRGBA2Timeline *timeline = spRGBA2Timeline_create(frameCount, bezierCount, slotIndex);
float time = readFloat(input);
float r = readByte(input) / 255.0;
float g = readByte(input) / 255.0;
float b = readByte(input) / 255.0;
float a = readByte(input) / 255.0;
float r2 = readByte(input) / 255.0;
float g2 = readByte(input) / 255.0;
float b2 = readByte(input) / 255.0;
for (frame = 0, bezier = 0;; frame++) {
float time2, nr, ng, nb, na, nr2, ng2, nb2;
spRGBA2Timeline_setFrame(timeline, frame, time, r, g, b, a, r2, g2, b2);
if (frame == frameLast) break;
time2 = readFloat(input);
nr = readByte(input) / 255.0;
ng = readByte(input) / 255.0;
nb = readByte(input) / 255.0;
na = readByte(input) / 255.0;
nr2 = readByte(input) / 255.0;
ng2 = readByte(input) / 255.0;
nb2 = readByte(input) / 255.0;
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, r, nr, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 1, time, time2, g, ng, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 2, time, time2, b, nb, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 3, time, time2, a, na, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 4, time, time2, r2, nr2, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 5, time, time2, g2, ng2, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 6, time, time2, b2, nb2, 1);
}
time = time2;
r = nr;
g = ng;
b = nb;
a = na;
r2 = nr2;
g2 = ng2;
b2 = nb2;
}
spTimelineArray_add(timelines, SUPER(SUPER(timeline)));
break;
}
case SLOT_RGB2: {
int bezierCount = readVarint(input, 1);
spRGB2Timeline *timeline = spRGB2Timeline_create(frameCount, bezierCount, slotIndex);
float time = readFloat(input);
float r = readByte(input) / 255.0;
float g = readByte(input) / 255.0;
float b = readByte(input) / 255.0;
float r2 = readByte(input) / 255.0;
float g2 = readByte(input) / 255.0;
float b2 = readByte(input) / 255.0;
for (frame = 0, bezier = 0;; frame++) {
float time2, nr, ng, nb, nr2, ng2, nb2;
spRGB2Timeline_setFrame(timeline, frame, time, r, g, b, r2, g2, b2);
if (frame == frameLast) break;
time2 = readFloat(input);
nr = readByte(input) / 255.0;
ng = readByte(input) / 255.0;
nb = readByte(input) / 255.0;
nr2 = readByte(input) / 255.0;
ng2 = readByte(input) / 255.0;
nb2 = readByte(input) / 255.0;
switch (readSByte(input)) {
case CURVE_STEPPED:
spCurveTimeline_setStepped(frame);
break;
case CURVE_BEZIER:
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 0, time, time2, r, nr, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 1, time, time2, g, ng, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 2, time, time2, b, nb, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 3, time, time2, r2, nr2, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 4, time, time2, g2, ng2, 1);
setBezier(input, SUPER(SUPER(timeline)), bezier++, frame, 5, time, time2, b2, nb2, 1);
}
time = time2;
r = nr;
g = ng;
b = nb;
r2 = nr2;
g2 = ng2;
b2 = nb2;
}
spTimelineArray_add(timelines, SUPER(SUPER(timeline)));
break;
}
case SLOT_ALPHA: {
int bezierCount = readVarint(input, 1);
spAlphaTimeline *timeline = spAlphaTimeline_create(frameCount, bezierCount, slotIndex);
float time = readFloat(input);
float a = readByte(input) / 255.0;
for (frame = 0, bezier = 0;; frame++) {
float time2, a2;
spAlphaTimeline_setFrame(timeline, frame, time, a);
if (frame == frameLast) break;
time2 = readFloat(input);
a2 = readByte(input) / 255;
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, a, a2, 1);
}
time = time2;
a = a2;
}
spTimelineArray_add(timelines, SUPER(SUPER(timeline)));
break;
}
default: {
return NULL;
}
}
}
}
@ -873,6 +1089,8 @@ spSkeletonData* spSkeletonBinary_readSkeletonDataFile (spSkeletonBinary* self, c
spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const unsigned char* binary,
const int length) {
int i, n, ii, nonessential;
char buffer[16];
int lowHash, highHash;
spSkeletonData* skeletonData;
_spSkeletonBinary* internal = SUB_CAST(_spSkeletonBinary, self);
@ -885,24 +1103,18 @@ spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const
internal->linkedMeshCount = 0;
skeletonData = spSkeletonData_create();
skeletonData->hash = readString(input);
if (!strlen(skeletonData->hash)) {
FREE(skeletonData->hash);
skeletonData->hash = 0;
}
lowHash = readInt(input);
highHash = readInt(input);
sprintf(buffer, "%x", highHash);
sprintf(buffer + 8, "%x", lowHash);
buffer[15] = 0;
skeletonData->hash = strdup(buffer);
skeletonData->version = readString(input);
if (!strlen(skeletonData->version)) {
FREE(skeletonData->version);
skeletonData->version = 0;
}
if (strcmp(skeletonData->version, "3.8.75") == 0) {
FREE(input);
spSkeletonData_dispose(skeletonData);
_spSkeletonBinary_setError(self, "Unsupported skeleton data, please export with a newer version of Spine.", "");
return 0;
}
skeletonData->x = readFloat(input);
skeletonData->y = readFloat(input);
@ -1031,10 +1243,12 @@ spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const
data->offsetScaleX = readFloat(input);
data->offsetScaleY = readFloat(input);
data->offsetShearY = readFloat(input);
data->rotateMix = readFloat(input);
data->translateMix = readFloat(input);
data->scaleMix = readFloat(input);
data->shearMix = readFloat(input);
data->mixRotate = readFloat(input);
data->mixX = readFloat(input);
data->mixY = readFloat(input);
data->mixScaleX = readFloat(input);
data->mixScaleY = readFloat(input);
data->mixShearY = readFloat(input);
skeletonData->transformConstraints[i] = data;
}
@ -1061,8 +1275,9 @@ spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const
if (data->positionMode == SP_POSITION_MODE_FIXED) data->position *= self->scale;
data->spacing = readFloat(input);
if (data->spacingMode == SP_SPACING_MODE_LENGTH || data->spacingMode == SP_SPACING_MODE_FIXED) data->spacing *= self->scale;
data->rotateMix = readFloat(input);
data->translateMix = readFloat(input);
data->mixRotate = readFloat(input);
data->mixX = readFloat(input);
data->mixY = readFloat(input);
skeletonData->pathConstraints[i] = data;
}