キーフレームを手で置いてモーションを作るときの注意
モーションを手付けするのは「ポーズを作る → フレーム番号を決める → 登録する」の繰り返しです。仕組みは単純ですが、VMDの補間の効き方を知らないと「動かしていない時間」を表現できず、物理の扱いを間違えると保存したモーションが揺れものと綱引きします。
フレーム番号と秒は必ず並べて出す
VMDの時間の単位はフレーム番号で、30fps固定です。ファイルの中にfpsは書かれていません。番号 ÷ 30 が秒になります。作業中は番号だけを見ていると長さの感覚が掴めないので、画面には両方出すのが親切です(90フレーム = 3.0秒)。
補間は「同じボーンのキーフレームどうし」の間だけ効く
ここが手付けでいちばん引っかかる点です。 30フレーム目で腕を上げたキーフレームを1つ置いたとして、そのボーンに他のキーフレームが無ければ、0フレーム目から最後まで腕は上がったままになります。「30フレーム目に上げる」という意味にはなりません。
VMDは「そのボーンの値が書かれた点」の列でしかないので、動かしていない時間は「動かしていない」と明示的に書かないと表現できません。 0フレーム目に初期姿勢のキーフレームを置いて初めて、0→30の間で腕が上がります。
だから、すべてのキーフレームに全部のボーンを書く
実務的な解はこれです。登録した全キーフレームのボーン名・表情名の和集合を取り、各キーフレームでその全部を書き出します。そのキーフレームで動かしていないボーンには、初期姿勢(回転なし・移動なし・表情0)を明示的に置きます。
ファイルは大きくなりますが(ボーン10種 × キーフレーム5つ = 50件)、「思った時刻にだけ動く」という当たり前の挙動が保証されます。 手付けのモーションは元からキーフレームが少ないので、実害はありません。
逆に、ツールが書き出したVMDを読むときは「キーフレームが飛んでいるボーン」がある前提で書くこと。 実物のモーションでは、腰やセンターのように動きの少ないボーンが数百フレームに1件しかキーを持ちません(切り出しで問題になる話は切り出し・結合・速度変更の記事に書いています)。
物理で揺れるボーンは書き出さない
髪・スカート・胸は剛体(物理演算)が毎フレーム動かします。その姿勢をVMDへ書き出すと、指定した姿勢と物理が綱引きになります。 素立ちのポーズを登録したつもりでも、揺れが収まる前の姿勢が固定され、再生すると不自然に硬くなります。
見分け方は剛体の種別です。PMXの剛体は種別を持っていて、0 はボーン追従(物理で動かない)、それ以外は物理が動かします。種別が0以外の剛体が付いているボーンを除外すれば済みます。
| モデル | ボーン | 剛体 | 剛体の種別 | 物理が動かすボーン | 書き出してよいボーン |
|---|---|---|---|---|---|
| アリシア | 150本 | 79個 | 0が26 / 2が53 | 53本 | 97本 |
| ad_org8 | 310本 | 141個 | 0が27 / 1が58 / 2が56 | 114本 | 196本 |
実際にポーズ編集で試すと、除外なしではボーン63件が書き出され(髪とスカートが全部入る)、除外すると10件になりました。残る10件は足IKが曲げている脚のボーンで、こちらは書き出して構いません — 足IKは再生時に解き直されます。
動いていないボーン(回転が単位クォータニオン・移動が0)も省くと、ファイルがさらに小さくなります。ただし上の「全キーフレームに全ボーンを書く」とは両立させること — 省いてよいのは「どのキーフレームでも一度も動かしていないボーン」だけです。
ポーズは1フレームのVMDとして書き出せる
MMDでは「ポーズ」をVPD(テキスト形式)で扱うのが一般的ですが、0フレーム目だけのVMDでも同じことができます。 ボーンの回転と表情のウェイトを1件ずつ書くだけで、そのまま再生もアップロードもできるので、扱う形式を増やさずに済みます。
VMDのボーン位置は初期姿勢からの差分である点に注意してください。絶対座標ではないので、読み込み直後のローカル位置を控えておいて、差を取る必要があります。
three.js で作る場合の座標変換
- 位置は Z を反転する。
- 回転(クォータニオン)は X と Y を反転する →
(x, y, z, w)→(-x, -y, z, w)。どちらも自己反転なので、逆方向も同じ式で戻せます。 - 回転の値をそのまま渡すと、腕が上がるはずのところで下がります。左右対称のポーズで検算するのがいちばん早い(対称なら符号の間違いがすぐ見える)。
アニメーションヘルパーに登録したままボーンを触らない
three.js の MMDAnimationHelper は、add() した時点のボーン姿勢をバックアップして毎フレーム復元します。 そのままボーンを手で回しても即座に戻されるので、ポーズを編集している間はモデルをヘルパーから外して、素のオブジェクトとして触る必要があります。
編集が終わったら登録し直します。確実に初期姿勢へ戻したいときは、モデルを読み直すほうが早いです。
試し再生は、作ったバイト列をそのまま再生経路へ流す
「登録したキーフレームを自前で補間して見せる」実装にすると、試し再生で見えたものと、保存して開き直したものが食い違います。 組み立てたVMDのバイト列をそのままローダへ渡せば、同じ経路を通るので食い違いようがありません。