Переглянути джерело

Added TrackEntry#shortestRotation.

Nathan Sweet 3 роки тому
батько
коміт
c21891835d

+ 20 - 8
spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/AnimationState.java

@@ -242,14 +242,15 @@ public class AnimationState {
 			} else {
 				int[] timelineMode = current.timelineMode.items;
 
-				boolean firstFrame = current.timelinesRotation.size != timelineCount << 1;
+				boolean shortestRotation = current.shortestRotation;
+				boolean firstFrame = !shortestRotation && current.timelinesRotation.size != timelineCount << 1;
 				if (firstFrame) current.timelinesRotation.setSize(timelineCount << 1);
 				float[] timelinesRotation = current.timelinesRotation.items;
 
 				for (int ii = 0; ii < timelineCount; ii++) {
 					Timeline timeline = (Timeline)timelines[ii];
 					MixBlend timelineBlend = timelineMode[ii] == SUBSEQUENT ? blend : MixBlend.setup;
-					if (timeline instanceof RotateTimeline) {
+					if (!shortestRotation && timeline instanceof RotateTimeline) {
 						applyRotateTimeline((RotateTimeline)timeline, skeleton, applyTime, mix, timelineBlend, timelinesRotation,
 							ii << 1, firstFrame);
 					} else if (timeline instanceof AttachmentTimeline)
@@ -315,7 +316,8 @@ public class AnimationState {
 			int[] timelineMode = from.timelineMode.items;
 			Object[] timelineHoldMix = from.timelineHoldMix.items;
 
-			boolean firstFrame = from.timelinesRotation.size != timelineCount << 1;
+			boolean shortestRotation = from.shortestRotation;
+			boolean firstFrame = !shortestRotation && from.timelinesRotation.size != timelineCount << 1;
 			if (firstFrame) from.timelinesRotation.setSize(timelineCount << 1);
 			float[] timelinesRotation = from.timelinesRotation.items;
 
@@ -350,7 +352,7 @@ public class AnimationState {
 					break;
 				}
 				from.totalAlpha += alpha;
-				if (timeline instanceof RotateTimeline) {
+				if (!shortestRotation && timeline instanceof RotateTimeline) {
 					applyRotateTimeline((RotateTimeline)timeline, skeleton, applyTime, alpha, timelineBlend, timelinesRotation, i << 1,
 						firstFrame);
 				} else if (timeline instanceof AttachmentTimeline)
@@ -871,7 +873,7 @@ public class AnimationState {
 		@Null TrackEntry previous, next, mixingFrom, mixingTo;
 		@Null AnimationStateListener listener;
 		int trackIndex;
-		boolean loop, holdPrevious, reverse;
+		boolean loop, holdPrevious, reverse, shortestRotation;
 		float eventThreshold, attachmentThreshold, drawOrderThreshold;
 		float animationStart, animationEnd, animationLast, nextAnimationLast;
 		float delay, trackTime, trackLast, nextTrackLast, trackEnd, timeScale;
@@ -1205,6 +1207,19 @@ public class AnimationState {
 			return holdPrevious;
 		}
 
+		public void setShortestRotation (boolean shortestRotation) {
+			this.shortestRotation = shortestRotation;
+		}
+
+		/** 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.
+		 * <p>
+		 * 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. */
+		public boolean getShortestRotation () {
+			return shortestRotation;
+		}
+
 		/** Resets the rotation directions for mixing this entry's rotate timelines. This can be useful to avoid bones rotating the
 		 * long way around when using {@link #alpha} and starting animations on other tracks.
 		 * <p>
@@ -1336,9 +1351,6 @@ public class AnimationState {
 	/** The interface to implement for receiving TrackEntry events. It is always safe to call AnimationState methods when receiving
 	 * events.
 	 * <p>
-	 * TrackEntry events are collected during {@link AnimationState#update(float)} and {@link AnimationState#apply(Skeleton)} and
-	 * fired only after those methods are finished.
-	 * <p>
 	 * See TrackEntry {@link TrackEntry#setListener(AnimationStateListener)} and AnimationState
 	 * {@link AnimationState#addListener(AnimationStateListener)}. */
 	static public interface AnimationStateListener {