Exemple #1
0
        /** \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();
        }
Exemple #2
0
        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);
            }
        }