概要

BVH(Biovision Hierarchy)は、BioVision社が提唱したモーションキャプチャデータファイルフォーマット。


フォーマット

以下の特徴を持つ。

  • テキストベース
  • 半角スペース、タブ文字、改行文字を区切り文字とする。連続する区切り文字は1つの区切りと見做される。
  • 右手座標系
  • XYZ軸のいずれがヨー・ピッチ・ロールとするかは任意
  • モデルの骨格を階層構造で記述するHierarchy部と、動作データを記述するMotion部で構成される
  • Motion部は1行=1フレームに該当し、Hierarchy部の定義順に各関節の情報を記述する
  • モーションは関節をノードとして、その回転角度によって記述する
  • 回転角度はオイラー角、単位は度で記述する

セカンドライフで使用する場合には次の制約がある
  • 1ファイルにつき、最大で900フレームまで。
  • 最初のフレームは再生されない。第2フレームから再生される。
  • 軸方向は次の通り。
    • X軸: アバター固有空間の水平左右方向。+がアバター左手方向。
    • Y軸: アバター固有空間の鉛直方向。+が上。
    • Z軸: アバター固有空間の水平前後方向。+がアバター前方。

Hierarchy部


以下に単純な構成の例を示す。
HIERARCHY
ROOT hip
{
    OFFSET 0.000000 0.000000 0.000000
    CHANNELS 6 Xposition Yposition Zposition Yrotation Xrotation Zrotation
    JOINT abdomen
    {
        OFFSET 0.000000 3.422050 0.000000
        CHANNELS 3 Yrotation Xrotation Zrotation
        End Site
        {
            OFFSET 0.000000 3.148289 0.000000
        }
    }
}

HIERARYCH

Hierarchy部は『HIERARYCH』の記述により始まる。

ジョイント

モデルの骨格のつなぎ目。
ジョイントにはROOT、JOINT, ENDの3種類が存在する。
各ジョイントの定義は{で始まり、}で終わる。

JOINT

モデルの関節に該当する。
JOINTは必ず、OFFSET、CHANNELS(回転のみ=3チャンネル)、子ノード(JOINTまたはEND)を持たなければならない。
『JOINT』に続く文字列は該当する関節の名称で、任意の文字列を指定できる。
セカンドライフで使用する場合は、それぞれ該当する関節の名称を指定する。

ROOT

モデルの原点となるノードを定義する。すなわち、骨格階層構造の視点となる関節を表す特殊なジョイント。
ROOTは必ず、OFFSET、CHANNELS(位置と回転=6チャンネル)、子ノード(JOINTまたはEND)を持たなければならない。
『ROOT』に続く文字列はRootノードの名称で、任意の文字列を指定できる。
セカンドライフで使用する場合は『hip』となる。

End

骨格階層構造の終端となるノードを定義する特殊なジョイント。
Endは必ず、OFFSETのみを持たなければならない。
『End』に続く文字列はEndノードの名称で、任意の文字列を指定できる。
セカンドライフで使用する場合は『Site』となる。

OFFSET

骨格階層構造における親ノードから見たJOINTの相対座標。
ROOTノードの場合、ワールド座標における初期位置を表す。
X-Y-Zの順に記述する。
セカンドライフで使用する場合、ワールド座標とはアバターがいる位置を原点とし、アバターの鉛直情報をY+、正面前方をZ+としたアバター固有の座標空間となる。

CHANNELS

ROOTまたはJOINTごとの動きを表す位置情報、回転情報の順序を定義する。
位置情報は『Xposition』, 『Yposition』, 『Zposition』のリテラルにて指定する。
回転情報は『Xrotation』, 『Yrotation』, 『Zrotation』のリテラルにて指定する。(回転順序である。計算はこの逆順で行われる。)

セカンドライフ用サンプル

