概要
Houdini での制作は基本的にノードベースであり、プログラミングを必要としません。
しかし Houdini がサポートする PythonやWrangle などの言語を使うことで、これらのノードを制御し、さらに柔軟な表現が可能になります。
本記事では、Houdini 18.5 から追加された KineFX と VEX 版 dict を使って、キャラクタスケルトンとアニメーションデータの接続情報を辞書型に格納するサンプルを作ります。
以下ソーススケルトン(fbx)をアニメーション、ターゲットスケルトン(sofia)をキャラクタと呼びます。
KineFX と VEX dict に関する他の記事はこちらをご参考ください:
Houdini でプログラミング:dict 型(VEX)
KineFXでモーションリターゲティング
アニメーションデータをサイクル可能アニメーションに設定する
アニメーションリターゲットが正しく行われない
Look At(KineFX)を設定する
KineFX:肩の補正
KineFXとPDGを組み合わせて、FBXをまとめてリターゲット&FBX出力してみる
アニメーションをキャラクタにリターゲット
以下の記事を参考に、アニメーションのリターゲットをします。
最後まで進めると、ノードネットワークが上のようになります。
mappoints のパラメータを確認すると、それぞれキャラクタのどのジョイントがどのアニメーションにリターゲットされているのかが確認できます。
今回はこの Mapping と To をそれぞれ key と value として辞書を構成します。
mappoints
参照するノードは mappoints です。
参考記事内で説明があった通り、mappoints は source skeleton と target skeleton という二つの入力を受けます。なので出力も二つ持ち、それぞれでアトリビュートも異なります。
上の二つから、source skeleton はアニメーションの情報を持ち target skeleton はモデルの情報を持っていることがわかります。
今回は独立した Attribute Wrangle を使い、絶対パスを使って mappoints からパラメータを取得します。
マッピングされたジョイントの取得と辞書の構築
キャラクタのジョイント名
アニメーションのジョイントの名前ならマウスオーバーでパラメータ名(to)が確認できますが、キャラクタの Mapping0 の上にカーソルを置いてもヘルプが出ませんでした。
代わりに隣にあるカーソルをクリックすると、
リグツリーが出てきました。
ここに mappoints.from0 とあるので、欲しいパラメータ名が from であることが確認できました。
実際のコードは上の通りです。Attribute Wrangle ノードは入力を受けず独立しているので、絶対パス("op:/...")を使って mappoints ノードを参照します。
Run Over は Detail です。
取得したパラメータ名を格納する配列を from[] とし、
chi() で取得した、マッピングされたポイントの数だけ for ループを回します。
出力してみると、27 個分のパラメータ名が取得できていることがが確認できました。
先頭についている @name= は lsprit() で削除しています。
lstrip() は削除したい文字列を削除先の文字列の左から探索し、ヒットし続ける限り削除し続けます。
アニメーションのジョイント名
アニメーションについてもやることは同じです。
ジョイント名から辞書を作成
VEX でも Python でも、辞書はキーと値からなる要素で成り立ちます。
今回はモデルのジョイント名(FromPass[])をキー、アニメーションのジョイント名(ToPass[])を値とします。
ジョイント名を取得する二つのコードをまとめ、新たに dict joint を定義します。
マッピングされたジョイントの個数分 for ループを回し、dict["keyname"] = "valuename" を使って要素を作っていきます。
mappoints ノードと見比べても、順番こそ違うものの対応するジョイント名は一致していることがわかります。
Houdini 18.5 から追加された KineFX では大量のデータ同士のつながりを正しく取り扱うことが重要になります。
データが必要になる度に関数を使って取得していると、必ず途中で間違えてしまいます。
辞書型を使って予め必要なデータを手元に用意しておくことで、各データへの理解を持ち、間違いを減らすことができます。