Эх сурвалжийг харах

Merge branch '3.6' of https://github.com/esotericsoftware/spine-runtimes into 3.6

badlogic 8 жил өмнө
parent
commit
43f37ce565

+ 1 - 0
CHANGELOG.md

@@ -35,6 +35,7 @@
   * Removed `spBone_worldToLocalRotationX` and `spBone_worldToLocalRotationY`. Replaced by `spBone_worldToLocalRotation` (rotation given relative to x-axis, counter-clockwise, in degrees).
   * Replaced `r`, `g`, `b`, `a` fields with instances of new `spColor` struct in `spRegionAttachment`, `spMeshAttachment`, `spSkeleton`, `spSkeletonData`, `spSlot` and `spSlotData`.
   * Removed `spVertexIndex`from public API.
+  * Listeners on `spAnimationState` or `spTrackEntry` will now be also called in case a track entry is disposed as part of dispoing the `spAnimationState`.
  * **Additions**
   * Added support for local and relative transform constraint calculation, including additional fields in `spTransformConstraintData`.  
   * Added `spPointAttachment`, additional method `spAtlasAttachmentLoadeR_newPointAttachment`.

+ 1 - 1
spine-c/spine-c/include/spine/dll.h

@@ -45,4 +45,4 @@
 	#define SP_API SPINEPLUGIN_API
 #endif
 
-#endif /* SPINE_SHAREDLIB_H */
+#endif /* SPINE_SHAREDLIB_H */

+ 4 - 0
spine-c/spine-c/src/spine/AnimationState.c

@@ -193,9 +193,13 @@ void _spAnimationState_disposeTrackEntries (spAnimationState* state, spTrackEntr
 		spTrackEntry* from = entry->mixingFrom;
 		while (from) {
 			spTrackEntry* nextFrom = from->mixingFrom;
+			if (entry->listener) entry->listener(state, SP_ANIMATION_DISPOSE, from, 0);
+			if (state->listener) state->listener(state, SP_ANIMATION_DISPOSE, from, 0);
 			_spAnimationState_disposeTrackEntry(from);
 			from = nextFrom;
 		}
+		if (entry->listener) entry->listener(state, SP_ANIMATION_DISPOSE, entry, 0);
+		if (state->listener) state->listener(state, SP_ANIMATION_DISPOSE, entry, 0);
 		_spAnimationState_disposeTrackEntry(entry);
 		entry = next;
 	}

+ 4 - 4
spine-csharp/src/Animation.cs

@@ -436,11 +436,11 @@ namespace Spine {
 				}
 				// Mixing out uses sign of setup or current pose, else use sign of key.
 				if (direction == MixDirection.Out) {
-					x = Math.Abs(x) * Math.Sign(bx);
-					y = Math.Abs(y) * Math.Sign(by);
+					x = (x >= 0 ? x : -x) * (bx >= 0 ? 1 : -1);
+					y = (y >= 0 ? y : -y) * (by >= 0 ? 1 : -1);
 				} else {
-					bx = Math.Abs(bx) * Math.Sign(x);
-					by = Math.Abs(by) * Math.Sign(y);
+					bx = (bx >= 0 ? bx : -bx) * (x >= 0 ? 1 : -1);
+					by = (by >= 0 ? by : -by) * (y >= 0 ? 1 : -1);
 				}
 				bone.scaleX = bx + (x - bx) * alpha;
 				bone.scaleY = by + (y - by) * alpha;

+ 5 - 3
spine-libgdx/spine-libgdx/src/com/esotericsoftware/spine/SkeletonRenderer.java

