投稿者「HEXADRIVE001」のアーカイブ

TAとOpenMaya SkinCluster

 こんにちは、Ritaro です。

 

 こちらに記事を書くのはこれで2回目となります。

今回も、よろしくお願い致します。

 

 TAにとって開発上の問題点を解くのに 技術的な引き出しを色々な持っておくことが必要、

と前回の記事に書いた部分を・・もう少し紹介したいと思います。

 

近年はゲームを開発する上で DCCツール(MayaやMotionBuilder)の知識だけでなく、

ミドルウェア(UnityやUnrealEngine)の知識もたくさん 必要となって来ているという点は、

もちろんあります。

その中でTAがグラフィックに関する部分を任されると 必然的にシェーダーの開発の話にもなったりします。

で、TAなのですからその作業というのは、

ゲームで使うと決められるようなシェーダーの判断材料の制作になります。

”前準備”ですね。

DCC側でのデータの準備をどう工夫してミドルウェアに持っていくのか、

その場合の作業簡易ツールはどうあるべきか、

ミドルウェア側ではそのデータを使ってどう組むと目的に近いシェーダーになるのか。

更にはその処理負荷はどのくらいなのかもです。

これはこれで、たくさん引き出しが必要そうですね。

 

と、更にもう1つの引き出しとしては、アニメーションに関してもあるはずです。

キャラクターセットアップ用のツールやモーション出力用のツールなども

ミドルウェアと合わせて用意したりします。

これはこれで、たくさんの引き出しが必要そうです~。

 

 ちょっと具体的な、面白い対処法、

でもあったら『おお、使えるかも』 ・・って思うようなものをまた1つご紹介してみましょう。

 


 

「OpenMayaを使ってSkinClusterを取得してツールの高速化をはかりたい!!」

 

Mayaを使ってキャラクター用のツールを開発する時、

避けて通れないのかSkinBindしたポリゴンメッシュデータの編集、

特にWeight値に関するツール開発は最たるものです。

しかも通常のPythonコマンドでも便利ツールは作れるのに・・

処理速度がイマイチなものが出来上がります。

 

 便利ツール出来たー!! > 実行 > 遅~い ;_;   です。

 

そこで、OpenMayaなるものに挑戦して高速化を図る訳です。

OpenMayaの引き出しも必要になって来ました~。

 

情報として良く探れるものにはWeight値を扱う例があったりします、

・・・・ありがたきかな(「一握の砂」)。

で、そのはじめの部分はこんな感じのスクリプトから山開きしています。

 

clusterName = 'skinCluster1'

selList = OpenMaya.MSelectionList()
selList.add(clusterName)
clusterNode = OpenMaya.MObject()
selList.getDependNode(0, clusterNode)
skinFn = OpenMayaAnim.MFnSkinCluster(clusterNode)

infDags = OpenMaya.MDagPathArray()
skinFn.influenceObjects(infDags)
・・・・

で、私的には気になる、”前準備”的なところがある訳なんです。

?? ‘skinCluster1’ って書いてあるスキンクラスター名はどうやって取ってるの?。

 

MayaのSkinBindされたキャラクターデータを見ると、

そのJointにはそのポリゴンメッシュの数分だけ SkinClusterも存在しています。

ここはその数だけのループ処理が発生しているはずです。

 

こんなアプローチでどうぞ。

SkinBindされたポリゴンを1つ選択した状態で実行すると

スキンクラスター名が取得出来ます。

 

*— ”前々準備”

Iterator には、以下あり。

kDepthFirst = 深さ優先探索 、kBreadthFirst = 幅優先探索

 

dagIterator = OpenMaya.MItDag(OpenMaya.MItDag.kDepthFirst,OpenMaya.MFn.kInvalid)

で、前のデータが残っている場合があるので、リセットします。

dagIterator.reset(***.node(),OpenMaya.MItDag.kDepthFirst,OpenMaya.MFn.kInvalid)

if文の curr_obj.hasFn(OpenMaya.MFn.kMesh) は 選択したものがポリゴンメッシュなら、です。

そして、skinFnの名前 skinFn.name() がスキンクラスター名です。

ポリゴンメッシュにスキンクラスター名が無い場合は、

BindSkinされてないポリゴンとして別処理(処理を飛ばす等が)出来ます。

*—

(Weight値処理部分は記載しておりません)
<ツールは自己責任でお使いください>

 

import maya.OpenMaya as OpenMaya
import maya.OpenMayaAnim as OpenMayaAnim


selList = OpenMaya.MSelectionList()
OpenMaya.MGlobal.getActiveSelectionList(selList)

selList_iter = OpenMaya.MItSelectionList(selList)
sel_obj = OpenMaya.MObject()
selList_iter.getDependNode(sel_obj)
DagPath = OpenMaya.MDagPath.getAPathTo(sel_obj)

dagIterator = OpenMaya.MItDag(OpenMaya.MItDag.kDepthFirst,
    OpenMaya.MFn.kInvalid)
dagIterator.reset(DagPath.node(),OpenMaya.MItDag.kDepthFirst,
    OpenMaya.MFn.kInvalid)

clusterName = ""
while not dagIterator.isDone():
    curr_obj = dagIterator.currentItem()
    if (curr_obj.hasFn(OpenMaya.MFn.kMesh)):
        objMeshName = OpenMaya.MObject(curr_obj)
        itDG = OpenMaya.MItDependencyGraph(objMeshName,
            OpenMaya.MFn.kSkinClusterFilter,
            OpenMaya.MItDependencyGraph.kUpstream)

        while not itDG.isDone():
            try:
                currentCluster = itDG.currentItem()
                skinFn = OpenMayaAnim.MFnSkinCluster(currentCluster)
                clusterName = skinFn.name()
                break
            except:
                clusterName = ""
    dagIterator.next()

print clusterName