[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;
for (; i >= 0; i--) {
entry = self->tracks[i];
if (!entry) continue;
while (entry != 0) {
_spTrackEntry_computeNotLast(entry, self);
entry = entry->mixingFrom;

View File

@ -428,22 +428,24 @@ namespace spine {
void queueEvents(TrackEntry* entry, float animationTime);
/// 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);
/// Object-pooling version of new TrackEntry. Obtain an unused TrackEntry from the pool and clear/initialize its values.
/// @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.
void disposeNext(TrackEntry* entry);
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);
Vector<float> &getAttachmentVertices();
Vector<float> &getDeform();
private:
SlotData &_data;
@ -120,7 +120,7 @@ private:
bool _hasDarkColor;
Attachment *_attachment;
float _attachmentTime;
Vector<float> _attachmentVertices;
Vector<float> _deform;
};
}

View File

@ -43,6 +43,7 @@
#include <spine/BoneData.h>
#include <spine/AttachmentTimeline.h>
#include <spine/DrawOrderTimeline.h>
#include <spine/EventTimeline.h>
using namespace spine;
@ -275,6 +276,7 @@ const int Subsequent = 0;
const int First = 1;
const int Hold = 2;
const int HoldMix = 3;
const int NotLast = 4;
AnimationState::AnimationState(AnimationStateData *data) :
_data(data),
@ -418,7 +420,7 @@ bool AnimationState::apply(Skeleton &skeleton) {
Timeline *timeline = timelines[ii];
assert(timeline);
MixBlend timelineBlend = timelineMode[ii] == Subsequent ? blend : MixBlend_Setup;
MixBlend timelineBlend = (timelineMode[ii] & (NotLast - 1)) == Subsequent ? blend : MixBlend_Setup;
RotateTimeline *rotateTimeline = NULL;
if (timeline->getRTTI().isExactly(RotateTimeline::rtti)) {
@ -787,7 +789,7 @@ float AnimationState::applyMixingFrom(TrackEntry *to, Skeleton &skeleton, MixBle
MixDirection direction = MixDirection_Out;
MixBlend timelineBlend;
float alpha;
switch (timelineMode[i]) {
switch (timelineMode[i] & (NotLast - 1)) {
case Subsequent:
if (!attachments && (timeline->getRTTI().isExactly(AttachmentTimeline::rtti))) continue;
if (!drawOrder && (timeline->getRTTI().isExactly(DrawOrderTimeline::rtti))) continue;
@ -815,7 +817,7 @@ float AnimationState::applyMixingFrom(TrackEntry *to, Skeleton &skeleton, MixBle
} else {
if (timelineBlend == MixBlend_Setup) {
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)) {
if (drawOrder) direction = MixDirection_In;
}
@ -967,13 +969,22 @@ void AnimationState::animationsChanged() {
entry = entry->_mixingFrom;
do {
if (entry->_mixingTo == NULL || entry->_mixBlend != MixBlend_Add) setTimelineModes(entry);
if (entry->_mixingTo == NULL || entry->_mixBlend != MixBlend_Add) computeHold(entry);
entry = entry->_mixingTo;
} 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;
Vector<Timeline *> &timelines = entry->_animation->_timelines;
size_t timelinesCount = timelines.size();
@ -995,13 +1006,16 @@ void AnimationState::setTimelineModes(TrackEntry *entry) {
size_t i = 0;
continue_outer:
for (; i < timelinesCount; ++i) {
int id = timelines[i]->getPropertyId();
Timeline *timeline = timelines[i];
int id = timeline->getPropertyId();
if (_propertyIDs.contains(id)) {
timelineMode[i] = Subsequent;
} else {
_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;
} else {
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) {
Vector<Timeline *> &timelines = entry->_animation->_timelines;
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;
}
Vector<float> &verticesArray = slot._attachmentVertices;
if (verticesArray.size() == 0) {
Vector<float> &deformArray = slot._deform;
if (deformArray.size() == 0) {
blend = MixBlend_Setup;
}
@ -91,25 +91,25 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
if (time < _frames[0]) {
switch (blend) {
case MixBlend_Setup:
verticesArray.clear();
deformArray.clear();
return;
case MixBlend_First: {
if (alpha == 1) {
verticesArray.clear();
deformArray.clear();
return;
}
verticesArray.setSize(vertexCount, 0);
Vector<float> &vertices = verticesArray;
deformArray.setSize(vertexCount, 0);
Vector<float> &deformInner = deformArray;
if (attachment->getBones().size() == 0) {
// Unweighted vertex positions.
Vector<float> &setupVertices = attachment->getVertices();
for (size_t i = 0; i < vertexCount; i++)
vertices[i] += (setupVertices[i] - vertices[i]) * alpha;
deformInner[i] += (setupVertices[i] - deformInner[i]) * alpha;
} else {
// Weighted deform offsets.
alpha = 1 - alpha;
for (size_t i = 0; i < vertexCount; i++)
vertices[i] *= alpha;
deformInner[i] *= alpha;
}
}
case MixBlend_Replace:
@ -118,8 +118,8 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
}
}
verticesArray.setSize(vertexCount, 0);
Vector<float> &vertices = verticesArray;
deformArray.setSize(vertexCount, 0);
Vector<float> &deform = deformArray;
if (time >= frames[frames.size() - 1]) { // Time is after last frame.
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.
Vector<float> &setupVertices = vertexAttachment->getVertices();
for (size_t i = 0; i < vertexCount; i++)
vertices[i] += lastVertices[i] - setupVertices[i];
deform[i] += lastVertices[i] - setupVertices[i];
} else {
// Weighted deform offsets, no alpha.
for (size_t i = 0; i < vertexCount; i++)
vertices[i] += lastVertices[i];
deform[i] += lastVertices[i];
}
} else {
// Vertex positions or deform offsets, no alpha.
memcpy(vertices.buffer(), lastVertices.buffer(), vertexCount * sizeof(float));
memcpy(deform.buffer(), lastVertices.buffer(), vertexCount * sizeof(float));
}
} else {
switch (blend) {
@ -149,12 +149,12 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
Vector<float> &setupVertices = vertexAttachment->getVertices();
for (size_t i = 0; i < vertexCount; i++) {
float setup = setupVertices[i];
vertices[i] = setup + (lastVertices[i] - setup) * alpha;
deform[i] = setup + (lastVertices[i] - setup) * alpha;
}
} else {
// Weighted deform offsets, with alpha.
for (size_t i = 0; i < vertexCount; i++)
vertices[i] = lastVertices[i] * alpha;
deform[i] = lastVertices[i] * alpha;
}
break;
}
@ -162,7 +162,7 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
case MixBlend_Replace:
// Vertex positions or deform offsets, with alpha.
for (size_t i = 0; i < vertexCount; i++)
vertices[i] += (lastVertices[i] - vertices[i]) * alpha;
deform[i] += (lastVertices[i] - deform[i]) * alpha;
break;
case MixBlend_Add:
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.
Vector<float> &setupVertices = vertexAttachment->getVertices();
for (size_t i = 0; i < vertexCount; i++)
vertices[i] += (lastVertices[i] - setupVertices[i]) * alpha;
deform[i] += (lastVertices[i] - setupVertices[i]) * alpha;
} else {
// Weighted deform offsets, alpha.
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();
for (size_t i = 0; i < vertexCount; i++) {
float prev = prevVertices[i];
vertices[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i];
deform[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i];
}
} else {
// Weighted deform offsets, no alpha.
for (size_t i = 0; i < vertexCount; i++) {
float prev = prevVertices[i];
vertices[i] += prev + (nextVertices[i] - prev) * percent;
deform[i] += prev + (nextVertices[i] - prev) * percent;
}
}
} else {
// Vertex positions or deform offsets, no alpha.
for (size_t i = 0; i < vertexCount; i++) {
float prev = prevVertices[i];
vertices[i] = prev + (nextVertices[i] - prev) * percent;
deform[i] = prev + (nextVertices[i] - prev) * percent;
}
}
} else {
@ -221,13 +221,13 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
Vector<float> &setupVertices = vertexAttachment->getVertices();
for (size_t i = 0; i < vertexCount; 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 {
// Weighted deform offsets, with alpha.
for (size_t i = 0; i < vertexCount; i++) {
float prev = prevVertices[i];
vertices[i] = (prev + (nextVertices[i] - prev) * percent) * alpha;
deform[i] = (prev + (nextVertices[i] - prev) * percent) * alpha;
}
}
break;
@ -237,7 +237,7 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
// Vertex positions or deform offsets, with alpha.
for (size_t i = 0; i < vertexCount; 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;
case MixBlend_Add:
@ -247,13 +247,13 @@ void DeformTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto
Vector<float> &setupVertices = vertexAttachment->getVertices();
for (size_t i = 0; i < vertexCount; 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 {
// Weighted deform offsets, with alpha.
for (size_t i = 0; i < vertexCount; 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;
_attachmentTime = _skeleton.getTime();
_attachmentVertices.clear();
_deform.clear();
}
float Slot::getAttachmentTime() {
@ -111,6 +111,6 @@ void Slot::setAttachmentTime(float inValue) {
_attachmentTime = _skeleton.getTime() - inValue;
}
Vector<float> &Slot::getAttachmentVertices() {
return _attachmentVertices;
Vector<float> &Slot::getDeform() {
return _deform;
}

View File

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