public void MoveRelationsToWays(List <OnlineMapsOSMRelation> relations, Dictionary <string, OnlineMapsOSMWay> ways, Dictionary <string, OnlineMapsOSMNode> nodes) { List <string> waysInRelation = new List <string>(); foreach (OnlineMapsOSMRelation relation in relations) { MoveRelationToWay(relation, ways, waysInRelation, nodes); } foreach (string id in waysInRelation) { if (!ways.ContainsKey(id)) { continue; } OnlineMapsOSMWay way = ways[id]; way.Dispose(); ways.Remove(id); } foreach (KeyValuePair <string, OnlineMapsOSMWay> pair in ways) { newBuildingsData.Enqueue(new OnlineMapsBuildingsNodeData(pair.Value, nodes)); } }
private static void AnalizeHouseRoofType(OnlineMapsOSMWay way, ref float baseHeight, ref OnlineMapsBuildingRoofType roofType, ref float roofHeight) { string roofShape = way.GetTagValue("roof:shape"); string roofHeightStr = way.GetTagValue("roof:height"); string minHeightStr = way.GetTagValue("min_height"); if (!String.IsNullOrEmpty(roofShape)) { if ((roofShape == "dome" || roofShape == "pyramidal") && !String.IsNullOrEmpty(roofHeightStr)) { GetHeightFromString(roofHeightStr, ref roofHeight); baseHeight -= roofHeight; roofType = OnlineMapsBuildingRoofType.dome; } } else if (!String.IsNullOrEmpty(roofHeightStr)) { GetHeightFromString(roofHeightStr, ref roofHeight); baseHeight -= roofHeight; roofType = OnlineMapsBuildingRoofType.dome; } else if (!String.IsNullOrEmpty(minHeightStr)) { float totalHeight = baseHeight; GetHeightFromString(minHeightStr, ref baseHeight); roofHeight = totalHeight - baseHeight; roofType = OnlineMapsBuildingRoofType.dome; } }
private static void AnalizeHouseTags(OnlineMapsOSMWay way, ref Material wallMaterial, ref Material roofMaterial, ref float baseHeight) { string heightStr = way.GetTagValue("height"); string levelsStr = way.GetTagValue("building:levels"); GetHeightFromString(heightStr, ref baseHeight); if (String.IsNullOrEmpty(heightStr) && !String.IsNullOrEmpty(levelsStr)) { baseHeight = float.Parse(levelsStr) * OnlineMapsBuildings.instance.levelHeight; } else { baseHeight = Random.Range(OnlineMapsBuildings.instance.levelsRange.min, OnlineMapsBuildings.instance.levelsRange.max) * OnlineMapsBuildings.instance.levelHeight; } if (baseHeight < OnlineMapsBuildings.instance.minHeight) { baseHeight = OnlineMapsBuildings.instance.minHeight; } string colorStr = way.GetTagValue("building:colour"); if (!String.IsNullOrEmpty(colorStr)) { wallMaterial.color = roofMaterial.color = StringToColor(colorStr); } }
private static void AnalizeHouseRoofType(OnlineMapsOSMWay way, ref float baseHeight, ref RoofType roofType, ref float roofHeight) { string roofShape = way.GetTagValue("roof:shape"); string roofHeightStr = way.GetTagValue("roof:height"); string minHeightStr = way.GetTagValue("min_height"); if (!String.IsNullOrEmpty(roofShape)) { if ((roofShape == "dome" || roofShape == "pyramidal") && !String.IsNullOrEmpty(roofHeightStr)) { GetHeightFromString(roofHeightStr, ref roofHeight); baseHeight -= roofHeight; roofType = RoofType.dome; } } else if (!String.IsNullOrEmpty(roofHeightStr)) { GetHeightFromString(roofHeightStr, ref roofHeight); baseHeight -= roofHeight; roofType = RoofType.dome; } else if (!String.IsNullOrEmpty(minHeightStr)) { float totalHeight = baseHeight; GetHeightFromString(minHeightStr, ref baseHeight); roofHeight = totalHeight - baseHeight; roofType = RoofType.dome; } }
/// <summary> /// Fast way to get data from the response Open Street Map Overpass API. /// </summary> /// <param name="response">Response from Overpass API</param> /// <param name="nodes">Dictionary of nodes</param> /// <param name="ways">List of ways</param> /// <param name="relations">List of relations</param> public static void ParseOSMResponseFast(string response, out Dictionary <string, OnlineMapsOSMNode> nodes, out Dictionary <string, OnlineMapsOSMWay> ways, out List <OnlineMapsOSMRelation> relations) { int i = 0; OSMXMLNode rootNode = new OSMXMLNode(response, ref i); if (rootNode.childs == null) { nodes = new Dictionary <string, OnlineMapsOSMNode>(); ways = new Dictionary <string, OnlineMapsOSMWay>(); relations = new List <OnlineMapsOSMRelation>(); return; } int countNodes = 0; int countWays = 0; int countRelations = 0; for (int j = 0; j < rootNode.childs.Count; j++) { OSMXMLNode node = rootNode.childs[j]; if (node.name == "node") { countNodes++; } else if (node.name == "way") { countWays++; } else if (node.name == "relation") { countRelations++; } } nodes = new Dictionary <string, OnlineMapsOSMNode>(countNodes); ways = new Dictionary <string, OnlineMapsOSMWay>(countWays); relations = new List <OnlineMapsOSMRelation>(countRelations); for (int j = 0; j < rootNode.childs.Count; j++) { OSMXMLNode node = rootNode.childs[j]; if (node.name == "node") { nodes.Add(node.GetAttribute("id"), new OnlineMapsOSMNode(node)); } else if (node.name == "way") { OnlineMapsOSMWay way = new OnlineMapsOSMWay(node); if (!ways.ContainsKey(way.id)) { ways.Add(way.id, way); } } else if (node.name == "relation") { relations.Add(new OnlineMapsOSMRelation(node)); } } }
private static void AnalizeHouseTags(OnlineMapsBuildings container, OnlineMapsOSMWay way, ref Material wallMaterial, ref Material roofMaterial, ref float baseHeight) { string heightStr = container.useHeightTag? way.GetTagValue("height"): null; bool hasHeight = false; if (!string.IsNullOrEmpty(heightStr)) { hasHeight = GetHeightFromString(heightStr, ref baseHeight); } if (!hasHeight && container.useHeightTag) { string levelsStr = way.GetTagValue("building:levels"); if (!String.IsNullOrEmpty(levelsStr)) { float countLevels; if (float.TryParse(levelsStr, NumberStyles.AllowDecimalPoint, OnlineMapsUtils.numberFormat, out countLevels)) { baseHeight = countLevels * OnlineMapsBuildings.instance.levelHeight; hasHeight = true; } } } if (!hasHeight) { if (OnlineMapsBuildings.instance.OnGenerateBuildingHeight != null) { baseHeight = OnlineMapsBuildings.instance.OnGenerateBuildingHeight(way); } else { string minHeightStr = container.useHeightTag? way.GetTagValue("min_height"): null; if (!string.IsNullOrEmpty(minHeightStr)) { GetHeightFromString(minHeightStr, ref baseHeight); } else { baseHeight = Random.Range(OnlineMapsBuildings.instance.levelsRange.min, OnlineMapsBuildings.instance.levelsRange.max) * OnlineMapsBuildings.instance.levelHeight; } } } if (baseHeight < OnlineMapsBuildings.instance.minHeight) { baseHeight = OnlineMapsBuildings.instance.minHeight; } if (container.useColorTag) { string colorStr = way.GetTagValue("building:colour"); if (!String.IsNullOrEmpty(colorStr)) { wallMaterial.color = roofMaterial.color = StringToColor(colorStr); } } }
protected static bool CheckIgnoredBuildings(OnlineMapsOSMWay way) { if (way.GetTagValue("building") == "bridge") return true; string layer = way.GetTagValue("layer"); if (!String.IsNullOrEmpty(layer) && Int32.Parse(layer) < 0) return true; return false; }
private static void AnalizeHouseTags(OnlineMapsOSMWay way, ref Material wallMaterial, ref Material roofMaterial, ref float baseHeight) { string heightStr = way.GetTagValue("height"); string levelsStr = way.GetTagValue("building:levels"); GetHeightFromString(heightStr, ref baseHeight); if (String.IsNullOrEmpty(heightStr) && !String.IsNullOrEmpty(levelsStr)) baseHeight = float.Parse(levelsStr) * OnlineMapsBuildings.instance.levelHeight; else baseHeight = Random.Range(OnlineMapsBuildings.instance.levelsRange.min, OnlineMapsBuildings.instance.levelsRange.max) * OnlineMapsBuildings.instance.levelHeight; if (baseHeight < OnlineMapsBuildings.instance.minHeight) baseHeight = OnlineMapsBuildings.instance.minHeight; string colorStr = way.GetTagValue("building:colour"); if (!String.IsNullOrEmpty(colorStr)) wallMaterial.color = roofMaterial.color = StringToColor(colorStr); }
private static void AnalizeHouseTags(OnlineMapsOSMWay way, ref Material wallMaterial, ref Material roofMaterial, ref float baseHeight) { string heightStr = way.GetTagValue("height"); bool hasHeight = false; if (!string.IsNullOrEmpty(heightStr)) { hasHeight = GetHeightFromString(heightStr, ref baseHeight); } if (!hasHeight) { string levelsStr = way.GetTagValue("building:levels"); if (!String.IsNullOrEmpty(levelsStr)) { float countLevels; if (float.TryParse(levelsStr, out countLevels)) { baseHeight = countLevels * OnlineMapsBuildings.instance.levelHeight; hasHeight = true; } } } if (!hasHeight) { if (OnlineMapsBuildings.instance.OnGenerateBuildingHeight != null) { baseHeight = OnlineMapsBuildings.instance.OnGenerateBuildingHeight(way); } else { baseHeight = Random.Range(OnlineMapsBuildings.instance.levelsRange.min, OnlineMapsBuildings.instance.levelsRange.max) * OnlineMapsBuildings.instance.levelHeight; } } if (baseHeight < OnlineMapsBuildings.instance.minHeight) { baseHeight = OnlineMapsBuildings.instance.minHeight; } string colorStr = way.GetTagValue("building:colour"); if (!String.IsNullOrEmpty(colorStr)) { wallMaterial.color = roofMaterial.color = StringToColor(colorStr); } }
/// <summary> /// Checks ignore the building. /// </summary> /// <param name="way">Building way.</param> /// <returns>TRUE - ignore building, FALSE - generate building.</returns> protected static bool CheckIgnoredBuildings(OnlineMapsOSMWay way) { if (way.GetTagValue("building") == "bridge") { return(true); } string layer = way.GetTagValue("layer"); if (!String.IsNullOrEmpty(layer) && Int32.Parse(layer) < 0) { return(true); } return(false); }
/// <summary> /// Checks ignore the building. /// </summary> /// <param name="way">Building way.</param> /// <returns>TRUE - ignore building, FALSE - generate building.</returns> protected static bool CheckIgnoredBuildings(OnlineMapsOSMWay way) { string buildingType = way.GetTagValue("building"); if (buildingType == "bridge" || buildingType == "roof") { return(true); } string layer = way.GetTagValue("layer"); if (!string.IsNullOrEmpty(layer) && int.Parse(layer) < 0) { return(true); } return(false); }
private void MoveRelationToWay(OnlineMapsOSMRelation relation, Dictionary <string, OnlineMapsOSMWay> ways, List <string> waysInRelation, Dictionary <string, OnlineMapsOSMNode> nodes) { if (relation.members.Count == 0) { return; } OnlineMapsOSMWay way = new OnlineMapsOSMWay(); List <string> nodeRefs = new List <string>(); List <OnlineMapsOSMRelationMember> members = relation.members.Where(m => m.type == "way" && m.role == "outer").ToList(); if (members.Count == 0) { return; } OnlineMapsOSMWay relationWay; if (!ways.TryGetValue(members[0].reference, out relationWay) || relationWay == null) { return; } nodeRefs.AddRange(relationWay.nodeRefs); members.RemoveAt(0); while (members.Count > 0) { if (!MoveRelationMemberToWay(nodeRefs, members, ways)) { break; } } waysInRelation.AddRange(relation.members.Select(m => m.reference)); way.nodeRefs = nodeRefs; way.id = relation.id; way.tags = relation.tags; newBuildingsData.Enqueue(new OnlineMapsBuildingsNodeData(way, nodes)); }
private static bool MoveRelationMemberToWay(List <string> nodeRefs, List <OnlineMapsOSMRelationMember> members, Dictionary <string, OnlineMapsOSMWay> ways) { string lastRef = nodeRefs[nodeRefs.Count - 1]; int memberIndex = -1; for (int i = 0; i < members.Count; i++) { OnlineMapsOSMRelationMember member = members[i]; OnlineMapsOSMWay w = ways[member.reference]; if (w.nodeRefs[0] == lastRef) { nodeRefs.AddRange(w.nodeRefs.Skip(1)); memberIndex = i; break; } if (w.nodeRefs[w.nodeRefs.Count - 1] == lastRef) { List <string> refs = w.nodeRefs; refs.Reverse(); nodeRefs.AddRange(refs.Skip(1)); memberIndex = i; break; } } if (memberIndex != -1) { members.RemoveAt(memberIndex); } else { return(false); } return(true); }
/// <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); }
/// <summary> /// Disposes this object. /// </summary> public void Dispose() { way = null; nodes = null; }
/// <summary> /// Constructor /// </summary> /// <param name="way">Way of a building contour.</param> /// <param name="nodes">Dictionary of nodes.</param> public OnlineMapsBuildingsNodeData(OnlineMapsOSMWay way, Dictionary <string, OnlineMapsOSMNode> nodes) { this.way = way; this.nodes = nodes; }
public void Dispose() { way = null; nodes = null; }
public OnlineMapsBuildingsNodeData(OnlineMapsOSMWay way, Dictionary<string, OnlineMapsOSMNode> nodes) { this.way = way; this.nodes = nodes; }
/// <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; List<OnlineMapsOSMNode> usedNodes = way.GetNodes(nodes); 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); foreach (Vector3 point in points) { 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; } //centerPoint = points.Aggregate(centerPoint, (current, point) => current + point) / points.Count; Vector3 centerPoint = new Vector3((cp.z + cp.x) / 2, points.Min(p => p.y), (cp.y + cp.w) / 2); 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 defWallMaterial = (material != null)? material.wall: null; Material defRoofMaterial = (material != null) ? material.roof : null; Vector2 scale = (material != null) ? material.scale : Vector2.one; if (defWallMaterial == null) defWallMaterial = new Material(Shader.Find("Diffuse")); if (defRoofMaterial == null) defRoofMaterial = new Material(Shader.Find("Diffuse")); Material wallMaterial = new Material(defWallMaterial); Material roofMaterial = new Material(defRoofMaterial); OnlineMapsBuildingRoofType roofType = OnlineMapsBuildingRoofType.flat; AnalizeHouseTags(way, ref wallMaterial, ref roofMaterial, ref baseHeight); AnalizeHouseRoofType(way, ref baseHeight, ref roofType, ref roofHeight); Vector3[] baseVerticles = points.Select(p => p - centerPoint).ToArray(); 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>(); houseGO.transform.localPosition = centerPoint; houseGO.transform.localRotation = Quaternion.Euler(Vector3.zero); 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)); List<Vector3> vertices = new List<Vector3>(); List<Vector2> uvs = new List<Vector2>(); List<int> wallTriangles = new List<int>(); List<int> roofTriangles = new List<int>(); if (generateWall) building.CreateHouseWall(baseVerticles, baseHeight, wallMaterial, scale, ref vertices, ref uvs, ref wallTriangles); building.CreateHouseRoof(baseVerticles, baseHeight, roofHeight, roofType, ref vertices, ref uvs, ref roofTriangles); if (building.hasErrors) { 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; }
private void OnBuildingRequestComplete(string response) { osmRequest = null; Action action = () => { Dictionary <string, OnlineMapsOSMNode> nodes; List <OnlineMapsOSMWay> ways; List <OnlineMapsOSMRelation> relations; OnlineMapsOSMAPIQuery.ParseOSMResponseFast(response, out nodes, out ways, out relations); lock (newBuildingsData) { List <string> waysInRelation = new List <string>(); foreach (OnlineMapsOSMRelation relation in relations) { if (relation.members.Count == 0) { continue; } OnlineMapsOSMWay way = new OnlineMapsOSMWay(); List <string> nodeRefs = new List <string>(); List <OnlineMapsOSMRelationMember> members = relation.members.Where(m => m.type == "way" && m.role == "outer").ToList(); if (members.Count == 0) { continue; } OnlineMapsOSMWay relationWay = GetWayByID(ways, members[0].reference); if (relationWay == null) { continue; } nodeRefs.AddRange(relationWay.nodeRefs); members.RemoveAt(0); while (members.Count > 0) { string lastRef = nodeRefs[nodeRefs.Count - 1]; int memberIndex = -1; for (int i = 0; i < members.Count; i++) { OnlineMapsOSMRelationMember member = members[i]; OnlineMapsOSMWay w = GetWayByID(ways, member.reference); if (w.nodeRefs[0] == lastRef) { nodeRefs.AddRange(w.nodeRefs.Skip(1)); memberIndex = i; break; } if (w.nodeRefs[w.nodeRefs.Count - 1] == lastRef) { List <string> refs = w.nodeRefs; refs.Reverse(); nodeRefs.AddRange(refs.Skip(1)); memberIndex = i; break; } } if (memberIndex != -1) { members.RemoveAt(memberIndex); } else { break; } } waysInRelation.AddRange(relation.members.Select(m => m.reference)); way.nodeRefs = nodeRefs; way.id = relation.id; way.tags = relation.tags; newBuildingsData.Enqueue(new OnlineMapsBuildingsNodeData(way, nodes)); } ways.RemoveAll(delegate(OnlineMapsOSMWay w) { if (waysInRelation.Contains(w.id)) { w.Dispose(); return(true); } return(false); }); foreach (OnlineMapsOSMWay way in ways) { newBuildingsData.Enqueue(new OnlineMapsBuildingsNodeData(way, nodes)); } } sendBuildingsReceived = true; }; #if !UNITY_WEBGL if (map.renderInThread) { OnlineMapsThreadManager.AddThreadAction(action); } else { action(); } #else action(); #endif if (OnRequestComplete != null) { OnRequestComplete(); } }