public ClusterInfo BuildCluster(List <VertexInfo> allVertexList) { ClusterInfo clusterInfo = new ClusterInfo(); clusterInfo.clusterindex = (allVertexList.Count - MCRConstant.CLUSTER_VERTEX_COUNT) / MCRConstant.CLUSTER_VERTEX_COUNT; //计算bounds,找出最大的点和最小的点 float3 minPoint = float.MaxValue; float3 maxPoint = float.MinValue; for (int index = clusterInfo.clusterindex * MCRConstant.CLUSTER_VERTEX_COUNT; index < allVertexList.Count; index++) { VertexInfo vertexInfo = allVertexList[index]; //x if (vertexInfo.worldPos.x < minPoint.x) { minPoint.x = vertexInfo.worldPos.x; } else if (vertexInfo.worldPos.x > maxPoint.x) { maxPoint.x = vertexInfo.worldPos.x; } //y if (vertexInfo.worldPos.y < minPoint.y) { minPoint.y = vertexInfo.worldPos.y; } else if (vertexInfo.worldPos.y > maxPoint.y) { maxPoint.y = vertexInfo.worldPos.y; } //z if (vertexInfo.worldPos.z < minPoint.z) { minPoint.z = vertexInfo.worldPos.z; } else if (vertexInfo.worldPos.z > maxPoint.z) { maxPoint.z = vertexInfo.worldPos.z; } } clusterInfo.center = new float4((minPoint + maxPoint) / 2, 0); clusterInfo.extent = (maxPoint - minPoint) / 2; return(clusterInfo); }
IEnumerator LoadingBytes() { while (true) { UnityWebRequest req = UnityWebRequest.Get(ClusterInfoAssetsPath); yield return(req.SendWebRequest()); byte[] allData = req.downloadHandler.data; byte[] intBytes = new byte[4]; int position = 0; System.Array.Copy(allData, position, intBytes, 0, 4); int clusterCount = IOUtils.ByteToStruct <int>(intBytes); position += 4; System.Array.Copy(allData, position, intBytes, 0, 4); int vertexCount = IOUtils.ByteToStruct <int>(intBytes); position += 4; intBytes = null; byte[] clusterByte = new byte[clusterStride]; byte[] vertexByte = new byte[vertexStride]; for (int i = 0; i < clusterCount; i++) { System.Array.Copy(allData, position, clusterByte, 0, clusterStride); ClusterInfo clusterinfo = IOUtils.ByteToStruct <ClusterInfo>(clusterByte); clusterList[i] = clusterinfo; position += clusterStride; } for (int i = 0; i < vertexCount; i++) { System.Array.Copy(allData, position, vertexByte, 0, vertexStride); VertexInfo vertexinfo = IOUtils.ByteToStruct <VertexInfo>(vertexByte); vertexList[i] = vertexinfo; position += vertexStride; } clusterByte = null; vertexByte = null; req.Dispose(); bLoadFinish = true; yield break; } }
//private static bool isHaveMission() //{ // return bakeAssetsQueue.Count > 0; //} private static void ProcessBakeAssetLoadingQueue() { MCRSceneContext mcrScenecontext = null; lock (lockObj) { if (bakeAssetsQueue.Count > 0) { mcrScenecontext = bakeAssetsQueue.Dequeue(); } } if (null == mcrScenecontext || mcrScenecontext.bDestroyed) { return; } System.IO.BinaryReader reader = new System.IO.BinaryReader(System.IO.File.OpenRead(mcrScenecontext.ClusterInfoAssetsPath)); int clusterCount = reader.ReadInt32(); int vertexCount = reader.ReadInt32(); //读取cluster for (int i = 0; i < clusterCount; i++) { byte[] bytes = reader.ReadBytes(Marshal.SizeOf <ClusterInfo>()); ClusterInfo clusterinfo = IOUtils.ByteToStruct <ClusterInfo>(bytes); if (mcrScenecontext.bDestroyed) { reader.Close(); return; } mcrScenecontext.clusterList[i] = clusterinfo; } //读取顶点 for (int i = 0; i < vertexCount; i++) { byte[] bytes = reader.ReadBytes(Marshal.SizeOf <VertexInfo>()); VertexInfo vertexinfo = IOUtils.ByteToStruct <VertexInfo>(bytes); if (mcrScenecontext.bDestroyed) { reader.Close(); return; } mcrScenecontext.vertexList[i] = vertexinfo; } if (mcrScenecontext.bDestroyed) { reader.Close(); return; } mcrScenecontext.bLoadFinish = true; reader.Close(); }
void Bake() { GameObject parentRoot = GameObject.Find(MCRParentRoot); if (!parentRoot) { return; } MeshFilter[] allFilters = parentRoot.GetComponentsInChildren <MeshFilter>(); if (allFilters.Length < 0) { return; } MCRScene mcrScene = parentRoot.GetComponent <MCRScene>(); if (!mcrScene) { mcrScene = parentRoot.AddComponent <MCRScene>(); } string currentSceneName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name; string fullSavedAssetsPath = MCRConstant.BakeAssetSavePath + "/" + currentSceneName + "_MCRBakeAsset" + ".mcr"; List <ClusterInfo> allClusterList = new List <ClusterInfo>(); List <VertexInfo> allVertexList = new List <VertexInfo>(); //提取cluster foreach (MeshFilter mf in allFilters) { if (!mf.sharedMesh || !mf.gameObject.activeInHierarchy) { continue; } MeshRenderer render = mf.GetComponent <MeshRenderer>(); if (!render) { continue; } if (render.sharedMaterials.Length != mf.sharedMesh.subMeshCount) { Debug.LogError(mf.gameObject.name + "材质数量与submesh不匹配" + ",submeshcout:" + mf.sharedMesh.subMeshCount + ",材质数量:" + render.sharedMaterials.Length); continue; } //if(mf.sharedMesh.subMeshCount > 1) //{ // Debug.LogError("不支持多submesh的物体:" + mf.gameObject.name + ",submeshcout:" + mf.sharedMesh.subMeshCount); // continue; //} List <Vector3> vertex = new List <Vector3>(); List <int> triangles = new List <int>(); List <Vector2> uv = new List <Vector2>(); List <Vector3> normal = new List <Vector3>(); List <Color> color = new List <Color>(); mf.sharedMesh.GetVertices(vertex); mf.sharedMesh.GetUVs(0, uv); mf.sharedMesh.GetColors(color); mf.sharedMesh.GetNormals(normal); //处理submesh for (int k = 0; k < mf.sharedMesh.subMeshCount; k++) { triangles.Clear(); mf.sharedMesh.GetTriangles(triangles, k); //读取三角形顶点信息 for (int i = 0; i < triangles.Count; i += 3) { VertexInfo vertex1 = new VertexInfo(); int index0 = triangles[i]; vertex1.worldPos = mf.transform.localToWorldMatrix.MultiplyPoint(vertex[index0]); vertex1.worldNormal = mf.transform.localToWorldMatrix.MultiplyVector(normal[index0]); vertex1.UV0 = uv[index0]; //看看有没有顶点色 if (color.Count > 0) { vertex1.Color = new float4(color[index0].r, color[index0].g, color[index0].b, color[index0].a); } allVertexList.Add(vertex1); VertexInfo vertex2 = new VertexInfo(); int index1 = triangles[i + 1]; vertex2.worldPos = mf.transform.localToWorldMatrix.MultiplyPoint(vertex[index1]); vertex2.worldNormal = mf.transform.localToWorldMatrix.MultiplyVector(normal[index1]); vertex2.UV0 = uv[index1]; //看看有没有顶点色 if (color.Count > 0) { vertex2.Color = new float4(color[index1].r, color[index1].g, color[index1].b, color[index1].a); } allVertexList.Add(vertex2); VertexInfo vertex3 = new VertexInfo(); int index2 = triangles[i + 2]; vertex3.worldPos = mf.transform.localToWorldMatrix.MultiplyPoint(vertex[index2]); vertex3.worldNormal = mf.transform.localToWorldMatrix.MultiplyVector(normal[index2]); vertex3.UV0 = uv[index2]; //看看有没有顶点色 if (color.Count > 0) { vertex3.Color = new float4(color[index2].r, color[index2].g, color[index2].b, color[index2].a); } allVertexList.Add(vertex3); //完成了一个Cluster所需要的顶点数 if ((allVertexList.Count % MCRConstant.CLUSTER_VERTEX_COUNT) == 0 && allVertexList.Count > 0) { allClusterList.Add(BuildCluster(allVertexList)); } } } } int packCout = allVertexList.Count - (MCRConstant.CLUSTER_VERTEX_COUNT * allClusterList.Count); //完了之后看看顶点数是否刚好够,不够的话,补上去 if (packCout > 0) { int dt = MCRConstant.CLUSTER_VERTEX_COUNT - packCout; for (int i = 0; i < dt; i++) { VertexInfo info = allVertexList[allVertexList.Count - 1]; allVertexList.Add(info); } allClusterList.Add(BuildCluster(allVertexList)); } AddRedundancyCluster(allClusterList); //保存cluster SaveClustetInfo(allClusterList, allVertexList, fullSavedAssetsPath); mcrScene.context.ClusterInfoAssetsPath = fullSavedAssetsPath.Replace(MCRConstant.BakeAssetSavePath + "/", string.Empty); mcrScene.context.ClusterCount = allClusterList.Count; mcrScene.context.VertexCount = allVertexList.Count; }