예제 #1
0
        /// <summary>
        /// Creates splatmaps which are (by default) applied to terrain splat shaders.
        /// </summary>
        /// <param name="applySplats">When true, the generated splat is automatically applied to the terrain.
        /// Otherwise, it can be applied by calling ApplySplatmapsToShader</param>
        /// <param name="debug">When true, the generated alpha maps are saved to the disk.
        /// They're located at [Your project's root dir]/SplatImages/</param>
        /// <returns>Created alphamap textures</returns>
        public List <Texture2D> GenerateSplatmaps(bool applySplats = true)
        {
            //Ensure correct shader is set
            SetFirstPassShader(true);

            //Set amount of required maps
            List <Texture2D> maps = new List <Texture2D>();

            for (int i = 0; i < Mathf.CeilToInt(SplatSettings.Count / 4f); i++)
            {
                maps.Add(new Texture2D(AlphaMapResolution, AlphaMapResolution));
            }

            //Sample weights and fill in textures
            for (int x = 0; x < AlphaMapResolution; x++)
            {
                for (int y = 0; y < AlphaMapResolution; y++)
                {
                    MeshSampler.MeshSample sample = Sampler.SampleAt(y / (float)AlphaMapResolution, x / (float)AlphaMapResolution);
                    AddWeightsToTextures(CalculateWeights(sample), ref maps, y, x);
                }
            }

            if (TerraDebug.WRITE_SPLAT_TEXTURES)
            {
                TerrainTile tile = TerrainObject.GetComponent <TerrainTile>();

                string tileName = tile != null ?
                                  "Tile[" + tile.Position.x + "_" + tile.Position.y + "]" :
                                  "Tile[0_0]";
                string folderPath = Application.dataPath + "/SplatImages/";
                if (!Directory.Exists(folderPath))
                {
                    Directory.CreateDirectory(folderPath);
                }

                for (var i = 0; i < maps.Count; i++)
                {
                    byte[] bytes = maps[i].EncodeToPNG();
                    string name  = "Splat" + i + "_" + tileName + ".png";
                    File.WriteAllBytes(folderPath + name, bytes);
                }
            }

            //Apply set pixel values to textures
            maps.ForEach(t => t.Apply());
            if (applySplats)
            {
                ApplySplatmapsToShaders(maps);
            }

            return(maps);
        }
예제 #2
0
        /// <summary>
        /// First creates a poisson grid based on the passed density.
        /// Positions are then filtered based on the passed object placement
        /// type taking into account height and angle constraints.
        ///
        /// Unlike the <c>GetFilteredGrid(ObjectPlacementType, float)</c> method
        /// this method samples from the passed Mesh rather than pulling
        /// mesh information from TerraSettings.
        /// </summary>
        /// <param name="m">Mesh to sample height and angle values from</param>
        /// <param name="type">object placement type to sample</param>
        /// <returns>List of vectors within the grid and sample constraints</returns>
        public List <Vector3> GetFilteredGrid(Mesh m, ObjectPlacementType type)
        {
            MeshSampler    sampler = new MeshSampler(m, Settings.MeshResolution);
            List <Vector2> grid    = GetPoissonGrid(type.Spread / 10);
            List <Vector3> toAdd   = new List <Vector3>();

            foreach (Vector2 pos in grid)
            {
                MeshSampler.MeshSample sample = sampler.SampleAt(pos.x, pos.y);

                if (type.ShouldPlaceAt(sample.Height, sample.Angle))
                {
                    Vector3 newPos = new Vector3(pos.x, sample.Height, pos.y);
                    toAdd.Add(newPos);
                }
            }

            return(toAdd);
        }
        /// <summary>
        /// First creates a poisson grid based on the passed density.
        /// Positions are then filtered based on the passed object placement
        /// type taking into account height and angle constraints.
        ///
        /// Unlike the <c>GetFilteredGrid(ObjectPlacementType, float)</c> method
        /// this method samples from the passed Mesh rather than pulling
        /// mesh information from TerraSettings.
        /// </summary>
        /// <param name="m">Mesh to sample height and angle values from</param>
        /// <param name="objectPlacementData">object placement type to sample</param>
        /// <returns>List of vectors within the grid and sample constraints</returns>
        public List <Vector3> GetFilteredGrid(Mesh m, ObjectPlacementData objectPlacementData)
        {
            MeshSampler    sampler = /**new MeshSampler(m, Settings.Generator.MeshResolution);*/ new MeshSampler(m, 128);          //TODO Resolution from TerraSettings
            List <Vector2> grid    = GetPoissonGrid(objectPlacementData.Spread / 10);
            List <Vector3> toAdd   = new List <Vector3>();

            foreach (Vector2 pos in grid)
            {
                MeshSampler.MeshSample sample = sampler.SampleAt(pos.x, pos.y);

                if (objectPlacementData.ShouldPlaceAt(sample.Height, sample.Angle))
                {
                    Vector3 newPos = new Vector3(pos.x, sample.Height, pos.y);
                    toAdd.Add(newPos);
                }
            }

            return(toAdd);
        }