Initial commit

This commit is contained in:
gunnbr committed 2021-01-11 22:20:43 -08:00
1 parent ee9615239e
commit 16feac691f
4093 files changed
+1030491

No files matched your search

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d08bfda1add410042ac41353ecc7e799
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,396 @@
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.SceneManagement;
using static Gaia.GaiaConstants;
#if !GAIA_PRO_PRESENT
namespace Gaia
{
//public enum CurrentlyViewing { Unknown, Terrain, WorldMap }
[InitializeOnLoad]
class Gaia2TopPanel
{
static Gaia2TopPanel()
{
SceneView.duringSceneGui -= RenderSceneGUI;
SceneView.duringSceneGui += RenderSceneGUI;
m_lastActiveScene = SceneManager.GetActiveScene();
CheckForSessionManager();
}
private static void CheckForSessionManager()
{
if (SessionManager != null)
{
m_sessionManagerExits = true;
}
else
{
m_sessionManagerExits = false;
}
}
public static bool m_sessionManagerExits = false;
private static Scene m_lastActiveScene;
private static GUIStyle GUIStylePanel;
private static GUIStyle GUIStyleHeader;
private static GaiaSessionManager m_sessionManager;
private static Vector2 m_terrainOpScrollPos;
//private static EditorUtils m_editorUtils;
private static GaiaSessionManager SessionManager {
get {
if (m_sessionManager == null)
{
m_sessionManager = GaiaSessionManager.GetSessionManager(false,false);
if (m_sessionManager == null)
{
m_sessionManagerExits = false;
}
}
return m_sessionManager;
}
}
private static GaiaSettings m_gaiaSettings;
private static GaiaSettings GaiaSettings
{
get
{
if (m_gaiaSettings == null)
{
m_gaiaSettings = GaiaUtils.GetGaiaSettings();
}
return m_gaiaSettings;
}
}
private static Terrain m_worldMapTerrain;
private static Terrain WorldMapTerrain
{
get
{
if (m_worldMapTerrain == null)
{
m_worldMapTerrain = TerrainHelper.GetWorldMapTerrain();
}
return m_worldMapTerrain;
}
}
public static void RenderSceneGUI(SceneView sceneview)
{
if (m_lastActiveScene != SceneManager.GetActiveScene())
{
CheckForSessionManager();
m_lastActiveScene = SceneManager.GetActiveScene();
}
if (!m_sessionManagerExits)
{
return;
}
if (SessionManager == null)
{
return;
}
if (GUIStyleHeader == null)
{
GUIStyleHeader = new GUIStyle(GUI.skin.label);
GUIStyleHeader.alignment = TextAnchor.MiddleCenter;
GUIStyleHeader.fontStyle = FontStyle.Bold;
}
if (GUIStylePanel == null)
{
GUIStylePanel = new GUIStyle();
GUIStylePanel.padding = new RectOffset(0, 0, 0, 0);
GUIStylePanel.margin = new RectOffset(0, 0, 0, 0);
GUIStylePanel.alignment = TextAnchor.MiddleCenter;
GUIStylePanel.border = new RectOffset(2, 2, 2, 2);
GUIStylePanel.imagePosition = ImagePosition.ImageOnly;
if (EditorGUIUtility.isProSkin)
{
GUIStylePanel.normal.background = GaiaSettings.m_originUIProBackgroundPro;
GUIStylePanel.normal.textColor = Color.white;
}
else
{
GUIStylePanel.normal.background = GaiaSettings.m_originUIBackground;
GUIStylePanel.normal.textColor = Color.black;
}
}
Handles.BeginGUI();
if (TerrainLoaderManager.Instance.TerrainSceneStorage.m_hasWorldMap)
{
DrawTopPanel();
}
Handles.EndGUI();
}
private static void DrawTopPanel()
{
bool currentGUIState = GUI.enabled;
float dpiScalingFactor = (96 / Screen.dpi);
float scaledScreenWidth = (Camera.current.pixelRect.size.x * dpiScalingFactor);
float scaledScreenHeight = (Camera.current.pixelRect.size.y * dpiScalingFactor);
float sizeX = GaiaSettings.m_gaiaPanelSizeType == PositionType.Relative ? scaledScreenWidth * GaiaSettings.m_gaiaPanelSize.x / 100f : GaiaSettings.m_gaiaPanelSize.x;
float sizeY = GaiaSettings.m_gaiaPanelSizeType == PositionType.Relative ? scaledScreenHeight * GaiaSettings.m_gaiaPanelSize.y / 100f : GaiaSettings.m_gaiaPanelSize.y;
float x = GaiaSettings.m_gaiaPanelPositionType == PositionType.Relative ? (scaledScreenWidth * GaiaSettings.m_gaiaPanelPosition.x / 100f) - (sizeX + 50f) / 2f : GaiaSettings.m_gaiaPanelPosition.x;
float y = GaiaSettings.m_gaiaPanelPositionType == PositionType.Relative ? (scaledScreenHeight * GaiaSettings.m_gaiaPanelPosition.y / 100f) : GaiaSettings.m_gaiaPanelPosition.y;
GUILayout.BeginArea(new Rect(x, y, sizeX+50, sizeY));
float leftSpace = 6f;
EditorGUI.BeginChangeCheck();
EditorGUILayout.BeginHorizontal();
{
GUILayout.FlexibleSpace();
EditorGUILayout.BeginVertical(GUIStylePanel, GUILayout.MaxWidth(sizeX));
{
EditorGUILayout.BeginHorizontal();
{
GUILayout.Space(leftSpace);
if (GUILayout.Button("Manager", GUILayout.Height(15), GUILayout.Width(70)))
{
var manager = EditorWindow.GetWindow<Gaia.GaiaManagerEditor>(false, "Gaia Manager");
//Manager can be null if the dependency package installation is started upon opening the manager window.
if (manager != null)
{
Vector2 initialSize = new Vector2(650f, 450f);
manager.position = new Rect(new Vector2(Screen.currentResolution.width / 2f - initialSize.x / 2f, Screen.currentResolution.height / 2f - initialSize.y / 2f), initialSize);
manager.Show();
}
}
if (TerrainLoaderManager.Instance.TerrainSceneStorage.m_hasWorldMap)
{
GUILayout.Label("Gaia", GUIStyleHeader, GUILayout.MaxHeight(16));
if (WorldMapTerrain != null)
{
if (!GaiaUtils.HasTerrains())
{
GUI.enabled = false;
}
if (GUILayout.Button("Terrain", GUILayout.Height(15), GUILayout.Width(75)))
{
TerrainLoaderManager.Instance.SwitchToLocalMap();
}
GUI.enabled = currentGUIState;
if (GUILayout.Button("Designer", GUILayout.Height(15), GUILayout.Width(75)))
{
TerrainLoaderManager.Instance.SwitchToWorldMap();
}
}
else
{
//GUILayout.Space(200);
}
}
else
{
GUILayout.Space(-50);
GUILayout.Label("Gaia", GUIStyleHeader, GUILayout.MaxHeight(16));
if (!TerrainLoaderManager.Instance.ShowLocalTerrain)
{
TerrainLoaderManager.Instance.SwitchToLocalMap();
}
}
}
EditorGUILayout.EndHorizontal();
#if GAIA_PRO_PRESENT
if (SessionManager.m_showSceneViewPanel)
{
EditorGUILayout.BeginHorizontal();
{
GUILayout.Label("Go To Terrain:", GUILayout.Width(100));
GUILayout.Label("X", GUILayout.Width(coordLabelWidth));
GaiaTerrainLoaderManager.Instance.m_originTargetTileX = EditorGUILayout.DelayedIntField(GaiaTerrainLoaderManager.Instance.m_originTargetTileX, GUILayout.Width(coordInputWidth));
GUILayout.Space(84);
GUILayout.Label("Z", GUILayout.Width(coordLabelWidth));
GaiaTerrainLoaderManager.Instance.m_originTargetTileZ = EditorGUILayout.DelayedIntField(GaiaTerrainLoaderManager.Instance.m_originTargetTileZ, GUILayout.Width(coordInputWidth));
if (GUILayout.Button("Go", GUILayout.Height(15), GUILayout.Width(52)))
{
GaiaTerrainLoaderManager.Instance.SetOriginByTargetTile();
range = GaiaTerrainLoaderManager.Instance.GetLoadingRange();
currentPos = GaiaTerrainLoaderManager.Instance.GetOrigin();
}
GUILayout.FlexibleSpace();
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
{
GUILayout.Label("Selected:", GUILayout.Width(100));
if (Selection.activeObject != null)
{
if (Selection.activeObject.GetType() == typeof(GameObject))
{
GameObject selectedObject = (GameObject)Selection.activeObject;
if (selectedObject.scene != null)
{
GUILayout.Label("X", GUILayout.Width(coordLabelWidth));
GUILayout.Label((selectedObject.transform.position.x + currentPos.x).ToString(), GUILayout.Width(coordInputWidth));
GUILayout.FlexibleSpace();
GUILayout.Label("Y", GUILayout.Width(coordLabelWidth));
GUILayout.Label((selectedObject.transform.position.y + currentPos.y).ToString(), GUILayout.Width(coordInputWidth));
GUILayout.FlexibleSpace();
GUILayout.Label("Z", GUILayout.Width(coordLabelWidth));
GUILayout.Label((selectedObject.transform.position.z + currentPos.z).ToString(), GUILayout.Width(coordInputWidth));
GUI.enabled = !Application.isPlaying;
if (GUILayout.Button("Center", GUILayout.Height(15)))
{
currentPos = new Vector3Double(selectedObject.transform.position.x + currentPos.x, selectedObject.transform.position.y + currentPos.y, selectedObject.transform.position.z + currentPos.z);
bool needsShift = true;
//Check if we should shift the selected object around as well
if (selectedObject.scene != SessionManager.gameObject.scene)
{
//in a separate scene from session manager -> should be shifted automatically
needsShift = false;
}
if (needsShift && selectedObject.transform.GetComponentInParent<Terrain>() != null)
{
//child of a terrain -> should be shifted automatically
needsShift = false;
}
if (needsShift && selectedObject.transform.GetComponentInParent<FloatingPointFixMember>() != null)
{
//is child of a floating point fix member -> should be shifted automatically
needsShift = false;
}
if (needsShift)
{
//still needs to be shifted -> ask the user if they wish to add a floating point fix
if (EditorUtility.DisplayDialog("Shift centered object?", "You are about to center on an object that does not seem to be set up to be shifted together with the world origin. Do you want to add a Floating Point Fix Member component on this object so that it will be shifted with the world, or do you want the object not to be affected by the shift?", "Add component", "Leave object in place"))
{
selectedObject.AddComponent<FloatingPointFixMember>();
}
}
}
GUI.enabled = currentGUIState;
}
}
}
GUILayout.FlexibleSpace();
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
{
GUI.enabled = !Application.isPlaying;
GUILayout.Label("Origin:", GUILayout.Width(100));
GUILayout.Label("X", GUILayout.Width(coordLabelWidth));
currentPos.x = EditorGUILayout.DelayedDoubleField(currentPos.x, GUILayout.Width(coordInputWidth));
GUILayout.FlexibleSpace();
GUILayout.Label("Y", GUILayout.Width(coordLabelWidth));
currentPos.y = EditorGUILayout.DelayedDoubleField(currentPos.y, GUILayout.Width(coordInputWidth));
GUILayout.FlexibleSpace();
GUILayout.Label("Z", GUILayout.Width(coordLabelWidth));
currentPos.z = EditorGUILayout.DelayedDoubleField(currentPos.z, GUILayout.Width(coordInputWidth));
GUILayout.Space(56);
GUI.enabled = currentGUIState;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
GUI.enabled = !Application.isPlaying;
{
GUILayout.Label("Loading Range:", GUILayout.Width(115));
range = EditorGUILayout.DelayedDoubleField(range, GUILayout.Width(60));
GUILayout.Space(25);
SessionManager.m_showOriginLoadingBounds = EditorGUILayout.Toggle("Show Loading Range", SessionManager.m_showOriginLoadingBounds);
}
GUI.enabled = currentGUIState;
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
{
if (GUILayout.Button("Show Loader Manager...", GUILayout.Height(15), GUILayout.Width(180)))
{
GameObject loaderObj = GaiaUtils.GetTerrainLoaderManagerObject();
Selection.activeObject = loaderObj;
}
GUILayout.Space(25);
SessionManager.m_showOriginTerrainBoxes = EditorGUILayout.Toggle("Show Terrain Boxes", SessionManager.m_showOriginTerrainBoxes);
}
EditorGUILayout.EndHorizontal();
}
//else
//{
// GUILayout.Space(Camera.current.pixelRect.size.x / 2f + 188);
//}
}
EditorGUILayout.EndVertical();
GUIContent buttonContent = null;
if (EditorGUIUtility.isProSkin)
{
if (SessionManager.m_showSceneViewPanel)
{
buttonContent = new GUIContent(GaiaSettings.m_originUIProUnfoldUp, "Hide Gaia Panel");
}
else
{
buttonContent = new GUIContent(GaiaSettings.m_originUIProUnfoldDown, "Show Gaia Panel");
}
}
else
{
if (SessionManager.m_showSceneViewPanel)
{
buttonContent = new GUIContent(GaiaSettings.m_originUIUnfoldUp, "Hide Gaia Panel");
}
else
{
buttonContent = new GUIContent(GaiaSettings.m_originUIUnfoldDown, "Show Gaia Panel");
}
}
if (GUILayout.Button(new GUIContent(buttonContent), GUIStylePanel, GUILayout.Width(20), GUILayout.Height(20)))
{
SessionManager.m_showSceneViewPanel = !SessionManager.m_showSceneViewPanel;
}
GUILayout.FlexibleSpace();
}
EditorGUILayout.EndHorizontal();
#else
}
EditorGUILayout.EndVertical();
}
EditorGUILayout.EndHorizontal();
#endif
GUILayout.EndArea();
}
}
}
#endif
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d713f54456bdd6044823775fb6fa6be7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,588 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using PWCommon4;
using Gaia.Internal;
using System;
using System.Linq;
using UnityEditor.SceneManagement;
using UnityEngine.SceneManagement;
using UnityEngine.Profiling;
namespace Gaia
{
[CustomEditor(typeof(TerrainLoaderManager))]
public class TerrainLoaderManagerEditor : PWEditor, IPWEditor
{
private TerrainLoaderManager m_terrainLoaderManager;
#if GAIA_PRO_PRESENT
private TerrainLoader[] m_terrainLoaders;
#endif
private EditorUtils m_editorUtils;
private GUIStyle m_terrainBoxStyle;
private Terrain m_ingestTerrain;
private static List<Texture2D> m_tempTextureList = new List<Texture2D>();
private GUIStyle redStyle;
private GUIStyle greenStyle;
public void OnEnable()
{
m_terrainLoaderManager = (TerrainLoaderManager)target;
#if GAIA_PRO_PRESENT
m_terrainLoaders = Resources.FindObjectsOfTypeAll<TerrainLoader>();
#endif
//m_placeHolders = Resources.FindObjectsOfTypeAll<GaiaTerrainPlaceHolder>();
//m_placeHolders = m_placeHolders.OrderBy(x => x.name).ToArray();
//foreach (GaiaTerrainPlaceHolder placeHolder in m_placeHolders)
//{
// placeHolder.UpdateLoadState();
//}
//Init editor utils
if (m_editorUtils == null)
{
// Get editor utils for this
m_editorUtils = PWApp.GetEditorUtils(this);
}
m_terrainLoaderManager.LookUpLoadingScreen();
}
private void OnDestroy()
{
for (int i = 0; i < m_tempTextureList.Count; i++)
{
UnityEngine.Object.DestroyImmediate(m_tempTextureList[i]);
}
}
public override void OnInspectorGUI()
{
if (redStyle == null || redStyle.normal.background == null || greenStyle == null || greenStyle.normal.background == null)
{
redStyle = new GUIStyle();
redStyle.normal.background = GaiaUtils.GetBGTexture(Color.red, m_tempTextureList);
greenStyle = new GUIStyle();
greenStyle.normal.background = GaiaUtils.GetBGTexture(Color.green, m_tempTextureList);
}
//Init editor utils
if (m_editorUtils == null)
{
// Get editor utils for this
m_editorUtils = PWApp.GetEditorUtils(this);
}
m_editorUtils.Initialize(); // Do not remove this!
if (GaiaUtils.HasDynamicLoadedTerrains())
{
m_editorUtils.Panel("GeneralSettings", DrawGeneralSettings, true);
m_editorUtils.Panel("LoaderPanel", DrawLoaders, false);
m_editorUtils.Panel("PlaceholderPanel", DrawTerrains, false);
}
else
{
EditorGUILayout.HelpBox(m_editorUtils.GetTextValue("NoTerrainLoadingMessage"),MessageType.Info);
}
}
private void DrawGeneralSettings(bool helpEnabled)
{
m_terrainLoaderManager.TerrainSceneStorage = (TerrainSceneStorage)m_editorUtils.ObjectField("TerrainSceneStorage", m_terrainLoaderManager.TerrainSceneStorage, typeof(TerrainSceneStorage), false, helpEnabled);
bool oldLoadingEnabled = m_terrainLoaderManager.TerrainSceneStorage.m_terrainLoadingEnabled;
m_terrainLoaderManager.TerrainSceneStorage.m_terrainLoadingEnabled = m_editorUtils.Toggle("TerrainLoadingEnabled", m_terrainLoaderManager.TerrainSceneStorage.m_terrainLoadingEnabled, helpEnabled);
if (!oldLoadingEnabled && m_terrainLoaderManager.TerrainSceneStorage.m_terrainLoadingEnabled)
{
//User re-enabled the loaders
m_terrainLoaderManager.UpdateTerrainLoadState();
}
if (oldLoadingEnabled != m_terrainLoaderManager.TerrainSceneStorage.m_terrainLoadingEnabled)
{
//Value was changed, dirty the object to make sure the value is being saved
EditorUtility.SetDirty(m_terrainLoaderManager.TerrainSceneStorage);
}
bool originalGUIState = GUI.enabled;
m_terrainLoaderManager.m_terrainLoadingTresholdMS = m_editorUtils.IntField("LoadingTimeTreshold", m_terrainLoaderManager.m_terrainLoadingTresholdMS, helpEnabled);
m_terrainLoaderManager.m_trackLoadingProgressTimeOut = m_editorUtils.LongField("LoadingProgressTimeout", m_terrainLoaderManager.m_trackLoadingProgressTimeOut, helpEnabled);
GUILayout.Space(10);
m_editorUtils.Heading("SceneViewLoading");
m_terrainLoaderManager.CenterSceneViewLoadingOn = (CenterSceneViewLoadingOn)m_editorUtils.EnumPopup("CenterSceneViewLoadingOn", m_terrainLoaderManager.CenterSceneViewLoadingOn, helpEnabled);
double loadingRange = m_editorUtils.DoubleField("SceneViewLoadingRange", m_terrainLoaderManager.GetLoadingRange(), helpEnabled);
double impostorLoadingRange = m_terrainLoaderManager.GetImpostorLoadingRange();
if (GaiaUtils.HasImpostorTerrains())
{
impostorLoadingRange = m_editorUtils.DoubleField("SceneViewImpostorLoadingRange", m_terrainLoaderManager.GetImpostorLoadingRange(), helpEnabled);
}
else
{
EditorGUILayout.BeginHorizontal();
m_editorUtils.Label("SceneViewImpostorLoadingRange");
//offer button to create impostors setup
if (m_editorUtils.Button("OpenTerrainMeshExporterForImpostors", GUILayout.Width(EditorGUIUtility.currentViewWidth - EditorGUIUtility.labelWidth - 38)))
{
ExportTerrain exportTerrainWindow = EditorWindow.GetWindow<ExportTerrain>();
exportTerrainWindow.FindAndSetPreset("Create Impostors");
exportTerrainWindow.m_settings.m_customSettingsFoldedOut = false;
}
EditorGUILayout.EndHorizontal();
}
if (loadingRange != m_terrainLoaderManager.GetLoadingRange() || impostorLoadingRange != m_terrainLoaderManager.GetImpostorLoadingRange())
{
m_terrainLoaderManager.SetLoadingRange(loadingRange, impostorLoadingRange);
}
GUILayout.Space(10);
m_editorUtils.Heading("CachingSettings");
m_editorUtils.InlineHelp("CachingSettings", helpEnabled);
EditorGUI.BeginChangeCheck();
m_terrainLoaderManager.m_cacheInRuntime = m_editorUtils.Toggle("CacheInRuntime", m_terrainLoaderManager.m_cacheInRuntime, helpEnabled);
m_terrainLoaderManager.m_cacheInEditor = m_editorUtils.Toggle("CacheInEditor", m_terrainLoaderManager.m_cacheInEditor, helpEnabled);
string allocatedMegabytes = (Math.Round(Profiler.GetTotalAllocatedMemoryLong() / Math.Pow(1024, 2))).ToString();
string availableMegabytes = SystemInfo.systemMemorySize.ToString();
allocatedMegabytes = allocatedMegabytes.PadLeft(allocatedMegabytes.Length + (availableMegabytes.Length - allocatedMegabytes.Length) * 3 , ' ');
GUIStyle style = new GUIStyle(GUI.skin.label);
if (m_terrainLoaderManager.m_cacheMemoryThreshold < Profiler.GetTotalAllocatedMemoryLong())
{
style = redStyle;
}
else
{
style = greenStyle;
}
m_editorUtils.LabelField("MemoryAvailable", new GUIContent(availableMegabytes), helpEnabled);
m_editorUtils.LabelField("MemoryAllocated", new GUIContent(allocatedMegabytes), style, helpEnabled);
//GUI.color = originalGUIColor;
if (m_terrainLoaderManager.m_cacheInRuntime || m_terrainLoaderManager.m_cacheInEditor)
{
m_terrainLoaderManager.m_cacheMemoryThresholdPreset = (CacheSizePreset)m_editorUtils.EnumPopup("CacheMemoryThreshold", m_terrainLoaderManager.m_cacheMemoryThresholdPreset, helpEnabled);
if (m_terrainLoaderManager.m_cacheMemoryThresholdPreset == CacheSizePreset.Custom)
{
EditorGUI.indentLevel++;
m_terrainLoaderManager.m_cacheMemoryThreshold = m_editorUtils.LongField("ThresholdInBytes", m_terrainLoaderManager.m_cacheMemoryThreshold, helpEnabled);
EditorGUI.indentLevel--;
}
int cacheKeepAliveSeconds = (int)m_terrainLoaderManager.m_cacheKeepAliveTime / 1000;
cacheKeepAliveSeconds = m_editorUtils.IntField("CacheKeepAliveSeconds", cacheKeepAliveSeconds, helpEnabled);
m_terrainLoaderManager.m_cacheKeepAliveTime = cacheKeepAliveSeconds * 1000;
}
if (EditorGUI.EndChangeCheck())
{
if (m_terrainLoaderManager.m_cacheMemoryThresholdPreset != CacheSizePreset.Custom)
{
m_terrainLoaderManager.m_cacheMemoryThreshold = (long)((int)m_terrainLoaderManager.m_cacheMemoryThresholdPreset * Math.Pow(1024, 3));
}
m_terrainLoaderManager.UpdateCaching();
}
GUILayout.Space(10);
if (!GaiaUtils.HasColliderTerrains())
{
GUI.enabled = false;
}
m_editorUtils.Heading("ColliderOnlyLoadingHeader");
//This flag is special in so far as that when the user switches it, we must first perform a scene unload while the old value is still active
//then change the flag in the terrain scene storage and then do a refresh with the new setting applied.
bool colliderLoadingEnabled = m_terrainLoaderManager.TerrainSceneStorage.m_colliderOnlyLoading;
colliderLoadingEnabled = m_editorUtils.Toggle("ColliderOnlyLoadingEnabled", colliderLoadingEnabled, helpEnabled);
if (colliderLoadingEnabled != m_terrainLoaderManager.TerrainSceneStorage.m_colliderOnlyLoading)
{
//User changed the flag, do an unload with the old setting
m_terrainLoaderManager.UnloadAll(true);
//then change the actual flag in storage
m_terrainLoaderManager.TerrainSceneStorage.m_colliderOnlyLoading = colliderLoadingEnabled;
//now do a refresh under the new setting
m_terrainLoaderManager.RefreshSceneViewLoadingRange();
//Add the required scenes to build settings
if (colliderLoadingEnabled)
{
GaiaSessionManager.AddOnlyColliderScenesToBuildSettings(TerrainLoaderManager.TerrainScenes);
}
else
{
GaiaSessionManager.AddTerrainScenesToBuildSettings(TerrainLoaderManager.TerrainScenes);
}
}
GUI.enabled = originalGUIState;
if (colliderLoadingEnabled)
{
EditorGUILayout.HelpBox(m_editorUtils.GetTextValue("ColliderOnlyLoadingInfo"), MessageType.Info);
m_editorUtils.Heading("DeactivateRuntimeHeader");
EditorGUI.indentLevel++;
m_terrainLoaderManager.TerrainSceneStorage.m_deactivateRuntimePlayer = m_editorUtils.Toggle("DeactivateRuntimePlayer", m_terrainLoaderManager.TerrainSceneStorage.m_deactivateRuntimePlayer, helpEnabled);
m_terrainLoaderManager.TerrainSceneStorage.m_deactivateRuntimeLighting = m_editorUtils.Toggle("DeactivateRuntimeLighting", m_terrainLoaderManager.TerrainSceneStorage.m_deactivateRuntimeLighting, helpEnabled);
m_terrainLoaderManager.TerrainSceneStorage.m_deactivateRuntimeAudio = m_editorUtils.Toggle("DeactivateRuntimeAudio", m_terrainLoaderManager.TerrainSceneStorage.m_deactivateRuntimeAudio, helpEnabled);
m_terrainLoaderManager.TerrainSceneStorage.m_deactivateRuntimeWeather = m_editorUtils.Toggle("DeactivateRuntimeWeather", m_terrainLoaderManager.TerrainSceneStorage.m_deactivateRuntimeWeather, helpEnabled);
m_terrainLoaderManager.TerrainSceneStorage.m_deactivateRuntimeWater = m_editorUtils.Toggle("DeactivateRuntimeWater", m_terrainLoaderManager.TerrainSceneStorage.m_deactivateRuntimeWater, helpEnabled);
m_terrainLoaderManager.TerrainSceneStorage.m_deactivateRuntimeScreenShotter = m_editorUtils.Toggle("DeactivateRuntimeScreenShotter", m_terrainLoaderManager.TerrainSceneStorage.m_deactivateRuntimeScreenShotter, helpEnabled);
EditorGUI.indentLevel--;
}
else
{
//offer button to create collider setup
if (m_editorUtils.Button("OpenTerrainMeshExporterForColliders"))
{
ExportTerrain exportTerrainWindow = EditorWindow.GetWindow<ExportTerrain>();
exportTerrainWindow.FindAndSetPreset("Collider");
exportTerrainWindow.m_settings.m_customSettingsFoldedOut = false;
}
}
}
private void DrawTerrains(bool helpEnabled)
{
bool originalGUIState = GUI.enabled;
#if GAIA_PRO_PRESENT
EditorGUILayout.BeginHorizontal();
m_editorUtils.Label("IngestTerrain", GUILayout.Width(100));
m_ingestTerrain = (Terrain)EditorGUILayout.ObjectField(m_ingestTerrain, typeof(Terrain), true);
if (m_editorUtils.Button("Ingest"))
{
////Try to find the X and Z coordinate for the scene name
//double minX = m_terrainLoaderManager.TerrainSceneStorage.m_terrainScenes.Select(x => x.m_pos.x).Min();
//double maxX = m_terrainLoaderManager.TerrainSceneStorage.m_terrainScenes.Select(x => x.m_pos.x).Max();
//double minZ = m_terrainLoaderManager.TerrainSceneStorage.m_terrainScenes.Select(x => x.m_pos.z).Min();
//double maxZ = m_terrainLoaderManager.TerrainSceneStorage.m_terrainScenes.Select(x => x.m_pos.z).Max();
GaiaSessionManager sessionManager = GaiaSessionManager.GetSessionManager();
WorldCreationSettings worldCreationSettings = new WorldCreationSettings()
{
m_autoUnloadScenes = false,
m_applyFloatingPointFix = TerrainLoaderManager.Instance.TerrainSceneStorage.m_useFloatingPointFix,
m_isWorldMap = false
};
TerrainScene newScene = TerrainSceneCreator.CreateTerrainScene(m_ingestTerrain.gameObject.scene, TerrainLoaderManager.Instance.TerrainSceneStorage, sessionManager.m_session, m_ingestTerrain.gameObject, worldCreationSettings);
TerrainLoaderManager.Instance.TerrainSceneStorage.m_terrainScenes.Add(newScene);
TerrainLoaderManager.Instance.SaveStorageData();
GaiaSessionManager.AddTerrainScenesToBuildSettings(new List<TerrainScene>() { newScene});
}
EditorGUILayout.EndHorizontal();
GUILayout.Space(EditorGUIUtility.singleLineHeight);
#endif
EditorGUILayout.BeginHorizontal();
if (m_editorUtils.Button("AddToBuildSettings"))
{
if (TerrainLoaderManager.ColliderOnlyLoadingActive)
{
if (EditorUtility.DisplayDialog(m_editorUtils.GetTextValue("AddColliderScenesToBuildSettingsPopupTitle"), m_editorUtils.GetTextValue("AddColliderScenesToBuildSettingsPopupText"), m_editorUtils.GetTextValue("Continue"), m_editorUtils.GetTextValue("Cancel")))
{
#if GAIA_PRO_PRESENT
GaiaSessionManager.AddOnlyColliderScenesToBuildSettings(m_terrainLoaderManager.TerrainSceneStorage.m_terrainScenes);
#endif
}
}
else
{
if (EditorUtility.DisplayDialog(m_editorUtils.GetTextValue("AddToBuildSettingsPopupTitle"), m_editorUtils.GetTextValue("AddToBuildSettingsPopupText"), m_editorUtils.GetTextValue("Continue"), m_editorUtils.GetTextValue("Cancel")))
{
#if GAIA_PRO_PRESENT
GaiaSessionManager.AddTerrainScenesToBuildSettings(m_terrainLoaderManager.TerrainSceneStorage.m_terrainScenes);
#endif
}
}
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.BeginHorizontal();
if (m_editorUtils.Button("UnloadAll"))
{
m_terrainLoaderManager.SetLoadingRange(0, 0);
m_terrainLoaderManager.UnloadAll(true);
}
if (m_editorUtils.Button("LoadAll"))
{
if (EditorUtility.DisplayDialog(m_editorUtils.GetTextValue("LoadAllPopupTitle"), m_editorUtils.GetTextValue("LoadAllPopupText"), m_editorUtils.GetTextValue("Continue"), m_editorUtils.GetTextValue("Cancel")))
{
foreach (TerrainScene terrainScene in m_terrainLoaderManager.TerrainSceneStorage.m_terrainScenes)
{
m_terrainLoaderManager.SetLoadingRange(100000, m_terrainLoaderManager.GetImpostorLoadingRange());
terrainScene.AddRegularReference(m_terrainLoaderManager.gameObject);
}
}
}
EditorGUILayout.EndHorizontal();
if (!GaiaUtils.HasImpostorTerrains())
{
GUI.enabled = false;
}
EditorGUILayout.BeginHorizontal();
if (m_editorUtils.Button("UnloadAllImpostors"))
{
m_terrainLoaderManager.SetLoadingRange(m_terrainLoaderManager.GetLoadingRange(), 0);
m_terrainLoaderManager.UnloadAllImpostors(true);
}
if (m_editorUtils.Button("LoadAllImpostors"))
{
if (EditorUtility.DisplayDialog(m_editorUtils.GetTextValue("LoadAllPopupTitle"), m_editorUtils.GetTextValue("LoadAllImpostorsPopupText"), m_editorUtils.GetTextValue("Continue"), m_editorUtils.GetTextValue("Cancel")))
{
m_terrainLoaderManager.SetLoadingRange(m_terrainLoaderManager.GetLoadingRange(), 100000);
foreach (TerrainScene terrainScene in m_terrainLoaderManager.TerrainSceneStorage.m_terrainScenes)
{
terrainScene.AddImpostorReference(m_terrainLoaderManager.gameObject);
}
}
}
EditorGUILayout.EndHorizontal();
GUI.enabled = originalGUIState;
GUILayout.Space(EditorGUIUtility.singleLineHeight);
float buttonWidth1 = 110;
float buttonWidth2 = 60;
if (m_terrainBoxStyle == null || m_terrainBoxStyle.normal.background == null)
{
m_terrainBoxStyle = new GUIStyle(EditorStyles.helpBox);
m_terrainBoxStyle.margin = new RectOffset(0, 0, 0, 0);
m_terrainBoxStyle.padding = new RectOffset(3, 3, 3, 3);
}
int removeIndex = -99;
int currentIndex = 0;
foreach (TerrainScene terrainScene in m_terrainLoaderManager.TerrainSceneStorage.m_terrainScenes)
{
EditorGUILayout.BeginVertical(m_terrainBoxStyle);
{
EditorGUILayout.LabelField(terrainScene.GetTerrainName());
EditorGUILayout.BeginHorizontal();
bool isLoaded = terrainScene.m_regularLoadState == LoadState.Loaded && terrainScene.TerrainObj != null && terrainScene.TerrainObj.activeInHierarchy;
bool isImpostorLoaded = terrainScene.m_impostorLoadState == LoadState.Loaded || terrainScene.m_impostorLoadState == LoadState.Cached;
bool currentGUIState = GUI.enabled;
GUI.enabled = isLoaded;
if (m_editorUtils.Button("SelectPlaceholder", GUILayout.Width(buttonWidth1)))
{
Selection.activeGameObject = GameObject.Find(terrainScene.GetTerrainName());
EditorGUIUtility.PingObject(Selection.activeObject);
}
GUI.enabled = currentGUIState;
if (isLoaded)
{
if (m_editorUtils.Button("UnloadPlaceholder", GUILayout.Width(buttonWidth2)))
{
if (ResetToWorldOriginLoading())
{
terrainScene.RemoveAllReferences(true);
}
}
}
else
{
if (m_editorUtils.Button("LoadPlaceholder", GUILayout.Width(buttonWidth2)))
{
if (ResetToWorldOriginLoading())
{
terrainScene.AddRegularReference(m_terrainLoaderManager.gameObject);
}
}
}
if (string.IsNullOrEmpty(terrainScene.m_impostorScenePath))
{
GUI.enabled = false;
}
if (isImpostorLoaded)
{
if (m_editorUtils.Button("UnLoadImpostor", GUILayout.Width(buttonWidth1)))
{
if (ResetToWorldOriginLoading())
{
terrainScene.RemoveImpostorReference(m_terrainLoaderManager.gameObject, 0, true);
}
}
}
else
{
if (m_editorUtils.Button("LoadImpostor", GUILayout.Width(buttonWidth1)))
{
if (ResetToWorldOriginLoading())
{
terrainScene.AddImpostorReference(m_terrainLoaderManager.gameObject);
}
}
}
GUI.enabled = originalGUIState;
if (m_editorUtils.Button("RemoveScene"))
{
if (EditorUtility.DisplayDialog(m_editorUtils.GetTextValue("RemoveSceneTitle"), m_editorUtils.GetTextValue("RemoveSceneText"), m_editorUtils.GetTextValue("Continue"), m_editorUtils.GetTextValue("Cancel")))
{
removeIndex = currentIndex;
}
}
EditorGUILayout.EndHorizontal();
if (terrainScene.RegularReferences.Count > 0)
{
EditorGUI.indentLevel++;
terrainScene.m_isFoldedOut = m_editorUtils.Foldout(terrainScene.m_isFoldedOut, "ShowTerrainReferences");
if (terrainScene.m_isFoldedOut)
{
foreach (GameObject go in terrainScene.RegularReferences)
{
EditorGUILayout.BeginHorizontal();
GUILayout.Space(20);
m_editorUtils.Label(new GUIContent(go.name, m_editorUtils.GetTextValue("TerrainReferenceToolTip")));
if (m_editorUtils.Button("TerrainReferenceSelect", GUILayout.Width(buttonWidth1)))
{
Selection.activeObject = go;
SceneView.lastActiveSceneView.FrameSelected();
}
if (m_editorUtils.Button("TerrainReferenceRemove", GUILayout.Width(buttonWidth2)))
{
terrainScene.RemoveRegularReference(go);
}
GUILayout.Space(100);
EditorGUILayout.EndHorizontal();
}
}
EditorGUI.indentLevel--;
}
if (terrainScene.ImpostorReferences.Count > 0)
{
EditorGUI.indentLevel++;
terrainScene.m_isFoldedOut = m_editorUtils.Foldout(terrainScene.m_isFoldedOut, "ShowImpostorReferences");
if (terrainScene.m_isFoldedOut)
{
foreach (GameObject go in terrainScene.ImpostorReferences)
{
EditorGUILayout.BeginHorizontal();
GUILayout.Space(20);
m_editorUtils.Label(new GUIContent(go.name, m_editorUtils.GetTextValue("TerrainReferenceToolTip")));
if (m_editorUtils.Button("TerrainReferenceSelect", GUILayout.Width(buttonWidth1)))
{
Selection.activeObject = go;
SceneView.lastActiveSceneView.FrameSelected();
}
if (m_editorUtils.Button("TerrainReferenceRemove", GUILayout.Width(buttonWidth2)))
{
terrainScene.RemoveImpostorReference(go);
}
GUILayout.Space(100);
EditorGUILayout.EndHorizontal();
}
}
EditorGUI.indentLevel--;
}
}
GUILayout.EndVertical();
GUILayout.Space(5f);
currentIndex++;
}
if (removeIndex != -99)
{
AssetDatabase.DeleteAsset(m_terrainLoaderManager.TerrainSceneStorage.m_terrainScenes[removeIndex].m_scenePath);
m_terrainLoaderManager.TerrainSceneStorage.m_terrainScenes.RemoveAt(removeIndex);
m_terrainLoaderManager.SaveStorageData();
}
}
/// <summary>
/// Checks if the scene view loading is currently set to center on world origin, if not, prompts the user to switch.
/// Used when loading in and out single terrains which would clash with the scene view camera loading mode.
/// </summary>
/// <returns>True if the scene was already on World Origin mode, or if the switch was performed.</returns>
private bool ResetToWorldOriginLoading()
{
if (m_terrainLoaderManager.CenterSceneViewLoadingOn != CenterSceneViewLoadingOn.WorldOrigin)
{
if (EditorUtility.DisplayDialog(m_editorUtils.GetTextValue("ManualLoadPopUpTitle"), m_editorUtils.GetTextValue("ManualLoadPopUpText"), m_editorUtils.GetTextValue("Continue"), m_editorUtils.GetTextValue("Cancel")))
{
m_terrainLoaderManager.CenterSceneViewLoadingOn = CenterSceneViewLoadingOn.WorldOrigin;
m_terrainLoaderManager.SetLoadingRange(0,0);
return true;
}
else
{
return false;
}
}
else
{
return true;
}
}
private void DrawLoaders(bool helpEnabled)
{
bool originalGUIState = GUI.enabled;
EditorGUIUtility.labelWidth = 20;
#if GAIA_PRO_PRESENT
foreach (TerrainLoader terrainLoader in m_terrainLoaders)
{
if (terrainLoader != null)
{
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(terrainLoader.name);
terrainLoader.LoadMode = (LoadMode)EditorGUILayout.EnumPopup(terrainLoader.LoadMode);
if (m_editorUtils.Button("SelectLoader", GUILayout.MaxWidth(100)))
{
Selection.activeGameObject = terrainLoader.gameObject;
EditorGUIUtility.PingObject(Selection.activeObject);
//Try to find out which kind of Gaia Tool that is, and open / highlight the terrain loading settings where appropiate
Stamper stamper = terrainLoader.gameObject.GetComponent<Stamper>();
if (stamper != null)
{
stamper.HighlightLoadingSettings();
}
BiomeController biomeController = terrainLoader.gameObject.GetComponent<BiomeController>();
if (biomeController != null)
{
biomeController.HighlightLoadingSettings();
}
Spawner spawner = terrainLoader.gameObject.GetComponent<Spawner>();
if (spawner != null)
{
spawner.HighlightLoadingSettings();
}
MaskMapExport maskMapExport = terrainLoader.gameObject.GetComponent<MaskMapExport>();
if (maskMapExport != null)
{
maskMapExport.HighlightLoadingSettings();
}
}
EditorGUILayout.EndHorizontal();
}
}
#endif
EditorGUIUtility.labelWidth = 0;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3ef4daf994caeab43b0085217c3ea4bc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9b6352847ed0a0f468565bd258ec6d56
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4b16076b8d3339d49b9620137d1144a5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,718 @@
using System;
using System.Collections;
using System.Collections.Generic;
#if UNITY_EDITOR
using UnityEditor.SceneManagement;
#endif
using UnityEngine;
using UnityEngine.Profiling;
using UnityEngine.SceneManagement;
namespace Gaia
{
[System.Serializable]
public enum LoadState { Loaded, Cached, Unloaded }
public enum ReferenceChange { AddImpostorReference, AddRegularReference, RemoveImpostorReference, RemoveRegularReference }
public class TerrainSceneActionQueueEntry { public TerrainScene m_terrainScene; public ReferenceChange m_referenceChange; public bool m_forced = false; public float m_distance = 0f; }
[System.Serializable]
public class TerrainScene
{
private List<GameObject> m_regularReferences = new List<GameObject>();
public List<GameObject> RegularReferences { get { return m_regularReferences; } }
private List<GameObject> m_impostorReferences = new List<GameObject>();
public List<GameObject> ImpostorReferences { get { return m_impostorReferences; } }
public Vector3Double m_pos;
public Vector3Double m_currentOriginOffset;
public BoundsDouble m_bounds;
public string m_scenePath;
public string m_impostorScenePath;
public string m_backupScenePath;
public string m_colliderScenePath;
public LoadState m_regularLoadState;
public LoadState m_impostorLoadState;
public bool m_useFloatingPointFix;
public long m_nextUpdateTimestamp;
private AsyncOperation asyncLoadOp;
public bool m_regularLoadRequested;
public bool m_regularUnloadRequested;
public bool m_impostorLoadRequested;
public bool m_impostorUnloadRequested;
private long m_loadCacheTreshold = 4294967296;
private bool m_forceSceneRemove = false;
private List<GameObject> m_rootGameObjects = new List<GameObject>();
public bool m_isFoldedOut;
private GameObject m_terrainObj;
public long m_regularCachedTimestamp;
public long m_impostorCachedTimestamp;
#if UNITY_EDITOR
public GameObject TerrainObj { get => m_terrainObj; }
#endif
public string GetTerrainName(string path = "")
{
if (path == "")
{
path = m_scenePath;
}
return path.Substring(path.LastIndexOf("Terrain")).Replace(".unity", "");
}
public void RemoveAllReferences(bool forceSceneRemove = false)
{
m_regularReferences.Clear();
m_impostorReferences.Clear();
#if GAIA_PRO_PRESENT
m_regularLoadRequested = false;
m_regularUnloadRequested = false;
m_impostorLoadRequested = false;
m_impostorUnloadRequested = false;
m_forceSceneRemove = forceSceneRemove;
UpdateLoadState(m_regularReferences, ref m_regularLoadState, ref m_regularLoadRequested, ref m_regularUnloadRequested, false);
UpdateLoadState(m_impostorReferences, ref m_impostorLoadState, ref m_impostorLoadRequested, ref m_impostorUnloadRequested, true);
#endif
}
public void RemoveAllImpostorReferences(bool forceSceneRemove = false)
{
m_impostorReferences.Clear();
#if GAIA_PRO_PRESENT
m_impostorLoadRequested = false;
m_impostorUnloadRequested = false;
m_forceSceneRemove = forceSceneRemove;
UpdateLoadState(m_impostorReferences, ref m_impostorLoadState, ref m_impostorLoadRequested, ref m_impostorUnloadRequested, true);
#endif
}
public void RemoveAllRegularReferences(bool forceSceneRemove = false)
{
m_regularReferences.Clear();
#if GAIA_PRO_PRESENT
m_regularLoadRequested = false;
m_regularUnloadRequested = false;
m_forceSceneRemove = forceSceneRemove;
UpdateLoadState(m_regularReferences, ref m_regularLoadState, ref m_regularLoadRequested, ref m_regularUnloadRequested, true);
#endif
}
public void AddRegularReference(GameObject gameObject)
{
if (!m_regularReferences.Contains(gameObject))
{
m_forceSceneRemove = false;
m_regularReferences.Add(gameObject);
}
UpdateLoadState(m_regularReferences, ref m_regularLoadState, ref m_regularLoadRequested, ref m_regularUnloadRequested, false);
}
public void RemoveRegularReference(GameObject gameObject, long cacheSize = 0, bool forceSceneRemove = false)
{
m_forceSceneRemove = forceSceneRemove;
if (m_regularReferences.Contains(gameObject))
{
m_regularReferences.Remove(gameObject);
}
if (cacheSize != 0)
{
m_loadCacheTreshold = cacheSize;
}
UpdateLoadState(m_regularReferences, ref m_regularLoadState, ref m_regularLoadRequested, ref m_regularUnloadRequested, false);
}
public bool HasRegularReference(GameObject gameObject)
{
return m_regularReferences.Contains(gameObject);
}
public void AddImpostorReference(GameObject gameObject)
{
if (!String.IsNullOrEmpty(m_impostorScenePath))
{
if (!m_impostorReferences.Contains(gameObject))
{
m_forceSceneRemove = false;
m_impostorReferences.Add(gameObject);
}
UpdateLoadState(m_impostorReferences, ref m_impostorLoadState, ref m_impostorLoadRequested, ref m_impostorUnloadRequested, true);
}
}
public void RemoveImpostorReference(GameObject gameObject, long cacheSize = 0, bool forceSceneRemove = false)
{
if (!String.IsNullOrEmpty(m_impostorScenePath))
{
m_forceSceneRemove = forceSceneRemove;
if (m_impostorReferences.Contains(gameObject))
{
m_impostorReferences.Remove(gameObject);
}
if (cacheSize != 0)
{
m_loadCacheTreshold = cacheSize;
}
UpdateLoadState(m_impostorReferences, ref m_impostorLoadState, ref m_impostorLoadRequested, ref m_impostorUnloadRequested, true);
}
}
public bool HasImpostorReference(GameObject gameObject)
{
return m_impostorReferences.Contains(gameObject);
}
public void UpdateLoadState(List<GameObject> referenceList, ref LoadState loadState, ref bool loadRequested, ref bool unLoadRequested, bool isImpostor)
{
string scenePath = m_scenePath;
if (isImpostor)
{
scenePath = m_impostorScenePath;
}
if (TerrainLoaderManager.ColliderOnlyLoadingActive)
{
scenePath = m_colliderScenePath;
}
#if GAIA_PRO_PRESENT
if (scenePath == null)
{
return;
}
//sanity check on the references: does the GO still exist?
CheckForRelevance(referenceList);
//locked - no state change for now, used when the loader is dragged around in the scene, etc.
#if UNITY_EDITOR
Scene scene = EditorSceneManager.GetSceneByPath(scenePath);
#else
Scene scene = SceneManager.GetSceneByPath(scenePath);
#endif
SyncLoadState(scene, ref loadState, ref loadRequested, ref unLoadRequested, isImpostor);
switch (loadState)
{
case LoadState.Loaded:
if (referenceList.Count <= 0 && scene.isLoaded)
{
UnloadScene(scene, ref loadRequested, ref unLoadRequested, ref loadState, isImpostor);
//if a regular terrain was just unloaded, do an update on the impostor to see if it needs to be loaded in
if (!isImpostor && !String.IsNullOrEmpty(m_impostorScenePath))
{
UpdateLoadState(m_impostorReferences, ref m_impostorLoadState, ref m_impostorLoadRequested, ref m_impostorUnloadRequested, true);
}
}
if (referenceList.Count >= 1)
{
//Is this a regular scene and the Impostor is still loaded? Remove it!
if (!isImpostor && m_impostorLoadState == LoadState.Loaded)
{
ReplaceImpostor();
}
}
break;
case LoadState.Cached:
if (referenceList.Count >= 1 && scene.isLoaded)
{
//do not need to activate the cached scene if this is an imposter and the regular scene has references and is loaded in already
if (isImpostor && m_regularReferences.Count >= 1 && m_regularLoadState == LoadState.Loaded)
{
break;
}
foreach (GameObject go in scene.GetRootGameObjects())
{
go.SetActive(true);
Terrain terrain = go.GetComponent<Terrain>();
if (terrain != null)
{
//rwactivate terrain / trees in case if culled
terrain.drawTreesAndFoliage = true;
terrain.drawHeightmap = true;
m_terrainObj = go;
}
}
//Is this a regular scene that just came out of cache and the Impostor is still loaded? Remove it!
if (!isImpostor && m_impostorLoadState == LoadState.Loaded)
{
ReplaceImpostor();
}
loadState = LoadState.Loaded;
}
//we still need to process force removal requests
if (referenceList.Count <= 0 && scene.isLoaded && m_forceSceneRemove)
{
UnloadScene(scene, ref loadRequested, ref unLoadRequested, ref loadState, isImpostor);
}
break;
case LoadState.Unloaded:
if (referenceList.Count >= 1 && !scene.isLoaded)
{
//do not need to load if this is an imposter and the regular scene has references and is loaded in already anyways
if (isImpostor && m_regularReferences.Count >= 1 && m_regularLoadState == LoadState.Loaded)
{
break;
}
LoadScene(scene, ref loadRequested, ref loadState, isImpostor);
}
break;
}
#if UNITY_EDITOR
scene = EditorSceneManager.GetSceneByPath(scenePath);
#else
scene = SceneManager.GetSceneByPath(scenePath);
#endif
SyncLoadState(scene, ref loadState, ref loadRequested, ref unLoadRequested, isImpostor);
#endif
}
/// <summary>
/// Synchronizes the load state of the unity scene object with Gaias terrain scene. There are edge cases where those two can get out of sync, e.g. race conditions, users opening
/// and closing scenes manually etc. so it can be required to compare the load state of the two object types.
/// </summary>
/// <param name="scene"></param>
private void SyncLoadState(Scene scene, ref LoadState loadState, ref bool loadRequested, ref bool unLoadRequested, bool isImpostor)
{
if (scene.isLoaded)
{
bool isCached = true;
foreach (GameObject go in scene.GetRootGameObjects())
{
if (go.activeInHierarchy)
{
isCached = false;
}
}
if (isCached)
{
if (loadState != LoadState.Cached)
{
//Here we discover by syncing the load state that the terrain is actually cached, so we need to update the timestamp.
if (isImpostor)
{
m_impostorCachedTimestamp = GaiaUtils.GetUnixTimestamp();
}
else
{
m_regularCachedTimestamp = GaiaUtils.GetUnixTimestamp();
}
}
loadState = LoadState.Cached;
}
else
{
loadState = LoadState.Loaded;
}
loadRequested = false;
}
else
{
loadState = LoadState.Unloaded;
unLoadRequested = false;
}
}
private void LoadScene(Scene scene, ref bool loadRequested, ref LoadState loadState, bool isImpostor)
{
string scenePath = m_scenePath;
if (isImpostor)
{
scenePath = m_impostorScenePath;
}
if (TerrainLoaderManager.ColliderOnlyLoadingActive)
{
scenePath = m_colliderScenePath;
}
#if UNITY_EDITOR
if (Application.isPlaying)
{
if (!loadRequested)
{
TerrainLoaderManager tlm = TerrainLoaderManager.Instance;
long currentTimeStamp = GaiaUtils.GetUnixTimestamp();
//don't load if the loading treshold has not passed yet
//this is to prevent a bottleneck from loading too many terrains at the same time
if (tlm.m_lastTerrainLoadedTimeStamp + tlm.m_terrainLoadingTresholdMS > currentTimeStamp)
{
return;
}
asyncLoadOp = SceneManager.LoadSceneAsync(scenePath, LoadSceneMode.Additive);
tlm.m_lastTerrainLoadedTimeStamp = currentTimeStamp;
if (isImpostor)
{
asyncLoadOp.completed += SceneLoadCompletedImpostor;
}
else
{
asyncLoadOp.completed += SceneLoadCompletedRegular;
}
loadRequested = true;
}
}
else
{
ProgressBar.Show(ProgressBarPriority.TerrainLoading, "Loading Terrain", "Loading Terrain...", 0, 0, false, false);
EditorSceneManager.sceneOpened += SceneOpened;
EditorSceneManager.OpenScene(scenePath, OpenSceneMode.Additive);
ProgressBar.Clear(ProgressBarPriority.TerrainLoading);
}
#else
if (!loadRequested)
{
TerrainLoaderManager tlm = TerrainLoaderManager.Instance;
long currentTimeStamp = GaiaUtils.GetUnixTimestamp();
//don't load if the loading treshold has not passed yet
//this is to prevent a bottleneck from loading too many terrains at the same time
if (tlm.m_lastTerrainLoadedTimeStamp + tlm.m_terrainLoadingTresholdMS > currentTimeStamp)
{
return;
}
asyncLoadOp = SceneManager.LoadSceneAsync(scenePath, LoadSceneMode.Additive);
tlm.m_lastTerrainLoadedTimeStamp = currentTimeStamp;
if (isImpostor)
{
asyncLoadOp.completed += SceneLoadCompletedImpostor;
}
else
{
asyncLoadOp.completed += SceneLoadCompletedRegular;
}
loadRequested = true;
}
#endif
}
/// <summary>
/// Will update the load state of the terrain scene for all scene types - regular, collider, impostor, with the data that is currently stored in the terrain scene.
/// </summary>
public void UpdateWithCurrentData()
{
UpdateLoadState(m_regularReferences, ref m_regularLoadState, ref m_regularLoadRequested, ref m_regularUnloadRequested, false);
UpdateLoadState(m_impostorReferences, ref m_impostorLoadState, ref m_impostorLoadRequested, ref m_impostorUnloadRequested, true);
}
private void UnloadScene(Scene scene, ref bool loadRequested, ref bool unLoadRequested, ref LoadState loadState, bool isImpostor, bool bypassTreshold = false)
{
if (Application.isPlaying)
{
TerrainLoaderManager tlm = TerrainLoaderManager.Instance;
long currentTimeStamp = GaiaUtils.GetUnixTimestamp();
//don't unload if the loading treshold has not passed yet
//this is to prevent a bottleneck from loading too many terrains at the same time
if (tlm.m_lastTerrainLoadedTimeStamp + tlm.m_terrainLoadingTresholdMS > currentTimeStamp && !bypassTreshold)
{
return;
}
tlm.m_lastTerrainLoadedTimeStamp = currentTimeStamp;
}
//Make sure that loading again is allowed
loadRequested = false;
//If this is not a request to unload an impostor, but the scene would have one that is referenced, we must not unload this scene until the impostor scene is loaded in.
if (!isImpostor && !String.IsNullOrEmpty(m_impostorScenePath) && m_impostorReferences.Count >= 1 && m_impostorLoadState != LoadState.Loaded)
{
//Force an update on the impostor, since it should be able to load in now with the regular scene having no references anymore.
UpdateLoadState(m_impostorReferences, ref m_impostorLoadState, ref m_impostorLoadRequested, ref m_impostorUnloadRequested, true);
return;
}
if (Profiler.GetTotalReservedMemoryLong() < m_loadCacheTreshold && !m_forceSceneRemove && TerrainLoaderManager.Instance.CachingAllowed())
{
//only deactivate the root game objects first, actual unload will happen later
foreach (GameObject go in scene.GetRootGameObjects())
{
go.SetActive(false);
}
#if UNITY_EDITOR
if (!Application.isPlaying)
{
if (scene.isDirty)
{
EditorSceneManager.SaveScene(scene);
}
}
#endif
unLoadRequested = false;
loadState = LoadState.Cached;
if (isImpostor)
{
m_impostorCachedTimestamp = GaiaUtils.GetUnixTimestamp();
}
else
{
m_regularCachedTimestamp = GaiaUtils.GetUnixTimestamp();
}
}
else
{
//conditions for caching not met, do full unload now
if (Application.isPlaying)
{
if (!unLoadRequested)
{
SceneManager.UnloadSceneAsync(scene.name);
loadState = LoadState.Unloaded;
unLoadRequested = true;
}
}
else
{
#if UNITY_EDITOR
ProgressBar.Show(ProgressBarPriority.TerrainLoading, "Unloading Terrain", "Unloading Terrain...", 0, 0, false, false);
if (scene.isDirty)
{
EditorSceneManager.SaveScene(scene);
}
EditorSceneManager.CloseScene(scene, true);
//TerrainLoaderManager.Instance.EmptyCache();
ProgressBar.Clear(ProgressBarPriority.TerrainLoading);
loadState = LoadState.Unloaded;
unLoadRequested = false;
#endif
}
}
}
private void CheckForRelevance(List<GameObject> referenceList)
{
#if GAIA_PRO_PRESENT
for (int i = referenceList.Count - 1; i >= 0; i--)
{
if (referenceList[i] == null)
{
referenceList.RemoveAt(i);
}
else
{
//Is it still relevant?
TerrainLoader loader = referenceList[i].GetComponent<TerrainLoader>();
if (loader != null)
{
if (!loader.enabled || !loader.gameObject.activeInHierarchy || loader.LoadMode == LoadMode.Disabled || (!loader.m_isSelected && loader.LoadMode == LoadMode.EditorSelected))
{
referenceList.RemoveAt(i);
}
}
}
}
#endif
}
#if UNITY_EDITOR
private void SceneOpened(Scene scene, OpenSceneMode mode)
{
if (m_scenePath == null)
{
return;
}
//there is an edge case when the scene opened event is fired but the scene is still not loaded
if (scene.isLoaded == false)
{
if (scene.path == m_scenePath || scene.path == m_colliderScenePath)
{
m_regularLoadState = LoadState.Unloaded;
}
if (scene.path == m_impostorScenePath)
{
m_impostorLoadState = LoadState.Unloaded;
}
return;
}
if (scene.path == m_scenePath || scene.path == m_colliderScenePath)
{
if (m_regularLoadState != LoadState.Loaded)
{
foreach (GameObject go in scene.GetRootGameObjects())
{
if (go.GetComponent<Terrain>() != null)
{
m_terrainObj = go;
go.transform.position = m_bounds.center - m_currentOriginOffset - new Vector3Double(m_bounds.size.x / 2f, 0f, m_bounds.size.z / 2f);
}
go.SetActive(true);
}
m_regularLoadState = LoadState.Loaded;
ReplaceImpostor();
}
EditorSceneManager.sceneOpened -= SceneOpened;
}
if (scene.path == m_impostorScenePath)
{
if (m_impostorLoadState != LoadState.Loaded)
{
foreach (GameObject go in scene.GetRootGameObjects())
{
go.SetActive(true);
}
m_impostorLoadState = LoadState.Loaded;
//Make sure the regular scene has not been loaded in the meantime due to a race condition. If it has, remove the impostor right away.
if (m_regularReferences.Count >= 1 && m_regularLoadState == LoadState.Loaded)
{
ReplaceImpostor();
}
}
EditorSceneManager.sceneOpened -= SceneOpened;
}
}
#endif
private void SceneLoadCompletedRegular(AsyncOperation obj)
{
#if GAIA_PRO_PRESENT
string scenePath = m_scenePath;
if (TerrainLoaderManager.ColliderOnlyLoadingActive)
{
scenePath = m_colliderScenePath;
}
Scene scene = SceneManager.GetSceneByPath(scenePath);
foreach (GameObject go in scene.GetRootGameObjects())
{
if (m_useFloatingPointFix)
{
go.transform.position += FloatingPointFix.Instance.totalOffset;
if (go.transform.GetComponent<FloatingPointFixMember>() == null)
{
go.AddComponent<FloatingPointFixMember>();
}
}
if (go.GetComponent<Terrain>() != null)
{
m_terrainObj = go;
}
go.SetActive(true);
}
m_regularLoadState = LoadState.Loaded;
ReplaceImpostor();
obj.completed -= SceneLoadCompletedRegular;
#endif
}
private void ReplaceImpostor()
{
#if GAIA_PRO_PRESENT
if (!String.IsNullOrEmpty(m_impostorScenePath) && m_impostorLoadState == LoadState.Loaded)
{
#if UNITY_EDITOR
Scene impostorScene = EditorSceneManager.GetSceneByPath(m_impostorScenePath);
#else
Scene impostorScene = SceneManager.GetSceneByPath(m_impostorScenePath);
#endif
UnloadScene(impostorScene, ref m_impostorLoadRequested, ref m_impostorUnloadRequested, ref m_impostorLoadState, true, true);
}
#endif
}
private void SceneLoadCompletedImpostor(AsyncOperation obj)
{
#if GAIA_PRO_PRESENT
Scene scene = SceneManager.GetSceneByPath(m_impostorScenePath);
foreach (GameObject go in scene.GetRootGameObjects())
{
if (m_useFloatingPointFix)
{
go.transform.position += FloatingPointFix.Instance.totalOffset;
if (go.transform.GetComponent<FloatingPointFixMember>() == null)
{
go.AddComponent<FloatingPointFixMember>();
}
}
go.SetActive(true);
}
m_impostorLoadState = LoadState.Loaded;
//Make sure the regular scene has not been loaded in the meantime due to a race condition. If it has, remove the impostor right away.
if (m_regularReferences.Count >= 1 && m_regularLoadState == LoadState.Loaded)
{
ReplaceImpostor();
}
#endif
obj.completed -= SceneLoadCompletedImpostor;
}
public void ShiftLoadedTerrain()
{
//Perform the shift for both loaded and cached terrains
if (m_regularLoadState == LoadState.Loaded || m_regularLoadState == LoadState.Cached)
{
string scenePath = m_scenePath;
if (TerrainLoaderManager.ColliderOnlyLoadingActive)
{
scenePath = m_colliderScenePath;
}
#if UNITY_EDITOR
Scene scene = EditorSceneManager.GetSceneByPath(scenePath);
#else
Scene scene = SceneManager.GetSceneByPath(m_scenePath);
#endif
if (scene.isLoaded)
{
scene.GetRootGameObjects(m_rootGameObjects);
foreach (GameObject go in m_rootGameObjects)
{
go.transform.position = m_bounds.center - m_currentOriginOffset - new Vector3Double(m_bounds.size.x / 2f, 0f, m_bounds.size.z / 2f);
}
}
else
{
m_regularLoadState = LoadState.Unloaded;
}
}
if (m_impostorLoadState == LoadState.Loaded || m_impostorLoadState == LoadState.Cached)
{
#if UNITY_EDITOR
Scene scene = EditorSceneManager.GetSceneByPath(m_impostorScenePath);
#else
Scene scene = SceneManager.GetSceneByPath(m_impostorScenePath);
#endif
if (scene.isLoaded)
{
scene.GetRootGameObjects(m_rootGameObjects);
foreach (GameObject go in m_rootGameObjects)
{
go.transform.position = m_bounds.center - m_currentOriginOffset - new Vector3Double(m_bounds.size.x / 2f, 0f, m_bounds.size.z / 2f);
}
}
else
{
m_impostorLoadState = LoadState.Unloaded;
}
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b39cdc1c94edf1d43b35ef53c1b7b702
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,104 @@
// Copyright © 2018 Procedural Worlds Pty Limited. All Rights Reserved.
using UnityEngine;
using System.Collections.Generic;
using static Gaia.GaiaConstants;
using System.Linq;
/*
* Scriptable Object containing the stored terrain metadata for loading terrain scenes plus additional world metadata like terrain tilesize etc.
*/
namespace Gaia
{
[System.Serializable]
public class TerrainSceneStorage : ScriptableObject
{
/// <summary>
/// Enables / Disables Terrain Loading on a global level.
/// </summary>
public bool m_terrainLoadingEnabled = true;
/// <summary>
/// Enables a special mode where the terrain loading will only load in collider terrain scenes instead of the regular scenes.
/// These collider scenes can be built with the terrain mesh exporter. This allows to run a scene with collisions only without terrain rendering e.g. for a server application
/// </summary>
public bool m_colliderOnlyLoading = false;
/// <summary>
/// The number of terrain tiles on the X axis
/// </summary>
public int m_terrainTilesX = 1;
/// <summary>
/// The number of terrain tiles on the Z axis
/// </summary>
public int m_terrainTilesZ = 1;
/// <summary>
/// The size of the individual terrain tiles
/// </summary>
public int m_terrainTilesSize;
/// <summary>
/// Set to true if the scene uses the floating point fix
/// </summary>
public bool m_useFloatingPointFix;
/// <summary>
/// Set to true if the scene has a world map. Used to not unneccessarily look for a world map in the scene.
/// </summary>
public bool m_hasWorldMap;
/// <summary>
/// The relative size of the world map in comparison to the actual terrain, e.g. 0.25% of the size of the full terrain.
/// This info is used to calculate things like the relative sea level on the world map.
/// </summary>
public float m_worldMaprelativeSize = 0.5f;
/// <summary>
/// The relative size to heightmap pixel ratio between world map and local map
/// This info is used to calculate heightmap relative things between world map and local map, e.g. stamper size
/// </summary>
public float m_worldMapRelativeHeightmapPixels = 1f;
/// <summary>
/// Holds all terrain scenes in a multi-terrain scenario with exported terrains.
/// </summary>
public List<TerrainScene> m_terrainScenes = new List<TerrainScene>();
/// <summary>
/// Toggles if the terrain loader should deactivate the player at runtime
/// </summary>
public bool m_deactivateRuntimePlayer = false;
/// <summary>
/// Toggles if the terrain loader should deactivate the lighting at runtime
/// </summary>
public bool m_deactivateRuntimeLighting = false;
/// <summary>
/// Toggles if the terrain loader should deactivate the audio at runtime
/// </summary>
public bool m_deactivateRuntimeAudio = false;
/// <summary>
/// Toggles if the terrain loader should deactivate the weather at runtime
/// </summary>
public bool m_deactivateRuntimeWeather = false;
/// <summary>
/// Toggles if the terrain loader should deactivate the water at runtime
/// </summary>
public bool m_deactivateRuntimeWater = false;
/// <summary>
/// Toggles if the terrain loader should deactivate the ScreenShotter at runtime
/// </summary>
public bool m_deactivateRuntimeScreenShotter = false;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: da50733ca13d24f45a2980dcd5a56ed5
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 0861027633dd71c4485845e27852793c, type: 3}
userData:
assetBundleName:
assetBundleVariant: