Microsoft XNA Game Studio Creator’s Guide- P11

Chia sẻ: Cong Thanh | Ngày: | Loại File: PDF | Số trang:30

0
51
lượt xem
8

Microsoft XNA Game Studio Creator’s Guide- P11

Mô tả tài liệu

Microsoft XNA Game Studio Creator’s Guide- P11:The release of the XNA platform and specifically the ability for anyone to write Xbox 360 console games was truly a major progression in the game-programming world. Before XNA, it was simply too complicated and costly for a student, software hobbyist, or independent game developer to gain access to a decent development kit for a major console platform.

Chủ đề:

Bình luận(0)

Lưu

Nội dung Text: Microsoft XNA Game Studio Creator’s Guide- P11

1. 278 MICROSOFT XNA GAME STUDIO CREATOR’S GUIDE vector that stores a rotation around an axis. Quaternion math is used to calculate an increment to update the camera’s Look vector. We can express the value of the Look vector like this: Look = View - Position By rearranging this equation we can say the following: View = Look + Position If the quaternion represents the updated Look vector, then Updated View = Updated Look Vector + Position Updated Look Vector The formula for calculating the updated Look vector is: qRotation * qLook * qRotation' (qRotation' is the conjugate of qRotation) Each of the three operands will be discussed next. Local Rotation Quaternion The first quaternion that is used to calculate the updated Look vector, qRotation, is a local rotation. Quaternion theory provides a formula for computing the local ro- tation. In this case, the local rotation is generated using a direction vector for X, Y, and Z. Rotations about the X axis are applied using the Look vector. Rotations about the Y axis are applied using the Right direction vector. The rotation angle stored in the W component is obtained from the deviation of the mouse (or thumbstick) from the center of the window. With this information, we can generate the local rotation by writing the following: qRotation.W = cos(MouseDeviationFromCenter/2) qRotation.X = UnitDirection.X * sin(MouseDeviationFromCenter/2) qRotation.Y = UnitDirection.Y * sin(MouseDeviationFromCenter/2) qRotation.Z = UnitDirection.Z * sin(MouseDeviationFromCenter/2) Using the Look Vector as a Quaternion The next quaternion used in the formula for the updated Look vector is based on the Look direction: qLook.X = Look.X qLook.Y = Look.Y qLook.Z = Look.Z qLook.W = 0
2. C H A P T E R 1 7 279 Building a Graphics Engine Camera Conjugate Quaternion A conjugate quaternion is used to calculate the updated Look vector. The conjugate is created by negating a quaternion vector’s X, Y, and Z components: Quaternion conjugate = (-Quaternion.X, -Quaternion.Y, -Quaternion.Z, Quaternion.W) Quaternion Product The equation for multiplying two quaternion is as follows: (Quaternion1*Quaternion2).W = W 1 x2 - x 1 w2 + y1y2 - z1z2 (Quaternion1*Quaternion2).X = w 1 x2 + x 1 w2 + y1z2 - z1y2 (Quaternion1*Quaternion2).Y = w 1 y2 - x 1 z2 + y1w2 + z1x2 (Quaternion1*Quaternion2).Z = w 1 z2 + x 1 y2 - y1x2 + z1w2 Updating the View The updated Look vector is obtained using the product of local rotation, look, and conjugate quaternions. Updated Look Vector = qRotation * qLook * qRotation' With the result from this product, the View can be updated: Updated View = Updated Look Vector + Position Now you will apply this logic to the graphics engine to update your view. Updating the View in the Camera Class RotationQuaternion() can be added to the camera class to generate the local rotation quaternion based on the direction vector. The first parameter of this method represents the shift of the mouse or thumbstick from the resting position. The second parameter is a direction vector that can be either the Look or Right vector: private Vector4 RotationQuaternion(float degrees, Vector3 direction){ Vector4 unitAxis = Vector4.Zero; Vector4 axis = new Vector4(direction, 0.0f); // only normalize if necessary if ((axis.X != 0 && axis.X != 1) || (axis.Y != 0 && axis.Y != 1) || (axis.Z != 0 && axis.Z != 1)){
3. 280 MICROSOFT XNA GAME STUDIO CREATOR’S GUIDE unitAxis = Vector4.Normalize(axis); } float angle = degrees * MathHelper.Pi/180.0f; float sin = (float)Math.Sin(angle/2.0f); // create the quaternion. Vector4 quaternion = new Vector4(0.0f, 0.0f, 0.0f, 0.0f); quaternion.X = axis.X * sin; quaternion.Y = axis.Y * sin; quaternion.Z = axis.Z * sin; quaternion.W = (float)Math.Cos(angle/2.0f); return Vector4.Normalize(quaternion); } Next, you’ll add the UpdateView() method. UpdateView() computes the product of these three quaternions and uses it to update the player’s view: private void UpdateView(float rotationAmount, Vector3 direction) { // local rotation quaternion Vector4 Q = RotationQuaternion(rotationAmount, direction); Vector4 look = Vector4.Zero; look.X = view.X - position.X; look.Y = view.Y - position.Y; look.Z = view.Z - position.Z; // rotation quaternion * look Vector4 Qp; Qp.X = Q.W*look.X + Q.X*look.W + Q.Y*look.Z - Q.Z*look.Y; Qp.Y = Q.W*look.Y - Q.X*look.Z + Q.Y*look.W + Q.Z*look.X; Qp.Z = Q.W*look.Z + Q.X*look.Y - Q.Y*look.X + Q.Z*look.W; Qp.W = Q.W*look.W - Q.X*look.X - Q.Y*look.Y - Q.Z*look.Z; // conjugate is made by negating quaternion x, y, and z Vector4 conj = new Vector4(-Q.X, -Q.Y, -Q.Z, Q.W); // updated look vector Vector4 Qlook;
4. C H A P T E R 1 7 281 Building a Graphics Engine Camera Qlook.X = Qp.W*conj.X + Qp.X*conj.W + Qp.Y*conj.Z - Qp.Z*conj.Y; Qlook.Y = Qp.W*conj.Y - Qp.X*conj.Z + Qp.Y*conj.W + Qp.Z*conj.X; Qlook.Z = Qp.W*conj.Z + Qp.X*conj.Y - Qp.Y*conj.X + Qp.Z*conj.W; Qlook.W = Qp.W*conj.W - Qp.X*conj.X - Qp.Y*conj.Y - Qp.Z*conj.Z; // cap view at ground and sky if (Qlook.Y > -0.49f && Qlook.Y < 0.49f){ // updated view equals position plus the quaternion view.X = position.X + Qlook.X; view.Y = position.Y + Qlook.Y; view.Z = position.Z + Qlook.Z; } } The camera class uses the ChangeView() method to receive changes in View di- rection from the game class and apply them to the camera orientation. ChangeView() checks whether the mouse or right stick has been shifted. If no movement is detected, the method exits and no changes to the view are performed. Otherwise, a relative measure for the X and Y rotations is generated based on the de- viation of the mouse from the center of the window. Rotations about the X axis are applied using the Right vector. Rotations about the Y axis are applied using the Up vector: public void ChangeView(float X, float Y) { // exit if no change to view if (X == 0 && Y == 0) return; float rotationX, rotationY; const float SCALEX = 50.0f; const float SCALEY = 2000.0f; Vector3 look = view - position; // tilt camera up and down Vector3 right = Vector3.Cross(look, up); rotationX = Y / SCALEX; UpdateView(rotationX, Vector3.Normalize(right)); // swivel camera left and right rotationY = X * timeLapse / SCALEY; UpdateView(-rotationY, up); }
5. 282 MICROSOFT XNA GAME STUDIO CREATOR’S GUIDE With ChangeView() in the game class, it will adjust the camera view according to shifts of the mouse or left thumbstick. A revised SetView() method in the cam- era class replaces the existing one to process changes to the camera’s Look direction for each frame: public void SetView(Vector2 viewChange){ ChangeView(viewChange.X, viewChange.Y); viewMatrix = Matrix.CreateLookAt(position, view, up); } Triggering Changes to the View from the Game Class Back inside the game class, the camera needs to be enabled for manipulation by the game controller, keyboard, and mouse. The camera will function on the PC like a first-person shooter, where a typical configuration uses the mouse to change the view. XNA provides the Mouse and MouseState classes to handle the mouse on a PC. When run on the PC, the mouse has to be enabled in the game class. The mouse will adjust the view by checking the distance from the center of the window to the mouse. At the top of the game class, a MouseState object is declared: #if !XBOX MouseState mouse; #endif The game class’s ChangeView() method receives changes in view on X and Y that are triggered from the game class by mouse movements, or by shifts to the right thumbstick. After the relative changes in view have been captured and processed on the PC, the Mouse class SetPosition() method moves the cursor back to the cen- ter of the window so the mouse’s relative change from the center of the window can be calculated in the next frame. Otherwise, the camera will use the right stick’s devia- tion from the center to calculate the change in view: Vector2 ChangeView(GameTime gameTime){ const float SENSITIVITY = 250.0f; const float VERTICAL_INVERSION =-1.0f; // vertical view control // negate to reverse // handle change in view using right and left keys KeyboardState kbState = Keyboard.GetState(); int widthMiddle = Window.ClientBounds.Width/2; int heightMiddle = Window.ClientBounds.Height/2; Vector2 change = Vector2.Zero;
6. C H A P T E R 1 7 283 Building a Graphics Engine Camera GamePadState gp = GamePad.GetState(PlayerIndex.One); if (gp.IsConnected == true) // gamepad on PC / Xbox { float scaleY = VERTICAL_INVERSION * (float) gameTime.ElapsedGameTime.Milliseconds/50.0f; change.Y = scaleY * gp.ThumbSticks.Right.Y * SENSITIVITY; change.X = gp.ThumbSticks.Right.X * SENSITIVITY; } else{ // mouse only (on PC) #if !XBOX float scaleY = VERTICAL_INVERSION * (float) gameTime.ElapsedGameTime.Milliseconds/100.0f; float scaleX = (float) gameTime.ElapsedGameTime.Milliseconds/400.0f; // get cursor position mouse = Mouse.GetState(); // cursor not at center on X if (mouse.X != widthMiddle){ change.X = mouse.X - widthMiddle; change.X /= scaleX; } // cursor not at center on Y if (mouse.Y != heightMiddle){ change.Y = mouse.Y - heightMiddle; change.Y /= scaleY; } // reset cursor back to center Mouse.SetPosition(widthMiddle, heightMiddle); #endif } return change; } To update your camera’s view from the game class (for each frame), replace the existing call to SetView() from the Update() method with this revision that changes the view based on how the mouse or right thumbstick is shifted: cam.SetView(ChangeView(gameTime)); If you run your code now, your project will have a fully functional camera en- abled. To actually see it moving, you need to draw some kind of reference, such as
8. CHAPTER 18 Collision Detection