public GameObject CreateMesh(CityModel cityModel, Vector3RD origin)
        {
            GameObject container = new GameObject();

            //Terraindata terrainData = container.AddComponent<Terraindata>();

            verts = GetVerts(cityModel, origin);
            List <Vector3> newVerts = new List <Vector3>();

            triangleLists = GetTriangleLists(cityModel);

            Vector2Int textureSize = ObjectIDMapping.GetTextureSize(triangleLists.Count);

            Debug.Log(textureSize);

            Mesh mesh = new Mesh();

            List <int>     triangles      = new List <int>();
            List <string>  objectIDs      = new List <string>();
            List <Vector2> uvs            = new List <Vector2>();
            List <int>     vectorIDs      = new List <int>();
            List <int>     triangleCount  = new List <int>();
            int            objectIDNumber = 0;
            int            vertexCounter  = 0;

            foreach (var item in triangleLists)
            {
                vertexCounter = 0;
                Vector2 uv = ObjectIDMapping.GetUV(objectIDNumber, textureSize);
                foreach (int vertexIndex in item.Value)
                {
                    newVerts.Add(verts[vertexIndex]);
                    uvs.Add(uv);
                    vectorIDs.Add(objectIDNumber);
                    triangles.Add(newVerts.Count - 1);
                    vertexCounter++;
                }
                triangleCount.Add(vertexCounter);
                objectIDs.Add(item.Key);
                objectIDNumber++;
            }

            mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
            mesh.vertices    = newVerts.ToArray();
            mesh.triangles   = triangles.ToArray();
            mesh.uv          = uvs.ToArray();
            //mesh.RecalculateNormals();
            //mesh.Optimize();
            container.AddComponent <MeshFilter>().mesh = mesh;
            ObjectMapping objectMapping = container.AddComponent <ObjectMapping>();

            objectMapping.vectorIDs     = vectorIDs;
            objectMapping.BagID         = objectIDs;
            objectMapping.TriangleCount = triangleCount;
            return(container);
        }
Example #2
0
        /// <summary>
        /// Combine all the children of this tile into a single mesh
        /// </summary>
        /// <param name="buildingTile">Target tile</param>
        /// <param name="worldPosition">Original position to move the tile to for previewing it</param>
        private void CreateBuildingTile(GameObject buildingTile, Vector3 worldPosition)
        {
            MeshFilter[]      meshFilters = buildingTile.GetComponentsInChildren <MeshFilter>();
            CombineInstance[] combine     = new CombineInstance[meshFilters.Length];

            //Construct the seperate metadata containing the seperation of the buildings
            ObjectMappingClass buildingMetaData = ScriptableObject.CreateInstance <ObjectMappingClass>();

            buildingMetaData.ids = new List <string>();
            foreach (var meshFilter in meshFilters)
            {
                buildingMetaData.ids.Add(meshFilter.gameObject.name);
            }
            var            textureSize         = ObjectIDMapping.GetTextureSize(buildingMetaData.ids.Count);
            List <Vector2> allObjectUVs        = new List <Vector2>();
            List <int>     allVectorMapIndices = new List <int>();

            buildingMetaData.uvs = allObjectUVs.ToArray();

            //Generate the combined tile mesh
            buildingTile.transform.position = Vector3.zero;

            string assetFileName         = unityMeshAssetFolder + buildingTile.name + ".asset";
            string assetMetaDataFileName = unityMeshAssetFolder + buildingTile.name + "-data.asset";

            var totalVertexCount = 0;

            for (int i = 0; i < combine.Length; i++)
            {
                combine[i].transform = meshFilters[i].transform.localToWorldMatrix;
                Mesh buildingMesh = meshFilters[i].sharedMesh;
                totalVertexCount += buildingMesh.vertexCount;
                //Create UVS
                var buildingUV = ObjectIDMapping.GetUV(i, textureSize);
                for (int v = 0; v < buildingMesh.vertexCount; v++)
                {
                    //UV count should match vert count
                    allObjectUVs.Add(buildingUV);
                    //Create vector map reference for vert
                    allVectorMapIndices.Add(i);
                }

                combine[i].mesh = buildingMesh;
                meshFilters[i].gameObject.SetActive(false);
            }
            //Now add all the combined uvs to our metadata
            buildingMetaData.uvs       = allObjectUVs.ToArray();
            buildingMetaData.vectorMap = allVectorMapIndices;

            Mesh newCombinedMesh = new Mesh();

            if (totalVertexCount > Mathf.Pow(2, 16))
            {
                newCombinedMesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
            }

            if (meshFilters.Length > 0)
            {
                newCombinedMesh.name = buildingTile.name;
                newCombinedMesh.CombineMeshes(combine, true);
                newCombinedMesh.RecalculateNormals();
                newCombinedMesh.Optimize();

                //And clean up memory
                for (int i = 0; i < combine.Length; i++)
                {
                    Destroy(meshFilters[i].sharedMesh);
                    Destroy(meshFilters[i].gameObject);
                }
            }
            if (renderInViewport)
            {
                buildingTile.AddComponent <MeshFilter>().sharedMesh = newCombinedMesh;
                buildingTile.AddComponent <MeshRenderer>().material = DefaultMaterial;
                buildingTile.transform.position = worldPosition;
            }
            else
            {
                Destroy(buildingTile);
            }

#if UNITY_EDITOR
            if (generateAssetFiles)
            {
                AssetDatabase.CreateAsset(newCombinedMesh, assetFileName);
                AssetDatabase.CreateAsset(buildingMetaData, assetMetaDataFileName);
                AssetDatabase.SaveAssets();
            }
#endif
        }