Esempio n. 1
0
        /// <summary>
        /// Place the (3D) camera such that the 3D terrain is drawn in exactly the same location as the other 2D elements
        /// </summary>
        /// <param name="drawArea">The area to draw upon (with physical location to pixel transformations)</param>
        void UpdateCamera(DrawArea drawArea)
        {
            // We create a view and projection matrix to allow viewing the world/terrain from the top.
            // All Vertices will be in real-world locations relative to a certain reference location

            //Using Pi/2 for projection, the distance from camera to plane is the same as the half the distance from top to bottom in the screen.
            //
            // So if the vertex positions are real world-locations, the camera-target should be at (worldCenterX, 0, worldCenterZ).
            // The Cameraposition itself is (world-center-X, cam-height, world-centerZ)
            //      where camheight is (worldHeight/2 = worldWidth/aspectRatio/2).
            // The distance of camera can be very large, so the backplane has to be set accordingly: cam-height/2 and cam-height*2.

            WorldLocation upperLeft        = drawArea.LocationUpperLeft;
            WorldLocation lowerRight       = drawArea.LocationLowerRight;
            Vector3       groundUpperLeft  = locationTranslator.VertexPosition(upperLeft);
            Vector3       groundLowerRight = locationTranslator.VertexPosition(lowerRight);
            Vector3       cameraTarget     = (groundUpperLeft + groundLowerRight) / 2;
            float         width            = groundLowerRight.X - groundUpperLeft.X;
            float         camHeight        = width / device.Viewport.AspectRatio / 2;
            Vector3       cameraPosition   = cameraTarget;

            cameraPosition.Y       = -camHeight;
            basicEffect.View       = Matrix.CreateLookAt(cameraPosition, cameraTarget, new Vector3(0, 0, 1));
            basicEffect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver2, device.Viewport.AspectRatio, camHeight / 2, camHeight * 2);
        }
Esempio n. 2
0
        /// <summary>
        /// Create a single vertex for a corner in the patch
        /// </summary>
        /// <param name="tile">The tile (parsed .t-file)</param>
        /// <param name="patch">The terrain patch (one of the patches in the tile)</param>
        /// <param name="cornerIndexX">Defines the x-value of the corner (0 or 1)</param>
        /// <param name="cornerIndexZ">Defines the z-value of the corner (0 or 1)</param>
        /// <param name="textureName">The name of the texture</param>
        private void CreateSingleCornerVertex(Tile tile, terrain_patchset_patch patch, float cornerIndexX, float cornerIndexZ, string textureName)
        {
            int squaresPerPatch = 16;

            cornerIndexX *= squaresPerPatch;
            cornerIndexZ *= squaresPerPatch;

            var   step    = tile.SampleSize;
            float cornerX = patch.CenterX - 1024;
            float cornerZ = patch.CenterZ - 1024 + 2048 * tile.Size;

            cornerX += -patch.RadiusM + cornerIndexX * step;
            cornerZ += -patch.RadiusM + (squaresPerPatch - cornerIndexZ) * step;
            var location = new WorldLocation(tile.TileX, tile.TileZ, cornerX, 0, cornerZ);

            // Rotate, Flip, and stretch the texture using the matrix coordinates stored in terrain_patchset_patch
            // transform uv by the 2x3 matrix made up of X,Y  W,B  C,H
            var U = cornerIndexX * patch.W + cornerIndexZ * patch.B + patch.X;
            var V = cornerIndexX * patch.C + cornerIndexZ * patch.H + patch.Y;

            newVertices[textureName].Add(new VertexPositionTexture(locationTranslator.VertexPosition(location), new Vector2(U, V)));
        }