Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm trying to implement zoom in/out functionality into my game. I can change the cameraDistance value with the Z and X keys. Instead of zooming, it looks like the model is scaled smaller or larger (moves closer or farther away from the camera). Instead, the camera should move closer to or farther away from the model.

Below are my view and projection matrix. cameraDistance is the value that seems to 'scale' the model. After days of messing around, I realize (yes after days!:)) that I should never change this value.

Matrix view = Matrix.CreateRotationY(MathHelper.ToRadians(cameraRotation)) *
                      Matrix.CreateRotationX(MathHelper.ToRadians(cameraArc)) *
                      Matrix.CreateTranslation(0, -45, 0) *
                      Matrix.CreateLookAt(new Vector3(0, forwardRotation, -cameraDistance), new Vector3(0, 0, 0), Vector3.Up);

        Matrix projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspectRatio, 1, 10000);

So instead of changing the cameraDistance value, I think I should change my CameraPositionOffset. Below is my updateCamera method

        // This vector controls how much the camera's position is offset from the
        // sphere. This value can be changed to move the camera further away from or
        // closer to the sphere.
        Vector3 CameraPositionOffset = new Vector3(0, 10, 90);

        // This value controls the point the camera will aim at. This value is an offset
        // from the sphere's position. middle value is distance from surface
        Vector3 CameraTargetOffset = new Vector3(0, 27, 0);

    private void UpdateCamera(GameTime gameTime)
        {

            // start arcball
            float time = (float)gameTime.ElapsedGameTime.TotalMilliseconds;

            // mouse movement
            MouseState currentMouseState = Mouse.GetState();
            if (currentMouseState != originalMouseState)
            {

                float xDifference = (currentMouseState.X - originalMouseState.X);
                float yDifference = currentMouseState.Y - originalMouseState.Y;

                Mouse.SetPosition(GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2);
                if (Mouse.GetState().RightButton == ButtonState.Pressed)
                {
                    cameraRotation -= xDifference * 1.05f;
                    cameraArc += yDifference * 1.025f;

                    // Limit the arc movement.
                    if (cameraArc > 90.0f)
                        cameraArc = 90.0f;
                    else if (cameraArc < -90.0f)
                        cameraArc = -90.0f;
                }
            }

            // Check for input to zoom camera in and out.
            if (currentKeyboardState.IsKeyDown(Keys.Z))
                cameraDistance += time * 0.25f;

            if (currentKeyboardState.IsKeyDown(Keys.X))
                cameraDistance -= time * 0.25f;

            // Limit the camera distance.
            if (cameraDistance > 500)
                cameraDistance = 500;
            else if (cameraDistance < 0.001f)
                cameraDistance = 0.001f;

            /// end of arcball

            // The camera's position depends on the sphere's facing direction: when the
            // sphere turns, the camera needs to stay behind it. So, we'll calculate a
            // rotation matrix using the sphere's facing direction, and use it to
            // transform the two offset values that control the camera.
            Matrix cameraFacingMatrix = Matrix.CreateRotationY(sphereFacingDirection);
            Vector3 positionOffset = Vector3.Transform(CameraPositionOffset, cameraFacingMatrix);

            Vector3 targetOffset = Vector3.Transform(CameraTargetOffset, cameraFacingMatrix);

            // once we've transformed the camera's position offset vector, it's easy to
            // figure out where we think the camera should be.
            Vector3 cameraPosition = spherePosition + positionOffset;

            // We don't want the camera to go beneath the heightmap, so if the camera is
            // over the terrain, we'll move it up.
            if (heightMapInfo.IsOnHeightmap(cameraPosition))
            {
                // we don't want the camera to go beneath the terrain's height +
                // a small offset.
                float minimumHeight = heightMapInfo.GetHeight(cameraPosition) + CameraPositionOffset.Y;

                if (cameraPosition.Y < minimumHeight)
                {
                    cameraPosition.Y = minimumHeight;
                }
            }

            // next, we need to calculate the point that the camera is aiming it. That's
            // simple enough - the camera is aiming at the sphere, and has to take the 
            // targetOffset into account.
            Vector3 cameraTarget = spherePosition + targetOffset;

            // with those values, we'll calculate the viewMatrix.
            viewMatrix = Matrix.CreateLookAt(cameraPosition, cameraTarget, new Vector3(0.0f, 1.0f, 0.0f));

        }

In summary: I want to move the camera farther or closer to the model, and keep the position and scale of the model.

How should I go about this?

share|improve this question
    
Isn't this a duplicate of your other question? gamedev.stackexchange.com/questions/61961/… –  Byte56 Sep 12 '13 at 21:52
    
not completely, because I'm really having a hard time with controlling the camera I've decided to chunk up the functionality I want to implement. I realized implementing a fully functioning arcball(or orbit) camera is way too hard right now. So I think implementing and learning to control the camera step by step is better. –  Maarten Hartman Sep 12 '13 at 22:00
add comment

1 Answer

Have you tried changing the field of view component of your projection matrix? Your current field of view is set to MathHelper.PiOver4 if swap this out for a modifiable value you should be able to zoom in and out.

share|improve this answer
    
ah thanks for pointing this out, now I know where to look :) this thread stackoverflow.com/questions/6155024/xna-global-zoom says the same. "MathHelper.PiOver4 // change this to, say 20°" should I change the '4' to '20', or the complete line to '20'? (cant test it within a few hours) –  Maarten Hartman Sep 13 '13 at 10:20
    
@MaartenHartman Set it to any value between 0.000001f (super zoomed in) and MathHelper.TwoPi (super fish eye). Hard values for this range is 0f to 6.24f. For most zooming, values between .2f & 2f work well. The typical PiOver4 is about .785f. –  Steve H Sep 13 '13 at 11:28
    
Thanks! Once I've tried your suggestions, I'll report back here –  Maarten Hartman Sep 13 '13 at 11:50
    
Great, nearly there! I'm now able to zoom :) just one thing to really finish it: everything that is surrounding my model is 'zoomed' aswell. For example the arena around the model becomes completeley stretched out (which isn't realistic of course). If I give models like the arena a static value (0.7f), the zoom works like the old behaviour (moving to and from the camera). How can I fix that? –  Maarten Hartman Sep 13 '13 at 19:41
    
if you're image is distorting a lot you may find this post helpful: stackoverflow.com/questions/18317620/… –  Steve Locke Sep 15 '13 at 18:39
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.