以下にセカンドライフ用BVHのHIERARCHY部のサンプルを示す。
HIERARCHY
ROOT hip
{
    OFFSET 0.000000 0.000000 0.000000
    CHANNELS 6 Xposition Yposition Zposition Yrotation Xrotation Zrotation
    JOINT abdomen
    {
        OFFSET 0.000000 3.422050 0.000000
        CHANNELS 3 Yrotation Xrotation Zrotation
        JOINT chest
        {
            OFFSET 0.000000 8.486693 -0.684411
            CHANNELS 3 Yrotation Xrotation Zrotation
            JOINT neck
            {
                OFFSET 0.000000 10.266162 -0.273764
                CHANNELS 3 Yrotation Xrotation Zrotation
                JOINT head
                {
                    OFFSET 0.000000 3.148285 0.000000
                    CHANNELS 3 Yrotation Xrotation Zrotation
                    End Site
                    {
                        OFFSET 0.000000 3.148289 0.000000
                    }
                }
            }
            JOINT lCollar
            {
                OFFSET 3.422053 6.707223 -0.821293
                CHANNELS 3 Yrotation Xrotation Zrotation
                JOINT lShldr
                {
                    OFFSET 3.285171 0.000000 0.000000
                    CHANNELS 3 Yrotation Xrotation Zrotation
                    JOINT lForeArm
                    {
                        OFFSET 10.129278 0.000000 0.000000
                        CHANNELS 3 Yrotation Xrotation Zrotation
                        JOINT lHand
                        {
                            OFFSET 8.486692 0.000000 0.000000
                            CHANNELS 3 Yrotation Xrotation Zrotation
                            End Site
                            {
                                OFFSET 4.106464 0.000000 0.000000
                            }
                        }
                    }
                }
            }
            JOINT rCollar
            {
                OFFSET -3.558935 6.707223 -0.821293
                CHANNELS 3 Yrotation Xrotation Zrotation
                JOINT rShldr
                {
                    OFFSET -3.148289 0.000000 0.000000
                    CHANNELS 3 Yrotation Xrotation Zrotation
                    JOINT rForeArm
                    {
                        OFFSET -10.266159 0.000000 0.000000
                        CHANNELS 3 Yrotation Xrotation Zrotation
                        JOINT rHand
                        {
                            OFFSET -8.349810 0.000000 0.000000
                            CHANNELS 3 Yrotation Xrotation Zrotation
                            End Site
                            {
                                OFFSET -4.106464 0.000000 0.000000
                            }
                        }
                    }
                }
            }
        }
    }
    JOINT lThigh
    {
        OFFSET 5.338403 -1.642589 1.368821
        CHANNELS 3 Yrotation Xrotation Zrotation
        JOINT lShin
        {
            OFFSET -2.053232 -20.121670 0.000000
            CHANNELS 3 Yrotation Xrotation Zrotation
            JOINT lFoot
            {
                OFFSET 0.000000 -19.300380 -1.231939
                CHANNELS 3 Yrotation Xrotation Zrotation
                End Site
                {
                    OFFSET 0.000000 -2.463878 4.653993
                }
            }
        }
    }
    JOINT rThigh
    {
        OFFSET -5.338403 -1.642589 1.368821
        CHANNELS 3 Yrotation Xrotation Zrotation
        JOINT rShin
        {
            OFFSET 2.053232 -20.121670 0.000000
            CHANNELS 3 Yrotation Xrotation Zrotation
            JOINT rFoot
            {
                OFFSET 0.000000 -19.300380 -1.231939
                CHANNELS 3 Yrotation Xrotation Zrotation
                End Site
                {
                    OFFSET 0.000000 -2.463878 4.653993
                }
            }
        }
    }
}
セカンドライフのアバターは骨格が決まっているので、骨格の階層順序、OFFSETはこのまま使用できる。
CHANNELSについては、Motion部との整合性が保たれていれば、順序を変更しても構わない。


Motion部


以下に単純な構成の例を示す。
MOTION
Frames:    900
Frame Time:    0.033333
0.000000 43.528519 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
3.500000 42.728520 0.000000 89.999980 0.000000 0.000000 0.000000 25.783100 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 -79.097240 -0.067489 105.093300 0.000002 0.000003 -14.896900 0.000007 0.000009 -40.107050 0.000000 0.000000 0.000000 -19.480560 0.000000 0.000000 40.280560 -37.338410 93.477790 38.390440 1.385436 32.482440 -0.222002 -23.058080 0.127754 0.000000 0.114592 0.000000 0.163977 4.135550 0.006704 0.222979 -23.143930 -0.128379 0.000000 0.114592 0.000000 -0.165372 4.239233 -0.005431


MOTION

Motion部は『MOTION』の記述により始まる。

Frames:

ファイルに含まれるフレームの総数を宣言する。

Frame Time:

1フレーム当たりの再生所要時間(秒)、すなわちFPSの逆数を宣言する。
セカンドライフで使用する場合、任意の値を指定可能。但し、MMDからモーションを変換するのであればMMDは30.0FPSであるので、 1/30 = 0.033333 とした方が効率も良いし、モーションの劣化も最少に抑えられる。

フレームデータ

以下、フレームデータを記述してゆく。
値は空白文字で区切る。(例では1フレーム毎に改行しているが、改行でなくとも空白文字で区切られていればよいし、1フレームの途中で改行してもよい。)
先頭フレームから順次記述してゆく。
フレーム内の各フィールドは、Hierarchy部で登場するジョイント順、かつそのCHANNELS順に従い記述する。
最終更新:2013年07月29日 11:19