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