/// <summary> /// Updates the caching mechanism with the new settings - effectively this does only unload cached terrains which are not allowed to be cached anymore due to the new settings. /// </summary> public void UpdateCaching() { long currentTimeStamp = GaiaUtils.GetUnixTimestamp(); foreach (TerrainScene terrainScene in m_terrainSceneStorage.m_terrainScenes) { if (terrainScene.m_impostorLoadState == LoadState.Cached && (!CachingAllowed() || terrainScene.m_impostorCachedTimestamp + m_cacheKeepAliveTime < currentTimeStamp)) { terrainScene.RemoveAllImpostorReferences(true); } if (terrainScene.m_regularLoadState == LoadState.Cached && (!CachingAllowed() || terrainScene.m_regularCachedTimestamp + m_cacheKeepAliveTime < currentTimeStamp)) { terrainScene.RemoveAllReferences(true); } } }
public void StartTrackingProgress() { #if GAIA_PRO_PRESENT //Update all runtime loaders to make sure the current references are set when we start tracking var allLoaders = Resources.FindObjectsOfTypeAll <TerrainLoader>(); foreach (TerrainLoader terrainLoader in allLoaders.Where(x => x.LoadMode == LoadMode.RuntimeAlways)) { terrainLoader.UpdateTerrains(); } m_progressTrackingRunning = true; m_lastLoadingProgressTimeStamp = GaiaUtils.GetUnixTimestamp(); if (OnLoadProgressStarted != null) { OnLoadProgressStarted(); } #endif }
/// <summary> /// Load and unload the terrain scenes stored in the current session for a certain object /// </summary> public void UpdateTerrainLoadState(BoundsDouble loadingBoundsRegular = null, BoundsDouble loadingBoundsImpostor = null, GameObject requestingObject = null, float minDistance = 0, float maxDistance = 0, float minThresholdMS = 0, float maxThresholdMS = 0) { //Do not accept changes to load state during runtime when there was no runtime init yet if (Application.isPlaying && !m_runtimeInitialized) { return; } //Do not perform any updates when terrain loading is disabled per default #if GAIA_PRO_PRESENT if (TerrainLoaderManager.Instance.m_terrainSceneStorage == null || !TerrainLoaderManager.Instance.m_terrainSceneStorage.m_terrainLoadingEnabled) { return; } #endif if (requestingObject == null) { requestingObject = gameObject; } long currentTimeStamp = GaiaUtils.GetUnixTimestamp(); m_terrainSceneActionQueue.Clear(); foreach (TerrainScene terrainScene in TerrainLoaderManager.TerrainScenes) { if (terrainScene.m_nextUpdateTimestamp > currentTimeStamp) { continue; } float distance = Vector3.Distance(terrainScene.m_bounds.center - terrainScene.m_currentOriginOffset, requestingObject.transform.position); terrainScene.m_currentOriginOffset = m_sceneViewOriginLoadingBounds.center; bool wasChanged = false; //only evaluate load state if local terrain is supposed to be displayed if (m_showLocalTerrain) { if (loadingBoundsImpostor != null && loadingBoundsImpostor.extents.magnitude > 0 && loadingBoundsImpostor.extents.magnitude > loadingBoundsRegular.extents.magnitude) { if (terrainScene.m_bounds.Intersects(loadingBoundsImpostor) && !TerrainSceneStorage.m_colliderOnlyLoading) { if (!terrainScene.HasImpostorReference(requestingObject) || terrainScene.m_impostorLoadState == LoadState.Unloaded) { //terrainScene.AddImpostorReference(requestingObject); AddToTerrainSceneActionQueue(terrainScene, ReferenceChange.AddImpostorReference, distance); terrainScene.m_useFloatingPointFix = m_terrainSceneStorage.m_useFloatingPointFix; wasChanged = true; } } else { if (terrainScene.HasImpostorReference(requestingObject) || terrainScene.m_impostorLoadState == LoadState.Loaded) { //terrainScene.RemoveImpostorReference(requestingObject, m_cacheMemoryThreshold); AddToTerrainSceneActionQueue(terrainScene, ReferenceChange.RemoveImpostorReference, distance); wasChanged = true; } if (terrainScene.m_impostorLoadState == LoadState.Cached && (!CachingAllowed() || terrainScene.m_impostorCachedTimestamp + m_cacheKeepAliveTime < currentTimeStamp)) { //terrainScene.RemoveImpostorReference(requestingObject, m_cacheMemoryThreshold, true); AddToTerrainSceneActionQueue(terrainScene, ReferenceChange.RemoveImpostorReference, distance, true); } } } else { if (terrainScene.HasImpostorReference(requestingObject)) { //terrainScene.RemoveImpostorReference(requestingObject, m_cacheMemoryThreshold); AddToTerrainSceneActionQueue(terrainScene, ReferenceChange.RemoveImpostorReference, distance); wasChanged = true; } } if (loadingBoundsRegular != null && loadingBoundsRegular.extents.magnitude > 0) { if (terrainScene.m_bounds.Intersects(loadingBoundsRegular)) { if (!terrainScene.HasRegularReference(requestingObject) || terrainScene.m_regularLoadState == LoadState.Unloaded) { //terrainScene.AddRegularReference(requestingObject); AddToTerrainSceneActionQueue(terrainScene, ReferenceChange.AddRegularReference, distance); terrainScene.m_useFloatingPointFix = m_terrainSceneStorage.m_useFloatingPointFix; wasChanged = true; } } else { if (terrainScene.HasRegularReference(requestingObject) || terrainScene.m_regularLoadState == LoadState.Loaded) { //terrainScene.RemoveRegularReference(requestingObject, m_cacheMemoryThreshold); AddToTerrainSceneActionQueue(terrainScene, ReferenceChange.RemoveRegularReference, distance); wasChanged = true; } if (terrainScene.m_regularLoadState == LoadState.Cached && (!CachingAllowed() || terrainScene.m_regularCachedTimestamp + m_cacheKeepAliveTime < currentTimeStamp)) { //terrainScene.RemoveRegularReference(requestingObject, m_cacheMemoryThreshold, true); AddToTerrainSceneActionQueue(terrainScene, ReferenceChange.RemoveRegularReference, distance, true); } } } } terrainScene.ShiftLoadedTerrain(); if (Application.isPlaying && !wasChanged) { long threshold = +(long)Mathf.Lerp(minThresholdMS, maxThresholdMS, Mathf.InverseLerp(minDistance, maxDistance, Vector3.Distance(loadingBoundsRegular.center, terrainScene.m_bounds.center))) + UnityEngine.Random.Range(10, 50); terrainScene.m_nextUpdateTimestamp = currentTimeStamp + threshold; } else { terrainScene.m_nextUpdateTimestamp = 0; } } for (int i = 0; i < m_terrainSceneActionQueue.Count; i++) { switch (m_terrainSceneActionQueue[i].m_referenceChange) { case ReferenceChange.AddImpostorReference: m_terrainSceneActionQueue[i].m_terrainScene.AddImpostorReference(requestingObject); break; case ReferenceChange.AddRegularReference: m_terrainSceneActionQueue[i].m_terrainScene.AddRegularReference(requestingObject); break; case ReferenceChange.RemoveImpostorReference: m_terrainSceneActionQueue[i].m_terrainScene.RemoveImpostorReference(requestingObject, m_cacheMemoryThreshold, m_terrainSceneActionQueue[i].m_forced); break; case ReferenceChange.RemoveRegularReference: m_terrainSceneActionQueue[i].m_terrainScene.RemoveRegularReference(requestingObject, m_cacheMemoryThreshold, m_terrainSceneActionQueue[i].m_forced); break; } } }
private void Update() { #if GAIA_PRO_PRESENT if (m_progressTrackingRunning) { float progress = 0f; int loadedScenesCount = TerrainSceneStorage.m_terrainScenes.FindAll(x => x.RegularReferences.Count > 0 && x.m_regularLoadState == LoadState.Loaded).Count; int referencedScenesCount = TerrainSceneStorage.m_terrainScenes.FindAll(x => x.RegularReferences.Count > 0).Count; int loadedScenesImpostorCount = TerrainSceneStorage.m_terrainScenes.FindAll(x => x.RegularReferences.Count == 0 && x.ImpostorReferences.Count > 0 && x.m_impostorLoadState == LoadState.Loaded).Count; int referencedImpostorScenesCount = TerrainSceneStorage.m_terrainScenes.FindAll(x => x.RegularReferences.Count == 0 && x.ImpostorReferences.Count > 0).Count; float loadedScenesTotal = loadedScenesCount + loadedScenesImpostorCount; float referencedScenesTotal = referencedScenesCount + referencedImpostorScenesCount; if (referencedScenesTotal > 0) { progress = loadedScenesTotal / referencedScenesTotal; } else { m_progressTrackingRunning = false; if (OnLoadProgressEnded != null) { OnLoadProgressEnded(); } } if (OnLoadProgressUpdated != null) { OnLoadProgressUpdated(progress); } if (progress >= 1f) { m_progressTrackingRunning = false; if (OnLoadProgressEnded != null) { OnLoadProgressEnded(); } } else { long currentTimeStamp = GaiaUtils.GetUnixTimestamp(); //Check if we made progress since the last update if (progress != m_lastTrackedProgressValue) { //we made loading progress, update the progress and timestamp m_lastTrackedProgressValue = progress; m_lastLoadingProgressTimeStamp = currentTimeStamp; } else { //no load progress anymore? Time out the loading tracking eventually if (m_lastLoadingProgressTimeStamp + m_trackLoadingProgressTimeOut < currentTimeStamp) { m_progressTrackingRunning = false; if (OnLoadProgressTimeOut != null) { List <TerrainScene> missingScenes = m_terrainSceneStorage.m_terrainScenes.FindAll(x => (x.RegularReferences.Count > 0 && x.m_regularLoadState != LoadState.Loaded) || (x.ImpostorReferences.Count > 0 && x.m_impostorLoadState != LoadState.Loaded)); OnLoadProgressTimeOut(missingScenes); } if (OnLoadProgressEnded != null) { OnLoadProgressEnded(); } } } } } #endif }
public void HighlightLoadingSettings() { m_highlightLoadingSettings = true; m_highlightLoadingSettingsStartedTimeStamp = GaiaUtils.GetUnixTimestamp(); }
/// <summary> /// Shows a progress bar with a given priority. /// </summary> /// <param name="priorityName">An enum value that controls the priority of this progress bar. (See ProgressBar.cs for the definitions!)</param> /// <param name="title">The title for the progress bar window. Will be appended by step count and ETA if chosen.</param> /// <param name="info">The info text below the progress bar.</param> /// <param name="currentStep">The current step for the process that the progress bar represents. If the process can't be split into steps, put 0 in here.</param> /// <param name="totalSteps">The total amount of steps for the process that the progress bar represents. If the process can't be split into steps, put 0 in here.</param> /// <param name="displayETA">Whether you want an ETA (estimated time of arrival) to be displayed in the title</param> /// <param name="cancelable">Whether the progress bar should have a cancel button.</param> /// <returns>Returns true if the user clicked on the cancel button in the progress bar.</returns> public static bool Show(ProgressBarPriority priority, string title, string info, int currentStep = 0, int totalSteps = 0, bool displayETA = false, bool cancelable = false) { #if UNITY_EDITOR int newPriority = 0; newPriority = (int)priority; //New priority needs to be higher as current one, otherwise we won't interrupt the current progress bar if (newPriority < m_currentPriority) { return(false); } if (newPriority != m_currentPriority) { m_currentPriority = newPriority; //new priority? reset the variables for ETA calculation as well m_averageStepDuration = 0; m_lastStepTimeStamp = 0; } if (totalSteps > 0) { title = string.Format(title + " - Step {0} of {1}", currentStep.ToString(), totalSteps.ToString()); } //ETA calculations if (m_lastStepTimeStamp > 0 && currentStep > 0) { m_averageStepDuration = (m_averageStepDuration * (currentStep - 1) + (GaiaUtils.GetUnixTimestamp() - m_lastStepTimeStamp)) / (long)currentStep; } m_lastStepTimeStamp = GaiaUtils.GetUnixTimestamp(); if (displayETA && currentStep >= 1) { title += ", ETA: " + TimeSpan.FromMilliseconds(m_averageStepDuration * (totalSteps - currentStep)).ToString(@"hh\:mm\:ss"); } //Progress calculations float progress = 0.5f; if (totalSteps > 0) { progress = (float)currentStep / (float)totalSteps; } if (cancelable) { if (EditorUtility.DisplayCancelableProgressBar(title, info, progress)) { //cancel was pressed, make sure the process bar is being cleared in any case. m_currentPriority = 0; m_averageStepDuration = 0; m_lastStepTimeStamp = 0; EditorUtility.ClearProgressBar(); return(true); } else { return(false); } } else { EditorUtility.DisplayProgressBar(title, info, progress); return(false); } #else return(false); #endif }