创建游戏内核(6)

创建游戏内核(6)


本篇是 创建游戏内核(5)的续篇,其中涉及到矩阵以及坐标系统变换的知识请参阅 DirectX 9的一些数学计算函数:矩阵,坐标变换。以及 DirectX 9的坐标系统变换。

视口变换和CAMERA

CAMERA类和 WORLD_POSITION类非常类似,但CAMERA类处理的是视口变换矩阵。

来看看CAMERA类的定义:
 
//================================================================================
// Defines for class CAMERA.
//================================================================================
class  CAMERA
{
protected :
    
float  _x_pos, _y_pos, _z_pos;                    // camera current position
     float  _x_rot, _y_rot, _z_rot;                    // camera current rotation

    
float  _start_x_pos, _start_y_pos, _start_z_pos;  // start tracking position
     float  _start_x_rot, _start_y_rot, _start_z_rot;  // start tracking rotation

    
float  _end_x_pos, _end_y_pos, _end_z_pos;        // end tracking position
     float  _end_x_rot, _end_y_rot, _end_z_rot;        // end tracking rotation

    D3DXMATRIX _mat_world;          
// world transform matrix
    D3DXMATRIX _mat_translation;     // translation matrix
    D3DXMATRIX _mat_rotation;        // rotation matrix

public :
    CAMERA();

    D3DXMATRIX* Get_Matrix();
    
void  Update();

    
void  Move( float  x_pos,  float  y_pos,  float  z_pos);
    
void  Move_Rel( float  x_add,  float  y_add,  float  z_add);

    
void  Rotate( float  x_rot,  float  y_rot,  float  z_rot);
    
void  Rotate_Rel( float  x_add,  float  y_add,  float  z_add);

    
void  Point( float  x_eye,  float  y_eye,  float  z_eye,  float  x_at,  float  y_at,  float  z_at);

    
void  Set_Start_Track();
    
void  Set_End_Track();
    
void  Track( float  time_ratio,  float  time_length);

    
float  Get_X_Pos();
    
float  Get_Y_Pos();
    
float  Get_Z_Pos();
    
float  Get_X_Rotation();
    
float  Get_Y_Rotation();
    
float  Get_Z_Rotation();
};

接着是CAMERA类的实现:
 
//-------------------------------------------------------------------
// Constructor, initialize camera's current position and rotation.
//-------------------------------------------------------------------
CAMERA::CAMERA()
{
    Move(0.0, 0.0, 0.0);
    Rotate(0.0, 0.0, 0.0);
    Update();
}

//-------------------------------------------------------------------
// Move camera to new position.
//-------------------------------------------------------------------
void  CAMERA::Move( float  x_pos,  float  y_pos,  float  z_pos)
{
    _x_pos = x_pos;  _y_pos = y_pos;  _z_pos = z_pos;

    D3DXMatrixTranslation(&_mat_translation, -x_pos, -y_pos, -z_pos);
}

//-------------------------------------------------------------------
// Move camera to new positoin which is summed by current position and 
// added position.
//-------------------------------------------------------------------
void  CAMERA::Move_Rel( float  x_add,  float  y_add,  float  z_add)
{
    Move(_x_pos + x_add, _y_pos + y_add, _z_pos + z_add);
}

//-------------------------------------------------------------------
// Build rotation matrix.
//-------------------------------------------------------------------
void  CAMERA::Rotate( float  x_rot,  float  y_rot,  float  z_rot)
{
    D3DXMATRIX mat_x_rot, mat_y_rot, mat_z_rot;

    _x_rot = x_rot;  _y_rot = y_rot; _z_rot = z_rot;

    D3DXMatrixRotationX(&mat_x_rot, -x_rot);
    D3DXMatrixRotationX(&mat_y_rot, -y_rot);
    D3DXMatrixRotationX(&mat_z_rot, -z_rot);

    _mat_rotation = mat_z_rot;
    
    D3DXMatrixMultiply(&_mat_rotation, &_mat_rotation, &mat_y_rot);
    D3DXMatrixMultiply(&_mat_rotation, &_mat_rotation, &mat_x_rot);       
}

//-------------------------------------------------------------------
// Build rotation matrix which is summed by current rotation value 
// and added rotation value.
//-------------------------------------------------------------------
void  CAMERA::Rotate_Rel( float  x_add,  float  y_add,  float  z_add)
{
    Rotate(_x_rot + x_add, _y_rot + y_add, _z_rot + z_add);
}

//-------------------------------------------------------------------
// Move camera to new position and look at new target position.
//-------------------------------------------------------------------
void  CAMERA::Point( float  x_eye,  float  y_eye,  float  z_eye,  float  x_at,  float  y_at,  float  z_at)
{
    
// Calculate angles between points

    
float  x_diff = x_at - x_eye;
    
float  y_diff = y_at - y_eye;
    
float  z_diff = z_at - z_eye;

    
float  x_rot = ( float ) atan2(-y_diff, sqrt(x_diff * x_diff + z_diff * z_diff));
    
float  y_rot = ( float ) atan2(x_diff, z_diff);

    
// Move camera to new position and look at new target
    Move(x_eye, y_eye, z_eye);
    Rotate(x_rot, y_rot, 0.0);
}

