Now that we know how to utilize our input, we can get working on implementing our
stationary camera. We actually have most of this done, but we need to add pitching as
well as the yaw we already have. One use for a stationary camera is to look at an object
and follow it by rotating as needed. This is commonly used in racing game replay mode.
Before we dig into the camera changes, though, let’s add a few more rectangles to our
world. We can do this by adding the following code to the end of our demo’s Update
method:
world = Matrix.CreateTranslation(new Vector3(8.0f, 0, -10.0f));
DrawRectangle(ref world);
world = Matrix.CreateTranslation(new Vector3(8.0f, 0, -6.0f));
DrawRectangle(ref world);
world = Matrix.CreateRotationY(Matrix.CreateTranslation(new Vector3(3.0f, 0, 10.0f));
DrawRectangle(ref world);
We should also change our cull mode to None so that as we rotate around that we will
always see our rectangles. We can do that by calling the following code at the top of our
game’s Draw method:
graphics.GraphicsDevice.RenderState.CullMode = CullMode.None;
To get our camera updated we need to modify our camera class a little bit. First we need
to declare a private member field as follows:
private float cameraPitch = 0.0f;
Now we can modify the Update method to set our camera pitch. Remember, pitching
refers to rotating around the x axis. To calculate this we simply take the code we did for
calculating the yaw and replace our reference to the y axis with the x axis. The following
is the code to check our keyboard and game pad:
if (input.KeyboardState.IsKeyDown(Keys.Down) ||
(input.GamePads[0].ThumbSticks.Right.Y < 0))
{
cameraPitch -= (spinRate * timeDelta);
}
if (input.KeyboardState.IsKeyDown(Keys.Up) ||
(input.GamePads[0].ThumbSticks.Right.Y > 0))
{
cameraPitch += (spinRate * timeDelta);
}
100 CHAPTER 5 Input Devices and Cameras
No surprises there, and we need to do the same thing with our mouse code. Inside of the
#if !XBOX360 compilation directive we already have we can add the following code:
if ((input.PreviousMouseState.Y > input.MouseState.Y) &&
(input.MouseState.LeftButton == ButtonState.Pressed))
{
cameraPitch += (spinRate * timeDelta);
}
else if ((input.PreviousMouseState.Y < input.MouseState.Y) &&
(input.MouseState.LeftButton == ButtonState.Pressed))
{
cameraPitch -= (spinRate * timeDelta);
}
We want to clamp our values so we do not rotate over 90 degrees in either direction:
if (cameraPitch > 89)
cameraPitch = 89;
if (cameraPitch < -89)
cameraPitch = -89;
Finally, we need to update our rotation matrix to include our pitch value. Here is the
updated calculation:
Matrix rotationMatrix;
Matrix.CreateRotationY(MathHelper.ToRadians(cameraYaw), out rotationMatrix);
//add in pitch to the rotation
rotationMatrix = Matrix.CreateRotationX(MathHelper.ToRadians(cameraPitch)) *
rotationMatrix;
The last statement is the only thing we added. We just added our pitch to the rotation
matrix that was already being used to transform our camera. The full Update listing can
be found in Listing 5.1.
LISTING 5.1 Our stationary camera’ s Update method
public override void Update(GameTime gameTime)
{
float timeDelta = (float)gameTime.ElapsedGameTime.TotalSeconds;
if (input.KeyboardState.IsKeyDown(Keys.Left) ||
(input.GamePads[0].ThumbSticks.Right.X < 0))
{
cameraYaw += (spinRate * timeDelta);
}
if (input.KeyboardState.IsKeyDown(Keys.Right) ||
(input.GamePads[0].ThumbSticks.Right.X > 0))
Creating a Stationary Camera 101
5
{
cameraYaw -= (spinRate * timeDelta);
}
if (input.KeyboardState.IsKeyDown(Keys.Down) ||
(input.GamePads[0].ThumbSticks.Right.Y < 0))
{
cameraPitch -= (spinRate * timeDelta);
}
if (input.KeyboardState.IsKeyDown(Keys.Up) ||
(input.GamePads[0].ThumbSticks.Right.Y > 0))
{
cameraPitch += (spinRate * timeDelta);
}
#if !XBOX360
if ((input.PreviousMouseState.X > input.MouseState.X) &&
(input.MouseState.LeftButton == ButtonState.Pressed))
{
cameraYaw += (spinRate * timeDelta);
}
else if ((input.PreviousMouseState.X < input.MouseState.X) &&
(input.MouseState.LeftButton == ButtonState.Pressed))
{
cameraYaw -= (spinRate * timeDelta);
}
if ((input.PreviousMouseState.Y > input.MouseState.Y) &&
(input.MouseState.LeftButton == ButtonState.Pressed))
{
cameraPitch += (spinRate * timeDelta);
}
else if ((input.PreviousMouseState.Y < input.MouseState.Y) &&
(input.MouseState.LeftButton == ButtonState.Pressed))
{
cameraPitch -= (spinRate * timeDelta);
}
#endif
//reset camera angle if needed
if (cameraYaw > 360)
cameraYaw -= 360;
else if (cameraYaw < 0)
102 CHAPTER 5 Input Devices and Cameras
LISTING 5.1 Continued
cameraYaw += 360;
//keep camera from rotating a full 90 degrees in either direction
if (cameraPitch > 89)
cameraPitch = 89;
if (cameraPitch < -89)
cameraPitch = -89;
Matrix rotationMatrix;
Matrix.CreateRotationY(MathHelper.ToRadians(cameraYaw),
out rotationMatrix);
//add in pitch to the rotation
rotationMatrix = Matrix.CreateRotationX(MathHelper.ToRadians(cameraPitch))
* rotationMatrix;
// Create a vector pointing the direction the camera is facing.
Vector3 transformedReference;
Vector3.Transform(ref cameraReference, ref rotationMatrix,
out transformedReference);
// Calculate the position the camera is looking at.
Vector3.Add(ref cameraPosition, ref transformedReference, out cameraTarget);
Matrix.CreateLookAt(ref cameraPosition, ref cameraTarget, ref cameraUpVector,
out view);
base.Update(gameTime);
}
Kamis, 03 April 2008
Creating a Stationary Camera
Label:
camera,
stationary,
xna
Langganan:
Posting Komentar
(Atom)
0 komentar:
Posting Komentar