private VertexPositionNormalTangentBinormalTexture[] GenerateTerrainVertices()
        {
            float terrainWidth = (vertexCountX - 1) * blockScale;
            float terrainDepth = (vertexCountZ - 1) * blockScale;
            halfTerrainWidth = terrainWidth * 0.5f;
            halfTerrainDepth = terrainDepth * 0.5f;

            float tu = 0;
            float tv = 0;
            float tuDerivative = 1.0f / (vertexCountX - 1);
            float tvDerivative = 1.0f / (vertexCountZ - 1);

            VertexPositionNormalTangentBinormalTexture[] vertices = new VertexPositionNormalTangentBinormalTexture[numVertices];

            int count = 0;
            for (float i = -halfTerrainDepth; i <= halfTerrainDepth; i += blockScale)
            {
                tu = 0.0f;
                for (float j = -halfTerrainWidth; j <= halfTerrainWidth; j += blockScale)
                {
                    vertices[count].Position = new Vector3(j, heightMap[count].R * heightScale, i);
                    vertices[count].TextureCoordinate = new Vector2(tu, tv);

                    tu += tuDerivative;
                    count++;
                 }
                tv += tvDerivative;
            }
            return vertices;
        }
        private void GenerateTerrainNormals(VertexPositionNormalTangentBinormalTexture[] vertices, uint[] indices)
        {
            for (uint i = 0; i < indices.Length; i += 3)
            {
                // Get the vertex position (v1, v2, and v3)
                Vector3 v1 = vertices[indices[i]].Position;
                Vector3 v2 = vertices[indices[i + 1]].Position;
                Vector3 v3 = vertices[indices[i + 2]].Position;

                // Calculate vectors v1->v3 and v1->v2 and the normal as a cross product
                Vector3 vu = v3 - v1;
                Vector3 vt = v2 - v1;
                Vector3 normal = Vector3.Cross(vu, vt);
                normal.Normalize();

                vertices[indices[i]].Normal += normal;
                vertices[indices[i + 1]].Normal += normal;
                vertices[indices[i + 2]].Normal += normal;
            }

            for (int i = 0; i < vertices.Length; i++)
                vertices[i].Normal.Normalize();
        }
 public void GenerateTerrainTangentBinormal(VertexPositionNormalTangentBinormalTexture[] vertices, uint[] indices)
 {
     for (uint i = 0; i < vertexCountZ; i++)
     {
         for (uint j = 0; j < vertexCountX; j++)
         {
             uint vertexIndex = j + i * vertexCountX;
             Vector3 v1 = vertices[vertexIndex].Position;
             if (j < vertexCountX - 1)
             {
                 Vector3 v2 = vertices[vertexIndex + 1].Position;
                 vertices[vertexIndex].Tangent = (v2 - v1);
             }
             else
             {
                 Vector3 v2 = vertices[vertexIndex - 1].Position;
                 vertices[vertexIndex].Tangent = (v1 - v2);
             }
             vertices[vertexIndex].Tangent.Normalize();
             vertices[vertexIndex].Binormal = Vector3.Cross(
             vertices[vertexIndex].Tangent, vertices[vertexIndex].Normal);
         }
     }
 }