Esempio n. 1
0
        /// <summary>
        /// Adds a grass billboard
        /// </summary>
        private void AddGrass(VertexTerrain v, List <VertexBillboard> grassVertices, List <int> grassIndices,
                              Random r, Climate climate)
        {
            float   rg    = r.Next(50, 101) / 100.0f;
            Vector3 color = Vector3.One;

            if (climate == Climate.Tropical)
            {
                color = new Vector3(rg, rg, r.Next(40, 101) / 100.0f);
            }
            else if (climate == Climate.Polar)
            {
                color = new Vector3(rg, rg, rg);
            }
            else if (climate == Climate.Dry)
            {
                color = new Vector3(rg, rg, r.Next(1, 40) / 100.0f);
            }

            Vector2 scale = new Vector2(r.Next(5, 8), r.Next(5, 20) / 10.0f);

            grassVertices.Add(new VertexBillboard(v.Position, v.Normal, color, Vector2.Zero, scale));
            grassVertices.Add(new VertexBillboard(v.Position, v.Normal, color, Vector2.UnitX, scale));
            grassVertices.Add(new VertexBillboard(v.Position, v.Normal, color, Vector2.One, scale));
            grassVertices.Add(new VertexBillboard(v.Position, v.Normal, color, Vector2.UnitY, scale));

            int[] baseIndices = new int[] { 0, 1, 2, 0, 2, 3 };
            int   offset      = grassIndices.Count / 6 * 4;

            for (int i = 0; i < 6; i++)
            {
                grassIndices.Add(baseIndices[i] + offset);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Adds a tree billboard
        /// </summary>
        private void AddTree(VertexTerrain v, List <VertexBillboard> treeVertices, List <int> treeIndices,
                             Random r, Climate climate)
        {
            Vector3 color;

            if (climate == Climate.Polar)
            {
                color = new Vector3(1, r.Next(90, 101) / 100.0f, r.Next(90, 101) / 100.0f);
            }
            else
            {
                color = new Vector3(1, r.Next(90, 101) / 100.0f, r.Next(40, 101) / 100.0f);
            }

            Vector2 scale = new Vector2(r.Next(4, 11), r.Next(50, 100) / 10.0f);

            treeVertices.Add(new VertexBillboard(v.Position, Vector3.Up, color, Vector2.Zero, scale));
            treeVertices.Add(new VertexBillboard(v.Position, Vector3.Up, color, Vector2.UnitX, scale));
            treeVertices.Add(new VertexBillboard(v.Position, Vector3.Up, color, Vector2.One, scale));
            treeVertices.Add(new VertexBillboard(v.Position, Vector3.Up, color, Vector2.UnitY, scale));

            int[] baseIndices = new int[] { 0, 1, 2, 0, 2, 3 };
            int   offset      = treeIndices.Count / 6 * 4;

            for (int i = 0; i < 6; i++)
            {
                treeIndices.Add(baseIndices[i] + offset);
            }
        }
Esempio n. 3
0
        private void Build(Terrain t, Climate climate)
        {
            float min  = 5;
            float low  = t.LowMark * 2;
            float max  = t.HighMark / 2;
            float high = (max + low) / 2.0f;

            List <VertexBillboard> treeVertices = new List <VertexBillboard>();
            List <int>             treeIndices  = new List <int>();

            List <VertexBillboard> grassVertices = new List <VertexBillboard>();
            List <int>             grassIndices  = new List <int>();

            Random rand = new Random();

            for (int i = 0; i < t.Vertices.Length; i++)
            {
                VertexTerrain v               = t.Vertices[i]; // current vertex in the terrain mesh
                float         height          = v.Position.Y;
                float         baseProbability = 0;             // initially, there is no chance of adding a plant

                if (height > min && height < max)              // check if the vertex is within allowed height range
                {
                    if (v.TextureWeights.W >= 0.5f)
                    {
                        baseProbability = 0;
                    }
                    else if (climate == Climate.Dry)
                    {
                        if (height < low)
                        {
                            baseProbability = 0.6f - (height - max / 2) / (max / 2 - min);
                        }
                        else if (height > high)
                        {
                            baseProbability = 0.2f - (height - high) / (max - high);
                        }
                        else
                        {
                            baseProbability = 0.2f;
                        }
                    }
                    else
                    {
                        if (height < low)
                        {
                            baseProbability = (height - min) / (low - min);     // fewer plants toward shore
                        }
                        else if (height > high)
                        {
                            baseProbability = v.TextureWeights.Z - (height - high) / (max - high);   // fewer plants near mountain peaks
                        }
                        else
                        {
                            baseProbability = v.TextureWeights.Z;    // otherwise, the vertex is perfectly good for a plant
                        }
                    }
                }

                baseProbability *= density;                 // scale probability by density
                float  treeProbability = baseProbability * treeDensity;
                double roll            = rand.NextDouble(); // get a random number to check if the plant should be added
                if (baseProbability > roll)
                {
                    if (treeProbability > roll)
                    {
                        //trees.Add(new TreeModel(treeModel, v.Position, rand.Next(175,250)/100.0f));
                        AddTree(v, treeVertices, treeIndices, rand, climate);
                    }
                    else
                    {
                        AddGrass(v, grassVertices, grassIndices, rand, climate);
                    }
                }
            }

            // buffer the vegetation
            if (grassVertices.Count > 0)
            {
                vBufferGrass = new VertexBuffer(sim.GraphicsDevice, grassVertices.Count * VertexBillboard.SizeInBytes, BufferUsage.WriteOnly);
                vBufferGrass.SetData(grassVertices.ToArray());
                iBufferGrass = new IndexBuffer(sim.GraphicsDevice, typeof(int), grassIndices.Count, BufferUsage.WriteOnly);
                iBufferGrass.SetData(grassIndices.ToArray());
            }

            if (treeVertices.Count > 0)
            {
                vBufferTrees = new VertexBuffer(sim.GraphicsDevice, treeVertices.Count * VertexBillboard.SizeInBytes, BufferUsage.WriteOnly);
                vBufferTrees.SetData(treeVertices.ToArray());
                iBufferTrees = new IndexBuffer(sim.GraphicsDevice, typeof(int), treeIndices.Count, BufferUsage.WriteOnly);
                iBufferTrees.SetData(treeIndices.ToArray());
            }
        }
Esempio n. 4
0
 public TerrainTile(Vector2 position, VertexTerrain[] vertices, VertexBuffer buffer, BoundingBox boundingBox)
 {
     this.Vertices = vertices;
     this.Position = position;
     this.Buffer = buffer;
     this.BoundingBox = boundingBox;
 }
Esempio n. 5
0
        /// <summary>
        /// Calculate the normals of each vertices by getting the
        /// two sides of each vertex' triangle and crossing then.
        /// </summary>
        /// <param name="vertices">The vertices on which to calculate normals.</param>
        private void SetupNormals(VertexTerrain[] vertices)
        {
            for (int i = 0; i < indices.Length / 3; i++)
            {
                int index0 = indices[i * 3];
                int index1 = indices[i * 3 + 1];
                int index2 = indices[i * 3 + 2];

                Vector3 side0 = vertices[index0].Position - vertices[index2].Position;
                Vector3 side1 = vertices[index0].Position - vertices[index1].Position;
                Vector3 normal = Vector3.Cross(side1, side0);

                vertices[index0].Normal += normal;
                vertices[index1].Normal += normal;
                vertices[index2].Normal += normal;
            }

            for (int i = 0; i < vertices.Length; i++)
                vertices[i].Normal = vertices[i].Normal.SafeNormalize();
        }
Esempio n. 6
0
        /// <summary>
        /// Construct the vertices and the vertexbuffer.
        /// </summary>
        private void LoadVertices()
        {
            TileSize = Math.Min(Math.Min(this.Width, this.Height), TileSize);

            int widthInTiles = (int)Math.Ceiling((this.Width - 1) / (double)(TileSize));
            int heightInTiles = (int)Math.Ceiling((this.Height - 1) / (double)(TileSize));

            this.tiles = new TerrainTile[widthInTiles * heightInTiles];
            Vector3 color = new Vector3(0xed/255.0f, 0xaa/255.0f, 0x09/255.0f);
            for (int ty = 0; ty < heightInTiles; ty++)
            {
                for (int tx = 0; tx < widthInTiles; tx++)
                {
                    int width = TileSize + 1;
                    int height = TileSize + 1;

                    VertexTerrain[] vertices = new VertexTerrain[width * height];

                    Vector3 bbmax = Vector3.One * float.MinValue;
                    Vector3 bbmin = Vector3.One * float.MaxValue;
                    for (int x = 0; x < width; x++)
                    {
                        for (int y = 0; y < height; y++)
                        {
                            int rx = (tx * TileSize + x);
                            int ry = (ty * TileSize + y);
                            int ri = rx + ry * this.Width;
                            int i = x + y * width;
                            vertices[i].Position = new Vector3(rx, data[Math.Min(rx, this.Width - 1), Math.Min(ry, this.Height - 1)], ry);
                            bbmax = Vector3.Max(bbmax, vertices[i].Position);
                            bbmin = Vector3.Min(bbmin, vertices[i].Position);

                            float weight = vertices[i].Position.Y;
                            weight -= minheight;
                            weight /= (maxheight - minheight);
                            weight *= weight;
                            vertices[i].Color = Vector3.Lerp(color, Vector3.One, weight);
                        }
                    }

                    this.SetupNormals(vertices);

                    VertexBuffer buffer = new VertexBuffer(GraphicsDevice, typeof(VertexTerrain), vertices.Length, BufferUsage.None);
                    tiles[ty * widthInTiles + tx] = new TerrainTile(new Vector2(tx, ty), vertices, buffer, new BoundingBox(bbmin, bbmax));
                }
            }
        }