///关键帧结构
typedef struct KsyFrame
{
DWORD time; //关键帧时间
D3DXMATRIX matTransformation; //关键帧的模型变换矩阵(动画)
}sKeyframe;
sKeyframe g_KeyFrmaes[4]=
{
//keyframe0 ,0ms
{
0,
D3DXMATRIX
(
1.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 1.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 1.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 1.000000f
)
},
//keyframe1,40ms
{
400,
D3DXMATRIX
(
0.000796f, 1.000000f, 0.000000f, 0.000000f,
-1.000000f, 0.000796f, 0.000000f,0.000000f,
0.000000f, 0.000000f, 1.000000f, 0.000000f,
50.000000f, 0.000000f, 0.000000f, 1.000000f
)
},
//keyframe2,80ms
{
800,
D3DXMATRIX
(
-0.999999f, 0.001593f, 0.000000f, 0.000000f,
-0.001593f, -0.999999f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 1.000000f, 0.000000f,
25.000000f, 25.000000f, 0.000000f, 1.000000f
)
},
//keyframe3,120ms
{
1200,
D3DXMATRIX
(
1.000000f, 0.000000f, 0.000000f, 0.000000f,
0.000000f, 1.000000f, 0.000000f, 0.000000f,
0.000000f, 0.000000f, 1.000000f, 0.000000f,
0.000000f, 0.000000f, 0.000000f, 1.000000f
)
}
}; //定义了4帧的关键动画。其中第3帧和第0帧的变换矩阵一样,为了使动画能进入循环状态
///动画循环函数
void DoFrame()
{
//获取程序启初始启动时间
static DWORD start_time=timeGetTime();
//程序运行时间
DWORD run_time=timeGetTime()-start_time;
//得到一个从0到1200ms之间变化的毫秒数,以定位程序当前所处的关键帧
run_time %=(g_KeyFrmaes[3].time+1);
//当前帧 ,从第0帧开始
DWORD keyframe=0;
//获取当前的关键帧
for(int i=0;i<4;++i)
{
if(run_time>=g_KeyFrmaes[i].time)
//更新当前帧
keyframe=i;
}
//获取下一帧
DWORD nextKeyframe=(keyframe==3)?keyframe:(keyframe+1);
///插值运算,获取当前时间的模型变换矩阵
//计算两个关键帧之间的时间差
DWORD timediff=g_KeyFrmaes[nextKeyframe].time-g_KeyFrmaes[keyframe].time;
if (!timediff)
{
timediff=1;
}
//插值时间
float scalar=(float)(run_time-g_KeyFrmaes[keyframe].time/timediff);
D3DXMATRIX matInt = D3DXMATRIX(g_KeyFrmaes[nextKeyframe].matTransformation) -
D3DXMATRIX(g_KeyFrmaes[keyframe].matTransformation);
//插值变换矩阵
matInt*=scalar;
//计算当前时间相对于当前帧keyframe的模型变换矩阵
matInt+=g_KeyFrmaes[keyframe].matTransformation;
//模型变换
g_pd3dDevice->SetTransform(D3DTS_WORLD,&matInt);
}