前回の記事では、worldMartixを用いてコンストレインを再現していました。
今回は、localのmatrixでコンストレインを再現してみることにします。
支点における目的箇所の位置・回転をlocal座標を用いて再現する
具体例がないと、この見出しは、なんのこっちゃ??? なので、お題を設けたいと思います。
お題:"spineD_prx"支点における"hand_prx_L"(左手首)の位置と回転情報を、locatorを用いて再現する
multMatrixを用いてlocal座標のmatrixをつなぐ
import pymel.core as pm
pm.createNode("multMatrix", n=u"hand_prx_L_spineD_prx_multMat")
transformノードのlocal座標を意味するアトリビュートは.matrixです。
hand_prx_Lからさかのぼってshoulder_prx_Lまでのlocal座標を足していくと、
おのずとspineD_prxにおけるhand_prx_Lの位置関係がmatrixで取得できるわけです。
下図のように各transformのmatrixをmultMatrixのmatrixIn[0]からつないでいきます。
ここで重要なのは、さかのぼった順番に.matrixInへコネクションをする、という事です。
decomposeMatrixでtranslate, rotateを出力しやすくする
前回の記事で既にお分かりかと思いますが、
matrixのままだと位置・回転情報を出力しにくい為、decomposeMatrixを用います。
pm.createNode("decomposeMatrix", n=u"hand_prx_L_spineD_prx_decMat")
locatorへコネクト!
decomposeMatrixから下図のようにhead_pos_Lへコネクトを行う
結果
hend_pos_Lを見ると、なんだか関係のない場所にあるように思えます。(下図)
これはspineD_prxを支点として取得したmatrixの結果なので、spineD_prxの位置が原点だとすると、そうなることになります。
理解できない場合は、spineD_posをspineD_prxの位置に用意し、hand_pos_Lを子供にすれば一目瞭然です。(下図)
jointの最上位にあたる箇所、hipTranslation_prxを移動させてみましょう。
hand_pos_Lはついてきません。(下図 赤い箇所)
hand_pos_Lも同期して回転しました。
何に使うか?
この仕組み、様々な使い道があると思いますが、私はこれをデフォームやシミュレーション要素を含むリグでよく用いています。
なぜなら、local座標系でmatrixを使うという一見カッコいい小技が使えるからです!
...うそです、ごめんなさい。
それだけの面倒な小技、できることならば私は使いたくありません。
これを使う大きな要因の1つの、ある条件下におけるエラーを除外するためです。
例えば、原点からのリグへの位相が大きい場合、Mayaの計算制度が落ちてパーツなどがズレる事があります。皆さん経験ありませんか?
それを回避するためです。
映像系の制作過程ではよく起こることですが、
ゲーム系ではどうなのでしょう?
ゲームだとその物全体をフィールド上で動かす要素は別となってると思うので、そういうエラーには陥らないのかな?
特に宇宙や大海原のような広大な敷地でアニメーションする必要がある場合、
髪の毛が頭皮からズレてたりするんですよね。。。
そんなエラーを回避するのにmatrixの理解が必要なんて、ですよね!
12月10日に公開されたMaya2020のヘルプでは、
offsetParentMatrixのinput行列が追加されると記載がありました。
恐らく、今回記載したdecomposeMatrixを介すことなく、直接matrixでトランスフォーム制御ができるという事なのかな。少し楽になりそうですね!
そういう意味では超ギリギリセーフの記事となってしまいました(汗)