VMDファイルの中身

VMDは「ヘッダ + モデル名 + 6つのブロック」という素直な形式です。自前のパーサを書いて実物31本で読み書きを往復させたときに分かったことをまとめます。

最終更新: 2026-09-01 · kphpリポジトリ同梱の実VMD 31本で「読み→書き→読み」が一致することを確認

全体の構造

先頭からこの順に並びます。数値はすべてリトルエンディアン、文字列はShift_JISです。古いVMDでは後ろのブロックが存在しないことがあるので、読めるところまで読んで打ち切る作りにしないと落ちます。

位置内容1件あたり
0〜29ヘッダ(Vocaloid Motion Data 0002 + 埋め)30バイト
30〜49モデル名(Shift_JIS)20バイト
以降モーション数(uint32)+ 本体111バイト
表情数 + 本体23バイト
カメラ数 + 本体61バイト
照明数 + 本体28バイト
セルフ影数 + 本体9バイト
IK/表示数 + 本体可変(9 + 21×IK数)

ボーンのキーフレーム(111バイト)

  • ボーン名 15バイト(Shift_JISの固定長。足りない分は0埋め)
  • フレーム番号 4バイト(uint32)。MMDは30fps固定なので、番号÷30が秒
  • 位置 12バイト(float32 × 3)。初期姿勢からの差分であって絶対座標ではない
  • 回転 16バイト(クォータニオン float32 × 4)
  • 補間曲線 64バイト

ボーン名が15バイトを超えると入りません。 Shift_JISの日本語は1文字2バイトなので、日本語だけなら7文字までです。書き出す側は必ず往復できるかを確かめてください。

補間はどこに効くのか

VMDの補間は「同じボーンのキーフレームどうし」の間でしか働きません。 30フレーム目でだけ腕を上げたつもりでも、そのボーンに他のキーフレームが無ければ、0フレーム目から最後まで上がったままになります。

手でモーションを作るときは、動かしていないところにも「元の姿勢」を明示的に置く必要があります。このサイトのモーション作成機能は、登録した全キーフレームのボーン名の和集合を取り、書かれていないところへ初期姿勢を書き込んでいます。

種類(モーション・表情・カメラ・照明)の見分け方

VMDのファイル自体に「これはカメラです」という印はありません。どのブロックに何件入っているかで判断します。 このサイトは次の順で判定しています(現行のmmdbox.netと同じ閾値)。

判定条件
モーションボーンのキーフレームが10件を超える
表情表情が10件を超え、ボーンが10件以下
カメラカメラが10件を超え、ボーンが10件以下
照明照明が1件以上あり、ボーンとカメラが10件以下
不明上のどれにも当てはまらない

照明だけ閾値が0なのは、光の色を数フレームだけ変えるファイルが実際に多いためです。10件を境にすると、そういうファイルが「不明」に落ちます。

書き出すときに気をつけること

  • レコードは生バイト列のまま持ち回るほうが安全。 補間曲線64バイトのような触る必要のないデータを構造体へ展開して書き戻すと、往復で取りこぼしが起きます。トリミングや結合で必要なのは「どのレコードを残すか」と「フレーム番号を書き換えること」だけです。
  • 2つのVMDを繋ぐときは、後ろのVMDをずらしてから連結する。 どちらも0フレーム目から始まるので、そのまま結合すると同じ(ボーン, フレーム)が重複して壊れます。
  • 速度を上げると、丸めで同じ(ボーン, フレーム)が重なる。 落とした件数は利用者に見せるべきです(黙って捨てると、なぜ短くなったのか分かりません)。