diff --git a/spine-c/spine-c/include/spine/AnimationState.h b/spine-c/spine-c/include/spine/AnimationState.h index 2fc32fedd..fbbed376d 100644 --- a/spine-c/spine-c/include/spine/AnimationState.h +++ b/spine-c/spine-c/include/spine/AnimationState.h @@ -68,6 +68,7 @@ struct spTrackEntry { int /*boolean*/ loop; int /*boolean*/ holdPrevious; int /*boolean*/ reverse; + int /*boolean*/ shortestRotation; float eventThreshold, attachmentThreshold, drawOrderThreshold; float animationStart, animationEnd, animationLast, nextAnimationLast; float delay, trackTime, trackLast, nextTrackLast, trackEnd, timeScale; diff --git a/spine-c/spine-c/src/spine/AnimationState.c b/spine-c/spine-c/src/spine/AnimationState.c index 5d5d7283b..72703d95d 100644 --- a/spine-c/spine-c/src/spine/AnimationState.c +++ b/spine-c/spine-c/src/spine/AnimationState.c @@ -374,7 +374,7 @@ int spAnimationState_apply(spAnimationState *self, spSkeleton *skeleton) { float animationLast, animationTime; int timelineCount; spTimeline **timelines; - int /*boolean*/ firstFrame; + int /*boolean*/ firstFrame, shortestRotation; float *timelinesRotation; spTimeline *timeline; int applied = 0; @@ -427,14 +427,15 @@ int spAnimationState_apply(spAnimationState *self, spSkeleton *skeleton) { } else { spIntArray *timelineMode = current->timelineMode; - firstFrame = current->timelinesRotationCount != timelineCount << 1; + shortestRotation = current->shortestRotation; + firstFrame = !shortestRotation && current->timelinesRotationCount != timelineCount << 1; if (firstFrame) _spAnimationState_resizeTimelinesRotation(current, timelineCount << 1); timelinesRotation = current->timelinesRotation; for (ii = 0; ii < timelineCount; ii++) { timeline = timelines[ii]; timelineBlend = timelineMode->items[ii] == SUBSEQUENT ? blend : SP_MIX_BLEND_SETUP; - if (timeline->propertyIds[0] == SP_PROPERTY_ROTATE) + if (!shortestRotation && timeline->propertyIds[0] == SP_PROPERTY_ROTATE) _spAnimationState_applyRotateTimeline(self, timeline, skeleton, applyTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame); else if (timeline->propertyIds[0] == SP_PROPERTY_ATTACHMENT) @@ -481,7 +482,7 @@ float _spAnimationState_applyMixingFrom(spAnimationState *self, spTrackEntry *to float alphaHold; float alphaMix; float alpha; - int /*boolean*/ firstFrame; + int /*boolean*/ firstFrame, shortestRotation; float *timelinesRotation; int i; spTrackEntry *holdMix; @@ -525,7 +526,8 @@ float _spAnimationState_applyMixingFrom(spAnimationState *self, spTrackEntry *to timelineMode = from->timelineMode; timelineHoldMix = from->timelineHoldMix; - firstFrame = from->timelinesRotationCount != timelineCount << 1; + shortestRotation = from->shortestRotation; + firstFrame = !shortestRotation && from->timelinesRotationCount != timelineCount << 1; if (firstFrame) _spAnimationState_resizeTimelinesRotation(from, timelineCount << 1); timelinesRotation = from->timelinesRotation; @@ -559,7 +561,7 @@ float _spAnimationState_applyMixingFrom(spAnimationState *self, spTrackEntry *to break; } from->totalAlpha += alpha; - if (timeline->propertyIds[0] == SP_PROPERTY_ROTATE) + if (!shortestRotation && timeline->propertyIds[0] == SP_PROPERTY_ROTATE) _spAnimationState_applyRotateTimeline(self, timeline, skeleton, applyTime, alpha, timelineBlend, timelinesRotation, i << 1, firstFrame); else if (timeline->propertyIds[0] == SP_PROPERTY_ATTACHMENT) @@ -908,6 +910,7 @@ _spAnimationState_trackEntry(spAnimationState *self, int trackIndex, spAnimation entry->loop = loop; entry->holdPrevious = 0; entry->reverse = 0; + entry->shortestRotation = 0; entry->previous = 0; entry->next = 0; @@ -928,9 +931,10 @@ _spAnimationState_trackEntry(spAnimationState *self, int trackIndex, spAnimation entry->timeScale = 1; entry->alpha = 1; - entry->interruptAlpha = 1; entry->mixTime = 0; entry->mixDuration = !last ? 0 : spAnimationStateData_getMix(self->data, last->animation, animation); + entry->interruptAlpha = 1; + entry->totalAlpha = 0; entry->mixBlend = SP_MIX_BLEND_REPLACE; entry->timelineMode = spIntArray_create(16); diff --git a/spine-cpp/spine-cpp/include/spine/AnimationState.h b/spine-cpp/spine-cpp/include/spine/AnimationState.h index dc9410021..c8c5a7937 100644 --- a/spine-cpp/spine-cpp/include/spine/AnimationState.h +++ b/spine-cpp/spine-cpp/include/spine/AnimationState.h @@ -131,6 +131,10 @@ namespace spine { void setReverse(bool inValue); + bool getShortestRotation(); + + void setShortestRotation(bool inValue); + /// 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 /// track entry will become the current track entry. @@ -275,7 +279,7 @@ namespace spine { TrackEntry *_mixingTo; int _trackIndex; - bool _loop, _holdPrevious, _reverse; + bool _loop, _holdPrevious, _reverse, _shortestRotation; float _eventThreshold, _attachmentThreshold, _drawOrderThreshold; float _animationStart, _animationEnd, _animationLast, _nextAnimationLast; float _delay, _trackTime, _trackLast, _nextTrackLast, _trackEnd, _timeScale; diff --git a/spine-cpp/spine-cpp/src/spine/AnimationState.cpp b/spine-cpp/spine-cpp/src/spine/AnimationState.cpp index e24975e1c..4d0eb4479 100644 --- a/spine-cpp/spine-cpp/src/spine/AnimationState.cpp +++ b/spine-cpp/spine-cpp/src/spine/AnimationState.cpp @@ -59,6 +59,7 @@ void dummyOnAnimationEventFunc(AnimationState *state, spine::EventType type, Tra TrackEntry::TrackEntry() : _animation(NULL), _previous(NULL), _next(NULL), _mixingFrom(NULL), _mixingTo(0), _trackIndex(0), _loop(false), _holdPrevious(false), _reverse(false), + _shortestRotation(false), _eventThreshold(0), _attachmentThreshold(0), _drawOrderThreshold(0), _animationStart(0), _animationEnd(0), _animationLast(0), _nextAnimationLast(0), _delay(0), _trackTime(0), _trackLast(0), _nextTrackLast(0), _trackEnd(0), _timeScale(1.0f), _alpha(0), _mixTime(0), @@ -86,6 +87,10 @@ bool TrackEntry::getReverse() { return _reverse; } void TrackEntry::setReverse(bool inValue) { _reverse = inValue; } +bool TrackEntry::getShortestRotation() { return _shortestRotation; } + +void TrackEntry::setShortestRotation(bool inValue) { _shortestRotation = inValue; } + float TrackEntry::getDelay() { return _delay; } void TrackEntry::setDelay(float inValue) { _delay = inValue; } @@ -211,7 +216,7 @@ EventQueueEntry::EventQueueEntry(EventType eventType, TrackEntry *trackEntry, Ev } EventQueue *EventQueue::newEventQueue(AnimationState &state, Pool &trackEntryPool) { - return new (__FILE__, __LINE__) EventQueue(state, trackEntryPool); + return new(__FILE__, __LINE__) EventQueue(state, trackEntryPool); } EventQueueEntry EventQueue::newEventQueueEntry(EventType eventType, TrackEntry *entry, Event *event) { @@ -457,7 +462,8 @@ bool AnimationState::apply(Skeleton &skeleton) { } else { Vector &timelineMode = current._timelineMode; - bool firstFrame = current._timelinesRotation.size() != timelines.size() << 1; + bool shortestRotation = current._shortestRotation; + bool firstFrame = !shortestRotation && current._timelinesRotation.size() != timelines.size() << 1; if (firstFrame) current._timelinesRotation.setSize(timelines.size() << 1, 0); Vector &timelinesRotation = current._timelinesRotation; @@ -467,7 +473,7 @@ bool AnimationState::apply(Skeleton &skeleton) { MixBlend timelineBlend = timelineMode[ii] == Subsequent ? blend : MixBlend_Setup; - if (timeline->getRTTI().isExactly(RotateTimeline::rtti)) + if (!shortestRotation && timeline->getRTTI().isExactly(RotateTimeline::rtti)) applyRotateTimeline(static_cast(timeline), skeleton, applyTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame); else if (timeline->getRTTI().isExactly(AttachmentTimeline::rtti)) @@ -491,7 +497,8 @@ bool AnimationState::apply(Skeleton &skeleton) { Slot *slot = slots[i]; if (slot->getAttachmentState() == setupState) { const String &attachmentName = slot->getData().getAttachmentName(); - slot->setAttachment(attachmentName.isEmpty() ? NULL : skeleton.getAttachment(slot->getData().getIndex(), attachmentName)); + slot->setAttachment(attachmentName.isEmpty() ? NULL : skeleton.getAttachment(slot->getData().getIndex(), + attachmentName)); } } _unkeyedState += 2; @@ -816,7 +823,8 @@ float AnimationState::applyMixingFrom(TrackEntry *to, Skeleton &skeleton, MixBle Vector &timelineMode = from->_timelineMode; Vector &timelineHoldMix = from->_timelineHoldMix; - bool firstFrame = from->_timelinesRotation.size() != timelines.size() << 1; + bool shortestRotation = from->_shortestRotation; + bool firstFrame = !shortestRotation && from->_timelinesRotation.size() != timelines.size() << 1; if (firstFrame) from->_timelinesRotation.setSize(timelines.size() << 1, 0); Vector &timelinesRotation = from->_timelinesRotation; @@ -852,7 +860,7 @@ float AnimationState::applyMixingFrom(TrackEntry *to, Skeleton &skeleton, MixBle break; } from->_totalAlpha += alpha; - if ((timeline->getRTTI().isExactly(RotateTimeline::rtti))) { + if (!shortestRotation && (timeline->getRTTI().isExactly(RotateTimeline::rtti))) { applyRotateTimeline((RotateTimeline *) timeline, skeleton, applyTime, alpha, timelineBlend, timelinesRotation, i << 1, firstFrame); } else if (timeline->getRTTI().isExactly(AttachmentTimeline::rtti)) { @@ -953,6 +961,9 @@ TrackEntry *AnimationState::newTrackEntry(size_t trackIndex, Animation *animatio entry._loop = loop; entry._holdPrevious = 0; + entry._reverse = false; + entry._shortestRotation = false; + entry._eventThreshold = 0; entry._attachmentThreshold = 0; entry._drawOrderThreshold = 0; @@ -970,9 +981,10 @@ TrackEntry *AnimationState::newTrackEntry(size_t trackIndex, Animation *animatio entry._timeScale = 1; entry._alpha = 1; - entry._interruptAlpha = 1; entry._mixTime = 0; entry._mixDuration = (last == NULL) ? 0 : _data->getMix(last->_animation, animation); + entry._interruptAlpha = 1; + entry._totalAlpha = 0; entry._mixBlend = MixBlend_Replace; return entryP; @@ -1024,7 +1036,7 @@ void AnimationState::computeHold(TrackEntry *entry) { // outer: size_t i = 0; -continue_outer: + continue_outer: for (; i < timelinesCount; ++i) { Timeline *timeline = timelines[i]; Vector &ids = timeline->getPropertyIds();