예제 #1
0
        public static IEnumerator Apply(CoordRect rect, Terrain terrain, object dataBox, Func <float, bool> stop = null)
        {
                        #if RTP
            //guard if old-style rtp approach is used
            ReliefTerrain chunkRTP = terrain.gameObject.GetComponent <ReliefTerrain>();
            if (chunkRTP != null && chunkRTP.enabled)
            {
                Debug.Log("MapMagic: RTP component on terain chunk detected. RTP Output Generator works with one RTP script assigned to main MM object only. Make sure that Copy Components is turned off.");
                chunkRTP.enabled = false;
            }
            yield return(null);

            //loading objects
            RTPTuple tuple = (RTPTuple)dataBox;
            if (tuple == null)
            {
                yield break;
            }

            //creating control textures
            Texture2D controlA = new Texture2D(MapMagic.instance.resolution, MapMagic.instance.resolution);
            controlA.wrapMode = TextureWrapMode.Clamp;
            controlA.SetPixels(0, 0, controlA.width, controlA.height, tuple.colorsA);
            controlA.Apply();
            yield return(null);

            Texture2D controlB = null;
            if (tuple.colorsB != null)
            {
                controlB          = new Texture2D(MapMagic.instance.resolution, MapMagic.instance.resolution);
                controlB.wrapMode = TextureWrapMode.Clamp;
                controlB.SetPixels(0, 0, controlB.width, controlB.height, tuple.colorsB);
                controlB.Apply();
                yield return(null);
            }

            //welding
            if (MapMagic.instance != null && MapMagic.instance.splatsWeldMargins != 0)
            {
                Coord coord = Coord.PickCell(rect.offset, MapMagic.instance.resolution);
                //Chunk chunk = MapMagic.instance.chunks[coord.x, coord.z];

                Chunk neigPrevX = MapMagic.instance.chunks[coord.x - 1, coord.z];
                if (neigPrevX != null && neigPrevX.worker.ready && neigPrevX.terrain.materialTemplate.HasProperty("_Control1"))
                {
                    WeldTerrains.WeldTextureToPrevX(controlA, (Texture2D)neigPrevX.terrain.materialTemplate.GetTexture("_Control1"));
                    if (controlB != null && neigPrevX.terrain.materialTemplate.HasProperty("_Control2"))
                    {
                        WeldTerrains.WeldTextureToPrevX(controlB, (Texture2D)neigPrevX.terrain.materialTemplate.GetTexture("_Control2"));
                    }
                }

                Chunk neigNextX = MapMagic.instance.chunks[coord.x + 1, coord.z];
                if (neigNextX != null && neigNextX.worker.ready && neigNextX.terrain.materialTemplate.HasProperty("_Control1"))
                {
                    WeldTerrains.WeldTextureToNextX(controlA, (Texture2D)neigNextX.terrain.materialTemplate.GetTexture("_Control1"));
                    if (controlB != null && neigNextX.terrain.materialTemplate.HasProperty("_Control2"))
                    {
                        WeldTerrains.WeldTextureToNextX(controlB, (Texture2D)neigNextX.terrain.materialTemplate.GetTexture("_Control2"));
                    }
                }

                Chunk neigPrevZ = MapMagic.instance.chunks[coord.x, coord.z - 1];
                if (neigPrevZ != null && neigPrevZ.worker.ready && neigPrevZ.terrain.materialTemplate.HasProperty("_Control1"))
                {
                    WeldTerrains.WeldTextureToPrevZ(controlA, (Texture2D)neigPrevZ.terrain.materialTemplate.GetTexture("_Control1"));
                    if (controlB != null && neigPrevZ.terrain.materialTemplate.HasProperty("_Control2"))
                    {
                        WeldTerrains.WeldTextureToPrevZ(controlB, (Texture2D)neigPrevZ.terrain.materialTemplate.GetTexture("_Control2"));
                    }
                }

                Chunk neigNextZ = MapMagic.instance.chunks[coord.x, coord.z + 1];
                if (neigNextZ != null && neigNextZ.worker.ready && neigNextZ.terrain.materialTemplate.HasProperty("_Control1"))
                {
                    WeldTerrains.WeldTextureToNextZ(controlA, (Texture2D)neigNextZ.terrain.materialTemplate.GetTexture("_Control1"));
                    if (controlB != null && neigNextZ.terrain.materialTemplate.HasProperty("_Control2"))
                    {
                        WeldTerrains.WeldTextureToNextZ(controlB, (Texture2D)neigNextZ.terrain.materialTemplate.GetTexture("_Control2"));
                    }
                }
            }
            yield return(null);

            //assigning material propery block (not saving for fixed terrains)
            //#if UNITY_5_5_OR_NEWER
            //assign textures using material property
            //MaterialPropertyBlock matProp = new MaterialPropertyBlock();
            //matProp.SetTexture("_Control1", controlA);
            //if (controlB!=null) matProp.SetTexture("_Control2", controlB);
            //#endif

            //duplicating material and assign it's values
            //if (MapMagic.instance.customTerrainMaterial != null)
            //{
            //	//duplicating material
            //	terrain.materialTemplate = new Material(MapMagic.instance.customTerrainMaterial);
            //
            //	//assigning control textures
            //	if (terrain.materialTemplate.HasProperty("_Control1"))
            //		terrain.materialTemplate.SetTexture("_Control1", controlA);
            //	if (controlB != null && terrain.materialTemplate.HasProperty("_Control2"))
            //		terrain.materialTemplate.SetTexture("_Control2", controlB);
            //}

            if (rtp == null)
            {
                rtp = MapMagic.instance.gameObject.GetComponent <ReliefTerrain>();
            }
            if (rtp == null || rtp.globalSettingsHolder == null)
            {
                yield break;
            }

            //getting rtp material
            Material mat = null;
            if (terrain.materialTemplate != null && terrain.materialTemplate.shader.name == "Relief Pack/ReliefTerrain-FirstPas")          //if relief terrain material assigned to terrain
            {
                mat = terrain.materialTemplate;
            }
            //if (mat==null && chunk.previewBackupMaterial!=null && chunk.previewBackupMaterial.shader.name=="Relief Pack/ReliefTerrain-FirstPas") //if it is backed up for preview
            //	mat = chunk.previewBackupMaterial;
            if (mat == null)             //if still could not find material - creating new
            {
                Shader shader = Shader.Find("Relief Pack/ReliefTerrain-FirstPass");
                mat = new Material(shader);

                if (Preview.previewOutput == null)
                {
                    terrain.materialTemplate = mat;
                }
                //else chunk.previewBackupMaterial = mat;
            }
            terrain.materialType = Terrain.MaterialType.Custom;

            //setting
            rtp.RefreshTextures(mat);
            rtp.globalSettingsHolder.Refresh(mat, rtp);
            mat.SetTexture("_Control1", controlA);
            if (controlB != null)
            {
                mat.SetTexture("_Control2", controlB); mat.SetTexture("_Control3", controlB);
            }
                        #else
            yield return(null);
                        #endif
        }
