[c][cpp] Port of shortestRotation, see #2027

This commit is contained in:
Mario Zechner 2022-02-02 12:02:43 +01:00
parent 9271eb239a
commit ffb9e75b09
4 changed files with 37 additions and 16 deletions

View File

@ -68,6 +68,7 @@ struct spTrackEntry {
int /*boolean*/ loop; int /*boolean*/ loop;
int /*boolean*/ holdPrevious; int /*boolean*/ holdPrevious;
int /*boolean*/ reverse; int /*boolean*/ reverse;
int /*boolean*/ shortestRotation;
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;

View File

@ -374,7 +374,7 @@ int spAnimationState_apply(spAnimationState *self, spSkeleton *skeleton) {
float animationLast, animationTime; float animationLast, animationTime;
int timelineCount; int timelineCount;
spTimeline **timelines; spTimeline **timelines;
int /*boolean*/ firstFrame; int /*boolean*/ firstFrame, shortestRotation;
float *timelinesRotation; float *timelinesRotation;
spTimeline *timeline; spTimeline *timeline;
int applied = 0; int applied = 0;
@ -427,14 +427,15 @@ int spAnimationState_apply(spAnimationState *self, spSkeleton *skeleton) {
} else { } else {
spIntArray *timelineMode = current->timelineMode; 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); if (firstFrame) _spAnimationState_resizeTimelinesRotation(current, timelineCount << 1);
timelinesRotation = current->timelinesRotation; timelinesRotation = current->timelinesRotation;
for (ii = 0; ii < timelineCount; ii++) { for (ii = 0; ii < timelineCount; ii++) {
timeline = timelines[ii]; timeline = timelines[ii];
timelineBlend = timelineMode->items[ii] == SUBSEQUENT ? blend : SP_MIX_BLEND_SETUP; 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, _spAnimationState_applyRotateTimeline(self, timeline, skeleton, applyTime, mix, timelineBlend,
timelinesRotation, ii << 1, firstFrame); timelinesRotation, ii << 1, firstFrame);
else if (timeline->propertyIds[0] == SP_PROPERTY_ATTACHMENT) else if (timeline->propertyIds[0] == SP_PROPERTY_ATTACHMENT)
@ -481,7 +482,7 @@ float _spAnimationState_applyMixingFrom(spAnimationState *self, spTrackEntry *to
float alphaHold; float alphaHold;
float alphaMix; float alphaMix;
float alpha; float alpha;
int /*boolean*/ firstFrame; int /*boolean*/ firstFrame, shortestRotation;
float *timelinesRotation; float *timelinesRotation;
int i; int i;
spTrackEntry *holdMix; spTrackEntry *holdMix;
@ -525,7 +526,8 @@ float _spAnimationState_applyMixingFrom(spAnimationState *self, spTrackEntry *to
timelineMode = from->timelineMode; timelineMode = from->timelineMode;
timelineHoldMix = from->timelineHoldMix; timelineHoldMix = from->timelineHoldMix;
firstFrame = from->timelinesRotationCount != timelineCount << 1; shortestRotation = from->shortestRotation;
firstFrame = !shortestRotation && from->timelinesRotationCount != timelineCount << 1;
if (firstFrame) _spAnimationState_resizeTimelinesRotation(from, timelineCount << 1); if (firstFrame) _spAnimationState_resizeTimelinesRotation(from, timelineCount << 1);
timelinesRotation = from->timelinesRotation; timelinesRotation = from->timelinesRotation;
@ -559,7 +561,7 @@ float _spAnimationState_applyMixingFrom(spAnimationState *self, spTrackEntry *to
break; break;
} }
from->totalAlpha += alpha; 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, _spAnimationState_applyRotateTimeline(self, timeline, skeleton, applyTime, alpha, timelineBlend,
timelinesRotation, i << 1, firstFrame); timelinesRotation, i << 1, firstFrame);
else if (timeline->propertyIds[0] == SP_PROPERTY_ATTACHMENT) else if (timeline->propertyIds[0] == SP_PROPERTY_ATTACHMENT)
@ -908,6 +910,7 @@ _spAnimationState_trackEntry(spAnimationState *self, int trackIndex, spAnimation
entry->loop = loop; entry->loop = loop;
entry->holdPrevious = 0; entry->holdPrevious = 0;
entry->reverse = 0; entry->reverse = 0;
entry->shortestRotation = 0;
entry->previous = 0; entry->previous = 0;
entry->next = 0; entry->next = 0;
@ -928,9 +931,10 @@ _spAnimationState_trackEntry(spAnimationState *self, int trackIndex, spAnimation
entry->timeScale = 1; entry->timeScale = 1;
entry->alpha = 1; entry->alpha = 1;
entry->interruptAlpha = 1;
entry->mixTime = 0; entry->mixTime = 0;
entry->mixDuration = !last ? 0 : spAnimationStateData_getMix(self->data, last->animation, animation); entry->mixDuration = !last ? 0 : spAnimationStateData_getMix(self->data, last->animation, animation);
entry->interruptAlpha = 1;
entry->totalAlpha = 0;
entry->mixBlend = SP_MIX_BLEND_REPLACE; entry->mixBlend = SP_MIX_BLEND_REPLACE;
entry->timelineMode = spIntArray_create(16); entry->timelineMode = spIntArray_create(16);

View File

@ -131,6 +131,10 @@ namespace spine {
void setReverse(bool inValue); 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 /// 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.
@ -275,7 +279,7 @@ namespace spine {
TrackEntry *_mixingTo; TrackEntry *_mixingTo;
int _trackIndex; int _trackIndex;
bool _loop, _holdPrevious, _reverse; bool _loop, _holdPrevious, _reverse, _shortestRotation;
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;

View File

@ -59,6 +59,7 @@ void dummyOnAnimationEventFunc(AnimationState *state, spine::EventType type, Tra
TrackEntry::TrackEntry() : _animation(NULL), _previous(NULL), _next(NULL), _mixingFrom(NULL), _mixingTo(0), TrackEntry::TrackEntry() : _animation(NULL), _previous(NULL), _next(NULL), _mixingFrom(NULL), _mixingTo(0),
_trackIndex(0), _loop(false), _holdPrevious(false), _reverse(false), _trackIndex(0), _loop(false), _holdPrevious(false), _reverse(false),
_shortestRotation(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),
@ -86,6 +87,10 @@ bool TrackEntry::getReverse() { return _reverse; }
void TrackEntry::setReverse(bool inValue) { _reverse = inValue; } void TrackEntry::setReverse(bool inValue) { _reverse = inValue; }
bool TrackEntry::getShortestRotation() { return _shortestRotation; }
void TrackEntry::setShortestRotation(bool inValue) { _shortestRotation = 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; }
@ -457,7 +462,8 @@ bool AnimationState::apply(Skeleton &skeleton) {
} else { } else {
Vector<int> &timelineMode = current._timelineMode; Vector<int> &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); if (firstFrame) current._timelinesRotation.setSize(timelines.size() << 1, 0);
Vector<float> &timelinesRotation = current._timelinesRotation; Vector<float> &timelinesRotation = current._timelinesRotation;
@ -467,7 +473,7 @@ 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 (!shortestRotation && timeline->getRTTI().isExactly(RotateTimeline::rtti))
applyRotateTimeline(static_cast<RotateTimeline *>(timeline), skeleton, applyTime, mix, applyRotateTimeline(static_cast<RotateTimeline *>(timeline), skeleton, applyTime, mix,
timelineBlend, timelinesRotation, ii << 1, firstFrame); timelineBlend, timelinesRotation, ii << 1, firstFrame);
else if (timeline->getRTTI().isExactly(AttachmentTimeline::rtti)) else if (timeline->getRTTI().isExactly(AttachmentTimeline::rtti))
@ -491,7 +497,8 @@ bool AnimationState::apply(Skeleton &skeleton) {
Slot *slot = slots[i]; Slot *slot = slots[i];
if (slot->getAttachmentState() == setupState) { if (slot->getAttachmentState() == setupState) {
const String &attachmentName = slot->getData().getAttachmentName(); 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; _unkeyedState += 2;
@ -816,7 +823,8 @@ float AnimationState::applyMixingFrom(TrackEntry *to, Skeleton &skeleton, MixBle
Vector<int> &timelineMode = from->_timelineMode; Vector<int> &timelineMode = from->_timelineMode;
Vector<TrackEntry *> &timelineHoldMix = from->_timelineHoldMix; Vector<TrackEntry *> &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); if (firstFrame) from->_timelinesRotation.setSize(timelines.size() << 1, 0);
Vector<float> &timelinesRotation = from->_timelinesRotation; Vector<float> &timelinesRotation = from->_timelinesRotation;
@ -852,7 +860,7 @@ float AnimationState::applyMixingFrom(TrackEntry *to, Skeleton &skeleton, MixBle
break; break;
} }
from->_totalAlpha += alpha; from->_totalAlpha += alpha;
if ((timeline->getRTTI().isExactly(RotateTimeline::rtti))) { if (!shortestRotation && (timeline->getRTTI().isExactly(RotateTimeline::rtti))) {
applyRotateTimeline((RotateTimeline *) timeline, skeleton, applyTime, alpha, timelineBlend, applyRotateTimeline((RotateTimeline *) timeline, skeleton, applyTime, alpha, timelineBlend,
timelinesRotation, i << 1, firstFrame); timelinesRotation, i << 1, firstFrame);
} else if (timeline->getRTTI().isExactly(AttachmentTimeline::rtti)) { } else if (timeline->getRTTI().isExactly(AttachmentTimeline::rtti)) {
@ -953,6 +961,9 @@ TrackEntry *AnimationState::newTrackEntry(size_t trackIndex, Animation *animatio
entry._loop = loop; entry._loop = loop;
entry._holdPrevious = 0; entry._holdPrevious = 0;
entry._reverse = false;
entry._shortestRotation = false;
entry._eventThreshold = 0; entry._eventThreshold = 0;
entry._attachmentThreshold = 0; entry._attachmentThreshold = 0;
entry._drawOrderThreshold = 0; entry._drawOrderThreshold = 0;
@ -970,9 +981,10 @@ TrackEntry *AnimationState::newTrackEntry(size_t trackIndex, Animation *animatio
entry._timeScale = 1; entry._timeScale = 1;
entry._alpha = 1; entry._alpha = 1;
entry._interruptAlpha = 1;
entry._mixTime = 0; entry._mixTime = 0;
entry._mixDuration = (last == NULL) ? 0 : _data->getMix(last->_animation, animation); entry._mixDuration = (last == NULL) ? 0 : _data->getMix(last->_animation, animation);
entry._interruptAlpha = 1;
entry._totalAlpha = 0;
entry._mixBlend = MixBlend_Replace; entry._mixBlend = MixBlend_Replace;
return entryP; return entryP;