コード例 #1
0
        public static void Show(GrassNodeEditor grassNode)
        {
            EditorGUI.BeginChangeCheck();

            GrassDetailNode grassDetail = grassNode.GrassDetailNode;

            grassDetail.RenderMode = (DetailRenderMode)EditorGUILayout.EnumPopup("Render Mode", grassDetail.RenderMode);

            if (grassDetail.RenderMode == DetailRenderMode.VertexLit)
            {
                grassDetail.Prefab = (GameObject)
                                     EditorGUILayout.ObjectField(new GUIContent("Prefab"), grassDetail.Prefab, typeof(GameObject), false);
            }
            else
            {
                grassDetail.Texture = (Texture2D)
                                      EditorGUILayout.ObjectField(new GUIContent("Texture"), grassDetail.Texture, typeof(Texture2D), false);
            }

            Show(grassDetail, () => {
                if (grassDetail.RenderMode != DetailRenderMode.VertexLit)
                {
                    grassDetail.HealthyColor = EditorGUILayout.ColorField("Healthy Color", grassDetail.HealthyColor);
                    grassDetail.DryColor     = EditorGUILayout.ColorField("Dry Color", grassDetail.DryColor);
                }
            });

            if (EditorGUI.EndChangeCheck())
            {
                grassNode.serializedObject.ApplyModifiedProperties();
            }
        }
コード例 #2
0
        /// <summary>
        /// Adds all non-tree details to the Terrain according to the
        /// <see cref="_biomeMap"/> in this <see cref="Tile"/>. This adds
        /// grass and detail meshes.
        /// </summary>
        public IEnumerator AddDetailLayers()
        {
            BiomeNode[] biomeNodes = _painter.Biomes;
            int         res        = TerraConfig.Instance.Generator.DetailmapResolution;

            //Collect prototypes
            GrassDetailNode[] allDetailNodes = biomeNodes
                                               .SelectMany(bn => bn.GetGrassInputs())
                                               .ToArray();
            List <DetailPrototype> prototypes = new List <DetailPrototype>(allDetailNodes.Length);

            foreach (GrassDetailNode detailNode in allDetailNodes)
            {
                prototypes.Add((DetailPrototype)detailNode.GetDetailPrototype());
            }

            int            coroutineRes   = TerraConfig.Instance.Generator.CoroutineRes;
            int            iterations     = 0;
            int            prototypeIndex = 0;
            GenerationData conf           = TerraConfig.Instance.Generator;

            _terrain.terrainData.SetDetailResolution(res, 16);
            _terrain.terrainData.detailPrototypes = prototypes.ToArray();
            _terrain.detailObjectDistance         = conf.DetailDistance;
            _terrain.detailObjectDensity          = conf.DetailDensity;

            for (int i = 0; i < biomeNodes.Length; i++)
            {
                //Collect all details for this biome
                BiomeNode         biome      = biomeNodes[i];
                GrassDetailNode[] grassNodes = biome.GetGrassInputs();

                if (grassNodes.Length == 0)   //A biome may contain no grass nodes
                {
                    continue;
                }

                foreach (GrassDetailNode grassNode in grassNodes)
                {
                    int[,] layer = new int[res, res];

                    //Get map of normalized placement positions
                    Vector2[] samples = null;
                    if (!TerraConfig.Instance.IsEditor)
                    {
                        bool            isDone = false;
                        GrassDetailNode node   = grassNode;
                        TerraConfig.Instance.Worker.Enqueue(() => samples = node.SamplePositions(_tile.Random), () => isDone = true);

                        while (!isDone)
                        {
                            yield return(null);
                        }
                    }
                    else
                    {
                        samples = grassNode.SamplePositions(_tile.Random);
                    }

                    foreach (Vector2 sample in samples)
                    {
                        iterations++;

                        if (iterations > coroutineRes)
                        {
                            iterations = 0;
                            yield return(null);
                        }

                        int selectedBiome = _sampler.GetBiomeAtInterpolatedCoords(_biomeMap, sample.x, sample.y);
                        if (selectedBiome != i)
                        {
                            continue; //Not in this biome, skip
                        }

                        //Check whether an object can be placed here
                        float   amp    = TerraConfig.Instance.Generator.Amplitude;
                        float   height = _terrain.terrainData.GetInterpolatedHeight(sample.x, sample.y) / amp;
                        float   angle  = Vector3.Angle(Vector3.up, _terrain.terrainData.GetInterpolatedNormal(sample.x, sample.y)) / 90;
                        Vector2 world  = MathUtil.NormalToWorld(_tile.GridPosition, sample);

                        if (grassNode.ShouldPlaceAt(world.x, world.y, height, angle))
                        {
                            //Convert normalized x,y coordinates to positions in layer map
                            Vector2 sampleWorld = sample * res;
                            int     x           = Mathf.Clamp(Mathf.RoundToInt(sampleWorld.x), 0, res - 1);
                            int     y           = Mathf.Clamp(Mathf.RoundToInt(sampleWorld.y), 0, res - 1);

                            layer[y, x] = 1; //Display object here
                        }
                    }

                    _terrain.terrainData.SetDetailLayer(0, 0, prototypeIndex, layer);
                    prototypeIndex++;
                }
            }
        }