//-------------------------------------------------------------------
// Set camera's start tracking position and rotation.
//-------------------------------------------------------------------
void  CAMERA::Set_Start_Track()
{
    _start_x_pos = _x_pos;  _start_y_pos = _y_pos;  _start_z_pos = _z_pos;
    _start_x_rot = _x_rot;  _start_y_rot = _y_rot;  _start_z_rot = _z_rot;
}

//-------------------------------------------------------------------
// Set camera's end tracking position and rotation.
//-------------------------------------------------------------------
void  CAMERA::Set_End_Track()
{
    _end_x_pos = _x_pos;  _end_y_pos = _y_pos;  _end_z_pos = _z_pos;
    _end_x_rot = _x_rot;  _end_y_rot = _y_rot;  _end_z_rot = _z_rot;
}

//-------------------------------------------------------------------
// Move camera to new position and ratation by giving time, 
// 0 <= time_ratio <= 1.
//-------------------------------------------------------------------
void  CAMERA::Track( float  time_ratio,  float  time_length)
{
    
float  time_offset = time_length * time_ratio;

    
float  x = (_end_x_pos - _start_x_pos) / time_length * time_offset;
    
float  y = (_end_y_pos - _start_y_pos) / time_length * time_offset;
    
float  z = (_end_z_pos - _start_z_pos) / time_length * time_offset;

    Move(_start_x_pos + x, _start_y_pos + y, _start_z_pos + z);

    x = (_end_x_rot - _start_x_rot) / time_length * time_offset;
    y = (_end_y_rot - _start_y_rot) / time_length * time_offset;
    z = (_end_z_rot - _start_z_rot) / time_length * time_offset;

    Rotate(_start_x_rot + x, _start_y_rot + y, _start_z_rot + z);
}

//-------------------------------------------------------------------
// Update new camera world transform matrix.
//-------------------------------------------------------------------
void  CAMERA::Update()
{
    D3DXMatrixMultiply(&_mat_world, &_mat_translation, &_mat_rotation);
}

//-------------------------------------------------------------------
// Get camera world transform matrix.
//-------------------------------------------------------------------
D3DXMATRIX* CAMERA::Get_Matrix()
{
    Update();

    
return  &_mat_world;
}

//-------------------------------------------------------------------
// Get camera current position (x coordinate).
//-------------------------------------------------------------------
float  CAMERA::Get_X_Pos()
{
    
return  _x_pos;
}

//-------------------------------------------------------------------
// Get camera current position (y coordinate).
//-------------------------------------------------------------------
float  CAMERA::Get_Y_Pos()
{
    
return  _y_pos;
}

//-------------------------------------------------------------------
// Get camera current position (z coordinate).
//-------------------------------------------------------------------
float  CAMERA::Get_Z_Pos()
{
    
return  _z_pos;
}

//-------------------------------------------------------------------
// Get camera current rotation (x coordinate).
//-------------------------------------------------------------------
float  CAMERA::Get_X_Rotation()
{
    
return  _x_rot;
}

//-------------------------------------------------------------------
// Get camera current rotation (y coordinate).
//-------------------------------------------------------------------
float  CAMERA::Get_Y_Rotation()
{
    
return  _y_rot;
}

//-------------------------------------------------------------------
// Get camera current rotation (z coordinate).
//-------------------------------------------------------------------
float  CAMERA::Get_Z_Rotation()
{
    
return  _z_rot;
}

CAMERA类和WORLD_POSITION类惟一的不同就是加上了Point、Set_Start_Track、 Set_End_Track以及Track函数。Point函数用来确定观察点的方位并在瞬间将它指向一个特定的方向。

三个同追踪有关的函数随着时间追踪摄像机的移动路径。要使用摄像机追踪方位,将摄像机放到预想的起始位置并调用CAMERA:: Set_Start_Track,然后再将摄像机移动到预想的结束方位并调用CAMERA::Set_End_Track即可。

接下来需要调用CAMERA::Track函数(要在调用CAMERA::Update之前调用它)沿着创建的轨迹来定位摄像机。 Track函数的time_ratio参数的范围从0.0(起始方位)-1.0(结束方位),任何介于此范围内的值都会将摄像机沿着轨迹进行移动, time_length可以是任意起作用的值(举例来说,毫秒)。

摄像机追踪创建了一些很棒的效果,下面的示例说明了这一点:
 
    CAMERA camera;

    
// 移到位置(0.0, 100.0, -100.0)处并朝向原点
    camera.Point(0.0, 100.0, -100.0, 0.0, 0.0, 0.0);
    camera.Set_Start_Track();

    
// 移到结束方位
    camera.Point(-100.0, 0.0, 0.0, 0.0, 100.0, 0.0);
    camera.Set_End_Track();

    
// 每过10000毫秒将摄像机放置到起始方位和结束方位的一半处
    camera.Track(0.5, 10000);
    camera.Update();

你可能感兴趣的:(创建游戏内核(6))