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?