static int SetToSetupPose(IntPtr L) { try { ToLua.CheckArgsCount(L, 1); Spine.Skeleton obj = (Spine.Skeleton)ToLua.CheckObject <Spine.Skeleton>(L, 1); obj.SetToSetupPose(); return(0); } catch (Exception e) { return(LuaDLL.toluaL_exception(L, e)); } }
static AnimationClip ExtractAnimation (string name, SkeletonData skeletonData, Dictionary<int, List<string>> slotLookup, bool bakeIK, SendMessageOptions eventOptions, AnimationClip clip = null) { var animation = skeletonData.FindAnimation(name); var timelines = animation.Timelines; if (clip == null) { clip = new AnimationClip(); } else { clip.ClearCurves(); AnimationUtility.SetAnimationEvents(clip, new AnimationEvent[0]); } #if UNITY_5 #else AnimationUtility.SetAnimationType(clip, ModelImporterAnimationType.Generic); #endif clip.name = name; Skeleton skeleton = new Skeleton(skeletonData); List<int> ignoreRotateTimelineIndexes = new List<int>(); if (bakeIK) { foreach (IkConstraint i in skeleton.IkConstraints) { foreach (Bone b in i.Bones) { int index = skeleton.FindBoneIndex(b.Data.Name); ignoreRotateTimelineIndexes.Add(index); BakeBone(b, animation, clip); } } } foreach (Bone b in skeleton.Bones) { if (b.Data.InheritRotation == false) { int index = skeleton.FindBoneIndex(b.Data.Name); if (ignoreRotateTimelineIndexes.Contains(index) == false) { ignoreRotateTimelineIndexes.Add(index); BakeBone(b, animation, clip); } } } foreach (Timeline t in timelines) { skeleton.SetToSetupPose(); if (t is ScaleTimeline) { ParseScaleTimeline(skeleton, (ScaleTimeline)t, clip); } else if (t is TranslateTimeline) { ParseTranslateTimeline(skeleton, (TranslateTimeline)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) ParseRotateTimeline(skeleton, (RotateTimeline)t, clip); } else if (t is AttachmentTimeline) { ParseAttachmentTimeline(skeleton, (AttachmentTimeline)t, slotLookup, clip); } else if (t is EventTimeline) { ParseEventTimeline((EventTimeline)t, clip, eventOptions); } } var settings = AnimationUtility.GetAnimationClipSettings(clip); settings.loopTime = true; settings.stopTime = Mathf.Max(clip.length, 0.001f); SetAnimationSettings(clip, settings); clip.EnsureQuaternionContinuity(); EditorUtility.SetDirty(clip); return clip; }
static void ParseRotateTimeline (Skeleton skeleton, RotateTimeline timeline, AnimationClip clip) { var boneData = skeleton.Data.Bones[timeline.BoneIndex]; var bone = skeleton.Bones[timeline.BoneIndex]; AnimationCurve curve = new AnimationCurve(); float endTime = timeline.Frames[(timeline.FrameCount * 2) - 2]; float currentTime = timeline.Frames[0]; List<Keyframe> keys = new List<Keyframe>(); float rotation = timeline.Frames[1] + boneData.Rotation; keys.Add(new Keyframe(timeline.Frames[0], rotation, 0, 0)); int listIndex = 1; int frameIndex = 1; int f = 2; float[] frames = timeline.Frames; skeleton.SetToSetupPose(); float lastTime = 0; float angle = rotation; while (currentTime < endTime) { int pIndex = listIndex - 1; float curveType = timeline.GetCurveType(frameIndex - 1); if (curveType == 0) { //linear Keyframe pk = keys[pIndex]; float time = frames[f]; rotation = frames[f + 1] + boneData.Rotation; angle += Mathf.DeltaAngle(angle, rotation); float r = angle; float rOut = (r - pk.value) / (time - pk.time); pk.outTangent = rOut; keys.Add(new Keyframe(time, r, rOut, 0)); keys[pIndex] = pk; currentTime = time; timeline.Apply(skeleton, lastTime, currentTime, null, 1); lastTime = time; listIndex++; } else if (curveType == 1) { //stepped Keyframe pk = keys[pIndex]; float time = frames[f]; rotation = frames[f + 1] + boneData.Rotation; angle += Mathf.DeltaAngle(angle, rotation); float r = angle; float rOut = float.PositiveInfinity; pk.outTangent = rOut; keys.Add(new Keyframe(time, r, rOut, 0)); keys[pIndex] = pk; currentTime = time; timeline.Apply(skeleton, lastTime, currentTime, null, 1); lastTime = time; listIndex++; } else if (curveType == 2) { //bezier Keyframe pk = keys[pIndex]; float time = frames[f]; timeline.Apply(skeleton, lastTime, currentTime, null, 1); skeleton.UpdateWorldTransform(); rotation = frames[f + 1] + boneData.Rotation; angle += Mathf.DeltaAngle(angle, rotation); float r = angle; int steps = Mathf.FloorToInt((time - pk.time) / bakeIncrement); for (int i = 1; i <= steps; i++) { currentTime += bakeIncrement; if (i == steps) currentTime = time; timeline.Apply(skeleton, lastTime, currentTime, null, 1); skeleton.UpdateWorldTransform(); pk = keys[listIndex - 1]; rotation = bone.Rotation; angle += Mathf.DeltaAngle(angle, rotation); r = angle; float rOut = (r - pk.value) / (currentTime - pk.time); pk.outTangent = rOut; keys.Add(new Keyframe(currentTime, r, rOut, 0)); keys[listIndex - 1] = pk; listIndex++; lastTime = currentTime; } } frameIndex++; f += 2; } curve = EnsureCurveKeyCount(new AnimationCurve(keys.ToArray())); string path = GetPath(boneData); string propertyName = "localEulerAnglesBaked"; EditorCurveBinding xBind = EditorCurveBinding.FloatCurve(path, typeof(Transform), propertyName + ".x"); AnimationUtility.SetEditorCurve(clip, xBind, new AnimationCurve()); EditorCurveBinding yBind = EditorCurveBinding.FloatCurve(path, typeof(Transform), propertyName + ".y"); AnimationUtility.SetEditorCurve(clip, yBind, new AnimationCurve()); EditorCurveBinding zBind = EditorCurveBinding.FloatCurve(path, typeof(Transform), propertyName + ".z"); AnimationUtility.SetEditorCurve(clip, zBind, curve); }
static void ParseScaleTimeline (Skeleton skeleton, ScaleTimeline timeline, AnimationClip clip) { var boneData = skeleton.Data.Bones[timeline.BoneIndex]; var bone = skeleton.Bones[timeline.BoneIndex]; AnimationCurve xCurve = new AnimationCurve(); AnimationCurve yCurve = new AnimationCurve(); AnimationCurve zCurve = new AnimationCurve(); float endTime = timeline.Frames[(timeline.FrameCount * 3) - 3]; float currentTime = timeline.Frames[0]; List<Keyframe> xKeys = new List<Keyframe>(); List<Keyframe> yKeys = new List<Keyframe>(); xKeys.Add(new Keyframe(timeline.Frames[0], timeline.Frames[1] * boneData.ScaleX, 0, 0)); yKeys.Add(new Keyframe(timeline.Frames[0], timeline.Frames[2] * boneData.ScaleY, 0, 0)); int listIndex = 1; int frameIndex = 1; int f = 3; 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 px = xKeys[pIndex]; Keyframe py = yKeys[pIndex]; float time = frames[f]; float x = frames[f + 1] * boneData.ScaleX; float y = frames[f + 2] * boneData.ScaleY; float xOut = (x - px.value) / (time - px.time); float yOut = (y - py.value) / (time - py.time); px.outTangent = xOut; py.outTangent = yOut; xKeys.Add(new Keyframe(time, x, xOut, 0)); yKeys.Add(new Keyframe(time, y, yOut, 0)); xKeys[pIndex] = px; yKeys[pIndex] = py; currentTime = time; timeline.Apply(skeleton, lastTime, currentTime, null, 1); lastTime = time; listIndex++; } else if (curveType == 1) { //stepped Keyframe px = xKeys[pIndex]; Keyframe py = yKeys[pIndex]; float time = frames[f]; float x = frames[f + 1] * boneData.ScaleX; float y = frames[f + 2] * boneData.ScaleY; float xOut = float.PositiveInfinity; float yOut = float.PositiveInfinity; px.outTangent = xOut; py.outTangent = yOut; xKeys.Add(new Keyframe(time, x, xOut, 0)); yKeys.Add(new Keyframe(time, y, yOut, 0)); xKeys[pIndex] = px; yKeys[pIndex] = py; currentTime = time; timeline.Apply(skeleton, lastTime, currentTime, null, 1); lastTime = time; listIndex++; } else if (curveType == 2) { //bezier Keyframe px = xKeys[pIndex]; Keyframe py = yKeys[pIndex]; float time = frames[f]; int steps = Mathf.FloorToInt((time - px.time) / bakeIncrement); for (int i = 1; i <= steps; i++) { currentTime += bakeIncrement; if (i == steps) currentTime = time; timeline.Apply(skeleton, lastTime, currentTime, null, 1); px = xKeys[listIndex - 1]; py = yKeys[listIndex - 1]; float xOut = (bone.ScaleX - px.value) / (currentTime - px.time); float yOut = (bone.ScaleY - py.value) / (currentTime - py.time); px.outTangent = xOut; py.outTangent = yOut; xKeys.Add(new Keyframe(currentTime, bone.ScaleX, xOut, 0)); yKeys.Add(new Keyframe(currentTime, bone.ScaleY, yOut, 0)); xKeys[listIndex - 1] = px; yKeys[listIndex - 1] = py; listIndex++; lastTime = currentTime; } } frameIndex++; f += 3; } xCurve = EnsureCurveKeyCount(new AnimationCurve(xKeys.ToArray())); yCurve = EnsureCurveKeyCount(new AnimationCurve(yKeys.ToArray())); string path = GetPath(boneData); string propertyName = "localScale"; clip.SetCurve(path, typeof(Transform), propertyName + ".x", xCurve); clip.SetCurve(path, typeof(Transform), propertyName + ".y", yCurve); clip.SetCurve(path, typeof(Transform), propertyName + ".z", zCurve); }
static void ParseColorTimeline(Skeleton skeleton, ColorTimeline timeline, Dictionary<int, List<string>> slotLookup, AnimationClip clip) { var slotData = skeleton.Data.Slots[timeline.SlotIndex]; var slot = skeleton.Slots[timeline.SlotIndex]; AnimationCurve rCurve = new AnimationCurve(); AnimationCurve gCurve = new AnimationCurve(); AnimationCurve bCurve = new AnimationCurve(); AnimationCurve aCurve = new AnimationCurve(); float endTime = timeline.Frames[(timeline.FrameCount * 5) - 5]; float currentTime = timeline.Frames[0]; List<Keyframe> rKeys = new List<Keyframe>(); List<Keyframe> gKeys = new List<Keyframe>(); List<Keyframe> bKeys = new List<Keyframe>(); List<Keyframe> aKeys = new List<Keyframe>(); rKeys.Add(new Keyframe(timeline.Frames[0], timeline.Frames[1] * slotData.R, 0, 0)); gKeys.Add(new Keyframe(timeline.Frames[0], timeline.Frames[2] * slotData.G, 0, 0)); bKeys.Add(new Keyframe(timeline.Frames[0], timeline.Frames[3] * slotData.B, 0, 0)); aKeys.Add(new Keyframe(timeline.Frames[0], timeline.Frames[4] * slotData.A, 0, 0)); int listIndex = 1; int frameIndex = 1; int f = 5; 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 cr = rKeys[pIndex]; Keyframe cg = gKeys[pIndex]; Keyframe cb = bKeys[pIndex]; Keyframe ca = aKeys[pIndex]; float time = frames[f]; float r = frames[f + 1] * slotData.R; float g = frames[f + 2] * slotData.G; float b = frames[f + 3] * slotData.B; float a = frames[f + 4] * slotData.A; float rOut = (r - cr.value) / (time - cr.time); float gOut = (g - cg.value) / (time - cg.time); float bOut = (b - cb.value) / (time - cb.time); float aOut = (a - ca.value) / (time - ca.time); cr.outTangent = rOut; cg.outTangent = gOut; cb.outTangent = bOut; ca.outTangent = aOut; rKeys.Add(new Keyframe(time, r, rOut, 0)); gKeys.Add(new Keyframe(time, g, gOut, 0)); bKeys.Add(new Keyframe(time, b, bOut, 0)); aKeys.Add(new Keyframe(time, a, aOut, 0)); rKeys[pIndex] = cr; gKeys[pIndex] = cg; bKeys[pIndex] = cb; aKeys[pIndex] = ca; currentTime = time; timeline.Apply(skeleton, lastTime, currentTime, null, 1); lastTime = time; listIndex++; } else if (curveType == 1) { //stepped Keyframe cr = rKeys[pIndex]; Keyframe cg = gKeys[pIndex]; Keyframe cb = bKeys[pIndex]; Keyframe ca = aKeys[pIndex]; float time = frames[f]; float r = frames[f + 1] * slotData.R; float g = frames[f + 2] * slotData.G; float b = frames[f + 3] * slotData.B; float a = frames[f + 4] * slotData.A; float rOut = float.PositiveInfinity; float gOut = float.PositiveInfinity; float bOut = float.PositiveInfinity; float aOut = float.PositiveInfinity; cr.outTangent = rOut; cg.outTangent = gOut; cb.outTangent = bOut; ca.outTangent = aOut; rKeys.Add(new Keyframe(time, r, rOut, 0)); gKeys.Add(new Keyframe(time, g, gOut, 0)); bKeys.Add(new Keyframe(time, b, bOut, 0)); aKeys.Add(new Keyframe(time, a, aOut, 0)); rKeys[pIndex] = cr; gKeys[pIndex] = cg; bKeys[pIndex] = cb; aKeys[pIndex] = ca; currentTime = time; timeline.Apply(skeleton, lastTime, currentTime, null, 1); lastTime = time; listIndex++; } else if (curveType == 2) { //bezier Keyframe cr = rKeys[pIndex]; Keyframe cg = gKeys[pIndex]; Keyframe cb = bKeys[pIndex]; Keyframe ca = aKeys[pIndex]; float time = frames[f]; int steps = Mathf.FloorToInt((time - cr.time) / bakeIncrement); for (int i = 1; i <= steps; i++) { currentTime += bakeIncrement; if (i == steps) currentTime = time; timeline.Apply(skeleton, lastTime, currentTime, null, 1); cr = rKeys[listIndex - 1]; cg = gKeys[listIndex - 1]; cb = bKeys[listIndex - 1]; ca = aKeys[listIndex - 1]; float rOut = (slot.R - cr.value) / (currentTime - cr.time); float gOut = (slot.G - cg.value) / (currentTime - cg.time); float bOut = (slot.B - cb.value) / (currentTime - cb.time); float aOut = (slot.A - ca.value) / (currentTime - ca.time); cr.outTangent = rOut; cg.outTangent = gOut; cb.outTangent = bOut; ca.outTangent = aOut; rKeys.Add(new Keyframe(currentTime, slot.R, rOut, 0)); gKeys.Add(new Keyframe(currentTime, slot.G, gOut, 0)); bKeys.Add(new Keyframe(currentTime, slot.B, bOut, 0)); aKeys.Add(new Keyframe(currentTime, slot.A, aOut, 0)); rKeys[listIndex - 1] = cr; gKeys[listIndex - 1] = cg; bKeys[listIndex - 1] = cb; aKeys[listIndex - 1] = ca; listIndex++; lastTime = currentTime; } } frameIndex++; f += 5; } rCurve = EnsureCurveKeyCount(new AnimationCurve(rKeys.ToArray())); gCurve = EnsureCurveKeyCount(new AnimationCurve(gKeys.ToArray())); bCurve = EnsureCurveKeyCount(new AnimationCurve(bKeys.ToArray())); aCurve = EnsureCurveKeyCount(new AnimationCurve(aKeys.ToArray())); var attachmentNames = slotLookup[timeline.SlotIndex]; string bonePath = GetPath(skeleton.Slots[timeline.SlotIndex].Bone.Data); string slotPath = bonePath + "/" + slotData.Name; Dictionary<string, AnimationCurve> curveTable = new Dictionary<string, AnimationCurve>(); foreach (string str in attachmentNames) { curveTable.Add(str, new AnimationCurve()); } string propertyName = "material._Color"; foreach (var pair in curveTable) { string path = slotPath + "/" + pair.Key; clip.SetCurve(path, typeof(MeshRenderer), propertyName + ".r", rCurve); clip.SetCurve(path, typeof(MeshRenderer), propertyName + ".g", gCurve); clip.SetCurve(path, typeof(MeshRenderer), propertyName + ".b", bCurve); clip.SetCurve(path, typeof(MeshRenderer), propertyName + ".a", aCurve); } }