diff --git a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBaker.cs b/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBaker.cs index 5ff45fa2c..720f826ff 100644 --- a/spine-unity/Assets/Spine/Editor/spine-unity/Editor/Windows/SkeletonBaker.cs +++ b/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); } + /// Parses a single TranslateXTimeline or TranslateYTimeline. + /// Only one of timelineX or timelineY shall be filled out, the other must be null. + 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 keys = new List(); + 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 keys = new List(); + 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];