mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-12 10:08:44 +08:00
[c] Sequence support in SkeletonBinary and SkeletonJson.
This commit is contained in:
parent
3289550eb0
commit
9319029763
@ -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;
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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)));
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user