カメラVMDの中身と、カメラ位置の正しい求め方
カメラVMDは「注視点・距離・回転・画角」を持ちます。位置そのものは持っていないので、再生する側が組み立てます。この組み立て方を間違えると、寄りの絵が引きになります。
カメラのキーフレーム(61バイト)
| 位置 | 内容 | 大きさ |
|---|---|---|
| 0 | フレーム番号 | 4バイト(uint32) |
| 4 | 距離 | 4バイト(float32、通常は負の値) |
| 8 | 注視点 x, y, z | 12バイト |
| 20 | 回転 x, y, z(ラジアン) | 12バイト |
| 32 | 補間曲線 | 24バイト |
| 56 | 視野角(度) | 4バイト(uint32) |
| 60 | パースペクティブ | 1バイト |
補間曲線の24バイトは6項目 ×(x1, x2, y1, y2)の並びです。項目の順は 注視点X・注視点Y・注視点Z・回転・距離・視野角。よくある x1, y1, x2, y2 の順ではない点に注意してください。
カメラ位置の式
MMDでのカメラ位置は、注視点から見て、回転させた方向へ距離のぶんだけ下がった点です。
カメラ位置 = 注視点 + R ・ (0, 0, -distance)R は回転から作る行列です。距離が負なので -distance は正の値になり、カメラは注視点の後ろへ引かれます。
three.js の MMDLoader は式が違う
three.js r171 の MMDLoader.buildCameraAnimation() は、これを次のように組み立てています。
カメラ位置 = R ・ (注視点 + (0, 0, -distance)) // ← 注視点まで回している注視点が原点から離れているほど、この2つは食い違います。 実物のカメラVMD(129キーフレーム)で測ると、注視点からの実効距離が作者の指定と一致しませんでした。
| 作者が指定した距離 | MMDLoaderでの実効距離 |
|---|---|
| 16.40 | 15.29 |
| 24.60 | 21.95 |
| 64.60 | 61.82 |
位置のずれは平均3.4・最大19.0(MMDの単位。モデルの全高が約20)でした。向きは再生時に注視点を向き直すので気づきにくいのですが、被写体との距離が変わるため「寄りで撮ったつもりの絵が引きになる」という形で構図が変わります。
このサイトは、カメラVMDの解析と適用を自前で持ち、上の正しい式で毎フレーム当てています。登録した画角と再生される画角が画素レベルで一致することをブラウザで確認済みです。
補間で見落としやすい2点
- 補間曲線は「後ろのキーフレーム」のものを使う。 そのキーフレームへ「どう入ってくるか」を表すためです。
- 1フレームしか離れていないキーフレームの間は補間しない。 カメラの「カット」はこの形で書かれているので、素直に補間するとカットのたびに視点が滑って飛びます。