[c] Ported AniamtionState and Animation changes. See #1303.

This commit is contained in:
badlogic 2019-03-25 14:55:34 +01:00
parent f0e9164648
commit 4785ad656d
5 changed files with 85 additions and 52 deletions

View File

@ -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;

View File

@ -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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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) {

View File

@ -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;
}