static void CreateAnimDeform(SpineArmatureEditor armatureEditor, AnimationClip clip, SpineData.AnimationDeformData[] animDeformDatas) { string[] skins = armatureEditor.armature.GetComponent <Armature>().skins; bool multiSkin = (skins == null || skins.Length <= 1)? false : true; for (int i = 0; i < animDeformDatas.Length; ++i) { SpineData.AnimationDeformData animDeformData = animDeformDatas[i]; if (animDeformData.timelines == null || animDeformData.timelines.Length == 0) { continue; } Dictionary <string, AnimationCurve[]> xCurveKV = new Dictionary <string, AnimationCurve[]>(); //key is attachment name Dictionary <string, AnimationCurve[]> yCurveKV = new Dictionary <string, AnimationCurve[]>(); Transform slot = armatureEditor.slotsKV[animDeformData.slotName]; bool isHaveCurve = false; for (int j = 0; j < animDeformData.timelines.Length; ++j) { SpineData.DeformTimeline timeline = animDeformData.timelines[j]; Transform attachment = multiSkin? slot.Find(animDeformData.skinName + "/" + timeline.attachment) : slot.Find(timeline.attachment); string prevTweeneasing = "linear"; //前一帧的tweenEasing float[] prevCurves = null; if (j > 0) { prevTweeneasing = animDeformData.timelines[j - 1].tweenEasing; prevCurves = animDeformData.timelines[j - 1].curve; } TangentMode tanModeL = GetPrevFrameTangentMode(prevTweeneasing, prevCurves); TangentMode tanModeR = TangentMode.Linear; if (timeline.curve != null && timeline.curve.Length > 0) { tanModeR = TangentMode.Editable; isHaveCurve = true; } else { if (timeline.tweenEasing == "stepped") { tanModeR = TangentMode.Stepped; } else { tanModeR = TangentMode.Linear; } } if (!xCurveKV.ContainsKey(timeline.attachment)) { xCurveKV[timeline.attachment] = new AnimationCurve[attachment.childCount]; yCurveKV[timeline.attachment] = new AnimationCurve[attachment.childCount]; } AnimationCurve[] xCurveArray = xCurveKV[timeline.attachment]; AnimationCurve[] yCurveArray = yCurveKV[timeline.attachment]; int len = attachment.childCount; if (timeline.vertices != null && timeline.vertices.Length > 0) { for (int r = 0; r < len; ++r) { if (xCurveArray[r] == null) { xCurveArray[r] = new AnimationCurve(); yCurveArray[r] = new AnimationCurve(); } AnimationCurve xCurve = xCurveArray[r]; AnimationCurve yCurve = yCurveArray[r]; Transform vCtr = attachment.GetChild(r); //vertex control if (r >= timeline.offset && r - timeline.offset < timeline.vertices.Length) { Vector3 v = timeline.vertices[r - timeline.offset]; v += vCtr.localPosition; Keyframe kfx = KeyframeUtil.GetNew(timeline.time, v.x, tanModeL, tanModeR); xCurve.AddKey(kfx); Keyframe kfy = KeyframeUtil.GetNew(timeline.time, v.y, tanModeL, tanModeR); yCurve.AddKey(kfy); } else { Keyframe kfx = KeyframeUtil.GetNew(timeline.time, vCtr.localPosition.x, tanModeL, tanModeR); xCurve.AddKey(kfx); Keyframe kfy = KeyframeUtil.GetNew(timeline.time, vCtr.localPosition.y, tanModeL, tanModeR); yCurve.AddKey(kfy); } } } else { //add default vertex position for (int r = 0; r < len; ++r) { if (xCurveArray[r] == null) { xCurveArray[r] = new AnimationCurve(); yCurveArray[r] = new AnimationCurve(); } AnimationCurve xCurve = xCurveArray[r]; AnimationCurve yCurve = yCurveArray[r]; Transform vCtr = attachment.GetChild(r); //vertex control Keyframe kfx = KeyframeUtil.GetNew(timeline.time, vCtr.localPosition.x, tanModeL, tanModeR); xCurve.AddKey(kfx); Keyframe kfy = KeyframeUtil.GetNew(timeline.time, vCtr.localPosition.y, tanModeL, tanModeR); yCurve.AddKey(kfy); } } } string path = ""; if (slotPathKV.ContainsKey(slot.name)) { path = slotPathKV[slot.name]; } else { path = GetNodeRelativePath(armatureEditor, slot); slotPathKV[slot.name] = path; } if (multiSkin) { path += "/" + animDeformData.skinName; } foreach (string attachmentName in xCurveKV.Keys) { AnimationCurve[] vertex_xcurves = xCurveKV[attachmentName]; AnimationCurve[] vertex_ycurves = yCurveKV[attachmentName]; Transform attachment = multiSkin? slot.Find(animDeformData.skinName + "/" + attachmentName) : slot.Find(attachmentName); int len = attachment.childCount; for (int r = 0; r < len; ++r) { AnimationCurve vertex_xcurve = vertex_xcurves[r]; AnimationCurve vertex_ycurve = vertex_ycurves[r]; Transform v = attachment.GetChild(r); string ctrlPath = path + "/" + attachment.name + "/" + v.name; CurveExtension.OptimizesCurve(vertex_xcurve); CurveExtension.OptimizesCurve(vertex_ycurve); bool vcurveFlag = false; if (vertex_xcurve.keys != null && vertex_xcurve.keys.Length > 0 && CheckCurveValid(vertex_xcurve, v.localPosition.x)) { vcurveFlag = true; } if (vertex_ycurve.keys != null && vertex_ycurve.keys.Length > 0 && CheckCurveValid(vertex_ycurve, v.localPosition.y)) { vcurveFlag = true; } if (vcurveFlag) { if (isHaveCurve) { SetCustomCurveTangents(vertex_xcurve, animDeformData.timelines); } CurveExtension.UpdateAllLinearTangents(vertex_xcurve); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(ctrlPath, typeof(Transform), "m_LocalPosition.x"), vertex_xcurve); if (isHaveCurve) { SetCustomCurveTangents(vertex_ycurve, animDeformData.timelines); } CurveExtension.UpdateAllLinearTangents(vertex_ycurve); AnimationUtility.SetEditorCurve(clip, EditorCurveBinding.FloatCurve(ctrlPath, typeof(Transform), "m_LocalPosition.y"), vertex_ycurve); //add pose AnimationCurve pose_vertex_xcurve = new AnimationCurve(); AnimationCurve pose_vertex_ycurve = new AnimationCurve(); pose_vertex_xcurve.AddKey(new Keyframe(0f, v.localPosition.x)); pose_vertex_ycurve.AddKey(new Keyframe(0f, v.localPosition.y)); AnimationUtility.SetEditorCurve(poseClip, EditorCurveBinding.FloatCurve(ctrlPath, typeof(Transform), "m_LocalPosition.x"), pose_vertex_xcurve); AnimationUtility.SetEditorCurve(poseClip, EditorCurveBinding.FloatCurve(ctrlPath, typeof(Transform), "m_LocalPosition.y"), pose_vertex_ycurve); } } } } }
private static SpineData.AnimationDeformData ParseDeformAnimTimeline(SpineArmatureEditor armatureEditor, string skinName, string slotname, string attchmentname, Bones2D.JSONArray deformAnimObj) { SpineData.AnimationDeformData animDeformDatas = new SpineData.AnimationDeformData(); animDeformDatas.slotName = slotname; animDeformDatas.skinName = skinName; animDeformDatas.timelines = new SpineData.DeformTimeline[deformAnimObj.Count]; SpineData.SkinAttachment skinAtt = GetSkinAttachment(armatureEditor, skinName, slotname, attchmentname); bool haveWeight = (skinAtt == null || skinAtt.weights == null || skinAtt.weights.Count == 0) ? false : true; for (int i = 0; i < deformAnimObj.Count; ++i) { SpineData.DeformTimeline timeline = new SpineData.DeformTimeline(); animDeformDatas.timelines[i] = timeline; timeline.attachment = attchmentname; Bones2D.JSONClass animObj = deformAnimObj[i].AsObject; if (animObj.ContainKey("time")) { timeline.time = animObj["time"].AsFloat; } if (animObj.ContainKey("curve")) { if (animObj["curve"] == "stepped") { timeline.tweenEasing = "stepped"; } else if (animObj["curve"] == "linear") { //default } else { timeline.curve = ConvertJsonArrayToFloatArr(animObj["curve"].AsArray); } } if (animObj.ContainKey("offset")) { timeline.offset = animObj["offset"].AsInt / 2; } if (animObj.ContainKey("vertices")) { Bones2D.JSONArray verticesObj = animObj["vertices"].AsArray; int index = 0; int k = 0; timeline.vertices = new Vector3[verticesObj.Count / 2]; for (; k < verticesObj.Count && k + 1 < verticesObj.Count; k += 2) { timeline.vertices[index] = new Vector3(verticesObj[k].AsFloat * armatureEditor.unit, verticesObj[k + 1].AsFloat * armatureEditor.unit, 0f); ++index; } armatureEditor.ffdKV [attchmentname] = true; if (haveWeight) { CreateBonePose(armatureEditor); BoneMatrix2D matrix = new BoneMatrix2D(); int vertexIndex = 0; int offset = timeline.offset; int newOffset = 0; for (int j = 0; j < skinAtt.weights.Count; ++j) { int boneCount = (int)skinAtt.weights[j]; if (offset <= 0) { Vector3 v = timeline.vertices [vertexIndex]; Vector3 result = new Vector3(); for (int w = 0; w < boneCount * 4; w += 4) { int boneIndex = (int)skinAtt.weights [j + w + 1]; SpineData.BoneData boneData = armatureEditor.armatureData.bones [boneIndex]; float weight = skinAtt.weights [j + w + 4]; BoneMatrix2D boneMatrix = armatureEditor.bonePoseKV [boneData.name]; matrix.Identity(); matrix.a = boneMatrix.a; matrix.b = boneMatrix.b; matrix.c = boneMatrix.c; matrix.d = boneMatrix.d; matrix.Invert(); //to local Vector2 p = matrix.TransformPoint(v.x, v.y); result.x += p.x * weight; result.y += p.y * weight; } timeline.vertices [vertexIndex] = result; ++vertexIndex; if (vertexIndex >= timeline.vertices.Length) { break; } } else { ++newOffset; } offset -= boneCount; j += boneCount * 4; } timeline.offset = newOffset; } } } return(animDeformDatas); }