zerO

纪念我所怀念的一切.

« achemy3d地形 »
2009-9-23 11:50:53 | 发布:linfuqing | 分类:achemy3d | 评论:0 | 引用:0 | 浏览:

MD2及动画技术

Blog好久没有更新了,Alchemy3D的MD2导入已经完美完成,给大家介绍下相关技术。

———————————————————————————————————————

MD2模型文件格式是在id software 于1997年11月发布Quake 2时推广出来的。

相对其他格式来说,这算是老技术了,但是比较有用的是它支持纹理,网格以及动画系统。使用它可以很自由设置帧动画,多更衣纹理。

目前alchemy3d已经完美地支持MD2格式的导入,当然这句话是废话。

 好吧,请看大屏幕:

下面说说MD2的动画。

MD2的动画是渐变动画,所谓渐变动画,就是每个关键帧记录当前顶点位置信息,然后每一次调用帧按照时间对其进行缓冲,让他们看起来是连续的,这就成了动画的效果。

这样说可能会觉得很抽象,下面来看看GL的调用方式:

void
RenderFrame (
int n, const struct md2_model_t *mdl)
{
  
int i, j;
  GLfloat s, t;
  vec3_t v;
  
struct md2_frame_t *pframe;
  
struct md2_vertex_t *pvert;
  
/* Check if n is in a valid range */
  
if ((n < 0|| (n > mdl->header.num_frames - 1))
    
return;
  
/* Enable model's texture */
  glBindTexture (GL_TEXTURE_2D, mdl
->tex_id);
  
/* Draw the model */
  glBegin (GL_TRIANGLES);
    
/* Draw each triangle */
    
for (i = 0; i < mdl->header.num_tris; ++i)
      {
    
/* Draw each vertex */
    
for (j = 0; j < 3++j)
      {
        pframe 
= &mdl->frames[n];
        pvert 
= &pframe->verts[mdl->triangles[i].vertex[j]];
        
/* Compute texture coordinates */
        s 
= (GLfloat)mdl->texcoords[mdl->triangles[i].st[j]].s / mdl->header.skinwidth;
        t 
= (GLfloat)mdl->texcoords[mdl->triangles[i].st[j]].t / mdl->header.skinheight;
        
/* Pass texture coordinates to OpenGL */
        glTexCoord2f (s, t);
        
/* Normal vector */
        glNormal3fv (anorms_table[pvert
->normalIndex]);
        
/* Calculate vertex real position */
        v[
0= (pframe->scale[0* pvert->v[0]) + pframe->translate[0];
        v[
1= (pframe->scale[1* pvert->v[1]) + pframe->translate[1];
        v[
2= (pframe->scale[2* pvert->v[2]) + pframe->translate[2];
        glVertex3fv (v);
      }
      }
  glEnd ();
}

下面是渐变处理:

struct md2_frame_t *pframe1, *pframe2;
struct md2_vertex_t *pvert1, *pvert2;
vec3_t v_curr, v_next, v;
for (/*  */)
  {
    pframe1 
= &mdl->frames[current];
    pframe2 
= &mdl->frames[current + 1];
    pvert1 
= &pframe1->verts[mdl->triangles[i].vertex[j]];
    pvert2 
= &pframe2->verts[mdl->triangles[i].vertex[j]];
    
/*  */
    v_curr[
0= (pframe1->scale[0* pvert1->v[0]) + pframe1->translate[0];
    v_curr[
1= (pframe1->scale[1* pvert1->v[1]) + pframe1->translate[1];
    v_curr[
2= (pframe1->scale[2* pvert1->v[2]) + pframe1->translate[2];
    v_next[
0= (pframe2->scale[0* pvert2->v[0]) + pframe2->translate[0];
    v_next[
1= (pframe2->scale[1* pvert2->v[1]) + pframe2->translate[1];
    v_next[
2= (pframe2->scale[2* pvert2->v[2]) + pframe2->translate[2];
    v[
0= v_curr[0+ interp * (v_next[0- v_curr[0]);
    v[
1= v_curr[1+ interp * (v_next[1- v_curr[1]);
    v[
2= v_curr[2+ interp * (v_next[2- v_curr[2]);
    
/*  */
  }

好的,我假设你已经了解MD2动画是如何运转的,让我们回到Alchemy3D的Demo上,如果你足够细心,可能已经发现了某些问题,比如它前后的动作似乎是不关联的。

这是怎么回事呢,其实MD2的动画并不是单一的,具体的说每个模型的动画都是由帧动画的集合组成。每个帧动画都可以是独立存在的,它包含了自己的帧长度。要想获取单个帧动画,我们必须把它们从MD2的动画堆里提取出来。

对计算机图形学动画有些了解的朋友也许会知道,每个关键帧都会包含自己的帧名字,MD2的关键帧名字格式是这样的:

[帧动画名][帧动画第n帧]

现在我们所要做的就是把帧动画名提取出来,与你想要的动画匹配,像这样:

( ch = strstr( animation -> frames[i].name, name ) ) == animation -> frames[i].name

//然后检查后面是否全部是数字

ch += strlen( name );

   match = TRUE;
   
   while( * ch != '\0' )
   {
    if( !isdigit( ( int )( * ch ++ ) ) )
    {
     match = FALSE;
     break;
    }
   }

  • 相关文章:

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最近发表

最新评论及回复

友情链接

[Top] Powered By Z-Blog 1.8 Arwen Build 81206. Theme FormerDays Design By haphic

[-Do U rmAmb al _LEAVEs_ Missing UnderTheTree-]
All by 怀念从前.