private Dictionary <string, List <int> > GetTriangleLists(CityModel cityModel) { Dictionary <string, List <int> > triangleList = new Dictionary <string, List <int> >(); // string = objectID // List<int> = triangles string cityObjectType = ""; foreach (JSONNode cityObject in cityModel.cityjsonNode["CityObjects"]) { cityObjectType = cityObject["type"]; // Skip non-Buildings string objectID = GetObjectID("identificatie", cityObject); if (objectID == "") { objectID = GetObjectID("name", cityObject); } if (triangleList.ContainsKey(objectID) == true) { triangleList[objectID].AddRange(ReadTriangles(cityObject)); } else { triangleList.Add(objectID, ReadTriangles(cityObject)); } } return(triangleList); }
public List <Vector3RD> GetTriangleListRD(CityModel cityModel, string cityObjectType, string bgtProperty, List <string> bgtValues, bool include) { List <Vector3RD> vertsRD = GetVertsRD(cityModel); List <Vector3RD> triangleList = new List <Vector3RD>(); List <int> triangles = new List <int>(); bool Include; foreach (JSONNode cityObject in cityModel.cityjsonNode["CityObjects"]) { Include = !include; if (cityObject["type"] == cityObjectType) { if (bgtValues == null) { Include = !Include; } else if (bgtValues.Contains(cityObject["attributes"][bgtProperty])) { Include = !Include; } if (Include) { triangles.AddRange(ReadTriangles(cityObject)); } } } for (int i = 0; i < triangles.Count; i++) { triangleList.Add(vertsRD[triangles[i]]); } return(triangleList); }
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); }
private Dictionary <string, List <int> > GetTriangleLists(CityModel cityModel) { Dictionary <string, List <int> > triangleList = new Dictionary <string, List <int> >(); triangleList.Add("LandUse", new List <int>()); triangleList.Add("PlantCover", new List <int>()); triangleList.Add("Bridge", new List <int>()); triangleList.Add("Road", new List <int>()); triangleList.Add("Railway", new List <int>()); triangleList.Add("TransportSquare", new List <int>()); triangleList.Add("WaterBody", new List <int>()); triangleList.Add("GenericCityObject", new List <int>()); triangleList.Add("Building", new List <int>()); string cityObjectType = ""; foreach (JSONNode cityObject in cityModel.cityjsonNode["CityObjects"]) { cityObjectType = cityObject["type"]; // Skip Buildings //if (cityObjectType =="Building") //{ // continue; //} // Skip Bridges //if (cityObjectType == "Bridge") //{ // continue; //} if (cityObjectType == "LandUse") { string property = cityObject["attributes"]["bgt_fysiekvoorkomen"].Value; property = cityObject["attributes"]["bgt_functie"].Value; if (fysiek_voorkomen.Contains(property) == false) { fysiek_voorkomen.Add(property); } } if (triangleList.ContainsKey(cityObjectType) == true) { triangleList[cityObjectType].AddRange(ReadTriangles(cityObject)); } else { Debug.Log("cityObject: " + cityObjectType); } } return(triangleList); }
static private List <Vector3RD> GetVertsRD(CityModel cityModel) { List <Vector3RD> vertsRD = new List <Vector3RD>(); Vector3RD vertexCoordinate = new Vector3RD(); foreach (Vector3Double vertex in cityModel.vertices) { vertexCoordinate.x = vertex.x; vertexCoordinate.y = vertex.y; vertexCoordinate.z = vertex.z; vertsRD.Add(vertexCoordinate); } return(vertsRD); }
private List <Vector3RD> GetVertsRD(CityModel cityModel) { List <Vector3RD> vertsRD = new List <Vector3RD>(); Vector3 vertexCoordinate = new Vector3(); foreach (Vector3Double vertex in cityModel.vertices) { vertexCoordinate.x = (float)vertex.x; vertexCoordinate.y = (float)vertex.z; vertexCoordinate.z = (float)vertex.y; vertsRD.Add(CoordConvert.UnitytoRD(vertexCoordinate)); } return(vertsRD); }
private List <Vector3> GetVerts(CityModel cityModel, Vector3RD origin) { List <Vector3> verts = new List <Vector3>(); Vector3 unityOrigin = CoordConvert.RDtoUnity(origin); Vector3RD vertexCoordinate = new Vector3RD(); foreach (Vector3Double vertex in cityModel.vertices) { vertexCoordinate.x = vertex.x; vertexCoordinate.y = vertex.y; vertexCoordinate.z = vertex.z; verts.Add(CoordConvert.RDtoUnity(vertexCoordinate) - unityOrigin); } return(verts); }
public GameObject CreateMesh(CityModel cityModel, Vector3RD origin) { GameObject container = new GameObject(); //Terraindata terrainData = container.AddComponent<Terraindata>(); verts = GetVerts(cityModel, origin); triangleLists = GetTriangleLists(cityModel); Mesh mesh = new Mesh(); mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; mesh.SetVertices(verts.ToArray()); mesh.subMeshCount = triangleLists.Count; int submeshnumber = 0; foreach (var item in triangleLists) { //terrainData.terrainTypes.Add(item.Key); //if (submeshnumber==0 || submeshnumber==1) //{ mesh.SetTriangles(item.Value.ToArray(), submeshnumber); //} submeshnumber++; } mesh.RecalculateNormals(); mesh.Optimize(); container.AddComponent <MeshFilter>().mesh = mesh; container.AddComponent <MeshRenderer>().sharedMaterials = new Material[submeshnumber]; return(container); }
static void ImportSingle(double OriginX, double OriginY) { double originX = OriginX; double originY = OriginY; string basefilepath = "E:/TiledData/Terrain1000x1000/"; string jsonfilename = originX.ToString() + "-" + originY.ToString() + ".json"; float tileSize = 1000; string filepath = basefilepath; Debug.Log(filepath); if (File.Exists(filepath + jsonfilename)) { CityModel cm = new CityModel(filepath, jsonfilename); //type voetpad Mesh RoadsvoetpadMesh = CreateCityObjectMesh(cm, "Road", originX, originY, tileSize, "bgt_functie", new List <string> { "voetpad", "voetgangersgebied", "ruiterpad", "voetpad op trap" }, true); Mesh LandUseVoetpadMesh = CreateCityObjectMesh(cm, "LandUse", originX, originY, tileSize, "bgt_fysiekvoorkomen", new List <string> { "open verharding" }, true); LandUseVoetpadMesh = SimplifyMesh(LandUseVoetpadMesh, 0.05f); //combine meshes of type "voetpad" CombineInstance[] voetpadcombi = new CombineInstance[2]; voetpadcombi[0].mesh = RoadsvoetpadMesh; voetpadcombi[1].mesh = LandUseVoetpadMesh; Mesh voetpadmesh = new Mesh(); voetpadmesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; voetpadmesh.CombineMeshes(voetpadcombi, true, false); //type fietspad Mesh fietspadMesh = CreateCityObjectMesh(cm, "Road", originX, originY, tileSize, "bgt_functie", new List <string> { "fietspad" }, true); //type parkeervak Mesh parkeervlakMesh = CreateCityObjectMesh(cm, "Road", originX, originY, tileSize, "bgt_functie", new List <string> { "parkeervlak" }, true); //type spoorbaan Mesh spoorbaanMesh = CreateCityObjectMesh(cm, "Road", originX, originY, tileSize, "bgt_functie", new List <string> { "spoorbaan" }, true); //type woonerf Mesh WoonerfMesh = CreateCityObjectMesh(cm, "Road", originX, originY, tileSize, "bgt_functie", new List <string> { "transitie", "woonerf" }, true); // type weg Mesh roadsMesh = CreateCityObjectMesh(cm, "Road", originX, originY, tileSize, "bgt_functie", new List <string> { "fietspad", "parkeervlak", "ruiterpad", "spoorbaan", "voetgangersgebied", "voetpad", "voetpad op trap", "woonerf" }, false); Mesh LandUseVerhardMesh = CreateCityObjectMesh(cm, "LandUse", originX, originY, tileSize, "bgt_fysiekvoorkomen", new List <string> { "gesloten verharding" }, true); LandUseVerhardMesh = SimplifyMesh(LandUseVerhardMesh, 0.05f); // combine meshes of type "weg" CombineInstance[] wegcombi = new CombineInstance[2]; wegcombi[0].mesh = roadsMesh; wegcombi[1].mesh = LandUseVerhardMesh; Mesh wegmesh = new Mesh(); wegmesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; wegmesh.CombineMeshes(wegcombi, true, false); // type groen Mesh plantcoverMesh = CreateCityObjectMesh(cm, "PlantCover", originX, originY, tileSize, "bgt_fysiekvoorkomen", new List <string> { "alles" }, false); Mesh LanduseGroenMesh = CreateCityObjectMesh(cm, "LandUse", originX, originY, tileSize, "bgt_fysiekvoorkomen", new List <string> { "groenvoorziening" }, true); LanduseGroenMesh = SimplifyMesh(LanduseGroenMesh, 0.05f); //combine meshes of type "groen" CombineInstance[] groencombi = new CombineInstance[2]; groencombi[0].mesh = plantcoverMesh; groencombi[1].mesh = LanduseGroenMesh; Mesh groenMesh = new Mesh(); groenMesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; groenMesh.CombineMeshes(groencombi, true, false); //type erf Mesh erfMesh = CreateCityObjectMesh(cm, "LandUse", originX, originY, tileSize, "bgt_fysiekvoorkomen", new List <string> { "erf" }, true); erfMesh = SimplifyMesh(erfMesh, 0.05f); //type onverhard Mesh LandUseMesh = CreateCityObjectMesh(cm, "LandUse", originX, originY, tileSize, "bgt_fysiekvoorkomen", new List <string> { "erf", "groenvoorziening", "gesloten verharding", "open verharding" }, false); LandUseMesh = SimplifyMesh(LandUseMesh, 0.05f); Mesh genericCityObjectMesh = CreateCityObjectMesh(cm, "GenericCityObject", originX, originY, tileSize, "bgt_type", null, true); Mesh waterBodyMesh = CreateCityObjectMesh(cm, "WaterBody", originX, originY, tileSize, "bgt_type", null, true); Mesh bridgeMesh = CreateCityObjectMesh(cm, "Bridge", originX, originY, tileSize, "bgt_type", null, true); //create LOD1 Mesh CombineInstance[] combi = new CombineInstance[12]; combi[0].mesh = voetpadmesh; // combi[1].mesh = fietspadMesh; // combi[2].mesh = parkeervlakMesh; // combi[3].mesh = wegmesh; // combi[4].mesh = groenMesh; // combi[5].mesh = erfMesh; // combi[6].mesh = LandUseMesh; // combi[7].mesh = spoorbaanMesh; // combi[8].mesh = WoonerfMesh; // combi[9].mesh = genericCityObjectMesh; combi[10].mesh = bridgeMesh; combi[11].mesh = waterBodyMesh; ; Mesh lod1Mesh = new Mesh(); lod1Mesh.CombineMeshes(combi, false, false); lod1Mesh.uv2 = RDuv2(lod1Mesh.vertices, CoordConvert.RDtoUnity(new Vector3RD(originX, originY, 0)), tileSize); Physics.BakeMesh(lod1Mesh.GetInstanceID(), false); AssetDatabase.CreateAsset(lod1Mesh, "Assets/terrainMeshes/LOD0/terrain_" + originX + "-" + originY + "-lod1.mesh"); //for debug //GetComponent<MeshFilter>().sharedMesh = lod1Mesh; //create LOD0MEsh combi = new CombineInstance[5]; combi[0].mesh = voetpadmesh; combi[1].mesh = fietspadMesh; combi[2].mesh = parkeervlakMesh; combi[3].mesh = wegmesh; combi[4].mesh = spoorbaanMesh; Mesh Roads = new Mesh(); Roads.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; Roads.CombineMeshes(combi, true, false); Roads = SimplifyMesh(Roads, 0.05f); combi = new CombineInstance[3]; combi[0].mesh = erfMesh; combi[1].mesh = LandUseMesh; combi[2].mesh = WoonerfMesh; Mesh landuse = new Mesh(); landuse.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; landuse.CombineMeshes(combi, true, false); landuse = SimplifyMesh(landuse, 0.05f); combi = new CombineInstance[12]; combi[0].mesh = CreateEmptyMesh(); // combi[1].mesh = CreateEmptyMesh(); // combi[2].mesh = CreateEmptyMesh(); // combi[3].mesh = Roads; // combi[4].mesh = SimplifyMesh(groenMesh, 0.05f); // combi[5].mesh = CreateEmptyMesh(); // combi[6].mesh = landuse; // combi[7].mesh = CreateEmptyMesh(); // combi[8].mesh = CreateEmptyMesh(); // combi[9].mesh = genericCityObjectMesh; combi[10].mesh = bridgeMesh; combi[11].mesh = waterBodyMesh; Mesh lod0Mesh = new Mesh(); lod0Mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; lod0Mesh.CombineMeshes(combi, false, false); lod0Mesh.uv2 = RDuv2(lod0Mesh.vertices, CoordConvert.RDtoUnity(new Vector3RD(originX, originY, 0)), tileSize); Physics.BakeMesh(lod0Mesh.GetInstanceID(), false); AssetDatabase.CreateAsset(lod0Mesh, "Assets/terrainMeshes/LOD0/terrain_" + originX + "-" + originY + "-lod0.mesh"); } }
static private Mesh CreateCityObjectMesh(CityModel cityModel, string cityObjectType, double originX, double originY, float tileSize, string bgtProperty, List <string> bgtValues, bool include) { List <Vector3RD> RDTriangles = GetTriangleListRD(cityModel, cityObjectType, bgtProperty, bgtValues, include); List <Vector3RD> clippedRDTriangles = new List <Vector3RD>(); List <Vector3> vectors = new List <Vector3>(); List <Vector3> clipboundary = CreateClippingPolygon(tileSize); if (RDTriangles.Count == 0) { return(CreateEmptyMesh()); } //clip all the triangles for (int i = 0; i < RDTriangles.Count; i += 3) { if (PointISInsideArea(RDTriangles[i], originX, originY, tileSize) && PointISInsideArea(RDTriangles[i + 1], originX, originY, tileSize) && PointISInsideArea(RDTriangles[i + 2], originX, originY, tileSize)) { clippedRDTriangles.Add(RDTriangles[i + 2]); clippedRDTriangles.Add(RDTriangles[i + 1]); clippedRDTriangles.Add(RDTriangles[i]); continue; } //offset RDvertices so coordinates can be saved as a float // flip y and z-axis so clippingtool works //reverse order to make them clockwise so the clipping-algorithm can use them vectors.Clear(); vectors.Add(new Vector3((float)(RDTriangles[i + 2].x - originX), (float)RDTriangles[i + 2].z, (float)(RDTriangles[i + 2].y - originY))); vectors.Add(new Vector3((float)(RDTriangles[i + 1].x - originX), (float)RDTriangles[i + 1].z, (float)(RDTriangles[i + 1].y - originY))); vectors.Add(new Vector3((float)(RDTriangles[i].x - originX), (float)RDTriangles[i].z, (float)(RDTriangles[i].y - originY))); List <Vector3> defshape = Netherlands3D.Utilities.TriangleClipping.SutherlandHodgman.ClipPolygon(vectors, clipboundary); if (defshape.Count < 3) { continue; } if (defshape[0].x.ToString() == "NaN") { continue; } Vector3RD vectorRD = new Vector3RD(); // add first three vectors vectorRD.x = defshape[0].x + originX; vectorRD.y = defshape[0].z + originY; vectorRD.z = defshape[0].y; clippedRDTriangles.Add(vectorRD); vectorRD.x = defshape[1].x + originX; vectorRD.y = defshape[1].z + originY; vectorRD.z = defshape[1].y; clippedRDTriangles.Add(vectorRD); vectorRD.x = defshape[2].x + originX; vectorRD.y = defshape[2].z + originY; vectorRD.z = defshape[2].y; clippedRDTriangles.Add(vectorRD); // add extra vectors. vector makes a triangle with the first and the previous vector. for (int j = 3; j < defshape.Count; j++) { vectorRD.x = defshape[0].x + originX; vectorRD.y = defshape[0].z + originY; vectorRD.z = defshape[0].y; clippedRDTriangles.Add(vectorRD); vectorRD.x = defshape[j - 1].x + originX; vectorRD.y = defshape[j - 1].z + originY; vectorRD.z = defshape[j - 1].y; clippedRDTriangles.Add(vectorRD); vectorRD.x = defshape[j].x + originX; vectorRD.y = defshape[j].z + originY; vectorRD.z = defshape[j].y; clippedRDTriangles.Add(vectorRD); } } //createMesh List <Vector3> verts = new List <Vector3>(); Vector3RD tileCenterRD = new Vector3RD(); tileCenterRD.x = originX + (tileSize / 2); tileCenterRD.y = originY + (tileSize / 2); tileCenterRD.z = 0; Vector3 tileCenterUnity = CoordConvert.RDtoUnity(tileCenterRD); List <int> ints = new List <int>(); for (int i = 0; i < clippedRDTriangles.Count; i++) { Vector3 coord = CoordConvert.RDtoUnity(clippedRDTriangles[i]) - tileCenterUnity; ints.Add(i); verts.Add(coord); } ints.Reverse(); //reverse the trianglelist to make the triangles counter-clockwise again if (ints.Count == 0) { return(CreateEmptyMesh()); } Mesh mesh = new Mesh(); mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; mesh.vertices = verts.ToArray(); mesh.triangles = ints.ToArray(); mesh = WeldVertices(mesh); mesh.RecalculateNormals(); mesh.Optimize(); return(mesh); }