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 void GenerateTerrains() { ListTerrainObjects = new List <TerrainObject>(); const string containerName = "Terrains"; string cName = containerName; //Destroy prv created terrain if (RemovePrevTerrain) { Destroy(GameObject.Find(cName)); } else { int index = 1; while (GameObject.Find(cName) != null) { cName = containerName + " " + index.ToString(); index++; } } var container = new GameObject(cName); container.transform.position = new Vector3(0, 0, 0); progress = 0; Vector2 TlimiteFrom = new Vector2(prefs.terrainDimensions.x, 0); Vector2 TlimiteTo = new Vector2(prefs.terrainDimensions.y, 0); Vector2Int tCount = new Vector2Int((int)prefs.terrainCount.x, (int)prefs.terrainCount.y); float maxElevation = floatReader.MaxElevation; float minElevation = floatReader.MinElevation; float ElevationRange = maxElevation - minElevation; var sizeX = Mathf.Floor(prefs.terrainDimensions.x * prefs.terrainScale.x) / prefs.terrainCount.x; var sizeZ = Mathf.Floor(prefs.terrainDimensions.y * prefs.terrainScale.z) / prefs.terrainCount.y; var sizeY = (ElevationRange) / ElevationScaleValue * prefs.TerrainExaggeration * 100 * prefs.terrainScale.y; Vector3 size; if (prefs.TerrainElevation == TerrainElevation.RealWorldElevation) { sizeY = ((ElevationRange)) * prefs.terrainScale.y / 100; size = new Vector3(sizeX, sizeY, sizeZ); } else { size = new Vector3(sizeX, sizeY, sizeZ); } terrains = new TerrainObject[tCount.x, tCount.y]; container.AddComponent <TerrainContainerObject>(); var terrainContainer = container.GetComponent <TerrainContainerObject>(); Terrainscontainer = terrainContainer; terrainContainer.terrainCount = prefs.terrainCount; terrainContainer.scale = prefs.terrainScale; terrainContainer.size = new Vector3(size.x * tCount.x, size.y, size.z * tCount.y); //Set Terrain Coordinates to the container TerrainContainer script (Lat/lon) + Mercator terrainContainer.TLPointLatLong = floatReader.TopLeftPoint; terrainContainer.DRPointLatLong = floatReader.DownRightPoint; terrainContainer.TLPointMercator = GeoRefConversion.LatLongToMercat(terrainContainer.TLPointLatLong.x, terrainContainer.TLPointLatLong.y); terrainContainer.DRPointMercator = GeoRefConversion.LatLongToMercat(terrainContainer.DRPointLatLong.x, terrainContainer.DRPointLatLong.y); progress = 0; for (int x = 0; x < tCount.x; x++) { for (int y = 0; y < tCount.y; y++) { terrains[x, y] = CreateTerrain(container.transform, x, y, size, prefs.terrainScale); terrains[x, y].container = terrainContainer; ListTerrainObjects.Add(terrains[x, y]); } } terrainContainer.terrains = terrains; phase = GeneratingTerrainPhase.generateHeightmaps; }
public void GenerateTerrains() { const string containerName = "Terrains"; string cName = containerName; //Destroy prv created terrain if (RemovePrvTerrain) { DestroyImmediate(GameObject.Find(cName)); } else { int index = 1; while (GameObject.Find(cName) != null) { cName = containerName + " " + index.ToString(); index++; } } var container = new GameObject(cName); container.transform.position = new Vector3(0, 0, 0); CurrentTerrainIndex = 0; Vector2Int tCount = new Vector2Int(terrainCount.x, terrainCount.y); float maxElevation = floatReader.MaxElevation; float minElevation = floatReader.MinElevation; float ElevationRange = maxElevation - minElevation; var sizeX = Mathf.Floor(m_terrainDimensions.x * terrainScale.x * 10) / terrainCount.x; var sizeZ = Mathf.Floor(m_terrainDimensions.y * terrainScale.z * 10) / terrainCount.y; var sizeY = (ElevationRange) / ElevationScaleValue * TerrainExaggeration * 100 * terrainScale.y * 10; Vector3 size; if (terrainElevation == TerrainElevation.RealWorldElevation) { sizeY = ((ElevationRange)) * terrainScale.y; size = new Vector3(sizeX, sizeY, sizeZ); } else { sizeY = sizeY * 10; size = new Vector3(sizeX, sizeY, sizeZ); } string resultFolder = "Assets/Generated GIS Terrains"; string resultFullPath = Path.Combine(Application.dataPath, "Generated GIS Terrains"); if (!Directory.Exists(resultFullPath)) { Directory.CreateDirectory(resultFullPath); } string dateStr = DateTime.Now.ToString("yyyy-MM-dd HH-mm-") + DateTime.Now.Second.ToString(); resultFolder += "/" + dateStr; resultFullPath = Path.Combine(resultFullPath, dateStr); if (!Directory.Exists(resultFullPath)) { Directory.CreateDirectory(resultFullPath); } terrains = new TerrainObject[tCount.x, tCount.y]; container.AddComponent <TerrainContainerObject>(); var terrainContainer = container.GetComponent <TerrainContainerObject>(); terrainContainer.terrainCount = new Vector2Int(terrainCount.x, terrainCount.y); terrainContainer.GeneratedTerrainfolder = resultFolder; terrainContainer.scale = terrainScale; terrainContainer.size = new Vector3(size.x * tCount.x, size.y, size.z * tCount.y); //Set Terrain Coordinates to the container TerrainContainer script (Lat/lon) + Mercator terrainContainer.TLPointLatLong = floatReader.TopLeftPoint; terrainContainer.DRPointLatLong = floatReader.DownRightPoint; terrainContainer.TLPointMercator = GeoRefConversion.LatLongToMercat(terrainContainer.TLPointLatLong.x, terrainContainer.TLPointLatLong.y); terrainContainer.DRPointMercator = GeoRefConversion.LatLongToMercat(terrainContainer.DRPointLatLong.x, terrainContainer.DRPointLatLong.y); //Terrain Size Bounds var centre = new Vector3(terrainContainer.size.x / 2, 0, terrainContainer.size.z / 2); terrainContainer.GlobalTerrainBounds = new Bounds(centre, new Vector3(centre.x + terrainContainer.size.x / 2, 0, centre.z + terrainContainer.size.z / 2)); for (int x = 0; x < tCount.x; x++) { for (int y = 0; y < tCount.y; y++) { terrains[x, y] = CreateTerrain(terrainContainer, x, y, size, terrainScale); terrains[x, y].container = terrainContainer; } } terrainContainer.terrains = terrains; GeneratedContainer = terrainContainer; phase = GeneratingTerrainPhase.generateHeightmaps; }
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]); } } } }