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 RTP if (stop != null && stop(0)) { return; } //finding number of layers int layersCount = 0; foreach (RTPOutput gen in MapMagic.instance.gens.GeneratorsOfType <RTPOutput>(onlyEnabled:true, checkBiomes:true)) { layersCount = gen.baseLayers.Length; break; } //creating color arrays RTPTuple result = new RTPTuple(); result.colorsA = new Color[MapMagic.instance.resolution * MapMagic.instance.resolution]; if (layersCount > 4) { result.colorsB = new Color[MapMagic.instance.resolution * MapMagic.instance.resolution]; } //filling color arrays foreach (RTPOutput gen in MapMagic.instance.gens.GeneratorsOfType <RTPOutput>(onlyEnabled:true, checkBiomes:true)) { //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 } } for (int i = 0; i < gen.baseLayers.Length; i++) { //reading output directly Output output = gen.baseLayers[i].output; if (stop != null && stop(0)) { return; //checking stop before reading output } if (!results.results.ContainsKey(output)) { continue; } Matrix matrix = (Matrix)results.results[output]; if (matrix.IsEmpty()) { continue; } for (int x = 0; x < rect.size.x; x++) { for (int z = 0; z < rect.size.z; z++) { int pos = matrix.rect.GetPos(x + matrix.rect.offset.x, z + matrix.rect.offset.z); //pos should be the same for colors array and matrix array //get value and adjust with biome mask float val = matrix.array[pos]; float biomeVal = biomeMask != null? biomeMask.array[pos] : 1; val *= biomeVal; //save value to colors array switch (gen.baseLayers[i].index) { case 0: result.colorsA[pos].r += val; break; case 1: result.colorsA[pos].g += val; break; case 2: result.colorsA[pos].b += val; break; case 3: result.colorsA[pos].a += val; break; case 4: result.colorsB[pos].r += val; break; case 5: result.colorsB[pos].g += val; break; case 6: result.colorsB[pos].b += val; break; case 7: result.colorsB[pos].a += val; break; } } } if (stop != null && stop(0)) { return; } } } //TODO: normalizing color arrays (if needed) //pushing to apply if (stop != null && stop(0)) { return; } results.apply.CheckAdd(typeof(RTPOutput), result, replace: true); #endif }