MayaのキャラクタライズのID番号とジョイント

この記事はMaya Advent Calendar 2020の8日目の記事です。

戦国時代で赤が似合う武将は思い浮かぶけど、意外と緑の似合う武将は思い浮かばないな。戦国クリスマス対決が妄想できない……。
どうも、クリーク・アンド・リバー社 COYOTE CG STUDIO テクニカルチーム 戦国大好き人間の中林です。

今回はMayaでHumanIKのキャラクタライズをスクリプトを使って簡単にする内容、ではありません。
それについては甘夏ニットさんが過去記事「HumanIKをコマンドで操作する」でまとめてくれ分かり易いです。
こちらの記事を見てキャラクタライズ未経験のTAの僕が半日でツール化、今ではそのツールを使って7体キャラクタライズを3分で終わらせています。しかも3分のほとんどはMayaのデータロード時間です。
感謝してもしきれない内容の記事です(ヨイショッ)

そもそものキッカケは?

キャラクタライズのスクリプト作成後の作業は順調に行きました。スクリプトを実行するだけなので、ワンクリックで終わるので確認作業の方が時間がかかるくらいです。
問題はスクリプトを作成する時のジョイントのアサイン処理です。ちなみにmelコマンドはこちらです。

setCharacterObject("Character1_Hips","Character1",1,0);

完成されたキャラクタライズの第一引数のジョイント名と第三引数のID番号の関連性が分からないです。
キッカケの時は作業を振り返る余裕がなかったので、手動で
1・ジョイント選択
2・「Assign Selected Bone」でアサイン
3・undoで上記のコマンドがスクリプトエディタに表示
4・コマンドのコピペ

この作業を70本以上、繰り返しました。半日の作業の大半はこちらでした。
別プロジェクトでキャラクタライズをする場合は当然、ジョイントの名前と本数は変わるのでこの作業を繰り返すのは辛いですね。
少なくとも僕は二度とやりたくはないです。
そこで、この引数をスクリプトでペアで取得できないか調べました。

全ての答えは【HIKCharacterNode】ノードにある

今回は説明に「Create Skeleton」で作成したデフォルトの「Character1」とジョイント名の組み合わせを利用しています。
【HIKCharacterNode】ノードと大層なこと言ってますが「Character1」を選択してノードエディタを開いてみるだけです。

この画像でノードのアトリビュートにどこかで見た名前とジョイントがつながっています。
甘夏ニットさんの記事に載っていた「GetHIKNodeName(ID番号)」で入手した名前とほぼ一致してます。

15 :Head
 1 :Hips
 9 :LeftArm
 4 :LeftFoot
……………………
以下略

ノードのコネクトを調べればOK

ここまで分かればアトリビュートからlistConnectionsでソース側をたどれば分かります。
これを上手いことコマンドになる様にprint内容を調整すれば……

for ($i = 0; $i < 212; $i++){
    $name = GetHIKNodeName($i);
    string $attr = "Character1." + $name;
    string $joint[] = `listConnections -s on -d off $attr`;
    if(size($joint) == 0){
        continue;
    }
    print ("setCharacterObject(\"" + $joint[0] + "\",\"Character1\"," + $i + ",0);\n");
}

setCharacterObject("Character1_Reference","Character1",0,0);
setCharacterObject("Character1_Hips","Character1",1,0);
setCharacterObject("Character1_LeftUpLeg","Character1",2,0);
setCharacterObject("Character1_LeftLeg","Character1",3,0);
setCharacterObject("Character1_LeftFoot","Character1",4,0);
……………………
中略
……………………
setCharacterObject("Character1_RightHandRing4","Character1",89,0);
setCharacterObject("Character1_RightHandPinky1","Character1",90,0);
setCharacterObject("Character1_RightHandPinky2","Character1",91,0);
setCharacterObject("Character1_RightHandPinky3","Character1",92,0);
setCharacterObject("Character1_RightHandPinky4","Character1",93,0);

これで第三引数の番号と第一引数のジョイント名の組み合わせたコマンド群ができます。
この結果を全てスクリプトにコピペするだけでもすべてのジョイントのアサインが再現できます。
僕個人としてはツールを作るときはユーザーであるアーティストさんの手間を減らすことに力を入れて、自身の手間を省くのは頓着してます。それでも、たまには作る側の手間を減らす為に調べるのもありかと思いました。
僕のキャラクタライズのための数時間のコピペの作業が、収集のための1クリックに変わりました。
この情報がキャラクタライズをするTAの一助になればと思います。

明日12/9は tm8rさんの記事です、おたのしみに!

Author: nakabayashinobukazu