예제 #2
0
        public static void Process(CoordRect rect, Chunk.Results results, GeneratorsAsset gens, Chunk.Size terrainSize, Func <float, bool> stop = null)
        {
                        #if VOXELAND
            if (stop != null && stop(0))
            {
                return;
            }
            if (voxeland == null)
            {
                return;
            }

            //finding area by rect offset
            Coord areaCoord          = Coord.PickCell(rect.offset.x, rect.offset.z, voxeland.data.areaSize);
            Voxeland5.Data.Area area = voxeland.data.areas[areaCoord.x, areaCoord.z];

            //clearing grass
            area.ClearGrass();

            //preparing random
            //Noise noise = new Noise(12345); //to switch grass depending on it's opacity

            //processing
            foreach (VoxelandGrassOutput gen in gens.GeneratorsOfType <VoxelandGrassOutput>(onlyEnabled:true, checkBiomes:true))
            {
                //reading output directly
                if (stop != null && stop(0))
                {
                    return;                                        //checking stop before reading output
                }
                //loading biome matrix
                Matrix biomeMask = null;
                if (gen.biome != null)
                {
                    object biomeMaskObj = gen.biome.mask.GetObject(results);
                    if (biomeMaskObj == null)
                    {
                        continue;                                         //adding nothing if biome has no mask
                    }
                    biomeMask = (Matrix)biomeMaskObj;
                    if (biomeMask == null)
                    {
                        continue;
                    }
                    if (biomeMask.IsEmpty())
                    {
                        continue;                                          //optimizing empty biomes
                    }
                }

                //iterating layers
                for (int l = 0; l < gen.layers.Length; l++)
                {
                    Layer layer = gen.layers[l];

                    //loading inputs
                    Matrix src = (Matrix)layer.input.GetObject(results);
                    if (src == null)
                    {
                        continue;
                    }
                    //multiplying with biome mask - in SetGrassLayer

                    //apply
                    //area.SetGrassLayer(src, (byte)l, layer.density, noise:noise, layerNum:l, mask:biomeMask);
                    area.SetGrassLayer(src.rect.offset.x, src.rect.offset.z, src.rect.size.x, src.array, (byte)l, layer.density, l, biomeMask == null? null : biomeMask.array);
                }
            }

            //pushing to apply
            if (stop != null && stop(0))
            {
                return;
            }
            results.apply.CheckAdd(typeof(VoxelandOutput), null, replace: true);
                        #endif
        }
