예제 #1
0
        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);
                        }
                    }
                }
            }
        }
예제 #2
0
        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);
        }