public void Deserialize( //string name, Stream in_stream) { Clear(); using (BinaryReader sr = new BinaryReader(in_stream)) { //模型版本号 byte version = sr.ReadByte(); VertexFormat vf = (VertexFormat)sr.ReadByte();//顶点格式 //顶点数量 int vertexCount = sr.ReadInt32(); Vector2[] UV = new Vector2[vertexCount]; //uv信息 for (int i = 0; i < vertexCount; i++) { Vector2 uv = new Vector2(); uv.x = sr.ReadSingle(); uv.y = sr.ReadSingle(); UV[i] = uv; } //子网 int[] trangles; { { int indexCount = sr.ReadInt32();//子网索引数量 trangles = new int[indexCount]; for (int j = 0; j < indexCount; j++) { trangles[j] = sr.ReadUInt16(); //子网索引信息 } } } //帧信息 { m_Frames = new MFAFrames(); int frameCount = sr.ReadInt32();//帧数 m_Frames.KeyFrames = new Mesh[frameCount]; for (int i = 0; i < frameCount; i++) { Mesh newKF = new Mesh(); //帧顶点 Vector3[] possitionArray = new Vector3[vertexCount]; if (vf == VertexFormat.Float) { for (int vi = 0; vi < vertexCount; vi++) { Vector3 v3 = new Vector3(); v3.x = sr.ReadSingle(); v3.y = sr.ReadSingle(); v3.z = sr.ReadSingle(); possitionArray[vi] = v3; } } else { for (int vi = 0; vi < vertexCount; vi++) { Vector3 v3 = new Vector3(); v3.x = (float)sr.ReadInt16() / 1000f; v3.y = (float)sr.ReadInt16() / 1000f; v3.z = (float)sr.ReadInt16() / 1000f; possitionArray[vi] = v3; } } newKF.vertices = possitionArray; newKF.uv = UV; newKF.triangles = trangles; newKF.RecalculateBounds(); m_Frames.KeyFrames[i] = newKF; } } //动画信息 int clipCount = sr.ReadInt32();//动作数量 m_ClipsIndexByName.Clear(); m_ClipsIndexByHashName.Clear(); for (int i = 0; i < clipCount; i++) { MFAClip nClip = new MFAClip(); nClip.clipName = sr.ReadString(); //动作名字 nClip.frameDelay = sr.ReadSingle(); //动作帧延迟 int clipFrameCount = sr.ReadInt32(); //动作帧数 nClip.KeyFrameIndexs = new int[clipFrameCount]; for (int j = 0; j < clipFrameCount; j++) { nClip.KeyFrameIndexs[j] = sr.ReadInt32(); //帧数组 } m_ClipsIndexByName.Add(nClip.clipName, nClip); m_ClipsIndexByHashName.Add(nClip.clipName.GetHashCode(), nClip); } sr.Close(); UpdateDefaultHashClipName(); } //Name = name; }
/// <summary> /// 序列化 /// </summary> /// <param name="stream"></param> public void Serialize(Stream out_stream) { if (m_Frames == null || m_Frames.KeyFrames.Length < 1) { return; } using (BinaryWriter sw = new BinaryWriter(out_stream)) { Mesh firstMesh = m_Frames.KeyFrames[0]; //模型版本号 sw.Write((byte)1); VertexFormat vf = CheckVertexFormat(); sw.Write((byte)vf);//顶点格式 Debug.Log(string.Format("导出模型,顶点格式{0}", vf == VertexFormat.Float?"浮点":"短整")); //顶点数量 sw.Write(firstMesh.vertexCount); Vector2[] uvs = firstMesh.uv; //uv信息 for (int i = 0; i < uvs.Length; i++) { Vector2 uv = uvs[i]; sw.Write(uv.x); sw.Write(uv.y); } //子网 int[] triangles = firstMesh.triangles; { sw.Write(triangles.Length); //子网索引数量 foreach (int index in triangles) { sw.Write((ushort)index); //子网索引信息 } } sw.Write(m_Frames.KeyFrames.Length); //帧数 //帧信息 if (vf == VertexFormat.Float) { foreach (Mesh currKF in m_Frames.KeyFrames) { Vector3[] vertices = currKF.vertices; //帧顶点 foreach (Vector3 pos in vertices) { sw.Write(pos.x); sw.Write(pos.y); sw.Write(pos.z); } } } else { foreach (Mesh currKF in m_Frames.KeyFrames) { Vector3[] vertices = currKF.vertices; //帧顶点 foreach (Vector3 pos in vertices) { sw.Write((short)(pos.x * 1000f)); sw.Write((short)(pos.y * 1000f)); sw.Write((short)(pos.z * 1000f)); } } } //动画信息 sw.Write(m_ClipsIndexByName.Count); //动作数量 foreach (KeyValuePair <string, MFAClip> clipkv in m_ClipsIndexByName) { MFAClip clip = clipkv.Value; sw.Write(clipkv.Key); //动作名字 sw.Write(clip.frameDelay); //动作帧延迟 sw.Write(clip.KeyFrameIndexs.Length); //动作帧数 for (int i = 0; i < clip.KeyFrameIndexs.Length; i++) { sw.Write(clip.KeyFrameIndexs[i]); //帧数组 } } sw.Close(); } }
/* * 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); } }