예제 #3
0
        public static void Process(CoordRect rect, Chunk.Results results, GeneratorsAsset gens, Chunk.Size terrainSize, Func <float, bool> stop = null)
        {
                        #if VOXELAND
            if (stop != null && stop(0))
            {
                return;
            }
            if (voxeland == null)
            {
                return;
            }

            //TODO get height factor
            int heightFactor = 200;

            //finding area by rect offset
            Coord areaCoord          = Coord.PickCell(rect.offset.x, rect.offset.z, voxeland.data.areaSize);
            Voxeland5.Data.Area area = voxeland.data.areas[areaCoord.x, areaCoord.z];

            //clearing objects
            area.ClearObjects();

            //preparing random
            Noise noise = new Noise(12345);             //to disable biome objects

            //processing
            foreach (VoxelandObjectsOutput gen in gens.GeneratorsOfType <VoxelandObjectsOutput>(onlyEnabled:true, checkBiomes:true))
            {
                //reading output directly
                //Output output = gen.areaOutput;
                if (stop != null && stop(0))
                {
                    return;                                        //checking stop before reading output
                }
                //if (!results.results.ContainsKey(output)) continue;
                //Voxeland5.Data.Area genArea = (Voxeland5.Data.Area)results.results[output];

                //loading biome matrix
                Matrix biomeMask = null;
                if (gen.biome != null)
                {
                    object biomeMaskObj = gen.biome.mask.GetObject(results);
                    if (biomeMaskObj == null)
                    {
                        continue;                                         //adding nothing if biome has no mask
                    }
                    biomeMask = (Matrix)biomeMaskObj;
                    if (biomeMask == null)
                    {
                        continue;
                    }
                    if (biomeMask.IsEmpty())
                    {
                        continue;                                          //optimizing empty biomes
                    }
                }

                //iterating layers
                for (int l = 0; l < gen.layers.Length; l++)
                {
                    Layer layer = gen.layers[l];

                    //loading inputs
                    SpatialHash src = (SpatialHash)layer.input.GetObject(results);
                    if (src == null)
                    {
                        continue;
                    }

                    foreach (SpatialObject obj in src.AllObjs())
                    {
                        int objX = (int)(obj.pos.x + 0.5f);
                        int objZ = (int)(obj.pos.y + 0.5f);

                        //biome masking
                        float biomeVal = 1;
                        if (gen.biome != null)
                        {
                            if (biomeMask == null)
                            {
                                biomeVal = 0;
                            }
                            else
                            {
                                biomeVal = biomeMask[objX, objZ];
                            }
                        }
                        if (biomeVal < noise.Random(objX, objZ))
                        {
                            continue;
                        }

                        //flooring
                        float terrainHeight = layer.relativeHeight? results.heights[objX, objZ] : 0;
                        int   objHeight     = (int)((obj.height + terrainHeight) * heightFactor + 0.5f);

                        //area.AddObject(new CoordDir(objX, objHeight, objZ), (short)l);
                        area.AddObject(objX, objHeight, objZ, 0, (short)l);
                    }
                }
            }

            //pushing to apply
            if (stop != null && stop(0))
            {
                return;
            }
            results.apply.CheckAdd(typeof(VoxelandOutput), null, replace: true);
                        #endif
        }
