本篇是创建游戏内核(5)【接口与实现分离版】的续篇,关于该内核的细节说明请参考创建游戏内核(6),这个版本主要是按照功能划分模块的思想,并严格按照接口与实现相分离的原则来写的,没有用面向对象的思想来写,没有继承没有多态。大家可以对比两个版本,比较优劣。
接口:
/*************************************************************************
PURPOSE:
Interface for D3D camera.
*************************************************************************/
#ifndef _CORE_CAMERA_H_
#define _CORE_CAMERA_H_
#include "core_common.h"
typedef void* CAMERA;
CAMERA camera_create();
void camera_move(CAMERA camera, float x_pos, float y_pos, float z_pos);
void camera_rotate(CAMERA camera, float x_rot, float y_rot, float z_rot);
void camera_point(CAMERA camera,
float x_eye, float y_eye, float z_eye,
float x_at, float y_at, float z_at);
void camera_set_start_track(CAMERA camera);
void camera_set_end_track(CAMERA camera);
void camera_track(CAMERA camera, float time_ratio, float time_length);
void camera_update(CAMERA camera);
D3DXMATRIX* camera_get_matrix(CAMERA camera);
float camera_get_x_pos(CAMERA camera);
float camera_get_y_pos(CAMERA camera);
float camera_get_z_pos(CAMERA camera);
float camera_get_x_rot(CAMERA camera);
float camera_get_y_rot(CAMERA camera);
float camera_get_z_rot(CAMERA camera);
#endif
实现:
/***********************************************************************************
PURPOSE:
Implement for D3D camera.
***********************************************************************************/
#include "core_common.h"
#include "core_camera.h"
typedef struct _CAMERA
{
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
} *_CAMERA_PTR;
//----------------------------------------------------------------------------------------
// Create camera.
//----------------------------------------------------------------------------------------
CAMERA camera_create()
{
_CAMERA_PTR _camera = (_CAMERA_PTR) malloc(sizeof(_CAMERA));
memset(_camera, 0, sizeof(_CAMERA));
return (CAMERA) _camera;
}
//----------------------------------------------------------------------------------------
// move camera to new position.
//----------------------------------------------------------------------------------------
void camera_move(CAMERA camera, float x_pos, float y_pos, float z_pos)
{
_CAMERA_PTR _camera = (_CAMERA_PTR) camera;
_camera->x_pos = x_pos;
_camera->y_pos = y_pos;
_camera->z_pos = z_pos;
D3DXMatrixTranslation(&_camera->mat_translation, -x_pos, -y_pos, -z_pos);
}
//-------------------------------------------------------------------------
// rotate camera.
//-------------------------------------------------------------------------
void camera_rotate(CAMERA camera, float x_rot, float y_rot, float z_rot)
{
D3DXMATRIX _mat_x_rot, _mat_y_rot, _mat_z_rot;
_CAMERA_PTR _camera = (_CAMERA_PTR) camera;
_camera->x_rot = x_rot;
_camera->y_rot = y_rot;
_camera->z_rot = z_rot;
_camera->mat_rotation = _mat_z_rot;
D3DXMatrixMultiply(&_camera->mat_rotation, &_camera->mat_rotation, &_mat_y_rot);
D3DXMatrixMultiply(&_camera->mat_rotation, &_camera->mat_rotation, &_mat_x_rot);
}
//-------------------------------------------------------------------------
// move camera to new position and look at new target position.
//-------------------------------------------------------------------------
void camera_point(CAMERA camera,
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
camera_move(camera, x_eye, y_eye, z_eye);
camera_rotate(camera, _x_rot, _y_rot, 0.0);
}
//-------------------------------------------------------------------------
// set camera's start tracking position and rotation.
//-------------------------------------------------------------------------
void camera_set_start_track(CAMERA camera)
{
_CAMERA_PTR _camera = (_CAMERA_PTR) camera;
_camera->start_x_pos = _camera->x_pos;
_camera->start_y_pos = _camera->y_pos;
_camera->start_z_pos = _camera->z_pos;
_camera->start_x_rot = _camera->x_rot;
_camera->start_y_rot = _camera->y_rot;
_camera->start_z_rot = _camera->z_rot;
}
//-------------------------------------------------------------------------
// set camera's end tracking position and rotation.
//-------------------------------------------------------------------------
void camera_set_end_track(CAMERA camera)
{
_CAMERA_PTR _camera = (_CAMERA_PTR) camera;
_camera->end_x_pos = _camera->x_pos;
_camera->end_y_pos = _camera->y_pos;
_camera->end_z_pos = _camera->z_pos;
_camera->end_x_rot = _camera->x_rot;
_camera->end_y_rot = _camera->y_rot;
_camera->end_z_rot = _camera->z_rot;
}
//-------------------------------------------------------------------------
// move camera to new position and ratation by giving time,
// 0 <= time_ratio <= 1.
//-------------------------------------------------------------------------
void camera_track(CAMERA camera, float time_ratio, float time_length)
{
_CAMERA_PTR _camera = (_CAMERA_PTR) camera;
float _time_offset = time_length * time_ratio;
float _x = (_camera->end_x_pos - _camera->start_x_pos) / time_length * _time_offset;
float _y = (_camera->end_y_pos - _camera->start_y_pos) / time_length * _time_offset;
float _z = (_camera->end_z_pos - _camera->start_z_pos) / time_length * _time_offset;
camera_move(camera, _camera->start_x_pos + _x, _camera->start_y_pos + _y, _camera->start_z_pos + _z);
_x = (_camera->end_x_rot - _camera->start_x_rot) / time_length * _time_offset;
_y = (_camera->end_y_rot - _camera->start_y_rot) / time_length * _time_offset;
_z = (_camera->end_z_rot - _camera->start_z_rot) / time_length * _time_offset;
camera_rotate(camera, _camera->start_x_rot + _x, _camera->start_y_rot + _y, _camera->start_z_rot + _z);
}
//-------------------------------------------------------------------------
// update new camera world transform matrix.
//-------------------------------------------------------------------------
void camera_update(CAMERA camera)
{
_CAMERA_PTR _camera = (_CAMERA_PTR) camera;
D3DXMatrixMultiply(&_camera->mat_world, &_camera->mat_translation, &_camera->mat_rotation);
}
//-------------------------------------------------------------------------
// Get camera world transform matrix.
//-------------------------------------------------------------------------
D3DXMATRIX* camera_get_matrix(CAMERA camera)
{
camera_update(camera);
return & ((_CAMERA_PTR) camera)->mat_world;
}
//-------------------------------------------------------------------------
// Get camera current position (x coordinate).
//-------------------------------------------------------------------------
float camera_get_x_pos(CAMERA camera)
{
return ((_CAMERA_PTR) camera)->x_pos;
}
//-------------------------------------------------------------------------
// Get camera current position (y coordinate).
//-------------------------------------------------------------------------
float camera_get_y_pos(CAMERA camera)
{
return ((_CAMERA_PTR) camera)->y_pos;
}
//-------------------------------------------------------------------------
// Get camera current position (z coordinate).
//-------------------------------------------------------------------------
float camera_get_z_pos(CAMERA camera)
{
return ((_CAMERA_PTR) camera)->z_pos;
}
//-------------------------------------------------------------------------
// Get camera current rotation (x coordinate).
//-------------------------------------------------------------------------
float camera_get_x_rot(CAMERA camera)
{
return ((_CAMERA_PTR) camera)->x_rot;
}
//-------------------------------------------------------------------------
// Get camera current rotation (y coordinate).
//-------------------------------------------------------------------------
float camera_get_y_rot(CAMERA camera)
{
return ((_CAMERA_PTR) camera)->y_rot;
}
//-------------------------------------------------------------------------
// Get camera current rotation (z coordinate).
//-------------------------------------------------------------------------
float camera_get_z_rot(CAMERA camera)
{
return ((_CAMERA_PTR) camera)->z_rot;
}