public void CommitChanges(int width, int height)
        {
            int count = width * height;

              VertexPositionNormalTextureHeight[] vertices = new VertexPositionNormalTextureHeight[count];

              // see if we have a border
              int left = 0;
              int top = 0;
              int columns = width;

              if (count != this.Vertices.Length)
              {
            left++;
            top++;
            columns += 2;
              }

              // transfer vertices from full, bordered vertex data
              int vertexIndex = 0;

              for (int y = 0; y < height; y++)
            for (int x = 0; x < width; x++)
              vertices[vertexIndex++] = this.Vertices[(top + y) * columns + (left + x)];

              vertexBuffer = new VertexBuffer(graphicsDevice, VertexPositionNormalTextureHeight.VertexDeclaration, count, BufferUsage.WriteOnly);
              vertexBuffer.SetData(vertices);
        }
Example #2
0
        /// <summary>
        /// Generate terrain mesh for this node
        /// </summary>
        public void GenerateMesh(TerrainNodeSplitItem item)
        {
            // the minus one here is correct: e.g. 3x3 vertices labeled 0, 1, 2: v0.x = 0, v1.x = 0.5, v2.x = 1.  The increment = 1 / (3 - 1) = 0.5
              double horizontalStep = bounds.Width / (Constants.PatchWidth - 1);
              double verticalStep = bounds.Height / (Constants.PatchHeight - 1);
              float horizontalTextureStep = 1.0f / (Constants.PatchWidth - 1);
              float verticalTextureStep = 1.0f / (Constants.PatchHeight - 1);

              float MinX, MinY, MinZ;
              float MaxX, MaxY, MaxZ;

              // initialize min and max vertex tracking
              MinX = MinY = MinZ = 999999;
              MaxX = MaxY = MaxZ = -999999;

              // get matrix used to transform vertices to the proper cube face
              Matrix faceMatrix = CubeFaces.GetFace(bounds.Face).FaceMatrix;

              // create vertex storage using user supplied delegate
              vertexBuffer = createTerrainNodeVertexBuffer(item.HeightData.Length);

              //int cubeVertexIndex = 0;
              //CubeVertices = new Vector2[item.HeightData.Length];

              hasMeshBorder = false;
              int vertexIndex = 0;
              int Rows = Constants.PatchHeight;
              int Columns = Constants.PatchWidth;

              if (item.HeightData.Length > Constants.PatchWidth * Constants.PatchHeight)
              {
            hasMeshBorder = true;
            Rows += 2;
            Columns += 2;
              }

              patchRows = Rows;
              patchColumns = Columns;

              float v = 0;
              double y = bounds.Bottom;

              if (hasMeshBorder)
              {
            v -= verticalTextureStep;
            y -= verticalStep;
              }

              for (int hy = 0; hy < Rows; hy++)
              {
            float u = 0;
            double x = bounds.Left;

            if (hasMeshBorder)
            {
              u -= horizontalTextureStep;
              x -= horizontalStep;
            }

            for (int hx = 0; hx < Columns; hx++)
            {
              // create the vertex position and rotate it to the appropriate face
              Position3 cubePosition = new Position3(x, y, 1);

              Position3 spherePosition = Tools.CubeToSphereMapping(x, y, 1);
              spherePosition.Transform(ref faceMatrix);
              cubePosition.Transform(ref faceMatrix);

              // transform the vertex based on the user defined delegate
              double height;
              Position3 finalPosition;
              Vector2 patchPosition = new Vector2(hx, hy);

              if (item == null)
            CreatePosition(ref spherePosition, ref cubePosition, ref patchPosition, out finalPosition, out height);
              else
              {
            height = item.HeightData[hy * Columns + hx];
            if (height < 0) height = 0;
            finalPosition = spherePosition * (radius + height);
            TranslateToPatchSpace(ref finalPosition);
              }

              VertexPositionNormalTextureHeight vertex = new VertexPositionNormalTextureHeight();

              vertex.Position = (Vector3)finalPosition;
              vertex.Height = (float)height;
              vertex.Normal = (Vector3)spherePosition;
              vertex.TextureCoordinate = new Vector2(u, v);
              vertex.Tangent = Vector4.Zero;
              vertexBuffer.Vertices[vertexIndex++] = vertex;

              // track min and max coordinates, but only  for the vertices that will be in the final mesh
              if (hx >= 1 && hx < Columns - 1 && hy >= 1 && hy < Rows - 1)
              {
            if (vertex.Position.X < MinX) MinX = vertex.Position.X;
            if (vertex.Position.Y < MinY) MinY = vertex.Position.Y;
            if (vertex.Position.Z < MinZ) MinZ = vertex.Position.Z;

            if (vertex.Position.X > MaxX) MaxX = vertex.Position.X;
            if (vertex.Position.Y > MaxY) MaxY = vertex.Position.Y;
            if (vertex.Position.Z > MaxZ) MaxZ = vertex.Position.Z;
              }

              x += horizontalStep;
              u += horizontalTextureStep;
            }

            y += verticalStep;
            v += verticalTextureStep;
              }

              // create min and max bounding vertices, in patch-space
              minVertex = new Vector3(MinX, MinY, MinZ);
              maxVertex = new Vector3(MaxX, MaxY, MaxZ);

              // calculate normals and tangents
              CalculateNormals();
              CalculateTangents();

              // save vertex buffer changes - this effectively copies the raw data to a vertex buffer on the device
              vertexBuffer.CommitChanges(Constants.PatchWidth, Constants.PatchHeight);
        }