mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-03-03 22:29:13 +08:00
[unity] Fixed prefab baking ignoring separated timelines. Closes #2035.
This commit is contained in:
parent
c523576895
commit
a4e7654bc5
@ -782,8 +782,16 @@ namespace Spine.Unity.Editor {
|
|||||||
|
|
||||||
if (t is ScaleTimeline) {
|
if (t is ScaleTimeline) {
|
||||||
ParseScaleTimeline(skeleton, (ScaleTimeline)t, clip);
|
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) {
|
} else if (t is TranslateTimeline) {
|
||||||
ParseTranslateTimeline(skeleton, (TranslateTimeline)t, clip);
|
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) {
|
} else if (t is RotateTimeline) {
|
||||||
//bypass any rotation keys if they're going to get baked anyway to prevent localEulerAngles vs Baked collision
|
//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)
|
if (ignoreRotateTimelineIndexes.Contains(((RotateTimeline)t).BoneIndex) == false)
|
||||||
@ -895,7 +903,7 @@ namespace Spine.Unity.Editor {
|
|||||||
AnimationCurve yCurve = new AnimationCurve();
|
AnimationCurve yCurve = new AnimationCurve();
|
||||||
AnimationCurve zCurve = 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];
|
float currentTime = timeline.Frames[0];
|
||||||
|
|
||||||
@ -907,7 +915,7 @@ namespace Spine.Unity.Editor {
|
|||||||
|
|
||||||
int listIndex = 1;
|
int listIndex = 1;
|
||||||
int frameIndex = 1;
|
int frameIndex = 1;
|
||||||
int f = 3;
|
int f = TranslateTimeline.ENTRIES;
|
||||||
float[] frames = timeline.Frames;
|
float[] frames = timeline.Frames;
|
||||||
skeleton.SetToSetupPose();
|
skeleton.SetToSetupPose();
|
||||||
float lastTime = 0;
|
float lastTime = 0;
|
||||||
@ -1006,7 +1014,7 @@ namespace Spine.Unity.Editor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
frameIndex++;
|
frameIndex++;
|
||||||
f += 3;
|
f += TranslateTimeline.ENTRIES;
|
||||||
}
|
}
|
||||||
|
|
||||||
xCurve = EnsureCurveKeyCount(new AnimationCurve(xKeys.ToArray()));
|
xCurve = EnsureCurveKeyCount(new AnimationCurve(xKeys.ToArray()));
|
||||||
@ -1022,6 +1030,107 @@ namespace Spine.Unity.Editor {
|
|||||||
clip.SetCurve(path, typeof(Transform), propertyName + ".z", zCurve);
|
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) {
|
static void ParseScaleTimeline (Skeleton skeleton, ScaleTimeline timeline, AnimationClip clip) {
|
||||||
var boneData = skeleton.Data.Bones.Items[timeline.BoneIndex];
|
var boneData = skeleton.Data.Bones.Items[timeline.BoneIndex];
|
||||||
var bone = skeleton.Bones.Items[timeline.BoneIndex];
|
var bone = skeleton.Bones.Items[timeline.BoneIndex];
|
||||||
@ -1030,7 +1139,7 @@ namespace Spine.Unity.Editor {
|
|||||||
AnimationCurve yCurve = new AnimationCurve();
|
AnimationCurve yCurve = new AnimationCurve();
|
||||||
AnimationCurve zCurve = 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];
|
float currentTime = timeline.Frames[0];
|
||||||
|
|
||||||
@ -1042,7 +1151,7 @@ namespace Spine.Unity.Editor {
|
|||||||
|
|
||||||
int listIndex = 1;
|
int listIndex = 1;
|
||||||
int frameIndex = 1;
|
int frameIndex = 1;
|
||||||
int f = 3;
|
int f = ScaleTimeline.ENTRIES;
|
||||||
float[] frames = timeline.Frames;
|
float[] frames = timeline.Frames;
|
||||||
skeleton.SetToSetupPose();
|
skeleton.SetToSetupPose();
|
||||||
float lastTime = 0;
|
float lastTime = 0;
|
||||||
@ -1140,7 +1249,7 @@ namespace Spine.Unity.Editor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
frameIndex++;
|
frameIndex++;
|
||||||
f += 3;
|
f += ScaleTimeline.ENTRIES;
|
||||||
}
|
}
|
||||||
|
|
||||||
xCurve = EnsureCurveKeyCount(new AnimationCurve(xKeys.ToArray()));
|
xCurve = EnsureCurveKeyCount(new AnimationCurve(xKeys.ToArray()));
|
||||||
@ -1154,6 +1263,103 @@ namespace Spine.Unity.Editor {
|
|||||||
clip.SetCurve(path, typeof(Transform), propertyName + ".z", zCurve);
|
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) {
|
static void ParseRotateTimeline (Skeleton skeleton, RotateTimeline timeline, AnimationClip clip) {
|
||||||
var boneData = skeleton.Data.Bones.Items[timeline.BoneIndex];
|
var boneData = skeleton.Data.Bones.Items[timeline.BoneIndex];
|
||||||
var bone = skeleton.Bones.Items[timeline.BoneIndex];
|
var bone = skeleton.Bones.Items[timeline.BoneIndex];
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user