【Three.js】动作文件BVH文件格式解析

动捕相关的文件格式有很多,常见的像BVH、FBX等等,今天我们着重和大家分享一下BVH这种文件格式。

一、简介

BVH是BioVision等设备对人体运动进行捕获后产生文件格式的文件扩展名。

BVH文件包含角色的骨骼和肢体关节旋转数据。BVH 是一种通用的人体特征动画文件格式,广泛地被当今流行的各种动画制作软件支持,如3DMax。

 

【Three.js】动作文件BVH文件格式解析

 

二、文件格式

文件主要部分

骨架信息 和 数据块

  • 骨架信息:按照层次关系,定义了如root hip leg等位置和旋转分量,从而形成一个完整的骨架
  • 数据块:对应上面的骨架各部位标出每帧的数据信息

一个BVH文件包含两部分,头部部分和数据部分,头部部分描述了骨架的层次关系和初始姿势,数据部分包含了动作(motion)的数据.

三、文件示例

HIERARCHY
ROOT Hips
{
    OFFSET  0.00    0.00    0.00
    CHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation
    JOINT Chest
    {
        OFFSET   0.00    5.21    0.00
        CHANNELS 3 Zrotation Xrotation Yrotation
        JOINT Neck
        {
            OFFSET   0.00    18.65   0.00
            CHANNELS 3 Zrotation Xrotation Yrotation
            JOINT Head
            {
                OFFSET   0.00    5.45    0.00
                CHANNELS 3 Zrotation Xrotation Yrotation
                End Site 
                {
                    OFFSET   0.00    3.87    0.00
                }
            }
        }
        JOINT LeftCollar
        {
            OFFSET   1.12    16.23   1.87
            CHANNELS 3 Zrotation Xrotation Yrotation
            JOINT LeftUpArm
            {
                OFFSET   5.54    0.00    0.00
                CHANNELS 3 Zrotation Xrotation Yrotation
                JOINT LeftLowArm
                {
                    OFFSET   0.00   -11.96   0.00
                    CHANNELS 3 Zrotation Xrotation Yrotation
                    JOINT LeftHand
                    {
                        OFFSET   0.00   -9.93    0.00
                        CHANNELS 3 Zrotation Xrotation Yrotation
                        End Site 
                        {
                            OFFSET   0.00   -7.00    0.00
                        }
                    }
                }
            }
        }
        JOINT RightCollar
        {
            OFFSET  -1.12    16.23   1.87
            CHANNELS 3 Zrotation Xrotation Yrotation
            JOINT RightUpArm
            {
                OFFSET  -6.07    0.00    0.00
                CHANNELS 3 Zrotation Xrotation Yrotation
                JOINT RightLowArm
                {
                    OFFSET   0.00   -11.82   0.00
                    CHANNELS 3 Zrotation Xrotation Yrotation
                    JOINT RightHand
                    {
                        OFFSET   0.00   -10.65   0.00
                        CHANNELS 3 Zrotation Xrotation Yrotation
                        End Site 
                        {
                            OFFSET   0.00   -7.00    0.00
                        }
                    }
                }
            }
        }
    }
    JOINT LeftUpLeg
    {
        OFFSET   3.91    0.00    0.00
        CHANNELS 3 Zrotation Xrotation Yrotation
        JOINT LeftLowLeg
        {
            OFFSET   0.00   -18.34   0.00
            CHANNELS 3 Zrotation Xrotation Yrotation
            JOINT LeftFoot
            {
                OFFSET   0.00   -17.37   0.00
                CHANNELS 3 Zrotation Xrotation Yrotation
                End Site 
                {
                    OFFSET   0.00   -3.46    0.00
                }
            }
        }
    }
    JOINT RightUpLeg
    {
        OFFSET  -3.91    0.00    0.00
        CHANNELS 3 Zrotation Xrotation Yrotation
        JOINT RightLowLeg
        {
            OFFSET   0.00   -17.63   0.00
            CHANNELS 3 Zrotation Xrotation Yrotation
            JOINT RightFoot
            {
                OFFSET   0.00   -17.14   0.00
                CHANNELS 3 Zrotation Xrotation Yrotation
                End Site 
                {
                    OFFSET   0.00   -3.75    0.00
                }
            }
        }
    }
}
MOTION
Frames:    2
Frame Time: 0.033333
 8.03    35.01   88.36  -3.41    14.78  -164.35  13.09   40.30  -24.60   7.88    43.80   0.00   -3.61   -41.45   5.82    10.08   0.00    10.21   97.95  -23.53  -2.14   -101.86 -80.77  -98.91   0.69    0.03    0.00   -14.04   0.00   -10.50  -85.52  -13.72  -102.93  61.91  -61.18   65.18  -1.57    0.69    0.02    15.00   22.78  -5.92    14.93   49.99   6.60    0.00   -1.14    0.00   -16.58  -10.51  -3.11    15.38   52.66  -21.80   0.00   -23.95   0.00   
 7.81    35.10   86.47  -3.78    12.94  -166.97  12.64   42.57  -22.34   7.67    43.61   0.00   -4.23   -41.41   4.89    19.10   0.00    4.16    93.12  -9.69   -9.43    132.67 -81.86   136.80  0.70    0.37    0.00   -8.62    0.00   -21.82  -87.31  -27.57  -100.09  56.17  -61.56   58.72  -1.63    0.95    0.03    13.16   15.44  -3.56    7.97    59.29   4.97    0.00    1.64    0.00   -17.18  -10.02  -3.08    13.56   53.38  -18.07   0.00   -25.93   0.00

