[c] Sequence support in SkeletonBinary and SkeletonJson.

This commit is contained in:
Mario Zechner 2022-02-10 16:00:53 +01:00
parent 3289550eb0
commit 9319029763
10 changed files with 340 additions and 140 deletions

View File

@ -34,6 +34,7 @@
#include <spine/Event.h>
#include <spine/Attachment.h>
#include <spine/VertexAttachment.h>
#include <spine/Sequence.h>
#include <spine/Array.h>
#include <stdint.h>
@ -99,6 +100,7 @@ typedef enum {
SP_TIMELINE_SHEAR,
SP_TIMELINE_TRANSLATE,
SP_TIMELINE_DEFORM,
SP_TIMELINE_SEQUENCE,
SP_TIMELINE_IKCONSTRAINT,
SP_TIMELINE_PATHCONSTRAINTMIX,
SP_TIMELINE_RGB2,
@ -131,7 +133,8 @@ typedef enum {
SP_PROPERTY_TRANSFORMCONSTRAINT = 1 << 15,
SP_PROPERTY_PATHCONSTRAINT_POSITION = 1 << 16,
SP_PROPERTY_PATHCONSTRAINT_SPACING = 1 << 17,
SP_PROPERTY_PATHCONSTRAINT_MIX = 1 << 18
SP_PROPERTY_PATHCONSTRAINT_MIX = 1 << 18,
SP_PROPERTY_SEQUENCE = 1 << 19
} spProperty;
#define SP_MAX_PROPERTY_IDS 3
@ -399,6 +402,20 @@ SP_API void spDeformTimeline_setFrame(spDeformTimeline *self, int frameIndex, fl
/**/
typedef struct spSequenceTimeline {
spTimeline super;
int slotIndex;
spAttachment *attachment;
} spSequenceTimeline;
SP_API spSequenceTimeline *spSequenceTimeline_create(int framesCount, int slotIndex, spAttachment *attachment);
SP_API void spSequenceTimeline_setFrame(spSequenceTimeline *self, int frameIndex, float time, int mode, int index, float delay);
/**/
/**/
typedef struct spEventTimeline {
spTimeline super;
spEvent **const events;

View File

@ -1999,6 +1999,122 @@ void spDeformTimeline_setFrame(spDeformTimeline *self, int frame, float time, fl
/**/
static const int SEQUENCE_ENTRIES = 3, MODE = 1, DELAY = 2;
void _spSequenceTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time, spEvent **firedEvents,
int *eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
spSequenceTimeline *self = (spSequenceTimeline *) timeline;
spSlot *slot = skeleton->slots[self->slotIndex];
spAttachment *slotAttachment;
float *frames;
int i, modeAndIndex, count, index, mode;
float before, delay;
spSequence *sequence = NULL;
if (!slot->bone->active) return;
slotAttachment = slot->attachment;
if (slotAttachment != self->attachment) {
switch (slot->attachment->type) {
case SP_ATTACHMENT_BOUNDING_BOX:
case SP_ATTACHMENT_CLIPPING:
case SP_ATTACHMENT_MESH:
case SP_ATTACHMENT_PATH: {
spVertexAttachment *vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment);
if (vertexAttachment->timelineAttachment != self->attachment) return;
break;
}
default:
return;
}
}
frames = self->super.frames->items;
if (time < frames[0]) { /* Time is before first frame. */
if (blend == SP_MIX_BLEND_SETUP || blend == SP_MIX_BLEND_FIRST) slot->sequenceIndex = -1;
return;
}
i = search2(self->super.frames, time, SEQUENCE_ENTRIES);
before = frames[i];
modeAndIndex = (int) frames[i + MODE];
delay = frames[i + DELAY];
if (self->attachment->type == SP_ATTACHMENT_REGION) sequence = ((spRegionAttachment *) self->attachment)->sequence;
if (self->attachment->type == SP_ATTACHMENT_MESH) sequence = ((spMeshAttachment *) self->attachment)->sequence;
index = modeAndIndex >> 4;
count = sequence->regions->size;
mode = modeAndIndex & 0xf;
if (mode != SP_SEQUENCE_MODE_HOLD) {
index += (int) (((time - before) / delay + 0.00001));
switch (mode) {
case SP_SEQUENCE_MODE_ONCE:
index = MIN(count - 1, index);
break;
case SP_SEQUENCE_MODE_LOOP:
index %= count;
break;
case SP_SEQUENCE_MODE_PINGPONG: {
int n = (count << 1) - 2;
index %= n;
if (index >= count) index = n - index;
break;
}
case SP_SEQUENCE_MODE_ONCEREVERSE:
index = MAX(count - 1 - index, 0);
break;
case SP_SEQUENCE_MODE_LOOPREVERSE:
index = count - 1 - (index % count);
break;
case SP_SEQUENCE_MODE_PINGPONGREVERSE: {
int n = (count << 1) - 2;
index = (index + count - 1) % n;
if (index >= count) index = n - index;
}
}
}
slot->sequenceIndex = index;
UNUSED(lastTime);
UNUSED(firedEvents);
UNUSED(eventsCount);
UNUSED(alpha);
UNUSED(direction);
}
void _spSequenceTimeline_dispose(spTimeline *timeline) {
spEventTimeline *self = SUB_CAST(spEventTimeline, timeline);
int i;
for (i = 0; i < self->super.frames->size; ++i)
spEvent_dispose(self->events[i]);
FREE(self->events);
}
spSequenceTimeline *spSequenceTimeline_create(int framesCount, int slotIndex, spAttachment *attachment) {
int sequenceId = 0;
spSequenceTimeline *self = NEW(spSequenceTimeline);
spPropertyId ids[1];
if (attachment->type == SP_ATTACHMENT_REGION) sequenceId = ((spRegionAttachment *) attachment)->sequence->id;
if (attachment->type == SP_ATTACHMENT_MESH) sequenceId = ((spMeshAttachment *) attachment)->sequence->id;
ids[0] = (spPropertyId) SP_PROPERTY_SEQUENCE << 32 | ((slotIndex << 16 | sequenceId) & 0xffffffff);
_spTimeline_init(SUPER(self), framesCount, SEQUENCE_ENTRIES, ids, 1, SP_TIMELINE_SEQUENCE, _spSequenceTimeline_dispose,
_spSequenceTimeline_apply, 0);
self->slotIndex = slotIndex;
self->attachment = attachment;
return self;
}
void spSequenceTimeline_setFrame(spSequenceTimeline *self, int frame, float time, int mode, int index, float delay) {
float *frames = self->super.frames->items;
frame *= SEQUENCE_ENTRIES;
frames[frame] = time;
frames[frame + MODE] = mode | (index << 4);
frames[frame + DELAY] = delay;
}
/**/
/** Fires events for frames > lastTime and <= time. */
void _spEventTimeline_apply(spTimeline *timeline, spSkeleton *skeleton, float lastTime, float time, spEvent **firedEvents,
int *eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {

View File

@ -205,6 +205,10 @@ void spDebug_printTimeline(spTimeline *timeline) {
_spDebug_printTimelineBase(&t->super);
break;
}
case SP_TIMELINE_SEQUENCE: {
spSequenceTimeline *t = (spSequenceTimeline *) timeline;
_spDebug_printTimelineBase(&t->super);
}
}
}

View File

@ -33,6 +33,7 @@
void _spMeshAttachment_dispose(spAttachment *attachment) {
spMeshAttachment *self = SUB_CAST(spMeshAttachment, attachment);
if (self->sequence) spSequence_dispose(self->sequence);
FREE(self->path);
FREE(self->uvs);
if (!self->parentMesh) {

View File

@ -43,6 +43,7 @@ typedef enum {
void _spRegionAttachment_dispose(spAttachment *attachment) {
spRegionAttachment *self = SUB_CAST(spRegionAttachment, attachment);
if (self->sequence) spSequence_dispose(self->sequence);
_spAttachment_deinit(attachment);
FREE(self->path);
FREE(self);

View File

@ -50,9 +50,6 @@ void spSequence_dispose(spSequence *self) {
spSequence *spSequence_copy(spSequence *self) {
int i = 0;
spSequence *copy = spSequence_create(self->regions->size);
copy->start = self->start;
copy->digits = self->digits;
copy->setupIndex = self->setupIndex;
for (; i < self->regions->size; i++)
copy->regions->items[i] = self->regions->items[i];
copy->start = self->start;

View File

@ -192,8 +192,8 @@ static void readColor(_dataInput *input, float *r, float *g, float *b, float *a)
#define SLOT_RGB2 4
#define SLOT_ALPHA 5
#define ATTACHMENT_DEFORM = 0
#define ATTACHMENT_SEQUENCE = 1
#define ATTACHMENT_DEFORM 0
#define ATTACHMENT_SEQUENCE 1
#define PATH_POSITION 0
#define PATH_SPACING 1
@ -705,8 +705,7 @@ static spAnimation *_spSkeletonBinary_readAnimation(spSkeletonBinary *self, cons
int bezierCount = readVarint(input, 1);
switch (type) {
case PATH_POSITION: {
spTimelineArray_add(timelines, readTimeline(input, SUPER(spPathConstraintPositionTimeline_create(
frameCount, bezierCount, index)),
spTimelineArray_add(timelines, readTimeline(input, SUPER(spPathConstraintPositionTimeline_create(frameCount, bezierCount, index)),
data->positionMode == SP_POSITION_MODE_FIXED ? scale
: 1));
break;
@ -717,9 +716,9 @@ static spAnimation *_spSkeletonBinary_readAnimation(spSkeletonBinary *self, cons
bezierCount,
index)),
data->spacingMode == SP_SPACING_MODE_LENGTH ||
data->spacingMode == SP_SPACING_MODE_FIXED
? scale
: 1));
data->spacingMode == SP_SPACING_MODE_FIXED
? scale
: 1));
break;
}
case PATH_MIX: {
@ -762,19 +761,17 @@ static spAnimation *_spSkeletonBinary_readAnimation(spSkeletonBinary *self, cons
}
}
/* Deform timelines. */
/* Attachment timelines. */
for (i = 0, n = readVarint(input, 1); i < n; ++i) {
spSkin *skin = skeletonData->skins[readVarint(input, 1)];
for (ii = 0, nn = readVarint(input, 1); ii < nn; ++ii) {
int slotIndex = readVarint(input, 1);
for (iii = 0, nnn = readVarint(input, 1); iii < nnn; ++iii) {
float *tempDeform;
spDeformTimeline *timeline;
int weighted, deformLength;
const char *attachmentName = readStringRef(input, skeletonData);
int frameCount, frameLast, bezierCount;
float time, time2;
unsigned int timelineType;
const char *attachmentName = readStringRef(input, skeletonData);
spVertexAttachment *attachment = SUB_CAST(spVertexAttachment,
spSkin_getAttachment(skin, slotIndex, attachmentName));
if (!attachment) {
@ -785,59 +782,83 @@ static spAnimation *_spSkeletonBinary_readAnimation(spSkeletonBinary *self, cons
return NULL;
}
weighted = attachment->bones != 0;
deformLength = weighted ? attachment->verticesCount / 3 * 2 : attachment->verticesCount;
tempDeform = MALLOC(float, deformLength);
timelineType = readByte(input);
frameCount = readVarint(input, 1);
frameLast = frameCount - 1;
bezierCount = readVarint(input, 1);
timeline = spDeformTimeline_create(frameCount, deformLength, bezierCount, slotIndex, attachment);
time = readFloat(input);
for (frame = 0, bezier = 0;; ++frame) {
float *deform;
int end = readVarint(input, 1);
if (!end) {
if (weighted) {
deform = tempDeform;
memset(deform, 0, sizeof(float) * deformLength);
} else
deform = attachment->vertices;
} else {
int v, start = readVarint(input, 1);
deform = tempDeform;
memset(deform, 0, sizeof(float) * start);
end += start;
if (self->scale == 1) {
for (v = start; v < end; ++v)
deform[v] = readFloat(input);
} else {
for (v = start; v < end; ++v)
deform[v] = readFloat(input) * self->scale;
switch (timelineType) {
case ATTACHMENT_DEFORM: {
float *tempDeform;
int weighted, deformLength;
spDeformTimeline *timeline;
weighted = attachment->bones != 0;
deformLength = weighted ? attachment->verticesCount / 3 * 2 : attachment->verticesCount;
tempDeform = MALLOC(float, deformLength);
bezierCount = readVarint(input, 1);
timeline = spDeformTimeline_create(frameCount, deformLength, bezierCount, slotIndex,
attachment);
time = readFloat(input);
for (frame = 0, bezier = 0;; ++frame) {
float *deform;
int end = readVarint(input, 1);
if (!end) {
if (weighted) {
deform = tempDeform;
memset(deform, 0, sizeof(float) * deformLength);
} else
deform = attachment->vertices;
} else {
int v, start = readVarint(input, 1);
deform = tempDeform;
memset(deform, 0, sizeof(float) * start);
end += start;
if (self->scale == 1) {
for (v = start; v < end; ++v)
deform[v] = readFloat(input);
} else {
for (v = start; v < end; ++v)
deform[v] = readFloat(input) * self->scale;
}
memset(deform + v, 0, sizeof(float) * (deformLength - v));
if (!weighted) {
float *vertices = attachment->vertices;
for (v = 0; v < deformLength; ++v)
deform[v] += vertices[v];
}
}
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;
}
memset(deform + v, 0, sizeof(float) * (deformLength - v));
if (!weighted) {
float *vertices = attachment->vertices;
for (v = 0; v < deformLength; ++v)
deform[v] += vertices[v];
FREE(tempDeform);
spTimelineArray_add(timelines, (spTimeline *) timeline);
break;
}
case ATTACHMENT_SEQUENCE: {
int modeAndIndex;
float delay;
spSequenceTimeline *timeline = spSequenceTimeline_create(frameCount, slotIndex, (spAttachment *) attachment);
for (frame = 0; frame < frameCount; frame++) {
time = readFloat(input);
modeAndIndex = readInt(input);
delay = readFloat(input);
spSequenceTimeline_setFrame(timeline, frame, time, modeAndIndex & 0xf, modeAndIndex >> 4, delay);
}
spTimelineArray_add(timelines, (spTimeline *) timeline);
break;
}
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);
}
}
}
@ -1484,8 +1505,7 @@ spSkeletonData *spSkeletonBinary_readSkeletonData(spSkeletonBinary *self, const
/* Linked meshes. */
for (i = 0; i < internal->linkedMeshCount; ++i) {
_spLinkedMesh *linkedMesh = internal->linkedMeshes + i;
spSkin *skin = !linkedMesh->skin ? skeletonData->defaultSkin : spSkeletonData_findSkin(skeletonData,
linkedMesh->skin);
spSkin *skin = !linkedMesh->skin ? skeletonData->defaultSkin : spSkeletonData_findSkin(skeletonData, linkedMesh->skin);
spAttachment *parent;
if (!skin) {
FREE(input);

View File

@ -188,6 +188,16 @@ readTimeline2(Json *keyMap, spCurveTimeline2 *timeline, const char *name1, const
return SUPER(timeline);
}
static spSequence *readSequence(Json *item) {
spSequence *sequence;
if (item == NULL) return NULL;
sequence = spSequence_create(Json_getInt(item, "count", 0));
sequence->start = Json_getInt(item, "start", 1);
sequence->digits = Json_getInt(item, "digits", 0);
sequence->setupIndex = Json_getInt(item, "setupIndex", 0);
return sequence;
}
static void _spSkeletonJson_addLinkedMesh(spSkeletonJson *self, spMeshAttachment *mesh, const char *skin, int slotIndex,
const char *parent, int inheritDeform) {
_spLinkedMesh *linkedMesh;
@ -268,10 +278,11 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro
Json *ik = Json_getItem(root, "ik");
Json *transform = Json_getItem(root, "transform");
Json *paths = Json_getItem(root, "path");
Json *deformJson = Json_getItem(root, "deform");
Json *attachmentsJson = Json_getItem(root, "attachments");
Json *drawOrderJson = Json_getItem(root, "drawOrder");
Json *events = Json_getItem(root, "events");
Json *boneMap, *slotMap, *constraintMap, *keyMap, *nextMap, *curve, *timelineMap;
Json *boneMap, *slotMap, *keyMap, *nextMap, *curve, *timelineMap;
Json *attachmentsMap, *constraintMap;
int frame, bezier, i, n;
spColor color, color2, newColor, newColor2;
@ -286,7 +297,7 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro
spAttachmentTimeline *timeline = spAttachmentTimeline_create(frames, slotIndex);
for (keyMap = timelineMap->child, frame = 0; keyMap; keyMap = keyMap->next, ++frame) {
spAttachmentTimeline_setFrame(timeline, frame, Json_getFloat(keyMap, "time", 0),
Json_getItem(keyMap, "name")->valueString);
Json_getItem(keyMap, "name") ? Json_getItem(keyMap, "name")->valueString : NULL);
}
spTimelineArray_add(timelines, SUPER(timeline));
@ -691,82 +702,113 @@ static spAnimation *_spSkeletonJson_readAnimation(spSkeletonJson *self, Json *ro
}
}
/* Deform timelines. */
for (constraintMap = deformJson ? deformJson->child : 0; constraintMap; constraintMap = constraintMap->next) {
spSkin *skin = spSkeletonData_findSkin(skeletonData, constraintMap->name);
for (slotMap = constraintMap->child; slotMap; slotMap = slotMap->next) {
/* Attachment timelines. */
for (attachmentsMap = attachmentsJson ? attachmentsJson->child : 0; attachmentsMap; attachmentsMap = attachmentsMap->next) {
spSkin *skin = spSkeletonData_findSkin(skeletonData, attachmentsMap->name);
for (slotMap = attachmentsMap->child; slotMap; slotMap = slotMap->next) {
Json *attachmentMap;
int slotIndex = findSlotIndex(self, skeletonData, slotMap->name, timelines);
if (slotIndex == -1) return NULL;
for (timelineMap = slotMap->child; timelineMap; timelineMap = timelineMap->next) {
float *tempDeform;
spVertexAttachment *attachment;
int weighted, deformLength;
spDeformTimeline *timeline;
float time;
keyMap = timelineMap->child;
if (keyMap == NULL) continue;
attachment = SUB_CAST(spVertexAttachment, spSkin_getAttachment(skin, slotIndex, timelineMap->name));
if (!attachment) {
for (attachmentMap = slotMap->child; attachmentMap; attachmentMap = attachmentMap->next) {
spAttachment *baseAttachment = spSkin_getAttachment(skin, slotIndex, attachmentMap->name);
if (!baseAttachment) {
cleanUpTimelines(timelines);
_spSkeletonJson_setError(self, 0, "Attachment not found: ", timelineMap->name);
_spSkeletonJson_setError(self, 0, "Attachment not found: ", attachmentMap->name);
return NULL;
}
weighted = attachment->bones != 0;
deformLength = weighted ? attachment->verticesCount / 3 * 2 : attachment->verticesCount;
tempDeform = MALLOC(float, deformLength);
timeline = spDeformTimeline_create(timelineMap->size, deformLength, timelineMap->size, slotIndex,
attachment);
time = Json_getFloat(keyMap, "time", 0);
for (frame = 0, bezier = 0;; ++frame) {
Json *vertices = Json_getItem(keyMap, "vertices");
float *deform;
float time2;
for (timelineMap = attachmentMap->child; timelineMap; timelineMap = timelineMap->next) {
int frames;
const char *timelineName;
keyMap = timelineMap->child;
if (keyMap == NULL) continue;
frames = timelineMap->size;
timelineName = timelineMap->name;
if (!strcmp("deform", timelineName)) {
float *tempDeform;
spVertexAttachment *vertexAttachment;
int weighted, deformLength;
spDeformTimeline *timeline;
float time;
if (!vertices) {
if (weighted) {
deform = tempDeform;
memset(deform, 0, sizeof(float) * deformLength);
} else
deform = attachment->vertices;
} else {
int v, start = Json_getInt(keyMap, "offset", 0);
Json *vertex;
deform = tempDeform;
memset(deform, 0, sizeof(float) * start);
if (self->scale == 1) {
for (vertex = vertices->child, v = start; vertex; vertex = vertex->next, ++v)
deform[v] = vertex->valueFloat;
} else {
for (vertex = vertices->child, v = start; vertex; vertex = vertex->next, ++v)
deform[v] = vertex->valueFloat * self->scale;
vertexAttachment = SUB_CAST(spVertexAttachment, baseAttachment);
weighted = vertexAttachment->bones != 0;
deformLength = weighted ? vertexAttachment->verticesCount / 3 * 2 : vertexAttachment->verticesCount;
tempDeform = MALLOC(float, deformLength);
timeline = spDeformTimeline_create(timelineMap->size, deformLength, timelineMap->size,
slotIndex,
vertexAttachment);
time = Json_getFloat(keyMap, "time", 0);
for (frame = 0, bezier = 0;; ++frame) {
Json *vertices = Json_getItem(keyMap, "vertices");
float *deform;
float time2;
if (!vertices) {
if (weighted) {
deform = tempDeform;
memset(deform, 0, sizeof(float) * deformLength);
} else
deform = vertexAttachment->vertices;
} else {
int v, start = Json_getInt(keyMap, "offset", 0);
Json *vertex;
deform = tempDeform;
memset(deform, 0, sizeof(float) * start);
if (self->scale == 1) {
for (vertex = vertices->child, v = start; vertex; vertex = vertex->next, ++v)
deform[v] = vertex->valueFloat;
} else {
for (vertex = vertices->child, v = start; vertex; vertex = vertex->next, ++v)
deform[v] = vertex->valueFloat * self->scale;
}
memset(deform + v, 0, sizeof(float) * (deformLength - v));
if (!weighted) {
float *verticesValues = vertexAttachment->vertices;
for (v = 0; v < deformLength; ++v)
deform[v] += verticesValues[v];
}
}
spDeformTimeline_setFrame(timeline, frame, time, deform);
nextMap = keyMap->next;
if (!nextMap) {
/* timeline.shrink(); // BOZO */
break;
}
time2 = Json_getFloat(nextMap, "time", 0);
curve = Json_getItem(keyMap, "curve");
if (curve) {
bezier = readCurve(curve, SUPER(timeline), bezier, frame, 0, time, time2, 0, 1, 1);
}
time = time2;
keyMap = nextMap;
}
memset(deform + v, 0, sizeof(float) * (deformLength - v));
if (!weighted) {
float *verticesValues = attachment->vertices;
for (v = 0; v < deformLength; ++v)
deform[v] += verticesValues[v];
FREE(tempDeform);
spTimelineArray_add(timelines, SUPER(SUPER(timeline)));
} else if (!strcmp(timelineName, "sequence")) {
spSequenceTimeline *timeline = spSequenceTimeline_create(frames, slotIndex, baseAttachment);
float lastDelay = 0;
for (frame = 0; keyMap != NULL; keyMap = keyMap->next, frame++) {
float delay = Json_getFloat(keyMap, "delay", lastDelay);
float time = Json_getFloat(keyMap, "time", 0);
const char *modeString = Json_getString(keyMap, "mode", "hold");
int index = Json_getInt(keyMap, "index", 0);
int mode = SP_SEQUENCE_MODE_HOLD;
if (!strcmp(modeString, "once")) mode = SP_SEQUENCE_MODE_ONCE;
if (!strcmp(modeString, "loop")) mode = SP_SEQUENCE_MODE_LOOP;
if (!strcmp(modeString, "pingpong")) mode = SP_SEQUENCE_MODE_PINGPONG;
if (!strcmp(modeString, "onceReverse")) mode = SP_SEQUENCE_MODE_ONCEREVERSE;
if (!strcmp(modeString, "loopReverse")) mode = SP_SEQUENCE_MODE_LOOPREVERSE;
if (!strcmp(modeString, "pingpongReverse")) mode = SP_SEQUENCE_MODE_PINGPONGREVERSE;
spSequenceTimeline_setFrame(timeline, frame, time, mode, index, delay);
}
spTimelineArray_add(timelines, SUPER(timeline));
}
spDeformTimeline_setFrame(timeline, frame, time, deform);
nextMap = keyMap->next;
if (!nextMap) {
/* timeline.shrink(); // BOZO */
break;
}
time2 = Json_getFloat(nextMap, "time", 0);
curve = Json_getItem(keyMap, "curve");
if (curve) {
bezier = readCurve(curve, SUPER(timeline), bezier, frame, 0, time, time2, 0, 1, 1);
}
time = time2;
keyMap = nextMap;
}
FREE(tempDeform);
spTimelineArray_add(timelines, SUPER(SUPER(timeline)));
}
}
}
@ -1297,6 +1339,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
const char *path = Json_getString(attachmentMap, "path", attachmentName);
const char *color;
Json *entry;
spSequence *sequence;
const char *typeString = Json_getString(attachmentMap, "type", "region");
spAttachmentType type;
@ -1319,8 +1362,9 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
return NULL;
}
sequence = readSequence(attachmentMap);
attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, attachmentName,
path);
path, sequence);
if (!attachment) {
if (self->attachmentLoader->error1) {
spSkeletonData_dispose(skeletonData);
@ -1342,6 +1386,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
region->rotation = Json_getFloat(attachmentMap, "rotation", 0);
region->width = Json_getFloat(attachmentMap, "width", 32) * self->scale;
region->height = Json_getFloat(attachmentMap, "height", 32) * self->scale;
region->sequence = sequence;
color = Json_getString(attachmentMap, "color", 0);
if (color) {
@ -1352,7 +1397,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
toColor(color, 3));
}
spRegionAttachment_updateRegion(region);
if (region->region != NULL) spRegionAttachment_updateRegion(region);
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
break;
@ -1374,6 +1419,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
mesh->width = Json_getFloat(attachmentMap, "width", 32) * self->scale;
mesh->height = Json_getFloat(attachmentMap, "height", 32) * self->scale;
mesh->sequence = sequence;
entry = Json_getItem(attachmentMap, "parent");
if (!entry) {
@ -1392,7 +1438,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
_readVertices(self, attachmentMap, SUPER(mesh), verticesLength);
spMeshAttachment_updateRegion(mesh);
if (mesh->region != NULL) spMeshAttachment_updateRegion(mesh);
mesh->hullLength = Json_getInt(attachmentMap, "hull", 0);
@ -1406,10 +1452,10 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
} else {
int inheritDeform = Json_getInt(attachmentMap, "deform", 1);
int inheritTimelines = Json_getInt(attachmentMap, "timelines", 1);
_spSkeletonJson_addLinkedMesh(self, SUB_CAST(spMeshAttachment, attachment),
Json_getString(attachmentMap, "skin", 0), slot->index,
entry->valueString, inheritDeform);
entry->valueString, inheritTimelines);
}
break;
}
@ -1517,7 +1563,7 @@ spSkeletonData *spSkeletonJson_readSkeletonData(spSkeletonJson *self, const char
linkedMesh->mesh->super.timelineAttachment = linkedMesh->inheritTimeline ? parent
: SUPER(SUPER(linkedMesh->mesh));
spMeshAttachment_setParentMesh(linkedMesh->mesh, SUB_CAST(spMeshAttachment, parent));
spMeshAttachment_updateRegion(linkedMesh->mesh);
if (linkedMesh->mesh->region != NULL) spMeshAttachment_updateRegion(linkedMesh->mesh);
spAttachmentLoader_configureAttachment(self->attachmentLoader, SUPER(SUPER(linkedMesh->mesh)));
}

View File

@ -513,7 +513,6 @@ void test(spSkeletonData *skeletonData, spAtlas *atlas) {
float d = 3;
for (int i = 0; i < 1; i++) {
spSkeleton_update(skeleton, d);
spAnimationState_update(animState, d);
spAnimationState_apply(animState, skeleton);
spSkeleton_updateWorldTransform(skeleton);

View File

@ -151,7 +151,6 @@ namespace spine {
}
void SkeletonDrawable::update(float deltaTime) {
spSkeleton_update(skeleton, deltaTime);
spAnimationState_update(state, deltaTime * timeScale);
spAnimationState_apply(state, skeleton);
spSkeleton_updateWorldTransform(skeleton);
@ -197,7 +196,7 @@ namespace spine {
continue;
}
spRegionAttachment_computeWorldVertices(regionAttachment, slot->bone, vertices, 0, 2);
spRegionAttachment_computeWorldVertices(regionAttachment, slot, vertices, 0, 2);
verticesCount = 4;
uvs = regionAttachment->uvs;
indices = quadIndices;