mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 14:24:53 +08:00
[c] Ported AniamtionState and Animation changes. See #1303.
This commit is contained in:
parent
f0e9164648
commit
4785ad656d
@ -47,9 +47,9 @@ typedef struct spSlot {
|
||||
spColor* darkColor;
|
||||
spAttachment* const attachment;
|
||||
|
||||
int attachmentVerticesCapacity;
|
||||
int attachmentVerticesCount;
|
||||
float* attachmentVertices;
|
||||
int deformCapacity;
|
||||
int deformCount;
|
||||
float* deform;
|
||||
|
||||
#ifdef __cplusplus
|
||||
spSlot() :
|
||||
@ -58,9 +58,9 @@ typedef struct spSlot {
|
||||
color(),
|
||||
darkColor(0),
|
||||
attachment(0),
|
||||
attachmentVerticesCapacity(0),
|
||||
attachmentVerticesCount(0),
|
||||
attachmentVertices(0) {
|
||||
deformCapacity(0),
|
||||
deformCount(0),
|
||||
deform(0) {
|
||||
}
|
||||
#endif
|
||||
} spSlot;
|
||||
|
||||
@ -890,7 +890,7 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
|
||||
float* frames;
|
||||
int framesCount;
|
||||
const float** frameVertices;
|
||||
float* vertices;
|
||||
float* deformArray;
|
||||
spDeformTimeline* self = (spDeformTimeline*)timeline;
|
||||
|
||||
spSlot *slot = skeleton->slots[self->slotIndex];
|
||||
@ -911,39 +911,39 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
|
||||
frames = self->frames;
|
||||
framesCount = self->framesCount;
|
||||
vertexCount = self->frameVerticesCount;
|
||||
if (slot->attachmentVerticesCount < vertexCount) {
|
||||
if (slot->attachmentVerticesCapacity < vertexCount) {
|
||||
FREE(slot->attachmentVertices);
|
||||
slot->attachmentVertices = MALLOC(float, vertexCount);
|
||||
slot->attachmentVerticesCapacity = vertexCount;
|
||||
if (slot->deformCount < vertexCount) {
|
||||
if (slot->deformCapacity < vertexCount) {
|
||||
FREE(slot->deform);
|
||||
slot->deform = MALLOC(float, vertexCount);
|
||||
slot->deformCapacity = vertexCount;
|
||||
}
|
||||
}
|
||||
if (slot->attachmentVerticesCount == 0) blend = SP_MIX_BLEND_SETUP;
|
||||
if (slot->deformCount == 0) blend = SP_MIX_BLEND_SETUP;
|
||||
|
||||
frameVertices = self->frameVertices;
|
||||
vertices = slot->attachmentVertices;
|
||||
deformArray = slot->deform;
|
||||
|
||||
if (time < frames[0]) { /* Time is before first frame. */
|
||||
spVertexAttachment* vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment);
|
||||
switch (blend) {
|
||||
case SP_MIX_BLEND_SETUP:
|
||||
slot->attachmentVerticesCount = 0;
|
||||
slot->deformCount = 0;
|
||||
return;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
if (alpha == 1) {
|
||||
slot->attachmentVerticesCount = 0;
|
||||
slot->deformCount = 0;
|
||||
return;
|
||||
}
|
||||
slot->attachmentVerticesCount = vertexCount;
|
||||
slot->deformCount = vertexCount;
|
||||
if (!vertexAttachment->bones) {
|
||||
float* setupVertices = vertexAttachment->vertices;
|
||||
for (i = 0; i < vertexCount; i++) {
|
||||
vertices[i] += (setupVertices[i] - vertices[i]) * alpha;
|
||||
deformArray[i] += (setupVertices[i] - deformArray[i]) * alpha;
|
||||
}
|
||||
} else {
|
||||
alpha = 1 - alpha;
|
||||
for (i = 0; i < vertexCount; i++) {
|
||||
vertices[i] *= alpha;
|
||||
deformArray[i] *= alpha;
|
||||
}
|
||||
}
|
||||
case SP_MIX_BLEND_REPLACE:
|
||||
@ -953,7 +953,7 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
|
||||
return;
|
||||
}
|
||||
|
||||
slot->attachmentVerticesCount = vertexCount;
|
||||
slot->deformCount = vertexCount;
|
||||
if (time >= frames[framesCount - 1]) { /* Time is after last frame. */
|
||||
const float* lastVertices = self->frameVertices[framesCount - 1];
|
||||
if (alpha == 1) {
|
||||
@ -963,16 +963,16 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
|
||||
/* Unweighted vertex positions, with alpha. */
|
||||
float* setupVertices = vertexAttachment->vertices;
|
||||
for (i = 0; i < vertexCount; i++) {
|
||||
vertices[i] += lastVertices[i] - setupVertices[i];
|
||||
deformArray[i] += lastVertices[i] - setupVertices[i];
|
||||
}
|
||||
} else {
|
||||
/* Weighted deform offsets, with alpha. */
|
||||
for (i = 0; i < vertexCount; i++)
|
||||
vertices[i] += lastVertices[i];
|
||||
deformArray[i] += lastVertices[i];
|
||||
}
|
||||
} else {
|
||||
/* Vertex positions or deform offsets, no alpha. */
|
||||
memcpy(vertices, lastVertices, vertexCount * sizeof(float));
|
||||
memcpy(deformArray, lastVertices, vertexCount * sizeof(float));
|
||||
}
|
||||
} else {
|
||||
spVertexAttachment* vertexAttachment;
|
||||
@ -984,30 +984,30 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
|
||||
float* setupVertices = vertexAttachment->vertices;
|
||||
for (i = 0; i < vertexCount; i++) {
|
||||
float setup = setupVertices[i];
|
||||
vertices[i] = setup + (lastVertices[i] - setup) * alpha;
|
||||
deformArray[i] = setup + (lastVertices[i] - setup) * alpha;
|
||||
}
|
||||
} else {
|
||||
/* Weighted deform offsets, with alpha. */
|
||||
for (i = 0; i < vertexCount; i++)
|
||||
vertices[i] = lastVertices[i] * alpha;
|
||||
deformArray[i] = lastVertices[i] * alpha;
|
||||
}
|
||||
break;
|
||||
case SP_MIX_BLEND_FIRST:
|
||||
case SP_MIX_BLEND_REPLACE:
|
||||
/* Vertex positions or deform offsets, with alpha. */
|
||||
for (i = 0; i < vertexCount; i++)
|
||||
vertices[i] += (lastVertices[i] - vertices[i]) * alpha;
|
||||
deformArray[i] += (lastVertices[i] - deformArray[i]) * alpha;
|
||||
case SP_MIX_BLEND_ADD:
|
||||
vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment);
|
||||
if (!vertexAttachment->bones) {
|
||||
/* Unweighted vertex positions, with alpha. */
|
||||
float* setupVertices = vertexAttachment->vertices;
|
||||
for (i = 0; i < vertexCount; i++) {
|
||||
vertices[i] += (lastVertices[i] - setupVertices[i]) * alpha;
|
||||
deformArray[i] += (lastVertices[i] - setupVertices[i]) * alpha;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < vertexCount; i++)
|
||||
vertices[i] += lastVertices[i] * alpha;
|
||||
deformArray[i] += lastVertices[i] * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1028,18 +1028,18 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
|
||||
float* setupVertices = vertexAttachment->vertices;
|
||||
for (i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
vertices[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i];
|
||||
deformArray[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i];
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
vertices[i] += prev + (nextVertices[i] - prev) * percent;
|
||||
deformArray[i] += prev + (nextVertices[i] - prev) * percent;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
vertices[i] = prev + (nextVertices[i] - prev) * percent;
|
||||
deformArray[i] = prev + (nextVertices[i] - prev) * percent;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -1051,12 +1051,12 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
|
||||
float *setupVertices = vertexAttachment->vertices;
|
||||
for (i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i], setup = setupVertices[i];
|
||||
vertices[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha;
|
||||
deformArray[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
vertices[i] = (prev + (nextVertices[i] - prev) * percent) * alpha;
|
||||
deformArray[i] = (prev + (nextVertices[i] - prev) * percent) * alpha;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1064,7 +1064,7 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
|
||||
case SP_MIX_BLEND_REPLACE:
|
||||
for (i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
vertices[i] += (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha;
|
||||
deformArray[i] += (prev + (nextVertices[i] - prev) * percent - deformArray[i]) * alpha;
|
||||
}
|
||||
break;
|
||||
case SP_MIX_BLEND_ADD:
|
||||
@ -1073,12 +1073,12 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
|
||||
float *setupVertices = vertexAttachment->vertices;
|
||||
for (i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
vertices[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha;
|
||||
deformArray[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < vertexCount; i++) {
|
||||
float prev = prevVertices[i];
|
||||
vertices[i] += (prev + (nextVertices[i] - prev) * percent) * alpha;
|
||||
deformArray[i] += (prev + (nextVertices[i] - prev) * percent) * alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
#define FIRST 1
|
||||
#define HOLD 2
|
||||
#define HOLD_MIX 3
|
||||
#define NOT_LAST 4
|
||||
|
||||
_SP_ARRAY_IMPLEMENT_TYPE(spTrackEntryArray, spTrackEntry*)
|
||||
|
||||
@ -62,7 +63,8 @@ float* _spAnimationState_resizeTimelinesRotation(spTrackEntry* entry, int newSiz
|
||||
int* _spAnimationState_resizeTimelinesFirst(spTrackEntry* entry, int newSize);
|
||||
void _spAnimationState_ensureCapacityPropertyIDs(spAnimationState* self, int capacity);
|
||||
int _spAnimationState_addPropertyID(spAnimationState* self, int id);
|
||||
void _spTrackEntry_setTimelineData(spTrackEntry* self, spAnimationState* state);
|
||||
void _spTrackEntry_computeHold(spTrackEntry* self, spAnimationState* state);
|
||||
void _spTrackEntry_computeNotLast(spTrackEntry* self, spAnimationState* state);
|
||||
|
||||
|
||||
_spEventQueue* _spEventQueue_create (_spAnimationState* state) {
|
||||
@ -389,7 +391,7 @@ int spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) {
|
||||
|
||||
for (ii = 0; ii < timelineCount; ii++) {
|
||||
timeline = timelines[ii];
|
||||
timelineBlend = timelineMode->items[ii] == SUBSEQUENT ? blend : SP_MIX_BLEND_SETUP;
|
||||
timelineBlend = (timelineMode->items[ii] & (NOT_LAST - 1)) == SUBSEQUENT ? blend : SP_MIX_BLEND_SETUP;
|
||||
if (timeline->type == SP_TIMELINE_ROTATE)
|
||||
_spAnimationState_applyRotateTimeline(self, timeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame);
|
||||
else
|
||||
@ -465,7 +467,7 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* t
|
||||
spMixDirection direction = SP_MIX_DIRECTION_OUT;
|
||||
spTimeline *timeline = timelines[i];
|
||||
|
||||
switch (timelineMode->items[i]) {
|
||||
switch (timelineMode->items[i] & (NOT_LAST - 1)) {
|
||||
case SUBSEQUENT:
|
||||
if (!attachments && timeline->type == SP_TIMELINE_ATTACHMENT) continue;
|
||||
if (!drawOrder && timeline->type == SP_TIMELINE_DRAWORDER) continue;
|
||||
@ -493,7 +495,7 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* t
|
||||
else {
|
||||
if (timelineBlend == SP_MIX_BLEND_SETUP) {
|
||||
if (timeline->type == SP_TIMELINE_ATTACHMENT) {
|
||||
if (attachments) direction = SP_MIX_DIRECTION_IN;
|
||||
if (attachments || (timelineMode->items[i] & NOT_LAST) == NOT_LAST) direction = SP_MIX_DIRECTION_IN;
|
||||
} else if (timeline->type == SP_TIMELINE_DRAWORDER) {
|
||||
if (drawOrder) direction = SP_MIX_DIRECTION_IN;
|
||||
}
|
||||
@ -866,10 +868,20 @@ void _spAnimationState_animationsChanged (spAnimationState* self) {
|
||||
while (entry->mixingFrom != 0)
|
||||
entry = entry->mixingFrom;
|
||||
do {
|
||||
if (entry->mixingTo == 0 || entry->mixBlend != SP_MIX_BLEND_ADD) _spTrackEntry_setTimelineData(entry, self);
|
||||
if (entry->mixingTo == 0 || entry->mixBlend != SP_MIX_BLEND_ADD) _spTrackEntry_computeHold(entry, self);
|
||||
entry = entry->mixingTo;
|
||||
} while (entry != 0);
|
||||
}
|
||||
|
||||
internal->propertyIDsCount = 0;
|
||||
i = self->tracksCount - 1;
|
||||
for (; i >= 0; i--) {
|
||||
entry = self->tracks[i];
|
||||
while (entry != 0) {
|
||||
_spTrackEntry_computeNotLast(entry, self);
|
||||
entry = entry->mixingFrom;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float* _spAnimationState_resizeTimelinesRotation(spTrackEntry* entry, int newSize) {
|
||||
@ -934,7 +946,7 @@ int /*boolean*/ _spTrackEntry_hasTimeline(spTrackEntry* self, int id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void _spTrackEntry_setTimelineData(spTrackEntry* entry, spAnimationState* state) {
|
||||
void _spTrackEntry_computeHold(spTrackEntry* entry, spAnimationState* state) {
|
||||
spTrackEntry* to;
|
||||
spTimeline** timelines;
|
||||
int timelinesCount;
|
||||
@ -962,12 +974,14 @@ void _spTrackEntry_setTimelineData(spTrackEntry* entry, spAnimationState* state)
|
||||
i = 0;
|
||||
continue_outer:
|
||||
for (; i < timelinesCount; i++) {
|
||||
int id = spTimeline_getPropertyId(timelines[i]);
|
||||
spTimeline* timeline = timelines[i];
|
||||
int id = spTimeline_getPropertyId(timeline);
|
||||
if (!_spAnimationState_addPropertyID(state, id))
|
||||
timelineMode[i] = SUBSEQUENT;
|
||||
else if (to == 0 || !_spTrackEntry_hasTimeline(to, id))
|
||||
else if (to == 0 || timeline->type == SP_TIMELINE_ATTACHMENT || timeline->type == SP_TIMELINE_DRAWORDER ||
|
||||
timeline->type == SP_TIMELINE_EVENT || !_spTrackEntry_hasTimeline(to, id)) {
|
||||
timelineMode[i] = FIRST;
|
||||
else {
|
||||
} else {
|
||||
for (next = to->mixingTo; next != 0; next = next->mixingTo) {
|
||||
if (_spTrackEntry_hasTimeline(next, id)) continue;
|
||||
if (next->mixDuration > 0) {
|
||||
@ -982,3 +996,22 @@ void _spTrackEntry_setTimelineData(spTrackEntry* entry, spAnimationState* state)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _spTrackEntry_computeNotLast(spTrackEntry* entry, spAnimationState* state) {
|
||||
spTimeline** timelines ;
|
||||
int timelinesCount;
|
||||
int* timelineMode;
|
||||
int i, n;
|
||||
|
||||
timelines = entry->animation->timelines;
|
||||
timelinesCount = entry->animation->timelinesCount;
|
||||
timelineMode = entry->timelineMode->items;
|
||||
|
||||
i = 0;
|
||||
for (; i < timelinesCount; i++) {
|
||||
if (timelines[i]->type == SP_TIMELINE_ATTACHMENT) {
|
||||
spAttachmentTimeline* timeline = SUB_CAST(spAttachmentTimeline, timelines[i]);
|
||||
if (!_spAnimationState_addPropertyID(state, timeline->slotIndex)) timelineMode[i] |= NOT_LAST;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ spSlot* spSlot_create (spSlotData* data, spBone* bone) {
|
||||
}
|
||||
|
||||
void spSlot_dispose (spSlot* self) {
|
||||
FREE(self->attachmentVertices);
|
||||
FREE(self->deform);
|
||||
FREE(self->darkColor);
|
||||
FREE(self);
|
||||
}
|
||||
@ -56,7 +56,7 @@ void spSlot_setAttachment (spSlot* self, spAttachment* attachment) {
|
||||
if (attachment == self->attachment) return;
|
||||
CONST_CAST(spAttachment*, self->attachment) = attachment;
|
||||
SUB_CAST(_spSlot, self)->attachmentTime = self->bone->skeleton->time;
|
||||
self->attachmentVerticesCount = 0;
|
||||
self->deformCount = 0;
|
||||
}
|
||||
|
||||
void spSlot_setAttachmentTime (spSlot* self, float time) {
|
||||
|
||||
@ -47,21 +47,21 @@ void _spVertexAttachment_deinit (spVertexAttachment* attachment) {
|
||||
void spVertexAttachment_computeWorldVertices (spVertexAttachment* self, spSlot* slot, int start, int count, float* worldVertices, int offset, int stride) {
|
||||
spSkeleton* skeleton;
|
||||
int deformLength;
|
||||
float* deform;
|
||||
float* deformArray;
|
||||
float* vertices;
|
||||
int* bones;
|
||||
|
||||
count = offset + (count >> 1) * stride;
|
||||
skeleton = slot->bone->skeleton;
|
||||
deformLength = slot->attachmentVerticesCount;
|
||||
deform = slot->attachmentVertices;
|
||||
deformLength = slot->deformCount;
|
||||
deformArray = slot->deform;
|
||||
vertices = self->vertices;
|
||||
bones = self->bones;
|
||||
if (!bones) {
|
||||
spBone* bone;
|
||||
int v, w;
|
||||
float x, y;
|
||||
if (deformLength > 0) vertices = deform;
|
||||
if (deformLength > 0) vertices = deformArray;
|
||||
bone = slot->bone;
|
||||
x = bone->worldX;
|
||||
y = bone->worldY;
|
||||
@ -102,7 +102,7 @@ void spVertexAttachment_computeWorldVertices (spVertexAttachment* self, spSlot*
|
||||
n += v;
|
||||
for (; v < n; v++, b += 3, f += 2) {
|
||||
spBone* bone = skeletonBones[bones[v]];
|
||||
float vx = vertices[b] + deform[f], vy = vertices[b + 1] + deform[f + 1], weight = vertices[b + 2];
|
||||
float vx = vertices[b] + deformArray[f], vy = vertices[b + 1] + deformArray[f + 1], weight = vertices[b + 2];
|
||||
wx += (vx * bone->a + vy * bone->b + bone->worldX) * weight;
|
||||
wy += (vx * bone->c + vy * bone->d + bone->worldY) * weight;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user