Exemple #1
0
        public static void CombineMesh(Transform source, Transform target, bool deleteOriginal, bool splitSectors)
        {
            var originalPos = source.transform.position;

            source.transform.position = Vector3.zero;
            MeshFilter[]      allFilters  = source.GetComponentsInChildren <MeshFilter>();
            List <MeshFilter> meshFilters = new List <MeshFilter>();

            for (int i = 0; i < allFilters.Length; i++)
            {
                if (allFilters[i] == null || allFilters[i].transform.parent.GetComponent <LODGroup>() != null ||
                    !allFilters[i].gameObject.isStatic)
                {
                    continue;
                }
                meshFilters.Add(allFilters[i]);
            }
            Dictionary <Point3, List <MeshCombiner> > sectorMeshCombines = new Dictionary <Point3, List <MeshCombiner> >();
            List <MeshCombiner> meshCombines = null;
            MeshCombiner        current      = null;

            if (!splitSectors)
            {
                meshCombines = new List <MeshCombiner>();
                current      = new MeshCombiner();
                meshCombines.Add(current);
            }
            int errorCnt = 0;

            for (int i = 0; i < meshFilters.Count; i++)
            {
                var          meshFilter   = meshFilters[i];
                MeshRenderer meshRenderer = meshFilter.GetComponent <MeshRenderer>();
                if (meshRenderer == null)
                {
                    continue;
                }
                meshRenderer.enabled = !deleteOriginal;
                if (splitSectors)
                {
                    var secPos = Game.WorldToSector(meshFilter.transform.position);
                    if (!sectorMeshCombines.TryGetValue(secPos, out meshCombines))
                    {
                        meshCombines = new List <MeshCombiner>();
                        sectorMeshCombines.Add(secPos, meshCombines);
                        current = new MeshCombiner();
                        meshCombines.Add(current);
                    }
                    else
                    {
                        current = meshCombines.LastElement();
                    }
                }
                var mesh = Application.isPlaying ? meshFilter.mesh : meshFilter.sharedMesh;
                if (mesh.GetInstanceID() < 0)   //is already combined
                {
                    continue;
                }
                for (int m = 0; m < mesh.subMeshCount; m++)
                {
                    var matList = Application.isPlaying ? meshRenderer.materials : meshRenderer.sharedMaterials;
                    if (m >= matList.Length || m >= mesh.subMeshCount)
                    {
                        if (errorCnt < 50)
                        {
                            errorCnt++;
                            Debug.LogError(
                                string.Format(
                                    "MeshCombine: GameObject {0} is missing a material",
                                    meshRenderer.name));
                        }
                        continue;
                    }
                    Material mat = matList[m];
                    if (!current.CanAdd(mesh.vertexCount))
                    {
                        current = new MeshCombiner();
                        meshCombines.Add(current);
                    }
                    current.AddMesh(meshFilter, mat, m);
                }
            }
            if (splitSectors)
            {
                foreach (var combine in sectorMeshCombines)
                {
                    var created = BuildCombineList(combine.Value, target, deleteOriginal, combine.Key.ToString());
                    for (int i = 0; i < created.Count; i++)
                    {
                        World.Get <CullingSystem>().Add(combine.Key, created[i]);
                    }
                }
            }
            else
            {
                BuildCombineList(meshCombines, target, deleteOriginal, source.name);
            }
            source.transform.position = originalPos;
            if (!deleteOriginal)
            {
                return;
            }
            for (int i = 0; i < meshFilters.Count; i++)
            {
                if (meshFilters[i] != null && meshFilters[i].gameObject.isStatic)
                {
                    UnityEngine.Object.DestroyImmediate(meshFilters[i].gameObject);
                }
            }
            var childTr = source.GetComponentsInChildren <Transform>();

            for (int i = 0; i < childTr.Length; i++)
            {
                if (childTr[i] == null ||
                    childTr[i].transform.childCount > 0 || !childTr[i].CompareTag(StringConst.TagDummy))
                {
                    continue;
                }
                UnityEngine.Object.DestroyImmediate(childTr[i].gameObject);
            }
        }
