XNA Quaternions Sample Program

advertisement
XNA Quaternions Sample Program:
This program makes use of Quaternions for the rotation of points/vectors around an
arbitrary axis in 3D space. In particular, we use Quaternions to create a first-person camera
system that is used to navigate a player through a 3D world.
1. Creating the world:

Start off by creating a flat, two dimensional plane to represent the ground level
in the scene. The plane can be represented with two triangles using either a
triangle list or triangle strip primitive topology.

The plane should be tiled with a texture image that resembles some sort of
floor/ground surface.
o Note: texture coordinates that exceed 1.0 in either the U or V dimensions
will produce a tiling effect.
2. Creating the player:

Conceptually our world can be thought of as two dimensional (in the XZ plane).
Likewise, the player can be thought of as a point on the XZ plane that is moving
along the ground created in part 1.

Define the following three attributes of the player in your program:
i.
ii.
iii.
Position
Height
Speed

The position is essentially a 3d point in space where the player’s feet would
come into contact with the world.

The height is a scalar that defines how high the camera should be positioned
away from the player’s position on the Y axis in the world’s coordinate system.

Lastly, the speed is another scalar that defines the distance travelled by the
player in some length of time.
3. Creating the camera:

A first-person camera can be represented as a three dimensional coordinate
system, with the camera positioned at the origin:

Store these three vectors in your program and give them some initial values such
as:
o LookDir
= (0, 0, -1)
o RightDir
= (1, 0, 0)
o UpDir
= (0, 1, 0)

Using quaternions we can now apply rotations to the camera using the three
basis vectors (look, up, right) based on user input. First, read in the change in the
horizontal position of the mouse cursor and use it to generate a turning angle
(yaw) for the frame. Next, read in the change in the vertical position of the
mouse cursor and use it to generate a tilting angle (pitch) for the frame.

Use these two angles to rotate the orientation of the three camera vectors. Note
that a yaw is a rotation around the up vector, and a pitch is a rotation around the
right vector. Typically in first-person games the yaw rotation is around the
world’s up vector as opposed to the camera’s current up vector. If the camera
was allowed to “fly” through space (perhaps as a spectator), then it would make
sense for the yaw rotation to use the camera’s up vector.
o As an example, if a tilt (pitch) rotation is being performed we would need
to rotate both the look direction and the up direction by some angle
around the camera’s right vector. In this case, the angle would be read
from the vertical mouse movements.
o To create a quaternion that represents a rotation around a particular axis
you can use the function contained within the Quaternion data structure:
quaternion = Quaternion.CreateFromAxisAngle(Vector3 axis, float angle)
o To rotate a vector around a quaternion you can use the function
contained within the Vector3 data structure:
newVector = Vector3.Transform( Vector3 vector, Quaternion rotation)

After both rotations (yaw and pitch) have been applied on the camera’s basis
vectors, you will need to rebuild the view matrix in your program.
o NOTE: The look, up, and right vectors of the camera should all be
normalized and orthogonal to each other.
o To orthogonalize a set of three 3D vectors (lookDir, upDir, rightDir):
i) lookDir
= lookDir.normalize();
ii) rightDir
= Cross( lookDir, upDir ).normalize();
iii) upDir
= Cross(rightDir, lookDir);
4. Controlling the Player:

In your input handling function, calculate a normalized 2D movement vector (in
the XZ-axis) based on the user’s keyboard input. The player should be able to
move forwards and backwards (relative to the direction the camera is looking),
as well as strafe to the left and to the right (relative to the camera’s current right
vector).
o
Note: We do not want to move the player at all in the Y-axis assuming the
ground you are using is flat. Therefore if the player is looking up or down
in the world’s up direction, this should not affect the movement
direction. If you choose to have a 3D landscape rather than a flat plane,
you would want to move the player in the direction tangent to the
terrain’s surface.

Multiplying this normalized movement vector by the player’s speed will give the
velocity vector of the player in a particular frame. Use this velocity to displace
the player’s current position.

Add the ability for the player to crouch and crawl. This can be achieved by
modifying the player’s height value. The best approach would be to store a
floating point scalar in the range [0, 1] and multiply the player’s height by this
value when setting the camera’s position for the frame.

Using a similar approach as mentioned above, modify the player’s speed value
depending on the current stance they are in. If the player is standing, the speed
should be 100%. If the player is crouching, the speed should be approximately
50%. And lastly, if the player is crawling, the speed should be roughly 10%.
5. Additional Features:

In this program we implemented a yaw and pitch rotation system using
quaternions. We could also add the ability to “roll” the camera by performing
rotations around the camera’s current look vector. This rotation can give the
effect of leaning, however, we also would need to rotate the camera’s position
around a particular point on the player (such as the neck or waist) to get the full
effect.

To get a better understanding of the current state of the camera’s view space,
render the camera’s look, up, and right vectors (as line list primitives) each frame
as a HUD element.
o One simple way to render a 3D object as a HUD element is to add a
translation matrix to the projection matrix. Once objects are in projection
space they have “Normalized Device Coordinates” meaning that the
vertices are in the range [-1, 1] in the XY-axis (where -1 and 1 are the
edges of the screen/back buffer).
Download