Example #1
0
			public void SetSettings ()
			{
				MapMagic magic = MapMagic.instance;

				terrain.heightmapPixelError = magic.pixelError;
				if (magic.showBaseMap) terrain.basemapDistance = magic.baseMapDist;
				else terrain.basemapDistance = 999999;
				terrain.castShadows = magic.castShadows;
				
				if (terrainCollider==null) terrainCollider = terrain.GetComponent<TerrainCollider>();
				if (terrainCollider!=null) terrainCollider.enabled = MapMagic.instance.applyColliders;

				//material
				if (!Preview.enabled)
				{
					terrain.materialType = MapMagic.instance.terrainMaterialType;

					if (MapMagic.instance.terrainMaterialType == Terrain.MaterialType.Custom && MapMagic.instance.assignCustomTerrainMaterial)
						terrain.materialTemplate = MapMagic.instance.customTerrainMaterial;

					/*if (MapMagic.instance.terrainMaterialType == Terrain.MaterialType.Custom)
					{
						if (MapMagic.instance.materialTemplateMode)
						{
							//assigning new mat only it has different name or shader in template mode
							if (terrain.materialTemplate == null || terrain.materialTemplate.shader != MapMagic.instance.customTerrainMaterial.shader || terrain.materialTemplate.name != MapMagic.instance.customTerrainMaterial.name)
								terrain.materialTemplate = MapMagic.instance.customTerrainMaterial;
						}
						else
							terrain.materialTemplate = MapMagic.instance.customTerrainMaterial;

//						terrain.materialTemplate = MapMagic.instance.customTerrainMaterial;
					}*/
				}

				terrain.drawTreesAndFoliage = magic.detailDraw;
				terrain.detailObjectDistance = magic.detailDistance;
				terrain.detailObjectDensity = magic.detailDensity;
				terrain.treeDistance = magic.treeDistance;
				terrain.treeBillboardDistance = magic.treeBillboardStart;
				terrain.treeCrossFadeLength = magic.treeFadeLength;
				terrain.treeMaximumFullLODCount = magic.treeFullLod;
				#if UNITY_EDITOR
				terrain.bakeLightProbesForTrees = magic.bakeLightProbesForTrees;
				#endif

				terrain.terrainData.wavingGrassSpeed = magic.windSpeed;
				terrain.terrainData.wavingGrassAmount = magic.windSize;
				terrain.terrainData.wavingGrassStrength = magic.windBending;
				terrain.terrainData.wavingGrassTint = magic.grassTint;

				//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 (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);
					}
				}
			}
Example #2
0
			public void Preview ()
			{
				#if UNITY_EDITOR 
				if (Event.current == null || Event.current.type != EventType.Repaint) return;
					
				//clearing preview if prevew generator is off (or non-map)
				if (MapMagic.instance.previewOutput==null || MapMagic.instance.previewOutput.type!=Generator.InoutType.Map)
				{
					if (terrain.materialTemplate != null && terrain.materialTemplate.shader.name == "MapMagic/TerrainPreviewFirstPass")
					{
						terrain.materialType = MapMagic.ToUnityTerrMatType(MapMagic.instance.terrainMaterialType);
						terrain.materialTemplate = previewBackupMaterial;

						previewBackupMaterial = null;
						lastPreviewedMatrix = null;

						UnityEditor.SceneView.RepaintAll();
					}
				}
						
				if (MapMagic.instance.previewOutput!=null && MapMagic.instance.previewOutput.type == Generator.InoutType.Map)
				{
					//loading preview material from terrain (or creating new)
					Material previewMat = null;
					if (terrain.materialTemplate!=null && terrain.materialTemplate.shader.name=="MapMagic/TerrainPreviewFirstPass") previewMat = terrain.materialTemplate;
					if (previewMat == null) 
					{
						Shader previewShader = Shader.Find("MapMagic/TerrainPreviewFirstPass");
						previewMat = new Material(previewShader);

						previewBackupMaterial = terrain.materialTemplate;
						terrain.materialTemplate = previewMat;
						terrain.materialType = Terrain.MaterialType.Custom;
						
						UnityEditor.SceneView.RepaintAll();
					}

					//loading matrix
					Matrix matrix = MapMagic.instance.previewOutput.GetObject<Matrix>(this);

					//refreshing preview texture
					if (matrix != lastPreviewedMatrix)
					{
						Texture2D tex = null;
						
						//populate
						if (matrix != null) 
						{
							tex = new Texture2D(matrix.rect.size.x, matrix.rect.size.z);
			 
							Color[] line = new Color[matrix.rect.size.z];
							for (int x=0; x<matrix.rect.size.x; x++)
							{
								for (int z=0; z<matrix.rect.size.z; z++)
								{
									float val = matrix[x+matrix.rect.offset.x, z+matrix.rect.offset.z];
									line[z] = new Color(val, val, val);
								}
								tex.SetPixels(x,0,1,line.Length,line);
							}
						}
						else //in case the output is not generated
						{
							tex = Extensions.ColorTexture(2,2,Color.gray);
						}

						//apply
						tex.Apply();
						previewMat.SetTexture("_Preview", tex);
						if (MapMagic.instance.guiDebug) Debug.Log("Preview Applied");

						lastPreviewedMatrix = matrix;

						UnityEditor.SceneView.RepaintAll();
					}
				}

				//spatial hash
				if (MapMagic.instance.previewOutput!=null && MapMagic.instance.previewOutput.type == Generator.InoutType.Objects)
				{
					float pixelSize = 1f * MapMagic.instance.terrainSize / MapMagic.instance.resolution;
					
					SpatialHash objs = MapMagic.instance.previewOutput.GetObject<SpatialHash>(this);

					if (objs != null)
					{
						int objsCount = objs.Count;
						foreach (SpatialObject obj in objs)
						{
							float terrainHeight = 0;
							if (heights != null) terrainHeight = heights.GetInterpolated(obj.pos.x, obj.pos.y);
							Vector3 pos = new Vector3(obj.pos.x*pixelSize, (obj.height+terrainHeight)*MapMagic.instance.terrainHeight, obj.pos.y*pixelSize);
							pos += MapMagic.instance.transform.position;

							UnityEditor.Handles.color = new Color(1,1,1,1);
							UnityEditor.Handles.DrawLine(pos+new Vector3(obj.size/2f,0,0), pos-new Vector3(obj.size/2f,0,0));
							UnityEditor.Handles.DrawLine(pos+new Vector3(0,0,obj.size/2f), pos-new Vector3(0,0,obj.size/2f));

							if (objsCount < 100)
							{
								Vector3 oldPoint = pos;
								foreach (Vector3 point in pos.CircleAround(obj.size/2f, 12, true))
								{
									UnityEditor.Handles.DrawLine(oldPoint,point);
									oldPoint = point;
								}
							}

							UnityEditor.Handles.color = new Color(1,1,1,0.15f); 
							UnityEditor.Handles.DrawLine(new Vector3(pos.x, 0, pos.z), new Vector3(pos.x, MapMagic.instance.terrainHeight, pos.z));
						}
					}
				}

				#endif
			}
