从头实现一套骨骼动画系统之md5anim文件结构解析

一直想从底层开始写一个简单的游戏引擎,至于多底层,不好界定,目前来看就是自己直接调用用dx11或opengl api那个层面吧,这种想法很久了,但是游戏引擎方面的技术问题太多了,单说一个渲染引擎来说,各种技法,对想自己写着玩的就足够折腾好几年了吧?最近这段有时间,所以静下心来一步一步来吧,打算先把骨骼动画这块整出来,目标是3dsmax模型动画导出到动画模型解析显示都来自己做,这样能比较系统详细的理解游戏中动画方面的所有基础内容,而且方便以后添加一些特效,比如,最近看到只狼游戏中那种精美的画面,主角的剑在挥动的时候会有一些光波粒子特效出来并跟随剑的位置也变化,自己想了想怎么实现,发现这东西必须和动画模块深度融合才行,目前想到就是把动画模块的手和剑的位置读取出来(可以使用transform feedback),根据位置的一些变化来调整特效光波粒子的外形和位置来实现。所以,骨骼动画这块完全自己来实现后期会有很多能自定义的地方!我的骨骼动画系统是基于md5格式存放的,md5格式的好处是格式是开源的,而且网上能搜索到开源的3dsmax导出插件,自己稍微改一下用到自己的3dsmax2014 sdk上,然后自己再写个md5loader集成到自己的引擎中,下面就是记录一下自己在做的过程中对md5anim文件结构的理解。

md5anim文件结构

MD5Version <int:version>
commandline <string:commandline>

numFrames <int:numFrames>
numJoints <int:numJoints>
frameRate <int:frameRate>
numAnimatedComponents <int:numAnimatedComponents>

hierarchy {
<string:jointName> <int:parentIndex> <int:flags> <int:startIndex>
...
}

bounds {
( vec3:boundMin ) ( vec3:boundMax )
...
}

baseframe {
( vec3:position ) ( vec3:orientation )
...
}

frame <int:frameNum> {
<float:frameData> ...
}

其中比较重要的hierarchy组里面的信息,这里面会按层级顺序列出所有的骨骼节点的信息,每个记录包括骨骼的名字,父节点的索引,该骨骼节点的标记,还有该骨骼节点在frame中的动画信息的起始索引。每个记录的顺序就代表了自己的索引,这样引用父节点的索引就是父节点的位置。这个flags的意思这里要说下,可能是md5标准定义的这些标记吧,提供的标记有下面这些:

enum eHierarchyFlag
{
    eHierarchyFlag_None=0,
    eHierarchyFlag_Pos_X=0x00000001,
    eHierarchyFlag_Pos_Y=0x00000002,
    eHierarchyFlag_Pos_Z=0x00000004,
    eHierarchyFlag_Rot_X=0x00000008,
    eHierarchyFlag_Rot_Y=0x00000010,
    eHierarchyFlag_Rot_Z=0x00000020,
};

什么意思呢?就是一些骨骼会在这个动画中都没有发生位置上或旋转上的变动,这很常见,这样就没有必要存储这些没有发生变化的位置或旋转信息,可以节约空间,那么怎么判断哪些些骨骼在动画中没有发生位置或旋转上的变动呢?实现逻辑就是在导出动画时通过比较这根骨头在所有的帧中的位置和旋转信息,如果是一样的或者差距小到某个临界点(可以忽略不计,由于float的精度问题可能不会完全相同),只要有其中任意相邻两帧中出现不一样,那么这个骨头节点就不会出现这个标记,在这个记录中的这个flags的值会影响后面每一个frame里面的位置和旋转信息的结构,同时也引出了后一个字段的意义,这个骨头在frame里面的信息的start index,因为在frame里面不是每一个bone都包含相同的信息,有的可能没有位置pos_x的信息,所以需要在这里指定描述本骨头的位置和旋转信息在这个frame里的位置,这个startindex的值是和flags相关的。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值