[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*/ holdPrevious;
int /*boolean*/ reverse;
int /*boolean*/ shortestRotation;
float eventThreshold, attachmentThreshold, drawOrderThreshold;
float animationStart, animationEnd, animationLast, nextAnimationLast;
float delay, trackTime, trackLast, nextTrackLast, trackEnd, timeScale;

View File

@ -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);

View File

@ -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;

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),
_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<TrackEntry> &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<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);
Vector<float> &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<RotateTimeline *>(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<int> &timelineMode = from->_timelineMode;
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);
Vector<float> &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<PropertyId> &ids = timeline->getPropertyIds();