Example #3
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);
			}
Example #4
0
			public void ClearSplats () //same as SplatOutput.Clear
			{
				terrain.terrainData.splatPrototypes = new SplatPrototype[] { new SplatPrototype() { texture = Extensions.ColorTexture(2,2,new Color(0.5f, 0.5f, 0.5f, 0f)) } };

				float[,,] emptySplats = new float[16,16,1];
				for (int x=0; x<16; x++)
					for (int z=0; z<16; z++)
						emptySplats[z,x,0] = 1;

				terrain.terrainData.alphamapResolution = 16;
				terrain.terrainData.SetAlphamaps(0,0,emptySplats);

				if (MapMagic.instance.guiDebug) Debug.Log("Splats Cleared");
			}
Example #5
0
		public void Update () 
		{ 
			//shifting world
			if (!isEditor && shift) WorldShifter.Update(shiftThreshold, shiftExcludeLayers);

			//checking if instance already exists and disabling if it is another mm
			if (instance != null && instance != this) { Debug.LogError("MapMagic object already present in scene. Disabling duplicate"); this.enabled = false; return; }
		
			//do nothing if chink size is zero
			if (terrainSize < 0.1f) return;

			//finding camera positions
			camPoses = Extensions.GetCamPoses(genAroundMainCam:genAroundMainCam, genAroundTag:genAroundObjsTag? genAroundTag : null, camPoses:camPoses);
			if (camPoses.Length == 0) return; //no cameras to deploy Voxeland
			transform.InverseTransformPoint(camPoses); 
				
			//deploy
			if (!isEditor && generateInfinite) 
			{
				//finding deploy rects
				if (deployRects == null || deployRects.Length!=camPoses.Length)
				{
					deployRects = new CoordRect[camPoses.Length]; 
					removeRects = new CoordRect[camPoses.Length];
				}
				
				for (int r=0; r<camPoses.Length; r++) //TODO: add cam pos change check
				{
					deployRects[r] = CoordRect.PickIntersectingCellsByPos(camPoses[r], generateRange, cellSize:terrainSize);
					removeRects[r] = CoordRect.PickIntersectingCellsByPos(camPoses[r], removeRange, cellSize:terrainSize);
				}

				//checking and deploying
				bool chunksChange = chunks.CheckDeploy(deployRects);
				if (chunksChange) chunks.Deploy(deployRects, removeRects, parent:this, allowMove:true);
			}

			//updating chunks
			foreach (Chunk chunk in chunks.All()) 
			{
				//removing (unpinning) chunk if it's terrain was removed somehow
				if (chunk.terrain==null || chunk.terrain.transform==null || chunk.terrain.terrainData==null) { chunk.pinned = false; return; } //TODO: causes out of sync error

				//distance, priority and visibility
				float distance = camPoses.DistToRectAxisAligned(chunk.coord.x*terrainSize, chunk.coord.z*terrainSize, terrainSize);
				chunk.worker.priority = 1f / distance;

				//starting generate
				if ((distance<MapMagic.instance.generateRange || MapMagic.instance.isEditor) && chunk.worker.blank && !chunk.locked && instantGenerate) chunk.worker.Start(); 

				//enabling/disabling (after starting generate to avoid blink)
				if (!MapMagic.instance.isEditor && //if non-editor
					(
					(!chunk.worker.ready && !chunk.locked) || //if non-ready
					(MapMagic.instance.hideFarTerrains && distance>MapMagic.instance.enableRange) //or if out of range in playmode
					)	) 
					//TODO: it works but I don't like the way it formatted
						{ if (chunk.terrain.gameObject.activeSelf) chunk.terrain.gameObject.SetActive(false); } //disabling
				else 
					{ if (!chunk.terrain.gameObject.activeSelf) chunk.terrain.gameObject.SetActive(true); } //enabling
					

				//setting terrain neighbors (they reset after each serialize)
				chunk.SetNeighbors(); //TODO: try doing in ondeserialize
			}


			//updating threads
			ThreadWorker.multithreading = multithreading;
			ThreadWorker.maxThreads = maxThreads; 
			ThreadWorker.autoMaxThreads = autoMaxThreads;
			ThreadWorker.maxApplyTime = maxApplyTime;
			ThreadWorker.Refresh();

            //Water
            doWater();
           
        }