예제 #4
0
        public static void Process(CoordRect rect, Chunk.Results results, GeneratorsAsset gens, Chunk.Size terrainSize, Func <float, bool> stop = null)
        {
                        #if VOXELAND
            if (stop != null && stop(0))
            {
                return;
            }
            if (voxeland == null)
            {
                return;
            }

            //TODO get height factor
            int heightFactor = 200;

            //finding area by rect offset
            Coord areaCoord          = Coord.PickCell(rect.offset.x, rect.offset.z, voxeland.data.areaSize);
            Voxeland5.Data.Area area = voxeland.data.areas[areaCoord.x, areaCoord.z];

            //clearing area
            area.ClearLand();

            //finding a list of areas and their opacities
            List <Voxeland5.Data.Area> areas = new List <Voxeland5.Data.Area>();
            List <Matrix> opacities          = new List <Matrix>();
            foreach (VoxelandOutput gen in gens.GeneratorsOfType <VoxelandOutput>(onlyEnabled:true, checkBiomes:true))
            {
                //reading output directly
                Output output = gen.areaOutput;
                if (stop != null && stop(0))
                {
                    return;                                        //checking stop before reading output
                }
                if (!results.results.ContainsKey(output))
                {
                    continue;
                }
                Voxeland5.Data.Area genArea = (Voxeland5.Data.Area)results.results[output];

                //loading biome matrix
                Matrix biomeMask = null;
                if (gen.biome != null)
                {
                    object biomeMaskObj = gen.biome.mask.GetObject(results);
                    if (biomeMaskObj == null)
                    {
                        continue;                                         //adding nothing if biome has no mask
                    }
                    biomeMask = (Matrix)biomeMaskObj;
                    if (biomeMask == null)
                    {
                        continue;
                    }
                    if (biomeMask.IsEmpty())
                    {
                        continue;                                          //optimizing empty biomes
                    }
                }

                areas.Add(genArea);
                opacities.Add(biomeMask);
            }

            //merge areas using biome mask
            if (areas.Count >= 2)
            //area.MixAreas(areas.ToArray(), opacities.ToArray());
            {
                float[][] opacityArrays = new float[opacities.Count][];
                for (int i = 0; i < opacityArrays.Length; i++)
                {
                    if (opacities[i] != null)
                    {
                        opacityArrays[i] = opacities[i].array;
                    }
                }
                area.MixAreas(areas.ToArray(), rect.offset.x, rect.offset.z, rect.size.x, opacityArrays);
            }
            else
            {
                Voxeland5.Data.Area.CopyLand(areas[0], area);
            }

            //reading heights
            if (results.heights == null || results.heights.rect.size.x != rect.size.x)
            {
                results.heights = new Matrix(rect);
            }
            if (results.heights.rect != rect)
            {
                results.heights.Resize(rect);
            }
            results.heights.Clear();

            for (int x = 0; x < results.heights.rect.size.x; x++)
            {
                for (int z = 0; z < results.heights.rect.size.z; z++)
                {
                    results.heights[x + results.heights.rect.offset.x, z + results.heights.rect.offset.z] = 1f * area.lines[x].columns[z].topLevel / heightFactor;
                }
            }

            //pushing to apply
            if (stop != null && stop(0))
            {
                return;
            }
            results.apply.CheckAdd(typeof(VoxelandOutput), null, replace: true);
                        #endif
        }
