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); }
/// <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 }