创建游戏内核(5)【C风格版】

创建游戏内核(5)【C风格版】

 

本篇是创建游戏内核(4)【C风格版】的续篇,关于该内核的细节说明请参考创建游戏内核(5)。

 

接口:

typedef  struct  WORLD_POS
{
    BOOL use_billboard;                 
// flag indicates whether use billboard

    
float  x_pos, y_pos, z_pos;           // current position
     float  x_rot, y_rot, z_rot;           // cuurent rotation
     float  x_scale, y_scale, z_scale;     // current scale value

    D3DXMATRIX  mat_world;              
// world transform matrix
    D3DXMATRIX  mat_scale;               // scale matrix
    D3DXMATRIX  mat_rotation;            // rotation matrix
    D3DXMATRIX  mat_translation;         // translation matrix
    D3DXMATRIX* mat_combine_1;           // pointer to combination matrix 1
    D3DXMATRIX* mat_combine_2;           // pointer to combination matrix 2
} *WORLD_POS_PTR;

WORLD_POS_PTR create_world_pos();
void  destroy_world_pos(WORLD_POS_PTR world_pos);

void  clone_world_pos(WORLD_POS_PTR dest,  const  WORLD_POS_PTR source);

void  move_world_pos(WORLD_POS_PTR world_pos, 
                    
float  x_pos,  float  y_pos,  float  z_pos);

void  move_world_pos_rel(WORLD_POS_PTR world_pos, 
                        
float  x_add,  float  y_add,  float  z_add);

void  rotate_world_pos(WORLD_POS_PTR world_pos, 
                      
float  x_rot,  float  y_rot,  float  z_rot);

void  rotate_world_pos_rel(WORLD_POS_PTR world_pos, 
                          
float  x_add,  float  y_add,  float  z_add);

void  scale_world_pos(WORLD_POS_PTR world_pos, 
                     
float  x_scale,  float  y_scale,  float  z_scale);

void  scale_world_pos_rel(WORLD_POS_PTR world_pos, 
                         
float  x_add,  float  y_add,  float  z_add);

void  update_world_pos(WORLD_POS_PTR world_pos);

实现:

//-------------------------------------------------------------------------
// create world position object.
//-------------------------------------------------------------------------
WORLD_POS_PTR create_world_pos()
{
    WORLD_POS_PTR world_pos = (WORLD_POS_PTR) malloc(
sizeof (WORLD_POS));

    memset(world_pos, 0, 
sizeof (WORLD_POS));

    world_pos->use_billboard = TRUE;
    world_pos->x_scale = world_pos->y_scale = world_pos->z_scale = 1.0f;

    update_world_pos(world_pos);
    
    
return  world_pos;
}

//-------------------------------------------------------------------------
// destroy world position object.
//-------------------------------------------------------------------------
void  destroy_world_pos(WORLD_POS_PTR world_pos)
{
    free(world_pos);
}

//-------------------------------------------------------------------------
// clone world position information to another world position object.
//-------------------------------------------------------------------------
void  clone_world_pos(WORLD_POS_PTR dest,  const  WORLD_POS_PTR source)
{        
    move_world_pos(dest, source->x_pos, source->y_pos, source->z_pos);
    rotate_world_pos(dest, source->x_rot, source->y_rot, source->z_rot);
    scale_world_pos(dest, source->x_scale, source->y_scale, source->z_scale);
    
    dest->use_billboard = source->use_billboard;    
}

//-------------------------------------------------------------------------
// move to new world position with specified relative value.
//-------------------------------------------------------------------------
void  move_world_pos(WORLD_POS_PTR world_pos, 
                    
float  x_pos,  float  y_pos,  float  z_pos)
{    
    world_pos->x_pos = x_pos;
    world_pos->y_pos = y_pos;
    world_pos->z_pos = z_pos;

    D3DXMatrixTranslation(&world_pos->mat_translation, x_pos, y_pos, z_pos);
}

//-------------------------------------------------------------------------
// move to new world position which relative to current position.
//-------------------------------------------------------------------------
void  move_world_pos_rel(WORLD_POS_PTR world_pos, 
                        
float  x_add,  float  y_add,  float  z_add)
{    
    move_world_pos(world_pos, 
        world_pos->x_pos + x_add, world_pos->y_pos + y_add, world_pos->z_pos + z_add);
}

//-------------------------------------------------------------------------
// rotate around x, y, z, axis with specified degree.
//-------------------------------------------------------------------------
void  rotate_world_pos(WORLD_POS_PTR world_pos, 
                      
float  x_rot,  float  y_rot,  float  z_rot)
{    
    world_pos->x_rot = x_rot;
    world_pos->y_rot = y_rot;
    world_pos->z_rot = z_rot;

    
// Builds a matrix with a specified yaw, pitch, and roll.
    D3DXMatrixRotationYawPitchRoll(&world_pos->mat_rotation, y_rot, x_rot, z_rot);
}

//-------------------------------------------------------------------------
// rotate around x, y, z, axis which relative to cuurent x, y, z angle.
//-------------------------------------------------------------------------
void  rotate_world_pos_rel(WORLD_POS_PTR world_pos, 
                          
float  x_add,  float  y_add,  float  z_add)
{   
    rotate_world_pos(world_pos, 
        world_pos->x_rot + x_add, world_pos->y_rot + y_add, world_pos->z_rot + z_add);    
}

//-------------------------------------------------------------------------
// Scale world position.
//-------------------------------------------------------------------------
void  scale_world_pos(WORLD_POS_PTR world_pos, 
                     
float  x_scale,  float  y_scale,  float  z_scale)
{    
    world_pos->x_scale = x_scale;
    world_pos->y_scale = y_scale;
    world_pos->z_scale = z_scale;

    D3DXMatrixScaling(&world_pos->mat_scale, x_scale, y_scale, z_scale);
}

//-------------------------------------------------------------------------
// Scale world position which relative to current scale value.
//-------------------------------------------------------------------------
void  scale_world_pos_rel(WORLD_POS_PTR world_pos, 
                         
float  x_add,  float  y_add,  float  z_add)
{
    scale_world_pos(world_pos, 
        world_pos->x_pos + x_add, world_pos->y_pos + y_add, world_pos->z_pos + z_add);
}

//-------------------------------------------------------------------------
// Update world transformation matrix.
//-------------------------------------------------------------------------
void  update_world_pos(WORLD_POS_PTR world_pos)
{   
    D3DXMATRIX mat_view, mat_transposed;    

    
// setup billboarding matrix
     if (world_pos->use_billboard)
    {        
        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;        
    }

    
// combine scaling and rotation matrices first
    D3DXMatrixMultiply(&world_pos->mat_world, &world_pos->mat_scale, &world_pos->mat_rotation);

    
// apply billboard matrix
     if (world_pos->use_billboard)
        D3DXMatrixMultiply(&world_pos->mat_world, &world_pos->mat_world, &mat_transposed);

    
// combine with translation matrix
    D3DXMatrixMultiply(&world_pos->mat_world, &world_pos->mat_world, &world_pos->mat_translation);

    
// combine with combined matrices (if any)

    
if (world_pos->mat_combine_1)
        D3DXMatrixMultiply(&world_pos->mat_world, &world_pos->mat_world, world_pos->mat_combine_1);

    
if (world_pos->mat_combine_2)
        D3DXMatrixMultiply(&world_pos->mat_world, &world_pos->mat_world, world_pos->mat_combine_2);
}

 

你可能感兴趣的:(创建游戏内核(5)【C风格版】)