mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 09:46:02 +08:00
[cpp] More 4.0 porting, animation state.
This commit is contained in:
parent
7b154fb92f
commit
df6de224e3
@ -45,6 +45,8 @@ class Skeleton;
|
|||||||
|
|
||||||
class Event;
|
class Event;
|
||||||
|
|
||||||
|
class AnimationState;
|
||||||
|
|
||||||
class SP_API Animation : public SpineObject {
|
class SP_API Animation : public SpineObject {
|
||||||
friend class AnimationState;
|
friend class AnimationState;
|
||||||
|
|
||||||
@ -115,8 +117,8 @@ public:
|
|||||||
void setDuration(float inValue);
|
void setDuration(float inValue);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector<Timeline *> _timelines;
|
Vector<Timeline *> _timelines;
|
||||||
HashMap<PropertyId, bool> _timelineIds;
|
HashMap<PropertyId, bool> _timelineIds;
|
||||||
float _duration;
|
float _duration;
|
||||||
String _name;
|
String _name;
|
||||||
|
|
||||||
|
|||||||
@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include <spine/Vector.h>
|
#include <spine/Vector.h>
|
||||||
#include <spine/Pool.h>
|
#include <spine/Pool.h>
|
||||||
|
#include <spine/Property.h>
|
||||||
#include <spine/MixBlend.h>
|
#include <spine/MixBlend.h>
|
||||||
#include <spine/SpineObject.h>
|
#include <spine/SpineObject.h>
|
||||||
#include <spine/SpineString.h>
|
#include <spine/SpineString.h>
|
||||||
@ -94,6 +95,8 @@ namespace spine {
|
|||||||
/// The animation to apply for this track entry.
|
/// The animation to apply for this track entry.
|
||||||
Animation* getAnimation();
|
Animation* getAnimation();
|
||||||
|
|
||||||
|
TrackEntry* getPrevious();
|
||||||
|
|
||||||
/// If true, the animation will repeat. If false, it will not, instead its last frame is applied if played beyond its duration.
|
/// If true, the animation will repeat. If false, it will not, instead its last frame is applied if played beyond its duration.
|
||||||
bool getLoop();
|
bool getLoop();
|
||||||
void setLoop(bool inValue);
|
void setLoop(bool inValue);
|
||||||
@ -112,6 +115,9 @@ namespace spine {
|
|||||||
bool getHoldPrevious();
|
bool getHoldPrevious();
|
||||||
void setHoldPrevious(bool inValue);
|
void setHoldPrevious(bool inValue);
|
||||||
|
|
||||||
|
bool getReverse();
|
||||||
|
void setReverse(bool inValue);
|
||||||
|
|
||||||
/// Seconds to postpone playing the animation. When a track entry is the current track entry, delay postpones incrementing
|
/// Seconds to postpone playing the animation. When a track entry is the current track entry, delay postpones incrementing
|
||||||
/// the track time. When a track entry is queued, delay is the time from the start of the previous animation to when the
|
/// the track time. When a track entry is queued, delay is the time from the start of the previous animation to when the
|
||||||
/// track entry will become the current track entry.
|
/// track entry will become the current track entry.
|
||||||
@ -228,19 +234,21 @@ namespace spine {
|
|||||||
/// TrackEntry chooses the short way the first time it is applied and remembers that direction.
|
/// TrackEntry chooses the short way the first time it is applied and remembers that direction.
|
||||||
void resetRotationDirections();
|
void resetRotationDirections();
|
||||||
|
|
||||||
|
float getTrackComplete();
|
||||||
|
|
||||||
void setListener(AnimationStateListener listener);
|
void setListener(AnimationStateListener listener);
|
||||||
|
|
||||||
void setListener(AnimationStateListenerObject* listener);
|
void setListener(AnimationStateListenerObject* listener);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Animation* _animation;
|
Animation* _animation;
|
||||||
|
TrackEntry* _previous;
|
||||||
TrackEntry* _next;
|
TrackEntry* _next;
|
||||||
TrackEntry* _mixingFrom;
|
TrackEntry* _mixingFrom;
|
||||||
TrackEntry* _mixingTo;
|
TrackEntry* _mixingTo;
|
||||||
int _trackIndex;
|
int _trackIndex;
|
||||||
|
|
||||||
bool _loop, _holdPrevious;
|
bool _loop, _holdPrevious, _reverse;
|
||||||
float _eventThreshold, _attachmentThreshold, _drawOrderThreshold;
|
float _eventThreshold, _attachmentThreshold, _drawOrderThreshold;
|
||||||
float _animationStart, _animationEnd, _animationLast, _nextAnimationLast;
|
float _animationStart, _animationEnd, _animationLast, _nextAnimationLast;
|
||||||
float _delay, _trackTime, _trackLast, _nextTrackLast, _trackEnd, _timeScale;
|
float _delay, _trackTime, _trackLast, _nextTrackLast, _trackEnd, _timeScale;
|
||||||
@ -403,7 +411,7 @@ namespace spine {
|
|||||||
Vector<Event*> _events;
|
Vector<Event*> _events;
|
||||||
EventQueue* _queue;
|
EventQueue* _queue;
|
||||||
|
|
||||||
HashMap<int, bool> _propertyIDs;
|
HashMap<PropertyId, bool> _propertyIDs;
|
||||||
bool _animationsChanged;
|
bool _animationsChanged;
|
||||||
|
|
||||||
AnimationStateListener _listener;
|
AnimationStateListener _listener;
|
||||||
@ -428,6 +436,9 @@ namespace spine {
|
|||||||
/// 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);
|
||||||
|
|
||||||
|
/// Removes the next entry and all entries after it for the specified entry. */
|
||||||
|
void clearNext(TrackEntry *entry);
|
||||||
|
|
||||||
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.
|
||||||
|
|||||||
@ -52,7 +52,7 @@ namespace spine {
|
|||||||
/// Sets the time and value of the specified keyframe.
|
/// Sets the time and value of the specified keyframe.
|
||||||
void setFrame(int frameIndex, float time, Vector<float> &vertices);
|
void setFrame(int frameIndex, float time, Vector<float> &vertices);
|
||||||
|
|
||||||
Vector <Vector<float>> &getVertices();
|
Vector <Vector<float> > &getVertices();
|
||||||
|
|
||||||
VertexAttachment *getAttachment();
|
VertexAttachment *getAttachment();
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ namespace spine {
|
|||||||
protected:
|
protected:
|
||||||
int _slotIndex;
|
int _slotIndex;
|
||||||
|
|
||||||
Vector <Vector<float>> _vertices;
|
Vector <Vector<float> > _vertices;
|
||||||
|
|
||||||
VertexAttachment *_attachment;
|
VertexAttachment *_attachment;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -129,6 +129,14 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool addAll(Vector<K> &keys, const V &value) {
|
||||||
|
size_t oldSize = _size;
|
||||||
|
for (size_t i = 0; i < keys.size(); i++) {
|
||||||
|
put(keys[i], value);
|
||||||
|
}
|
||||||
|
return _size != oldSize;
|
||||||
|
}
|
||||||
|
|
||||||
bool containsKey(const K &key) {
|
bool containsKey(const K &key) {
|
||||||
return find(key) != NULL;
|
return find(key) != NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,7 +57,7 @@ void dummyOnAnimationEventFunc(AnimationState *state, spine::EventType type, Tra
|
|||||||
SP_UNUSED(event);
|
SP_UNUSED(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackEntry::TrackEntry() : _animation(NULL), _next(NULL), _mixingFrom(NULL), _mixingTo(0), _trackIndex(0), _loop(false), _holdPrevious(false),
|
TrackEntry::TrackEntry() : _animation(NULL), _previous(NULL), _next(NULL), _mixingFrom(NULL), _mixingTo(0), _trackIndex(0), _loop(false), _holdPrevious(false), _reverse(false),
|
||||||
_eventThreshold(0), _attachmentThreshold(0), _drawOrderThreshold(0), _animationStart(0),
|
_eventThreshold(0), _attachmentThreshold(0), _drawOrderThreshold(0), _animationStart(0),
|
||||||
_animationEnd(0), _animationLast(0), _nextAnimationLast(0), _delay(0), _trackTime(0),
|
_animationEnd(0), _animationLast(0), _nextAnimationLast(0), _delay(0), _trackTime(0),
|
||||||
_trackLast(0), _nextTrackLast(0), _trackEnd(0), _timeScale(1.0f), _alpha(0), _mixTime(0),
|
_trackLast(0), _nextTrackLast(0), _trackEnd(0), _timeScale(1.0f), _alpha(0), _mixTime(0),
|
||||||
@ -71,6 +71,8 @@ int TrackEntry::getTrackIndex() { return _trackIndex; }
|
|||||||
|
|
||||||
Animation *TrackEntry::getAnimation() { return _animation; }
|
Animation *TrackEntry::getAnimation() { return _animation; }
|
||||||
|
|
||||||
|
TrackEntry* TrackEntry::getPrevious() { return _previous; }
|
||||||
|
|
||||||
bool TrackEntry::getLoop() { return _loop; }
|
bool TrackEntry::getLoop() { return _loop; }
|
||||||
|
|
||||||
void TrackEntry::setLoop(bool inValue) { _loop = inValue; }
|
void TrackEntry::setLoop(bool inValue) { _loop = inValue; }
|
||||||
@ -79,6 +81,10 @@ bool TrackEntry::getHoldPrevious() { return _holdPrevious; }
|
|||||||
|
|
||||||
void TrackEntry::setHoldPrevious(bool inValue) { _holdPrevious = inValue; }
|
void TrackEntry::setHoldPrevious(bool inValue) { _holdPrevious = inValue; }
|
||||||
|
|
||||||
|
bool TrackEntry::getReverse() { return _reverse; }
|
||||||
|
|
||||||
|
void TrackEntry::setReverse(bool inValue) { _reverse = inValue; }
|
||||||
|
|
||||||
float TrackEntry::getDelay() { return _delay; }
|
float TrackEntry::getDelay() { return _delay; }
|
||||||
|
|
||||||
void TrackEntry::setDelay(float inValue) { _delay = inValue; }
|
void TrackEntry::setDelay(float inValue) { _delay = inValue; }
|
||||||
@ -174,6 +180,7 @@ void TrackEntry::setListener(AnimationStateListenerObject* inValue) {
|
|||||||
|
|
||||||
void TrackEntry::reset() {
|
void TrackEntry::reset() {
|
||||||
_animation = NULL;
|
_animation = NULL;
|
||||||
|
_previous = NULL;
|
||||||
_next = NULL;
|
_next = NULL;
|
||||||
_mixingFrom = NULL;
|
_mixingFrom = NULL;
|
||||||
_mixingTo = NULL;
|
_mixingTo = NULL;
|
||||||
@ -188,6 +195,15 @@ void TrackEntry::reset() {
|
|||||||
_listenerObject = NULL;
|
_listenerObject = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float TrackEntry::getTrackComplete() {
|
||||||
|
float duration = _animationEnd - _animationStart;
|
||||||
|
if (duration != 0) {
|
||||||
|
if (_loop) return duration * (1 + (int)(_trackTime / duration)); // Completion of next loop.
|
||||||
|
if (_trackTime < duration) return duration; // Before duration.
|
||||||
|
}
|
||||||
|
return _trackTime; // Next update.
|
||||||
|
}
|
||||||
|
|
||||||
EventQueueEntry::EventQueueEntry(EventType eventType, TrackEntry *trackEntry, Event *event) :
|
EventQueueEntry::EventQueueEntry(EventType eventType, TrackEntry *trackEntry, Event *event) :
|
||||||
_type(eventType),
|
_type(eventType),
|
||||||
_entry(trackEntry),
|
_entry(trackEntry),
|
||||||
@ -412,15 +428,21 @@ bool AnimationState::apply(Skeleton &skeleton) {
|
|||||||
|
|
||||||
// apply current entry.
|
// apply current entry.
|
||||||
float animationLast = current._animationLast, animationTime = current.getAnimationTime();
|
float animationLast = current._animationLast, animationTime = current.getAnimationTime();
|
||||||
|
float applyTime = animationTime;
|
||||||
|
Vector<Event *> *applyEvents = &_events;
|
||||||
|
if (current._reverse) {
|
||||||
|
applyTime = current._animation->getDuration() - applyTime;
|
||||||
|
applyEvents = NULL;
|
||||||
|
}
|
||||||
size_t timelineCount = current._animation->_timelines.size();
|
size_t timelineCount = current._animation->_timelines.size();
|
||||||
Vector<Timeline *> &timelines = current._animation->_timelines;
|
Vector<Timeline *> &timelines = current._animation->_timelines;
|
||||||
if ((i == 0 && mix == 1) || blend == MixBlend_Add) {
|
if ((i == 0 && mix == 1) || blend == MixBlend_Add) {
|
||||||
for (size_t ii = 0; ii < timelineCount; ++ii) {
|
for (size_t ii = 0; ii < timelineCount; ++ii) {
|
||||||
Timeline *timeline = timelines[ii];
|
Timeline *timeline = timelines[ii];
|
||||||
if (timeline->getRTTI().isExactly(AttachmentTimeline::rtti))
|
if (timeline->getRTTI().isExactly(AttachmentTimeline::rtti))
|
||||||
applyAttachmentTimeline(static_cast<AttachmentTimeline *>(timeline), skeleton, animationTime, blend, true);
|
applyAttachmentTimeline(static_cast<AttachmentTimeline *>(timeline), skeleton, applyTime, blend, true);
|
||||||
else
|
else
|
||||||
timeline->apply(skeleton, animationLast, animationTime, &_events, mix, blend, MixDirection_In);
|
timeline->apply(skeleton, animationLast, applyTime, applyEvents, mix, blend, MixDirection_In);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Vector<int> &timelineMode = current._timelineMode;
|
Vector<int> &timelineMode = current._timelineMode;
|
||||||
@ -436,11 +458,11 @@ bool AnimationState::apply(Skeleton &skeleton) {
|
|||||||
MixBlend timelineBlend = timelineMode[ii] == Subsequent ? blend : MixBlend_Setup;
|
MixBlend timelineBlend = timelineMode[ii] == Subsequent ? blend : MixBlend_Setup;
|
||||||
|
|
||||||
if (timeline->getRTTI().isExactly(RotateTimeline::rtti))
|
if (timeline->getRTTI().isExactly(RotateTimeline::rtti))
|
||||||
applyRotateTimeline(static_cast<RotateTimeline *>(timeline), skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame);
|
applyRotateTimeline(static_cast<RotateTimeline *>(timeline), skeleton, applyTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame);
|
||||||
else if (timeline->getRTTI().isExactly(AttachmentTimeline::rtti))
|
else if (timeline->getRTTI().isExactly(AttachmentTimeline::rtti))
|
||||||
applyAttachmentTimeline(static_cast<AttachmentTimeline *>(timeline), skeleton, animationTime, timelineBlend, true);
|
applyAttachmentTimeline(static_cast<AttachmentTimeline *>(timeline), skeleton, applyTime, timelineBlend, true);
|
||||||
else
|
else
|
||||||
timeline->apply(skeleton, animationLast, animationTime, &_events, mix, timelineBlend, MixDirection_In);
|
timeline->apply(skeleton, animationLast, applyTime, applyEvents, mix, timelineBlend, MixDirection_In);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,19 +577,8 @@ TrackEntry *AnimationState::addAnimation(size_t trackIndex, Animation *animation
|
|||||||
_queue->drain();
|
_queue->drain();
|
||||||
} else {
|
} else {
|
||||||
last->_next = entry;
|
last->_next = entry;
|
||||||
if (delay <= 0) {
|
entry->_previous = last;
|
||||||
float duration = last->_animationEnd - last->_animationStart;
|
if (delay <= 0) delay += last->getTrackComplete() - entry->_mixDuration;
|
||||||
if (duration != 0) {
|
|
||||||
if (last->_loop) {
|
|
||||||
delay += duration * (1 + (int) (last->_trackTime / duration));
|
|
||||||
} else {
|
|
||||||
delay += MathUtil::max(duration, last->_trackTime);
|
|
||||||
}
|
|
||||||
delay -= _data->getMix(last->_animation, animation);
|
|
||||||
} else {
|
|
||||||
delay = last->_trackTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entry->_delay = delay;
|
entry->_delay = delay;
|
||||||
@ -582,14 +593,11 @@ TrackEntry *AnimationState::setEmptyAnimation(size_t trackIndex, float mixDurati
|
|||||||
}
|
}
|
||||||
|
|
||||||
TrackEntry *AnimationState::addEmptyAnimation(size_t trackIndex, float mixDuration, float delay) {
|
TrackEntry *AnimationState::addEmptyAnimation(size_t trackIndex, float mixDuration, float delay) {
|
||||||
if (delay <= 0) {
|
TrackEntry *entry = addAnimation(trackIndex, AnimationState::getEmptyAnimation(), false, delay <= 0 ? 1 : delay);
|
||||||
delay -= mixDuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
TrackEntry *entry = addAnimation(trackIndex, AnimationState::getEmptyAnimation(), false, delay);
|
|
||||||
entry->_mixDuration = mixDuration;
|
entry->_mixDuration = mixDuration;
|
||||||
entry->_trackEnd = mixDuration;
|
entry->_trackEnd = mixDuration;
|
||||||
return entry;
|
if (delay <= 0 && entry->_previous != NULL) entry->_delay = entry->_previous->getTrackComplete() - entry->_mixDuration;
|
||||||
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimationState::setEmptyAnimations(float mixDuration) {
|
void AnimationState::setEmptyAnimations(float mixDuration) {
|
||||||
@ -657,12 +665,7 @@ void AnimationState::applyAttachmentTimeline(AttachmentTimeline* attachmentTimel
|
|||||||
if (blend == MixBlend_Setup || blend == MixBlend_First)
|
if (blend == MixBlend_Setup || blend == MixBlend_First)
|
||||||
setAttachment(skeleton, *slot, slot->getData().getAttachmentName(), attachments);
|
setAttachment(skeleton, *slot, slot->getData().getAttachmentName(), attachments);
|
||||||
} else {
|
} else {
|
||||||
int frameIndex = 0;
|
setAttachment(skeleton, *slot, attachmentTimeline->getAttachmentNames()[Animation::search(frames, time)], attachments);
|
||||||
if (time >= frames[attachmentTimeline->getFrames().size() - 1])
|
|
||||||
frameIndex = attachmentTimeline->getFrames().size() - 1;
|
|
||||||
else
|
|
||||||
frameIndex = Animation::binarySearch(frames, time) - 1;
|
|
||||||
setAttachment(skeleton, *slot, attachmentTimeline->getAttachmentNames()[frameIndex], attachments);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If an attachment wasn't set (ie before the first frame or attachments is false), set the setup attachment later.*/
|
/* If an attachment wasn't set (ie before the first frame or attachments is false), set the setup attachment later.*/
|
||||||
@ -696,21 +699,7 @@ void AnimationState::applyRotateTimeline(RotateTimeline *rotateTimeline, Skeleto
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
r1 = blend == MixBlend_Setup ? bone->_data._rotation : bone->_rotation;
|
r1 = blend == MixBlend_Setup ? bone->_data._rotation : bone->_rotation;
|
||||||
if (time >= frames[frames.size() - RotateTimeline::ENTRIES]) {
|
r2 = bone->_data._rotation + rotateTimeline->getCurveValue(time);
|
||||||
// Time is after last frame.
|
|
||||||
r2 = bone->_data._rotation + frames[frames.size() + RotateTimeline::PREV_ROTATION];
|
|
||||||
} else {
|
|
||||||
// Interpolate between the previous frame and the current frame.
|
|
||||||
int frame = Animation::binarySearch(frames, time, RotateTimeline::ENTRIES);
|
|
||||||
float prevRotation = frames[frame + RotateTimeline::PREV_ROTATION];
|
|
||||||
float frameTime = frames[frame];
|
|
||||||
float percent = rotateTimeline->getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame +
|
|
||||||
RotateTimeline::PREV_TIME] - frameTime));
|
|
||||||
r2 = frames[frame + RotateTimeline::ROTATION] - prevRotation;
|
|
||||||
r2 -= (16384 - (int) (16384.499999999996 - r2 / 360)) * 360;
|
|
||||||
r2 = prevRotation + r2 * percent + bone->_data._rotation;
|
|
||||||
r2 -= (16384 - (int) (16384.499999999996 - r2 / 360)) * 360;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mix between rotations using the direction of the shortest route on the first frame while detecting crosses.
|
// Mix between rotations using the direction of the shortest route on the first frame while detecting crosses.
|
||||||
@ -743,8 +732,7 @@ void AnimationState::applyRotateTimeline(RotateTimeline *rotateTimeline, Skeleto
|
|||||||
timelinesRotation[i] = total;
|
timelinesRotation[i] = total;
|
||||||
}
|
}
|
||||||
timelinesRotation[i + 1] = diff;
|
timelinesRotation[i + 1] = diff;
|
||||||
r1 += total * alpha;
|
bone->_rotation = r1 + total * alpha;
|
||||||
bone->_rotation = r1 - (16384 - (int) (16384.499999999996 - r1 / 360)) * 360;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AnimationState::updateMixingFrom(TrackEntry *to, float delta) {
|
bool AnimationState::updateMixingFrom(TrackEntry *to, float delta) {
|
||||||
@ -793,16 +781,22 @@ float AnimationState::applyMixingFrom(TrackEntry *to, Skeleton &skeleton, MixBle
|
|||||||
if (blend != MixBlend_First) blend = from->_mixBlend;
|
if (blend != MixBlend_First) blend = from->_mixBlend;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<Event *> *eventBuffer = mix < from->_eventThreshold ? &_events : NULL;
|
|
||||||
bool attachments = mix < from->_attachmentThreshold, drawOrder = mix < from->_drawOrderThreshold;
|
bool attachments = mix < from->_attachmentThreshold, drawOrder = mix < from->_drawOrderThreshold;
|
||||||
float animationLast = from->_animationLast, animationTime = from->getAnimationTime();
|
|
||||||
Vector<Timeline *> &timelines = from->_animation->_timelines;
|
Vector<Timeline *> &timelines = from->_animation->_timelines;
|
||||||
size_t timelineCount = timelines.size();
|
size_t timelineCount = timelines.size();
|
||||||
float alphaHold = from->_alpha * to->_interruptAlpha, alphaMix = alphaHold * (1 - mix);
|
float alphaHold = from->_alpha * to->_interruptAlpha, alphaMix = alphaHold * (1 - mix);
|
||||||
|
float animationLast = from->_animationLast, animationTime = from->getAnimationTime();
|
||||||
|
float applyTime = animationTime;
|
||||||
|
Vector<Event *> *events = NULL;
|
||||||
|
if (from->_reverse) {
|
||||||
|
applyTime = from->_animation->_duration - applyTime;
|
||||||
|
} else {
|
||||||
|
if (mix < from->_eventThreshold) events = &_events;
|
||||||
|
}
|
||||||
|
|
||||||
if (blend == MixBlend_Add) {
|
if (blend == MixBlend_Add) {
|
||||||
for (size_t i = 0; i < timelineCount; i++)
|
for (size_t i = 0; i < timelineCount; i++)
|
||||||
timelines[i]->apply(skeleton, animationLast, animationTime, eventBuffer, alphaMix, blend, MixDirection_Out);
|
timelines[i]->apply(skeleton, animationLast, applyTime, events, alphaMix, blend, MixDirection_Out);
|
||||||
} else {
|
} else {
|
||||||
Vector<int> &timelineMode = from->_timelineMode;
|
Vector<int> &timelineMode = from->_timelineMode;
|
||||||
Vector<TrackEntry *> &timelineHoldMix = from->_timelineHoldMix;
|
Vector<TrackEntry *> &timelineHoldMix = from->_timelineHoldMix;
|
||||||
@ -844,13 +838,13 @@ float AnimationState::applyMixingFrom(TrackEntry *to, Skeleton &skeleton, MixBle
|
|||||||
}
|
}
|
||||||
from->_totalAlpha += alpha;
|
from->_totalAlpha += alpha;
|
||||||
if ((timeline->getRTTI().isExactly(RotateTimeline::rtti))) {
|
if ((timeline->getRTTI().isExactly(RotateTimeline::rtti))) {
|
||||||
applyRotateTimeline((RotateTimeline*)timeline, skeleton, animationTime, alpha, timelineBlend, timelinesRotation, i << 1, firstFrame);
|
applyRotateTimeline((RotateTimeline*)timeline, skeleton, applyTime, alpha, timelineBlend, timelinesRotation, i << 1, firstFrame);
|
||||||
} else if (timeline->getRTTI().isExactly(AttachmentTimeline::rtti)) {
|
} else if (timeline->getRTTI().isExactly(AttachmentTimeline::rtti)) {
|
||||||
applyAttachmentTimeline(static_cast<AttachmentTimeline*>(timeline), skeleton, animationTime, timelineBlend, attachments);
|
applyAttachmentTimeline(static_cast<AttachmentTimeline*>(timeline), skeleton, applyTime, timelineBlend, attachments);
|
||||||
} else {
|
} else {
|
||||||
if (drawOrder && timeline->getRTTI().isExactly(DrawOrderTimeline::rtti) && timelineBlend == MixBlend_Setup)
|
if (drawOrder && timeline->getRTTI().isExactly(DrawOrderTimeline::rtti) && timelineBlend == MixBlend_Setup)
|
||||||
direction = MixDirection_In;
|
direction = MixDirection_In;
|
||||||
timeline->apply(skeleton, animationLast, animationTime, eventBuffer, alpha, timelineBlend, direction);
|
timeline->apply(skeleton, animationLast, applyTime, events, alpha, timelineBlend, direction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -897,13 +891,18 @@ void AnimationState::queueEvents(TrackEntry *entry, float animationTime) {
|
|||||||
for (; i < n; ++i) {
|
for (; i < n; ++i) {
|
||||||
Event *e = _events[i];
|
Event *e = _events[i];
|
||||||
if (e->_time < animationStart) continue; // Discard events outside animation start/end.
|
if (e->_time < animationStart) continue; // Discard events outside animation start/end.
|
||||||
_queue->event(entry, _events[i]);
|
_queue->event(entry, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AnimationState::clearNext(TrackEntry *entry) {
|
||||||
|
disposeNext(entry->_next);
|
||||||
|
}
|
||||||
|
|
||||||
void AnimationState::setCurrent(size_t index, TrackEntry *current, bool interrupt) {
|
void AnimationState::setCurrent(size_t index, TrackEntry *current, bool interrupt) {
|
||||||
TrackEntry *from = expandToIndex(index);
|
TrackEntry *from = expandToIndex(index);
|
||||||
_tracks[index] = current;
|
_tracks[index] = current;
|
||||||
|
current->_previous = NULL;
|
||||||
|
|
||||||
if (from != NULL) {
|
if (from != NULL) {
|
||||||
if (interrupt) _queue->interrupt(from);
|
if (interrupt) _queue->interrupt(from);
|
||||||
@ -1002,13 +1001,7 @@ void AnimationState::computeHold(TrackEntry *entry) {
|
|||||||
|
|
||||||
if (to != NULL && to->_holdPrevious) {
|
if (to != NULL && to->_holdPrevious) {
|
||||||
for (size_t i = 0; i < timelinesCount; i++) {
|
for (size_t i = 0; i < timelinesCount; i++) {
|
||||||
int id = timelines[i]->getPropertyId();
|
timelineMode[i] = _propertyIDs.addAll(timelines[i]->getPropertyIds(), true) ? HoldFirst : HoldSubsequent;
|
||||||
if (!_propertyIDs.containsKey(id)) {
|
|
||||||
_propertyIDs.put(id, true);
|
|
||||||
timelineMode[i] = HoldFirst;
|
|
||||||
} else {
|
|
||||||
timelineMode[i] = HoldSubsequent;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1018,19 +1011,17 @@ void AnimationState::computeHold(TrackEntry *entry) {
|
|||||||
continue_outer:
|
continue_outer:
|
||||||
for (; i < timelinesCount; ++i) {
|
for (; i < timelinesCount; ++i) {
|
||||||
Timeline *timeline = timelines[i];
|
Timeline *timeline = timelines[i];
|
||||||
int id = timeline->getPropertyId();
|
Vector<PropertyId> &ids = timeline->getPropertyIds();
|
||||||
if (_propertyIDs.containsKey(id)) {
|
if (!_propertyIDs.addAll(ids, true)) {
|
||||||
timelineMode[i] = Subsequent;
|
timelineMode[i] = Subsequent;
|
||||||
} else {
|
} else {
|
||||||
_propertyIDs.put(id, true);
|
|
||||||
|
|
||||||
if (to == NULL || timeline->getRTTI().isExactly(AttachmentTimeline::rtti) ||
|
if (to == NULL || timeline->getRTTI().isExactly(AttachmentTimeline::rtti) ||
|
||||||
timeline->getRTTI().isExactly(DrawOrderTimeline::rtti) ||
|
timeline->getRTTI().isExactly(DrawOrderTimeline::rtti) ||
|
||||||
timeline->getRTTI().isExactly(EventTimeline::rtti) || !to->_animation->hasTimeline(id)) {
|
timeline->getRTTI().isExactly(EventTimeline::rtti) || !to->_animation->hasTimeline(ids)) {
|
||||||
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) {
|
||||||
if (next->_animation->hasTimeline(id)) continue;
|
if (next->_animation->hasTimeline(ids)) continue;
|
||||||
if (next->_mixDuration > 0) {
|
if (next->_mixDuration > 0) {
|
||||||
timelineMode[i] = HoldMix;
|
timelineMode[i] = HoldMix;
|
||||||
timelineHoldMix[i] = next;
|
timelineHoldMix[i] = next;
|
||||||
|
|||||||
@ -67,7 +67,6 @@ void AttachmentTimeline::apply(Skeleton &skeleton, float lastTime, float time, V
|
|||||||
SP_UNUSED(pEvents);
|
SP_UNUSED(pEvents);
|
||||||
SP_UNUSED(alpha);
|
SP_UNUSED(alpha);
|
||||||
|
|
||||||
String *attachmentName;
|
|
||||||
Slot *slot = skeleton._slots[_slotIndex];
|
Slot *slot = skeleton._slots[_slotIndex];
|
||||||
if (!slot->_bone._active) return;
|
if (!slot->_bone._active) return;
|
||||||
|
|
||||||
@ -84,7 +83,6 @@ void AttachmentTimeline::apply(Skeleton &skeleton, float lastTime, float time, V
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t frameIndex;
|
|
||||||
if (time < _frames[0]) {
|
if (time < _frames[0]) {
|
||||||
if (blend == MixBlend_Setup || blend == MixBlend_First) setAttachment(skeleton, *slot, &slot->_data._attachmentName);
|
if (blend == MixBlend_Setup || blend == MixBlend_First) setAttachment(skeleton, *slot, &slot->_data._attachmentName);
|
||||||
return;
|
return;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user