private static void Update() { if (currentTask != null) { lock (_queueLock) { int count = 0; int maxDuration = 200; System.Diagnostics.Stopwatch stopwatch = System.Diagnostics.Stopwatch.StartNew(); while (TaskQueue.Count > 0 && (stopwatch.ElapsedMilliseconds < maxDuration)) { TaskQueue.Dequeue()(); count++; } // int duration = (int)(stopwatch.ElapsedMilliseconds); // Debug.Log("handled " + count + " tasks in " + duration); if (TaskQueue.Count == 0) { currentTask = null; } } } else { // Should we start new th if (pendingTasks.Count > 0) { currentTask = pendingTasks.Dequeue(); TerrainCombiner terrainCombiner = currentTask.terrainCombiner; Debug.Log("TerrainCombiner starting update tasks"); // Cache updated instantly so we get data for all parts in one frame UpdateCaches(terrainCombiner); lock (_queueLock) { // Start combine TaskQueue.Enqueue(delegate() { TCHeightmapHelper.StartCombine(terrainCombiner, terrainCombiner.groundLevelFraction); }); TaskQueue.Enqueue(delegate() { TCMaterialHelper.StartCombine(terrainCombiner); }); // Sample texture TaskQueue.Enqueue(delegate() { TCHeightmapHelper.SampleTexture(currentTask.terrainCombiner, currentTask.heightmapResolution); }); for (int nLayer = 0; nLayer < currentTask.terrainData.alphamapLayers; nLayer++) { int i = nLayer; TaskQueue.Enqueue(delegate() { TCMaterialHelper.SampleTexture(currentTask.terrainCombiner, i); }); } // Apply data TaskQueue.Enqueue(delegate() { TCHeightmapHelper.ApplyData(currentTask.terrainCombiner); }); TaskQueue.Enqueue(delegate() { TCMaterialHelper.ApplyData(currentTask.terrainCombiner); }); } } } }
public override void OnInspectorGUI() { var source = (TerrainCombinerSource)target; var terrain = source.GetComponent <Terrain>(); source.GroundLevelFraction = EditorGUILayout.FloatField("HeightDataGround", source.GroundLevelFraction); if (GUILayout.Button("Calculate ground level")) { source.GroundLevelFraction = FindGroundLevel(terrain.terrainData); EditorUtility.SetDirty(source); EditorUtility.SetDirty(source.gameObject); } source.alphaMaterial = (TerrainLayer)EditorGUILayout.ObjectField("AlphaMaterial", source.alphaMaterial, typeof(TerrainLayer), false); if (GUILayout.Button("Add alpha to terrain")) { TCMaterialHelper.AddTerrainLayer(terrain.terrainData, source.alphaMaterial); EditorUtility.SetDirty(terrain.terrainData); EditorUtility.SetDirty(source); EditorUtility.SetDirty(source.gameObject); } source.CacheDirty = true; }
public static void UpdateCombinerCache(TerrainCombiner combiner) { TerrainData terrainData = combiner.GetComponent <Terrain>().terrainData; // Update target materials from sources List <TerrainLayer> targetMatList = new List <TerrainLayer>(); for (int i = 0; i < combiner.Instances.Length; i++) { TerrainCombinerInstance sourceData = combiner.Instances[i]; if (sourceData.source == null) { continue; } Terrain sourceTerrain = sourceData.source.GetComponent <Terrain>(); foreach (var terrainLayer in sourceTerrain.terrainData.terrainLayers) { if (terrainLayer.diffuseTexture == null) { continue; } // If splay use alpha material it should not be added to target if (sourceData.source.alphaMaterial != null && terrainLayer == sourceData.source.alphaMaterial) { continue; } int index = TCMaterialHelper.GetLayerIndex(targetMatList.ToArray(), terrainLayer); if (index == -1) { targetMatList.Add(terrainLayer); } } } terrainData.terrainLayers = targetMatList.ToArray(); // TODO: release ?? combiner.MaterialCache.RenderTextures.Clear(); int size = terrainData.alphamapResolution; int targetLayerCount = terrainData.alphamapLayers; for (int i = 0; i < targetLayerCount; i++) { RenderTexture renderTexture = TCGraphicsHelper.CreateRenderTarget(size); combiner.MaterialCache.RenderTextures.Add(renderTexture); } combiner.MaterialCache.Texture = TCGraphicsHelper.CreateTexture(size); combiner.MaterialCache.ResultData = new float[size, size, terrainData.alphamapLayers]; }
private static void UpdateCaches(TerrainCombiner terrainCombiner) { // Update source caches for (int i = 0; i < terrainCombiner.Instances.Length; i++) { TerrainCombinerSource source = terrainCombiner.Instances[i].source; if (source != null && source.CacheDirty) { TCHeightmapHelper.UpdateSourceCache(source); TCMaterialHelper.UpdateSourceCache(source); source.CacheDirty = false; } } // Update target caches if (terrainCombiner.CacheDirty) { TCHeightmapHelper.UpdateCombinerCache(terrainCombiner); TCMaterialHelper.UpdateCombinerCache(terrainCombiner); terrainCombiner.CacheDirty = false; } }