モーションを左右反転するときの計算と、反転できないもの
「振り付けの左右を入れ替えたい」はモーションを扱っていると必ず出てくる要望です。やることは3つだけですが、回転の符号とボーン名の入れ替え方を間違えると、見た目は動いているのに姿勢が破綻します。
反転するのは3つだけ
| 対象 | どうするか |
|---|---|
| 位置 (x, y, z) | x の符号を反転する |
| 回転 (x, y, z, w) | y と z の符号を反転する → (x, -y, -z, w) |
| ボーン名 | 「左」と「右」を入れ替える |
補間曲線は触りません。 あれは各項目の時間に対するカーブなので、左右を入れ替えても緩急は変わりません。フレーム番号も変わりません。
なぜ回転は y と z だけなのか
左右反転はX軸に垂直な面での鏡像です。位置はふつうのベクトルなので、面に垂直な成分(x)が反転します。ところが回転は擬ベクトル(軸ベクトル)で、鏡像にすると符号の付き方が逆になります — 面に平行な成分だけが反転します。クォータニオンの (x, y, z) は回転軸の方向なので、x は据え置き、y と z が反転し、実部 w はそのままです。
ここを「位置と同じようにxを反転」と書くと、腕や脚が捻れた向きに回ります。 見た目は動いているので気づきにくく、「なんとなく変」で終わってしまいます。反転した結果を左右対称のポーズ(両手を横に広げる等)で確かめるのがいちばん早い検算です。
ボーン名は1文字ずつ、同時に入れ替える
左腕 → 右腕 のように名前も入れ替えますが、文字列置換を順番にやってはいけません。 「左」を「右」に置換した後に「右」を「左」に置換すると、1回目で作った「右」も戻されて元の名前に帰ってきます。1文字ずつ走査して、その場で反対の文字へ写す必要があります。
// これは壊れる
name.replace("左", "右").replace("右", "左") // 左腕 → 右腕 → 左腕
// 1文字ずつ写す
[...name].map((c) => (c === "左" ? "右" : c === "右" ? "左" : c)).join("")実測では、31本のVMDが動かすボーン名1,079種のうち668種が「左」または「右」を含んでいました。kimino.vmd 1本を反転しただけで29,602件のレコードの名前が書き換わります。
名前の長さは変わりません。 「左」も「右」もShift_JISで2バイトなので、15バイトの固定長からあふれることはありません(実測でも、入れ替えた結果が15バイトに収まらない名前は0件でした)。とはいえ「左」を含む名前が元から15バイトぎりぎりであることは普通にあるので、書き出す前に収まるか確かめる作りにしておくのが安全です。
IKのオン・オフにもボーン名がある(20バイト)
VMDの末尾にある「IK/表示切替」ブロックは、右足IK のようなIKボーン名を持ち、それぞれの有効・無効を切り替えます。ここを入れ替え忘れると、反転したモーションで足のIKが左右食い違ったまま効きます。 このブロックのボーン名は15バイトではなく20バイト固定長である点にも注意してください。
実測した31本に出てきたIK名は28種で、右足IK 右つま先IK 左足IK 左つま先IK 右髪IK 左髪IK 左ひざDIK 右ひざDIK などでした。
カメラVMDは反転できない
カメラのキーフレームは注視点と距離と回転を別々に持ちます。位置そのものを持っていないので、「x を反転する」の対象がありません。注視点だけを反転すれば被写体は逆側に映りますが、回転の向きは別に考える必要があり、そもそも「カメラワークの左右反転」が何を意味するのかが一意に決まりません(手前に回り込む動きを反転したいのか、被写体の左右を入れ替えたいのか)。
このサイトはカメラのキーフレームを1件でも含むVMDは反転の対象から外します(実物のcamera.vmdは129キーフレームで、対象外と判定されます)。黙って壊れた結果を返すより、断るほうが親切だという判断です。
表情(モーフ)も反転していない
表情名にも ウィンク右 左まぶた上 のように左右があります。しかし機械的な入れ替えができません。 実測すると、425種の表情名のうち左右を含むものは53種で、そのうち反対側が存在するのは50種でした。残る3種は ウィンク右 ウィンク右2 ウィンク2右 — MMDでは左目のウィンクを単に ウィンク と名付ける慣習があるため、「右」の反対が「左」ではなく無印になっているのです。
ウィンク2右 のように半角カナが混じるものもあります。名前は完全一致で突き合わされるので、こういう命名が1つあるだけで機械的な変換は当てになりません。表情は触らず、必要なら人が直すのが確実です。