|
|
发表于 2006-11-21 16:09:00
|
显示全部楼层
Re:再论纯关键帧动画
我的构架是这样的,有一个物体对象,然后物体对象里面有ID3DXMesh的网格。
这个网格是每次根据当前物体的帧数而决定的。每次都要重新生成这个网格。这在NextFrame中执行。然后在Rander里面依次画每个物体。这是建立网格的函数。画网格就只是一句char_mesh->DrawSubset(0)就行了。
void AlphaObject::BuildAnimMesh(LPDEVICE device)
{
// 清除旧的网格
SAFE_RELEASE(char_mesh);
SAFE_RELEASE(weapon_mesh);
// 获取动画信息
AlphaAnimFrame & anim = origin->anims[action];
AlphaAnimFrame & anim_next = origin->anims[next_action];
// 确定开始帧和结束帧
// 进行顶点插值计算
float factor = frame - (int)frame;
// 获取两个帧的位置
int curr_frame = frame;
int next_frame = curr_frame + 1;
// 判断下一个顶点是不是超出边界了(用于处理循环动画)
if (next_frame >= anim.start + anim.count)
{
next_frame = anim_next.start;
}
// 获取两个帧的顶点
const PtrVector3D char_curr = origin->vlist + origin->num_verts * curr_frame;
const PtrVector3D char_next = origin->vlist + origin->num_verts * next_frame;
const PtrTextCoord char_text = origin->tlist;
const PtrVector3D weapon_curr = weapon->vlist + weapon->num_verts * curr_frame;
const PtrVector3D weapon_next = weapon->vlist + weapon->num_verts * next_frame;
const PtrTextCoord weapon_text = weapon->tlist;
// 顶点缓冲
PtrVertex char_vlist = new Vertex[origin->num_index];
PtrVertex weapon_vlist = new Vertex[weapon->num_index];
// 确定不需要插值计算的情况
if (factor < 0.01f)
{
for (int p = 0, v = 0; p < origin->num_polys; ++p, v += 3)
{
char_vlist[v + 0].x = char_curr[origin->plist[p].vindex[0]].x;
char_vlist[v + 0].y = char_curr[origin->plist[p].vindex[0]].y;
char_vlist[v + 0].z = char_curr[origin->plist[p].vindex[0]].z;
char_vlist[v + 0].u = char_text[origin->plist[p].tindex[0]].u;
char_vlist[v + 0].v = char_text[origin->plist[p].tindex[0]].v;
char_vlist[v + 1].x = char_curr[origin->plist[p].vindex[1]].x;
char_vlist[v + 1].y = char_curr[origin->plist[p].vindex[1]].y;
char_vlist[v + 1].z = char_curr[origin->plist[p].vindex[1]].z;
char_vlist[v + 1].u = char_text[origin->plist[p].tindex[1]].u;
char_vlist[v + 1].v = char_text[origin->plist[p].tindex[1]].v;
char_vlist[v + 2].x = char_curr[origin->plist[p].vindex[2]].x;
char_vlist[v + 2].y = char_curr[origin->plist[p].vindex[2]].y;
char_vlist[v + 2].z = char_curr[origin->plist[p].vindex[2]].z;
char_vlist[v + 2].u = char_text[origin->plist[p].tindex[2]].u;
char_vlist[v + 2].v = char_text[origin->plist[p].tindex[2]].v;
}
for (int p = 0, v = 0; p < weapon->num_polys; ++p, v += 3)
{
weapon_vlist[v + 0].x = weapon_curr[weapon->plist[p].vindex[0]].x;
weapon_vlist[v + 0].y = weapon_curr[weapon->plist[p].vindex[0]].y;
weapon_vlist[v + 0].z = weapon_curr[weapon->plist[p].vindex[0]].z;
weapon_vlist[v + 0].u = weapon_text[weapon->plist[p].tindex[0]].u;
weapon_vlist[v + 0].v = weapon_text[weapon->plist[p].tindex[0]].v;
weapon_vlist[v + 1].x = weapon_curr[weapon->plist[p].vindex[1]].x;
weapon_vlist[v + 1].y = weapon_curr[weapon->plist[p].vindex[1]].y;
weapon_vlist[v + 1].z = weapon_curr[weapon->plist[p].vindex[1]].z;
weapon_vlist[v + 1].u = weapon_text[weapon->plist[p].tindex[1]].u;
weapon_vlist[v + 1].v = weapon_text[weapon->plist[p].tindex[1]].v;
weapon_vlist[v + 2].x = weapon_curr[weapon->plist[p].vindex[2]].x;
weapon_vlist[v + 2].y = weapon_curr[weapon->plist[p].vindex[2]].y;
weapon_vlist[v + 2].z = weapon_curr[weapon->plist[p].vindex[2]].z;
weapon_vlist[v + 2].u = weapon_text[weapon->plist[p].tindex[2]].u;
weapon_vlist[v + 2].v = weapon_text[weapon->plist[p].tindex[2]].v;
}
// 根据顶点列表来创建网格
CreateMesh(device, char_mesh, char_vlist, origin->num_index, origin->ilist, origin->num_index);
CreateMesh(device, weapon_mesh, weapon_vlist, weapon->num_index, weapon->ilist, weapon->num_index);
}
else // 需要进行差值计算
{
for (int p = 0, v = 0; p < origin->num_polys; ++p, v += 3)
{
const Vector3D & va0 = char_curr[origin->plist[p].vindex[0]];
const Vector3D & va1 = char_curr[origin->plist[p].vindex[1]];
const Vector3D & va2 = char_curr[origin->plist[p].vindex[2]];
const Vector3D & vb0 = char_next[origin->plist[p].vindex[0]];
const Vector3D & vb1 = char_next[origin->plist[p].vindex[1]];
const Vector3D & vb2 = char_next[origin->plist[p].vindex[2]];
char_vlist[v + 0].x = (va0.x + (vb0.x - va0.x) * factor);
char_vlist[v + 0].y = (va0.y + (vb0.y - va0.y) * factor);
char_vlist[v + 0].z = (va0.z + (vb0.z - va0.z) * factor);
char_vlist[v + 0].u = char_text[origin->plist[p].tindex[0]].u;
char_vlist[v + 0].v = char_text[origin->plist[p].tindex[0]].v;
char_vlist[v + 1].x = (va1.x + (vb1.x - va1.x) * factor);
char_vlist[v + 1].y = (va1.y + (vb1.y - va1.y) * factor);
char_vlist[v + 1].z = (va1.z + (vb1.z - va1.z) * factor);
char_vlist[v + 1].u = char_text[origin->plist[p].tindex[1]].u;
char_vlist[v + 1].v = char_text[origin->plist[p].tindex[1]].v;
char_vlist[v + 2].x = (va2.x + (vb2.x - va2.x) * factor);
char_vlist[v + 2].y = (va2.y + (vb2.y - va2.y) * factor);
char_vlist[v + 2].z = (va2.z + (vb2.z - va2.z) * factor);
char_vlist[v + 2].u = char_text[origin->plist[p].tindex[2]].u;
char_vlist[v + 2].v = char_text[origin->plist[p].tindex[2]].v;
}
for (int p = 0, v = 0; p < weapon->num_polys; ++p, v += 3)
{
Vector3D & va0 = weapon_curr[weapon->plist[p].vindex[0]];
Vector3D & va1 = weapon_curr[weapon->plist[p].vindex[1]];
Vector3D & va2 = weapon_curr[weapon->plist[p].vindex[2]];
Vector3D & vb0 = weapon_next[weapon->plist[p].vindex[0]];
Vector3D & vb1 = weapon_next[weapon->plist[p].vindex[1]];
Vector3D & vb2 = weapon_next[weapon->plist[p].vindex[2]];
weapon_vlist[v + 0].x = va0.x + (vb0.x - va0.x) * factor;
weapon_vlist[v + 0].y = va0.y + (vb0.y - va0.y) * factor;
weapon_vlist[v + 0].z = va0.z + (vb0.z - va0.z) * factor;
weapon_vlist[v + 0].u = weapon_text[weapon->plist[p].tindex[0]].u;
weapon_vlist[v + 0].v = weapon_text[weapon->plist[p].tindex[0]].v;
weapon_vlist[v + 1].x = va1.x + (vb1.x - va1.x) * factor;
weapon_vlist[v + 1].y = va1.y + (vb1.y - va1.y) * factor;
weapon_vlist[v + 1].z = va1.z + (vb1.z - va1.z) * factor;
weapon_vlist[v + 1].u = weapon_text[weapon->plist[p].tindex[1]].u;
weapon_vlist[v + 1].v = weapon_text[weapon->plist[p].tindex[1]].v;
weapon_vlist[v + 2].x = va2.x + (vb2.x - va2.x) * factor;
weapon_vlist[v + 2].y = va2.y + (vb2.y - va2.y) * factor;
weapon_vlist[v + 2].z = va2.z + (vb2.z - va2.z) * factor;
weapon_vlist[v + 2].u = weapon_text[weapon->plist[p].tindex[2]].u;
weapon_vlist[v + 2].v = weapon_text[weapon->plist[p].tindex[2]].v;
}
// 根据插值后的顶点列表来创建网格
CreateMesh(device, char_mesh, char_vlist, origin->num_index, origin->ilist, origin->num_index);
CreateMesh(device, weapon_mesh, weapon_vlist, weapon->num_index, weapon->ilist, weapon->num_index);
}
// 善后工作
delete [] char_vlist;
delete [] weapon_vlist;
// 大功告成
return ;
} |
|