3.1头部部分

  1. HIERARCHY:头部部分开头包含”HIERARCHY“关键词

  2. ROOT:接着一行开头为”ROOT”关键词,后面跟着root的名字.当然,一个root段(segment)之后,允许再定义另一个段,也可以定义为”ROOT”.原理上,BVH文件能够包含任何数量的骨架段;

  3. Hips:我们的根节点通常选择是在髋部,也就是Hip位置,这个位置选的很关键,它是一个人体偏向于重心的位置。为什么将Hip选择作为根节点?相信大家都知道,人体姿态还原是通过IK或者FK算法,由于算法本身存在一定的误差,所以如果我们将ROOT端取在头部或者其他部分的话,当我们运算到另一端的时候,动作就会产生较大的误差(惯性捕捉)。
  4. segment:BVH文件的格式为递归的格式,层次结构的每一个segment包含了一些相关数据,该segment要递归定义它的子segment.

  5. OFFSET:segment的第一个信息是该segment相对于父segment的偏移量(OFFSET), 如果是根ROOT segment则偏移量OFFSET则通常为0,OFFSET指定了X,Y,Z方向上与父segment的偏移量,偏移量也指示用于绘制父segment的长度和方向.

  6. CHANNEL(节点旋转角度的欧拉角):接下来一是”CHANNEL“头部信息,后面跟着的数字表明channels的数目,后面的标签表明每一个channel的类型,默认顺序通常是ZXY;在后面MOTION信息被解析的时候,这个顺序在解析每一行的MOTION数据的时候需要用到.这种格式规定很明显具有灵活性,能够允许segment拥有任何数目的channel,且能够按照任何顺序.通常OFFSET的数据只有在骨架信息里面会呈现出来,毕竟我们人不可能在运动过程中突然骨头变长或者变短。旋转角则是驱动骨架动作的主要数据了(大部分模型的默认姿态都是TPos,也就是人双手平伸,呈一个T形站立),通过这些数据,我们就能完整地还原出人体的一个姿态,通过连续不断的姿态,我们就能还原出人体的运动状态了。

  7. JOINT:接下来能看到”JOINT“和”END SITE“关键词,一个JOINT的定义和ROOT的定义是相同的,除了CHANNEL的数目不同,JOINT正是递归开始的地方,剩下部分对JOINT的解析和ROOT一样的.

  8. END SITE:END SITE结束了递归,它的定义还包含了一些数据,它提供了前segment的长度,就像前面子segment提供了offset用于绘制父segment的长度和方向(由于此时该节点为最后一个节点,例如手指末端,所以不再有旋转数据);

  9. JOINT结尾:JOINT的结尾以右括号结束,BVH中,空间被定义成了右旋坐标系与Y轴作为世界矢量;

  10. 平移量:通常来说,子关节的平移信息存储在OFFSET里面,而旋转信息是Motion部分存储的,跟关节的话,平移量=OFFSET+Motion存储的XYZ。

3.2数据部分

  1. MOTION:数据部分以MOTION开头,Frames: 定义帧数,Frame Time:定义数据采样速率-每帧的时间长度,如0.033333则表示BVH文件的一般采样速率,每秒30帧

  2. 接下来的一长串数字就是实际的运动数据数据块,对应上面定义好的骨架信息层次结构。(数字的个数=(JOINT个数*JOINT自带的CHANNELS个数+ROOT*ROOT自带的CHANNELS个数)*Frames,本例中:(17*3+6)*2=112)

四、关键词

  • HIERARCHY : 开头
  • ROOT : 根关节
  • JOINT : 根关节下的关节
  • OFFSET : 子关节相对父关节的偏移,也可以表示对应父关节的长度和方向,当子关节不止一个时,采用第一个子关节的数据.
  • CHANNELS : 给出了关于channel的个数和名称(ROOT总是拥有6个channels,而一般JOINT只有3个,较之ROOT缺少了XYZ的position信息,因为子关节只需要根据它相对于父关节的偏移就可以算出它在坐标系中的具体位置了)

 参照:https://zhuanlan.zhihu.com/p/71818887

上一篇:ASP.NET Core 3.x 学习笔记(3)——配置信息的使用


下一篇:在后台解析前端传递的json到list中