RealWorldTerrainWindow.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. /* INFINITY CODE */
  2. /* https://infinity-code.com */
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Threading;
  7. using InfinityCode.RealWorldTerrain.Generators;
  8. using InfinityCode.RealWorldTerrain.Net;
  9. using InfinityCode.RealWorldTerrain.Phases;
  10. using UnityEditor;
  11. using UnityEngine;
  12. using Debug = UnityEngine.Debug;
  13. namespace InfinityCode.RealWorldTerrain.Windows
  14. {
  15. public class RealWorldTerrainWindow : EditorWindow
  16. {
  17. /// <summary>
  18. /// Current version number
  19. /// </summary>
  20. public const string version = "4.6.2.1";
  21. /// <summary>
  22. /// The action that occurs when the user aborts the generation.
  23. /// </summary>
  24. public static Action OnCaptureCanceled;
  25. /// <summary>
  26. /// The action that occurs when the generation is completed.
  27. /// </summary>
  28. public static Action OnCaptureCompleted;
  29. /// <summary>
  30. /// The action that occurs when the generation is started.
  31. /// </summary>
  32. public static Action OnCaptureStarted;
  33. public static RealWorldTerrainContainer container;
  34. public static bool generateInThread;
  35. public static RealWorldTerrainMonoBase generateTarget;
  36. public static RealWorldTerrainGenerateType generateType = RealWorldTerrainGenerateType.full;
  37. public static bool isCapturing;
  38. public static float progress;
  39. public static RealWorldTerrainPrefs prefs;
  40. public static RealWorldTerrainItem[,] terrains;
  41. public static RealWorldTerrainWindow wnd;
  42. private static int textureLevel;
  43. private static Thread thread;
  44. public static void CancelCapture()
  45. {
  46. Dispose();
  47. if (OnCaptureCanceled != null) OnCaptureCanceled();
  48. }
  49. public static void CancelInMainThread()
  50. {
  51. EditorApplication.update += OnCancelInMainThread;
  52. }
  53. private static bool CheckFields()
  54. {
  55. if (prefs.resultType == RealWorldTerrainResultType.gaiaStamp)
  56. {
  57. #if !GAIA_PRESENT && !GAIA_PRO_PRESENT && !GAIA_2_PRESENT
  58. Debug.Log("Gaia not found. Import Gaia into the project.");
  59. return false;
  60. #endif
  61. }
  62. else if (prefs.resultType == RealWorldTerrainResultType.rawFile)
  63. {
  64. string filename = prefs.rawFilename;
  65. string ext = prefs.rawType == RealWorldTerrainRawType.RAW ? ".raw" : ".png";
  66. if (!filename.ToLower().EndsWith(ext)) filename += ext;
  67. if (File.Exists(filename))
  68. {
  69. if (!EditorUtility.DisplayDialog("Warning", "File already exists. Overwrite?", "Overwrite", "Cancel"))
  70. {
  71. return false;
  72. }
  73. }
  74. }
  75. if (prefs.leftLongitude >= prefs.rightLongitude)
  76. {
  77. Debug.Log("Bottom-Right Longitude must be greater than Top-Left Longitude");
  78. return false;
  79. }
  80. if (prefs.topLatitude <= prefs.bottomLatitude)
  81. {
  82. Debug.Log("Top-Left Latitude must be greater than Bottom-Right Latitude");
  83. return false;
  84. }
  85. if (prefs.leftLongitude < -180 || prefs.rightLongitude < -180 || prefs.leftLongitude > 180 || prefs.rightLongitude > 180)
  86. {
  87. Debug.Log("Longitude must be between -180 and 180.");
  88. return false;
  89. }
  90. if (prefs.elevationProvider == RealWorldTerrainElevationProvider.BingMaps)
  91. {
  92. RealWorldTerrainBingElevationGenerator.key = RealWorldTerrainPrefs.LoadPref("BingAPI", string.Empty);
  93. if (string.IsNullOrEmpty(RealWorldTerrainBingElevationGenerator.key))
  94. {
  95. Debug.LogError("Bing Maps API key is not specified.");
  96. return false;
  97. }
  98. }
  99. else if (prefs.elevationProvider == RealWorldTerrainElevationProvider.Mapbox)
  100. {
  101. if (string.IsNullOrEmpty(RealWorldTerrainPrefs.mapboxAccessToken))
  102. {
  103. Debug.LogError("Mapbox Access Token is not specified.");
  104. return false;
  105. }
  106. }
  107. else if (prefs.elevationProvider == RealWorldTerrainElevationProvider.SRTM30)
  108. {
  109. RealWorldTerrainSRTM30ElevationGenerator.login = RealWorldTerrainPrefs.LoadPref("EarthDataLogin", string.Empty);
  110. RealWorldTerrainSRTM30ElevationGenerator.pass = RealWorldTerrainPrefs.LoadPref("EarthDataPass", string.Empty);
  111. if (string.IsNullOrEmpty(RealWorldTerrainSRTM30ElevationGenerator.login))
  112. {
  113. Debug.LogError("EarthData username is not specified.");
  114. return false;
  115. }
  116. if (string.IsNullOrEmpty(RealWorldTerrainSRTM30ElevationGenerator.pass))
  117. {
  118. Debug.LogError("EarthData password is not specified.");
  119. return false;
  120. }
  121. }
  122. if (prefs.resultType == RealWorldTerrainResultType.terrain && !CheckHeightmapMemory()) return false;
  123. return true;
  124. }
  125. private static bool CheckHeightmapMemory()
  126. {
  127. int count = prefs.terrainCount;
  128. long size = prefs.heightmapResolution * prefs.heightmapResolution * 4 * count;
  129. size += prefs.baseMapResolution * prefs.baseMapResolution * 4 * count;
  130. size += prefs.detailResolution * prefs.detailResolution * 4 * count;
  131. size += 513 * 513 * 4 * count; //Alphamaps
  132. if (size > int.MaxValue * 0.75f)
  133. {
  134. return EditorUtility.DisplayDialog("Warning", "Too high settings. Perhaps out of memory error.", "Continue", "Abort");
  135. }
  136. return true;
  137. }
  138. public static void ClearCache()
  139. {
  140. RealWorldTerrainClearCacheWindow.OpenWindow();
  141. }
  142. public static void Dispose()
  143. {
  144. isCapturing = false;
  145. RealWorldTerrainImporter.showMessage = true;
  146. if (thread != null)
  147. {
  148. thread.Abort();
  149. thread = null;
  150. }
  151. RealWorldTerrainElevationGenerator.Dispose();
  152. RealWorldTerrainTextureGenerator.Dispose();
  153. RealWorldTerrainTerrainLayersGenerator.Dispose();
  154. RealWorldTerrainDownloadManager.Dispose();
  155. RealWorldTerrainRoadGenerator.Dispose();
  156. RealWorldTerrainGrassGenerator.Dispose();
  157. RealWorldTerrainTreesGenerator.Dispose();
  158. RealWorldTerrainBuildingGenerator.Dispose();
  159. EditorUtility.UnloadUnusedAssetsImmediate();
  160. RealWorldTerrainPhase.requiredPhases = null;
  161. if (RealWorldTerrainPhase.activePhase != null)
  162. {
  163. try
  164. {
  165. RealWorldTerrainPhase.activePhase.Finish();
  166. }
  167. catch
  168. {
  169. }
  170. }
  171. RealWorldTerrainPhase.activePhase = null;
  172. RealWorldTerrainPhase.activePhaseIndex = -1;
  173. if (wnd != null) wnd.Repaint();
  174. GC.Collect();
  175. }
  176. private static void OnCancelInMainThread()
  177. {
  178. CancelCapture();
  179. EditorApplication.update -= OnCancelInMainThread;
  180. }
  181. private void OnDestroy()
  182. {
  183. wnd = null;
  184. prefs.Save();
  185. }
  186. private void OnEnable()
  187. {
  188. wnd = this;
  189. if (prefs == null) prefs = new RealWorldTerrainPrefs();
  190. prefs.Load();
  191. RealWorldTerrainWindowUI.OnEnable();
  192. RealWorldTerrainUpdaterWindow.CheckNewVersionAvailable();
  193. }
  194. private void OnGUI()
  195. {
  196. RealWorldTerrainWindowUI.OnGUI();
  197. }
  198. [MenuItem("Window/Infinity Code/Real World Terrain/Open Real World Terrain", false, 0)]
  199. private static void OpenWindow()
  200. {
  201. OpenWindow(RealWorldTerrainGenerateType.full);
  202. }
  203. public static void OpenWindow(RealWorldTerrainGenerateType type, RealWorldTerrainMonoBase target = null)
  204. {
  205. generateTarget = target;
  206. generateType = type;
  207. wnd = GetWindow<RealWorldTerrainWindow>(false, "Real World Terrain");
  208. if (target == null)
  209. {
  210. prefs = new RealWorldTerrainPrefs();
  211. prefs.Load();
  212. }
  213. else if (type == RealWorldTerrainGenerateType.full)
  214. {
  215. prefs = RealWorldTerrainPrefs.GetPrefs(target, true);
  216. generateTarget = null;
  217. }
  218. else prefs = RealWorldTerrainPrefs.GetPrefs(target);
  219. if (type == RealWorldTerrainGenerateType.additional)
  220. {
  221. prefs.generateBuildings = false;
  222. prefs.generateGrass = false;
  223. prefs.generateRoads = false;
  224. prefs.generateTrees = false;
  225. }
  226. RealWorldTerrainWindowUI.InitTextureProviders();
  227. RealWorldTerrainUpdaterWindow.CheckNewVersionAvailable();
  228. }
  229. private static void PrepareStart()
  230. {
  231. generateInThread = RealWorldTerrainPrefs.LoadPref("GenerateInThread", true);
  232. RealWorldTerrainOSMUtils.InitOSMServer();
  233. if (!CheckFields()) return;
  234. if (prefs.resultType == RealWorldTerrainResultType.mesh)
  235. {
  236. if (prefs.generateTextures) prefs.terrainCount = prefs.textureCount;
  237. else prefs.terrainCount = RealWorldTerrainVector2i.one;
  238. }
  239. else if (prefs.resultType == RealWorldTerrainResultType.terrain)
  240. {
  241. prefs.textureCount = prefs.terrainCount;
  242. }
  243. RealWorldTerrainElevationGenerator.elevations = new List<RealWorldTerrainElevationGenerator>();
  244. if (generateType == RealWorldTerrainGenerateType.full || generateType == RealWorldTerrainGenerateType.terrain || generateType == RealWorldTerrainGenerateType.additional)
  245. {
  246. if (prefs.elevationProvider == RealWorldTerrainElevationProvider.SRTM) RealWorldTerrainSRTMElevationGenerator.Init();
  247. else if (prefs.elevationProvider == RealWorldTerrainElevationProvider.BingMaps) RealWorldTerrainBingElevationGenerator.Init();
  248. else if (prefs.elevationProvider == RealWorldTerrainElevationProvider.SRTM30) RealWorldTerrainSRTM30ElevationGenerator.Init();
  249. else if (prefs.elevationProvider == RealWorldTerrainElevationProvider.Mapbox) RealWorldTerrainMapboxElevationGenerator.Init();
  250. else if (prefs.elevationProvider == RealWorldTerrainElevationProvider.ArcGIS) RealWorldTerrainArcGISElevationGenerator.Init();
  251. }
  252. if (generateType == RealWorldTerrainGenerateType.full || generateType == RealWorldTerrainGenerateType.texture)
  253. {
  254. if (prefs.generateTextures && prefs.resultType != RealWorldTerrainResultType.gaiaStamp)
  255. {
  256. if (prefs.textureResultType == RealWorldTerrainTextureResultType.regularTexture || prefs.textureResultType == RealWorldTerrainTextureResultType.hugeTexture)
  257. {
  258. RealWorldTerrainTextureGenerator.Init();
  259. }
  260. else if (prefs.textureResultType == RealWorldTerrainTextureResultType.terrainLayers)
  261. {
  262. RealWorldTerrainTerrainLayersGenerator.Init();
  263. }
  264. }
  265. }
  266. if (generateType == RealWorldTerrainGenerateType.full || generateType == RealWorldTerrainGenerateType.additional)
  267. {
  268. if (prefs.resultType != RealWorldTerrainResultType.gaiaStamp)
  269. {
  270. RealWorldTerrainBuildingGenerator.Download();
  271. RealWorldTerrainRoadGenerator.Download();
  272. RealWorldTerrainTreesGenerator.Download();
  273. RealWorldTerrainGrassGenerator.Download();
  274. RealWorldTerrainRiverGenerator.Download();
  275. }
  276. }
  277. if (prefs.mapType == null) prefs.mapType = RealWorldTerrainTextureProviderManager.FindMapType(prefs.mapTypeID);
  278. prefs.mapTypeID = prefs.mapType.fullID;
  279. prefs.mapTypeExtraFields = prefs.mapType.GetSettings();
  280. if (generateTarget != null) prefs.Apply(generateTarget);
  281. if (generateType == RealWorldTerrainGenerateType.full) RealWorldTerrainHistoryWindow.Add(prefs);
  282. isCapturing = true;
  283. RealWorldTerrainPhase.Init();
  284. if (OnCaptureStarted != null) OnCaptureStarted();
  285. }
  286. public static void StartCapture()
  287. {
  288. prefs.Save();
  289. if (generateType == RealWorldTerrainGenerateType.additional)
  290. {
  291. RealWorldTerrainMonoBase target = generateTarget;
  292. if (target is RealWorldTerrainContainer)
  293. {
  294. if (prefs.generateBuildings) RealWorldTerrainUtils.DeleteGameObject(target.transform, "Buildings");
  295. if (prefs.generateRoads) RealWorldTerrainUtils.DeleteGameObject(target.transform, "Roads");
  296. if (prefs.generateRivers) RealWorldTerrainUtils.DeleteGameObject(target.transform, "Rivers");
  297. if (prefs.generateTrees)
  298. {
  299. foreach (RealWorldTerrainItem item in (target as RealWorldTerrainContainer).terrains)
  300. {
  301. item.terrainData.treeInstances = new TreeInstance[0];
  302. item.terrainData.treePrototypes = new TreePrototype[0];
  303. }
  304. }
  305. if (prefs.generateGrass)
  306. {
  307. foreach (RealWorldTerrainItem item in (target as RealWorldTerrainContainer).terrains)
  308. {
  309. item.terrainData.detailPrototypes = new DetailPrototype[0];
  310. }
  311. }
  312. }
  313. else
  314. {
  315. RealWorldTerrainItem item = target as RealWorldTerrainItem;
  316. string index = item.x + "x" + (item.container.terrainCount.y - item.y - 1);
  317. if (prefs.generateBuildings) RealWorldTerrainUtils.DeleteGameObject(target.transform.parent, "Buildings " + index);
  318. if (prefs.generateRoads) RealWorldTerrainUtils.DeleteGameObject(target.transform.parent, "Roads " + index);
  319. if (prefs.generateTrees)
  320. {
  321. item.terrainData.treeInstances = new TreeInstance[0];
  322. item.terrainData.treePrototypes = new TreePrototype[0];
  323. }
  324. if (prefs.generateGrass) item.terrainData.detailPrototypes = new DetailPrototype[0];
  325. }
  326. }
  327. PrepareStart();
  328. }
  329. private void Update()
  330. {
  331. if (RealWorldTerrainPhase.activePhase == null) return;
  332. try
  333. {
  334. RealWorldTerrainPhase.activePhase.Enter();
  335. }
  336. catch (Exception e)
  337. {
  338. Debug.LogException(e);
  339. CancelCapture();
  340. }
  341. }
  342. }
  343. }