/** \param removeOld: Remove terrains that are not in the collector. */ private void AddTerrains(Collector collector, bool removeOld = false) { // Get new nodes HashSet <Vector2Int> toRemove = new HashSet <Vector2Int>(_terrains.Keys); foreach (var nodeName in collector.GetNewNodes()) { var node = collector.GetNode(nodeName); string terrainName = node.Mesh; IntPtr terrainHandle = collector.GetTerrainHandle(terrainName); if (terrainHandle != IntPtr.Zero) { // get bbox BBox bbox = Terrains.terrainGetBBox(terrainHandle); double size = bbox.xmax - bbox.xmin; var coords = new Vector2Int((int)(bbox.xmin / size), (int)(bbox.ymin / size)); if (!_terrains.ContainsKey(coords)) { GameObject terrainGO = new GameObject("Terrain " + coords); #if UNITY_EDITOR Undo.RegisterCreatedObjectUndo(terrainGO, "Added terrain"); #endif terrainGO.transform.SetParent(transform); var worldTerrain = terrainGO.AddComponent <WorldTerrain>(); worldTerrain.terrainSystem = this; worldTerrain.coords = coords; var terrain = terrainGO.AddComponent <Terrain>(); terrain.materialTemplate = materialTemplate; terrain.terrainData = new TerrainData(); terrainGO.AddComponent <TerrainCollider>().terrainData = terrain.terrainData; Terrains.ReadTerrainData(terrain.terrainData, terrainHandle); Terrains.ReadTerrainTextures(terrain, terrainHandle, collector, _cacheLocation); Terrains.UpdateTerrainBBox(terrain, bbox); _terrainGOs.Add(coords, terrainGO); _terrains.Add(coords, terrain); } else { toRemove.Remove(coords); } } } if (removeOld) { foreach (var key in toRemove) { DeleteTerrain(key); } } UpdateNeighbours(); }
public static void ReadTerrainTextures(Terrain terrain, IntPtr terrainHandle, Collector collector, string cacheLocation = null) { TerrainData tData = terrain.terrainData; IntPtr matHandle = terrainGetMaterial(terrainHandle); int texCount = terrainGetLayerCount(terrainHandle); TerrainLayer[] layers = new TerrainLayer[texCount]; float[,,] alphamaps = null; for (int i = 0; i < texCount; ++i) { // Distribution string distribTex = materialGetCustomMap(matHandle, "distribution" + i); IntPtr distribHandle = collector.GetTerrainHandle(distribTex); if (distribHandle != IntPtr.Zero) { int distribRes = terrainGetResolution(distribHandle); if (alphamaps == null) { alphamaps = new float[distribRes, distribRes, texCount]; tData.alphamapResolution = distribRes; } float[,] alphamap = new float[distribRes, distribRes]; readTerrain(distribHandle, alphamap, false); // TODO find more elegant way to copy data (direct copy from C++, use of Array.Copy...) for (int x = 0; x < distribRes; ++x) { for (int y = 0; y < distribRes; ++y) { alphamaps[x, y, i] = alphamap[y, x]; for (int j = 0; j < i; ++j) { alphamaps[x, y, j] *= 1 - alphamap[y, x]; } } } } // Texture string layerTex = materialGetCustomMap(matHandle, "texture" + i); #if UNITY_EDITOR if (cacheLocation == null) { #endif layers[i] = new TerrainLayer { diffuseTexture = collector.GetTexture(layerTex) } ; #if UNITY_EDITOR } else { AssetDatabase.Refresh(); string texPath = cacheLocation + layerTex + ".png"; Texture2D tex = (Texture2D)AssetDatabase.LoadAssetAtPath(texPath, typeof(Texture2D)); layers[i] = new TerrainLayer { diffuseTexture = tex }; } #endif } if (texCount != 0) { tData.terrainLayers = layers; tData.SetAlphamaps(0, 0, alphamaps); } }