public IEnumerator Apply(MapMagic.CoordRect rect, Terrain terrain, object dataBox, Func <float, bool> stop = null) { TupleSet <float[, , ], SplatPrototypeWrapper[]> splatsTuple = (TupleSet <float[, , ], SplatPrototypeWrapper[]>)dataBox; float[,,] splats3D = splatsTuple.item1; SplatPrototypeWrapper[] prototypes = splatsTuple.item2; 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; //checking prototypes texture for (int i = 0; i < prototypes.Length; i++) { if (prototypes[i].Texture == null) { prototypes[i].Texture = defaultTex; } } yield return(null); //welding if (MapMagic.MapMagic.instance != null && MapMagic.MapMagic.instance.splatsWeldMargins != 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 && neigPrevX.worker.ready) { WeldTerrains.WeldSplatToPrevX(ref splats3D, neigPrevX.terrain, MapMagic.MapMagic.instance.splatsWeldMargins); } Chunk neigNextX = MapMagic.MapMagic.instance.chunks[coord.x + 1, coord.z]; if (neigNextX != null && neigNextX.worker.ready) { WeldTerrains.WeldSplatToNextX(ref splats3D, neigNextX.terrain, MapMagic.MapMagic.instance.splatsWeldMargins); } Chunk neigPrevZ = MapMagic.MapMagic.instance.chunks[coord.x, coord.z - 1]; if (neigPrevZ != null && neigPrevZ.worker.ready) { WeldTerrains.WeldSplatToPrevZ(ref splats3D, neigPrevZ.terrain, MapMagic.MapMagic.instance.splatsWeldMargins); } Chunk neigNextZ = MapMagic.MapMagic.instance.chunks[coord.x, coord.z + 1]; if (neigNextZ != null && neigNextZ.worker.ready) { WeldTerrains.WeldSplatToNextZ(ref splats3D, neigNextZ.terrain, MapMagic.MapMagic.instance.splatsWeldMargins); } } yield return(null); terrain.terrainData.splatPrototypes = new[] { new SplatPrototype() { texture = defaultTex } }; // To stop MapMagic purging what we're doing here alter on... var wrapper = terrain.gameObject.GetOrAddComponent <TerrainWrapper>(); var MMTerrainLayer = wrapper.GetLayer <MMTerrainLayer>(LayerName, false, true); MMTerrainLayer.SplatData.Clear(); var splatWidth = splats3D.GetLength(0); var splatHeight = splats3D.GetLength(1); if (terrain.terrainData.alphamapResolution != splatWidth) { Debug.Log("Set alphamapResolution to " + splatWidth); terrain.terrainData.alphamapResolution = splatWidth; } var data = new float[splatWidth, splatHeight]; for (int i = 0; i < prototypes.Length; i++) { var splatPrototypeWrapper = prototypes[i]; for (var u = 0; u < splatWidth; ++u) { for (var v = 0; v < splatHeight; ++v) { data[v, u] = splats3D[u, v, i]; } } MMTerrainLayer.SetSplatmap(splatPrototypeWrapper, 0, 0, data, splatWidth); } global::MapMagic.MapMagic.OnApplyCompleted -= MapMagicIntegrationUtilities.MapMagicOnOnApplyCompleted; global::MapMagic.MapMagic.OnApplyCompleted += MapMagicIntegrationUtilities.MapMagicOnOnApplyCompleted; wrapper.SetDirtyAbove(MMTerrainLayer); yield return(null); }
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); }