/* INFINITY CODE */
/* https://infinity-code.com */
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using InfinityCode.RealWorldTerrain.Generators;
using InfinityCode.RealWorldTerrain.Net;
using InfinityCode.RealWorldTerrain.Phases;
using UnityEditor;
using UnityEngine;
using Debug = UnityEngine.Debug;
namespace InfinityCode.RealWorldTerrain.Windows
{
public class RealWorldTerrainWindow : EditorWindow
{
///
/// Current version number
///
public const string version = "4.6.2.1";
///
/// The action that occurs when the user aborts the generation.
///
public static Action OnCaptureCanceled;
///
/// The action that occurs when the generation is completed.
///
public static Action OnCaptureCompleted;
///
/// The action that occurs when the generation is started.
///
public static Action OnCaptureStarted;
public static RealWorldTerrainContainer container;
public static bool generateInThread;
public static RealWorldTerrainMonoBase generateTarget;
public static RealWorldTerrainGenerateType generateType = RealWorldTerrainGenerateType.full;
public static bool isCapturing;
public static float progress;
public static RealWorldTerrainPrefs prefs;
public static RealWorldTerrainItem[,] terrains;
public static RealWorldTerrainWindow wnd;
private static int textureLevel;
private static Thread thread;
public static void CancelCapture()
{
Dispose();
if (OnCaptureCanceled != null) OnCaptureCanceled();
}
public static void CancelInMainThread()
{
EditorApplication.update += OnCancelInMainThread;
}
private static bool CheckFields()
{
if (prefs.resultType == RealWorldTerrainResultType.gaiaStamp)
{
#if !GAIA_PRESENT && !GAIA_PRO_PRESENT && !GAIA_2_PRESENT
Debug.Log("Gaia not found. Import Gaia into the project.");
return false;
#endif
}
else if (prefs.resultType == RealWorldTerrainResultType.rawFile)
{
string filename = prefs.rawFilename;
string ext = prefs.rawType == RealWorldTerrainRawType.RAW ? ".raw" : ".png";
if (!filename.ToLower().EndsWith(ext)) filename += ext;
if (File.Exists(filename))
{
if (!EditorUtility.DisplayDialog("Warning", "File already exists. Overwrite?", "Overwrite", "Cancel"))
{
return false;
}
}
}
if (prefs.leftLongitude >= prefs.rightLongitude)
{
Debug.Log("Bottom-Right Longitude must be greater than Top-Left Longitude");
return false;
}
if (prefs.topLatitude <= prefs.bottomLatitude)
{
Debug.Log("Top-Left Latitude must be greater than Bottom-Right Latitude");
return false;
}
if (prefs.leftLongitude < -180 || prefs.rightLongitude < -180 || prefs.leftLongitude > 180 || prefs.rightLongitude > 180)
{
Debug.Log("Longitude must be between -180 and 180.");
return false;
}
if (prefs.elevationProvider == RealWorldTerrainElevationProvider.BingMaps)
{
RealWorldTerrainBingElevationGenerator.key = RealWorldTerrainPrefs.LoadPref("BingAPI", string.Empty);
if (string.IsNullOrEmpty(RealWorldTerrainBingElevationGenerator.key))
{
Debug.LogError("Bing Maps API key is not specified.");
return false;
}
}
else if (prefs.elevationProvider == RealWorldTerrainElevationProvider.Mapbox)
{
if (string.IsNullOrEmpty(RealWorldTerrainPrefs.mapboxAccessToken))
{
Debug.LogError("Mapbox Access Token is not specified.");
return false;
}
}
else if (prefs.elevationProvider == RealWorldTerrainElevationProvider.SRTM30)
{
RealWorldTerrainSRTM30ElevationGenerator.login = RealWorldTerrainPrefs.LoadPref("EarthDataLogin", string.Empty);
RealWorldTerrainSRTM30ElevationGenerator.pass = RealWorldTerrainPrefs.LoadPref("EarthDataPass", string.Empty);
if (string.IsNullOrEmpty(RealWorldTerrainSRTM30ElevationGenerator.login))
{
Debug.LogError("EarthData username is not specified.");
return false;
}
if (string.IsNullOrEmpty(RealWorldTerrainSRTM30ElevationGenerator.pass))
{
Debug.LogError("EarthData password is not specified.");
return false;
}
}
if (prefs.resultType == RealWorldTerrainResultType.terrain && !CheckHeightmapMemory()) return false;
return true;
}
private static bool CheckHeightmapMemory()
{
int count = prefs.terrainCount;
long size = prefs.heightmapResolution * prefs.heightmapResolution * 4 * count;
size += prefs.baseMapResolution * prefs.baseMapResolution * 4 * count;
size += prefs.detailResolution * prefs.detailResolution * 4 * count;
size += 513 * 513 * 4 * count; //Alphamaps
if (size > int.MaxValue * 0.75f)
{
return EditorUtility.DisplayDialog("Warning", "Too high settings. Perhaps out of memory error.", "Continue", "Abort");
}
return true;
}
public static void ClearCache()
{
RealWorldTerrainClearCacheWindow.OpenWindow();
}
public static void Dispose()
{
isCapturing = false;
RealWorldTerrainImporter.showMessage = true;
if (thread != null)
{
thread.Abort();
thread = null;
}
RealWorldTerrainElevationGenerator.Dispose();
RealWorldTerrainTextureGenerator.Dispose();
RealWorldTerrainTerrainLayersGenerator.Dispose();
RealWorldTerrainDownloadManager.Dispose();
RealWorldTerrainRoadGenerator.Dispose();
RealWorldTerrainGrassGenerator.Dispose();
RealWorldTerrainTreesGenerator.Dispose();
RealWorldTerrainBuildingGenerator.Dispose();
EditorUtility.UnloadUnusedAssetsImmediate();
RealWorldTerrainPhase.requiredPhases = null;
if (RealWorldTerrainPhase.activePhase != null)
{
try
{
RealWorldTerrainPhase.activePhase.Finish();
}
catch
{
}
}
RealWorldTerrainPhase.activePhase = null;
RealWorldTerrainPhase.activePhaseIndex = -1;
if (wnd != null) wnd.Repaint();
GC.Collect();
}
private static void OnCancelInMainThread()
{
CancelCapture();
EditorApplication.update -= OnCancelInMainThread;
}
private void OnDestroy()
{
wnd = null;
prefs.Save();
}
private void OnEnable()
{
wnd = this;
if (prefs == null) prefs = new RealWorldTerrainPrefs();
prefs.Load();
RealWorldTerrainWindowUI.OnEnable();
RealWorldTerrainUpdaterWindow.CheckNewVersionAvailable();
}
private void OnGUI()
{
RealWorldTerrainWindowUI.OnGUI();
}
[MenuItem("Window/Infinity Code/Real World Terrain/Open Real World Terrain", false, 0)]
private static void OpenWindow()
{
OpenWindow(RealWorldTerrainGenerateType.full);
}
public static void OpenWindow(RealWorldTerrainGenerateType type, RealWorldTerrainMonoBase target = null)
{
generateTarget = target;
generateType = type;
wnd = GetWindow(false, "Real World Terrain");
if (target == null)
{
prefs = new RealWorldTerrainPrefs();
prefs.Load();
}
else if (type == RealWorldTerrainGenerateType.full)
{
prefs = RealWorldTerrainPrefs.GetPrefs(target, true);
generateTarget = null;
}
else prefs = RealWorldTerrainPrefs.GetPrefs(target);
if (type == RealWorldTerrainGenerateType.additional)
{
prefs.generateBuildings = false;
prefs.generateGrass = false;
prefs.generateRoads = false;
prefs.generateTrees = false;
}
RealWorldTerrainWindowUI.InitTextureProviders();
RealWorldTerrainUpdaterWindow.CheckNewVersionAvailable();
}
private static void PrepareStart()
{
generateInThread = RealWorldTerrainPrefs.LoadPref("GenerateInThread", true);
RealWorldTerrainOSMUtils.InitOSMServer();
if (!CheckFields()) return;
if (prefs.resultType == RealWorldTerrainResultType.mesh)
{
if (prefs.generateTextures) prefs.terrainCount = prefs.textureCount;
else prefs.terrainCount = RealWorldTerrainVector2i.one;
}
else if (prefs.resultType == RealWorldTerrainResultType.terrain)
{
prefs.textureCount = prefs.terrainCount;
}
RealWorldTerrainElevationGenerator.elevations = new List();
if (generateType == RealWorldTerrainGenerateType.full || generateType == RealWorldTerrainGenerateType.terrain || generateType == RealWorldTerrainGenerateType.additional)
{
if (prefs.elevationProvider == RealWorldTerrainElevationProvider.SRTM) RealWorldTerrainSRTMElevationGenerator.Init();
else if (prefs.elevationProvider == RealWorldTerrainElevationProvider.BingMaps) RealWorldTerrainBingElevationGenerator.Init();
else if (prefs.elevationProvider == RealWorldTerrainElevationProvider.SRTM30) RealWorldTerrainSRTM30ElevationGenerator.Init();
else if (prefs.elevationProvider == RealWorldTerrainElevationProvider.Mapbox) RealWorldTerrainMapboxElevationGenerator.Init();
else if (prefs.elevationProvider == RealWorldTerrainElevationProvider.ArcGIS) RealWorldTerrainArcGISElevationGenerator.Init();
}
if (generateType == RealWorldTerrainGenerateType.full || generateType == RealWorldTerrainGenerateType.texture)
{
if (prefs.generateTextures && prefs.resultType != RealWorldTerrainResultType.gaiaStamp)
{
if (prefs.textureResultType == RealWorldTerrainTextureResultType.regularTexture || prefs.textureResultType == RealWorldTerrainTextureResultType.hugeTexture)
{
RealWorldTerrainTextureGenerator.Init();
}
else if (prefs.textureResultType == RealWorldTerrainTextureResultType.terrainLayers)
{
RealWorldTerrainTerrainLayersGenerator.Init();
}
}
}
if (generateType == RealWorldTerrainGenerateType.full || generateType == RealWorldTerrainGenerateType.additional)
{
if (prefs.resultType != RealWorldTerrainResultType.gaiaStamp)
{
RealWorldTerrainBuildingGenerator.Download();
RealWorldTerrainRoadGenerator.Download();
RealWorldTerrainTreesGenerator.Download();
RealWorldTerrainGrassGenerator.Download();
RealWorldTerrainRiverGenerator.Download();
}
}
if (prefs.mapType == null) prefs.mapType = RealWorldTerrainTextureProviderManager.FindMapType(prefs.mapTypeID);
prefs.mapTypeID = prefs.mapType.fullID;
prefs.mapTypeExtraFields = prefs.mapType.GetSettings();
if (generateTarget != null) prefs.Apply(generateTarget);
if (generateType == RealWorldTerrainGenerateType.full) RealWorldTerrainHistoryWindow.Add(prefs);
isCapturing = true;
RealWorldTerrainPhase.Init();
if (OnCaptureStarted != null) OnCaptureStarted();
}
public static void StartCapture()
{
prefs.Save();
if (generateType == RealWorldTerrainGenerateType.additional)
{
RealWorldTerrainMonoBase target = generateTarget;
if (target is RealWorldTerrainContainer)
{
if (prefs.generateBuildings) RealWorldTerrainUtils.DeleteGameObject(target.transform, "Buildings");
if (prefs.generateRoads) RealWorldTerrainUtils.DeleteGameObject(target.transform, "Roads");
if (prefs.generateRivers) RealWorldTerrainUtils.DeleteGameObject(target.transform, "Rivers");
if (prefs.generateTrees)
{
foreach (RealWorldTerrainItem item in (target as RealWorldTerrainContainer).terrains)
{
item.terrainData.treeInstances = new TreeInstance[0];
item.terrainData.treePrototypes = new TreePrototype[0];
}
}
if (prefs.generateGrass)
{
foreach (RealWorldTerrainItem item in (target as RealWorldTerrainContainer).terrains)
{
item.terrainData.detailPrototypes = new DetailPrototype[0];
}
}
}
else
{
RealWorldTerrainItem item = target as RealWorldTerrainItem;
string index = item.x + "x" + (item.container.terrainCount.y - item.y - 1);
if (prefs.generateBuildings) RealWorldTerrainUtils.DeleteGameObject(target.transform.parent, "Buildings " + index);
if (prefs.generateRoads) RealWorldTerrainUtils.DeleteGameObject(target.transform.parent, "Roads " + index);
if (prefs.generateTrees)
{
item.terrainData.treeInstances = new TreeInstance[0];
item.terrainData.treePrototypes = new TreePrototype[0];
}
if (prefs.generateGrass) item.terrainData.detailPrototypes = new DetailPrototype[0];
}
}
PrepareStart();
}
private void Update()
{
if (RealWorldTerrainPhase.activePhase == null) return;
try
{
RealWorldTerrainPhase.activePhase.Enter();
}
catch (Exception e)
{
Debug.LogException(e);
CancelCapture();
}
}
}
}