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

This commit is contained in:
badlogic 2019-03-25 15:26:48 +01:00
parent 4785ad656d
commit ae63d28920
7 changed files with 76 additions and 43 deletions

View File

@ -877,6 +877,7 @@ void _spAnimationState_animationsChanged (spAnimationState* self) {
i = self->tracksCount - 1; i = self->tracksCount - 1;
for (; i >= 0; i--) { for (; i >= 0; i--) {
entry = self->tracks[i]; entry = self->tracks[i];
if (!entry) continue;
while (entry != 0) { while (entry != 0) {
_spTrackEntry_computeNotLast(entry, self); _spTrackEntry_computeNotLast(entry, self);
entry = entry->mixingFrom; entry = entry->mixingFrom;

View File

@ -428,22 +428,24 @@ namespace spine {
void queueEvents(TrackEntry* entry, float animationTime); void queueEvents(TrackEntry* entry, float animationTime);
/// Sets the active TrackEntry for a given track number. /// Sets the active TrackEntry for a given track number.
void setCurrent(size_t index, TrackEntry* current, bool interrupt); void setCurrent(size_t index, TrackEntry *current, bool interrupt);
TrackEntry* expandToIndex(size_t index); TrackEntry* expandToIndex(size_t index);
/// Object-pooling version of new TrackEntry. Obtain an unused TrackEntry from the pool and clear/initialize its values. /// Object-pooling version of new TrackEntry. Obtain an unused TrackEntry from the pool and clear/initialize its values.
/// @param last May be NULL. /// @param last May be NULL.
TrackEntry* newTrackEntry(size_t trackIndex, Animation* animation, bool loop, TrackEntry* last); TrackEntry* newTrackEntry(size_t trackIndex, Animation *animation, bool loop, TrackEntry *last);
/// Dispose all track entries queued after the given TrackEntry. /// Dispose all track entries queued after the given TrackEntry.
void disposeNext(TrackEntry* entry); void disposeNext(TrackEntry* entry);
void animationsChanged(); void animationsChanged();
void setTimelineModes(TrackEntry* entry); void computeHold(TrackEntry *entry);
bool hasTimeline(TrackEntry* entry, int inId); void computeNotLast(TrackEntry *entry);
bool hasTimeline(TrackEntry *entry, int inId);
}; };
} }

View File

@ -109,7 +109,7 @@ public:
void setAttachmentTime(float inValue); void setAttachmentTime(float inValue);
Vector<float> &getAttachmentVertices(); Vector<float> &getDeform();
private: private:
SlotData &_data; SlotData &_data;
@ -120,7 +120,7 @@ private:
bool _hasDarkColor; bool _hasDarkColor;
Attachment *_attachment; Attachment *_attachment;
float _attachmentTime; float _attachmentTime;
Vector<float> _attachmentVertices; Vector<float> _deform;
}; };
} }

View File

