RealWorldTerrainContainer.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /* INFINITY CODE 2013-2019 */
  2. /* http://www.infinity-code.com */
  3. using System;
  4. using System.Linq;
  5. using UnityEngine;
  6. namespace InfinityCode.RealWorldTerrain
  7. {
  8. /// <summary>
  9. /// This class is added to the resulting container.\n
  10. /// It contains all information about terrains.
  11. /// </summary>
  12. [Serializable]
  13. [AddComponentMenu("")]
  14. public class RealWorldTerrainContainer : RealWorldTerrainMonoBase
  15. {
  16. /// <summary>
  17. /// Billboard start.
  18. /// </summary>
  19. public float billboardStart = 50;
  20. /// <summary>
  21. /// Detail density.
  22. /// </summary>
  23. public float detailDensity = 1;
  24. /// <summary>
  25. /// Detail distance.
  26. /// </summary>
  27. public float detailDistance = 80;
  28. /// <summary>
  29. /// The folder in the project where located terrains.
  30. /// </summary>
  31. public string folder;
  32. /// <summary>
  33. /// Count of terrains.
  34. /// </summary>
  35. public RealWorldTerrainVector2i terrainCount;
  36. /// <summary>
  37. /// Title
  38. /// </summary>
  39. public string title;
  40. /// <summary>
  41. /// Tree distance.
  42. /// </summary>
  43. public float treeDistance = 2000;
  44. /// <summary>
  45. /// The array of elements that belong to the current process of generation.
  46. /// </summary>
  47. public RealWorldTerrainItem[] terrains;
  48. /// <summary>
  49. /// Gets all instances of RealWorldTerrainContainer.
  50. /// </summary>
  51. /// <returns>Instances of RealWorldTerrainContainer</returns>
  52. public static RealWorldTerrainContainer[] GetInstances()
  53. {
  54. return FindObjectsOfType<RealWorldTerrainContainer>().ToArray();
  55. }
  56. public override RealWorldTerrainItem GetItemByWorldPosition(Vector3 worldPosition)
  57. {
  58. for (int i = 0; i < terrains.Length; i++)
  59. {
  60. RealWorldTerrainItem item = terrains[i];
  61. if (item == null) continue;
  62. Bounds b = new Bounds(item.bounds.center + transform.position, item.bounds.size);
  63. if (b.min.x <= worldPosition.x && b.min.z <= worldPosition.z && b.max.x >= worldPosition.x && b.max.z >= worldPosition.z)
  64. {
  65. return item;
  66. }
  67. }
  68. return null;
  69. }
  70. public override bool GetWorldPosition(double lng, double lat, out Vector3 worldPosition)
  71. {
  72. worldPosition = new Vector3();
  73. if (!Contains(lng, lat))
  74. {
  75. Debug.Log("Wrong coordinates");
  76. return false;
  77. }
  78. if (terrains == null || terrains.Length == 0) return false;
  79. double mx, my;
  80. RealWorldTerrainUtils.LatLongToMercat(lng, lat, out mx, out my);
  81. double lX = RealWorldTerrainUtils.Clamp((mx - leftMercator) / (rightMercator - leftMercator), 0, 1);
  82. double lZ = RealWorldTerrainUtils.Clamp(1 - (my - topMercator) / (bottomMercator - topMercator), 0, 1);
  83. Bounds cb = new Bounds(bounds.center + transform.position, bounds.size);
  84. double x = cb.size.x * lX + cb.min.x;
  85. double z = cb.size.z * lZ + cb.min.z;
  86. if (prefs.resultType == RealWorldTerrainResultType.terrain)
  87. {
  88. Terrain terrain = null;
  89. for (int i = 0; i < terrains.Length; i++)
  90. {
  91. RealWorldTerrainItem item = terrains[i];
  92. Bounds b = new Bounds(item.bounds.center + transform.position, item.bounds.size);
  93. if (b.min.x <= x && b.min.z <= z && b.max.x >= x && b.max.z >= z)
  94. {
  95. terrain = item.terrain;
  96. break;
  97. }
  98. }
  99. if (terrain == null) return false;
  100. double ix = (x - terrain.gameObject.transform.position.x) / terrain.terrainData.size.x;
  101. double iz = (z - terrain.gameObject.transform.position.z) / terrain.terrainData.size.z;
  102. double y = terrain.terrainData.GetInterpolatedHeight((float)ix, (float)iz) + terrain.gameObject.transform.position.y;
  103. worldPosition.x = (float)x;
  104. worldPosition.y = (float)y;
  105. worldPosition.z = (float)z;
  106. }
  107. else if (prefs.resultType == RealWorldTerrainResultType.mesh)
  108. {
  109. bool success = false;
  110. for (int i = 0; i < terrains.Length; i++)
  111. {
  112. RealWorldTerrainItem item = terrains[i];
  113. Bounds b = new Bounds(item.bounds.center + transform.position, item.bounds.size);
  114. if (b.min.x <= x && b.min.z <= z && b.max.x >= x && b.max.z >= z)
  115. {
  116. float y = 0;
  117. RaycastHit[] hits = Physics.RaycastAll(new Vector3((float)x, item.bounds.max.y + 10, (float)z), Vector3.down, float.MaxValue);
  118. foreach (RaycastHit hit in hits)
  119. {
  120. if (hit.transform.gameObject.GetComponentInParent<RealWorldTerrainItem>() != null)
  121. {
  122. y = hit.point.y;
  123. break;
  124. }
  125. }
  126. worldPosition.x = (float)x;
  127. worldPosition.y = y;
  128. worldPosition.z = (float)z;
  129. success = true;
  130. break;
  131. }
  132. }
  133. if (!success) return false;
  134. }
  135. return true;
  136. }
  137. public override bool GetWorldPosition(Vector2 coordinates, out Vector3 worldPosition)
  138. {
  139. return GetWorldPosition(coordinates.x, coordinates.y, out worldPosition);
  140. }
  141. }
  142. }