예제 #5
0
		public static IEnumerator Apply(CoordRect rect, Terrain terrain, object dataBox, Func<float,bool> stop= null)
		{
			#if __MEGASPLAT__
			//loading objects
			MegaSplatData tuple = (MegaSplatData)dataBox;
			if (tuple == null)
				yield break;

			//terrain.materialType = Terrain.MaterialType.Custom; //it's already done with MapMagic
			//terrain.materialTemplate = new Material(tuple.template);

			// TODO: We should pool these textures instead of creating and destroying them!

			int res = MapMagic.instance.resolution;


			//control texture
			var control = new Texture2D(res, res, MegaSplatOutput.formatARGB? TextureFormat.ARGB32 : TextureFormat.RGBA32, false, true);
			control.wrapMode = TextureWrapMode.Clamp;
			control.filterMode = FilterMode.Point;
 
			control.SetPixels(0, 0, control.width, control.height, tuple.control);
			control.Apply();
			yield return null;
			

			//param texture
			var paramTex = new Texture2D(res, res, MegaSplatOutput.formatARGB? TextureFormat.ARGB32 : TextureFormat.RGBA32, false, true);
			paramTex.wrapMode = TextureWrapMode.Clamp;
			paramTex.filterMode = FilterMode.Point;

			paramTex.SetPixels(0, 0, paramTex.width, paramTex.height, tuple.param);
			paramTex.Apply();
			yield return null;


			//welding
			if (MapMagic.instance != null && MapMagic.instance.splatsWeldMargins!=0)
			{
				Coord coord = Coord.PickCell(rect.offset, MapMagic.instance.resolution);
				//Chunk chunk = MapMagic.instance.chunks[coord.x, coord.z];
				
				Chunk neigPrevX = MapMagic.instance.chunks[coord.x-1, coord.z];
				if (neigPrevX!=null && neigPrevX.worker.ready && neigPrevX.terrain.materialTemplate.HasProperty("_SplatControl")) 
				{
					WeldTerrains.WeldTextureToPrevX(control, (Texture2D)neigPrevX.terrain.materialTemplate.GetTexture("_SplatControl"));
					control.Apply();
				}

				Chunk neigNextX = MapMagic.instance.chunks[coord.x+1, coord.z];
				if (neigNextX!=null && neigNextX.worker.ready && neigNextX.terrain.materialTemplate.HasProperty("_SplatControl")) 
				{
					WeldTerrains.WeldTextureToNextX(control, (Texture2D)neigNextX.terrain.materialTemplate.GetTexture("_SplatControl"));
					control.Apply();
				}
				
				Chunk neigPrevZ = MapMagic.instance.chunks[coord.x, coord.z-1];
				if (neigPrevZ!=null && neigPrevZ.worker.ready && neigPrevZ.terrain.materialTemplate.HasProperty("_SplatControl")) 
				{
					WeldTerrains.WeldTextureToPrevZ(control, (Texture2D)neigPrevZ.terrain.materialTemplate.GetTexture("_SplatControl"));
					control.Apply();
				}

				Chunk neigNextZ = MapMagic.instance.chunks[coord.x, coord.z+1];
				if (neigNextZ!=null && neigNextZ.worker.ready && neigNextZ.terrain.materialTemplate.HasProperty("_SplatControl")) 
				{
					WeldTerrains.WeldTextureToNextZ(control, (Texture2D)neigNextZ.terrain.materialTemplate.GetTexture("_SplatControl"));
					control.Apply();
				}
			}
			yield return null;




			//TODO: weld textures with 1-pixel margin

			//assign textures using material property (not saving for fixed terrains)
			//#if UNITY_5_5_OR_NEWER
			//MaterialPropertyBlock matProp = new MaterialPropertyBlock();
			//matProp.SetTexture("_SplatControl", control);
			//matProp.SetTexture("_SplatParams", paramTex);
			//matProp.SetFloat("_ControlSize", res);
			//terrain.SetSplatMaterialPropertyBlock(matProp);
			//#endif

			//duplicating material
			if (MapMagic.instance.customTerrainMaterial != null)
			{
				terrain.materialTemplate = new Material(MapMagic.instance.customTerrainMaterial);

				//assigning control textures
				if (terrain.materialTemplate.HasProperty("_SplatControl"))
					terrain.materialTemplate.SetTexture("_SplatControl", control);
				if (terrain.materialTemplate.HasProperty("_SplatParams"))
					terrain.materialTemplate.SetTexture("_SplatParams", paramTex);
			}

			#else
			yield return null;
			#endif
		}