@ -43,6 +43,7 @@
#include <spine/BoneData.h> #include <spine/BoneData.h>
#include <spine/AttachmentTimeline.h> #include <spine/AttachmentTimeline.h>
#include <spine/DrawOrderTimeline.h> #include <spine/DrawOrderTimeline.h>
#include <spine/EventTimeline.h>
using namespace spine; using namespace spine;
@ -275,6 +276,7 @@ const int Subsequent = 0;
const int First = 1; const int First = 1;
const int Hold = 2; const int Hold = 2;
const int HoldMix = 3; const int HoldMix = 3;
const int NotLast = 4;
AnimationState::AnimationState(AnimationStateData *data) : AnimationState::AnimationState(AnimationStateData *data) :
_data(data), _data(data),
@ -418,7 +420,7 @@ bool AnimationState::apply(Skeleton &skeleton) {
Timeline *timeline = timelines[ii]; Timeline *timeline = timelines[ii];
assert(timeline); assert(timeline);
MixBlend timelineBlend = timelineMode[ii] == Subsequent ? blend : MixBlend_Setup; MixBlend timelineBlend = (timelineMode[ii] & (NotLast - 1)) == Subsequent ? blend : MixBlend_Setup;
RotateTimeline *rotateTimeline = NULL; RotateTimeline *rotateTimeline = NULL;
if (timeline->getRTTI().isExactly(RotateTimeline::rtti)) { if (timeline->getRTTI().isExactly(RotateTimeline::rtti)) {
@ -787,7 +789,7 @@ float AnimationState::applyMixingFrom(TrackEntry *to, Skeleton &skeleton, MixBle
MixDirection direction = MixDirection_Out; MixDirection direction = MixDirection_Out;
MixBlend timelineBlend; MixBlend timelineBlend;
float alpha; float alpha;
switch (timelineMode[i]) { switch (timelineMode[i] & (NotLast - 1)) {
case Subsequent: case Subsequent:
if (!attachments && (timeline->getRTTI().isExactly(AttachmentTimeline::rtti))) continue; if (!attachments && (timeline->getRTTI().isExactly(AttachmentTimeline::rtti))) continue;
if (!drawOrder && (timeline->getRTTI().isExactly(DrawOrderTimeline::rtti))) continue; if (!drawOrder && (timeline->getRTTI().isExactly(DrawOrderTimeline::rtti))) continue;
@ -815,7 +817,7 @@ float AnimationState::applyMixingFrom(TrackEntry *to, Skeleton &skeleton, MixBle
} else { } else {
if (timelineBlend == MixBlend_Setup) { if (timelineBlend == MixBlend_Setup) {
if (timeline->getRTTI().isExactly(AttachmentTimeline::rtti)) { if (timeline->getRTTI().isExactly(AttachmentTimeline::rtti)) {
if (attachments) direction = MixDirection_In; if (attachments || (timelineMode[i] & NotLast) == NotLast) direction = MixDirection_In;
} else if (timeline->getRTTI().isExactly(DrawOrderTimeline::rtti)) { } else if (timeline->getRTTI().isExactly(DrawOrderTimeline::rtti)) {
if (drawOrder) direction = MixDirection_In; if (drawOrder) direction = MixDirection_In;
} }
@ -967,13 +969,22 @@ void AnimationState::animationsChanged() {
entry = entry->_mixingFrom; entry = entry->_mixingFrom;
do { do {
if (entry->_mixingTo == NULL || entry->_mixBlend != MixBlend_Add) setTimelineModes(entry); if (entry->_mixingTo == NULL || entry->_mixBlend != MixBlend_Add) computeHold(entry);
entry = entry->_mixingTo; entry = entry->_mixingTo;
} while (entry != NULL); } while (entry != NULL);
} }
_propertyIDs.clear();
for (int i = (int)_tracks.size() - 1; i >= 0; i--) {
TrackEntry *entry = _tracks[i];
while (entry) {
computeNotLast(entry);
entry = entry->_mixingFrom;
}
}
} }
void AnimationState::setTimelineModes(TrackEntry *entry) { void AnimationState::computeHold(TrackEntry *entry) {
TrackEntry* to = entry->_mixingTo; TrackEntry* to = entry->_mixingTo;
Vector<Timeline *> &timelines = entry->_animation->_timelines; Vector<Timeline *> &timelines = entry->_animation->_timelines;
size_t timelinesCount = timelines.size(); size_t timelinesCount = timelines.size();
@ -995,13 +1006,16 @@ void AnimationState::setTimelineModes(TrackEntry *entry) {
size_t i = 0; size_t i = 0;
continue_outer: continue_outer:
for (; i < timelinesCount; ++i) { for (; i < timelinesCount; ++i) {
int id = timelines[i]->getPropertyId(); Timeline *timeline = timelines[i];
int id = timeline->getPropertyId();
if (_propertyIDs.contains(id)) { if (_propertyIDs.contains(id)) {
timelineMode[i] = Subsequent; timelineMode[i] = Subsequent;
} else { } else {
_propertyIDs.add(id); _propertyIDs.add(id);
if (to == NULL || !hasTimeline(to, id)) { if (to == NULL || timeline->getRTTI().isExactly(AttachmentTimeline::rtti) ||
timeline->getRTTI().isExactly(DrawOrderTimeline::rtti) ||
timeline->getRTTI().isExactly(EventTimeline::rtti) || !hasTimeline(to, id)) {
timelineMode[i] = First; timelineMode[i] = First;
} else { } else {
for (TrackEntry *next = to->_mixingTo; next != NULL; next = next->_mixingTo) { for (TrackEntry *next = to->_mixingTo; next != NULL; next = next->_mixingTo) {
@ -1020,6 +1034,22 @@ void AnimationState::setTimelineModes(TrackEntry *entry) {
} }
} }
void AnimationState::computeNotLast(TrackEntry *entry) {
Vector<Timeline *> &timelines = entry->_animation->_timelines;
size_t timelinesCount = timelines.size();
Vector<int> &timelineMode = entry->_timelineMode;
for (size_t i = 0; i < timelinesCount; i++) {
if (timelines[i]->getRTTI().isExactly(AttachmentTimeline::rtti)) {
AttachmentTimeline *timeline = static_cast<AttachmentTimeline *>(timelines[i]);
if (!_propertyIDs.contains(timeline->getSlotIndex())) {
_propertyIDs.add(timeline->getSlotIndex());
timelineMode[i] |= NotLast;
}
}
}
}
bool AnimationState::hasTimeline(TrackEntry* entry, int inId) { bool AnimationState::hasTimeline(TrackEntry* entry, int inId) {
Vector<Timeline *> &timelines = entry->_animation->_timelines; Vector<Timeline *> &timelines = entry->_animation->_timelines;
for (size_t i = 0, n = timelines.size(); i < n; ++i) { for (size_t i = 0, n = timelines.size(); i < n; ++i) {

View File

@ -79,8 +79,8 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
return; return;
} }
Vector<float> &verticesArray = slot._attachmentVertices; Vector<float> &deformArray = slot._deform;
if (verticesArray.size() == 0) { if (deformArray.size() == 0) {
blend = MixBlend_Setup; blend = MixBlend_Setup;
} }
@ -91,25 +91,25 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
if (time < _frames[0]) { if (time < _frames[0]) {
switch (blend) { switch (blend) {
case MixBlend_Setup: case MixBlend_Setup:
verticesArray.clear(); deformArray.clear();
return; return;
case MixBlend_First: { case MixBlend_First: {
if (alpha == 1) { if (alpha == 1) {
verticesArray.clear(); deformArray.clear();
return; return;
} }
verticesArray.setSize(vertexCount, 0); deformArray.setSize(vertexCount, 0);
Vector<float> &vertices = verticesArray; Vector<float> &deformInner = deformArray;
if (attachment->getBones().size() == 0) { if (attachment->getBones().size() == 0) {
// Unweighted vertex positions. // Unweighted vertex positions.
Vector<float> &setupVertices = attachment->getVertices(); Vector<float> &setupVertices = attachment->getVertices();
for (size_t i = 0; i < vertexCount; i++) for (size_t i = 0; i < vertexCount; i++)
vertices[i] += (setupVertices[i] - vertices[i]) * alpha; deformInner[i] += (setupVertices[i] - deformInner[i]) * alpha;
} else { } else {
// Weighted deform offsets. // Weighted deform offsets.
alpha = 1 - alpha; alpha = 1 - alpha;
for (size_t i = 0; i < vertexCount; i++) for (size_t i = 0; i < vertexCount; i++)
vertices[i] *= alpha; deformInner[i] *= alpha;
} }
} }
case MixBlend_Replace: case MixBlend_Replace:
@ -118,8 +118,8 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
} }
} }
verticesArray.setSize(vertexCount, 0); deformArray.setSize(vertexCount, 0);
Vector<float> &vertices = verticesArray; Vector<float> &deform = deformArray;
if (time >= frames[frames.size() - 1]) { // Time is after last frame. if (time >= frames[frames.size() - 1]) { // Time is after last frame.
Vector<float> &lastVertices = frameVertices[frames.size() - 1]; Vector<float> &lastVertices = frameVertices[frames.size() - 1];
@ -130,15 +130,15 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
// Unweighted vertex positions, no alpha. // Unweighted vertex positions, no alpha.
Vector<float> &setupVertices = vertexAttachment->getVertices(); Vector<float> &setupVertices = vertexAttachment->getVertices();
for (size_t i = 0; i < vertexCount; i++) for (size_t i = 0; i < vertexCount; i++)
vertices[i] += lastVertices[i] - setupVertices[i]; deform[i] += lastVertices[i] - setupVertices[i];
} else { } else {
// Weighted deform offsets, no alpha. // Weighted deform offsets, no alpha.
for (size_t i = 0; i < vertexCount; i++) for (size_t i = 0; i < vertexCount; i++)
vertices[i] += lastVertices[i]; deform[i] += lastVertices[i];
} }
} else { } else {
// Vertex positions or deform offsets, no alpha. // Vertex positions or deform offsets, no alpha.
memcpy(vertices.buffer(), lastVertices.buffer(), vertexCount * sizeof(float)); memcpy(deform.buffer(), lastVertices.buffer(), vertexCount * sizeof(float));
} }
} else { } else {
switch (blend) { switch (blend) {
@ -149,12 +149,12 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
Vector<float> &setupVertices = vertexAttachment->getVertices(); Vector<float> &setupVertices = vertexAttachment->getVertices();
for (size_t i = 0; i < vertexCount; i++) { for (size_t i = 0; i < vertexCount; i++) {
float setup = setupVertices[i]; float setup = setupVertices[i];
vertices[i] = setup + (lastVertices[i] - setup) * alpha; deform[i] = setup + (lastVertices[i] - setup) * alpha;
} }
} else { } else {
// Weighted deform offsets, with alpha. // Weighted deform offsets, with alpha.
for (size_t i = 0; i < vertexCount; i++) for (size_t i = 0; i < vertexCount; i++)
vertices[i] = lastVertices[i] * alpha; deform[i] = lastVertices[i] * alpha;
} }
break; break;
} }
@ -162,7 +162,7 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
case MixBlend_Replace: case MixBlend_Replace:
// Vertex positions or deform offsets, with alpha. // Vertex positions or deform offsets, with alpha.
for (size_t i = 0; i < vertexCount; i++) for (size_t i = 0; i < vertexCount; i++)
vertices[i] += (lastVertices[i] - vertices[i]) * alpha; deform[i] += (lastVertices[i] - deform[i]) * alpha;
break; break;
case MixBlend_Add: case MixBlend_Add:
VertexAttachment *vertexAttachment = static_cast<VertexAttachment *>(slotAttachment); VertexAttachment *vertexAttachment = static_cast<VertexAttachment *>(slotAttachment);
@ -170,11 +170,11 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
// Unweighted vertex positions, no alpha. // Unweighted vertex positions, no alpha.
Vector<float> &setupVertices = vertexAttachment->getVertices(); Vector<float> &setupVertices = vertexAttachment->getVertices();
for (size_t i = 0; i < vertexCount; i++) for (size_t i = 0; i < vertexCount; i++)
vertices[i] += (lastVertices[i] - setupVertices[i]) * alpha; deform[i] += (lastVertices[i] - setupVertices[i]) * alpha;
} else { } else {
// Weighted deform offsets, alpha. // Weighted deform offsets, alpha.
for (size_t i = 0; i < vertexCount; i++) for (size_t i = 0; i < vertexCount; i++)
vertices[i] += lastVertices[i] * alpha; deform[i] += lastVertices[i] * alpha;
} }
} }
} }
@ -196,20 +196,20 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
Vector<float> &setupVertices = vertexAttachment->getVertices(); Vector<float> &setupVertices = vertexAttachment->getVertices();
for (size_t i = 0; i < vertexCount; i++) { for (size_t i = 0; i < vertexCount; i++) {
float prev = prevVertices[i]; float prev = prevVertices[i];
vertices[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i]; deform[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i];
} }
} else { } else {
// Weighted deform offsets, no alpha. // Weighted deform offsets, no alpha.
for (size_t i = 0; i < vertexCount; i++) { for (size_t i = 0; i < vertexCount; i++) {
float prev = prevVertices[i]; float prev = prevVertices[i];
vertices[i] += prev + (nextVertices[i] - prev) * percent; deform[i] += prev + (nextVertices[i] - prev) * percent;
} }
} }
} else { } else {
// Vertex positions or deform offsets, no alpha. // Vertex positions or deform offsets, no alpha.
for (size_t i = 0; i < vertexCount; i++) { for (size_t i = 0; i < vertexCount; i++) {
float prev = prevVertices[i]; float prev = prevVertices[i];
vertices[i] = prev + (nextVertices[i] - prev) * percent; deform[i] = prev + (nextVertices[i] - prev) * percent;
} }
} }
} else { } else {
@ -221,13 +221,13 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
Vector<float> &setupVertices = vertexAttachment->getVertices(); Vector<float> &setupVertices = vertexAttachment->getVertices();
for (size_t i = 0; i < vertexCount; i++) { for (size_t i = 0; i < vertexCount; i++) {
float prev = prevVertices[i], setup = setupVertices[i]; float prev = prevVertices[i], setup = setupVertices[i];
vertices[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha; deform[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha;
} }
} else { } else {
// Weighted deform offsets, with alpha. // Weighted deform offsets, with alpha.
for (size_t i = 0; i < vertexCount; i++) { for (size_t i = 0; i < vertexCount; i++) {
float prev = prevVertices[i]; float prev = prevVertices[i];
vertices[i] = (prev + (nextVertices[i] - prev) * percent) * alpha; deform[i] = (prev + (nextVertices[i] - prev) * percent) * alpha;
} }
} }
break; break;
@ -237,7 +237,7 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
// Vertex positions or deform offsets, with alpha. // Vertex positions or deform offsets, with alpha.
for (size_t i = 0; i < vertexCount; i++) { for (size_t i = 0; i < vertexCount; i++) {
float prev = prevVertices[i]; float prev = prevVertices[i];
vertices[i] += (prev + (nextVertices[i] - prev) * percent - vertices[i]) * alpha; deform[i] += (prev + (nextVertices[i] - prev) * percent - deform[i]) * alpha;
} }
break; break;
case MixBlend_Add: case MixBlend_Add:
@ -247,13 +247,13 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
Vector<float> &setupVertices = vertexAttachment->getVertices(); Vector<float> &setupVertices = vertexAttachment->getVertices();
for (size_t i = 0; i < vertexCount; i++) { for (size_t i = 0; i < vertexCount; i++) {
float prev = prevVertices[i]; float prev = prevVertices[i];
vertices[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha; deform[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha;
} }
} else { } else {
// Weighted deform offsets, with alpha. // Weighted deform offsets, with alpha.
for (size_t i = 0; i < vertexCount; i++) { for (size_t i = 0; i < vertexCount; i++) {
float prev = prevVertices[i]; float prev = prevVertices[i];
vertices[i] += (prev + (nextVertices[i] - prev) * percent) * alpha; deform[i] += (prev + (nextVertices[i] - prev) * percent) * alpha;
} }
} }
} }

