本篇是创建游戏内核(4)【OO改良版】的续篇,关于该内核的细节说明请参阅创建游戏内核(5)。
接口:
class WORLD_POSITION
{
public:
WORLD_POSITION();
void init();
void update();
void copy_to(WORLD_POSITION* dest_pos);
void enable_billboard(BOOL use_billboard);
D3DXMATRIX* get_matrix();
void set_matrix(const D3DXMATRIX* mat_world);
void set_combine_matrix_1(D3DXMATRIX* matrix);
void set_combine_matrix_2(D3DXMATRIX* matrix);
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 scale(float x_scale, float y_scale, float z_scale);
void scale_rel(float x_add, float y_add, float z_add);
float get_x_pos();
float get_y_pos();
float get_z_pos();
float get_x_rotation();
float get_y_rotation();
float get_z_rotation();
float get_x_scale();
float get_y_scale();
float get_z_scale();
private:
BOOL m_use_billboard; // flag indicates whether use billboard
float m_x_pos, m_y_pos, m_z_pos; // current position
float m_x_rotation, m_y_rotation, m_z_rotation; // rotation
float m_x_scale, m_y_scale, m_z_scale; // scale value
D3DXMATRIX m_mat_world; // world transform matrix
D3DXMATRIX m_mat_scale; // scale matrix
D3DXMATRIX m_mat_rotation; // rotation matrix
D3DXMATRIX m_mat_translation; // translation matrix
D3DXMATRIX* m_mat_combine_1; // pointer to combination matrix 1
D3DXMATRIX* m_mat_combine_2; // pointer to combination matrix 2
};
typedef WORLD_POSITION* WORLD_POSITION_PTR;
实现:
//-------------------------------------------------------------------------
// Constrcutor, initialize data member.
//-------------------------------------------------------------------------
WORLD_POSITION::WORLD_POSITION()
{
memset(this, 0, sizeof(*this));
}
//-------------------------------------------------------------------------
// Initialize world position.
//-------------------------------------------------------------------------
void WORLD_POSITION::init()
{
m_use_billboard = TRUE;
scale(1.0, 1.0, 1.0);
update();
}
//-------------------------------------------------------------------------
// update world tranform matrix.
//-------------------------------------------------------------------------
void WORLD_POSITION::update()
{
D3DXMATRIX _mat_view, _mat_transposed;
// setup billboarding matrix
if(m_use_billboard)
{
if(g_d3d_device)
{
g_d3d_device->GetTransform(D3DTS_VIEW, &_mat_view);
D3DXMatrixTranspose(&_mat_transposed, &_mat_view);
_mat_transposed._41 = _mat_transposed._42 = _mat_transposed._43 = 0.0;
_mat_transposed._14 = _mat_transposed._24 = _mat_transposed._34 = 0.0;
}
else
D3DXMatrixIdentity(&_mat_transposed);
}
// combine scaling and rotation matrices first
D3DXMatrixMultiply(&m_mat_world, &m_mat_scale, &m_mat_rotation);
// apply billboard matrix
if(m_use_billboard)
D3DXMatrixMultiply(&m_mat_world, &m_mat_world, &_mat_transposed);
// combine with translation matrix
D3DXMatrixMultiply(&m_mat_world, &m_mat_world, &m_mat_translation);
// combine with combined matrices (if any)
if(m_mat_combine_1 != NULL)
D3DXMatrixMultiply(&m_mat_world, &m_mat_world, m_mat_combine_1);
if(m_mat_combine_2 != NULL)
D3DXMatrixMultiply(&m_mat_world, &m_mat_world, m_mat_combine_2);
}
//-------------------------------------------------------------------------
// copy world position information to another world position object.
//-------------------------------------------------------------------------
void WORLD_POSITION::copy_to(WORLD_POSITION* dest_pos)
{
dest_pos->move(m_x_pos, m_y_pos, m_z_pos);
dest_pos->rotate(m_x_rotation, m_y_rotation, m_z_rotation);
dest_pos->scale(m_x_scale, m_y_scale, m_z_scale);
dest_pos->enable_billboard(m_use_billboard);
}
//-------------------------------------------------------------------------
// Enable or disable billboard.
//-------------------------------------------------------------------------
void WORLD_POSITION::enable_billboard(BOOL use_billboard)
{
m_use_billboard = use_billboard;
}
//-------------------------------------------------------------------------
// Get current world transform matrix.
//-------------------------------------------------------------------------
D3DXMATRIX* WORLD_POSITION::get_matrix()
{
// update world tranform matrix first.
update();
return &m_mat_world;
}
//-------------------------------------------------------------------------
// set world transform matrix.
//-------------------------------------------------------------------------
void WORLD_POSITION::set_matrix(const D3DXMATRIX* mat_world)
{
m_mat_world = *mat_world;
}
//-------------------------------------------------------------------------
// set combination matrix 1 which will be combined with world matrix.
//-------------------------------------------------------------------------
void WORLD_POSITION::set_combine_matrix_1(D3DXMATRIX* matrix)
{
m_mat_combine_1 = matrix;
}
//-------------------------------------------------------------------------
// set combination matrix 2 which will be combined with world matrix.
//-------------------------------------------------------------------------
void WORLD_POSITION::set_combine_matrix_2(D3DXMATRIX* matrix)
{
m_mat_combine_2 = matrix;
}
//-------------------------------------------------------------------------
// move to new world position with specified relative value.
//-------------------------------------------------------------------------
void WORLD_POSITION::move(float x_pos, float y_pos, float z_pos)
{
m_x_pos = x_pos;
m_y_pos = y_pos;
m_z_pos = z_pos;
D3DXMatrixTranslation(&m_mat_translation, m_x_pos, m_y_pos, m_z_pos);
}
//-------------------------------------------------------------------------
// move to new world position which relative to current position.
//-------------------------------------------------------------------------
void WORLD_POSITION::move_rel(float x_add, float y_add, float z_add)
{
move(m_x_pos + x_add, m_y_pos + y_add, m_z_pos + z_add);
}
//-------------------------------------------------------------------------
// rotate around x, y, z, axis with specified degree.
//-------------------------------------------------------------------------
void WORLD_POSITION::rotate(float x_rot, float y_rot, float z_rot)
{
m_x_rotation = x_rot;
m_y_rotation = y_rot;
m_z_rotation = z_rot;
// Builds a matrix with a specified yaw, pitch, and roll.
D3DXMatrixRotationYawPitchRoll(&m_mat_rotation, m_y_rotation, m_x_rotation, m_z_rotation);
}
//-------------------------------------------------------------------------
// rotate around x, y, z, axis which relative to cuurent x, y, z angle.
//-------------------------------------------------------------------------
void WORLD_POSITION::rotate_rel(float x_add, float y_add, float z_add)
{
rotate(m_x_rotation + x_add, m_y_rotation + y_add, m_z_rotation + z_add);
}
//-------------------------------------------------------------------------
// Build scaling matrix.
//-------------------------------------------------------------------------
void WORLD_POSITION::scale(float x_scale, float y_scale, float z_scale)
{
m_x_scale = x_scale;
m_y_scale = y_scale;
m_z_scale = z_scale;
D3DXMatrixScaling(&m_mat_scale, x_scale, y_scale, z_scale);
}
//-------------------------------------------------------------------------
// Build scaling matrix with specified value and current scaling value.
//-------------------------------------------------------------------------
void WORLD_POSITION::scale_rel(float x_add, float y_add, float z_add)
{
scale(m_x_scale + x_add, m_y_scale + y_add, m_z_scale + z_add);
}
//-------------------------------------------------------------------------
// Get current position's x coordinate.
//-------------------------------------------------------------------------
float WORLD_POSITION::get_x_pos()
{
return m_x_pos;
}
//-------------------------------------------------------------------------
// Get current position's y coordinate.
//-------------------------------------------------------------------------
float WORLD_POSITION::get_y_pos()
{
return m_y_pos;
}
//-------------------------------------------------------------------------
// Get current position's z coordinate.
//-------------------------------------------------------------------------
float WORLD_POSITION::get_z_pos()
{
return m_z_pos;
}
//-------------------------------------------------------------------------
// Get current rotation value which rotate around x axis.
//-------------------------------------------------------------------------
float WORLD_POSITION::get_x_rotation()
{
return m_x_rotation;
}
//-------------------------------------------------------------------------
// Get current rotation value which rotate around y axis.
//-------------------------------------------------------------------------
float WORLD_POSITION::get_y_rotation()
{
return m_y_rotation;
}
//-------------------------------------------------------------------------
// Get current rotation value which rotate around z axis.
//-------------------------------------------------------------------------
float WORLD_POSITION::get_z_rotation()
{
return m_z_rotation;
}
//-------------------------------------------------------------------------
// Get current scale value which around x axis.
//-------------------------------------------------------------------------
float WORLD_POSITION::get_x_scale()
{
return m_x_scale;
}
//-------------------------------------------------------------------------
// Get current scale value which around y axis.
//-------------------------------------------------------------------------
float WORLD_POSITION::get_y_scale()
{
return m_y_scale;
}
//-------------------------------------------------------------------------
// Get current scale value which around z axis.
//-------------------------------------------------------------------------
float WORLD_POSITION::get_z_scale()
{
return m_z_scale;
}