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 }
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 }
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 }
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 }
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 }
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 }