示例#1
0
        /// <summary>
        /// Calculate the sphere-space position of the patch by determining where the center vertex lies on the sphere
        /// </summary>
        private void CalculatePatchPosition(TerrainNodeSplitItem item)
        {
            // find the cube position of the center vertex
              double x = bounds.Left + bounds.Width / 2;
              double y = bounds.Bottom + bounds.Height / 2;

              // get the matrix used to rotate the a position to the appropriate cube face
              Matrix faceMatrix = CubeFaces.GetFace(bounds.Face).FaceMatrix;

              // create the vertex position in cube-space and rotate it to the appropriate face
              Position3 cubePosition = new Position3(x, y, 1);
              cubePosition.Transform(ref faceMatrix);

              // get the vertex position on the unit sphere and rotate it to the appropriate face
              Position3 spherePosition = Tools.CubeToSphereMapping(x, y, 1);
              spherePosition.Transform(ref faceMatrix);
              spherePosition.Normalize();

              Vector2 patchPosition = new Vector2(Constants.PatchWidth / 2, Constants.PatchHeight / 2);

              if (item == null)
              {
            // transform the vertex based on the user defined delegate - this returns the height value of the point on the sphere
            createPosition(ref spherePosition, ref cubePosition, ref patchPosition, radius, out position);
              }
              else
              {
            double h = item.HeightData[(int)((patchPosition.Y + 1) * (Constants.PatchWidth + 2) + (patchPosition.X + 1))];
            if (h < 0) h = 0;
            position = spherePosition * (radius + h);
              }
        }
示例#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);
        }