网页功能: 加入收藏 设为首页 网站搜索  
骨骼动画(Skeletal Animation)(二)
发表日期:2007-03-22作者:[转贴] 出处:  

现在我们知道为了播放骨骼动画,需要有骨骼(bone)的数据,模型(mesh)的数据,关联骨骼和模型上每个顶点的关联数据,以及关键帧的坐标变换数据。所有这些数据必须以某种形式存在于某个地方供我们获取才行。这里要介绍的MS的x文件格式以及从中获取数据的方法。强烈建议大家都来学习一下x文件格式!你会发现它即简单又强大,即使用来存放自定义数据也是相当的方便,一旦掌握之后我保证你会对它爱不释手。

典型的x文件以数据模板和实际数据两部分组成。数据模板类似c++中的结构定义,不过更为灵活和开放。实际数据就是遵守模板定义的数据段。看一个例子,

template Employee {
  <3D82AB43-62DA-11cf-AB39-0020AF71E433>  // 每个模板关联唯一的GUID  
  STRING Name;                                               // 姓名
  DWORD  Sex;                                                // 性别 
  [ContactEntry]                                              // 联系方式, 另一个模板,模板可以嵌套
}

template ContactEntry {
  <4C9D055B-C64D-4bfe-A7D9-981F507E45FF>  // GUID
  STRING PhoneNumber;                                  // 电话号码
  STRING Address;                                           // 地址
}

Employee David{
  "David";
  1;
  ContactEntry{
    "100-100000000";
    "far far away";
  }
}

从上面这个简单的例子我们就可以看出x文件的大概模样了,详细的情况大家可以参考《Advanced Animation with DirectX》。下面我们看如何来读取这样一个x文件,借助下几个对象,

ID3DXFile                  -- x文件格式文档对象。例如Employee.x这样一个文件。
ID3DXFileEnumObject -- 用来枚举x文档的顶级模板数据。所谓顶级模板数据是指那些没有  
                                 父模板的数据,例如上面的David数据段。
ID3DXFILEDATA        -- 模板数据。上面的David和他的联系方式都是ID3DXFILEDATA
                                 对象,自包含。

下面看实际的分析函数, 下面的代码适用于DirectX 9.0 SDK Update (October 2004),原书的代码有点过时了...

//-----------------------------------------------------------------------------
// 名称 : Parse
// 描述 : 分析x文件格式文档
//-----------------------------------------------------------------------------
bool Parse( char *filename, void **pData )
{
  LPD3DXFILE        lpD3DXFile;
  LPD3DXFILEENUMOBJECT  lpD3DXFileEnumObj;
  LPD3DXFILEDATA             lpD3DXFileData;

  // 参数检查
  if( NULL == filename )
    return false;

  // 创建X文件对象
  HRESULT hr = D3DXFileCreate( &lpD3DXFile );
  if( FAILED( hr ) )
    return false;

  // 注册标准模板
  hr = lpD3DXFile->RegisterTemplates( 
            ( LPVOID )D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES );
  if( FAILED( hr ) )
  {
    Release<LPD3DXFILE>( lpD3DXFile );
    return false;
  }

  // 创建X文件枚举对象
  hr = lpD3DXFile->CreateEnumObject( 
           filename, D3DXF_FILELOAD_FROMFILE, &lpD3DXFileEnumObj );
  if( FAILED( hr ) )
  {
     Release<LPD3DXFILE>( lpD3DXFile );
     return false;
  }

  // 解析开始
  bool parseResult = BeginParse( pData );
  if( true == parseResult )
  {
     // 查询顶级模板数
     SIZE_T childCount = 0;
     lpD3DXFileEnumObj->GetChildren( &childCount );

     // 分析每个订级模板
     for( DWORD i=0; i<childCount; i++ )
     {
       // 获取当前模板
       hr = lpD3DXFileEnumObj->GetChild( i, &lpD3DXFileData );
       if( FAILED( hr ) )
         break;

       // 分析
       parseResult = ParseObject( lpD3DXFileData, NULL, 0, pData );

       // 释放FileData对象
       Release<LPD3DXFILEDATA>( lpD3DXFileData );

       // 出现错误,中断分析
       if( false == parseResult )
         break;
      }

      // 解析结束
      if( parseResult ) 
        parseResult = EndParse( pData );
  }

  // 释放相关对象
  Release<LPD3DXFILEENUMOBJECT>( lpD3DXFileEnumObj );
  Release<LPD3DXFILE>( lpD3DXFile );

  // 解析结束
  return parseResult;
}

//-----------------------------------------------------------------------------
// 名称 : ParseObject
// 描述 : 递归解析顶级模板
//-----------------------------------------------------------------------------
bool ParseObject( 
LPD3DXFILEDATA pDataObj,
LPD3DXFILEDATA pParentDataObj,
DWORD depth,
void **pData )
{
  LPD3DXFILEDATA pSubDataObj;
  bool parseResult = true;
  HRESULT hr;

  // 获取子模板数目
  DWORD childCount;
  pDataObj->GetChildren( &childCount );

  // 遍历模板并分析
  for( DWORD i=0; i<childCount; i++ )
  {
     // 取子模板对象
     hr = pDataObj->GetChild( i, &pSubDataObj );
     if( FAILED( hr ) )
       break;

     // 分析子模板
     parseResult = ParseObject( pSubDataObj, pDataObj, depth+1, pData );

     // 释放数据对象
     Release<LPD3DXFILEDATA>( pSubDataObj );

     // 出现错误,停止分析
     if( false == parseResult )
       break;
  }

  return parseResult;
}

就那么简单,相信大家都看得明白。通过重载ParseObject方法,我们以判断当前分析的模板类型,然后创建实际的模板对象,从文档中复制数据。有了上面的工具,我们就可以自己来读取和解析x格式的骨骼动画文件了。

我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 骨骼动画(Skeletal Animation)(二)
本类热点文章
  DDraw和D3D立即模式编程手册
  矩阵求逆的快速算法
  本地化支持:OGRE+CEGUI中文输入:OGRE方..
  Direct3D中实现图元的鼠标拾取
  3D场景中的圆形天空顶
  OpenGL显卡编程
  一种高效的基于大规模地形场景的OCCLUS..
  一个完善的读取3DS文件例子
  如何制作一个可控制的人体骨骼模型
  Direct3D 入门之我见
  Slope(斜坡) 法线生成算法,在地形渲染..
  新手翻译的FAQ--可视和转换(学opengl两..
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00544