Ejemplo n.º 1
0
			// 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);
			}
Ejemplo n.º 2
0
			//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; }
				}
			}