View File

@ -100,7 +100,7 @@ void Slot::setAttachment(Attachment *inValue) {
_attachment = inValue; _attachment = inValue;
_attachmentTime = _skeleton.getTime(); _attachmentTime = _skeleton.getTime();
_attachmentVertices.clear(); _deform.clear();
} }
float Slot::getAttachmentTime() { float Slot::getAttachmentTime() {
@ -111,6 +111,6 @@ void Slot::setAttachmentTime(float inValue) {
_attachmentTime = _skeleton.getTime() - inValue; _attachmentTime = _skeleton.getTime() - inValue;
} }
Vector<float> &Slot::getAttachmentVertices() { Vector<float> &Slot::getDeform() {
return _attachmentVertices; return _deform;
} }

View File

@ -66,7 +66,7 @@ void VertexAttachment::computeWorldVertices(Slot &slot, size_t start, size_t cou
size_t stride) { size_t stride) {
count = offset + (count >> 1) * stride; count = offset + (count >> 1) * stride;
Skeleton &skeleton = slot._bone._skeleton; Skeleton &skeleton = slot._bone._skeleton;
Vector<float> *deformArray = &slot.getAttachmentVertices(); Vector<float> *deformArray = &slot.getDeform();
Vector<float> *vertices = &_vertices; Vector<float> *vertices = &_vertices;
Vector<size_t> &bones = _bones; Vector<size_t> &bones = _bones;
if (bones.size() == 0) { if (bones.size() == 0) {