// applying public IEnumerator ApplyRoutine () { //calling before-apply event MapMagic.CallOnGenerateCompleted(terrain); //if (MapMagic.OnGenerateCompleted != null) MapMagic.OnGenerateCompleted(terrain); MapMagic.instance.applyRunning = true; //apply foreach (KeyValuePair<Type,object> kvp in apply) { //Type output = kvp.Key; //if (!(output as Generator).enabled) continue; //if (output is SplatOutput && MapMagic.instance.gens.GetGenerator<PreviewOutput>()!=null) continue; //skip splat out if preview exists //callback MapMagic.CallOnApply(terrain, kvp.Value); //if (OnApply!=null) OnApply(terrain, kvp.Value); //selecting apply enumerator (with switch, not reflection) IEnumerator e = null; System.Type type = kvp.Key; if (type == typeof(HeightOutput)) e = HeightOutput.Apply(this); else if (type == typeof(SplatOutput)) e = SplatOutput.Apply(this); else if (type == typeof(ObjectOutput)) e = ObjectOutput.Apply(this); else if (type == typeof(TreesOutput)) e = TreesOutput.Apply(this); else if (type == typeof(GrassOutput)) e = GrassOutput.Apply(this); else if (type == typeof(RTPOutput)) e = RTPOutput.Apply(this); //apply enumerator while (e.MoveNext()) { if (terrain==null) yield break; //guard in case max terrains count < actual terrains: terrain destroyed or still processing yield return null; } } //purging unused outputs HashSet<Type> existingOutputs = MapMagic.instance.gens.GetExistingOutputTypes(onlyEnabled:true, checkBiomes:true); if (!existingOutputs.Contains(typeof(HeightOutput)) && terrain.terrainData.heightmapResolution != 33) HeightOutput.Purge(this); if (!existingOutputs.Contains(typeof(SplatOutput)) && !existingOutputs.Contains(typeof(RTPOutput)) && terrain.terrainData.alphamapResolution != 16) SplatOutput.Purge(this); if (!existingOutputs.Contains(typeof(ObjectOutput)) && terrain.transform.childCount != 0) ObjectOutput.Purge(this); if (!existingOutputs.Contains(typeof(TreesOutput)) && terrain.terrainData.treeInstanceCount != 0) TreesOutput.Purge(this); if (!existingOutputs.Contains(typeof(GrassOutput)) && terrain.terrainData.detailResolution != 16) GrassOutput.Purge(this); //previewing /* if (instance.previewOutput != null && previewObject != null) { SplatOutput.Preview((Matrix)previewObject, this); }*/ //creating initial texture if splatmap count is 0 - just to look good if (terrain.terrainData.splatPrototypes.Length == 0) ClearSplats(); //clearing intermediate results apply.Clear(); if (!MapMagic.instance.isEditor || !MapMagic.instance.saveIntermediate) { results.Clear(); ready.Clear(); } //this should be done in thread, but thread has no access to isPlaying //if (!terrain.gameObject.activeSelf) terrain.gameObject.SetActive(true); //terrain.enabled = true; MapMagic.instance.applyRunning = false; //copy layer, tag, scripts from mm to terrains if (MapMagic.instance.copyLayersTags) { GameObject go = terrain.gameObject; go.layer = MapMagic.instance.gameObject.layer; go.isStatic = MapMagic.instance.gameObject.isStatic; try { go.tag = MapMagic.instance.gameObject.tag; } catch { Debug.LogError("MapMagic: could not copy object tag"); } //#if UNITY_EDITOR //UnityEditor.GameObjectUtility.SetStaticEditorFlags(go, UnityEditor.GameObjectUtility.GetStaticEditorFlags(MapMagic.instance.gameObject)); //#endif } if (MapMagic.instance.copyComponents) { GameObject go = terrain.gameObject; MonoBehaviour[] components = MapMagic.instance.GetComponents<MonoBehaviour>(); for (int i=0; i<components.Length; i++) { if (components[i] is MapMagic || components[i] == null) continue; //if MapMagic itself or script not assigned if (terrain.gameObject.GetComponent(components[i].GetType()) == null) Extensions.CopyComponent(components[i], go); } } //calling after-apply event MapMagic.CallOnApplyCompleted(terrain); //if (MapMagic.OnApplyCompleted != null) MapMagic.OnApplyCompleted(terrain); queuedApply = false; //returning preview if it is enabled //if (MapMagic.instance.previewOutput != null) Preview(forceRefresh:true); }
//generating public void ThreadFn () { if (locked) return; lock (locker) while (true) { stop=false; //in case it was restarted start = false; clear = false; apply.Clear(); //clearing debug timers to know what generators were processed MapMagic.instance.guiDebugProcessTimes.Clear(); MapMagic.instance.guiDebugApplyTimes.Clear(); try { #region Generating Main graph first //calculating the list of changed outputs List<Generator> changedOutputs = new List<Generator>(); foreach (Generator outGen in MapMagic.instance.gens.OutputGenerators(onlyEnabled:true, checkBiomes:false)) { outGen.CheckClearRecursive(this); if (!ready.Contains(outGen)) changedOutputs.Add(outGen); } //preview (checking it twice - here and in the fn end) if (MapMagic.instance.previewGenerator!=null && MapMagic.instance.previewOutput!=null) MapMagic.instance.previewGenerator.CheckClearRecursive(this); //types of objects that were changed (for process) HashSet<System.Type> changedTypes = new HashSet<Type>(); for (int i=0; i<changedOutputs.Count; i++) { changedTypes.Add(changedOutputs[i].GetType()); //adding all of the biome outgens to processing list if (changedOutputs[i] is Biome) { Biome biome = (Biome)changedOutputs[i]; if (biome.data == null) continue; foreach (Generator outGen in biome.data.OutputGenerators(onlyEnabled:true, checkBiomes:false)) changedTypes.Add(outGen.GetType()); } } //generating for (int i=0; i<changedOutputs.Count; i++) { changedOutputs[i].GenerateWithPriors(this); if (stop) return; } #endregion #region Generating Biomes //calculating the list of changed outputs changedOutputs.Clear(); foreach (Biome biome in MapMagic.instance.gens.GeneratorsOfType<Biome>(onlyEnabled:true, checkBiomes:false)) { if (biome.data==null) continue; if (biome.mask.linkGen==null) continue; Matrix biomeMask = (Matrix)biome.mask.GetObject(this); if (biomeMask==null || biomeMask.IsEmpty()) continue; foreach (Generator outGen in biome.data.OutputGenerators(onlyEnabled:true, checkBiomes:false)) { outGen.CheckClearRecursive(this); if (!ready.Contains(outGen)) changedOutputs.Add(outGen); } } //adding changed types for (int i=0; i<changedOutputs.Count; i++) changedTypes.Add(changedOutputs[i].GetType()); //generating for (int i=0; i<changedOutputs.Count; i++) { changedOutputs[i].GenerateWithPriors(this); if (stop) return; } #endregion #region Preview if (MapMagic.instance.previewGenerator!=null && MapMagic.instance.previewOutput!=null) { MapMagic.instance.previewGenerator.CheckClearRecursive(this); MapMagic.instance.previewGenerator.GenerateWithPriors(this); if (stop) return; //if (results.ContainsKey(MapMagic.instance.previewOutput)) previewObject = results[MapMagic.instance.previewOutput]; //else previewObject = defaultMatrix; } #endregion /*//checking and resetting ready state recursive foreach (Generator outGen in MapMagic.instance.gens.OutputGenerators(onlyEnabled:true, checkBiomes:true)) //for outputs (including biomes) outGen.CheckClearRecursive(this); if (MapMagic.instance.previewOutput != null) MapMagic.instance.previewGenerator.CheckClearRecursive(this); //for preview //types of objects that were changed (for process) HashSet<System.Type> changedTypes = new HashSet<Type>(); foreach (Generator outGen in MapMagic.instance.gens.OutputGenerators(onlyEnabled:true, checkBiomes:true)) if (!ready.Contains(outGen)) changedTypes.Add(outGen.GetType()); //resseting all biome output if it has changed foreach (Biome biome in MapMagic.instance.gens.GeneratorsOfType<Biome>(onlyEnabled:true, checkBiomes:true)) if (!ready.Contains(biome) && biome.data!=null && biome.mask.linkGen!=null) { foreach (Generator outGen in biome.data.OutputGenerators(onlyEnabled:true, checkBiomes:false)) changedTypes.Add(outGen.GetType()); } //generating main foreach (Generator outGen in MapMagic.instance.gens.OutputGenerators(onlyEnabled:true, checkBiomes:true)) //generating outputs if (!ready.Contains(outGen)) outGen.GenerateWithPriors(this); if (MapMagic.instance.previewOutput != null) //generating preview { MapMagic.instance.previewGenerator.GenerateWithPriors(this); if (!stop) { if (results.ContainsKey(MapMagic.instance.previewOutput)) previewObject = results[MapMagic.instance.previewOutput]; else previewObject = defaultMatrix; } }*/ //resetting objects if height changed (to floor them) if (changedTypes.Contains(typeof(HeightOutput))) { changedTypes.Add(typeof(TreesOutput)); changedTypes.Add(typeof(ObjectOutput)); } //finalizing (processing) if (changedTypes.Contains(typeof(HeightOutput))) HeightOutput.Process(this); //typeof(HeightOutput).GetMethod("Process", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static).Invoke(null,new object[] {this}); if (changedTypes.Contains(typeof(SplatOutput))) SplatOutput.Process(this); if (changedTypes.Contains(typeof(ObjectOutput))) ObjectOutput.Process(this); if (changedTypes.Contains(typeof(TreesOutput))) TreesOutput.Process(this); if (changedTypes.Contains(typeof(GrassOutput))) GrassOutput.Process(this); if (changedTypes.Contains(typeof(RTPOutput))) RTPOutput.Process(this); } catch (System.Exception e) { Debug.LogError("Generate Thread Error:\n" + e); } //if (!stop) Thread.Sleep(2000); //exiting thread - only if it should not be restared if (!start) { queuedApply=true; break; } } }