Exemplo n.º 1
0
        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();
        }
Exemplo n.º 4
0
        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;
        }