예제 #6
0
        public static new IEnumerator Apply(CoordRect rect, Terrain terrain, object dataBox, Func <float, bool> stop = null)
        {
                        #if CTS_PRESENT
            float[,,] splats3D = (float[, , ])dataBox;

            if (splats3D.GetLength(2) == 0)
            {
                Purge(rect, terrain); yield break;
            }

            TerrainData data = terrain.terrainData;

            //setting resolution
            int size = splats3D.GetLength(0);
            if (data.alphamapResolution != size)
            {
                data.alphamapResolution = size;
            }

            //welding
            if (MapMagic.instance != null && MapMagic.instance.splatsWeldMargins != 0)
            {
                Coord coord = Coord.PickCell(rect.offset, MapMagic.instance.resolution);
                //Chunk chunk = MapMagic.instance.chunks[coord.x, coord.z];

                Chunk neigPrevX = MapMagic.instance.chunks[coord.x - 1, coord.z];
                if (neigPrevX != null && neigPrevX.worker.ready)
                {
                    WeldTerrains.WeldSplatToPrevX(ref splats3D, neigPrevX.terrain, MapMagic.instance.splatsWeldMargins);
                }

                Chunk neigNextX = MapMagic.instance.chunks[coord.x + 1, coord.z];
                if (neigNextX != null && neigNextX.worker.ready)
                {
                    WeldTerrains.WeldSplatToNextX(ref splats3D, neigNextX.terrain, MapMagic.instance.splatsWeldMargins);
                }

                Chunk neigPrevZ = MapMagic.instance.chunks[coord.x, coord.z - 1];
                if (neigPrevZ != null && neigPrevZ.worker.ready)
                {
                    WeldTerrains.WeldSplatToPrevZ(ref splats3D, neigPrevZ.terrain, MapMagic.instance.splatsWeldMargins);
                }

                Chunk neigNextZ = MapMagic.instance.chunks[coord.x, coord.z + 1];
                if (neigNextZ != null && neigNextZ.worker.ready)
                {
                    WeldTerrains.WeldSplatToNextZ(ref splats3D, neigNextZ.terrain, MapMagic.instance.splatsWeldMargins);
                }
            }
            yield return(null);

            //number of splat prototypes should match splats3D layers
            if (data.alphamapLayers != splats3D.GetLength(2))
            {
                SplatPrototype[] prototypes = new SplatPrototype[splats3D.GetLength(2)];
                for (int i = 0; i < prototypes.Length; i++)
                {
                    prototypes[i] = new SplatPrototype()
                    {
                        texture = SplatOutput.defaultTex
                    }
                }
                ;
                data.splatPrototypes = prototypes;
            }

            //setting
            data.SetAlphamaps(0, 0, splats3D);

            //alphamap textures hide flag
            //data.alphamapTextures[0].hideFlags = HideFlags.None;


            //assigning CTS
            CTS.CompleteTerrainShader cts = terrain.gameObject.GetComponent <CTS.CompleteTerrainShader>();
            if (cts == null)
            {
                cts = terrain.gameObject.AddComponent <CTS.CompleteTerrainShader>();
            }
            cts.Profile = ctsProfile;



            cts.UpdateShader();

            yield return(null);
                        #else
            yield return(null);
                        #endif
        }