mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-25 22:23:42 +08:00
[cpp] Ported AniamtionState and Animation changes. See #1303.
This commit is contained in:
parent
4785ad656d
commit
ae63d28920
@ -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;
|
||||
|
||||
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user