public void ApplyUNature(Terrain terrain) /// Just in case I'll need to return compatibility { uNatureGrassTuple uNatureTuple = null; if (FoliageCore_MainManager.instance != null) { uNatureTuple = (uNatureGrassTuple)dataBox; grassTuple = uNatureTuple.tupleInformation; } else { //Debug.LogError("uNature_MapMagic extension is enabled but no foliage manager exists on the scene."); //yield break; grassTuple = (TupleSet <int[][, ], DetailPrototype[]>)dataBox; } int[][,] details = grassTuple.item1; DetailPrototype[] prototypes = grassTuple.item2; //resolution int resolution = details[0].GetLength(1); terrain.terrainData.SetDetailResolution(resolution, patchResolution); if (FoliageCore_MainManager.instance != null) { UNMapMagic_Manager.RegisterGrassPrototypesChange(prototypes); } //prototypes terrain.terrainData.detailPrototypes = prototypes; if (FoliageCore_MainManager.instance != null) { UNMapMagic_Manager.ApplyGrassOutput(uNatureTuple); } else { //Debug.LogError("uNature_MapMagic extension is enabled but no foliage manager exists on the scene."); //yield break; for (int i = 0; i < details.Length; i++) { terrain.terrainData.SetDetailLayer(0, 0, i, details[i]); } } }
public IEnumerator Apply(MapMagic.CoordRect rect, Terrain terrain, object dataBox, Func <float, bool> stop = null) { //init heights #if UN_MapMagic #if WDEBUG Profiler.BeginSample("UNature"); #endif uNatureHeightTuple heightTuple; float[,] heights2D; if (FoliageCore_MainManager.instance != null) { heightTuple = (uNatureHeightTuple)dataBox; // get data heights2D = heightTuple.normalizedHeights; UNMapMagic_Manager.ApplyHeightOutput(heightTuple, terrain); } else { //Debug.LogError("uNature_MapMagic extension is enabled but no foliage manager exists on the scene."); //yield break; heights2D = (float[, ])dataBox; } #if WDEBUG Profiler.EndSample(); #endif #else float[,] heights2D = (float[, ])dataBox; #endif heights2D = heights2D.Flip(); //quick lod apply /*if (chunk.lod) * { * //if (chunk.lodTerrain == null) { chunk.lodTerrain = (MapMagic.instance.transform.AddChild("Terrain " + chunk.coord.x + "," + chunk.coord.z + " LOD")).gameObject.AddComponent<Terrain>(); chunk.lodTerrain.terrainData = new TerrainData(); } * if (chunk.lodTerrain.terrainData==null) chunk.lodTerrain.terrainData = new TerrainData(); * * chunk.lodTerrain.Resize(heights2D.GetLength(0), new Vector3(MapMagic.instance.terrainSize, MapMagic.instance.terrainHeight, MapMagic.instance.terrainSize)); * chunk.lodTerrain.terrainData.SetHeightsDelayLOD(0,0,heights2D); * * yield break; * }*/ //determining data if (terrain == null || terrain.terrainData == null) { yield break; //chunk removed during apply } TerrainData data = terrain.terrainData; //resizing terrain (standard terrain resize is extremely slow. Even when creating a new terrain) Vector3 terrainSize = terrain.terrainData.size; //new Vector3(MapMagic.instance.terrainSize, MapMagic.instance.terrainHeight, MapMagic.instance.terrainSize); int terrainResolution = heights2D.GetLength(0); //heights2D[0].GetLength(0); if ((data.size - terrainSize).sqrMagnitude > 0.01f || data.heightmapResolution != terrainResolution) { if (terrainResolution <= 64) //brute force { data.heightmapResolution = terrainResolution; data.size = new Vector3(terrainSize.x, terrainSize.y, terrainSize.z); } else //setting res 64, re-scaling to 1/64, and then changing res { data.heightmapResolution = 65; terrain.Flush(); //otherwise unity crushes without an error int resFactor = (terrainResolution - 1) / 64; data.size = new Vector3(terrainSize.x / resFactor, terrainSize.y, terrainSize.z / resFactor); data.heightmapResolution = terrainResolution; } } yield return(null); var heightSize = heights2D.GetLength(0); for (int x = 0; x < heightSize - 1; x++) { for (int z = 0; z < heightSize - 1; z++) { heights2D[z, x] = Mathf.Clamp01(heights2D[z, x]); } } var wrapper = terrain.gameObject.GetOrAddComponent <TerrainWrapper>(); var MMTerrainLayer = wrapper.GetLayer <MMTerrainLayer>(LayerName, false, true); MMTerrainLayer.SetHeights(0, 0, heights2D, MapMagic.MapMagic.instance.resolution + 1); _pendingWrappers.Remove(rect); //welding if (MapMagic.MapMagic.instance != null && MapMagic.MapMagic.instance.heightWeldMargins != 0) { MapMagic.Coord coord = MapMagic.Coord.PickCell(rect.offset, MapMagic.MapMagic.instance.resolution); Chunk chunk = MapMagic.MapMagic.instance.chunks[coord.x, coord.z]; Chunk neigPrevX = MapMagic.MapMagic.instance.chunks[coord.x - 1, coord.z]; if (neigPrevX != null && !_pendingWrappers.Contains(neigPrevX.rect) && neigPrevX.terrain && neigPrevX.terrain.terrainData.heightmapResolution == terrainResolution) { var neighbourWrapper = neigPrevX.terrain.GetComponent <TerrainWrapper>(); if (neigPrevX.worker.ready && neighbourWrapper) { WeldTerrains.WeldToPrevZ(ref heights2D, neighbourWrapper, MapMagic.MapMagic.instance.heightWeldMargins); } //WeldTerrains.WeldToPrevX(ref heights2D, neighbourWrapper, MapMagic.MapMagic.instance.heightWeldMargins); Chunk.SetNeigsX(neigPrevX, chunk); } Chunk neigNextX = MapMagic.MapMagic.instance.chunks[coord.x + 1, coord.z]; if (neigNextX != null && !_pendingWrappers.Contains(neigNextX.rect) && neigNextX.terrain.terrainData.heightmapResolution == terrainResolution) { var neighbourWrapper = neigNextX.terrain.GetComponent <TerrainWrapper>(); if (neigNextX.worker.ready && neighbourWrapper) { WeldTerrains.WeldToNextZ(ref heights2D, neighbourWrapper, MapMagic.MapMagic.instance.heightWeldMargins); } //WeldTerrains.WeldToNextX(ref heights2D, neighbourWrapper, MapMagic.MapMagic.instance.heightWeldMargins); Chunk.SetNeigsX(chunk, neigNextX); } Chunk neigPrevZ = MapMagic.MapMagic.instance.chunks[coord.x, coord.z - 1]; if (neigPrevZ != null && !_pendingWrappers.Contains(neigPrevZ.rect) && neigPrevZ.terrain.terrainData.heightmapResolution == terrainResolution) { var neighbourWrapper = neigPrevZ.terrain.GetComponent <TerrainWrapper>(); if (neigPrevZ.worker.ready && neighbourWrapper) { //WeldTerrains.WeldToNextX(ref heights2D, neighbourWrapper, MapMagic.MapMagic.instance.heightWeldMargins); WeldTerrains.WeldToPrevX(ref heights2D, neighbourWrapper, MapMagic.MapMagic.instance.heightWeldMargins); } Chunk.SetNeigsZ(neigPrevZ, chunk); } Chunk neigNextZ = MapMagic.MapMagic.instance.chunks[coord.x, coord.z + 1]; if (neigNextZ != null && !_pendingWrappers.Contains(neigNextZ.rect) && neigNextZ.terrain.terrainData.heightmapResolution == terrainResolution) { var neighbourWrapper = neigNextZ.terrain.GetComponent <TerrainWrapper>(); if (neigNextZ.worker.ready && neighbourWrapper) { //WeldTerrains.WeldToPrevX(ref heights2D, neighbourWrapper, MapMagic.MapMagic.instance.heightWeldMargins); WeldTerrains.WeldToNextX(ref heights2D, neighbourWrapper, MapMagic.MapMagic.instance.heightWeldMargins); } Chunk.SetNeigsZ(chunk, neigNextZ); } } yield return(null); MMTerrainLayer.SetHeights(0, 0, heights2D, MapMagic.MapMagic.instance.resolution + 1); global::MapMagic.MapMagic.OnApplyCompleted -= MapMagicIntegrationUtilities.MapMagicOnOnApplyCompleted; global::MapMagic.MapMagic.OnApplyCompleted += MapMagicIntegrationUtilities.MapMagicOnOnApplyCompleted; wrapper.SetDirtyAbove(MMTerrainLayer); yield return(null); }