/* INFINITY CODE 2013-2019 */ /* http://www.infinity-code.com */ using System; using System.Linq; using UnityEngine; namespace InfinityCode.RealWorldTerrain { /// /// This class is added to the resulting container.\n /// It contains all information about terrains. /// [Serializable] [AddComponentMenu("")] public class RealWorldTerrainContainer : RealWorldTerrainMonoBase { /// /// Billboard start. /// public float billboardStart = 50; /// /// Detail density. /// public float detailDensity = 1; /// /// Detail distance. /// public float detailDistance = 80; /// /// The folder in the project where located terrains. /// public string folder; /// /// Count of terrains. /// public RealWorldTerrainVector2i terrainCount; /// /// Title /// public string title; /// /// Tree distance. /// public float treeDistance = 2000; /// /// The array of elements that belong to the current process of generation. /// public RealWorldTerrainItem[] terrains; /// /// Gets all instances of RealWorldTerrainContainer. /// /// Instances of RealWorldTerrainContainer public static RealWorldTerrainContainer[] GetInstances() { return FindObjectsOfType().ToArray(); } public override RealWorldTerrainItem GetItemByWorldPosition(Vector3 worldPosition) { for (int i = 0; i < terrains.Length; i++) { RealWorldTerrainItem item = terrains[i]; if (item == null) continue; Bounds b = new Bounds(item.bounds.center + transform.position, item.bounds.size); if (b.min.x <= worldPosition.x && b.min.z <= worldPosition.z && b.max.x >= worldPosition.x && b.max.z >= worldPosition.z) { return item; } } return null; } public override bool GetWorldPosition(double lng, double lat, out Vector3 worldPosition) { worldPosition = new Vector3(); if (!Contains(lng, lat)) { Debug.Log("Wrong coordinates"); return false; } if (terrains == null || terrains.Length == 0) return false; double mx, my; RealWorldTerrainUtils.LatLongToMercat(lng, lat, out mx, out my); double lX = RealWorldTerrainUtils.Clamp((mx - leftMercator) / (rightMercator - leftMercator), 0, 1); double lZ = RealWorldTerrainUtils.Clamp(1 - (my - topMercator) / (bottomMercator - topMercator), 0, 1); Bounds cb = new Bounds(bounds.center + transform.position, bounds.size); double x = cb.size.x * lX + cb.min.x; double z = cb.size.z * lZ + cb.min.z; if (prefs.resultType == RealWorldTerrainResultType.terrain) { Terrain terrain = null; for (int i = 0; i < terrains.Length; i++) { RealWorldTerrainItem item = terrains[i]; Bounds b = new Bounds(item.bounds.center + transform.position, item.bounds.size); if (b.min.x <= x && b.min.z <= z && b.max.x >= x && b.max.z >= z) { terrain = item.terrain; break; } } if (terrain == null) return false; double ix = (x - terrain.gameObject.transform.position.x) / terrain.terrainData.size.x; double iz = (z - terrain.gameObject.transform.position.z) / terrain.terrainData.size.z; double y = terrain.terrainData.GetInterpolatedHeight((float)ix, (float)iz) + terrain.gameObject.transform.position.y; worldPosition.x = (float)x; worldPosition.y = (float)y; worldPosition.z = (float)z; } else if (prefs.resultType == RealWorldTerrainResultType.mesh) { bool success = false; for (int i = 0; i < terrains.Length; i++) { RealWorldTerrainItem item = terrains[i]; Bounds b = new Bounds(item.bounds.center + transform.position, item.bounds.size); if (b.min.x <= x && b.min.z <= z && b.max.x >= x && b.max.z >= z) { float y = 0; RaycastHit[] hits = Physics.RaycastAll(new Vector3((float)x, item.bounds.max.y + 10, (float)z), Vector3.down, float.MaxValue); foreach (RaycastHit hit in hits) { if (hit.transform.gameObject.GetComponentInParent() != null) { y = hit.point.y; break; } } worldPosition.x = (float)x; worldPosition.y = y; worldPosition.z = (float)z; success = true; break; } } if (!success) return false; } return true; } public override bool GetWorldPosition(Vector2 coordinates, out Vector3 worldPosition) { return GetWorldPosition(coordinates.x, coordinates.y, out worldPosition); } } }