public static List <Vector3> GetGlobalPointsFromWay(OSMWay way, Dictionary <string, OSMNode> _nodes) { List <Vector3> points = new List <Vector3>(); if (way.nodeRefs.Count == 0) { return(points); } foreach (string nodeRef in way.nodeRefs) { OSMNode node; if (_nodes.TryGetValue(nodeRef, out node)) { points.Add(new Vector3((float)node.Longitude, 0, (float)node.Latitude)); } } return(points); }
public static void LoadOSMFile(string OsmFilepath, out Dictionary <string, OSMNode> nodes, out Dictionary <string, OSMWay> ways, out List <OSMMapMembers> relations) { nodes = new Dictionary <string, OSMNode>(); ways = new Dictionary <string, OSMWay>(); relations = new List <OSMMapMembers>(); if (File.Exists(OsmFilepath)) { var xmlText = File.ReadAllText(OsmFilepath); XmlDocument doc = new XmlDocument(); doc.LoadXml(xmlText); var nodesDoc = doc.DocumentElement.ChildNodes; foreach (XmlNode node in nodesDoc) { if (node.Name == "node") { OSMNode n = new OSMNode(node); if (!nodes.ContainsKey(n.id)) { nodes.Add(n.id, n); } } else if (node.Name == "way") { OSMWay way = new OSMWay(node); if (!ways.ContainsKey(way.id)) { ways.Add(way.id, way); } } else if (node.Name == "relation") { relations.Add(new OSMMapMembers(node)); } } } }
public static void GenerateTrees(TerrainContainerObject container, List <GameObject> m_treesPrefabs, float m_treeDensity, float TreeScaleFactor, float TreeRandomScaleFactor, float m_TreeDistance, float m_BillBoardStartDistance, Dictionary <string, OSMNode> nodes, Dictionary <string, OSMWay> ways, List <OSMMapMembers> relations) { TreeDistance = m_TreeDistance; BillBoardStartDistance = m_BillBoardStartDistance; AddTreesToTerrains(container, m_treesPrefabs); treeNodes = new List <OSMNode>(); woodWays = new List <OSMWay>(); treeRowWays = new List <OSMWay>(); foreach (KeyValuePair <string, OSMNode> pair in nodes) { OSMNode n = pair.Value; if (n.HasTag("natural", "tree")) { treeNodes.Add(n); } } foreach (KeyValuePair <string, OSMWay> pair in ways) { OSMWay w = pair.Value; if (w.HasTag("natural", "wood") || w.HasTags("landuse", "forest", "park")) { woodWays.Add(w); } else if (w.HasTag("natural", "tree_row")) { treeRowWays.Add(w); } } totalTreeCount = treeNodes.Count + treeRowWays.Count + woodWays.Count; if (totalTreeCount == 0) { return; } alreadyCreated = new HashSet <string>(); var treeDensity = m_treeDensity; var TLPMercator_X = container.TLPointMercator.x; var TLPMercator_Y = container.TLPointMercator.y; var DRPMercator_X = container.DRPointMercator.x; var DRPMercator_Y = container.DRPointMercator.y; for (int i = 0; i < treeNodes.Count; i++) { OSMNode node = treeNodes[i]; if (alreadyCreated.Contains(node.id)) { continue; } alreadyCreated.Add(node.id); var NodeP_Merc = GeoRefConversion.LatLongToMercat(node.Longitude, node.Latitude); double Offest_x = (NodeP_Merc.x - TLPMercator_X) / (DRPMercator_X - TLPMercator_X); double Offest_y = 1 - (NodeP_Merc.y - TLPMercator_Y) / (DRPMercator_Y - TLPMercator_Y); Vector3 WSPos = new Vector3((float)(container.transform.position.x + container.size.x * Offest_x), 0, (float)(container.size.z + container.size.z * Offest_y)); SetTreeToTerrain(TreeScaleFactor, TreeRandomScaleFactor, container, WSPos); } for (int index = 0; index < treeRowWays.Count; index++) { OSMWay way = treeRowWays[index]; if (alreadyCreated.Contains(way.id)) { continue; } alreadyCreated.Add(way.id); List <Vector3> points = OSMWay.GetGlobalPointsFromWay(way, nodes); for (int i = 0; i < points.Count; i++) { Vector3 WSPos = points[i]; var WSPos_Merc = GeoRefConversion.LatLongToMercat(WSPos.x, WSPos.z); double Offest_x = (WSPos_Merc.x - TLPMercator_X) / (DRPMercator_X - TLPMercator_X); double Offest_y = 1 - (WSPos_Merc.y - TLPMercator_Y) / (DRPMercator_Y - TLPMercator_Y); WSPos.x = (float)(container.transform.position.x + container.size.x * Offest_x); WSPos.z = (float)(container.transform.position.z + container.size.z * Offest_y); points[i] = WSPos; } for (int i = 0; i < points.Count - 1; i++) { int len = Mathf.RoundToInt((points[i] - points[i + 1]).magnitude / m_treeDensity); if (len > 0) { for (int j = 0; j <= len; j++) { SetTreeToTerrain(TreeScaleFactor, TreeRandomScaleFactor, container, Vector3.Lerp(points[i], points[i + 1], j / (float)len)); } } else { SetTreeToTerrain(TreeScaleFactor, TreeRandomScaleFactor, container, points[i]); } } } for (int index = 0; index < woodWays.Count; index++) { OSMWay way = woodWays[index]; if (alreadyCreated.Contains(way.id)) { continue; } alreadyCreated.Add(way.id); List <Vector3> points = OSMWay.GetGlobalPointsFromWay(way, nodes); for (int i = 0; i < points.Count; i++) { Vector3 p = points[i]; var sp = GeoRefConversion.LatLongToMercat(p.x, p.z); double rx = (sp.x - TLPMercator_X) / (DRPMercator_X - TLPMercator_X); double ry = 1 - (sp.y - TLPMercator_Y) / (DRPMercator_Y - TLPMercator_Y); p.x = (float)(container.transform.position.x + container.size.x * rx); p.z = (float)(container.transform.position.z + container.size.z * ry); points[i] = p; } Rect rect = Extensions.GetRectFromPoints(points); int lx = Mathf.RoundToInt(rect.width / m_treeDensity); int ly = Mathf.RoundToInt(rect.height / m_treeDensity); if (lx > 0 && ly > 0) { m_currentWayID = way.id; GenerateTerrainsTrees(TreeScaleFactor, TreeRandomScaleFactor, container, treeDensity, lx, ly, rect, points); } } }
public static void GenerateGrass(TerrainContainerObject m_container, List <GISTerrainLoaderSO_Grass> m_GrassPrefabs, float m_GrassDensity, float m_GrassScaleFactor, float m_DetailDistance, Dictionary <string, OSMNode> nodes, Dictionary <string, OSMWay> ways, List <OSMMapMembers> relations) { GrassPrefabs = m_GrassPrefabs; container = m_container; GrassScaleFactor = m_GrassScaleFactor; DetailDistance = m_DetailDistance; AddDetailsLayersToTerrains(); TerrainData tdata = container.terrains[0, 0].terrainData; int detailResolution = tdata.detailResolution; alreadyCreated = new List <string>(); details = new List <int[, ]>(container.terrains.Length); foreach (var item in container.terrains) { for (int i = 0; i < GrassPrefabs.Count; i++) { details.Add(new int[detailResolution, detailResolution]); } } var detailsInPoint = new float[GrassPrefabs.Count]; var grassWays = new List <OSMWay>(); foreach (KeyValuePair <string, OSMWay> pair in ways) { OSMWay w = pair.Value; if (w.HasTags("landuse", "grass", "farmland", "forest", "meadow", "park", "pasture", "recreation_ground") || w.HasTags("leisure", "park", "golf_course") || w.HasTags("natural", "scrub", "wood")) { grassWays.Add(w); } } var totalCount = grassWays.Count + container.terrainCount.x; float density = m_GrassDensity / 100f; if (density > 1) { density = 1; } density *= 64; for (int i = 0; i < grassWays.Count; i++) { OSMWay way = grassWays[i]; if (alreadyCreated.Contains(way.id)) { continue; } alreadyCreated.Add(way.id); if (way.nodeRefs.Count == 0) { continue; } List <Vector3> Points = new List <Vector3>(); float pxmin = float.MaxValue, pxmax = float.MinValue, pymin = float.MaxValue, pymax = float.MinValue; for (int m = 0; m < way.nodeRefs.Count; m++) { string nodeRef = way.nodeRefs[m]; OSMNode node; if (!nodes.TryGetValue(nodeRef, out node)) { continue; } var NodeP_Merc = GeoRefConversion.LatLongToMercat(node.Longitude, node.Latitude); Vector3 wspostion = GeoRefConversion.MercatCoordsToWorld(NodeP_Merc.x, 0, NodeP_Merc.y, container) - container.transform.position; wspostion = new Vector3(wspostion.x / tdata.size.x * detailResolution, 0, wspostion.z / tdata.size.z * detailResolution); if (wspostion.x < pxmin) { pxmin = wspostion.x; } if (wspostion.x > pxmax) { pxmax = wspostion.x; } if (wspostion.z < pymin) { pymin = wspostion.z; } if (wspostion.z > pymax) { pymax = wspostion.z; } Points.Add(wspostion); } if (Points.Count < 3) { continue; } Vector3[] points = Points.ToArray(); for (int x = (int)pxmin; x < pxmax; x++) { int tix = Mathf.FloorToInt(x / (float)detailResolution); if (tix < 0 || tix >= container.terrainCount.x) { continue; } int tx = x - tix * detailResolution; for (int y = (int)pymin; y < pymax; y++) { int tiy = Mathf.FloorToInt(y / (float)detailResolution); if (tiy >= container.terrainCount.y || tiy < 0) { continue; } int tIndex = tiy * container.terrainCount.x + tix; if (tIndex < 0 || tIndex >= container.terrains.Length) { continue; } bool intersect = Extensions.IsPointInPolygon(points, x + 0.5f, y - 0.5f); if (!intersect) { continue; } int ty = y - tiy * detailResolution; if (GrassPrefabs.Count == 1) { details[tIndex][ty, tx] = (int)density; } else { float totalInPoint = 0; int tIndex2 = tIndex * GrassPrefabs.Count; for (int k = 0; k < GrassPrefabs.Count; k++) { float v = Random.Range(0f, 1f); detailsInPoint[k] = v; totalInPoint += v; } for (int k = 0; k < GrassPrefabs.Count; k++) { int v = (int)(detailsInPoint[k] / totalInPoint * density); if (v > 255) { v = 255; } details[tIndex2 + k][ty, tx] = v; } } } } } for (int x = 0; x < container.terrainCount.x; x++) { for (int y = 0; y < container.terrainCount.y; y++) { for (int prefabIndex = 0; prefabIndex < GrassPrefabs.Count; prefabIndex++) { int tIndex = y * container.terrainCount.x + x; container.terrains[x, y].terrainData.SetDetailLayer(0, 0, prefabIndex, details[tIndex * GrassPrefabs.Count + prefabIndex]); } } } }