BVH动捕文件导入到E3D骨骼树
1. BVH动捕文件
BVH动作捕捉文件有两部分组成,第一部分描述了静止状态下角色的基本骨骼结构,角色通常处于Apose或Tpose姿态下.文本用树状结构描述了各个关节点的相对位置(OFFSET xyz),连接两关节点的边即是一块骨头(bone).根节点通常选在髋部的中心位置处,向下左右分别长出两下肢,向上长出脊椎/胸椎/脖子/头部,在胸椎处左右分别长出两上肢. BVH文件的第二部分是每一帧动作的关节旋转数据,每个关节一般有Zrotation/Xrotaion/Yrotation三个数据,分别对应顺序旋转的三个欧拉角, 在第一部分描述的静止状态的基础上,再加上这些旋转变换就可以还原角色此时的姿态.另外,根节点相比其他节点还会多出Xposition/Yposition/Zposition三个数据,这样可以让角色进行位置的移动,比如整体的前进,后退,跳跃等. 需要注意的是:作为生物的骨骼,一个关节只能连接一块骨头,即有公共节点的多块骨头应该作为一个整体考虑,他们共用一组旋转数据.比如连接根节点的三个bone和连接胸椎节点的三个bone.
2. E3D骨骼矩阵树
E3D骨骼矩阵树(E3D_BMatrixTree)包含了一个角色的所有骨头(E3DS_BMTreeNode骨骼节点),并将他们以简单的数状结构链接在一起,每一块骨头(E3DS_BMTreeNode)包含了以下数据:
float blen; 骨头的长度
E3D_Vector bv; 骨头的方向矢量(静止状态下)
E3D_RTMatrix pmat; 骨头的静态矩阵(静止状态下,相对其父节点)
E3D_RTMatrix amat; 骨头的动态矩阵(动态状态下,相对于静止状态)
E3D_RTMatrix gmat; 骨头的世界矩阵(相对于世界坐标系,gmat=amat*pmat*(parent->gmat))
E3D_AnimQuatrices animQts; 骨头的动画帧数据,记录了N组包含时间的四元数Qts矩阵.
可以通过对animQts插值得到某一时刻t下的amat, 然后更新gmat=amat*pmat*(parent->gmat), 最后通过gmat就可以将这个骨头在对应三维位置处渲染出来.
3. 由BVH动捕文件生成E3D骨骼树
E3D骨骼树以每一块骨头作为树的节点,而BVH动捕文件以骨关节作为树的节点,两者有一定的区别,在转换的时候需要通过前后的关节数据来生成一个骨骼节点.弄清了拓扑结构后,就可以将每一帧数据中所有关节的顺序旋转角转换成四元数,最后把结果和时间量t一起保存到对应骨头(E3DS_BMTreeNode)的animQts数组中.
另外,E3D和BVH都是右手坐标系,尽管相对单元骨骼来说其XYZ方向会不同,但是由于所有旋转矩阵都是相对的,因此不会影响最后转换结果.
更多https://github.com/widora/wegi/blob/master/cpptest/e3d_animate.h +e3d_animate.cpp