This commit is contained in:
2025-06-09 00:11:54 +08:00
parent d8c6eb0bd6
commit c773a6bb8d
11207 changed files with 48929 additions and 304 deletions

View File

@@ -0,0 +1,34 @@
/* INFINITY CODE 2013-2019 */
/* http://www.infinity-code.com */
using System;
using UnityEditor;
using UnityEngine;
namespace InfinityCode.RealWorldTerrain.Windows
{
public class RealWorldTerrainAboutWindow : EditorWindow
{
[MenuItem("Window/Infinity Code/Real World Terrain/About", false, 2000)]
public static void OpenWindow()
{
RealWorldTerrainAboutWindow window = GetWindow<RealWorldTerrainAboutWindow>(true, "About", true);
window.minSize = new Vector2(200, 100);
window.maxSize = new Vector2(200, 100);
}
public void OnGUI()
{
GUIStyle titleStyle = new GUIStyle(EditorStyles.boldLabel);
titleStyle.alignment = TextAnchor.MiddleCenter;
GUIStyle textStyle = new GUIStyle(EditorStyles.label);
textStyle.alignment = TextAnchor.MiddleCenter;
GUILayout.Label("Real World Terrain", titleStyle);
GUILayout.Label("version " + RealWorldTerrainWindow.version, textStyle);
GUILayout.Label("created Infinity Code", textStyle);
GUILayout.Label("2013-" + DateTime.Now.Year, textStyle);
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: c49762c2dfe9bc945b29081dac646717
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,133 @@
/* INFINITY CODE 2013-2019 */
/* http://www.infinity-code.com */
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;
using UnityEditor;
using UnityEngine;
namespace InfinityCode.RealWorldTerrain.Windows
{
public class RealWorldTerrainBuildRPresetsWindow : EditorWindow
{
public static string[] buildrGeneratorStyles;
public static string[] buildrGeneratorTexturePacks;
private static RealWorldTerrainBuildRPresetsWindow wnd;
public static List<RealWorldTerrainBuildRPresetsItem> presets;
private Vector2 scrollPosition;
private static RealWorldTerrainPrefs prefs
{
get { return RealWorldTerrainWindow.prefs; }
}
public static void OpenWindow()
{
wnd = GetWindow<RealWorldTerrainBuildRPresetsWindow>("BuildR Presets");
if (prefs.customBuildRPresets != null) presets = prefs.customBuildRPresets.ToList();
else presets = new List<RealWorldTerrainBuildRPresetsItem>();
}
private static List<string> GetBuildRXML(string datatype)
{
const string xmlPath = "Assets/Buildr/XML/";
string[] paths = Directory.GetFiles(xmlPath);
List<string> filelist = new List<string>();
foreach (string path in paths)
{
if (path.Contains(".meta")) continue;
if (!path.Contains(".xml")) continue;
XmlDocument xml = new XmlDocument();
xml.Load(path);
XmlNodeList xmlData = xml.SelectNodes("data/datatype");
if (xmlData != null && xmlData.Count > 0 && xmlData[0].FirstChild.Value == datatype) filelist.Add(path.Substring(xmlPath.Length));
}
return filelist;
}
private static string OnBuildRPreset(string val, string title)
{
GUILayout.BeginHorizontal();
val = EditorGUILayout.TextField(title, val);
if (GUILayout.Button("...", GUILayout.ExpandWidth(false)))
{
string v1 = EditorUtility.OpenFilePanel(title, Application.dataPath, "xml");
if (!string.IsNullOrEmpty(v1)) val = v1;
}
if (GUILayout.Button("Clear", GUILayout.ExpandWidth(false))) val = "";
GUILayout.EndHorizontal();
return val;
}
private void OnDestroy()
{
prefs.customBuildRPresets = presets.ToArray();
}
private void OnGUI()
{
if (buildrGeneratorStyles == null)
{
List<string> generatorStyles = GetBuildRXML("ProGen");
buildrGeneratorStyles = generatorStyles.ToArray();
prefs.customBuildRGeneratorStyle = generatorStyles.IndexOf("none.xml");
}
if (buildrGeneratorTexturePacks == null)
{
List<string> generatorTexturePacks = GetBuildRXML("TexturePack");
buildrGeneratorTexturePacks = generatorTexturePacks.ToArray();
prefs.customBuildRGeneratorTexturePack = generatorTexturePacks.IndexOf("alltextures.xml");
}
prefs.customBuildRGeneratorStyle = EditorGUILayout.Popup("Style: ", prefs.customBuildRGeneratorStyle, buildrGeneratorStyles);
prefs.customBuildRGeneratorTexturePack = EditorGUILayout.Popup("Texture Pack: ", prefs.customBuildRGeneratorTexturePack, buildrGeneratorTexturePacks);
if (presets == null)
{
if (prefs.customBuildRPresets != null) presets = prefs.customBuildRPresets.ToList();
else presets = new List<RealWorldTerrainBuildRPresetsItem>();
}
if (GUILayout.Button("Add preset") || presets.Count == 0) presets.Add(new RealWorldTerrainBuildRPresetsItem());
scrollPosition = GUILayout.BeginScrollView(scrollPosition);
for (int i = 0; i < presets.Count; i++)
{
RealWorldTerrainBuildRPresetsItem preset = presets[i];
GUILayout.BeginHorizontal();
GUILayout.Label((i + 1).ToString(), GUILayout.ExpandWidth(false));
GUILayout.BeginVertical();
preset.facade = OnBuildRPreset(preset.facade, "Facade presets:");
preset.roof = OnBuildRPreset(preset.roof, "Roof presets:");
preset.texture = OnBuildRPreset(preset.texture, "Texture presets:");
GUILayout.EndVertical();
if (GUILayout.Button("X", GUILayout.ExpandWidth(false))) presets[i] = null;
GUILayout.EndHorizontal();
}
GUILayout.EndScrollView();
presets.RemoveAll(p => p == null);
if (GUILayout.Button("Close"))
{
wnd.Close();
}
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 905b52232d8632b46bc77031daf0ba82
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,163 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using System.IO;
using UnityEditor;
using UnityEngine;
namespace InfinityCode.RealWorldTerrain.Windows
{
public class RealWorldTerrainClearCacheWindow : EditorWindow
{
private long elevationSize;
private long osmSize;
private long textureSize;
private void ClearElevationCache()
{
RealWorldTerrainFileSystem.SafeDeleteDirectory(RealWorldTerrainEditorUtils.heightmapCacheFolder);
elevationSize = 0;
}
private void ClearHistory()
{
RealWorldTerrainFileSystem.SafeDeleteDirectory(RealWorldTerrainEditorUtils.historyCacheFolder);
RealWorldTerrainHistoryWindow.Load();
}
private void ClearOSMCache()
{
RealWorldTerrainFileSystem.SafeDeleteDirectory(RealWorldTerrainEditorUtils.osmCacheFolder);
osmSize = 0;
}
private static void ClearSettings()
{
if (File.Exists(RealWorldTerrainPrefs.prefsFilename)) File.Delete(RealWorldTerrainPrefs.prefsFilename);
RealWorldTerrainSettingsWindow.ClearSettings();
RealWorldTerrainEditorUtils.ClearFoldersCache();
}
private void ClearTextureCache(bool errorOnly = false)
{
if (!errorOnly)
{
RealWorldTerrainFileSystem.SafeDeleteDirectory(RealWorldTerrainEditorUtils.textureCacheFolder);
textureSize = 0;
}
else
{
string[] files = Directory.GetFiles(RealWorldTerrainEditorUtils.textureCacheFolder, "*.err", SearchOption.AllDirectories);
foreach (string file in files) RealWorldTerrainFileSystem.SafeDeleteFile(file);
textureSize = RealWorldTerrainFileSystem.GetDirectorySize(RealWorldTerrainEditorUtils.textureCacheFolder);
}
}
private void OnEnable()
{
elevationSize = RealWorldTerrainFileSystem.GetDirectorySize(RealWorldTerrainEditorUtils.heightmapCacheFolder);
osmSize = RealWorldTerrainFileSystem.GetDirectorySize(RealWorldTerrainEditorUtils.osmCacheFolder);
textureSize = RealWorldTerrainFileSystem.GetDirectorySize(RealWorldTerrainEditorUtils.textureCacheFolder);
}
public static string FormatSize(long size)
{
if (size > 10485760) return size / 1048576 + " MB";
if (size > 1024) return (size / 1048576f).ToString("0.000") + " MB";
return size + " B";
}
private void OnGUI()
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Elevations", FormatSize(elevationSize), EditorStyles.textField);
if (GUILayout.Button("Open", GUILayout.ExpandWidth(false))) EditorUtility.RevealInFinder(RealWorldTerrainEditorUtils.heightmapCacheFolder);
if (GUILayout.Button("Clear", GUILayout.ExpandWidth(false)))
{
if (EditorUtility.DisplayDialog("Clear cache", "Are you sure you want to clear the elevation cache?", "Yes", "No"))
{
ClearElevationCache();
EditorUtility.DisplayDialog("Complete", "Clear cache complete.", "OK");
}
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Textures", FormatSize(textureSize), EditorStyles.textField);
if (GUILayout.Button("Open", GUILayout.ExpandWidth(false))) EditorUtility.RevealInFinder(RealWorldTerrainEditorUtils.textureCacheFolder);
if (GUILayout.Button("Clear", GUILayout.ExpandWidth(false)))
{
int result = EditorUtility.DisplayDialogComplex("Clear cache", "Are you sure you want to clear the texture cache?", "Full", "No", "Errors only");
if (result == 0)
{
ClearTextureCache();
EditorUtility.DisplayDialog("Complete", "Clear cache complete.", "OK");
}
else if (result == 2)
{
ClearTextureCache(true);
EditorUtility.DisplayDialog("Complete", "Clear cache complete.", "OK");
}
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("OSM", FormatSize(osmSize), EditorStyles.textField);
if (GUILayout.Button("Open", GUILayout.ExpandWidth(false))) EditorUtility.RevealInFinder(RealWorldTerrainEditorUtils.osmCacheFolder);
if (GUILayout.Button("Clear", GUILayout.ExpandWidth(false)))
{
if (EditorUtility.DisplayDialog("Clear cache", "Are you sure you want to clear the OSM cache?", "Yes", "No"))
{
ClearOSMCache();
EditorUtility.DisplayDialog("Complete", "Clear cache complete.", "OK");
}
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("History");
if (GUILayout.Button("Open", GUILayout.ExpandWidth(false))) EditorUtility.RevealInFinder(RealWorldTerrainEditorUtils.historyCacheFolder);
if (GUILayout.Button("Clear", GUILayout.ExpandWidth(false)))
{
if (EditorUtility.DisplayDialog("Clear cache", "Are you sure you want to clear the history?", "Yes", "No"))
{
ClearHistory();
EditorUtility.DisplayDialog("Complete", "Clear cache complete.", "OK");
}
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Settings");
if (GUILayout.Button("Clear", GUILayout.ExpandWidth(false)))
{
if (EditorUtility.DisplayDialog("Clear cache", "Are you sure you want to clear the settings?", "Yes", "No"))
{
ClearSettings();
EditorUtility.DisplayDialog("Complete", "Clear cache complete.", "OK");
}
}
EditorGUILayout.EndHorizontal();
if (GUILayout.Button("Clear All"))
{
if (EditorUtility.DisplayDialog("Clear cache", "Are you sure you want to clear the cache?", "Yes", "No"))
{
ClearElevationCache();
ClearTextureCache();
ClearOSMCache();
ClearHistory();
ClearSettings();
EditorUtility.DisplayDialog("Complete", "Clear cache complete.", "OK");
Close();
}
}
}
public static void OpenWindow()
{
RealWorldTerrainClearCacheWindow wnd = GetWindow<RealWorldTerrainClearCacheWindow>(true, "Clear cache");
DontDestroyOnLoad(wnd);
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: fb5edb018da5f88499d42bf04f186ca2
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,167 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using UnityEditor;
using UnityEngine;
namespace InfinityCode.RealWorldTerrain.Windows
{
public class RealWorldTerrainHistoryWindow: EditorWindow
{
private static List<RealWorldTerrainHistoryItem> recent;
private Vector2 scrollPosition;
private static string historyPath
{
get
{
return Path.Combine(RealWorldTerrainEditorUtils.historyCacheFolder, "hystory.xml");
}
}
public static void Add(RealWorldTerrainPrefs prefs)
{
string id = Guid.NewGuid().ToString();
string path = Path.Combine(RealWorldTerrainEditorUtils.historyCacheFolder, id + ".xml");
File.WriteAllText(path, prefs.ToXML(new XmlDocument()).OuterXml, Encoding.UTF8);
if (recent == null) Load();
recent.Add(new RealWorldTerrainHistoryItem(prefs, id));
Save();
}
public static void Load()
{
if (recent == null) recent = new List<RealWorldTerrainHistoryItem>();
else recent.Clear();
if (!File.Exists(historyPath)) return;
XmlDocument doc = new XmlDocument();
doc.Load(historyPath);
foreach (XmlNode node in doc.FirstChild.ChildNodes) recent.Add(new RealWorldTerrainHistoryItem(node));
}
private void OnGUI()
{
if (recent == null) Load();
GUIStyle headerStyle = new GUIStyle(EditorStyles.label);
headerStyle.alignment = TextAnchor.MiddleCenter;
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
GUILayout.Label("№", headerStyle, GUILayout.Width(40));
GUILayout.Label("Title", headerStyle);
GUILayout.Label("Time", headerStyle, GUILayout.Width(120));
GUILayout.Box("", GUIStyle.none, GUILayout.Width(50));
EditorGUILayout.EndHorizontal();
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
GUIContent useContent = new GUIContent(">", "Restore");
GUIContent deleteContent = new GUIContent("X", "Remove");
int removeIndex = -1;
int index = 1;
for (int i = recent.Count - 1; i >= 0; i--)
{
RealWorldTerrainHistoryItem item = recent[i];
EditorGUILayout.BeginHorizontal();
GUILayout.Label(index.ToString(), GUILayout.Width(40));
GUILayout.Label(item.title);
DateTime time = new DateTime(item.timestamp);
GUILayout.Label(time.ToString("yyyy-MM-dd HH:mm"), GUILayout.Width(120));
if (GUILayout.Button(useContent, GUILayout.Width(20)))
{
if (RealWorldTerrainWindow.wnd != null) RealWorldTerrainWindow.wnd.Close();
RealWorldTerrainWindow.OpenWindow(RealWorldTerrainGenerateType.full);
RealWorldTerrainWindow.prefs.LoadFromXML(Path.Combine(RealWorldTerrainEditorUtils.historyCacheFolder, item.id + ".xml"));
}
if (GUILayout.Button(deleteContent, GUILayout.Width(20))) removeIndex = i;
EditorGUILayout.EndHorizontal();
index++;
}
EditorGUILayout.EndScrollView();
if (GUILayout.Button("Close")) Close();
if (removeIndex != -1)
{
RealWorldTerrainHistoryItem item = recent[removeIndex];
string filaname = Path.Combine(RealWorldTerrainEditorUtils.historyCacheFolder, item.id + ".xml");
if (File.Exists(filaname)) File.Delete(filaname);
recent.RemoveAt(removeIndex);
Save();
Repaint();
}
}
private static void Save()
{
XmlDocument doc = new XmlDocument();
XmlNode node = doc.CreateElement("History");
doc.AppendChild(node);
foreach (RealWorldTerrainHistoryItem item in recent) item.Save(node);
File.WriteAllText(historyPath, doc.OuterXml, Encoding.UTF8);
}
[MenuItem("Window/Infinity Code/Real World Terrain/History")]
public static void OpenWindow()
{
GetWindow<RealWorldTerrainHistoryWindow>(true, "History");
}
}
public class RealWorldTerrainHistoryItem
{
public string title;
public string id;
public long timestamp;
public RealWorldTerrainHistoryItem(RealWorldTerrainPrefs prefs, string id)
{
if (!string.IsNullOrEmpty(prefs.title)) title = prefs.title;
else title = "(" + prefs.topLatitude + ", " + prefs.leftLongitude + ") - (" + prefs.bottomLatitude + ", " + prefs.rightLongitude + ")";
this.id = id;
timestamp = DateTime.Now.Ticks;
}
public RealWorldTerrainHistoryItem(XmlNode node)
{
title = node["Title"].InnerText.Trim();
id = node["ID"].InnerText;
timestamp = long.Parse(node["Timestamp"].InnerText);
}
public void Save(XmlNode node)
{
XmlDocument doc = node.OwnerDocument;
XmlElement itemNode = doc.CreateElement("Item");
XmlElement titleNode = doc.CreateElement("Title");
XmlElement idNode = doc.CreateElement("ID");
XmlElement timestampNode = doc.CreateElement("Timestamp");
titleNode.AppendChild(doc.CreateCDataSection(title));
idNode.AppendChild(doc.CreateTextNode(id));
timestampNode.AppendChild(doc.CreateTextNode(timestamp.ToString()));
itemNode.AppendChild(titleNode);
itemNode.AppendChild(idNode);
itemNode.AppendChild(timestampNode);
node.AppendChild(itemNode);
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 3d96879a74ae6564dacf5ea4e9b73c30
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,159 @@
using System;
using UnityEditor;
using UnityEngine;
namespace InfinityCode.RealWorldTerrain.Windows
{
public class RealWorldTerrainInfoWindow : EditorWindow
{
private Vector2 scrollPosition;
private const float mb = 1048576;
private static RealWorldTerrainInfoWindow instance;
private MemoryUsage memoryUsage = new MemoryUsage();
private DownloadInfo downloadInfo = new DownloadInfo();
private int selectedTool = 0;
private bool CalculateUsage()
{
RealWorldTerrainPrefs p = RealWorldTerrainWindow.prefs;
if (p == null)
{
EditorUtility.DisplayDialog("Error", "Can not find the prefs. Open Real World Terrain window.", "OK");
Close();
return false;
}
if (selectedTool == 0) downloadInfo.Calculate(p);
else if (selectedTool == 1) memoryUsage.Calculate(p);
return true;
}
private static void DrawField(string prefix, string value)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(prefix, GUILayout.MaxWidth(instance.position.size.x / 2 - 10));
EditorGUILayout.LabelField(value, GUILayout.MaxWidth(instance.position.size.x / 2 - 10));
EditorGUILayout.EndHorizontal();
}
private void OnEnable()
{
instance = this;
CalculateUsage();
}
public void OnGUI()
{
EditorGUI.BeginChangeCheck();
//selectedTool = GUILayout.Toolbar(selectedTool, new[] {"Download", "Result"});
if (EditorGUI.EndChangeCheck())
{
if (!CalculateUsage()) return;
scrollPosition = Vector2.zero;
}
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
/*if (selectedTool == 0) downloadInfo.Draw();
else if (selectedTool == 1)*/ memoryUsage.Draw();
EditorGUILayout.EndScrollView();
if (GUILayout.Button("Refresh")) CalculateUsage();
}
public static void OpenWindow()
{
GetWindow<RealWorldTerrainInfoWindow>(true, "Area Info", true);
}
internal class DownloadInfo
{
private int heightmapRequests;
private int texturesRequests;
private int osmRequests;
private int totalRequests;
public void Calculate(RealWorldTerrainPrefs p)
{
}
public void Draw()
{
}
}
internal class MemoryUsage
{
private long heightmap;
private long controltexture;
private long detailmap;
private int countGrass;
private long basemap;
private long texture;
private long totalPerTerrain;
private RealWorldTerrainVector2i countTerrains;
private long total;
private string heightmapS;
private string controltextureS;
private string detailmapS;
private string basemapS;
private string textureS;
private string totalPerTerrainS;
private string totalS;
private string countTerrainsS;
public void Calculate(RealWorldTerrainPrefs p)
{
heightmap = p.heightmapResolution * p.heightmapResolution * 4;
controltexture = p.controlTextureResolution * p.controlTextureResolution * 4;
detailmap = p.detailResolution * p.detailResolution * 4;
countGrass = p.generateGrass ? p.grassPrefabs.Count : 0;
basemap = p.baseMapResolution * p.baseMapResolution * 4;
texture = 0;
if (p.generateTextures)
{
if (p.textureResultType == RealWorldTerrainTextureResultType.regularTexture) texture = p.textureSize.x * p.textureSize.y * 4;
else if (p.textureResultType == RealWorldTerrainTextureResultType.hugeTexture) texture = p.hugeTexturePageSize * p.hugeTexturePageSize * p.hugeTextureCols * p.hugeTextureRows * 3;
}
totalPerTerrain = heightmap + countTerrains + detailmap * countGrass + basemap + texture;
countTerrains = p.terrainCount;
total = totalPerTerrain * countTerrains.count;
string format = "{0:### ##0.00}";
heightmapS = string.Format(format, heightmap / mb) + " mb";
controltextureS = string.Format(format, controltexture / mb) + " mb";
detailmapS = string.Format(format, detailmap * countGrass / mb) + " mb";
basemapS = string.Format(format, basemap / mb) + " mb";
textureS = string.Format(format, texture / mb) + " mb";
totalPerTerrainS = string.Format(format, totalPerTerrain / mb) + " mb";
countTerrainsS = countTerrains.count + " (" + countTerrains.x + "x" + countTerrains.y + ")";
totalS = string.Format(format, total / mb) + " mb";
}
public void Draw()
{
EditorGUILayout.HelpBox("Uncompressed size of the result by the fields.\nHere only the main fields affecting the size are shown.\nNote that the memory that RWT will use for generation is not shown here.", MessageType.Info);
DrawField("Height Map:", heightmapS);
DrawField("Control Texture:", controltextureS);
DrawField("Detail Map: ", detailmapS);
DrawField("Base Map: ", basemapS);
DrawField("Textures: ", textureS);
EditorGUILayout.Space();
DrawField("Total Per Terrain: ", totalPerTerrainS);
EditorGUILayout.LabelField("---");
DrawField("Count Terrains: ", countTerrainsS);
DrawField("Total: ", totalS);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7661126f067dcc24abc2b041b0d1c041
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,116 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using System;
using UnityEditor;
using UnityEngine;
namespace InfinityCode.RealWorldTerrain.Windows
{
public class RealWorldTerrainMemoryUsageWindow : EditorWindow
{
private Vector2 scrollPosition;
private float mb = 1048576;
private long heightmap;
private long controltexture;
private long detailmap;
private int countGrass;
private long basemap;
private long texture;
private long totalPerTerrain;
private RealWorldTerrainVector2i countTerrains;
private long total;
private string heightmapS;
private string controltextureS;
private string detailmapS;
private string basemapS;
private string textureS;
private string totalPerTerrainS;
private string totalS;
private string countTerrainsS;
private void CalculateUsage()
{
RealWorldTerrainPrefs p = RealWorldTerrainWindow.prefs;
if (p == null)
{
EditorUtility.DisplayDialog("Error", "Can not find the prefs. Open Real World Terrain window.", "OK");
Close();
return;
}
heightmap = p.heightmapResolution * p.heightmapResolution * 4;
controltexture = p.controlTextureResolution * p.controlTextureResolution * 4;
detailmap = p.detailResolution * p.detailResolution * 4;
countGrass = p.generateGrass ? p.grassPrefabs.Count : 0;
basemap = p.baseMapResolution * p.baseMapResolution * 4;
texture = 0;
if (p.generateTextures)
{
if (p.textureResultType == RealWorldTerrainTextureResultType.regularTexture) texture = p.textureSize.x * p.textureSize.y * 4;
else if (p.textureResultType == RealWorldTerrainTextureResultType.hugeTexture) texture = p.hugeTexturePageSize * p.hugeTexturePageSize * p.hugeTextureCols * p.hugeTextureRows * 3;
}
totalPerTerrain = heightmap + countTerrains + detailmap * countGrass + basemap + texture;
countTerrains = p.terrainCount;
total = totalPerTerrain * countTerrains.count;
string format = "{0:### ##0.00}";
heightmapS = String.Format(format, heightmap / mb) + " mb";
controltextureS = String.Format(format, controltexture / mb) + " mb";
detailmapS = String.Format(format, detailmap * countGrass / mb) + " mb";
basemapS = String.Format(format, basemap / mb) + " mb";
textureS = String.Format(format, texture / mb) + " mb";
totalPerTerrainS = String.Format(format, totalPerTerrain / mb) + " mb";
countTerrainsS = countTerrains.count + " (" + countTerrains.x + "x" + countTerrains.y + ")";
totalS = String.Format(format, total / mb) + " mb";
}
private void OnEnable()
{
CalculateUsage();
}
private void DrawField(string prefix, string value)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(prefix, GUILayout.MaxWidth(position.size.x / 2 - 10));
EditorGUILayout.LabelField(value, GUILayout.MaxWidth(position.size.x / 2 - 10));
EditorGUILayout.EndHorizontal();
}
public void OnGUI()
{
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
EditorGUILayout.HelpBox("Uncompressed size of the result by the fields.\nHere only the main fields affecting the size are shown.\nNote that the memory that RWT will use for generation is not shown here.", MessageType.Info);
DrawField("Height Map:", heightmapS);
DrawField("Control Texture:", controltextureS);
DrawField("Detail Map: ", detailmapS);
DrawField("Base Map: ", basemapS);
DrawField("Textures: ", textureS);
EditorGUILayout.Space();
DrawField("Total Per Terrain: ", totalPerTerrainS);
EditorGUILayout.LabelField("---");
DrawField("Count Terrains: ", countTerrainsS);
DrawField("Total: ", totalS);
EditorGUILayout.EndScrollView();
if (GUILayout.Button("Refresh"))
{
CalculateUsage();
}
}
public static void OpenWindow()
{
GetWindow<RealWorldTerrainMemoryUsageWindow>(true, "Memory Usage", true);
}
}
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 9376171e0d65a59409225ae4c95728ca
timeCreated: 1539976693
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,116 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using System;
using UnityEditor;
using UnityEngine;
namespace InfinityCode.RealWorldTerrain.Windows
{
public class RealWorldTerrainSettingsGeneratorWindow : EditorWindow
{
private int heightmapQuality = 50;
private int textureQuality = 50;
private Vector2 scrollPosition;
private bool generateGrass;
private bool generateTexture = true;
public static void OpenWindow()
{
GetWindow<RealWorldTerrainSettingsGeneratorWindow>(false, "Settings generator");
}
private void OnGUI()
{
RealWorldTerrainPrefs prefs = RealWorldTerrainWindow.prefs;
heightmapQuality = EditorGUILayout.IntSlider("Heightmap quality:", heightmapQuality, 1, 100);
generateTexture = EditorGUILayout.Toggle("Generate texture:", generateTexture);
if (generateTexture) textureQuality = EditorGUILayout.IntSlider("Texture quality:", textureQuality, 1, 100);
generateGrass = EditorGUILayout.Toggle("Generate grass", generateGrass);
double rangeX = prefs.rightLongitude - prefs.leftLongitude;
double rangeY = prefs.topLatitude - prefs.bottomLatitude;
double sizeX = 0;
double sizeY = 0;
if (prefs.sizeType == 0)
{
double scfY = Math.Sin(prefs.topLatitude * Mathf.Deg2Rad);
double sctY = Math.Sin(prefs.bottomLatitude * Mathf.Deg2Rad);
double ccfY = Math.Cos(prefs.topLatitude * Mathf.Deg2Rad);
double cctY = Math.Cos(prefs.bottomLatitude * Mathf.Deg2Rad);
double cX = Math.Cos(rangeX * Mathf.Deg2Rad);
double sizeX1 = Math.Abs(RealWorldTerrainGeo.EARTH_RADIUS * Math.Acos(scfY * scfY + ccfY * ccfY * cX));
double sizeX2 = Math.Abs(RealWorldTerrainGeo.EARTH_RADIUS * Math.Acos(sctY * sctY + cctY * cctY * cX));
sizeX = (sizeX1 + sizeX2) / 2.0;
sizeY = RealWorldTerrainGeo.EARTH_RADIUS * Math.Acos(scfY * sctY + ccfY * cctY);
}
else if (prefs.sizeType == 1)
{
sizeX = Math.Abs(rangeX / 360 * RealWorldTerrainGeo.EQUATOR_LENGTH);
sizeY = Math.Abs(rangeY / 360 * RealWorldTerrainGeo.EQUATOR_LENGTH);
}
int hmX = (int)Math.Round(sizeX / 9 * heightmapQuality);
int hmY = (int)Math.Round(sizeY / 9 * heightmapQuality);
int tsX = generateTexture ? (int)Math.Round(sizeX * 10 * textureQuality) : 0;
int tsY = generateTexture ? (int)Math.Round(sizeY * 10 * textureQuality) : 0;
int countX = Mathf.Max(hmX / 4096 + 1, tsX / 4096 + 1);
int countY = Mathf.Max(hmY / 4096 + 1, tsY / 4096 + 1);
if (countX > 10 || countY > 10)
{
GUIStyle style = new GUIStyle(GUI.skin.label);
style.normal.textColor = Color.red;
style.fontStyle = FontStyle.Bold;
style.wordWrap = true;
GUILayout.Label("Too high a settings. Memory overflow may occur.", style);
}
int heightmapRes = Mathf.Max(hmX / countX, hmY / countY);
heightmapRes = Mathf.Clamp(Mathf.NextPowerOfTwo(heightmapRes), 32, 4096);
int detailRes = (generateGrass) ? heightmapRes : 32;
int textureWidth = Mathf.Clamp(Mathf.NextPowerOfTwo(tsX / countX), 32, 4096);
int textureHeight = Mathf.Clamp(Mathf.NextPowerOfTwo(tsY / countY), 32, 4096);
int basemapRes = Mathf.Clamp(Mathf.NextPowerOfTwo(Mathf.Max(textureWidth, textureHeight) / 4), 32, 4096);
GUILayout.Space(10);
GUILayout.Label(string.Format("Area size X:{0} km, Y:{1} km", sizeX, sizeY));
GUILayout.Space(10);
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
GUILayout.Label("Recommended settings:");
GUILayout.Label(string.Format("Count terrains: {0}x{1}", countX, countY));
GUILayout.Label("Heightmap resolution: " + heightmapRes);
GUILayout.Label("Detail resolution: " + detailRes);
GUILayout.Label("Basemap resolution: " + basemapRes);
if (generateTexture) GUILayout.Label(string.Format("Texture size: {0}x{1}", textureWidth, textureHeight));
EditorGUILayout.EndScrollView();
if (GUILayout.Button("Apply"))
{
prefs.terrainCount = new RealWorldTerrainVector2i(countX, countY);
prefs.heightmapResolution = heightmapRes;
prefs.detailResolution = detailRes;
prefs.baseMapResolution = basemapRes;
if (generateTexture)
{
prefs.textureSize = new RealWorldTerrainVector2i(textureWidth, textureHeight);
prefs.generateTextures = true;
}
else prefs.generateTextures = false;
if (RealWorldTerrainWindow.wnd != null) RealWorldTerrainWindow.wnd.Repaint();
Close();
}
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: b3e684d2dc6475a46a11a65c99e1e823
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,520 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using System;
using System.IO;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
namespace InfinityCode.RealWorldTerrain.Windows
{
public class RealWorldTerrainSettingsWindow : EditorWindow
{
private static RealWorldTerrainSettingsWindow wnd;
private string customCacheFolder;
private bool defaultCacheFolder = true;
private bool hasThirdPartyAssets;
private string resultName = "RealWorld Terrain";
private Vector2 scrollPosition = Vector2.zero;
private bool showGeneral = true;
private bool showCacheFolder = true;
private bool showResultName = true;
private bool showTerrainNames = true;
private bool showTerrainTokens;
private bool showThirdPartyAssets = false;
private bool showResultTokens;
private static Assembly assembly;
private bool appendResultNameIndex = true;
private string terrainName = "Terrain {x}x{y}";
private bool generateInThread = true;
private RealWorldTerrainOSMOverpassServer osmServer = RealWorldTerrainOSMOverpassServer.main;
private bool hasBuildR2;
private bool hasBuildR3;
private bool hasEasyRoads;
private bool hasProceduralToolkit;
private bool hasRoadArchitect;
private bool hasRTP;
private bool hasVolumeGrass;
private bool hasWorldStreamer;
private bool hasRAM2019;
private static void AddCompilerDirective(string key)
{
BuildTargetGroup g = EditorUserBuildSettings.selectedBuildTargetGroup;
#if UNITY_2023_1_OR_NEWER
UnityEditor.Build.NamedBuildTarget buildTarget = UnityEditor.Build.NamedBuildTarget.FromBuildTargetGroup(g);
string currentDefinitions = PlayerSettings.GetScriptingDefineSymbols(buildTarget);
#else
string currentDefinitions = PlayerSettings.GetScriptingDefineSymbolsForGroup(g);
#endif
string[] defs = currentDefinitions.Split(';').Select(d => d.Trim(' ')).ToArray();
if (defs.All(d => d != key))
{
ArrayUtility.Add(ref defs, key);
currentDefinitions = string.Join(";", defs);
#if UNITY_2023_1_OR_NEWER
PlayerSettings.SetScriptingDefineSymbols(buildTarget, currentDefinitions);
#else
PlayerSettings.SetScriptingDefineSymbolsForGroup(g, currentDefinitions);
#endif
}
}
public static void ClearSettings()
{
RealWorldTerrainPrefs.DeletePref("CacheFolder");
RealWorldTerrainPrefs.DeletePref("ResultName");
RealWorldTerrainPrefs.DeletePref("TerrainName");
RealWorldTerrainPrefs.DeletePref("AppendIndex");
RealWorldTerrainPrefs.DeletePref("GenerateInTread");
RealWorldTerrainPrefs.DeletePref("OSMServer");
if (wnd != null) wnd.Repaint();
}
private static void DeleteCompilerDirective(string key)
{
BuildTargetGroup g = EditorUserBuildSettings.selectedBuildTargetGroup;
#if UNITY_2023_1_OR_NEWER
UnityEditor.Build.NamedBuildTarget buildTarget = UnityEditor.Build.NamedBuildTarget.FromBuildTargetGroup(g);
string currentDefinitions = PlayerSettings.GetScriptingDefineSymbols(buildTarget);
#else
string currentDefinitions = PlayerSettings.GetScriptingDefineSymbolsForGroup(g);
#endif
string[] defs = currentDefinitions.Split(';').Select(d => d.Trim(' ')).ToArray();
if (defs.Any(d => d == key))
{
ArrayUtility.Remove(ref defs, key);
currentDefinitions = string.Join(";", defs);
#if UNITY_2023_1_OR_NEWER
PlayerSettings.SetScriptingDefineSymbols(buildTarget, currentDefinitions);
#else
PlayerSettings.SetScriptingDefineSymbolsForGroup(g, currentDefinitions);
#endif
}
}
private void DrawResultTokens()
{
EditorGUILayout.BeginVertical(GUI.skin.box);
showResultTokens = EditorGUILayout.Foldout(showResultTokens, "Available tokens");
if (showResultTokens)
{
GUILayout.Label("{title} - Title");
GUILayout.Label("{tllat} - Top-Left latitude");
GUILayout.Label("{tllng} - Top-Left longitude");
GUILayout.Label("{brlat} - Bottom-Right latitude");
GUILayout.Label("{brlng} - Bottom-Right longitude");
GUILayout.Label("{cx} - Count X");
GUILayout.Label("{cy} - Count Y");
GUILayout.Label("{st} - Size type");
GUILayout.Label("{me} - Max elevation");
GUILayout.Label("{mu} - Max underwater depth");
GUILayout.Label("{ds} - Depth shrapness");
GUILayout.Label("{dr} - Detail resolution");
GUILayout.Label("{rpp} - Resolution per patch");
GUILayout.Label("{bmr} - Base map resolution");
GUILayout.Label("{hmr} - Height map resolution");
GUILayout.Label("{tp} - Texture provider");
GUILayout.Label("{tw} - Texture width");
GUILayout.Label("{th} - Texture height");
GUILayout.Label("{tml} - Texture max level");
GUILayout.Label("{ticks} - Current time ticks");
GUILayout.Space(10);
}
EditorGUILayout.EndVertical();
}
private void DrawTerrainTokens()
{
EditorGUILayout.BeginVertical(GUI.skin.box);
showTerrainTokens = EditorGUILayout.Foldout(showTerrainTokens, "Available tokens");
if (showTerrainTokens)
{
GUILayout.Label("{tllat} - Top-Left latitude");
GUILayout.Label("{tllng} - Top-Left longitude");
GUILayout.Label("{brlat} - Bottom-Right latitude");
GUILayout.Label("{brlng} - Bottom-Right longitude");
GUILayout.Label("{x} - X Index");
GUILayout.Label("{y} - Y Index");
GUILayout.Space(10);
}
EditorGUILayout.EndVertical();
}
private static Type FindType(string className)
{
if (assembly == null) assembly = typeof(RealWorldTerrainSettingsWindow).Assembly;
return assembly.GetType(className);
}
private void OnCacheFolderGUI()
{
EditorGUILayout.BeginVertical(GUI.skin.box);
showCacheFolder = EditorGUILayout.Foldout(showCacheFolder, "Cache folder:");
if (showCacheFolder)
{
defaultCacheFolder = GUILayout.Toggle(defaultCacheFolder, "{PROJECT FOLDER}/RWT_Cache");
defaultCacheFolder = !GUILayout.Toggle(!defaultCacheFolder, "Custom cache folder");
if (!defaultCacheFolder)
{
GUILayout.BeginHorizontal();
customCacheFolder = EditorGUILayout.TextField("", customCacheFolder);
GUI.SetNextControlName("BrowseButton");
if (GUILayout.Button("Browse", GUILayout.ExpandWidth(false)))
{
GUI.FocusControl("BrowseButton");
string newCustomFolder = EditorUtility.OpenFolderPanel("Select the folder for the cache.", EditorApplication.applicationPath, "");
if (!string.IsNullOrEmpty(newCustomFolder)) customCacheFolder = newCustomFolder;
}
GUILayout.EndHorizontal();
}
}
EditorGUILayout.EndVertical();
}
private void OnBuildR2(ref bool dirty)
{
if (!hasBuildR2) return;
#if !BUILDR2
if (GUILayout.Button("Enable BuildR2"))
{
AddCompilerDirective("BUILDR2");
dirty = true;
}
#else
if (GUILayout.Button("Disable BuildR2"))
{
DeleteCompilerDirective("BUILDR2");
dirty = true;
}
#endif
hasThirdPartyAssets = true;
}
private void OnBuildR3(ref bool dirty)
{
if (!hasBuildR3) return;
#if !BUILDR3
if (GUILayout.Button("Enable BuildR3"))
{
AddCompilerDirective("BUILDR3");
dirty = true;
}
#else
if (GUILayout.Button("Disable BuildR3"))
{
DeleteCompilerDirective("BUILDR3");
dirty = true;
}
#endif
hasThirdPartyAssets = true;
}
private void OnEasyRoads(ref bool dirty)
{
if (!hasEasyRoads) return;
#if !EASYROADS3D
if (GUILayout.Button("Enable EasyRoads3D v3"))
{
AddCompilerDirective("EASYROADS3D");
dirty = true;
}
#else
if (GUILayout.Button("Disable EasyRoads3D v3"))
{
DeleteCompilerDirective("EASYROADS3D");
dirty = true;
}
#endif
hasThirdPartyAssets = true;
}
private void OnDestroy()
{
wnd = null;
}
private void OnEnable()
{
wnd = this;
customCacheFolder = RealWorldTerrainPrefs.LoadPref("CacheFolder", "");
defaultCacheFolder = customCacheFolder == "";
resultName = RealWorldTerrainPrefs.LoadPref("ResultName", "RealWorld Terrain");
terrainName = RealWorldTerrainPrefs.LoadPref("TerrainName", "Terrain {x}x{y}");
appendResultNameIndex = RealWorldTerrainPrefs.LoadPref("AppendIndex", true);
generateInThread = RealWorldTerrainPrefs.LoadPref("GenerateInThread", true);
osmServer = (RealWorldTerrainOSMOverpassServer)RealWorldTerrainPrefs.LoadPref("OSMServer", 0);
hasBuildR2 = FindType("BuildR2.BuildingEditor") != null;
hasBuildR3 = FindType("BuildRCities.EditorScripts.BuildREditor") != null;
string[] easyRoads3DResult = Directory.GetFiles("Assets", "EasyRoads3Dv3.dll", SearchOption.AllDirectories);
hasEasyRoads = easyRoads3DResult.Length > 0;
string[] proceduralToolkitResults = Directory.GetFiles("Assets", "ProceduralToolkit.Editor.asmdef", SearchOption.AllDirectories);
hasProceduralToolkit = proceduralToolkitResults.Length > 0;
hasRoadArchitect = FindType("GSDRoadEditor") != null;
hasRTP = FindType("RTP_LODmanagerEditor") != null;
hasVolumeGrass = FindType("VolumeGrassEditor") != null;
hasWorldStreamer = FindType("SceneSplitterEditor") != null;
hasRAM2019 = FindType("RamSplineEditor") != null;
}
private void OnGeneralGUI()
{
EditorGUILayout.BeginVertical(GUI.skin.box);
showGeneral = EditorGUILayout.Foldout(showGeneral, "General:");
if (!showGeneral) EditorGUILayout.EndVertical();
generateInThread = EditorGUILayout.Toggle("Generate in Thread", generateInThread);
osmServer = (RealWorldTerrainOSMOverpassServer)EditorGUILayout.EnumPopup("OSM Overpass Server", osmServer);
EditorGUILayout.EndVertical();
}
private void OnGUI()
{
bool dirty = false;
scrollPosition = GUILayout.BeginScrollView(scrollPosition);
OnGeneralGUI();
OnCacheFolderGUI();
OnResultNameGUI();
OnTerrainNameGUI();
OnThirdPartyGUI(ref dirty);
GUILayout.EndScrollView();
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Save"))
{
if (defaultCacheFolder) RealWorldTerrainPrefs.DeletePref("CacheFolder");
else RealWorldTerrainPrefs.SetPref("CacheFolder", customCacheFolder);
if (resultName == "") RealWorldTerrainPrefs.DeletePref("ResultName");
else RealWorldTerrainPrefs.SetPref("ResultName", resultName);
if (terrainName == "") RealWorldTerrainPrefs.DeletePref("TerrainName");
else RealWorldTerrainPrefs.SetPref("TerrainName", terrainName);
RealWorldTerrainPrefs.SetPref("AppendIndex", appendResultNameIndex);
RealWorldTerrainPrefs.SetPref("GenerateInThread", generateInThread);
RealWorldTerrainPrefs.SetPref("OSMServer", (int)osmServer);
RealWorldTerrainEditorUtils.ClearFoldersCache();
Close();
}
if (GUILayout.Button("Revert to default settings", GUILayout.ExpandWidth(false)))
{
int result = EditorUtility.DisplayDialogComplex("Revert to default settings", "Reset generation settings?", "Reset", "Ignore", "Cancel");
Debug.Log(result);
if (result < 2)
{
if (result == 0 && File.Exists(RealWorldTerrainPrefs.prefsFilename)) File.Delete(RealWorldTerrainPrefs.prefsFilename);
ClearSettings();
RealWorldTerrainEditorUtils.ClearFoldersCache();
}
}
EditorGUILayout.EndHorizontal();
if (dirty) Repaint();
}
private void OnProceduralToolkit(ref bool dirty)
{
if (!hasProceduralToolkit) return;
#if !PROCEDURAL_TOOLKIT
if (GUILayout.Button("Enable Procedural Toolkit"))
{
AddCompilerDirective("PROCEDURAL_TOOLKIT");
dirty = true;
}
#else
if (GUILayout.Button("Disable Procedural Toolkit"))
{
DeleteCompilerDirective("PROCEDURAL_TOOLKIT");
dirty = true;
}
#endif
hasThirdPartyAssets = true;
}
private void OnRAM2019(ref bool dirty)
{
if (!hasRAM2019) return;
#if !RAM2019
if (GUILayout.Button("Enable R.A.M 2019"))
{
AddCompilerDirective("RAM2019");
dirty = true;
}
#else
if (GUILayout.Button("Disable R.A.M 2019"))
{
DeleteCompilerDirective("RAM2019");
dirty = true;
}
#endif
hasThirdPartyAssets = true;
}
private void OnRTP(ref bool dirty)
{
if (!hasRTP) return;
#if !RTP
if (GUILayout.Button("Enable Relief Terrain Pack"))
{
AddCompilerDirective("RTP");
dirty = true;
}
#else
if (GUILayout.Button("Disable Relief Terrain Pack"))
{
DeleteCompilerDirective("RTP");
dirty = true;
}
#endif
hasThirdPartyAssets = true;
}
private void OnRoadArchitect(ref bool dirty)
{
if (!hasRoadArchitect) return;
#if !ROADARCHITECT
if (GUILayout.Button("Enable Road Architect"))
{
AddCompilerDirective("ROADARCHITECT");
dirty = true;
}
#else
if (GUILayout.Button("Disable Road Architect"))
{
DeleteCompilerDirective("ROADARCHITECT");
dirty = true;
}
#endif
hasThirdPartyAssets = true;
}
private void OnResultNameGUI()
{
EditorGUILayout.BeginVertical(GUI.skin.box);
showResultName = EditorGUILayout.Foldout(showResultName, "Result GameObject name: ");
if (showResultName)
{
resultName = EditorGUILayout.TextField("", resultName);
GUILayout.Label("Example:\nRWT_{cx}x{cy} = RWT_4x4");
DrawResultTokens();
appendResultNameIndex = GUILayout.Toggle(appendResultNameIndex, "Append index if GameObject already exists?");
}
EditorGUILayout.EndVertical();
}
private void OnTerrainNameGUI()
{
EditorGUILayout.BeginVertical(GUI.skin.box);
showTerrainNames = EditorGUILayout.Foldout(showTerrainNames, "Terrain GameObjects name: ");
if (showTerrainNames)
{
terrainName = EditorGUILayout.TextField("", terrainName);
GUILayout.Label("Example:\nTerrain_{x}x{y} = Terrain_1x3");
DrawTerrainTokens();
}
EditorGUILayout.EndVertical();
}
private void OnThirdPartyGUI(ref bool dirty)
{
EditorGUILayout.BeginVertical(GUI.skin.box);
showThirdPartyAssets = EditorGUILayout.Foldout(showThirdPartyAssets, "Third Party Assets:");
if (showThirdPartyAssets)
{
hasThirdPartyAssets = false;
OnBuildR2(ref dirty);
OnBuildR3(ref dirty);
OnEasyRoads(ref dirty);
//OnProceduralToolkit(ref dirty);
OnRAM2019(ref dirty);
OnRTP(ref dirty);
OnRoadArchitect(ref dirty);
OnVolumeGrass(ref dirty);
OnWorldStreamer(ref dirty);
if (!hasThirdPartyAssets) GUILayout.Label("Third Party Assets not found.");
}
EditorGUILayout.EndVertical();
}
private void OnVolumeGrass(ref bool dirty)
{
if (!hasVolumeGrass) return;
#if !VOLUMEGRASS
if (GUILayout.Button("Enable Volume Grass"))
{
AddCompilerDirective("VOLUMEGRASS");
dirty = true;
}
#else
if (GUILayout.Button("Disable Volume Grass"))
{
DeleteCompilerDirective("VOLUMEGRASS");
dirty = true;
}
#endif
hasThirdPartyAssets = true;
}
private void OnWorldStreamer(ref bool dirty)
{
if (!hasWorldStreamer) return;
#if !WORLDSTREAMER
if (GUILayout.Button("Enable WorldStreamer"))
{
AddCompilerDirective("WORLDSTREAMER");
dirty = true;
}
#else
if (GUILayout.Button("Disable WorldStreamer"))
{
DeleteCompilerDirective("WORLDSTREAMER");
dirty = true;
}
#endif
hasThirdPartyAssets = true;
}
[MenuItem("Window/Infinity Code/Real World Terrain/Settings")]
public static void OpenWindow()
{
wnd = GetWindow<RealWorldTerrainSettingsWindow>(false, "Settings");
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 1e2d352ec8995d9428a8fc49324b9420
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,335 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using InfinityCode.RealWorldTerrain.Net;
using UnityEditor;
using UnityEngine;
using Debug = UnityEngine.Debug;
namespace InfinityCode.RealWorldTerrain.Windows
{
public class RealWorldTerrainUpdaterWindow : EditorWindow
{
private const string packageID = "Real World Terrain";
private const string assetPrefix = "RealWorldTerrainWindow";
private const string lastVersionKey = assetPrefix + "LastVersion";
private const string lastVersionCheckKey = assetPrefix + "LastVersionCheck";
private const string channelKey = assetPrefix + "UpdateChannel";
private const string invoiceNumberKey = assetPrefix + "InvoiceNumber";
public static bool hasNewVersion = false;
private static RealWorldTerrainUpdateChannel channel = RealWorldTerrainUpdateChannel.stable;
private string invoiceNumber;
private Vector2 scrollPosition;
private List<RealWorldTerrainUpdateItem> updates;
private static string lastVersionID;
private void CheckNewVersions()
{
if (string.IsNullOrEmpty(invoiceNumber))
{
EditorUtility.DisplayDialog("Error", "Please enter the Invoice Number.", "OK");
return;
}
SavePrefs();
string updateKey = GetUpdateKey();
GetUpdateList(updateKey);
}
public static void CheckNewVersionAvailable()
{
if (EditorPrefs.HasKey(lastVersionKey))
{
lastVersionID = EditorPrefs.GetString(lastVersionKey);
if (CompareVersions())
{
hasNewVersion = true;
return;
}
}
const long ticksInHour = 36000000000;
if (EditorPrefs.HasKey(lastVersionCheckKey))
{
long lastVersionCheck = EditorPrefs.GetInt(lastVersionCheckKey) * ticksInHour;
if (DateTime.Now.Ticks - lastVersionCheck < 24 * ticksInHour)
{
return;
}
}
EditorPrefs.SetInt(lastVersionCheckKey, (int)(DateTime.Now.Ticks / ticksInHour));
if (EditorPrefs.HasKey(channelKey)) channel = (RealWorldTerrainUpdateChannel)EditorPrefs.GetInt(channelKey);
else channel = RealWorldTerrainUpdateChannel.stable;
if (channel == RealWorldTerrainUpdateChannel.stablePrevious) channel = RealWorldTerrainUpdateChannel.stable;
WebClient client = new WebClient();
client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
client.UploadDataCompleted += delegate (object sender, UploadDataCompletedEventArgs response)
{
if (response.Error != null)
{
Debug.Log("Real World Terrain Updater: " + response.Error.Message);
return;
}
string version = Encoding.UTF8.GetString(response.Result);
try
{
string[] vars = version.Split('.');
string[] vars2 = new string[4];
vars2[0] = vars[0];
vars2[1] = int.Parse(vars[1].Substring(0, 2)).ToString();
vars2[2] = int.Parse(vars[1].Substring(2, 2)).ToString();
vars2[3] = int.Parse(vars[1].Substring(4, 4)).ToString();
version = string.Join(".", vars2);
}
catch (Exception)
{
Debug.Log("Real World Terrain Updater: Bad response");
return;
}
lastVersionID = version;
hasNewVersion = CompareVersions();
EditorApplication.update += SetLastVersion;
};
client.UploadDataAsync(new Uri("https://infinity-code.com/products_update/getlastversion.php"), "POST", Encoding.UTF8.GetBytes("c=" + (int)channel + "&package=" + RealWorldTerrainDownloadManager.EscapeURL(packageID)));
}
private static bool CompareVersions()
{
double v1 = GetDoubleVersion(RealWorldTerrainWindow.version);
double v2 = GetDoubleVersion(lastVersionID);
return v1 < v2;
}
private static double GetDoubleVersion(string v)
{
string[] vs = v.Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
if (vs[1].Length < 2) vs[1] = "0" + vs[1];
if (vs[2].Length < 2) vs[2] = "0" + vs[2];
if (vs[3].Length < 4)
{
vs[3] = "000" + vs[3];
vs[3] = vs[3].Substring(vs[3].Length - 4, 4);
}
v = vs[0] + "." + vs[1] + vs[2] + vs[3];
double result;
if (!double.TryParse(v, out result)) result = 1;
return result;
}
private static void SetLastVersion()
{
EditorPrefs.SetString(lastVersionKey, lastVersionID);
EditorApplication.update -= SetLastVersion;
}
private string GetUpdateKey()
{
WebClient client = new WebClient();
client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
string updateKey = client.UploadString("https://infinity-code.com/products_update/getupdatekey.php",
"key=" + invoiceNumber + "&package=" + RealWorldTerrainDownloadManager.EscapeURL(packageID));
return updateKey;
}
private void GetUpdateList(string updateKey)
{
WebClient client = new WebClient();
client.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
try
{
string response = client.UploadString("https://infinity-code.com/products_update/checkupdates.php", "k=" + RealWorldTerrainDownloadManager.EscapeURL(updateKey) + "&v=" + RealWorldTerrainWindow.version + "&c=" + (int)channel);
XmlDocument doc = new XmlDocument();
doc.LoadXml(response);
updates = new List<RealWorldTerrainUpdateItem>();
foreach (XmlNode node in doc.DocumentElement.ChildNodes) updates.Add(new RealWorldTerrainUpdateItem(node));
}
catch (Exception exception)
{
Debug.LogError(exception.Message);
}
}
private void OnEnable()
{
invoiceNumber = EditorPrefs.HasKey(invoiceNumberKey) ? EditorPrefs.GetString(invoiceNumberKey) : "";
if (EditorPrefs.HasKey(channelKey)) channel = (RealWorldTerrainUpdateChannel)EditorPrefs.GetInt(channelKey);
else channel = RealWorldTerrainUpdateChannel.stable;
}
private void OnDestroy()
{
SavePrefs();
}
private void OnGUI()
{
EditorGUILayout.BeginHorizontal();
invoiceNumber = EditorGUILayout.TextField("Invoice Number:", invoiceNumber).Trim(' ');
GUIStyle helpStyle = new GUIStyle();
helpStyle.margin = new RectOffset(2, 2, 2, 2);
GUIContent helpContent = new GUIContent(RealWorldTerrainResources.helpIcon, "You can find out your Invoice Number in the email confirming the purchase, or page the user in Unity Asset Store.\nClick to go to the Unity Asset Store.");
if (GUILayout.Button(helpContent, helpStyle, GUILayout.ExpandWidth(false))) Process.Start("https://assetstore.unity.com/orders");
EditorGUILayout.EndHorizontal();
channel = (RealWorldTerrainUpdateChannel)EditorGUILayout.EnumPopup("Channel:", channel);
GUILayout.Label("Current version: " + RealWorldTerrainWindow.version);
if (GUILayout.Button("Check new versions")) CheckNewVersions();
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
if (updates != null)
{
foreach (RealWorldTerrainUpdateItem update in updates) update.Draw();
if (updates.Count == 0) GUILayout.Label("No updates");
}
EditorGUILayout.EndScrollView();
}
[MenuItem("Window/Infinity Code/Real World Terrain/Check Updates", false, 1999)]
public static void OpenWindow()
{
GetWindow<RealWorldTerrainUpdaterWindow>(false, "Real World Terrain Updater", true);
}
private void SavePrefs()
{
EditorPrefs.SetString(invoiceNumberKey, invoiceNumber);
EditorPrefs.SetInt(channelKey, (int)channel);
}
}
public class RealWorldTerrainUpdateItem
{
private string version;
private int type;
private string changelog;
private string download;
private string date;
private static GUIStyle _changelogStyle;
private static GUIStyle _titleStyle;
private static GUIStyle changelogStyle
{
get
{
if (_changelogStyle == null) _changelogStyle = new GUIStyle(EditorStyles.label) {wordWrap = true};
return _changelogStyle;
}
}
private static GUIStyle titleStyle
{
get
{
if (_titleStyle == null) _titleStyle = new GUIStyle(EditorStyles.boldLabel) {alignment = TextAnchor.MiddleCenter};
return _titleStyle;
}
}
public string typeStr
{
get { return Enum.GetName(typeof(RealWorldTerrainUpdateChannel), type); }
}
public RealWorldTerrainUpdateItem(XmlNode node)
{
version = node["Version"].InnerXml;
type = int.Parse(node["Type"].InnerXml);
changelog = Unescape(node["ChangeLog"].InnerXml);
download = node["Download"].InnerXml;
date = node["Date"].InnerXml;
string[] vars = version.Split('.');
string[] vars2 = new string[4];
vars2[0] = vars[0];
vars2[1] = int.Parse(vars[1].Substring(0, 2)).ToString();
vars2[2] = int.Parse(vars[1].Substring(2, 2)).ToString();
vars2[3] = int.Parse(vars[1].Substring(4, 4)).ToString();
version = string.Join(".", vars2);
}
public void Draw()
{
GUILayout.BeginVertical(GUI.skin.box);
GUILayout.Label("Version: " + version + " (" + typeStr + "). " + date, titleStyle);
GUILayout.Label(changelog, changelogStyle);
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Download"))
{
Process.Start("https://infinity-code.com/products_update/download.php?k=" + download);
}
if (GUILayout.Button("Copy download link", GUILayout.ExpandWidth(false)))
{
EditorGUIUtility.systemCopyBuffer = "https://infinity-code.com/products_update/download.php?k=" + download;
EditorUtility.DisplayDialog("Success",
"Download link is copied to the clipboard.\nOpen a browser and paste the link into the address bar.",
"OK");
}
EditorGUILayout.EndHorizontal();
GUILayout.EndVertical();
}
private static string Unescape(string str)
{
return Regex.Replace(str, @"&(\w+);", delegate (Match match)
{
string v = match.Groups[1].Value;
if (v == "amp") return "&";
if (v == "lt") return "<";
if (v == "gt") return ">";
if (v == "quot") return "\"";
if (v == "apos") return "'";
return match.Value;
});
}
}
public enum RealWorldTerrainUpdateChannel
{
stable = 10,
stablePrevious = 15,
releaseCandidate = 20,
beta = 30,
alpha = 40,
working = 50
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: 110ed232e8ee3294cadbf75cd6566785
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,189 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using System;
using System.IO;
using UnityEditor;
using UnityEngine;
namespace InfinityCode.RealWorldTerrain.Windows
{
public class RealWorldTerrainWaterMaskConverter : EditorWindow
{
private string inputFile;
private int width;
private int height;
private Depth depth = Depth.eight;
private RealWorldTerrainByteOrder byteOrder = RealWorldTerrainByteOrder.Windows;
private int threshold = 128;
private void Convert()
{
if (!Validate()) return;
string outputFile = EditorUtility.SaveFilePanel("Save Water Mask", "", "WaterMask.bytes", "bytes");
if (string.IsNullOrEmpty(outputFile)) return;
FileStream stream = File.OpenRead(inputFile);
BinaryReader reader = new BinaryReader(stream);
int countBytes = depth == Depth.eight ? 1 : 2;
int bufferSize = 8192 * countBytes;
byte[] buffer = new byte[bufferSize];
byte[] output = new byte[Mathf.CeilToInt(width * height / 8f) + 8];
MemoryStream ms = new MemoryStream(output);
BinaryWriter writer = new BinaryWriter(ms);
writer.Write(width);
writer.Write(height);
writer.Close();
long outputIndex = 64;
int bufferIndex = 0;
int bufferCount = 0;
int value = 0;
int delimiter = depth == Depth.eight ? 1 : 256;
while ((bufferCount = reader.Read(buffer, bufferIndex, bufferSize)) > 0)
{
for (int i = 0; i < bufferCount; i++)
{
if (depth == Depth.sixteen)
{
if (i % 2 == 0)
{
value = buffer[i];
continue;
}
if (byteOrder == RealWorldTerrainByteOrder.Windows)
{
value += buffer[i] * 256;
}
else
{
value = buffer[i] + value * 256;
}
}
else
{
value = buffer[i];
}
value /= delimiter;
int bitIndex = (int)(outputIndex % 8);
int bit = value > threshold ? 1 : 0;
byte o = (byte)(output[outputIndex / 8] | (bit << bitIndex));
output[outputIndex / 8] = o;
outputIndex++;
}
}
reader.Close();
stream.Close();
File.WriteAllBytes(outputFile, output);
AssetDatabase.Refresh();
EditorUtility.DisplayDialog("Success", "Water mask successfully saved.", "OK");
}
private void OnGUI()
{
ProcessDragAndDrop();
EditorGUILayout.HelpBox("Tool to convert RAW files to bitmask for water generation.", MessageType.Info);
EditorGUILayout.BeginHorizontal();
inputFile = EditorGUILayout.TextField("Input File", inputFile);
if (GUILayout.Button("...", GUILayout.ExpandWidth(false)))
{
inputFile = EditorUtility.OpenFilePanel("Select Input File", inputFile, "raw");
}
EditorGUILayout.EndHorizontal();
width = EditorGUILayout.IntField("Width", width);
height = EditorGUILayout.IntField("Height", height);
depth = (Depth)EditorGUILayout.EnumPopup("Depth", depth);
if (depth == Depth.sixteen)
{
byteOrder = (RealWorldTerrainByteOrder)EditorGUILayout.EnumPopup("Byte Order", byteOrder);
}
threshold = EditorGUILayout.IntField("Threshold", threshold);
if (GUILayout.Button("Convert"))
{
Convert();
}
}
private void ProcessDragAndDrop()
{
Event e = Event.current;
Rect rect = new Rect(0, 0, position.width, position.height);
switch (e.type)
{
case EventType.DragUpdated:
case EventType.DragPerform:
if (!rect.Contains(e.mousePosition)) return;
if (DragAndDrop.paths.Length != 1) return;
if (!string.IsNullOrEmpty(inputFile)) return;
DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
if (e.type != EventType.DragPerform) return;
DragAndDrop.AcceptDrag();
inputFile = DragAndDrop.paths[0];
break;
}
}
public static void OpenWindow()
{
GetWindow<RealWorldTerrainWaterMaskConverter>(true, "Raw to Water Mask Converter", true);
}
private bool Validate()
{
if (string.IsNullOrEmpty(inputFile))
{
EditorUtility.DisplayDialog("Error", "Input file is empty.", "OK");
return false;
}
if (!File.Exists(inputFile))
{
EditorUtility.DisplayDialog("Error", "Input file does not exist.", "OK");
return false;
}
if (width <= 0 || height <= 0)
{
EditorUtility.DisplayDialog("Error", "Width and height must be greater than zero.", "OK");
return false;
}
FileInfo info = new FileInfo(inputFile);
int countBytes = depth == Depth.eight ? 1 : 2;
if (info.Length != width * height * countBytes)
{
EditorUtility.DisplayDialog("Error", "File size does not match the specified width, height and depth.", "OK");
return false;
}
return true;
}
public enum Depth
{
eight,
sixteen,
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 52357ae39ca24d140b8557d6267a7b83
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,402 @@
/* 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
{
/// <summary>
/// Current version number
/// </summary>
public const string version = "4.9.4.1";
/// <summary>
/// The action that occurs when the user aborts the generation.
/// </summary>
public static Action OnCaptureCanceled;
/// <summary>
/// The action that occurs when the generation is completed.
/// </summary>
public static Action OnCaptureCompleted;
/// <summary>
/// The action that occurs when the generation is started.
/// </summary>
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 && !GAIA_2023
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.elevationRange == RealWorldTerrainElevationRange.fixedValue && prefs.fixedMaxElevation - prefs.fixedMinElevation < 0)
{
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;
if (thread != null)
{
thread.Abort();
thread = null;
}
RealWorldTerrainElevationGenerator.Dispose();
RealWorldTerrainTextureGenerator.Dispose();
RealWorldTerrainTerrainLayersGenerator.Dispose();
RealWorldTerrainDownloadManager.Dispose();
RealWorldTerrainRoadGenerator.Dispose();
RealWorldTerrainRiverGenerator.Dispose();
RealWorldTerrainGrassGenerator.Dispose();
RealWorldTerrainTreesGenerator.Dispose();
RealWorldTerrainBuildingGenerator.Dispose();
RealWorldTerrainWaterMask.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<RealWorldTerrainWindow>(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 ||
prefs.resultType == RealWorldTerrainResultType.terrain)
{
prefs.textureCount = prefs.terrainCount;
}
RealWorldTerrainElevationGenerator.elevations = new List<RealWorldTerrainElevationGenerator>();
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();
}
}
}
}

View File

@@ -0,0 +1,10 @@
fileFormatVersion: 2
guid: c13add9f7f666fc428a5c03c3b6fde57
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b023828a76464b74785d0fdc0f4dd374
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,219 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Xml;
using InfinityCode.RealWorldTerrain.Windows;
using UnityEditor;
using UnityEngine;
namespace InfinityCode.RealWorldTerrain
{
public static partial class RealWorldTerrainWindowUI
{
private static bool showCoordinates = true;
private static int coordinateMode = 0;
private static string utmTLLatZone;
private static int utmTLLngZone;
private static int utmTLEasting;
private static int utmTLNorthing;
private static string utmBRLatZone;
private static int utmBRLngZone;
private static int utmBREasting;
private static int utmBRNorthing;
private static void AnchorUI()
{
prefs.useAnchor = Toggle(prefs.useAnchor, "Use Anchor", true, "The coordinates of the anchor point at which there will be a zero position in the scene.");
if (!prefs.useAnchor) return;
prefs.anchorLatitude = DoubleField("Latitude", prefs.anchorLatitude, "Latitude of the Anchor. \nValues: -90 to 90.", "http://en.wikipedia.org/wiki/Latitude");
prefs.anchorLongitude = DoubleField("Longitude", prefs.anchorLongitude, "Longitude of the Anchor. \nValues: -180 to 180.", "http://en.wikipedia.org/wiki/Longitude");
}
private static void ApplyUTMValues()
{
RealWorldTerrainUTM.ToLngLat(utmTLLatZone, utmTLLngZone, utmTLEasting, utmTLNorthing, out prefs.leftLongitude, out prefs.topLatitude);
RealWorldTerrainUTM.ToLngLat(utmBRLatZone, utmBRLngZone, utmBREasting, utmBRNorthing, out prefs.rightLongitude, out prefs.bottomLatitude);
coordinateMode = 0;
}
private static void AreaUI()
{
EditorGUILayout.BeginVertical(GUI.skin.box);
showCoordinates = EditorGUILayout.Foldout(showCoordinates, "Area");
if (!showCoordinates)
{
EditorGUILayout.EndVertical();
return;
}
prefs.title = EditorGUILayout.TextField("Title", prefs.title);
GUILayout.Space(10);
CoordinatesUI();
AnchorUI();
AreaButtonsUI();
GUILayout.Space(10);
EditorGUILayout.EndVertical();
}
private static void AreaButtonsUI()
{
GUI.SetNextControlName("InsertCoordsButton");
if (GUILayout.Button("Insert the coordinates from the clipboard")) InsertCoords();
if (GUILayout.Button("Run the helper")) RunHelper();
if (prefs.resultType == RealWorldTerrainResultType.terrain && GUILayout.Button("Get the best settings for the specified coordinates")) RealWorldTerrainSettingsGeneratorWindow.OpenWindow();
if (GUILayout.Button("Show Open Street Map"))
{
Vector2 center;
int zoom;
RealWorldTerrainMath.GetCenterPointAndZoom(new[] {prefs.leftLongitude, prefs.topLatitude, prefs.rightLongitude, prefs.bottomLatitude}, out center, out zoom);
Process.Start(string.Format(RealWorldTerrainCultureInfo.numberFormat, "http://www.openstreetmap.org/#map={0}/{1}/{2}", zoom, center.y, center.x));
}
}
private static void CoordinatesUI()
{
EditorGUI.BeginChangeCheck();
coordinateMode = GUILayout.Toolbar(coordinateMode, new[] {"Decimal", "UTM"});
if (EditorGUI.EndChangeCheck() && coordinateMode == 1) InitUTMValues();
if (coordinateMode == 0) DecimalCoordinatesUI();
else UTMCoordinatesUI();
}
private static void DecimalCoordinatesUI()
{
GUILayout.Label("Top-Left");
EditorGUI.indentLevel++;
prefs.topLatitude = DoubleField("Latitude", prefs.topLatitude, "Latitude of the Top-Left corner of the area. \nValues: -90 to 90.", "http://en.wikipedia.org/wiki/Latitude");
prefs.leftLongitude = DoubleField("Longitude", prefs.leftLongitude, "Longitude of the Top-Left corner of the area. \nValues: -180 to 180.", "http://en.wikipedia.org/wiki/Longitude");
EditorGUI.indentLevel--;
GUILayout.Space(10);
GUILayout.Label("Bottom-Right");
EditorGUI.indentLevel++;
prefs.bottomLatitude = DoubleField("Latitude", prefs.bottomLatitude, "Latitude of the Bottom-Right corner of the area. \nValues: -90 to 90.", "http://en.wikipedia.org/wiki/Latitude");
prefs.rightLongitude = DoubleField("Longitude", prefs.rightLongitude, "Longitude of the Bottom-Right corner of the area. \nValues: -180 to 180.", "http://en.wikipedia.org/wiki/Longitude");
EditorGUI.indentLevel--;
GUILayout.Space(10);
if (prefs.topLatitude > 60 || prefs.bottomLatitude < -60)
{
if (prefs.elevationProvider == RealWorldTerrainElevationProvider.SRTM || prefs.elevationProvider == RealWorldTerrainElevationProvider.SRTM30)
{
EditorGUILayout.HelpBox("SRTM and SRTM30 only contain data in the latitude range 60 to -60. Please select another Elevation Provider.", MessageType.Error);
}
else if (/*prefs.elevationProvider == RealWorldTerrainElevationProvider.ArcGIS || */prefs.elevationProvider == RealWorldTerrainElevationProvider.BingMaps)
{
EditorGUILayout.HelpBox("For latitudes north of 60 degrees or south of -60 degrees, ArcGIS and Bing Maps contain data with an accuracy of 900 meters per value, which is very small for a good result. Try using Mapbox first.", MessageType.Warning);
}
}
}
private static void InitUTMValues()
{
double e, n;
RealWorldTerrainUTM.ToUTM(prefs.leftLongitude, prefs.topLatitude, out utmTLLatZone, out utmTLLngZone, out e, out n);
utmTLEasting = (int) Math.Round(e);
utmTLNorthing = (int) Math.Round(n);
RealWorldTerrainUTM.ToUTM(prefs.rightLongitude, prefs.bottomLatitude, out utmBRLatZone, out utmBRLngZone, out e, out n);
utmBREasting = (int) Math.Round(e);
utmBRNorthing = (int) Math.Round(n);
}
public static void InsertCoords()
{
GUI.FocusControl("InsertCoordsButton");
string nodeStr = EditorGUIUtility.systemCopyBuffer;
if (string.IsNullOrEmpty(nodeStr)) return;
XmlDocument doc = new XmlDocument();
try
{
doc.LoadXml(nodeStr);
XmlNode node = doc.FirstChild;
if (node.Name != "Coords" || node.Attributes == null) return;
prefs.leftLongitude = RealWorldTerrainXMLExt.GetAttribute<float>(node, "tlx");
prefs.topLatitude = RealWorldTerrainXMLExt.GetAttribute<float>(node, "tly");
prefs.rightLongitude = RealWorldTerrainXMLExt.GetAttribute<float>(node, "brx");
prefs.bottomLatitude = RealWorldTerrainXMLExt.GetAttribute<float>(node, "bry");
if (prefs.useAnchor)
{
if (EditorUtility.DisplayDialog("Remove Anchor", "Remove anchor point from previous settings?", "Remove", "Keep"))
{
prefs.useAnchor = false;
double mx1, my1, mx2, my2;
RealWorldTerrainGeo.LatLongToMercat(prefs.leftLongitude, prefs.topLatitude, out mx1, out my1);
RealWorldTerrainGeo.LatLongToMercat(prefs.rightLongitude, prefs.bottomLatitude, out mx2, out my2);
mx1 = (mx2 + mx1) / 2;
my1 = (my2 + my1) / 2;
RealWorldTerrainGeo.MercatToLatLong(mx1, my1, out prefs.anchorLongitude, out prefs.anchorLatitude);
}
}
XmlNodeList POInodes = node.SelectNodes("//POI");
prefs.POI = new List<RealWorldTerrainPOI>();
foreach (XmlNode n in POInodes) prefs.POI.Add(new RealWorldTerrainPOI(n));
prefs.Save();
}
catch { }
}
public static void RunHelper()
{
string helperPath = "file://" + Directory.GetFiles(Application.dataPath, "RWT_Helper.html", SearchOption.AllDirectories)[0].Replace('\\', '/');
if (Application.platform == RuntimePlatform.OSXEditor) helperPath = helperPath.Replace(" ", "%20");
prefs.Save();
Application.OpenURL(helperPath);
}
private static void UTMCoordinatesUI()
{
GUILayout.Label("Top-Left");
EditorGUI.indentLevel++;
EditorGUILayout.BeginHorizontal();
utmTLLngZone = EditorGUILayout.IntField(utmTLLngZone);
utmTLLatZone = EditorGUILayout.TextField(utmTLLatZone);
utmTLEasting = EditorGUILayout.IntField(utmTLEasting);
utmTLNorthing = EditorGUILayout.IntField(utmTLNorthing);
EditorGUILayout.EndHorizontal();
EditorGUI.indentLevel--;
GUILayout.Space(10);
GUILayout.Label("Bottom-Right");
EditorGUI.indentLevel++;
EditorGUILayout.BeginHorizontal();
utmBRLngZone = EditorGUILayout.IntField(utmBRLngZone);
utmBRLatZone = EditorGUILayout.TextField(utmBRLatZone);
utmBREasting = EditorGUILayout.IntField(utmBREasting);
utmBRNorthing = EditorGUILayout.IntField(utmBRNorthing);
EditorGUILayout.EndHorizontal();
EditorGUI.indentLevel--;
if (GUILayout.Button("Apply")) ApplyUTMValues();
GUILayout.Space(10);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 20ad28ba9a7439b45875728058473670
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,308 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
#if BUILDR2
using BuildR2;
#endif
#if BUILDR3
using BuildRCities;
#endif
#if PROCEDURAL_TOOLKIT
using ProceduralToolkit.Buildings;
#endif
namespace InfinityCode.RealWorldTerrain
{
public static partial class RealWorldTerrainWindowUI
{
private static bool showBuildRCustomPresets;
private static List<string> availableBuildingEngine;
private static List<int> availableBuildingsIDs;
private static void BuildR2Fields()
{
#if BUILDR2
prefs.buildRCollider = (RealWorldTerrainBuildR2Collider)EditorGUILayout.EnumPopup("Collider", prefs.buildRCollider);
prefs.buildRRenderMode = (RealWorldTerrainBuildR2RenderMode)EditorGUILayout.EnumPopup("Render Mode", prefs.buildRRenderMode);
if (prefs.buildR2Materials == null) prefs.buildR2Materials = new List<RealWorldTerrainBuildR2Material>{new RealWorldTerrainBuildR2Material()};
else if (prefs.buildR2Materials.Count == 0)
{
prefs.buildR2Materials.Add(new RealWorldTerrainBuildR2Material());
}
EditorGUILayout.LabelField("Surfaces & Facades");
int removeIndex = -1;
for (int i = 0; i < prefs.buildR2Materials.Count; i++)
{
RealWorldTerrainBuildR2Material material = prefs.buildR2Materials[i];
EditorGUILayout.BeginHorizontal(i % 2 == 0 ? evenStyle : oddStyle);
EditorGUILayout.LabelField(i + 1 + ": ", GUILayout.Width(30));
EditorGUILayout.BeginVertical();
material.roofSurface = EditorGUILayout.ObjectField(new GUIContent("Roof Surface:"), material.roofSurface, typeof(Surface), false) as Surface;
material.roofType = (Roof.Types)EditorGUILayout.EnumPopup("Roof Type:", material.roofType);
if (material.facades == null) material.facades = new List<Facade>();
EditorGUILayout.LabelField("Facades:");
int removeFacadeIndex = -1;
for (int j = 0; j < material.facades.Count; j++)
{
EditorGUI.BeginChangeCheck();
material.facades[j] = EditorGUILayout.ObjectField(material.facades[j], typeof(Facade), false) as Facade;
if (EditorGUI.EndChangeCheck())
{
if (material.facades[j] == null) removeFacadeIndex = j;
}
}
if (removeFacadeIndex != -1) material.facades.RemoveAt(removeFacadeIndex);
Facade newFacade = EditorGUILayout.ObjectField(null, typeof(Facade), false) as Facade;
if (newFacade != null) material.facades.Add(newFacade);
EditorGUILayout.EndVertical();
if (GUILayout.Button("X", GUILayout.ExpandWidth(false))) removeIndex = i;
EditorGUILayout.EndHorizontal();
}
if (removeIndex != -1) prefs.buildR2Materials.RemoveAt(removeIndex);
if (GUILayout.Button("Add new item"))
{
prefs.buildR2Materials.Add(new RealWorldTerrainBuildR2Material());
}
#endif
}
private static void BuildR3Fields()
{
#if BUILDR3
if (prefs.buildR3Materials == null) prefs.buildR3Materials = new List<RealWorldTerrainBuildR3Material> {new RealWorldTerrainBuildR3Material()};
else if (prefs.buildR3Materials.Count == 0)
{
prefs.buildR3Materials.Add(new RealWorldTerrainBuildR3Material());
}
prefs.buildR3Collider = EditorGUILayout.Toggle("Generate Colliders", prefs.buildR3Collider);
EditorGUILayout.LabelField("Surfaces & Facades");
int removeIndex = -1;
for (int i = 0; i < prefs.buildR3Materials.Count; i++)
{
RealWorldTerrainBuildR3Material material = prefs.buildR3Materials[i];
EditorGUILayout.BeginHorizontal(i % 2 == 0 ? evenStyle : oddStyle);
EditorGUILayout.LabelField(i + 1 + ": ", GUILayout.Width(30));
EditorGUILayout.BeginVertical();
EditorGUILayout.LabelField("Facades:");
material.wallFacade = EditorGUILayout.ObjectField("Wall:", material.wallFacade, typeof(FacadeAsset), false) as FacadeAsset;
material.roofTexture = EditorGUILayout.ObjectField("Roof:", material.roofTexture, typeof(DynamicTextureAsset), false) as DynamicTextureAsset;
material.roofType = (Roof.Types) EditorGUILayout.EnumPopup("Roof Type:", material.roofType);
EditorGUILayout.EndVertical();
if (GUILayout.Button("X", GUILayout.ExpandWidth(false))) removeIndex = i;
EditorGUILayout.EndHorizontal();
}
if (removeIndex != -1) prefs.buildR3Materials.RemoveAt(removeIndex);
if (GUILayout.Button("Add new item"))
{
prefs.buildR3Materials.Add(new RealWorldTerrainBuildR3Material());
}
#endif
}
private static void BuildingsUI()
{
EditorGUILayout.BeginVertical(GUI.skin.box);
prefs.generateBuildings = EditorGUILayout.Toggle("Generate buildings", prefs.generateBuildings);
if (!prefs.generateBuildings)
{
EditorGUILayout.EndVertical();
return;
}
prefs.buildingGenerator = EditorGUILayout.IntPopup("Building generator", prefs.buildingGenerator, availableBuildingEngine.ToArray(), availableBuildingsIDs.ToArray());
prefs.buildingSingleRequest = Toggle("Download using a single request", prefs.buildingSingleRequest, false, "If enabled, one request will be sent for the entire area.\nIf disabled, the request will be split into small parts, which will make downloading data for megacities more stable.");
if (prefs.buildingGenerator == 2) BuildR2Fields();
else if (prefs.buildingGenerator == 5) BuildR3Fields();
else if (prefs.buildingGenerator == 3) InstantiatePrefabsFields();
else if (prefs.buildingGenerator == 4) ProceduralToolkitBuildingsFields();
RealWorldTerrainRangeI range = prefs.buildingFloorLimits;
float minLevelLimit = range.min;
float maxLevelLimit = range.max;
MinMaxSlider(string.Format("Floors if unknown ({0}-{1})", range.min, range.max),
ref minLevelLimit, ref maxLevelLimit, 1, 50,
"If no building height or number of floors is specified in the OSM data, a random value for floors in this range will be used.");
range.Set(minLevelLimit, maxLevelLimit);
if (prefs.buildingGenerator == 0) BuiltInBuildingEngineFields();
EditorGUILayout.EndVertical();
}
private static void BuiltInBuildingEngineFields()
{
prefs.buildingFloorHeight = EditorGUILayout.FloatField("Floor Height", prefs.buildingFloorHeight);
prefs.buildingBottomMode = (RealWorldTerrainBuildingBottomMode)EditorGUILayout.EnumPopup("Bottom Mode", prefs.buildingBottomMode);
prefs.buildingBasementDepth = FloatField("Basement Depth", prefs.buildingBasementDepth, "Building depth below ground level in meters (Zero or positive number).");
prefs.buildingUseColorTags = Toggle("Use Color Tags", prefs.buildingUseColorTags, false, "Whether to use color tag from OSM data? If so, a new material will be created for each building with a color.");
prefs.dynamicBuildings = Toggle("Dynamic Buildings", prefs.dynamicBuildings, false, "Dynamic buildings are generated at runtime and are not saved as meshes, thus bypassing the meshes import phase.");
prefs.buildingSaveInResult = Toggle("Save In Result", prefs.buildingSaveInResult, false, "Should meshes and materials be saved in the project? If disabled, you may lose non-dynamic meshes and materials when resetting the scene state (saving / loading, compiling scripts, etc.).");
GUILayout.Label("Building Materials");
if (prefs.buildingMaterials == null) prefs.buildingMaterials = new List<RealWorldTerrainBuildingMaterial>();
for (int i = 0; i < prefs.buildingMaterials.Count; i++)
{
EditorGUILayout.BeginHorizontal();
GUILayout.Label((i + 1).ToString(), GUILayout.ExpandWidth(false));
EditorGUILayout.BeginVertical();
RealWorldTerrainBuildingMaterial material = prefs.buildingMaterials[i];
material.wall = EditorGUILayout.ObjectField("Wall material", material.wall, typeof(Material), false) as Material;
material.roof = EditorGUILayout.ObjectField("Roof material", material.roof, typeof(Material), false) as Material;
material.tileSize = EditorGUILayout.Vector2Field("Tile Size (meters)", material.tileSize);
EditorGUILayout.EndVertical();
if (GUILayout.Button("X", GUILayout.ExpandWidth(false)))
{
prefs.buildingMaterials[i] = null;
}
EditorGUILayout.EndHorizontal();
}
prefs.buildingMaterials.RemoveAll(m => m == null);
if (GUILayout.Button("Add material")) prefs.buildingMaterials.Add(new RealWorldTerrainBuildingMaterial());
}
private static void InitBuildingEngines()
{
availableBuildingEngine = new List<string> { "Built-in", "Instantiate Prefabs" };
availableBuildingsIDs = new List<int> { 0, 3 };
#if BUILDR2
availableBuildingEngine.Add("BuildR2");
availableBuildingsIDs.Add(2);
#endif
#if BUILDR3
availableBuildingEngine.Add("BuildR3");
availableBuildingsIDs.Add(5);
#endif
#if PROCEDURAL_TOOLKIT
availableBuildingEngine.Add("Procedural Toolkit");
availableBuildingsIDs.Add(4);
#endif
}
private static void InstantiatePrefabsFields()
{
EditorGUILayout.HelpBox("If you use highly detailed buildings, when generating areas that contain a lot of buildings (for example, cities), Unity Editor can crashes.", MessageType.Info);
EditorGUILayout.HelpBox("Prefab must contain a BoxCollider so that RWT can determine the boundaries of the building.", MessageType.Info);
if (prefs.buildingPrefabs == null) prefs.buildingPrefabs = new List<RealWorldTerrainBuildingPrefab>();
int removeIndex = -1;
for (int i = 0; i < prefs.buildingPrefabs.Count; i++)
{
RealWorldTerrainBuildingPrefab b = prefs.buildingPrefabs[i];
EditorGUILayout.BeginHorizontal(i % 2 == 0 ? evenStyle : oddStyle);
EditorGUILayout.LabelField(i + 1 + ": ", GUILayout.Width(30));
EditorGUILayout.BeginVertical();
b.prefab = EditorGUILayout.ObjectField("Prefab", b.prefab, typeof(GameObject), false) as GameObject;
b.sizeMode = (RealWorldTerrainBuildingPrefab.SizeMode) EditorGUILayout.EnumPopup("Size Mode", b.sizeMode);
b.heightMode = (RealWorldTerrainBuildingPrefab.HeightMode) EditorGUILayout.EnumPopup("Height Mode", b.heightMode);
if (b.heightMode == RealWorldTerrainBuildingPrefab.HeightMode.fixedHeight)
{
b.fixedHeight = EditorGUILayout.FloatField("Height", b.fixedHeight);
}
b.placementMode = (RealWorldTerrainBuildingPrefab.PlacementMode)EditorGUILayout.EnumPopup("Placement Mode", b.placementMode);
if (b.tags == null) b.tags = new List<RealWorldTerrainBuildingPrefab.OSMTag>();
EditorGUILayout.LabelField("Tags (if no tags, prefab can be used for all buildings)");
int tagRemoveIndex = -1;
for (int j = 0; j < b.tags.Count; j++)
{
EditorGUILayout.BeginHorizontal(j % 2 == 0 ? evenStyle : oddStyle);
EditorGUILayout.LabelField(j + 1 + ": ", GUILayout.Width(30));
EditorGUILayout.BeginVertical();
RealWorldTerrainBuildingPrefab.OSMTag t = b.tags[j];
t.key = EditorGUILayout.TextField("Key", t.key);
t.value = EditorGUILayout.TextField("Value", t.value);
EditorGUILayout.EndVertical();
if (GUILayout.Button("X", GUILayout.ExpandWidth(false))) tagRemoveIndex = j;
EditorGUILayout.EndHorizontal();
}
if (tagRemoveIndex != -1) b.tags.RemoveAt(tagRemoveIndex);
if (GUILayout.Button("Add tag"))
{
b.tags.Add(new RealWorldTerrainBuildingPrefab.OSMTag());
}
EditorGUILayout.EndVertical();
if (GUILayout.Button("X", GUILayout.ExpandWidth(false))) removeIndex = i;
EditorGUILayout.EndHorizontal();
}
if (removeIndex != -1) prefs.buildingPrefabs.RemoveAt(removeIndex);
if (GUILayout.Button("Add new item"))
{
RealWorldTerrainBuildingPrefab newPrefab = new RealWorldTerrainBuildingPrefab();
newPrefab.tags = new List<RealWorldTerrainBuildingPrefab.OSMTag>();
prefs.buildingPrefabs.Add(newPrefab);
}
}
private static void ProceduralToolkitBuildingsFields()
{
#if PROCEDURAL_TOOLKIT
prefs.ptFacadePlanningStrategy = EditorGUILayout.ObjectField("Facade Planning Strategy", prefs.ptFacadePlanningStrategy, typeof(FacadePlanningStrategy), false) as FacadePlanningStrategy;
prefs.ptFacadeConstructionStrategy = EditorGUILayout.ObjectField("Facade Construction Strategy", prefs.ptFacadeConstructionStrategy, typeof(FacadeConstructionStrategy), false) as FacadeConstructionStrategy;
prefs.ptRoofPlanningStrategy = EditorGUILayout.ObjectField("Roof Planning Strategy", prefs.ptRoofPlanningStrategy, typeof(RoofPlanningStrategy), false) as RoofPlanningStrategy;
prefs.ptRoofConstructionStrategy = EditorGUILayout.ObjectField("Roof Construction Strategy", prefs.ptRoofConstructionStrategy, typeof(RoofConstructionStrategy), false) as RoofConstructionStrategy;
#endif
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5c0c7518427817044a4d7e89f5306dfc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,137 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using System.Diagnostics;
using UnityEditor;
using UnityEngine;
namespace InfinityCode.RealWorldTerrain
{
public static partial class RealWorldTerrainWindowUI
{
private static string bingAPI;
private static string earthDataLogin;
private static string earthDataPass;
private static bool showElevationProvider = true;
private static void BingMapsElevationExtraFields()
{
if (bingAPI == null) bingAPI = RealWorldTerrainPrefs.LoadPref("BingAPI", "");
EditorGUILayout.HelpBox("Public Windows App or Public Windows Phone App have the 50.000 transaction within 24 hours. With the other chooses there's only 125.000 transactions within a year and the key will expire if exceeding it.", MessageType.Info);
GUILayout.BeginHorizontal();
EditorGUI.BeginChangeCheck();
bingAPI = EditorGUILayout.TextField("Bing Maps API key", bingAPI);
if (EditorGUI.EndChangeCheck())
{
if (bingAPI == "") RealWorldTerrainPrefs.DeletePref("BingAPI");
else RealWorldTerrainPrefs.SetPref("BingAPI", bingAPI);
}
if (string.IsNullOrEmpty(bingAPI))
{
GUILayout.Box(new GUIContent(RealWorldTerrainResources.warningIcon, "Required"), RealWorldTerrainResources.helpStyle, GUILayout.ExpandWidth(false));
}
if (GUILayout.Button("Create Key", GUILayout.ExpandWidth(false))) Process.Start("http://msdn.microsoft.com/en-us/library/ff428642.aspx");
GUILayout.EndHorizontal();
}
private static void ElevationProviderUI()
{
EditorGUILayout.BeginVertical(GUI.skin.box);
showElevationProvider = EditorGUILayout.Foldout(showElevationProvider, "Elevation Provider");
if (!showElevationProvider)
{
EditorGUILayout.EndVertical();
return;
}
prefs.elevationProvider = (RealWorldTerrainElevationProvider) EditorGUILayout.EnumPopup(prefs.elevationProvider);
if (prefs.elevationProvider == RealWorldTerrainElevationProvider.SRTM)
{
EditorGUILayout.HelpBox("The latitude range is 60°S - 60°N.\nThe resolution of the source data is 3 arc seconds(about 90 meters).", MessageType.Info);
}
else if (prefs.elevationProvider == RealWorldTerrainElevationProvider.SRTM30)
{
EditorGUILayout.HelpBox("The latitude range is 60°S - 60°N.\nThe resolution of the source data is 1 arc seconds(about 30 meters).", MessageType.Info);
}
else if (prefs.elevationProvider == RealWorldTerrainElevationProvider.BingMaps /*|| prefs.elevationProvider == RealWorldTerrainElevationProvider.ArcGIS*/)
{
EditorGUILayout.HelpBox("Global coverage.\nThe resolution of the source data:\nUSA - 10 meters, Global 56°S - 60°N - 90 meters, other (including poles) - 900 meters.", MessageType.Info);
}
else if (prefs.elevationProvider == RealWorldTerrainElevationProvider.Mapbox)
{
EditorGUILayout.HelpBox("Global coverage.\nThe resolution of the source data up to 5 meters.", MessageType.Info);
}
ElevationProviderExtraFields();
EditorGUILayout.EndVertical();
}
private static void ElevationProviderExtraFields()
{
if (prefs.elevationProvider == RealWorldTerrainElevationProvider.SRTM || prefs.elevationProvider == RealWorldTerrainElevationProvider.SRTM30)
{
prefs.ignoreSRTMErrors = EditorGUILayout.Toggle("Ignore SRTM errors", prefs.ignoreSRTMErrors);
}
if (prefs.elevationProvider == RealWorldTerrainElevationProvider.BingMaps) BingMapsElevationExtraFields();
else if (prefs.elevationProvider == RealWorldTerrainElevationProvider.Mapbox) MapboxElevationExtraFields();
else if (prefs.elevationProvider == RealWorldTerrainElevationProvider.SRTM30) SRTM30ExtraFields();
}
private static void MapboxElevationExtraFields()
{
MapboxAccessToken();
GUILayout.Space(10);
}
private static void SRTM30ExtraFields()
{
if (earthDataLogin == null || earthDataPass == null)
{
earthDataLogin = RealWorldTerrainPrefs.LoadPref("EarthDataLogin", "");
earthDataPass = RealWorldTerrainPrefs.LoadPref("EarthDataPass", "");
}
GUILayout.BeginHorizontal();
EditorGUI.BeginChangeCheck();
earthDataLogin = EditorGUILayout.TextField("EarthData username", earthDataLogin);
if (EditorGUI.EndChangeCheck())
{
if (earthDataLogin == "") RealWorldTerrainPrefs.DeletePref("EarthDataLogin");
else RealWorldTerrainPrefs.SetPref("EarthDataLogin", earthDataLogin);
}
if (string.IsNullOrEmpty(earthDataLogin))
{
GUILayout.Box(new GUIContent(RealWorldTerrainResources.warningIcon, "Required"), RealWorldTerrainResources.helpStyle, GUILayout.ExpandWidth(false));
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
EditorGUI.BeginChangeCheck();
earthDataPass = EditorGUILayout.TextField("EarthData password", earthDataPass);
if (EditorGUI.EndChangeCheck())
{
if (earthDataPass == "") RealWorldTerrainPrefs.DeletePref("EarthDataPass");
else RealWorldTerrainPrefs.SetPref("EarthDataPass", earthDataPass);
}
if (string.IsNullOrEmpty(earthDataPass))
{
GUILayout.Button(new GUIContent(RealWorldTerrainResources.warningIcon, "Required"), RealWorldTerrainResources.helpStyle, GUILayout.ExpandWidth(false));
}
GUILayout.EndHorizontal();
if (GUILayout.Button("Register on EarthData", GUILayout.ExpandWidth(true))) Process.Start("https://urs.earthdata.nasa.gov/users/new");
GUILayout.Space(10);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8e450b8bd11e19442833ce383d90bcdd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,113 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace InfinityCode.RealWorldTerrain
{
public static partial class RealWorldTerrainWindowUI
{
private static List<string> availableGrassType;
private static void GrassUI()
{
EditorGUILayout.BeginVertical(GUI.skin.box);
prefs.generateGrass = EditorGUILayout.Toggle("Generate grass", prefs.generateGrass);
if (!prefs.generateGrass)
{
EditorGUILayout.EndVertical();
return;
}
SelectGrassEngine();
if (prefs.grassEngine == "Standard") StandardGrassEngineFields();
else if (prefs.grassEngine == "Volume Grass") VolumeGrassFields();
else if (prefs.grassEngine == "Vegetation Studio") VegetationStudioGrassFields();
EditorGUILayout.Space();
EditorGUILayout.EndVertical();
}
private static void VegetationStudioGrassFields()
{
#if VEGETATION_STUDIO || VEGETATION_STUDIO_PRO
#if !VEGETATION_STUDIO_PRO
prefs.vegetationStudioPackage = EditorGUILayout.ObjectField("Package", prefs.vegetationStudioPackage, typeof(AwesomeTechnologies.VegetationPackage), false) as AwesomeTechnologies.VegetationPackage;
#else
prefs.vegetationStudioPackage = EditorGUILayout.ObjectField("Package", prefs.vegetationStudioPackage, typeof(AwesomeTechnologies.VegetationSystem.VegetationPackagePro), false) as AwesomeTechnologies.VegetationSystem.VegetationPackagePro;
#endif
if (prefs.vegetationStudioGrassTypes == null) prefs.vegetationStudioGrassTypes = new List<int> {1};
int removeIndex = -1;
for (int i = 0; i < prefs.vegetationStudioGrassTypes.Count; i++)
{
EditorGUILayout.BeginHorizontal();
prefs.vegetationStudioGrassTypes[i] = EditorGUILayout.IntSlider("Vegetation Type " + (i + 1) + ": ", prefs.vegetationStudioGrassTypes[i], 1, 32);
if (prefs.vegetationStudioGrassTypes.Count > 1 && GUILayout.Button("X", GUILayout.ExpandWidth(false))) removeIndex = i;
EditorGUILayout.EndHorizontal();
}
if (removeIndex != -1) prefs.vegetationStudioGrassTypes.RemoveAt(removeIndex);
if (GUILayout.Button("Add item")) prefs.vegetationStudioGrassTypes.Add(1);
#endif
}
private static void VolumeGrassFields()
{
#if VOLUMEGRASS
EditorGUILayout.HelpBox("Important: points outside terrains can crash Unity Editor.", MessageType.Info);
prefs.volumeGrassOutsidePoints = (RealWorldTerrainVolumeGrassOutsidePoints) EditorGUILayout.EnumPopup("Outside Points", prefs.volumeGrassOutsidePoints);
#endif
}
private static void StandardGrassEngineFields()
{
prefs.grassDensity = EditorGUILayout.IntField("Density (%)", prefs.grassDensity);
if (prefs.grassDensity < 1) prefs.grassDensity = 1;
if (prefs.grassPrefabs == null) prefs.grassPrefabs = new List<Texture2D>();
EditorGUILayout.LabelField("Grass Prefabs");
for (int i = 0; i < prefs.grassPrefabs.Count; i++)
{
prefs.grassPrefabs[i] =
(Texture2D)
EditorGUILayout.ObjectField(i + 1 + ":", prefs.grassPrefabs[i], typeof(Texture2D), false);
}
Texture2D newGrass =
(Texture2D)
EditorGUILayout.ObjectField(prefs.grassPrefabs.Count + 1 + ":", null, typeof(Texture2D), false);
if (newGrass != null) prefs.grassPrefabs.Add(newGrass);
prefs.grassPrefabs.RemoveAll(go => go == null);
}
private static void SelectGrassEngine()
{
if (availableGrassType.Count > 1)
{
int grassEngineIndex = availableGrassType.IndexOf(prefs.grassEngine);
if (grassEngineIndex == -1) grassEngineIndex = 0;
grassEngineIndex = EditorGUILayout.Popup("Grass engine ", grassEngineIndex, availableGrassType.ToArray());
prefs.grassEngine = availableGrassType[grassEngineIndex];
}
else prefs.grassEngine = availableGrassType[0];
}
private static void InitGrassEngines()
{
availableGrassType = new List<string>();
availableGrassType.Add("Standard");
#if VOLUMEGRASS
availableGrassType.Add("Volume Grass");
#endif
#if VEGETATION_STUDIO || VEGETATION_STUDIO_PRO
availableGrassType.Add("Vegetation Studio");
#endif
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7ddec60e0a0a6e6479429e629ec1cf14
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,49 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using System.Diagnostics;
using UnityEditor;
using UnityEngine;
namespace InfinityCode.RealWorldTerrain
{
public static partial class RealWorldTerrainWindowUI
{
#if HUGETEXTURE
private static readonly string[] labelsHugeTexturePageSize = { "256", "512", "1024", "2048", "4096", "8192" };
private static readonly int[] valuesHugeTexturePageSize = { 256, 512, 1024, 2048, 4096, 8192 };
#endif
private static void HugeTextureGUI()
{
#if HUGETEXTURE
EditorGUILayout.HelpBox("Important: when using Huge Texture, you cannot use Terrain Layers.", MessageType.Info);
TextureSourceUI();
prefs.hugeTexturePageSize = EditorGUILayout.IntPopup("Page Size", prefs.hugeTexturePageSize, labelsHugeTexturePageSize, valuesHugeTexturePageSize);
prefs.hugeTextureCols = EditorGUILayout.IntField("Cols", prefs.hugeTextureCols);
prefs.hugeTextureRows = EditorGUILayout.IntField("Rows", prefs.hugeTextureRows);
if (prefs.hugeTextureCols < 1) prefs.hugeTextureCols = 1;
if (prefs.hugeTextureRows < 1) prefs.hugeTextureRows = 1;
long width = prefs.hugeTexturePageSize * prefs.hugeTextureCols;
long height = prefs.hugeTexturePageSize * prefs.hugeTextureRows;
EditorGUILayout.LabelField("Width", width.ToString());
EditorGUILayout.LabelField("Height", height.ToString());
EditorGUILayout.LabelField("Total Pages", (prefs.hugeTextureCols * prefs.hugeTextureCols).ToString());
if (width * height * 3 > 2147483648L)
{
EditorGUILayout.HelpBox("Width * Height * 3 must be less than or equal to 2 GB (2 147 483 648 bytes).", MessageType.Error);
}
TextureMaxLevelUI();
#else
EditorGUILayout.HelpBox("HugeTexture is not in the project.", MessageType.Warning);
if (GUILayout.Button("Huge Texture")) Process.Start("https://assetstore.unity.com/packages/tools/input-management/huge-texture-163576?aid=1100liByC&pubref=rwt_ht_asset");
#endif
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 50e2498c71e291142be31fe592cabb1f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,40 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using InfinityCode.RealWorldTerrain.Windows;
using UnityEditor;
namespace InfinityCode.RealWorldTerrain
{
public static partial class RealWorldTerrainWindowUI
{
private static void OsmUI()
{
EditorGUIUtility.labelWidth = LabelWidth + 20;
if (RealWorldTerrainWindow.generateType == RealWorldTerrainGenerateType.additional)
{
prefs.elevationType = (RealWorldTerrainElevationType)EditorGUILayout.EnumPopup("Elevation", prefs.elevationType);
}
else prefs.elevationType = RealWorldTerrainElevationType.realWorld;
BuildingsUI();
RoadsUI();
RiversUI();
if (prefs.resultType == RealWorldTerrainResultType.terrain)
{
TreesUI();
GrassUI();
}
else
{
prefs.generateGrass = false;
prefs.generateTrees = false;
}
EditorGUIUtility.labelWidth = LabelWidth;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bf8d945692cc56c4a8362979015b534a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,68 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace InfinityCode.RealWorldTerrain
{
public static partial class RealWorldTerrainWindowUI
{
private static bool showPOI;
private static void PoiUI()
{
EditorGUILayout.BeginHorizontal(EditorStyles.toolbar);
if (prefs.POI == null) prefs.POI = new List<RealWorldTerrainPOI>();
if (GUILayout.Button(new GUIContent("+", "Add POI"), EditorStyles.toolbarButton, GUILayout.ExpandWidth(false)))
{
prefs.POI.Add(new RealWorldTerrainPOI("New POI " + (prefs.POI.Count + 1),
(prefs.leftLongitude + prefs.rightLongitude) / 2, (prefs.topLatitude + prefs.bottomLatitude) / 2));
}
GUILayout.Label("");
if (GUILayout.Button("Clear", EditorStyles.toolbarButton, GUILayout.ExpandWidth(false))) prefs.POI = new List<RealWorldTerrainPOI>();
EditorGUILayout.EndHorizontal();
if (prefs.POI.Count == 0)
{
GUILayout.Label("POI is not specified.");
}
int poiIndex = 1;
int poiDeleteIndex = -1;
foreach (RealWorldTerrainPOI poi in prefs.POI)
{
EditorGUILayout.BeginHorizontal();
GUILayout.Label(poiIndex.ToString(), GUILayout.ExpandWidth(false));
poi.title = EditorGUILayout.TextField("", poi.title);
GUILayout.Label("Lat", GUILayout.ExpandWidth(false));
poi.y = EditorGUILayout.DoubleField("", poi.y, GUILayout.Width(80));
GUILayout.Label("Lng", GUILayout.ExpandWidth(false));
poi.x = EditorGUILayout.DoubleField("", poi.x, GUILayout.Width(80));
if (GUILayout.Button(new GUIContent("X", "Delete POI"), GUILayout.ExpandWidth(false))) poiDeleteIndex = poiIndex - 1;
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
GUILayout.Space(16);
GUILayout.Label("Altitude", GUILayout.ExpandWidth(false));
poi.altitude = EditorGUILayout.FloatField("", poi.altitude, GUILayout.Width(40));
GUILayout.Label("Prefab", GUILayout.ExpandWidth(false));
poi.prefab = EditorGUILayout.ObjectField("", poi.prefab, typeof(GameObject), false) as GameObject;
EditorGUILayout.EndHorizontal();
poiIndex++;
}
if (poiDeleteIndex != -1) prefs.POI.RemoveAt(poiDeleteIndex);
EditorGUILayout.Space();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a2f50c1586916674592ee423773ff5ad
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,63 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using System.Collections.Generic;
using InfinityCode.RealWorldTerrain.Generators;
using UnityEditor;
using UnityEngine;
namespace InfinityCode.RealWorldTerrain
{
public static partial class RealWorldTerrainWindowUI
{
private static List<string> availableRiverEngines;
private static string[] availableRiverEnginesArr;
private static void InitRiverEngines()
{
availableRiverEngines = new List<string> {
RealWorldTerrainRiverGenerator.BUILTIN_RIVER_ENGINE,
#if RAM2019
RealWorldTerrainRiverGenerator.RAM2019_RIVER_ENGINE
#endif
};
availableRiverEnginesArr = availableRiverEngines.ToArray();
}
private static void RiversUI()
{
EditorGUILayout.BeginVertical(GUI.skin.box);
prefs.generateRivers = EditorGUILayout.Toggle("Generate rivers", prefs.generateRivers);
if (!prefs.generateRivers)
{
EditorGUILayout.EndVertical();
return;
}
int riverEngineIndex = availableRiverEngines.IndexOf(prefs.riverEngine);
if (riverEngineIndex == -1)
{
riverEngineIndex = 0;
prefs.riverEngine = availableRiverEnginesArr[0];
}
int ri = EditorGUILayout.Popup("River Engine", riverEngineIndex, availableRiverEnginesArr);
if (ri != riverEngineIndex) prefs.riverEngine = availableRiverEnginesArr[ri];
if (prefs.riverEngine == RealWorldTerrainRiverGenerator.BUILTIN_RIVER_ENGINE)
{
prefs.riverMaterial = EditorGUILayout.ObjectField("Material", prefs.riverMaterial, typeof(Material), false) as Material;
}
else if (prefs.riverEngine == RealWorldTerrainRiverGenerator.RAM2019_RIVER_ENGINE)
{
#if RAM2019
prefs.ramAreaProfile = EditorGUILayout.ObjectField("Area Profile", prefs.ramAreaProfile, typeof(LakePolygonProfile), false) as LakePolygonProfile;
prefs.ramSplineProfile = EditorGUILayout.ObjectField("Spline Profile", prefs.ramSplineProfile, typeof(SplineProfile), false) as SplineProfile;
#endif
}
EditorGUILayout.EndVertical();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 604a5631442b0a24b825aa03293ef1a4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,197 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
#if EASYROADS3D
using EasyRoads3Dv3;
#endif
namespace InfinityCode.RealWorldTerrain
{
public static partial class RealWorldTerrainWindowUI
{
private const string EasyRoadsLabel = "EasyRoads3D";
private const string RoadArchitectLabel = "Road Architect";
private static List<string> availableRoadType;
private static string[] roadTypeNames;
#if EASYROADS3D
private static ERModularBase roadNetwork;
private static bool needFindRoadNetwork = true;
private static string[] erRoadTypeNames;
#endif
private static void EasyRoads3DFields()
{
prefs.erSnapToTerrain = EditorGUILayout.Toggle("Snap to Terrain", prefs.erSnapToTerrain);
if (Math.Abs(prefs.erWidthMultiplier - 1) > float.Epsilon && prefs.erGenerateConnection)
{
EditorGUILayout.HelpBox("If you select any connection, the width of the road will be reset to the default value.", MessageType.Warning);
}
prefs.roadTypeMode = (RealWorldTerrainRoadTypeMode)EditorGUILayout.EnumPopup("Mode", prefs.roadTypeMode);
if (prefs.roadTypeMode == RealWorldTerrainRoadTypeMode.simple)
{
prefs.erWidthMultiplier = EditorGUILayout.FloatField("Width Multiplier", prefs.erWidthMultiplier);
}
prefs.erGenerateConnection = EditorGUILayout.Toggle("Generate Connections", prefs.erGenerateConnection);
if (prefs.erGenerateConnection)
{
EditorGUILayout.HelpBox("Important: the ability to generate connections is in beta. \nThis means that some roads may be not connected. \nWe and AndaSoft are working to improve this feature.", MessageType.Warning);
}
if (prefs.roadTypeMode == RealWorldTerrainRoadTypeMode.simple)
{
prefs.roadTypes = (RealWorldTerrainRoadType)EditorGUILayout.EnumFlagsField("Road types", prefs.roadTypes);
}
else if (prefs.roadTypeMode == RealWorldTerrainRoadTypeMode.advanced)
{
#if EASYROADS3D
if (roadNetwork == null && needFindRoadNetwork)
{
roadNetwork = RealWorldTerrainUtils.FindObjectOfType<ERModularBase>();
needFindRoadNetwork = false;
}
if (roadNetwork == null)
{
EditorGUILayout.HelpBox("Mode - Advanced requires a road network in the scene.", MessageType.Error);
if (GUILayout.Button("Find Road Network in scene"))
{
roadNetwork = RealWorldTerrainUtils.FindObjectOfType<ERModularBase>();
}
if (GUILayout.Button("Create Road Network"))
{
ERRoadNetwork newRoadNetwork = new ERRoadNetwork();
roadNetwork = newRoadNetwork.roadNetwork;
}
}
if (roadTypeNames == null) roadTypeNames = Enum.GetNames(typeof(RealWorldTerrainRoadType));
if (roadNetwork == null)
{
foreach (string name in roadTypeNames) EditorGUILayout.LabelField(ObjectNames.NicifyVariableName(name));
}
else
{
if (erRoadTypeNames == null) UpdateERRoadTypes();
if (GUILayout.Button("Update EasyRoad3D Road Types")) UpdateERRoadTypes();
if (erRoadTypeNames != null)
{
if (prefs.erRoadTypes == null) prefs.erRoadTypes = new string[roadTypeNames.Length];
if (prefs.erRoadTypes.Length != erRoadTypeNames.Length) Array.Resize(ref prefs.erRoadTypes, roadTypeNames.Length);
for (int i = 0; i < roadTypeNames.Length; i++)
{
int index = 0;
string roadTypeName = prefs.erRoadTypes[i];
if (!string.IsNullOrEmpty(roadTypeName))
{
for (int j = 0; j < erRoadTypeNames.Length; j++)
{
if (erRoadTypeNames[j] == roadTypeName)
{
index = j;
break;
}
}
}
index = EditorGUILayout.Popup(ObjectNames.NicifyVariableName(roadTypeNames[i]), index, erRoadTypeNames);
if (index != 0) prefs.erRoadTypes[i] = erRoadTypeNames[index];
else prefs.erRoadTypes[i] = string.Empty;
}
}
}
#endif
}
}
private static void InitRoadEngines()
{
availableRoadType = new List<string>();
#if EASYROADS3D
availableRoadType.Add(EasyRoadsLabel);
#endif
#if ROADARCHITECT
availableRoadType.Add(RoadArchitectLabel);
#endif
}
private static void RoadArchitectFields()
{
prefs.roadTypeMode = RealWorldTerrainRoadTypeMode.simple;
prefs.roadTypes = (RealWorldTerrainRoadType)EditorGUILayout.EnumFlagsField("Road types", prefs.roadTypes);
}
private static void RoadsUI()
{
if (availableRoadType.Count == 0)
{
prefs.generateRoads = false;
return;
}
EditorGUILayout.BeginVertical(GUI.skin.box);
prefs.generateRoads = EditorGUILayout.Toggle("Generate roads", prefs.generateRoads);
if (!prefs.generateRoads)
{
EditorGUILayout.EndVertical();
return;
}
EditorGUILayout.HelpBox("If the selected area contains cities, generation of roads can take a VERY long time.", MessageType.Info);
SelectRoadEngine();
prefs.normalizeRoadDistances = EditorGUILayout.Toggle("Normalize Road Distances", prefs.normalizeRoadDistances);
if (prefs.roadEngine == EasyRoadsLabel) EasyRoads3DFields();
else if (prefs.roadEngine == RoadArchitectLabel) RoadArchitectFields();
EditorGUILayout.EndVertical();
}
private static void SelectRoadEngine()
{
if (availableRoadType.Count == 1)
{
EditorGUILayout.LabelField("Road engine - " + availableRoadType[0]);
prefs.roadEngine = availableRoadType[0];
}
else
{
int roadEngineIndex = availableRoadType.IndexOf(prefs.roadEngine);
if (roadEngineIndex == -1) roadEngineIndex = 0;
roadEngineIndex = EditorGUILayout.Popup("Road engine", roadEngineIndex, availableRoadType.ToArray());
prefs.roadEngine = availableRoadType[roadEngineIndex];
}
}
private static void UpdateERRoadTypes()
{
#if EASYROADS3D
ERRoadType[] erRoadTypes = roadNetwork.GetRoadTypes();
if (erRoadTypes != null) erRoadTypeNames = new[] { "Ignore" }.Concat(erRoadTypes.Select(t => t.roadTypeName)).ToArray();
else erRoadTypeNames = null;
#endif
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ccdf09dcd9e60ba4abf323ac7e51cee9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,213 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using InfinityCode.RealWorldTerrain.Windows;
using UnityEditor;
using UnityEngine;
using Debug = UnityEngine.Debug;
namespace InfinityCode.RealWorldTerrain
{
public static partial class RealWorldTerrainWindowUI
{
private static readonly string[] labelsBaseMapRes = { "16", "32", "64", "128", "256", "512", "1024", "2048" };
private static readonly int[] valuesBaseMapRes = { 16, 32, 64, 128, 256, 512, 1024, 2048 };
private static bool showTerrains = true;
private static void CountTerrainsUI()
{
if (prefs.resultType != RealWorldTerrainResultType.terrain && prefs.resultType != RealWorldTerrainResultType.mesh) return;
GUILayout.BeginHorizontal();
GUILayout.Label("Count terrains. X");
prefs.terrainCount.x = Mathf.Max(EditorGUILayout.IntField(prefs.terrainCount.x), 1);
GUILayout.Label("Z");
prefs.terrainCount.y = Mathf.Max(EditorGUILayout.IntField(prefs.terrainCount.y), 1);
DrawHelpButton("The number of terrains horizontally and vertically (XZ axis).");
GUILayout.EndHorizontal();
}
private static void ElevationRangeUI()
{
if (prefs.resultType == RealWorldTerrainResultType.rawFile) return;
prefs.elevationRange = (RealWorldTerrainElevationRange) EditorGUILayout.EnumPopup("Elevation range", prefs.elevationRange);
if (prefs.elevationRange == RealWorldTerrainElevationRange.autoDetect)
{
prefs.autoDetectElevationOffset.x = EditorGUILayout.FloatField("Min elevation offset", prefs.autoDetectElevationOffset.x);
prefs.autoDetectElevationOffset.y = EditorGUILayout.FloatField("Max elevation offset", prefs.autoDetectElevationOffset.y);
}
else if (prefs.elevationRange == RealWorldTerrainElevationRange.fixedValue)
{
prefs.fixedMinElevation = EditorGUILayout.FloatField("Min elevation", prefs.fixedMinElevation);
prefs.fixedMaxElevation = EditorGUILayout.FloatField("Max elevation", prefs.fixedMaxElevation);
}
else if (prefs.elevationRange == RealWorldTerrainElevationRange.realWorldValue)
{
EditorGUILayout.HelpBox("When using Elevation range - Real World Value, you can have steps in the hills.\nThis is due to the way the Unity Terrain Engine stores elevation data.\nUse Elevation range - Real World Value only for areas that have a very wide range of heights, and when you are sure that you really need it!", MessageType.Warning);
}
}
private static void GaiaStampFields()
{
#if !GAIA_PRESENT && !GAIA_PRO_PRESENT && !GAIA_2_PRESENT && !GAIA_2023
EditorGUILayout.HelpBox("Gaia not found. Import Gaia into the project.", MessageType.Error);
#endif
prefs.gaiaStampResolution = EditorGUILayout.IntField("Stamp Resolution", prefs.gaiaStampResolution);
}
private static void GenerateUnderwaterUI()
{
prefs.generateUnderWater = EditorGUILayout.Toggle("Generate Underwater", prefs.generateUnderWater);
if (!prefs.generateUnderWater) return;
EditorGUI.indentLevel++;
int nodata = IntField(
"Max Underwater Depth",
prefs.nodataValue,
"SRTM v4.1 does not contain data on the underwater depths. Real World Terrain generates it by closest known areas of land. \nSpecify a value relative to sea level. \nFor example, if you want to get a depth of 200 meters, set the value \"-200\"."
);
if (nodata < short.MinValue) nodata = short.MinValue;
if (nodata > short.MaxValue) nodata = short.MaxValue;
prefs.depthSharpness = FloatField(
"Depth Sharpness",
prefs.depthSharpness,
"Escarpment of the seabed. \nGreater value - steeper slope.\nUnknown Value = Average Neighbor Known Values - Depth Sharpness."
);
if (prefs.depthSharpness < 0) prefs.depthSharpness = 0;
if (prefs.elevationProvider == RealWorldTerrainElevationProvider.BingMaps) prefs.bingMapsUseZeroAsUnknown = EditorGUILayout.Toggle("Zero Elevation is Unknown", prefs.bingMapsUseZeroAsUnknown);
prefs.nodataValue = (short) nodata;
prefs.waterDetectionSource = (RealWorldTerrainWaterDetectionSource)EditorGUILayout.EnumPopup("Water Detection Source", prefs.waterDetectionSource);
if (prefs.waterDetectionSource == RealWorldTerrainWaterDetectionSource.texture)
{
prefs.waterDetectionTexture = ObjectField("Water Detection Texture", prefs.waterDetectionTexture, typeof(Texture2D), "The texture of the current area where the water is white and the rest is black.\nThe coordinates of the borders of the texture must match the coordinates of the borders of the generated area.\nMust have Read / Write Enabled - ON.") as Texture2D;
}
else
{
prefs.waterDetectionBitMask = ObjectField("Water Detection BitMask", prefs.waterDetectionBitMask, typeof(TextAsset), "The bit mask of the current area where the water is 0 and the rest is 1.") as TextAsset;
if (GUILayout.Button("Open BitMask Convertor"))
{
RealWorldTerrainWaterMaskConverter.OpenWindow();
}
}
EditorGUI.indentLevel--;
}
private static void RawFileFields()
{
EditorGUILayout.BeginHorizontal();
prefs.rawFilename = EditorGUILayout.TextField("Filename", prefs.rawFilename);
if (GUILayout.Button("...", GUILayout.ExpandWidth(false)))
{
GUI.FocusControl(null);
string ext = prefs.rawType == RealWorldTerrainRawType.RAW ? "raw" : "png";
string rawFilename = EditorUtility.SaveFilePanel("Output RAW filename", Application.dataPath, "terrain." + ext, ext);
if (!string.IsNullOrEmpty(rawFilename)) prefs.rawFilename = rawFilename;
}
EditorGUILayout.EndHorizontal();
prefs.rawType = (RealWorldTerrainRawType) EditorGUILayout.EnumPopup("Type", prefs.rawType);
if (prefs.rawType == RealWorldTerrainRawType.RAW) prefs.rawByteOrder = (RealWorldTerrainByteOrder) EditorGUILayout.EnumPopup("Byte order", prefs.rawByteOrder);
prefs.rawWidth = EditorGUILayout.IntField("Width", prefs.rawWidth);
prefs.rawHeight = EditorGUILayout.IntField("Height", prefs.rawHeight);
}
private static void TerrainDataSettings()
{
if (values2n1.All(v => v != prefs.heightmapResolution))
{
prefs.heightmapResolution = Mathf.ClosestPowerOfTwo(prefs.heightmapResolution) + 1;
if (values2n1.All(v => v != prefs.heightmapResolution)) prefs.heightmapResolution = 129;
}
prefs.heightmapResolution =
IntPopup("Heightmap Resolution", prefs.heightmapResolution, labels2n1, values2n1,
"The Heightmap resolution for each Terrain.", "http://docs.unity3d.com/Documentation/Components/terrain-UsingTerrains.html");
prefs.detailResolution = IntField("Detail Resolution", prefs.detailResolution,
"The resolution of the map that controls grass and detail meshes. For performance reasons (to save on draw calls) the lower you set this number the better.",
"http://docs.unity3d.com/Documentation/Components/terrain-UsingTerrains.html");
prefs.detailResolution = Mathf.Clamp(prefs.detailResolution, 32, 4096);
prefs.resolutionPerPatch = IntField("Resolution Per Patch", prefs.resolutionPerPatch,
"Specifies the size in pixels of each individually rendered detail patch. A larger number reduces draw calls, but might increase triangle count since detail patches are culled on a per batch basis. A recommended value is 16. If you use a very large detail object distance and your grass is very sparse, it makes sense to increase the value.",
"http://docs.unity3d.com/Documentation/ScriptReference/TerrainData.SetDetailResolution.html");
prefs.resolutionPerPatch = Mathf.Clamp(prefs.resolutionPerPatch, 8, 1000);
if (prefs.detailResolution % prefs.resolutionPerPatch != 0)
{
prefs.detailResolution = prefs.detailResolution / prefs.resolutionPerPatch * prefs.resolutionPerPatch;
if (prefs.detailResolution < 32) prefs.detailResolution = 32;
}
prefs.controlTextureResolution = IntPopup("Control Texture Resolution", prefs.controlTextureResolution, labels2n, values2n,
"Resolution of the splatmap that controls the blending of the different terrain textures.",
"http://docs.unity3d.com/Documentation/Components/terrain-UsingTerrains.html");
prefs.baseMapResolution = IntPopup("Base Map Resolution", prefs.baseMapResolution, labelsBaseMapRes, valuesBaseMapRes,
"The resolution of the composite texture that is used in place of the splat map at certain distances.",
"http://docs.unity3d.com/Documentation/Components/terrain-UsingTerrains.html");
if (!valuesBaseMapRes.Contains(prefs.baseMapResolution)) prefs.baseMapResolution = 1024;
}
private static void TerrainFullFields()
{
prefs.resultType = (RealWorldTerrainResultType)EnumPopup("Result", prefs.resultType, "The type of the generated object.");
CountTerrainsUI();
prefs.alignWaterLine = Toggle("Align Water Line", prefs.alignWaterLine, false,
"If disabled terrains will have zero Y at minimum elevation.\nIf enabled, terrains will have zero Y on the water line(zero elevation).");
if (prefs.resultType == RealWorldTerrainResultType.gaiaStamp) GaiaStampFields();
else if (prefs.resultType == RealWorldTerrainResultType.rawFile) RawFileFields();
else TerrainSizeTypeUI();
ElevationRangeUI();
}
private static void TerrainSizeTypeUI()
{
prefs.sizeType = IntPopup(
"Size type",
prefs.sizeType, new[] {"Real world sizes", "Mercator sizes", "Fixed size"},
new[] {0, 1, 2},
"Specifies whether the projection will be determined by the size of the area.",
new[] {"http://en.wikipedia.org/wiki/Cylindrical_equal-area_projection", "http://en.wikipedia.org/wiki/Mercator_projection"}
);
if (prefs.sizeType == 2)
{
prefs.fixedTerrainSize.x = FloatField("Terrain Width", prefs.fixedTerrainSize.x, "Width of each terrain (units)");
prefs.fixedTerrainSize.z = FloatField("Terrain Length", prefs.fixedTerrainSize.z, "Length of each terrain (units)");
prefs.terrainScale.y = FloatField("Scale Y", prefs.terrainScale.y, "The scale of the elevations.");
}
else prefs.terrainScale = Vector3Field("Scale", prefs.terrainScale, "The scale of the resulting objects.");
}
private static void TerrainUI()
{
if (generateType == RealWorldTerrainGenerateType.full) TerrainFullFields();
if (prefs.resultType == RealWorldTerrainResultType.terrain) GenerateUnderwaterUI();
else prefs.generateUnderWater = false;
if (prefs.resultType == RealWorldTerrainResultType.terrain) TerrainDataSettings();
else if (prefs.resultType == RealWorldTerrainResultType.mesh)
{
prefs.heightmapResolution =
RealWorldTerrainMath.Limit(IntField("Height Map Resolution", prefs.heightmapResolution,
"Heightmap resolution for each mesh."), 8, 250);
}
GUILayout.Space(10);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 29aa7a479c145ba4ab7bd267c09fb7b1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,202 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
namespace InfinityCode.RealWorldTerrain
{
public static partial class RealWorldTerrainWindowUI
{
private const float TerrainLayerLineHeight = RealWorldTerrainVectorTerrainLayerFeature.TerrainLayerLineHeight;
private static ReorderableList terrainLayersList;
private static void AddVectorTerrainLayerFeature(ReorderableList list)
{
prefs.vectorTerrainLayers.Add(new RealWorldTerrainVectorTerrainLayerFeature());
}
private static int DrawVectorLayerData(RealWorldTerrainVectorTerrainLayerFeature.Rule rule, int index, ref Rect r)
{
int ret = 0; // 0 - do nothing, -1 - remove, 1 - update height
GUI.Label(new Rect(r.x, r.y, r.width - 20, r.height), "Rule " + (index + 1) + ": ");
if (GUI.Button(new Rect(r.xMax - 20, r.y, 20, r.height), "X")) ret = -1;
r.y += TerrainLayerLineHeight;
EditorGUI.BeginChangeCheck();
rule.layer = (RealWorldTerrainMapboxLayer)EditorGUI.EnumPopup(r, "Layer", rule.layer);
r.y += TerrainLayerLineHeight;
if (EditorGUI.EndChangeCheck())
{
rule.extra = ~0;
ret = 1;
}
if (rule.hasExtra)
{
if (rule.layer == RealWorldTerrainMapboxLayer.landuse)
{
rule.extra = (int)(RealWorldTerrainMapboxLanduse)EditorGUI.EnumFlagsField(r, "Classes", (RealWorldTerrainMapboxLanduse)rule.extra);
r.y += TerrainLayerLineHeight;
}
else if (rule.layer == RealWorldTerrainMapboxLayer.landuse_overlay)
{
rule.extra = (int)(RealWorldTerrainMapboxLanduseOverlay)EditorGUI.EnumFlagsField(r, "Classes", (RealWorldTerrainMapboxLanduseOverlay)rule.extra);
r.y += TerrainLayerLineHeight;
}
else if (rule.layer == RealWorldTerrainMapboxLayer.waterway)
{
rule.extra = (int)(RealWorldTerrainMapboxWaterway)EditorGUI.EnumFlagsField(r, "Classes", (RealWorldTerrainMapboxWaterway)rule.extra);
r.y += TerrainLayerLineHeight;
}
else if (rule.layer == RealWorldTerrainMapboxLayer.structure)
{
rule.extra = (int)(RealWorldTerrainMapboxStructure)EditorGUI.EnumFlagsField(r, "Classes", (RealWorldTerrainMapboxStructure)rule.extra);
r.y += TerrainLayerLineHeight;
}
}
return ret;
}
private static void DrawVectorTerrainBaseLayers()
{
EditorGUILayout.LabelField("Base Layers");
if (prefs.vectorTerrainBaseLayers == null) prefs.vectorTerrainBaseLayers = new List<TerrainLayer>();
if (prefs.vectorTerrainBaseLayers.Count == 0) prefs.vectorTerrainBaseLayers.Add(null);
int removeIndex = -1;
for (int i = 0; i < prefs.vectorTerrainBaseLayers.Count; i++)
{
EditorGUILayout.BeginHorizontal();
prefs.vectorTerrainBaseLayers[i] = EditorGUILayout.ObjectField(new GUIContent((i + 1).ToString()), prefs.vectorTerrainBaseLayers[i], typeof(TerrainLayer), false) as TerrainLayer;
if (GUILayout.Button("X", GUILayout.ExpandWidth(false))) removeIndex = i;
EditorGUILayout.EndHorizontal();
}
if (prefs.vectorTerrainBaseLayers.Count > 1)
{
prefs.vectorTerrainBaseLayersNoiseOffset = EditorGUILayout.Vector2Field("Noise Offset", prefs.vectorTerrainBaseLayersNoiseOffset);
prefs.vectorTerrainBaseLayersNoiseScale = EditorGUILayout.FloatField("Noise Scale", prefs.vectorTerrainBaseLayersNoiseScale);
}
if (removeIndex != -1) prefs.vectorTerrainBaseLayers.RemoveAt(removeIndex);
if (GUILayout.Button("Add Base Layer")) prefs.vectorTerrainBaseLayers.Add(null);
}
private static void DrawVectorTerrainLayerFeature(Rect rect, int index, bool isactive, bool isfocused)
{
Rect r = new Rect(rect)
{
height = TerrainLayerLineHeight - 2
};
RealWorldTerrainVectorTerrainLayerFeature layer = prefs.vectorTerrainLayers[index];
GUI.Label(r, "Layer " + (index + 1) + ": ");
r.y += TerrainLayerLineHeight;
if (layer.terrainLayers == null) layer.terrainLayers = new List<TerrainLayer>();
if (layer.terrainLayers.Count == 0) layer.terrainLayers.Add(null);
int removeIndex = -1;
for (int i = 0; i < layer.terrainLayers.Count; i++)
{
TerrainLayer terrainLayer = layer.terrainLayers[i];
layer.terrainLayers[i] = EditorGUI.ObjectField(new Rect(r.x, r.y, r.width - 20, r.height), new GUIContent("Terrain Layer"), terrainLayer, typeof(TerrainLayer), false) as TerrainLayer;
if (GUI.Button(new Rect(r.xMax - 20, r.y, 20, r.height), "X")) removeIndex = i;
r.y += TerrainLayerLineHeight;
}
if (layer.terrainLayers.Count > 1)
{
EditorGUI.LabelField(r, "Noise Offset");
float labelWidth = EditorGUIUtility.labelWidth;
EditorGUIUtility.labelWidth = 20;
float halfWidth = (r.width - labelWidth) / 2;
layer.noiseOffset.x = EditorGUI.FloatField(new Rect(r.x + labelWidth, r.y, halfWidth, r.height), "X", layer.noiseOffset.x);
layer.noiseOffset.y = EditorGUI.FloatField(new Rect(r.x + labelWidth + halfWidth, r.y, halfWidth, r.height), "Y", layer.noiseOffset.y);
EditorGUIUtility.labelWidth = labelWidth;
r.y += TerrainLayerLineHeight;
layer.noiseScale = EditorGUI.FloatField(r, "Noise Scale", layer.noiseScale);
r.y += TerrainLayerLineHeight;
}
if (GUI.Button(r, "Add TerrainLayer"))
{
layer.terrainLayers.Add(null);
layer.UpdateHeight();
}
r.y += TerrainLayerLineHeight;
if (removeIndex != -1)
{
layer.terrainLayers.RemoveAt(removeIndex);
layer.UpdateHeight();
}
if (layer.rules == null) layer.rules = new List<RealWorldTerrainVectorTerrainLayerFeature.Rule>();
removeIndex = -1;
for (int i = 0; i < layer.rules.Count; i++)
{
int ret = DrawVectorLayerData(layer.rules[i], i, ref r);
if (ret == -1) removeIndex = i;
else if (ret == 1) layer.UpdateHeight();
}
if (removeIndex != -1)
{
layer.rules.RemoveAt(removeIndex);
layer.UpdateHeight();
}
if (GUI.Button(r, "Add Rule"))
{
layer.rules.Add(new RealWorldTerrainVectorTerrainLayerFeature.Rule());
layer.UpdateHeight();
}
}
private static float HeightVectorTerrainLayerFeature(int index)
{
if (index < 0 || index >= prefs.vectorTerrainLayers.Count) return 0;
RealWorldTerrainVectorTerrainLayerFeature layer = prefs.vectorTerrainLayers[index];
return layer.height;
}
private static void RemoveVectorTerrainLayerFeature(ReorderableList list)
{
prefs.vectorTerrainLayers.RemoveAt(list.index);
}
private static void TerrainLayersUI()
{
EditorGUILayout.HelpBox("The ability to generate Terrain Layers is in beta. If you have any problems or have suggestions for improving this feature, please contact us (support@infinity-code.com).", MessageType.Info);
EditorGUILayout.HelpBox("Important: you can specify materials only for new terrains. During regeneration, modified Terrain Layers will not be assigned. This is some kind of bug in Unity Editor. We are working on finding a way around this.", MessageType.Warning);
MapboxAccessToken();
TextureMaxLevelUI();
DrawVectorTerrainBaseLayers();
if (prefs.vectorTerrainLayers == null) prefs.vectorTerrainLayers = new List<RealWorldTerrainVectorTerrainLayerFeature>();
if (terrainLayersList == null)
{
terrainLayersList = new ReorderableList(prefs.vectorTerrainLayers, typeof(RealWorldTerrainVectorTerrainLayerFeature), true, true, true, true);
terrainLayersList.drawElementCallback += DrawVectorTerrainLayerFeature;
terrainLayersList.drawHeaderCallback += r => GUI.Label(r, "Layers");
terrainLayersList.onAddCallback += AddVectorTerrainLayerFeature;
terrainLayersList.onRemoveCallback += RemoveVectorTerrainLayerFeature;
terrainLayersList.elementHeightCallback += HeightVectorTerrainLayerFeature;
}
terrainLayersList.DoLayoutList();
GUILayout.Space(10);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3e48b6a827433d84e9505d9925afc5d6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,256 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace InfinityCode.RealWorldTerrain
{
public static partial class RealWorldTerrainWindowUI
{
private static readonly string[] labelsTextureSize = { "32", "64", "128", "256", "512", "1024", "2048", "4096", "8192", "12288", "16384", "20480", "26624" };
private static readonly int[] valuesTextureSize = { 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 12288, 16384, 20480, 26624 };
private static int providerIndex;
private static string[] providersTitle;
private static RealWorldTerrainTextureProviderManager.Provider[] providers;
private static bool showCustomProviderTokens;
private static bool showTextures = true;
public static void InitTextureProviders()
{
providersTitle = RealWorldTerrainTextureProviderManager.GetProvidersTitle();
providers = RealWorldTerrainTextureProviderManager.GetProviders();
if (prefs.mapType == null) prefs.mapType = RealWorldTerrainTextureProviderManager.FindMapType(prefs.mapTypeID);
providerIndex = prefs.mapType.provider.index;
}
private static void PrecalculateMaxLevel()
{
int tx = 0;
int ty = 0;
int textureLevel = 0;
if (prefs.textureResultType == RealWorldTerrainTextureResultType.regularTexture)
{
tx = prefs.textureSize.x * prefs.terrainCount.x / 256;
ty = prefs.textureSize.y * prefs.terrainCount.y / 256;
}
else if (prefs.textureResultType == RealWorldTerrainTextureResultType.hugeTexture)
{
tx = prefs.hugeTexturePageSize * prefs.hugeTextureCols * prefs.terrainCount.x / 256;
ty = prefs.hugeTexturePageSize * prefs.hugeTextureRows * prefs.terrainCount.y / 256;
}
else if (prefs.textureResultType == RealWorldTerrainTextureResultType.terrainLayers)
{
tx = prefs.controlTextureResolution * prefs.terrainCount.x / 256;
ty = prefs.controlTextureResolution * prefs.terrainCount.y / 256;
}
for (int z = 5; z < 22; z++)
{
double stx, sty, etx, ety;
RealWorldTerrainGeo.LatLongToTile(prefs.leftLongitude, prefs.topLatitude, z, out stx, out sty);
RealWorldTerrainGeo.LatLongToTile(prefs.rightLongitude, prefs.bottomLatitude, z, out etx, out ety);
if (etx < stx) etx += 1 << z;
if (etx - stx > tx && ety - sty > ty)
{
textureLevel = z;
break;
}
}
if (textureLevel == 0) textureLevel = 22;
EditorGUILayout.HelpBox("Texture level = " + textureLevel + " will be used.", MessageType.Info);
}
private static void RegularTextureUI()
{
TextureSourceUI();
EditorGUILayout.BeginHorizontal();
GUILayout.Label("Texture width");
prefs.textureSize.x = EditorGUILayout.IntPopup(prefs.textureSize.x, labelsTextureSize, valuesTextureSize);
GUILayout.Label("height");
prefs.textureSize.y = EditorGUILayout.IntPopup(prefs.textureSize.y, labelsTextureSize, valuesTextureSize);
DrawHelpButton("Texture size for each terrains.");
EditorGUILayout.EndHorizontal();
if (prefs.textureSize.x > 8192 || prefs.textureSize.y > 8192)
{
#if !HUGETEXTURE
EditorGUILayout.HelpBox("To use textures with side sizes larger than 8192 px, you must have a Huge Texture asset in the project.", MessageType.Error);
if (GUILayout.Button("Huge Texture")) Process.Start("https://assetstore.unity.com/packages/tools/input-management/huge-texture-163576");
#else
EditorGUILayout.HelpBox("To use textures with side sizes larger than 8192 px switch to Result Type - Huge Texture.", MessageType.Error);
if (GUILayout.Button("Set Result Type - Huge Texture"))
{
prefs.textureResultType = RealWorldTerrainTextureResultType.hugeTexture;
prefs.hugeTexturePageSize = 1024;
prefs.hugeTextureCols = Mathf.CeilToInt(prefs.textureSize.x / (float)prefs.hugeTexturePageSize);
prefs.hugeTextureRows = Mathf.CeilToInt(prefs.textureSize.y / (float)prefs.hugeTexturePageSize);
}
#endif
}
prefs.textureMipMaps = Toggle(prefs.textureMipMaps, "Mipmaps", false, "Mipmaps are lists of progressively smaller versions of an image, used to optimize performance on real-time 3D engines. Objects that are far away from the Camera use smaller Texture versions.");
EditorGUILayout.BeginHorizontal();
prefs.textureFileType = (RealWorldTerrainTextureFileType)EnumPopup("Format", prefs.textureFileType, "Texture format. PNG is highly recommended to avoid double quality loss due to compression.");
if (prefs.textureFileType == RealWorldTerrainTextureFileType.jpg) prefs.textureFileQuality = EditorGUILayout.IntSlider("Quality", prefs.textureFileQuality, 0, 100);
EditorGUILayout.EndHorizontal();
TextureMaxLevelUI();
}
private static void TextureUI()
{
prefs.textureResultType = (RealWorldTerrainTextureResultType)EnumPopup("Result Type", prefs.textureResultType, "The type of the resulting texture.");
if (prefs.textureResultType == RealWorldTerrainTextureResultType.regularTexture) RegularTextureUI();
else if (prefs.textureResultType == RealWorldTerrainTextureResultType.hugeTexture) HugeTextureGUI();
else if (prefs.textureResultType == RealWorldTerrainTextureResultType.terrainLayers) TerrainLayersUI();
EditorGUILayout.Space();
}
private static void TextureMaxLevelUI()
{
List<string> levels = new List<string> { "Auto" };
for (int i = 5; i < 23; i++) levels.Add(i.ToString());
int index = prefs.maxTextureLevel;
if (index != 0) index -= 4;
index = EditorGUILayout.Popup("Max level", index, levels.ToArray());
prefs.maxTextureLevel = index;
if (index != 0) prefs.maxTextureLevel += 4;
else
{
PrecalculateMaxLevel();
prefs.reduceTextures = Toggle(prefs.reduceTextures, "Reduce size of textures, with no levels of tiles?", true,
"Reducing the size of the texture, reduces the time texture generation and memory usage.");
}
}
private static void TextureSourceUI()
{
TextureProviderUI();
if (prefs.mapType.provider.types.Length > 1)
{
GUIContent[] availableTypes = prefs.mapType.provider.types.Select(t => new GUIContent(t.title)).ToArray();
int mti = prefs.mapType.index;
EditorGUI.BeginChangeCheck();
mti = EditorGUILayout.Popup(new GUIContent("Type", "Type of map texture"), mti, availableTypes);
if (EditorGUI.EndChangeCheck())
{
prefs.mapType = prefs.mapType.provider.types[mti];
prefs.mapTypeID = prefs.mapType.fullID;
}
}
TextureProviderExtraFields();
TextureProviderHelp();
}
private static void TextureProviderExtraFields()
{
RealWorldTerrainTextureProviderManager.IExtraField[] extraFields = prefs.mapType.extraFields;
if (extraFields != null)
{
foreach (RealWorldTerrainTextureProviderManager.IExtraField field in extraFields)
{
if (field is RealWorldTerrainTextureProviderManager.ToggleExtraGroup) TextureProviderToggleExtraGroup(field as RealWorldTerrainTextureProviderManager.ToggleExtraGroup);
else if (field is RealWorldTerrainTextureProviderManager.ExtraField) TextureProviderExtraField(field as RealWorldTerrainTextureProviderManager.ExtraField);
}
}
extraFields = prefs.mapType.provider.extraFields;
if (extraFields != null)
{
foreach (RealWorldTerrainTextureProviderManager.IExtraField field in extraFields)
{
if (field is RealWorldTerrainTextureProviderManager.ToggleExtraGroup) TextureProviderToggleExtraGroup(field as RealWorldTerrainTextureProviderManager.ToggleExtraGroup);
else if (field is RealWorldTerrainTextureProviderManager.ExtraField) TextureProviderExtraField(field as RealWorldTerrainTextureProviderManager.ExtraField);
}
}
}
private static void TextureProviderExtraField(RealWorldTerrainTextureProviderManager.ExtraField field)
{
field.value = EditorGUILayout.TextField(field.title, field.value);
}
private static void TextureProviderHelp()
{
string[] help = prefs.mapType.help;
if (help != null)
{
foreach (string field in help)
{
EditorGUILayout.HelpBox(field, MessageType.Info);
}
}
help = prefs.mapType.provider.help;
if (help != null)
{
foreach (string field in help)
{
EditorGUILayout.HelpBox(field, MessageType.Info);
}
}
}
private static void TextureProviderToggleExtraGroup(RealWorldTerrainTextureProviderManager.ToggleExtraGroup @group)
{
@group.value = EditorGUILayout.Toggle(@group.title, @group.value);
EditorGUI.BeginDisabledGroup(@group.value);
if (@group.fields != null)
{
foreach (RealWorldTerrainTextureProviderManager.IExtraField field in @group.fields)
{
if (field is RealWorldTerrainTextureProviderManager.ToggleExtraGroup) TextureProviderToggleExtraGroup(field as RealWorldTerrainTextureProviderManager.ToggleExtraGroup);
else if (field is RealWorldTerrainTextureProviderManager.ExtraField) TextureProviderExtraField(field as RealWorldTerrainTextureProviderManager.ExtraField);
}
}
EditorGUI.EndDisabledGroup();
}
private static void TextureProviderUI()
{
EditorGUI.BeginChangeCheck();
providerIndex = Popup("Provider", providerIndex, providersTitle, "Source of tiles for generating texture.");
if (EditorGUI.EndChangeCheck())
{
prefs.mapType = providers[providerIndex].types[0];
prefs.mapTypeID = prefs.mapType.fullID;
}
if (prefs.mapType.isCustom)
{
prefs.textureProviderURL = EditorGUILayout.TextField(prefs.textureProviderURL);
EditorGUILayout.BeginVertical(GUI.skin.box);
showCustomProviderTokens = Foldout(showCustomProviderTokens, "Available tokens");
if (showCustomProviderTokens)
{
GUILayout.Label("{zoom}");
GUILayout.Label("{x}");
GUILayout.Label("{y}");
GUILayout.Label("{quad}");
GUILayout.Space(10);
}
EditorGUILayout.EndVertical();
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f2af5474c91bbe340bfb60ba389fdc6c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,100 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using System.IO;
using System.Text;
using System.Xml;
using InfinityCode.RealWorldTerrain.Editors;
using InfinityCode.RealWorldTerrain.Windows;
using UnityEditor;
using UnityEngine;
namespace InfinityCode.RealWorldTerrain
{
public static partial class RealWorldTerrainWindowUI
{
private static void ToolbarUI()
{
GUIStyle buttonStyle = new GUIStyle(EditorStyles.toolbarButton);
GUILayout.BeginHorizontal();
ToolbarFileUI(buttonStyle);
if (GUILayout.Button("History", buttonStyle, GUILayout.ExpandWidth(false)))
{
RealWorldTerrainHistoryWindow.OpenWindow();
}
ToolbarUpdateUI(buttonStyle);
if (GUILayout.Button("Settings", buttonStyle, GUILayout.ExpandWidth(false))) RealWorldTerrainSettingsWindow.OpenWindow();
ToolbarHelpUI(buttonStyle);
GUILayout.EndHorizontal();
EditorGUILayout.Space();
}
private static void ToolbarFileUI(GUIStyle buttonStyle)
{
if (GUILayout.Button("File", buttonStyle, GUILayout.ExpandWidth(false)))
{
GenericMenu menu = new GenericMenu();
menu.AddItem(new GUIContent("Import Prefs"), false, () =>
{
string filename = EditorUtility.OpenFilePanel("Import Prefs", Application.dataPath, "xml");
if (!string.IsNullOrEmpty(filename)) prefs.LoadFromXML(filename);
});
menu.AddItem(new GUIContent("Export Prefs"), false, () =>
{
string filename = EditorUtility.SaveFilePanel("Import Prefs", Application.dataPath, "Prefs", "xml");
if (!string.IsNullOrEmpty(filename)) File.WriteAllText(filename, prefs.ToXML(new XmlDocument()).OuterXml, Encoding.UTF8);
});
menu.ShowAsContext();
}
}
private static void ToolbarHelpUI(GUIStyle buttonStyle)
{
if (GUILayout.Button("Help", buttonStyle, GUILayout.ExpandWidth(false)))
{
GenericMenu menu = new GenericMenu();
menu.AddItem(new GUIContent("Documentation"), false, RealWorldTerrainLinks.OpenLocalDocumentation);
menu.AddItem(new GUIContent("Changelog"), false, RealWorldTerrainLinks.OpenChangelog);
menu.AddSeparator("");
menu.AddItem(new GUIContent("Asset Store"), false, RealWorldTerrainLinks.OpenAssetStore);
menu.AddItem(new GUIContent("Homepage"), false, RealWorldTerrainLinks.OpenHomepage);
menu.AddItem(new GUIContent("Support"), false, RealWorldTerrainLinks.OpenSupport);
menu.AddItem(new GUIContent("Forum"), false, RealWorldTerrainLinks.OpenForum);
menu.AddItem(new GUIContent("Discord"), false, RealWorldTerrainLinks.OpenDiscord);
menu.AddSeparator("");
menu.AddItem(new GUIContent("Check Updates"), false, RealWorldTerrainUpdaterWindow.OpenWindow);
menu.AddItem(new GUIContent("About"), false, RealWorldTerrainAboutWindow.OpenWindow);
menu.ShowAsContext();
}
}
private static void ToolbarUpdateUI(GUIStyle buttonStyle)
{
if (!RealWorldTerrainUpdaterWindow.hasNewVersion)
{
GUILayout.Label("", buttonStyle);
return;
}
Color defColor = GUI.backgroundColor;
GUI.backgroundColor = new Color(1, 0.5f, 0.5f);
if (GUILayout.Button("New version available!!! Click here to update.", buttonStyle))
{
wnd.Close();
RealWorldTerrainUpdaterWindow.OpenWindow();
}
GUI.backgroundColor = defColor;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6c295bc603ee4e545b6c21c00fa1faa7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,99 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace InfinityCode.RealWorldTerrain
{
public static partial class RealWorldTerrainWindowUI
{
private static List<string> availableTreeType;
private static void StandardTreeEngineFields()
{
prefs.treeDensity = EditorGUILayout.IntField("Density (%)", prefs.treeDensity);
if (prefs.treeDensity < 1) prefs.treeDensity = 1;
if (prefs.treePrefabs == null) prefs.treePrefabs = new List<GameObject>();
EditorGUILayout.LabelField("Tree Prefabs");
for (int i = 0; i < prefs.treePrefabs.Count; i++)
{
prefs.treePrefabs[i] =
(GameObject)
EditorGUILayout.ObjectField(i + 1 + ":", prefs.treePrefabs[i], typeof(GameObject), false);
}
GameObject newTree =
(GameObject)
EditorGUILayout.ObjectField(prefs.treePrefabs.Count + 1 + ":", null, typeof(GameObject), false);
if (newTree != null) prefs.treePrefabs.Add(newTree);
prefs.treePrefabs.RemoveAll(go => go == null);
}
private static void VegetationStudioTreeEngineFields()
{
#if VEGETATION_STUDIO || VEGETATION_STUDIO_PRO
#if !VEGETATION_STUDIO_PRO
prefs.vegetationStudioPackage = EditorGUILayout.ObjectField("Package", prefs.vegetationStudioPackage, typeof(AwesomeTechnologies.VegetationPackage), false) as AwesomeTechnologies.VegetationPackage;
#else
prefs.vegetationStudioPackage = EditorGUILayout.ObjectField("Package", prefs.vegetationStudioPackage, typeof(AwesomeTechnologies.VegetationSystem.VegetationPackagePro), false) as AwesomeTechnologies.VegetationSystem.VegetationPackagePro;
#endif
if (prefs.vegetationStudioTreeTypes == null) prefs.vegetationStudioTreeTypes = new List<int>{1};
int removeIndex = -1;
for (int i = 0; i < prefs.vegetationStudioTreeTypes.Count; i++)
{
EditorGUILayout.BeginHorizontal();
prefs.vegetationStudioTreeTypes[i] = EditorGUILayout.IntSlider("Vegetation Type " + (i + 1) + ": ", prefs.vegetationStudioTreeTypes[i], 1, 32);
if (prefs.vegetationStudioTreeTypes.Count > 1 && GUILayout.Button("X", GUILayout.ExpandWidth(false))) removeIndex = i;
EditorGUILayout.EndHorizontal();
}
if (removeIndex != -1) prefs.vegetationStudioTreeTypes.RemoveAt(removeIndex);
if (GUILayout.Button("Add item")) prefs.vegetationStudioTreeTypes.Add(1);
#endif
}
private static void InitTreeEngines()
{
availableTreeType = new List<string>();
availableTreeType.Add("Standard");
#if VEGETATION_STUDIO || VEGETATION_STUDIO_PRO
availableTreeType.Add("Vegetation Studio");
#endif
}
private static void SelectTreeEngine()
{
if (availableTreeType.Count > 1)
{
int treeEngineIndex = availableTreeType.IndexOf(prefs.treeEngine);
if (treeEngineIndex == -1) treeEngineIndex = 0;
treeEngineIndex = EditorGUILayout.Popup("Tree engine ", treeEngineIndex, availableTreeType.ToArray());
prefs.treeEngine = availableTreeType[treeEngineIndex];
}
else prefs.treeEngine = availableTreeType[0];
}
private static void TreesUI()
{
EditorGUILayout.BeginVertical(GUI.skin.box);
prefs.generateTrees = EditorGUILayout.Toggle("Generate trees", prefs.generateTrees);
if (!prefs.generateTrees)
{
EditorGUILayout.EndVertical();
return;
}
SelectTreeEngine();
if (prefs.treeEngine == "Standard") StandardTreeEngineFields();
else if (prefs.treeEngine == "Vegetation Studio") VegetationStudioTreeEngineFields();
EditorGUILayout.Space();
EditorGUILayout.EndVertical();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3da84962a2c31344baf3ec8849e2b863
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,362 @@
/* INFINITY CODE */
/* https://infinity-code.com */
using System;
using System.Diagnostics;
using InfinityCode.RealWorldTerrain.Net;
using InfinityCode.RealWorldTerrain.Phases;
using InfinityCode.RealWorldTerrain.Windows;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
namespace InfinityCode.RealWorldTerrain
{
public static partial class RealWorldTerrainWindowUI
{
private const int LabelWidth = 170;
public static int iProgress;
public static string phasetitle = "";
private static GUIStyle _oddStyle;
private static GUIStyle _evenStyle;
private static string mapboxAPI;
private static Vector2 scrollPos = Vector2.zero;
private static readonly string[] labels2n = { "32", "64", "128", "256", "512", "1024", "2048", "4096" };
private static readonly int[] values2n = { 32, 64, 128, 256, 512, 1024, 2048, 4096 };
private static readonly string[] labels2n1 = { "33", "65", "129", "257", "513", "1025", "2049", "4097" };
private static readonly int[] values2n1 = { 33, 65, 129, 257, 513, 1025, 2049, 4097 };
public static GUIStyle evenStyle
{
get
{
if (_evenStyle == null) _evenStyle = new GUIStyle();
return _evenStyle;
}
}
public static GUIStyle oddStyle
{
get
{
if (_oddStyle == null)
{
_oddStyle = new GUIStyle();
_oddStyle.normal.background = new Texture2D(1, 1);
_oddStyle.normal.background.SetPixel(0, 0, new Color(0.5f, 0.5f, 0.5f, 0.2f));
_oddStyle.normal.background.Apply();
}
return _oddStyle;
}
}
public static RealWorldTerrainGenerateType generateType
{
get { return RealWorldTerrainWindow.generateType; }
}
private static RealWorldTerrainPhase phase
{
get { return RealWorldTerrainPhase.activePhase; }
}
private static RealWorldTerrainPrefs prefs
{
get { return RealWorldTerrainWindow.prefs; }
}
private static RealWorldTerrainWindow wnd
{
get { return RealWorldTerrainWindow.wnd; }
}
public static double DoubleField(string label, double value, string tooltip, string href = "")
{
GUILayout.BeginHorizontal();
value = EditorGUILayout.DoubleField(label, value);
if (GUILayout.Button(new GUIContent(RealWorldTerrainResources.helpIcon, tooltip),
RealWorldTerrainResources.helpStyle, GUILayout.ExpandWidth(false)))
{
if (href != "") Application.OpenURL(href);
}
GUILayout.EndHorizontal();
return value;
}
public static void DrawHelpButton(string tooltip = null, string href = null)
{
if (string.IsNullOrEmpty(tooltip)) return;
GUIContent content = new GUIContent(RealWorldTerrainResources.helpIcon, tooltip);
if (GUILayout.Button(content, RealWorldTerrainResources.helpStyle, GUILayout.ExpandWidth(false))
&& !string.IsNullOrEmpty(href))
{
Application.OpenURL(href);
}
}
public static System.Enum EnumPopup(string label, System.Enum selected, string tooltip, string href = "")
{
GUILayout.BeginHorizontal();
Enum res = EditorGUILayout.EnumPopup(label, selected);
DrawHelpButton(tooltip, href);
GUILayout.EndHorizontal();
return res;
}
public static float FloatField(string label, float value, string tooltip, string href = "")
{
GUILayout.BeginHorizontal();
value = EditorGUILayout.FloatField(label, value);
DrawHelpButton(tooltip, href);
GUILayout.EndHorizontal();
return value;
}
public static bool Foldout(bool value, string text)
{
return GUILayout.Toggle(value, text, EditorStyles.foldout);
}
public static int IntPopup(string label, int value, string[] displayedOptions, int[] optionValues, string tooltip, string href)
{
GUILayout.BeginHorizontal();
value = EditorGUILayout.IntPopup(label, value, displayedOptions, optionValues);
DrawHelpButton(tooltip, href);
GUILayout.EndHorizontal();
return value;
}
public static int IntPopup(string label, int value, string[] displayedOptions, int[] optionValues, string tooltip, string[] hrefs)
{
GUILayout.BeginHorizontal();
value = EditorGUILayout.IntPopup(label, value, displayedOptions, optionValues);
string href = null;
if (hrefs != null && hrefs.Length > value) href = hrefs[value];
DrawHelpButton(tooltip, href);
GUILayout.EndHorizontal();
return value;
}
public static int IntField(string label, int value, string tooltip, string href = null)
{
GUILayout.BeginHorizontal();
value = EditorGUILayout.IntField(label, value);
DrawHelpButton(tooltip, href);
GUILayout.EndHorizontal();
return value;
}
private static void MapboxAccessToken()
{
if (mapboxAPI == null) mapboxAPI = RealWorldTerrainPrefs.LoadPref("MapboxAPI", "");
GUILayout.BeginHorizontal();
EditorGUI.BeginChangeCheck();
mapboxAPI = EditorGUILayout.TextField("Mapbox Access Token", mapboxAPI);
if (EditorGUI.EndChangeCheck())
{
if (mapboxAPI == "") RealWorldTerrainPrefs.DeletePref("MapboxAPI");
else RealWorldTerrainPrefs.SetPref("MapboxAPI", mapboxAPI);
}
if (string.IsNullOrEmpty(mapboxAPI))
{
GUILayout.Box(new GUIContent(RealWorldTerrainResources.warningIcon, "Required"), RealWorldTerrainResources.helpStyle, GUILayout.ExpandWidth(false));
}
GUILayout.EndHorizontal();
if (GUILayout.Button("Get Mapbox Access Token")) Process.Start("https://www.mapbox.com/studio/account/tokens/");
}
public static void OnEnable()
{
InitTextureProviders();
InitBuildingEngines();
InitRoadEngines();
InitGrassEngines();
InitTreeEngines();
InitRiverEngines();
}
public static void OnGUI()
{
if (!RealWorldTerrainWindow.isCapturing) OnIdleGUI();
else OnGenerate();
}
private static void OnGenerate()
{
if (phase != null && phase is RealWorldTerrainDownloadingPhase)
{
int completed = Mathf.FloorToInt(RealWorldTerrainDownloadManager.totalSizeMB * RealWorldTerrainWindow.progress);
GUILayout.Label(phasetitle + " (" + completed + " of " + RealWorldTerrainDownloadManager.totalSizeMB + " mb)");
}
else GUILayout.Label(phasetitle);
Rect r = EditorGUILayout.BeginVertical();
iProgress = Mathf.FloorToInt(RealWorldTerrainWindow.progress * 100);
EditorGUI.ProgressBar(r, RealWorldTerrainWindow.progress, iProgress + "%");
GUILayout.Space(16);
EditorGUILayout.EndVertical();
if (GUILayout.Button("Cancel")) RealWorldTerrainWindow.CancelCapture();
GUILayout.Label("Warning: Keep this window open.");
}
private static void OnIdleButtons()
{
GUILayout.BeginHorizontal();
if (GUILayout.Button("Start")) RealWorldTerrainWindow.StartCapture();
if (RealWorldTerrainWindow.generateType == RealWorldTerrainGenerateType.full)
{
if (GUILayout.Button("Memory Usage", GUILayout.ExpandWidth(false))) RealWorldTerrainMemoryUsageWindow.OpenWindow();
}
else
{
if (GUILayout.Button("Switch to Full", GUILayout.ExpandWidth(false)))
{
RealWorldTerrainWindow.generateType = RealWorldTerrainGenerateType.full;
RealWorldTerrainWindow.generateTarget = null;
}
}
if (GUILayout.Button("Clear Cache", GUILayout.ExpandWidth(false))) RealWorldTerrainWindow.ClearCache();
GUILayout.EndHorizontal();
}
private static void OnIdleGUI()
{
ToolbarUI();
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
EditorGUIUtility.labelWidth = LabelWidth;
bool isFull = RealWorldTerrainWindow.generateType == RealWorldTerrainGenerateType.full;
bool isTerrain = isFull || RealWorldTerrainWindow.generateType == RealWorldTerrainGenerateType.terrain;
bool isTexture = isFull || RealWorldTerrainWindow.generateType == RealWorldTerrainGenerateType.texture;
bool isAdditional = isFull || RealWorldTerrainWindow.generateType == RealWorldTerrainGenerateType.additional;
bool isRawOutput = prefs.resultType == RealWorldTerrainResultType.gaiaStamp || prefs.resultType == RealWorldTerrainResultType.rawFile;
if (isFull) AreaUI();
if (isTerrain)
{
EditorGUILayout.BeginVertical(GUI.skin.box);
showTerrains = EditorGUILayout.Foldout(showTerrains, "Terrains");
if (showTerrains) TerrainUI();
EditorGUILayout.EndVertical();
ElevationProviderUI();
}
if (isTexture && !isRawOutput)
{
if (isFull)
{
EditorGUILayout.BeginVertical(GUI.skin.box);
EditorGUILayout.BeginHorizontal();
if (prefs.generateTextures) showTextures = GUILayout.Toggle(showTextures, "", EditorStyles.foldout, GUILayout.ExpandWidth(false));
prefs.generateTextures = GUILayout.Toggle(prefs.generateTextures, "Textures");
EditorGUILayout.EndHorizontal();
if (showTextures && prefs.generateTextures) TextureUI();
EditorGUILayout.EndVertical();
}
else
{
EditorGUILayout.BeginVertical(GUI.skin.box);
EditorGUILayout.LabelField("Textures");
prefs.generateTextures = true;
TextureUI();
EditorGUILayout.EndVertical();
}
}
if (isFull && !isRawOutput)
{
EditorGUILayout.BeginVertical(GUI.skin.box);
EditorGUILayout.BeginHorizontal();
showPOI = EditorGUILayout.Foldout(showPOI, "POI");
DrawHelpButton("Here you can specify a point of interest, which will be created on the terrains.");
EditorGUILayout.EndHorizontal();
if (showPOI) PoiUI();
EditorGUILayout.EndVertical();
}
if (isAdditional && !isRawOutput) OsmUI();
GUILayout.EndScrollView();
OnIdleButtons();
}
public static Object ObjectField(string label, Object obj, Type type, string tooltip = null, string href = null)
{
EditorGUILayout.BeginHorizontal();
obj = EditorGUILayout.ObjectField(label, obj, type, false);
DrawHelpButton(tooltip, href);
EditorGUILayout.EndHorizontal();
return obj;
}
private static int Popup(string label, int selectedIndex, string[] displayedOptions, string tooltip = null, string href = null)
{
EditorGUILayout.BeginHorizontal();
int res = EditorGUILayout.Popup(label, selectedIndex, displayedOptions);
DrawHelpButton(tooltip, href);
EditorGUILayout.EndHorizontal();
return res;
}
private static bool Toggle(bool value, string text, string tooltip = null, string href = null)
{
return Toggle(value, text, true, tooltip, href);
}
private static bool Toggle(string text, bool value, bool left, string tooltip = null, string href = null)
{
return Toggle(value, text, left, tooltip, href);
}
private static bool Toggle(bool value, string text, bool left, string tooltip = null, string href = null)
{
EditorGUILayout.BeginHorizontal();
if (left) value = GUILayout.Toggle(value, text);
else value = EditorGUILayout.Toggle(text, value);
DrawHelpButton(tooltip, href);
EditorGUILayout.EndHorizontal();
return value;
}
private static Vector3 Vector3Field(string label, Vector3 value, string tooltip = null, string href = null)
{
EditorGUILayout.BeginHorizontal();
Vector3 res = EditorGUILayout.Vector3Field(label, value);
DrawHelpButton(tooltip, href);
EditorGUILayout.EndHorizontal();
return res;
}
private static void MinMaxSlider(string label, ref float minValue, ref float maxValue, int minLimit, int maxLimit, string tooltip = null, string href = null)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.MinMaxSlider(label, ref minValue, ref maxValue, minLimit, maxLimit);
DrawHelpButton(tooltip, href);
EditorGUILayout.EndHorizontal();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 01806f7a456c6f44b8d61036ece4952c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: