Game Development BASICS (12)

Source: Internet
Author: User

 

Chapter 2
The d3dxmatrixlookatlh function is used to calculate the observation matrix (that is, the landscape transformation matrix). This function is useful when the camera orientation is fixed at a fixed location, however, its users cannot respond to a mobile camera based on user input,

Use four camera vectors: Right vector, up vector, look vector, and position vector) to define the camera's position and orientation relative to the world coordinate system. these vectors define a local coordinate system for the camera that describes the relative world coordinate system. Because of the right vector, the upper vector and the observation vector define the orientation of the camera in the world coordinate system, sometimes these three vectors are collectively referred to as orientation vector direction vectors must be standard orthogonal. If the vectors in a vector set are orthogonal to each other and the modulus are 1, it is called the vector in the standard orthogonal way. The reason for introducing these constraints is to insert these vectors into some rows of a matrix, to make the matrix A standard orthogonal matrix (if the row vector of a matrix is standard orthogonal), an important property of the standard orthogonal matrix is that its inverse matrix is equal to its transpose matrix.

Using four vectors to describe the camera, we can implement six transformations on the camera.
# Pitch or pitch)
# Rotate the up vector (yaw, yaw)
# Rotate the look vector (scroll, roll)
# Strafe)
# Fly)
# Moving along the vector look

Through the above six operations, the camera can be moved along three axes and has been rotated around three axes, that is, the camera has 6 degrees of freedom

Class camera
{
Public:
// Supports two camera models aircraft allows free motion in space, with 6 degrees of freedom
// Landobject moves along certain axes
Enum cameratype {landobject, aircraft };
 
Camera ();
Camera (cameratype );
~ Camera ();

Void strafe (flaot units );
Void fly (float units );
Void walk (float units );

Void pitch (float angle );
Void yaw (float angle );
Void roll (float angle );

Void getviewmatrix (d3dxmatrix * V );
Void setcameratype (cameratype );
Void getposition (d3dxvector3 * POS );
Void setposition (d3dxvector3 * POS );

Void getright (d3dxvector3 * right );
Void getup (d3dxvector3 * up );
Void getlook (d3dxvector3 * Look );
PRIVATE:
Cameratype _ cameratype;
D3dxvector3 _ right;
D3dxvector3 _ up;
D3dxvector3 _ Look;
D3dxvector3 _ Pos;
};

Calculate the scene transformation matrix, such as P = (PX, Py, PZ), r = (RX, Ry, Rz), u = (UX, Uy, uz ), D = (dx, Dy, Dz) represents the position, right, up, And look vectors respectively.

In fact, the problem solved by landscape transformation is that if an object in the world coordinate system is described in the camera-centered coordinate system, it is equivalent to converting an object in the world coordinate system along with the camera, to make the camera coordinate system completely coincide with the world coordinate system

Therefore, the transformation matrix V can be implemented as follows:
# Pv = (, 0) matrix V moves the camera to the origin of the world coordinate system
# Rv = (, 0) matrix V overlaps the right vector of the camera with the X axis of the world coordinate system
# UV = (, 0) matrix V overlaps the up vector of the camera with the Y axis of the world coordinate system
# DV = (, 1) the rectangle v overlaps the camera's look vector with the Z axis of the world coordinate system.
In this way, the task of calculating this matrix can be divided into two steps: first, the camera is moved to the origin of the world coordinate system, and then the camera vectors and the world coordinate system correspond to each axis through Rotation Transformation

Translation:
The position vector p of the camera can be easily translated to the origin by adding it to the vector-P, Because p-p = 0
Rotate
The workload of the cameras to the axes in the world coordinate system is slightly larger. A 3x3 rotation matrix A is required to make the right, up, And look of the vectors overlap with the X, Y, and Z axes of the world coordinate system, respectively.

3x3 matrix is used, because it does not need to represent the rotation with homogeneous coordinates. In the following section, extend it to 4x4 matrix.

The following matrix can be used to make the conversion of the overlapping axes of the camera and the axes of the world coordinate system:
A = RX UX DX
[Ry Uy dy]
Rz uz DZ

Integration of the first two steps
Expand A to a 4x4 matrix and integrate the first two steps of the landscape transformation to obtain the complete observation matrix v.
Rx ux dx 0
Ry Uy Dy 0
V = [RZ uz DZ 0]
-Pr-pu-Pd 1

In the camera class, use the camera: getviematrix method to calculate the observation matrix.
Void camera: getviewmatrix (d3dxmatrix * V)
{
// Keep camera's axes orthogonal to eachother
D3dxvec3normalize (& _ Look, & _ Look );
 
D3dxvec3cross (& _ up, & _ Look, & _ right );
D3dxvec3normalize (& _ up, & _ up );
 
D3dxvec3cross (& _ right, & _ up, & _ Look );
D3dxvec3normalize (& _ right, & _ right );

// Build the view Matrix
Float x =-d3dxvec3dot (& _ right, & _ POS );
Float y =-d3dxvec3dot (& _ up, & _ POS );
Float Z =-d3dxvec3dot (& _ Look, & _ POS );

(* V) (0, 0) = _ right. X;
(* V) (0, 1) = _ up. X;
(* V) (0, 2) = _ Look. X;
(* V) (0, 3) = 0.0f;

(* V) (1, 0) = _ right. Y;
(* V) (1, 1) = _ up. Y;
(* V) (1, 2) = _ Look. Y;
(* V) (1, 3) = 0.0f;

(* V) (2, 0) = _ right. Z;
(* V) (2, 1) = _ up. Z;
(* V) (2, 2) = _ Look. Z;
(* V) (2, 3) = 0.0f;
 
(* V) (3,0) = x;
(* V) (3, 1) = y;
(* V) (3, 2) = z;
(* V) (3,3) = 1.0f;
}

Because of the error in floating-point calculation, each vector of the camera may no longer be a standard orthogonal, so each time you call this function, you must calculate the vector up based on the vector look, right to ensure that the three are orthogonal to each other, the new orthogonal vector up can be obtained by up = look * right. The new orthogonal vector right can be calculated by Right = up * look.

The camera rotation method should be able to rotate around any axis,
D3dxmatrix * d3dxmatrixrotationaxis (
D3dxmatrix * pout, // returns rotation matrix
Const d3dxvector3 * PV, // axis to rotate around
Float angle // angle, in radians to rotate
);

For example, rotate/2 around the axis determined by the vector (0.707f, 0.707f, 0.0f ).

D3dxmatrix R;
D3dxvector3 axis (0.707f, 0.707f, 0.0f );
D3dxmatrixrotationaxis (& R, & axis, & d3dx_pi/2.0f );

Because the direction vector describes the orientation of the camera in the world coordinate system, when the camera is pitch, yaw, or rolling, you must specify how the direction vector should be updated.

When the camera is raised, the vector up and look must rotate the specified angle around the right of the vector. Similarly, in the case of yaw, the vector look and right must rotate the specified angle around the vector up, when a tumble occurs, you need to rotate the right and up vectors around the specified angle of the vector look.

The necessity to use the d3dxmatrixrotationaxis function is determined because the three directions of the axis of rotation may be in any direction in the world coordinate system.

The implementation of methods pitch, yaw and roll should also follow the principles mentioned in the above discussion, but some constraints need to be added to cameras of the landobjet type.
Especially when a Ground Object is raised and then yaw or rolling occurs, it seems that there are always some problems, so for a landobject-type camera, we should make it rotate around the Y axis of the world coordinate system instead of the UP vector in the yaw method, and completely prohibit the Ground Objects. One thing we must know is that we can change the camera class to adapt to different requirements of applications.

Implementation of Methods pitch, yaw and roll:
// Pitch
Void camera: pitch (float angle)
{
D3dxmatrix T;
D3dxmatrixrotationaxis (& T, & _ right, angle );

// Rotate _ up and _ Look around _ right vector
D3dxvec3transfromcoord (& _ up, & _ up, & T );
D3dxvec3transfromcoord (& _ Look, & _ Look, & T );
}
// Yaw
Void camera: yaw (float angle)
{
D3dxmatrix T;
 
// Rotate around World Y (0, 0) always for land object
If (_ cameratype = landobject)
D3dxmatrixrotationy (& T, angle );

// Rotate around own vector for Aircraft
If (_ cameratype = aircraft)
D3dxmatrixrotationaxis (& T, & _ up, angle );
 
// Rotate _ Right and _ Look around _ up or Y-axis
D3dxvec3transformcoord (& _ right, & right, & T );
D3dxvec3transformcoord (& _ Look, & _ Look, & T );

}
// Scroll
Void camera: Roll (float angle)
{
// Only roll for Aircraft Type
If (_ cameratype = aircraft)
{
D3dxmatrix T;
D3dxmatrixrotationaxis (& T, & _ Look, angle );
 
// Rotate _ up and _ right around _ Look Vector
D3dxvect3transformcoord (& _ right, & right, & T );
D3dxvec3transformcoord (& _ up, & _ up, & T );
}

}

"Walking" refers to the translation along the camera's observation direction (that is, along the direction of the vector look)
'Strafing' means to keep the observation direction unchanged and pan from one side to the other side along the right direction of the vector.
"Flying" refers to the translation along the UP direction of the vector.
To perform translation along any of these axes, you only need to add the current position vector of the camera and a vector in the same direction as the axis.

Like rotation, some constraints must also be added to the motion of the Ground Object. For example, A landobject-type camera should not be moved up or down along its up vector when the observation direction is down, the camera should not be scanned on a slope, so the motion of the camera should be restricted to the xz plane. Then, because the landobject type camera can change its height (climb a building or climb a mountain ), we provide the camera: setposition method to manually specify the camera at a proper height and position.

// Walk
Void camera: Walk (float units)
{
// Move only on xz plane for land object
If (_ cameratype = landobject)
_ POS + = d3dxvector3 (_ Look. X, 0.0f, _ Look. Z) * units;

If (_ cameratype = aircraft)
_ POS + = _ look * units;
}
// Scan
Void camera: strafe (float units)
{
// Move only on xz plane for land object
If (_ cametype = landobject)
_ POS + = d3dxvector3 (_ right. X, 0, 0f, _ right. Z) * units;

If (_ cameratype = aircraft)
_ POS + = _ right * uints;
}
// Upgrade/Downgrade
Void camera: Fly (float units)
{
// Move only on Y-axis for land object
If (_ cameratype = landobject)
_ Pos. Y + = units;
If (_ cameratype = aircraft)
_ POS + = _ up * units;
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.