소스 검색

[unity] Fixed prefab baking ignoring separated timelines. Closes #2035.

Harald Csaszar 3 년 전
부모
커밋
a4e7654bc5
1개의 변경된 파일212개의 추가작업 그리고 6개의 파일을 삭제
  1. 212 6
      spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBaker.cs

+ 212 - 6
spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBaker.cs

@@ -782,8 +782,16 @@ namespace Spine.Unity.Editor {
 
 				if (t is ScaleTimeline) {
 					ParseScaleTimeline(skeleton, (ScaleTimeline)t, clip);
+				} else if (t is ScaleXTimeline) {
+					ParseSingleSplitScaleTimeline(skeleton, (ScaleXTimeline)t, null, clip);
+				} else if (t is ScaleYTimeline) {
+					ParseSingleSplitScaleTimeline(skeleton, null, (ScaleYTimeline)t, clip);
 				} else if (t is TranslateTimeline) {
 					ParseTranslateTimeline(skeleton, (TranslateTimeline)t, clip);
+				} else if (t is TranslateXTimeline) {
+					ParseSingleSplitTranslateTimeline(skeleton, (TranslateXTimeline)t, null, clip);
+				} else if (t is TranslateYTimeline) {
+					ParseSingleSplitTranslateTimeline(skeleton, null, (TranslateYTimeline)t, clip);
 				} else if (t is RotateTimeline) {
 					//bypass any rotation keys if they're going to get baked anyway to prevent localEulerAngles vs Baked collision
 					if (ignoreRotateTimelineIndexes.Contains(((RotateTimeline)t).BoneIndex) == false)
@@ -895,7 +903,7 @@ namespace Spine.Unity.Editor {
 			AnimationCurve yCurve = new AnimationCurve();
 			AnimationCurve zCurve = new AnimationCurve();
 
-			float endTime = timeline.Frames[(timeline.FrameCount * 3) - 3];
+			float endTime = timeline.Frames[(timeline.FrameCount * TranslateTimeline.ENTRIES) - TranslateTimeline.ENTRIES];
 
 			float currentTime = timeline.Frames[0];
 
@@ -907,7 +915,7 @@ namespace Spine.Unity.Editor {
 
 			int listIndex = 1;
 			int frameIndex = 1;
-			int f = 3;
+			int f = TranslateTimeline.ENTRIES;
 			float[] frames = timeline.Frames;
 			skeleton.SetToSetupPose();
 			float lastTime = 0;
@@ -1006,7 +1014,7 @@ namespace Spine.Unity.Editor {
 				}
 
 				frameIndex++;
-				f += 3;
+				f += TranslateTimeline.ENTRIES;
 			}
 
 			xCurve = EnsureCurveKeyCount(new AnimationCurve(xKeys.ToArray()));
@@ -1022,6 +1030,107 @@ namespace Spine.Unity.Editor {
 			clip.SetCurve(path, typeof(Transform), propertyName + ".z", zCurve);
 		}
 
+		/// <summary>Parses a single TranslateXTimeline or TranslateYTimeline.
+		/// Only one of <c>timelineX</c> or <c>timelineY</c> shall be filled out, the other must be null.</summary>
+		static void ParseSingleSplitTranslateTimeline (Skeleton skeleton,
+			TranslateXTimeline timelineX, TranslateYTimeline timelineY, AnimationClip clip) {
+
+			bool isXTimeline = timelineX != null;
+			CurveTimeline1 timeline = isXTimeline ? timelineX : timelineY as CurveTimeline1;
+			IBoneTimeline boneTimeline = isXTimeline ? timelineX : timelineY as IBoneTimeline;
+
+			var boneData = skeleton.Data.Bones.Items[boneTimeline.BoneIndex];
+			var bone = skeleton.Bones.Items[boneTimeline.BoneIndex];
+			float boneDataOffset = isXTimeline ? boneData.X : boneData.Y;
+
+			AnimationCurve curve = new AnimationCurve();
+			float endTime = timeline.Frames[(timeline.FrameCount * TranslateXTimeline.ENTRIES) - TranslateXTimeline.ENTRIES];
+			float currentTime = timeline.Frames[0];
+			List<Keyframe> keys = new List<Keyframe>();
+			keys.Add(new Keyframe(timeline.Frames[0], timeline.Frames[1] + boneDataOffset, 0, 0));
+
+			int listIndex = 1;
+			int frameIndex = 1;
+			int f = TranslateXTimeline.ENTRIES;
+			float[] frames = timeline.Frames;
+			skeleton.SetToSetupPose();
+			float lastTime = 0;
+			while (currentTime < endTime) {
+				int pIndex = listIndex - 1;
+
+				float curveType = timeline.GetCurveType(frameIndex - 1);
+				if (curveType == 0) {
+					//linear
+					Keyframe p = keys[pIndex];
+
+					float time = frames[f];
+					float value = frames[f + 1] + boneDataOffset;
+					float valueOut = (value - p.value) / (time - p.time);
+					p.outTangent = valueOut;
+					keys.Add(new Keyframe(time, value, valueOut, 0));
+
+					keys[pIndex] = p;
+					currentTime = time;
+					timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixBlend.Setup, MixDirection.In);
+
+					lastTime = time;
+					listIndex++;
+				} else if (curveType == 1) {
+					//stepped
+					Keyframe p = keys[pIndex];
+
+					float time = frames[f];
+					float value = frames[f + 1] + boneDataOffset;
+					float valueOut = float.PositiveInfinity;
+					p.outTangent = valueOut;
+					keys.Add(new Keyframe(time, value, valueOut, 0));
+
+					keys[pIndex] = p;
+					currentTime = time;
+					timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixBlend.Setup, MixDirection.In);
+
+					lastTime = time;
+					listIndex++;
+				} else {
+					//bezier
+					Keyframe p = keys[pIndex];
+
+					float time = frames[f];
+
+					int steps = Mathf.FloorToInt((time - p.time) / BakeIncrement);
+
+					for (int i = 1; i <= steps; i++) {
+						currentTime += BakeIncrement;
+						if (i == steps)
+							currentTime = time;
+
+						timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixBlend.Setup, MixDirection.In);
+
+						p = keys[listIndex - 1];
+						float boneOffset = isXTimeline ? bone.X : bone.Y;
+						float valueOut = (boneOffset - p.value) / (currentTime - p.time);
+						p.outTangent = valueOut;
+						keys.Add(new Keyframe(currentTime, boneOffset, valueOut, 0));
+
+						keys[listIndex - 1] = p;
+
+						listIndex++;
+						lastTime = currentTime;
+					}
+				}
+
+				frameIndex++;
+				f += TranslateXTimeline.ENTRIES;
+			}
+
+			curve = EnsureCurveKeyCount(new AnimationCurve(keys.ToArray()));
+
+			string path = GetPath(boneData);
+			const string propertyName = "localPosition";
+
+			clip.SetCurve(path, typeof(Transform), propertyName + (isXTimeline ? ".x" : ".y"), curve);
+		}
+
 		static void ParseScaleTimeline (Skeleton skeleton, ScaleTimeline timeline, AnimationClip clip) {
 			var boneData = skeleton.Data.Bones.Items[timeline.BoneIndex];
 			var bone = skeleton.Bones.Items[timeline.BoneIndex];
@@ -1030,7 +1139,7 @@ namespace Spine.Unity.Editor {
 			AnimationCurve yCurve = new AnimationCurve();
 			AnimationCurve zCurve = new AnimationCurve();
 
-			float endTime = timeline.Frames[(timeline.FrameCount * 3) - 3];
+			float endTime = timeline.Frames[(timeline.FrameCount * ScaleTimeline.ENTRIES) - ScaleTimeline.ENTRIES];
 
 			float currentTime = timeline.Frames[0];
 
@@ -1042,7 +1151,7 @@ namespace Spine.Unity.Editor {
 
 			int listIndex = 1;
 			int frameIndex = 1;
-			int f = 3;
+			int f = ScaleTimeline.ENTRIES;
 			float[] frames = timeline.Frames;
 			skeleton.SetToSetupPose();
 			float lastTime = 0;
@@ -1140,7 +1249,7 @@ namespace Spine.Unity.Editor {
 				}
 
 				frameIndex++;
-				f += 3;
+				f += ScaleTimeline.ENTRIES;
 			}
 
 			xCurve = EnsureCurveKeyCount(new AnimationCurve(xKeys.ToArray()));
@@ -1154,6 +1263,103 @@ namespace Spine.Unity.Editor {
 			clip.SetCurve(path, typeof(Transform), propertyName + ".z", zCurve);
 		}
 
+		static void ParseSingleSplitScaleTimeline (Skeleton skeleton,
+			ScaleXTimeline timelineX, ScaleYTimeline timelineY, AnimationClip clip) {
+
+			bool isXTimeline = timelineX != null;
+			CurveTimeline1 timeline = isXTimeline ? timelineX : timelineY as CurveTimeline1;
+			IBoneTimeline boneTimeline = isXTimeline ? timelineX : timelineY as IBoneTimeline;
+
+			var boneData = skeleton.Data.Bones.Items[boneTimeline.BoneIndex];
+			var bone = skeleton.Bones.Items[boneTimeline.BoneIndex];
+			float boneDataOffset = isXTimeline ? boneData.ScaleX : boneData.ScaleY;
+
+			AnimationCurve curve = new AnimationCurve();
+			float endTime = timeline.Frames[(timeline.FrameCount * ScaleXTimeline.ENTRIES) - ScaleXTimeline.ENTRIES];
+			float currentTime = timeline.Frames[0];
+			List<Keyframe> keys = new List<Keyframe>();
+			keys.Add(new Keyframe(timeline.Frames[0], timeline.Frames[1] * boneDataOffset, 0, 0));
+
+			int listIndex = 1;
+			int frameIndex = 1;
+			int f = ScaleXTimeline.ENTRIES;
+			float[] frames = timeline.Frames;
+			skeleton.SetToSetupPose();
+			float lastTime = 0;
+			while (currentTime < endTime) {
+				int pIndex = listIndex - 1;
+				float curveType = timeline.GetCurveType(frameIndex - 1);
+				if (curveType == 0) {
+					//linear
+					Keyframe p = keys[pIndex];
+
+					float time = frames[f];
+					float value = frames[f + 1] * boneDataOffset;
+					float valueOut = (value - p.value) / (time - p.time);
+					p.outTangent = valueOut;
+					keys.Add(new Keyframe(time, value, valueOut, 0));
+
+					keys[pIndex] = p;
+					currentTime = time;
+					timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixBlend.Setup, MixDirection.In);
+
+					lastTime = time;
+					listIndex++;
+				} else if (curveType == 1) {
+					//stepped
+					Keyframe p = keys[pIndex];
+
+					float time = frames[f];
+					float value = frames[f + 1] * boneDataOffset;
+					float valueOut = float.PositiveInfinity;
+					p.outTangent = valueOut;
+					keys.Add(new Keyframe(time, value, valueOut, 0));
+
+					keys[pIndex] = p;
+					currentTime = time;
+					timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixBlend.Setup, MixDirection.In);
+
+					lastTime = time;
+					listIndex++;
+				} else {
+					//bezier
+					Keyframe p = keys[pIndex];
+					float time = frames[f];
+					int steps = Mathf.FloorToInt((time - p.time) / BakeIncrement);
+
+					for (int i = 1; i <= steps; i++) {
+						currentTime += BakeIncrement;
+						if (i == steps)
+							currentTime = time;
+
+						timeline.Apply(skeleton, lastTime, currentTime, null, 1, MixBlend.Setup, MixDirection.In);
+
+						p = keys[listIndex - 1];
+
+						float boneScale = isXTimeline ? bone.ScaleX : bone.ScaleY;
+						float valueOut = (boneScale - p.value) / (currentTime - p.time);
+						p.outTangent = valueOut;
+						keys.Add(new Keyframe(currentTime, boneScale, valueOut, 0));
+
+						keys[listIndex - 1] = p;
+
+						listIndex++;
+						lastTime = currentTime;
+					}
+				}
+
+				frameIndex++;
+				f += ScaleXTimeline.ENTRIES;
+			}
+
+			curve = EnsureCurveKeyCount(new AnimationCurve(keys.ToArray()));
+
+			string path = GetPath(boneData);
+			string propertyName = "localScale";
+
+			clip.SetCurve(path, typeof(Transform), propertyName + (isXTimeline ? ".x" : ".y"), curve);
+		}
+
 		static void ParseRotateTimeline (Skeleton skeleton, RotateTimeline timeline, AnimationClip clip) {
 			var boneData = skeleton.Data.Bones.Items[timeline.BoneIndex];
 			var bone = skeleton.Bones.Items[timeline.BoneIndex];