@@ -100,7 +100,9 @@ public class SkeletonRenderer {
 				continue;
 
 			} else if (attachment instanceof MeshAttachment) {
-				throw new RuntimeException("SkeletonMeshRenderer is required to render meshes.");
+				throw new RuntimeException(
+					"SkeletonRenderer#draw(PolygonSpriteBatch, Skeleton) or #draw(TwoColorPolygonBatch, Skeleton) must be used to "
+						+ "render meshes.");
 
 			} else if (attachment instanceof SkeletonAttachment) {
 				Skeleton attachmentSkeleton = ((SkeletonAttachment)attachment).getSkeleton();
@@ -242,7 +244,7 @@ public class SkeletonRenderer {
 							tempLight.set(temp5);
 							tempDark.set(temp6);
 							tempUv.x = uvs[u];
-							tempUv.y = uvs[u + 1];							
+							tempUv.y = uvs[u + 1];
 							vertexEffect.transform(tempPos, tempUv, tempLight, tempDark);
 							vertices[v] = tempPos.x;
 							vertices[v + 1] = tempPos.y;
@@ -378,7 +380,7 @@ public class SkeletonRenderer {
 							tempLight.set(temp5);
 							tempDark.set(temp6);
 							tempUv.x = uvs[u];
-							tempUv.y = uvs[u + 1];				
+							tempUv.y = uvs[u + 1];
 							vertexEffect.transform(tempPos, tempUv, tempLight, tempDark);
 							vertices[v] = tempPos.x;
 							vertices[v + 1] = tempPos.y;

+ 2 - 2
spine-unity/Assets/spine-unity/Mesh Generation/SpineMesh.cs

@@ -265,7 +265,7 @@ namespace Spine.Unity {
 			bool hasSeparators = separatorCount > 0;
 
 			int clippingAttachmentSource = -1;
-			int lastPreActiveClipping = -1;
+			int lastPreActiveClipping = -1; // The index of the last slot that had an active ClippingAttachment.
 			SlotData clippingEndSlot = null;
 			int submeshIndex = 0;
 			var drawOrderItems = drawOrder.Items;
@@ -327,7 +327,7 @@ namespace Spine.Unity {
 				}
 
 				if (noRender) {
-					if (current.forceSeparate && generateMeshOverride && current.rawVertexCount > 0) {
+					if (current.forceSeparate && generateMeshOverride) { // && current.rawVertexCount > 0) {
 						{ // Add
 							current.endSlot = i;
 							current.preActiveClippingSlotSource = lastPreActiveClipping;

+ 4 - 2
spine-unity/Assets/spine-unity/Modules/Ghost/SkeletonGhost.cs

@@ -155,8 +155,10 @@ namespace Spine.Unity.Modules {
 		}
 
 		void OnDestroy () {
-			for (int i = 0; i < maximumGhosts; i++)
-				if (pool[i] != null) pool[i].Cleanup();
+			if (pool != null) {
+				for (int i = 0; i < maximumGhosts; i++)
+					if (pool[i] != null) pool[i].Cleanup();
+			}
 
 			foreach (var mat in materialTable.Values)
 				Destroy(mat);

+ 67 - 19
spine-unity/Assets/spine-unity/SkeletonAnimator.cs

@@ -36,7 +36,7 @@ using System.Collections.Generic;
 namespace Spine.Unity {
 	[RequireComponent(typeof(Animator))]
 	public class SkeletonAnimator : SkeletonRenderer, ISkeletonAnimation {
-		
+
 		[SerializeField] protected MecanimTranslator translator;
 		public MecanimTranslator Translator { get { return translator; } }
 
@@ -108,9 +108,13 @@ namespace Spine.Unity {
 
 			public enum MixMode { AlwaysMix, MixNext, SpineStyle }
 
-			readonly Dictionary<int, Spine.Animation> animationTable = new Dictionary<int, Spine.Animation>();
-			readonly Dictionary<AnimationClip, int> clipNameHashCodeTable = new Dictionary<AnimationClip, int>();
+			readonly Dictionary<int, Spine.Animation> animationTable = new Dictionary<int, Spine.Animation>(IntEqualityComparer.Instance);
+			readonly Dictionary<AnimationClip, int> clipNameHashCodeTable = new Dictionary<AnimationClip, int>(AnimationClipEqualityComparer.Instance);
 			readonly List<Animation> previousAnimations = new List<Animation>();
+			#if UNITY_2017_1_OR_NEWER
+			readonly List<AnimatorClipInfo> clipInfoCache = new List<AnimatorClipInfo>();
+			readonly List<AnimatorClipInfo> nextClipInfoCache = new List<AnimatorClipInfo>();
+			#endif
 			Animator animator;
 
 			public Animator Animator { get { return this.animator; } }
@@ -144,16 +148,19 @@ namespace Spine.Unity {
 						AnimatorStateInfo nextStateInfo = animator.GetNextAnimatorStateInfo(layer);
 
 						bool hasNext = nextStateInfo.fullPathHash != 0;
-						AnimatorClipInfo[] clipInfo = animator.GetCurrentAnimatorClipInfo(layer);
-						AnimatorClipInfo[] nextClipInfo = animator.GetNextAnimatorClipInfo(layer);
 
-						for (int c = 0; c < clipInfo.Length; c++) {
+						int clipInfoCount, nextClipInfoCount;
+						IList<AnimatorClipInfo> clipInfo, nextClipInfo;
+						GetAnimatorClipInfos(layer, out clipInfoCount, out nextClipInfoCount, out clipInfo, out nextClipInfo);
+
+						for (int c = 0; c < clipInfoCount; c++) {
 							var info = clipInfo[c];
 							float weight = info.weight * layerWeight; if (weight == 0) continue;
 							previousAnimations.Add(animationTable[NameHashCode(info.clip)]);
 						}
+
 						if (hasNext) {
-							for (int c = 0; c < nextClipInfo.Length; c++) {
+							for (int c = 0; c < nextClipInfoCount; c++) {
 								var info = nextClipInfo[c];
 								float weight = info.weight * layerWeight; if (weight == 0) continue;
 								previousAnimations.Add(animationTable[NameHashCode(info.clip)]);
@@ -169,22 +176,20 @@ namespace Spine.Unity {
 					AnimatorStateInfo nextStateInfo = animator.GetNextAnimatorStateInfo(layer);
 
 					bool hasNext = nextStateInfo.fullPathHash != 0;
-					AnimatorClipInfo[] clipInfo = animator.GetCurrentAnimatorClipInfo(layer);
-					AnimatorClipInfo[] nextClipInfo = animator.GetNextAnimatorClipInfo(layer);
-					//UNITY 4
-					//bool hasNext = nextStateInfo.nameHash != 0;
-					//var clipInfo = animator.GetCurrentAnimationClipState(i);
-					//var nextClipInfo = animator.GetNextAnimationClipState(i);
+
+					int clipInfoCount, nextClipInfoCount;
+					IList<AnimatorClipInfo> clipInfo, nextClipInfo;
+					GetAnimatorClipInfos(layer, out clipInfoCount, out nextClipInfoCount, out clipInfo, out nextClipInfo);
 
 					MixMode mode = layerMixModes[layer];
 					if (mode == MixMode.AlwaysMix) {
 						// Always use Mix instead of Applying the first non-zero weighted clip.
-						for (int c = 0; c < clipInfo.Length; c++) {
+						for (int c = 0; c < clipInfoCount; c++) {
 							var info = clipInfo[c];	float weight = info.weight * layerWeight; if (weight == 0) continue;
 							animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed < 0), stateInfo.loop, null, weight, MixPose.Current, MixDirection.In);
 						}
 						if (hasNext) {
-							for (int c = 0; c < nextClipInfo.Length; c++) {
+							for (int c = 0; c < nextClipInfoCount; c++) {
 								var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
 								animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime , info.clip.length,nextStateInfo.speed < 0), nextStateInfo.loop, null, weight, MixPose.Current, MixDirection.In);
 							}
@@ -192,13 +197,13 @@ namespace Spine.Unity {
 					} else { // case MixNext || SpineStyle
 						// Apply first non-zero weighted clip
 						int c = 0;
-						for (; c < clipInfo.Length; c++) {
+						for (; c < clipInfoCount; c++) {
 							var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
 							animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed < 0), stateInfo.loop, null, 1f, MixPose.Current, MixDirection.In);
 							break;
 						}
 						// Mix the rest
-						for (; c < clipInfo.Length; c++) {
+						for (; c < clipInfoCount; c++) {
 							var info = clipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
 							animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(stateInfo.normalizedTime, info.clip.length, stateInfo.loop, stateInfo.speed < 0), stateInfo.loop, null, weight, MixPose.Current, MixDirection.In);
 						}
@@ -207,14 +212,14 @@ namespace Spine.Unity {
 						if (hasNext) {
 							// Apply next clip directly instead of mixing (ie: no crossfade, ignores mecanim transition weights)
 							if (mode == MixMode.SpineStyle) {
-								for (; c < nextClipInfo.Length; c++) {
+								for (; c < nextClipInfoCount; c++) {
 									var info = nextClipInfo[c]; float weight = info.weight * layerWeight; if (weight == 0) continue;
 									animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime , info.clip.length,nextStateInfo.speed < 0), nextStateInfo.loop, null, 1f, MixPose.Current, MixDirection.In);
 									break;
 								}
 							}
 							// Mix the rest
-							for (; c < nextClipInfo.Length; c++) {
+							for (; c < nextClipInfoCount; c++) {
 								var info = nextClipInfo[c];	float weight = info.weight * layerWeight; if (weight == 0) continue;
 								animationTable[NameHashCode(info.clip)].Apply(skeleton, 0, AnimationTime(nextStateInfo.normalizedTime , info.clip.length,nextStateInfo.speed < 0), nextStateInfo.loop, null, weight, MixPose.Current, MixDirection.In);
 							}
@@ -239,6 +244,31 @@ namespace Spine.Unity {
 				return normalizedTime * clipLength;
 			}
 
+			void GetAnimatorClipInfos (
+				int layer,
+				out int clipInfoCount,
+				out int nextClipInfoCount,
+				out IList<AnimatorClipInfo> clipInfo,
+				out IList<AnimatorClipInfo> nextClipInfo) {
+				#if UNITY_2017_1_OR_NEWER
+				clipInfoCount = animator.GetCurrentAnimatorClipInfoCount(layer);
+				nextClipInfoCount = animator.GetNextAnimatorClipInfoCount(layer);
+				if (clipInfoCache.Capacity < clipInfoCount) clipInfoCache.Capacity = clipInfoCount;
+				if (nextClipInfoCache.Capacity < nextClipInfoCount) nextClipInfoCache.Capacity = nextClipInfoCount;
+				animator.GetCurrentAnimatorClipInfo(layer, clipInfoCache);
+				animator.GetNextAnimatorClipInfo(layer, nextClipInfoCache);
+
+				clipInfo = clipInfoCache;
+				nextClipInfo = nextClipInfoCache;
+				#else
+				clipInfo = animator.GetCurrentAnimatorClipInfo(layer);
+				nextClipInfo = animator.GetNextAnimatorClipInfo(layer);
+
+				clipInfoCount = clipInfo.Count;
+				nextClipInfoCount = nextClipInfo.Count;
+				#endif
+			}
+
 			int NameHashCode (AnimationClip clip) {
 				int clipNameHashCode;
 				if (!clipNameHashCodeTable.TryGetValue(clip, out clipNameHashCode)) {
@@ -247,6 +277,24 @@ namespace Spine.Unity {
 				}
 				return clipNameHashCode;
 			}
+
+			class AnimationClipEqualityComparer : IEqualityComparer<AnimationClip> {
+				internal static readonly IEqualityComparer<AnimationClip> Instance = new AnimationClipEqualityComparer();
+
+				public bool Equals (AnimationClip x, AnimationClip y) {
+					return x.GetInstanceID() == y.GetInstanceID();
+				}
+
+				public int GetHashCode (AnimationClip o) {
+					return o.GetInstanceID();
+				}
+			}
+
+			class IntEqualityComparer : IEqualityComparer<int> {
+				internal static readonly IEqualityComparer<int> Instance = new IntEqualityComparer();
+				public bool Equals (int x, int y) { return x == y; }
+				public int GetHashCode(int o) { return o; }
+			}
 		}
 
 	}