|
@@ -268,7 +268,8 @@ namespace Spine {
|
|
|
} else {
|
|
|
int[] timelineMode = current.timelineMode.Items;
|
|
|
|
|
|
- bool firstFrame = current.timelinesRotation.Count != timelineCount << 1;
|
|
|
+ bool shortestRotation = current.shortestRotation;
|
|
|
+ bool firstFrame = !shortestRotation && current.timelinesRotation.Count != timelineCount << 1;
|
|
|
if (firstFrame) current.timelinesRotation.Resize(timelineCount << 1);
|
|
|
float[] timelinesRotation = current.timelinesRotation.Items;
|
|
|
|
|
@@ -276,7 +277,7 @@ namespace Spine {
|
|
|
Timeline timeline = timelines[ii];
|
|
|
MixBlend timelineBlend = timelineMode[ii] == AnimationState.Subsequent ? blend : MixBlend.Setup;
|
|
|
var rotateTimeline = timeline as RotateTimeline;
|
|
|
- if (rotateTimeline != null)
|
|
|
+ if (!shortestRotation && rotateTimeline != null)
|
|
|
ApplyRotateTimeline(rotateTimeline, skeleton, applyTime, mix, timelineBlend, timelinesRotation,
|
|
|
ii << 1, firstFrame);
|
|
|
else if (timeline is AttachmentTimeline)
|
|
@@ -383,7 +384,8 @@ namespace Spine {
|
|
|
int[] timelineMode = from.timelineMode.Items;
|
|
|
TrackEntry[] timelineHoldMix = from.timelineHoldMix.Items;
|
|
|
|
|
|
- bool firstFrame = from.timelinesRotation.Count != timelineCount << 1;
|
|
|
+ bool shortestRotation = from.shortestRotation;
|
|
|
+ bool firstFrame = !shortestRotation && from.timelinesRotation.Count != timelineCount << 1;
|
|
|
if (firstFrame) from.timelinesRotation.Resize(timelineCount << 1);
|
|
|
float[] timelinesRotation = from.timelinesRotation.Items;
|
|
|
|
|
@@ -419,7 +421,7 @@ namespace Spine {
|
|
|
}
|
|
|
from.totalAlpha += alpha;
|
|
|
var rotateTimeline = timeline as RotateTimeline;
|
|
|
- if (rotateTimeline != null) {
|
|
|
+ if (!shortestRotation && rotateTimeline != null) {
|
|
|
ApplyRotateTimeline(rotateTimeline, skeleton, applyTime, alpha, timelineBlend, timelinesRotation, i << 1,
|
|
|
firstFrame);
|
|
|
} else if (timeline is AttachmentTimeline) {
|
|
@@ -990,7 +992,7 @@ namespace Spine {
|
|
|
|
|
|
internal int trackIndex;
|
|
|
|
|
|
- internal bool loop, holdPrevious, reverse;
|
|
|
+ internal bool loop, holdPrevious, reverse, shortestRotation;
|
|
|
internal float eventThreshold, attachmentThreshold, drawOrderThreshold;
|
|
|
internal float animationStart, animationEnd, animationLast, nextAnimationLast;
|
|
|
internal float delay, trackTime, trackLast, nextTrackLast, trackEnd, timeScale = 1f;
|
|
@@ -1257,6 +1259,14 @@ namespace Spine {
|
|
|
/// If true, the animation will be applied in reverse. Events are not fired when an animation is applied in reverse.</summary>
|
|
|
public bool Reverse { get { return reverse; } set { reverse = value; } }
|
|
|
|
|
|
+ /// <summary><para>
|
|
|
+ /// If true, mixing rotation between tracks always uses the shortest rotation direction. If the rotation is animated, the
|
|
|
+ /// shortest rotation direction may change during the mix.
|
|
|
+ /// </para><para>
|
|
|
+ /// If false, the shortest rotation direction is remembered when the mix starts and the same direction is used for the rest
|
|
|
+ /// of the mix. Defaults to false.</para></summary>
|
|
|
+ public bool ShortestRotation { get { return shortestRotation; } set { shortestRotation = value; } }
|
|
|
+
|
|
|
/// <summary>Returns true if this entry is for the empty animation. See <see cref="AnimationState.SetEmptyAnimation(int, float)"/>,
|
|
|
/// <see cref="AnimationState.AddEmptyAnimation(int, float, float)"/>, and <see cref="AnimationState.SetEmptyAnimations(float)"/>.
|
|
|
public bool IsEmptyAnimation { get { return animation == AnimationState.EmptyAnimation; } }
|