public void CreateBuilding(OnlineMapsBuildingsNodeData data) { if (OnCreateBuilding != null && !OnCreateBuilding(data)) { return; } if (buildings.ContainsKey(data.way.id) || unusedBuildings.ContainsKey(data.way.id)) { return; } int initialZoom = map.buffer.renderState.zoom; OnlineMapsBuildingBase building = OnlineMapsBuildingBuiltIn.Create(this, data.way, data.nodes); if (building != null) { building.LoadMeta(data.way); if (OnBuildingCreated != null) { OnBuildingCreated(building); } unusedBuildings.Add(data.way.id, building); if (Math.Abs(map.buffer.lastState.floatZoom - initialZoom) > float.Epsilon) { UpdateBuildingScale(building); } building.transform.localScale.Scale(new Vector3(1, heightScale, 1)); } else { //Debug.Log("Null building"); } }
public void CreateBuilding(OnlineMapsBuildingsNodeData data) { if (OnCreateBuilding != null && !OnCreateBuilding(data)) { return; } if (buildings.ContainsKey(data.way.id) || unusedBuildings.ContainsKey(data.way.id)) { return; } OnlineMapsBuildingBase building = null; building = OnlineMapsBuildingBuiltIn.Create(this, data.way, data.nodes); if (building != null) { building.LoadMeta(data.way); if (OnBuildingCreated != null) { OnBuildingCreated(building); } unusedBuildings.Add(data.way.id, building); } }
/// <summary> /// Creates a new building based on data /// </summary> /// <param name="data">Building data</param> public void CreateBuilding(OnlineMapsBuildingsNodeData data) { if (OnCreateBuilding != null && !OnCreateBuilding(data)) { return; } if (buildings.ContainsKey(data.way.id) || unusedBuildings.ContainsKey(data.way.id)) { return; } int initialZoom = map.buffer.apiZoom; OnlineMapsBuildingBase building = OnlineMapsBuildingBuiltIn.Create(this, data.way, data.nodes); if (building != null) { building.LoadMeta(data.way); if (OnBuildingCreated != null) { OnBuildingCreated(building); } unusedBuildings.Add(data.way.id, building); if (map.buffer.apiZoom != initialZoom) { UpdateBuildingScale(building); } } else { //Debug.Log("Null building"); } }
private void GenerateBuildings() { long startTicks = DateTime.Now.Ticks; const int maxTicks = 500000; lock (newBuildingsData) { while (newBuildingsData.Count > 0) { if (maxBuilding > 0 && unusedBuildings.Count + buildings.Count >= maxBuilding) { break; } OnlineMapsBuildingsNodeData data = newBuildingsData[0]; newBuildingsData.RemoveAt(0); if (OnCreateBuilding != null && !OnCreateBuilding(data)) { data.Dispose(); continue; } if (buildings.ContainsKey(data.way.id) || unusedBuildings.ContainsKey(data.way.id)) { data.Dispose(); continue; } OnlineMapsBuildingBase building = OnlineMapsBuildingBuiltIn.Create(this, data.way, data.nodes); if (building != null) { building.LoadMeta(data.way); if (OnBuildingCreated != null) { OnBuildingCreated(building); } unusedBuildings.Add(data.way.id, building); } data.Dispose(); if (DateTime.Now.Ticks - startTicks > maxTicks) { break; } } } OnlineMapsBuildingBuiltIn.usedNodes = null; OnlineMapsBuildingBuiltIn.roofIndices = null; }
/// <summary> /// Creates a new building, based on Open Street Map. /// </summary> /// <param name="container">Reference to OnlineMapsBuildings.</param> /// <param name="way">Way of building.</param> /// <param name="nodes">Nodes obtained from Open Street Maps.</param> /// <returns>Building instance.</returns> public static OnlineMapsBuildingBase Create(OnlineMapsBuildings container, OnlineMapsOSMWay way, Dictionary <string, OnlineMapsOSMNode> nodes) { if (CheckIgnoredBuildings(way)) { return(null); } if (usedNodes == null) { usedNodes = new List <OnlineMapsOSMNode>(30); } else { usedNodes.Clear(); } way.GetNodes(nodes, usedNodes); List <Vector3> points = GetLocalPoints(usedNodes); if (points.Count < 3) { return(null); } if (points[0] == points[points.Count - 1]) { points.RemoveAt(points.Count - 1); } if (points.Count < 3) { return(null); } for (int i = 0; i < points.Count; i++) { int prev = i - 1; if (prev < 0) { prev = points.Count - 1; } int next = i + 1; if (next >= points.Count) { next = 0; } float a1 = OnlineMapsUtils.Angle2D(points[prev], points[i]); float a2 = OnlineMapsUtils.Angle2D(points[i], points[next]); if (Mathf.Abs(a1 - a2) < 5) { points.RemoveAt(i); i--; } } if (points.Count < 3) { return(null); } Vector4 cp = new Vector4(float.MaxValue, float.MaxValue, float.MinValue, float.MinValue); for (int i = 0; i < points.Count; i++) { Vector3 point = points[i]; if (point.x < cp.x) { cp.x = point.x; } if (point.z < cp.y) { cp.y = point.z; } if (point.x > cp.z) { cp.z = point.x; } if (point.z > cp.w) { cp.w = point.z; } } Vector3 centerPoint = new Vector3((cp.z + cp.x) / 2, 0, (cp.y + cp.w) / 2); for (int i = 0; i < points.Count; i++) { points[i] -= centerPoint; } bool generateWall = true; if (way.HasTagKey("building")) { string buildingType = way.GetTagValue("building"); if (buildingType == "roof") { generateWall = false; } } float baseHeight = 15; float roofHeight = 0; OnlineMapsBuildingMaterial material = GetRandomMaterial(container); Material wallMaterial; Material roofMaterial; Vector2 scale = Vector2.one; if (defaultShader == null) { defaultShader = Shader.Find("Diffuse"); } if (material != null) { if (material.wall != null) { wallMaterial = Instantiate(material.wall) as Material; } else { wallMaterial = new Material(defaultShader); } if (material.roof != null) { roofMaterial = Instantiate(material.roof) as Material; } else { roofMaterial = new Material(defaultShader); } scale = material.scale; } else { if (defaultWallMaterial == null) { defaultWallMaterial = new Material(defaultShader); } if (defaultRoofMaterial == null) { defaultRoofMaterial = new Material(defaultShader); } wallMaterial = Instantiate(defaultWallMaterial) as Material; roofMaterial = Instantiate(defaultRoofMaterial) as Material; } RoofType roofType = RoofType.flat; AnalizeHouseTags(way, ref wallMaterial, ref roofMaterial, ref baseHeight); AnalizeHouseRoofType(way, ref baseHeight, ref roofType, ref roofHeight); GameObject houseGO = CreateGameObject(way.id); MeshRenderer renderer = houseGO.AddComponent <MeshRenderer>(); MeshFilter meshFilter = houseGO.AddComponent <MeshFilter>(); Mesh mesh = new Mesh { name = way.id }; meshFilter.sharedMesh = mesh; renderer.sharedMaterials = new [] { wallMaterial, roofMaterial }; OnlineMapsBuildingBuiltIn building = houseGO.AddComponent <OnlineMapsBuildingBuiltIn>(); building.way = way; building.nodes = usedNodes; houseGO.transform.localPosition = centerPoint; houseGO.transform.localRotation = Quaternion.Euler(Vector3.zero); houseGO.transform.localScale = Vector3.one; Vector2 centerCoords = Vector2.zero; float minCX = float.MaxValue, minCY = float.MaxValue, maxCX = float.MinValue, maxCY = float.MinValue; foreach (OnlineMapsOSMNode node in usedNodes) { Vector2 nodeCoords = node; centerCoords += nodeCoords; if (nodeCoords.x < minCX) { minCX = nodeCoords.x; } if (nodeCoords.y < minCY) { minCY = nodeCoords.y; } if (nodeCoords.x > maxCX) { maxCX = nodeCoords.x; } if (nodeCoords.y > maxCY) { maxCY = nodeCoords.y; } } building.id = way.id; building.initialZoom = OnlineMaps.instance.zoom; building.centerCoordinates = new Vector2((maxCX + minCX) / 2, (maxCY + minCY) / 2); building.boundsCoords = new Bounds(building.centerCoordinates, new Vector3(maxCX - minCX, maxCY - minCY)); int wallVerticesCount = (points.Count + 1) * 2; int roofVerticesCount = points.Count; int verticesCount = wallVerticesCount + roofVerticesCount; int countTriangles = wallVerticesCount * 3; if (vertices == null) { vertices = new List <Vector3>(verticesCount); } else { vertices.Clear(); } if (uvs == null) { uvs = new List <Vector2>(verticesCount); } else { uvs.Clear(); } if (wallTriangles == null) { wallTriangles = new List <int>(countTriangles); } else { wallTriangles.Clear(); } if (roofTriangles == null) { roofTriangles = new List <int>(); } else { roofTriangles.Clear(); } if (generateWall) { building.CreateHouseWall(points, baseHeight, wallMaterial, scale); } building.CreateHouseRoof(points, baseHeight, roofHeight, roofType); if (building.hasErrors) { OnlineMapsUtils.DestroyImmediate(building.gameObject); return(null); } mesh.vertices = vertices.ToArray(); mesh.uv = uvs.ToArray(); mesh.subMeshCount = 2; mesh.SetTriangles(wallTriangles.ToArray(), 0); mesh.SetTriangles(roofTriangles.ToArray(), 1); mesh.RecalculateBounds(); mesh.RecalculateNormals(); building.buildingCollider = houseGO.AddComponent <MeshCollider>(); (building.buildingCollider as MeshCollider).sharedMesh = mesh; return(building); }