예제 #1
0
        public GrassDataLayer(GrassDataLayer gdl)
        {
            usePrototypeMesh          = gdl.usePrototypeMesh;
            detailTexture             = gdl.detailTexture;
            detailMesh                = gdl.detailMesh;
            detailCountPerDetailPixel = gdl.detailCountPerDetailPixel;
            minSpawnH      = gdl.minSpawnH;
            maxSpawnH      = gdl.maxSpawnH;
            minSlope       = gdl.minSlope;
            maxSlope       = gdl.maxSlope;
            perlinTreshold = gdl.perlinTreshold;
            inverse        = gdl.inverse;
            frequency      = gdl.frequency;
            seed           = gdl.seed;
            disable        = gdl.disable;

            detailTexturePath = gdl.detailTexturePath;
            detailMeshPath    = gdl.detailMeshPath;

            details = new DetailPrototypeCustom(gdl.details);
        }
예제 #2
0
        public void GenerateGrass(Chunk chunk)
        {
            int alphamapWidth  = chunk.chunkTerrain.terrainData.alphamapWidth;
            int alphamapHeight = chunk.chunkTerrain.terrainData.alphamapHeight;
            int detailWidth    = chunk.chunkTerrain.terrainData.detailResolution;
            int detailHeight   = detailWidth;

            float resolutionDiffFactor = (float)alphamapWidth / detailWidth;


            DetailPrototype[] details = new DetailPrototype[grassLayers.Count];
            for (int i = 0; i < grassLayers.Count; ++i)
            {
                details[i] = new DetailPrototype();
                details[i].usePrototypeMesh = grassLayers[i].usePrototypeMesh;

                if (details[i].usePrototypeMesh)
                {
                    details[i].prototype  = grassLayers[i].detailMesh;
                    details[i].renderMode = DetailRenderMode.Grass;
                }
                else
                {
                    details[i].prototypeTexture = grassLayers[i].detailTexture;
                    details[i].renderMode       = DetailRenderMode.GrassBillboard;
                }

                details[i].minHeight    = grassLayers[i].details.minHeight;
                details[i].maxHeight    = grassLayers[i].details.maxHeight;
                details[i].minWidth     = grassLayers[i].details.minWidth;
                details[i].maxWidth     = grassLayers[i].details.maxWidth;
                details[i].dryColor     = grassLayers[i].details.dryColor;
                details[i].healthyColor = grassLayers[i].details.healthyColor;
            }
            chunk.chunkTerrain.terrainData.detailPrototypes = details;


            float[, ,] splatmap = chunk.chunkTerrain.terrainData.GetAlphamaps(0, 0, alphamapWidth, alphamapHeight);

            UnityEditor.Undo.RegisterCompleteObjectUndo(chunk.chunkTerrain.terrainData, "Grass");

            for (int i = 0; i < grassLayers.Count; ++i)
            {
                GrassDataLayer grassLayer = grassLayers[i];

                if (grassLayer.disable == true)
                {
                    continue;
                }

                int[,] newDetailLayer = new int[detailWidth, detailHeight];

                float seedX = grassLayer.seed + chunk.pos.x;
                float seedY = grassLayer.seed + chunk.pos.y;

                for (int j = 0; j < detailWidth; j++)
                {
                    float nj = (float)j / (float)detailWidth;

                    for (int k = 0; k < detailHeight; k++)
                    {
                        float nk = (float)k / (float)detailHeight;

                        float height    = chunk.chunkTerrain.terrainData.GetInterpolatedHeight(nk, nj);
                        float steepness = chunk.chunkTerrain.terrainData.GetSteepness(nk, nj);

                        if (height < grassLayer.minSpawnH || height > grassLayer.maxSpawnH)
                        {
                            continue;
                        }

                        if (steepness < grassLayer.minSlope || steepness > grassLayer.maxSlope)
                        {
                            continue;
                        }

                        float perlin = Mathf.PerlinNoise((seedX + nk) * grassLayer.frequency, (seedY + nj) * grassLayer.frequency);

                        if (grassLayer.inverse ? perlin >= grassLayer.perlinTreshold : perlin < grassLayer.perlinTreshold)
                        {
                            continue;
                        }

                        float alphaValue = splatmap[(int)(resolutionDiffFactor * j), (int)(resolutionDiffFactor * k), 0];

                        newDetailLayer[j, k] = (int)Mathf.Round(alphaValue * ((float)grassLayer.detailCountPerDetailPixel)) + newDetailLayer[j, k];
                    }
                }

                chunk.chunkTerrain.terrainData.SetDetailLayer(0, 0, i, newDetailLayer);
            }
        }