Exemple #2
0
        public static void CombineMesh(Transform source, Transform target, bool deleteOriginal, bool splitSectors)
        {
            var originalPos = source.transform.position;

            source.transform.position = Vector3.zero;
            MeshFilter[]      allFilters  = source.GetComponentsInChildren <MeshFilter>();
            List <MeshFilter> meshFilters = new List <MeshFilter>();

            for (int i = 0; i < allFilters.Length; i++)
            {
                if (allFilters[i] == null || allFilters[i].transform.parent.GetComponent <LODGroup>() != null ||
                    !allFilters[i].gameObject.isStatic)
                {
                    continue;
                }
                meshFilters.Add(allFilters[i]);
            }
            Dictionary <Point3, List <MeshCombiner> > sectorMeshCombines = new Dictionary <Point3, List <MeshCombiner> >();
            List <MeshCombiner> meshCombines = null;
            MeshCombiner        current      = null;

            if (!splitSectors)
            {
                meshCombines = new List <MeshCombiner>();
                current      = new MeshCombiner();
                meshCombines.Add(current);
            }
            int errorCnt = 0;

            for (int i = 0; i < meshFilters.Count; i++)
            {
                var          meshFilter   = meshFilters[i];
                MeshRenderer meshRenderer = meshFilter.GetComponent <MeshRenderer>();
                if (meshRenderer == null)
                {
                    continue;
                }
                meshRenderer.enabled = !deleteOriginal;
                if (splitSectors)
                {
                    var secPos = Game.WorldToSector(meshFilter.transform.position);
                    if (!sectorMeshCombines.TryGetValue(secPos, out meshCombines))
                    {
                        meshCombines = new List <MeshCombiner>();
                        sectorMeshCombines.Add(secPos, meshCombines);
                        current = new MeshCombiner();
                        meshCombines.Add(current);
                    }
                    else
                    {
                        current = meshCombines.LastElement();
                    }
                }
                var mesh = meshFilter.sharedMesh;
                //var mesh = Application.isPlaying ? meshFilter.mesh : meshFilter.sharedMesh;
                if (mesh.GetInstanceID() < 0)   //is already combined
                {
                    continue;
                }
                for (int m = 0; m < mesh.subMeshCount; m++)
                {
                    var matList = meshRenderer.sharedMaterials;
                    //var matList = Application.isPlaying ? meshRenderer.materials : meshRenderer.sharedMaterials;
                    if (m >= matList.Length || m >= mesh.subMeshCount)
                    {
                        if (errorCnt < 50)
                        {
                            errorCnt++;
                            Debug.LogError(
                                string.Format(
                                    "MeshCombine: GameObject {0} is missing a material",
                                    meshRenderer.name));
                        }
                        continue;
                    }
                    Material mat = matList[m];
                    if (!current.CanAdd(mesh.vertexCount))
                    {
                        current = new MeshCombiner();
                        meshCombines.Add(current);
                    }
                    current.AddMesh(meshFilter, mat, m);
                }
            }
            Transform createPivot = null;

            if (splitSectors)
            {
                foreach (var combine in sectorMeshCombines)
                {
                    var created = BuildCombineList(combine.Value, target, deleteOriginal, combine.Key.ToString());
                    for (int i = 0; i < created.Count; i++)
                    {
                        World.Get <CullingSystem>().Add(combine.Key, created[i]);
                    }
                    createPivot = created[0].transform;
                }
            }
            else
            {
                createPivot = BuildCombineList(meshCombines, target, deleteOriginal, source.name)[0].transform;
            }
            source.position = originalPos;
            if (!deleteOriginal || createPivot == null)
            {
                return;
            }
            var childTr = source.GetComponentsInChildren <Transform>(true);
            Dictionary <Point3, Dictionary <int, Transform> > colliderDict = new Dictionary <Point3, Dictionary <int, Transform> >();

            colliderDict.Add(createPivot.rotation.eulerAngles.toPoint3(), new Dictionary <int, Transform>()
            {
                { createPivot.gameObject.layer, createPivot }
            });
            for (int i = 0; i < meshFilters.Count; i++)
            {
                if (meshFilters[i] == null)
                {
                    continue;
                }
                if (meshFilters[i].gameObject.isStatic)
                {
                    DeleteObject(createPivot, meshFilters[i].gameObject, colliderDict);
                }
            }
            for (int i = 0; i < childTr.Length; i++)
            {
                if (childTr[i] == null)
                {
                    continue;
                }
                if (childTr[i].transform.childCount > 0 || childTr[i].CompareTag(StringConst.TagCreated) || childTr[i].CompareTag(StringConst.TagDoNotDisable))
                {
                    continue;
                }
                if (childTr[i].CompareTag(StringConst.TagDeleteObject))
                {
                    DeleteObject(createPivot, childTr[i].gameObject, colliderDict);
                    continue;
                }
                childTr[i].GetComponents <Component>(_monoList);
                bool foundScripts = false;
                for (int j = 0; j < _monoList.Count; j++)
                {
                    var mono = _monoList[j];
                    if (mono is Transform)
                    {
                        continue;
                    }
                    foundScripts = true;
                    break;
                }
                if (foundScripts)
                {
                    continue;
                }
                DeleteObject(createPivot, childTr[i].gameObject, colliderDict);
            }
        }