Maya Advent Calendar 2024 の16日目の記事になります。
はじめに
MayaのBifrostを使用した補助骨作成を行います。
補助骨とは何かの説明や、標準ノードを使用した手首/肘補助骨の一例を以下の記事に記載しています。
Mayaによる補助骨作成の基本
前回に引き続き、本記事はテクニカルアーティストやリガーを対象とした初学者向けの内容となっています。
作例もシステマチックな内容になっており、見た目の良さを追求したものでは無い点をご了承ください。
Bifrostとは
ノードベースで様々な処理を行うためのプラグインです。
標準ノードと比べて数学/物理系のノードが強化されており、VFXなどの分野でも使われます。
今回は汎用の計算ノードを組み合わせて簡単な補助骨リグを作るために使用します。
Bifrost 2.0 for Maya
また作成したノードの書き出し/読み込みができるため、配布しやすい点も利点として挙げられます。
本記事で制作した内容は公開していますので、まずは読み込んで使ってみてください。
普段テクニカルな内容を扱わないキャラクタモデラーの方でも簡単に導入できると思います。
公開しているグラフ
本記事で実現したいこと
肩と前腕に鎧のような硬い装飾がついているモデルを想定します。
肩鎧はY軸とZ軸の曲げの動きには完全追従しますが、X軸の捻りの動きにはゆるく追従させたいです。
前腕鎧はX軸の捻りの動きにはゆるく追従しますが、Y軸とZ軸の曲げの動きには全く追従させません。
バインドポーズ | 稼働 |
---|---|
計算
今回の補助骨で実現したい計算は以下の流れになります。
回転の曲げ、捻り分解
基礎骨の回転を、曲げと捻りの2つに分解します。
曲げの取得
基準となるベクトルを用意します。
基準ベクトルを基礎骨の回転角度で回転します。
基準ベクトルを回転後ベクトルに向ける回転を得ます。
ここで得た回転角度は2つのベクトルのなす角にあたり、元の基礎骨の回転から捻り成分を除いた曲げ回転になります。
いわゆるエイムを実装であり、別の計算方法でも構いません。
以下にプログラムで実装する場合の例を記載します。
\displaylines{
defaultVec = om.MVector(1, 0, 0) \\
rotateVec = defaultVec.rotateBy(baseQuat) \\
bendQuat = om.MQuaternion(defaultVec, rotateVec)
}
捻りの取得
基礎骨の回転と、前項で取得した曲げ回転を使用します。
捻り回転は、基礎骨の回転から曲げ回転を除いたものになります。
以下にプログラムで実装する場合の例を記載します。
\displaylines{
rollQuat = bendQuat.inverse() * baseQuat
}
任意の曲げ重みをかける/任意の捻り重みをかける
対象の回転を軸ベクトルとその軸周りの角度として得ます。
その軸周りの角度に重みをかけます。
軸ベクトルと重みを考慮した軸周りの角度から、重みを考慮した回転を得ます。
以下にプログラムで実装する場合の例を記載します。
\displaylines{
axis, angle = originalQuat.asAxisAngle() \\
weightedAngle = angle * weight \\
weightedQuat = om.MQuaternion(axis, weightedAngle)
}
回転合成
重みをかけた回転を合成します。
シンプルにQuaternionを合成するだけですが、合成する順番によって結果が異なります。
詳細は割愛しますが、両方試して見た目が良いほうを使用すればとりあえずOKです。
以下にプログラムで実装する場合の例を記載します。
\displaylines{
resultQuat = weightedBendQuat * weightedRollQuat \\
or \\
resultQuat = weightedRollQuat * weightedBendQuat \\
}
ノード接続
これまで上げた計算を、Bifrostで実装します。
Bifrostの使い方は省略し、該当部分のみ画像で添付します。
もっと短く作れる便利ノードもあると思いますが、簡単のために汎用の計算ノードで作成します。
まずはジョイントとの接続部分です。
オイラー角とクオータニオンの変換、弧度法と度数法の変換を行っています。
基礎骨との接続(入力) | 補助骨との接続(入力) |
---|---|
回転の曲げ、捻り分解
Bifrostのクオータニオン系の計算ノードを使用しています。
このあたりの便利ノードがありがたいです。
曲げを得る | 捻りを得る |
---|---|
任意の曲げ重みをかける/任意の捻り重みをかける
quaternion_to_axis_angleとaxis_angle_to_quaternionを使用しています。
このあたりの便利ノードがありがたいです。(2回目)
曲げに重みをかける | 捻りに重みをかける |
---|---|
回転合成
曲げ捻り、捻り曲げそれぞれの順番で回転を合成します。
その後どちらを使用するか分岐しています。
書き出し、読み込み
グラフを作成できたので、右肩、左肩、右前腕、左前腕の4つに複製します。
グラフメニューからPublish、ビューワーから読み込みを行います。
この機能を使用してシーン内で複製することもできますし、異なるシーンで使用することもできます。
再利用しやすくてありがたいです。
Export | Import |
---|---|
結果
肩鎧、前腕鎧にそれぞれ設定して動かします。
よさそうですね、軸ごとにウェイトが異なりつつ、変なフリップもなさそうです。
肩鎧駆動 | 前腕鎧駆動 |
---|---|
まとめ
本記事ではBifrostを使用した曲げ/捻り分解補助骨を作成しました。
今回作成したグラフは以下のリンクから配布します。
自由に使っていただいて構いません。
曲げ重みや合成順番を調整しつつ、ご自身の制作にご活用ください。
公開しているグラフ
曲げ重みじゃなくて、縦曲げ横曲げそれぞれで分けたい...
可動域を制限したい...
もっと数式ベースでの解説が読みたい...
などの要望も出てきそうですが、それらはまた別の機会にとっておこうと思います。
個人的な感想としては、今回初めてBifrostに触れてみました。
噂に聞いていた計算系ノードの充実が素晴らしく、また設定ファイルとして共有しやすい点もありがたかったです。
普段はカスタムノードで独自の処理を書いているのですが、一部の用途ではBifrostに乗り換えてもよいかもしれません。
本記事が、3Dゲーム開発の助けになっていれば幸いです。
おまけ
Unityでの実現方法を、以下の記事で公開しました。
UnityのAnimationC#Jobsを使用した曲げ捻り補助骨の実装例