Beispiel #1
0
    public MFABone(MFASkeletalModel model, GameObject obj, MFABone parent)
    {
        m_GameObj = obj;
        m_Parent  = parent;

        MeshRenderer cmMeshRenderer = m_GameObj.GetComponent <MeshRenderer>();

        if (cmMeshRenderer != null)
        {
            model.RegMesh(this);
        }

        SkinnedMeshRenderer cmSkinnedMeshRenderer = m_GameObj.GetComponent <SkinnedMeshRenderer>();

        if (cmSkinnedMeshRenderer != null)
        {
            model.RegSkeletal(this);
        }

        model.RegBone(this);

        //添加子骨骼
        int childCount = m_GameObj.transform.childCount;

        for (int i = 0; i < childCount; i++)
        {
            GameObject childObj = m_GameObj.transform.GetChild(i).gameObject;
            m_Child.Add(new MFABone(model, childObj, this));
        }
    }
Beispiel #2
0
/*
 *  List<Texture> tl = new List<Texture>();
 *         string[] paths = AssetDatabase.FindAssets("qibing_512red");
 *         foreach (var p in paths)
 *         {
 *             //Debug.Log(AssetDatabase.GUIDToAssetPath(p));
 *             var path = AssetDatabase.GUIDToAssetPath(p);
 *            // path = path.Substring(7,path.Length-7);
 *             Texture2D t = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
 *
 *                 // AssetDatabase.LoadAssetAtPath<Texture>(path);
 *             tl.Add(t);
 *         }
 */
    //反序列化测试

    /*
     * {
     *  using(MemoryStream mem = new MemoryStream( FileSystem.ReadFile(file.FullName)))
     *  {
     *      model.Deserialize(mem);
     *  }
     *
     * }*/

    //保存mesh并建立关联

    /*
     * string modelFilePath = "Assets/Resources/model/@" + modelName +"/" + lodFlag + ".prefab";// modelPackPath
     * YQ2MFAFrames nFrames =  model.GetComponent<YQ2MFAFrames>();
     * for (int i = 0; i < nFrames.KeyFrames.Length;i++ )
     * {
     *  Mesh kfmesh = nFrames.KeyFrames[i];
     *  string meshPath =
     *      string.Format("Assets/Resources/model/@{0}/Frames/{1}_{2:D2}.prefab",
     *      modelName,
     *      lodFlag,
     *      i
     *      );
     *  AssetDatabase.CreateAsset(kfmesh, meshPath);
     *
     *  kfmesh = AssetDatabase.LoadAssetAtPath(meshPath, typeof(Mesh)) as Mesh;
     *  nFrames.KeyFrames[i] = kfmesh;
     * }
     *
     * PrefabUtility.CreatePrefab(modelFilePath,model);
     * GameObject.DestroyImmediate(model);
     */



    /// <summary>
    /// 从骨架动画组件生成模型对象
    /// </summary>
    /// <returns></returns>
    static MFAModel FromYQ2AnimationClips(GameObject _obj, MFAAnimationExportInfo exportInfo)
    {
        var ModelClipsInfo = MFADatas.Single.ModelClips.Get(exportInfo.ModelClips);


        //检查剪辑帧数正确性
        {
            foreach (var curr in ModelClipsInfo.Clips)
            {
                int fCount = -1;
                int eCount = -1;
                foreach (var curr2 in curr.FrameRanges)
                {
                    if (fCount < 0)
                    {
                        fCount = curr2.ResFrameCount;
                    }
                    if (eCount < 0)
                    {
                        eCount = curr2.ExportFrameCount;
                    }

                    if (curr2.ResFrameCount != fCount)
                    {
                        throw new Exception("动画剪辑资源帧数不一致 " + curr.Name);
                    }

                    if (curr2.ExportFrameCount != eCount)
                    {
                        throw new Exception("动画剪辑导出帧数不一致 " + curr.Name);
                    }
                }
            }
        }

        //YQ2ModelAnimationClip
        using (MFASkeletalModel skin_model = new MFASkeletalModel(_obj))
        {
            string ckResTag = "";

            //检查剪辑基本配置信息
            foreach (var c1 in ModelClipsInfo.Clips)
            {
                SortedDictionary <string, string> tags = new SortedDictionary <string, string>();
                foreach (var curr in c1.FrameRanges)
                {
                    // if (!skin_model.HasClipInfo(curr.ResClipName))
                    //    throw new Exception("不存在的动画剪辑 " + curr.ResClipName);

                    if (curr.ExportFrameCount < 1)
                    {
                        throw new Exception(string.Format("动画剪辑{0} 导出帧数有误 ", c1.ClipName));
                    }

                    if (curr.ResStartFrameIndex < 0)
                    {
                        throw new Exception(string.Format("动画剪辑{0} 起始帧配置错误", c1.ClipName));
                    }

                    if (curr.ResEndFrameIndex - curr.ResStartFrameIndex < 1)
                    {
                        throw new Exception(string.Format("动画剪辑{0} 帧总数错误", c1.ClipName));
                    }

                    if (tags.ContainsKey(curr.ResTag))
                    {
                        throw new Exception(string.Format("动画剪辑{0} 重复的组件", c1.ClipName));
                    }
                    tags.Add(curr.ResTag, curr.ResTag);
                }

                string tmpTag = "";
                foreach (var curr in tags)
                {
                    tmpTag += curr.Key;
                }

                if (string.IsNullOrEmpty(ckResTag))
                {
                    ckResTag = tmpTag;
                }
                else
                if (ckResTag != tmpTag)
                {
                    throw new Exception(string.Format("动画剪辑{0} 各动作组件不一致", c1.ClipName));
                }
            }

            //统计tag队列

            /*
             * HashSet<string> tags = new HashSet<string>();
             * foreach (var c1 in ModelClipsInfo.Clips)
             * {
             *  foreach (var curr in c1.FrameRanges)  tags.Add(curr.ResTag);
             * }*/

            skin_model.ClearSnapshot();

            //构建快照
            foreach (var tag in exportInfo.Tags)
            {
                skin_model.BuildSnapshot(tag);
            }

            //过滤快照
            List <MFASkeletalModel.MeshFrame> firstSnapshot = skin_model.FilterSnapshot(exportInfo.Tags);


            int indexCount  = 0;
            int vertexCount = 0;

            //统计顶点和索引总量
            foreach (MFASkeletalModel.MeshFrame mf in firstSnapshot)
            {
                Mesh mesh = mf.mesh;
                for (int i = 0; i < mesh.subMeshCount; i++)
                {
                    indexCount += mesh.GetIndices(i).Length;
                }
                vertexCount += mesh.vertexCount;
            }



            //分配内存
            int[]     kfIndexs = new int[indexCount];
            Vector2[] kfUV     = new Vector2[vertexCount];

            {
                int startUV    = 0;
                int startIndex = 0;
                //填充uv和索引信息
                foreach (MFASkeletalModel.MeshFrame mf in firstSnapshot)
                {
                    Mesh mesh = mf.mesh;

                    //填充子网数据
                    for (int i = 0; i < mesh.subMeshCount; i++)
                    {
                        int[] indexs = mesh.GetIndices(i);
                        for (int ii = 0; ii < indexs.Length; ii++)
                        {
                            kfIndexs[ii + startIndex] = (ushort)(indexs[ii] + startUV);
                        }

                        startIndex += indexs.Length;
                    }

                    //填充UV数据
                    Array.Copy(mesh.uv, 0, kfUV, startUV, mesh.uv.Length);
                    startUV += mesh.uv.Length;
                }
            }


            Dictionary <int, Mesh> KeyFramesIndexByID = new Dictionary <int, Mesh>();                                                               //根据帧id索引的帧队列
            Dictionary <long, List <KeyValuePair <Mesh, int> > > KeyFramesIndexByHash = new Dictionary <long, List <KeyValuePair <Mesh, int> > >(); //根据哈希值生成的帧队列

            //GameObject reGameObject = new GameObject();

            MFAModel reModel = new MFAModel();
            reModel.m_Frames = new MFAFrames();

            //处理关键帧和动画
            foreach (var currC in ModelClipsInfo.Clips)
            {
                string _clipName        = currC.ClipName;
                var    ExportFrameCount = currC.FrameRanges[0].ExportFrameCount;
                var    ResFrameCount    = currC.FrameRanges[0].ResFrameCount;
                float  frameRate        = 0;

                foreach (var currClip in currC.FrameRanges)
                {
                    if (skin_model.HasClipInfo(currClip.ResClipName))
                    {
                        frameRate = skin_model.GetFrameRate(currClip.ResClipName); break;
                    }
                }

                if (frameRate < 0.000001)
                {
                    throw new Exception("无法正确获得帧率 " + _clipName);
                }

                MFAClip nClip = new MFAClip();
                nClip.clipName       = _clipName;
                nClip.frameDelay     = ((ResFrameCount - 1) * (1.0f / frameRate)) / ExportFrameCount;
                nClip.KeyFrameIndexs = new int[ExportFrameCount];
                reModel.m_ClipsIndexByName.Add(nClip.clipName, nClip);
                reModel.m_ClipsIndexByHashName.Add(nClip.clipName.GetHashCode(), nClip);

                for (int currFrame = 0; currFrame < ExportFrameCount; currFrame++)
                {
                    skin_model.ClearSnapshot();
                    foreach (var currClip in currC.FrameRanges)
                    {
                        string skinClipName  = currClip.ResClipName;
                        float  clipStartTime = currClip.ResStartFrameIndex * (1.0f / frameRate);                  //资源剪辑起始时间
                        float  clipEndTime   = clipStartTime + (currClip.ResFrameCount - 1) * (1.0f / frameRate); //资源剪辑终止时间

                        if (currClip.IsLoop)
                        {
                            clipEndTime -= nClip.frameDelay;
                        }

                        float timeBfb = (float)currFrame / (float)(ExportFrameCount - 1);
                        float t       = clipStartTime + (clipEndTime - clipStartTime) * timeBfb;
                        //采样动画时间点的帧
                        skin_model.SetTime(skinClipName, t, currClip.ResTag);
                    }
                    List <MFASkeletalModel.MeshFrame> frameSnapshot = skin_model.FilterSnapshot(exportInfo.Tags);

                    long      hashV;
                    Mesh      kf        = new Mesh();
                    Vector3[] kfvertexs = new Vector3[vertexCount];
                    {
                        double _hashv = 0;
                        //kf.possitionArray

                        int startVertex = 0;

                        //抓取当前顶点位置,并生成关键帧
                        foreach (MFASkeletalModel.MeshFrame mf in frameSnapshot)
                        {
                            Mesh      mesh     = mf.mesh;
                            Vector3[] vertices = mesh.vertices;
                            for (int vi = 0; vi < vertices.Length; vi++)
                            {
                                Vector3 v3 = vertices[vi];
                                kfvertexs[vi + startVertex] = mf.TransformMX.MultiplyPoint(v3);
                                _hashv += v3.x;
                                _hashv += v3.y;
                                _hashv += v3.z;
                            }

                            startVertex += vertices.Length;
                        }


                        kf.vertices = kfvertexs;
                        hashV       = (long)_hashv;
                    }

                    int selectIndex = -1;

                    if (KeyFramesIndexByHash.ContainsKey(hashV)) //哈希值存在
                    {
                        //逐顶点比对
                        List <KeyValuePair <Mesh, int> > kfList = KeyFramesIndexByHash[hashV];
                        foreach (KeyValuePair <Mesh, int> currKF in kfList)
                        {
                            Vector3[] currKFVertices = currKF.Key.vertices;
                            bool      isLike         = true;
                            for (int i = 0; i < kfvertexs.Length; i++)
                            {
                                if (currKFVertices[i] != kfvertexs[i])
                                {
                                    isLike = false;
                                    break;
                                }
                            }
                            if (isLike)
                            {
                                selectIndex = currKF.Value;
                                break;
                            }
                        }
                    }

                    if (selectIndex < 0)
                    {
                        //生成法线信息


                        //填充uv
                        kf.uv = kfUV;

                        //填充索引
                        kf.triangles = kfIndexs;

                        //加入到关键帧队列
                        int index = KeyFramesIndexByID.Count;
                        KeyFramesIndexByID.Add(index, kf);

                        if (!KeyFramesIndexByHash.ContainsKey(hashV))
                        {
                            KeyFramesIndexByHash.Add(hashV, new List <KeyValuePair <Mesh, int> >());
                        }


                        //加入到哈希索引
                        KeyFramesIndexByHash[hashV].Add(new KeyValuePair <Mesh, int>(kf, index));

                        //选择新生成的这个关键帧
                        selectIndex = index;
                    }

                    nClip.KeyFrameIndexs[currFrame] = selectIndex;
                } //end for(int currFrame = 0;currFrame<frameCount;currFrame++)
            }     //end foreach (ModelAnimationClip currClip in clips)

            //填充关键帧
            int keycount = KeyFramesIndexByID.Count;
            reModel.m_Frames.KeyFrames = new Mesh[keycount];
            for (int kindex = 0; kindex < keycount; kindex++)
            {
                reModel.m_Frames.KeyFrames[kindex] = KeyFramesIndexByID[kindex];
            }

            OptimalKeyFrames(reModel.m_Frames.KeyFrames);

            reModel.UpdateDefaultHashClipName();
            return(reModel);
        }
    }