SuiTechLog

Unity,Arduino,RaspberryPiなど、モノづくり系を気ままに書き残すブログ。

Motion Builder Python


Motion BuilderのPythonでアニメーションキーいじってみましたがえらいめんどくさかったので忘れないようにメモ

  

すでに打ってあるキーを取得する

 

キーデータはパラメータ毎にこういう入れ子構造になっているようです。

 

あるオブジェクト

 └AnimationNode(ルート。必ずあるっぽい)

    ├AnimationNode(親なのでデータなし?)

    │ ├AnimationNode(Aというパラメータのアニメーションデータ)

    │ ├AnimationNode (Bというパラメータのアニメーションデータ)

    │ └AnimationNode(Cというパラメータのアニメーションデータ)

    ├AnimationNode(Dという・・・ry)

    └AnimationNode(

   

なので、ルートから再起関数で必要なパラメーターのキーノードを探します(下端のAnimationNode.Nameで、パラメータ名がとれるはずです。)

 

 

ちなみに正確には、AnimationNodeはそれぞれNodesというリストをもっていて、その中に子のAnimationNodeが入っています。(上の図はあくまでイメージです)

 

サンプルでは以下のような再起関数にして必要なパラメータのAnimationNodeをとってきているようでした。

pNameには探したいパラメータ名

pNodeにはRootのAnimationNodeを指定します。

# Find the animation node recurvesive by name.
def findAnimationNode( pName, pNode ): 
    lResult = None 
    lName = pName.split( '/' ) 
    for lNode in pNode.Nodes: 
        if lNode.Name == lName[0]: 
            if len( lName ) > 1: 
                lResult = findAnimationNode( pName.replace( '%s/' % lName[0], '' ), lNode ) 
            else: 
                lResult = lNode 
    return lResult    

 (どうやらノード名が/で連結されているみたいで、必要なパラメータ名がでてくるまで再帰的に探し続けるみたいな感じですね。)

 

そして、上の関数でとれたAnimationNodeにたいして.FCurveとアクセスすると、そのパラメータのアニメーションがとれます。

そこからはFCurve.Keys[]でキーフレームのリストがとれます。

 

以下のような感じです

curves= AnimationNode.FCurve
lKeys = curves.Keys
fkeyframe = lKeys[0].Time.GetFrame()

 

ここでは、GetFrame()で最初のキーフレームのフレーム番号をとってきています。このあたりの詳細は各クラスの公式リファレンスをご覧ください。

 

例:XYZの位置回転のアニメーションノードを求める処理は以下です。objはアニメーションをいじくりたいオブジェクトです。

 

for pName in [ 'Lcl Translation/X','Lcl Translation/Y','Lcl Translation/Z', 'Lcl Rotation/X','Lcl Rotation/Y','Lcl Rotation/Z']: 
    lSrcNode = findAnimationNode( pName, obj.AnimationNode )
                        
    curves= lSrcNode.FCurve
    lKeys = curves.Keys
    fkeyframe = lKeys[0].Time.GetFrame()

    break

 

キーのないカスタムパラメータにキーを追加する

 

ここで私は詰まりました

キーがないパラメータの場合はそもそもAnimationNodeを検索しても当然でてこないのです。

この場合は新たにキーノードを作成しないといけません

 

やりかたとして、 まずカスタムパラメータをプロパティリストから検索して、あらたにAnimationNodeを生成してやります。これは以下の方法でできます。

 (objはオブジェクト名、customparamはカスタムプロパティ名のリストです)


for i in obj.PropertyList:
    if i.IsUserProperty():
        for pName in customparam:
            if( pName==i.Name ):
                i.SetAnimated(True) 

 

SetAnimatedをTrueにしてあげることで勝手にAnimationNodeが生成、登録されるみたいです。この時点で、上記のfindAnimationNode()で検索に引っ掛かるようになりますので、以下の関数などでキーをいれてあげると目的達成です。(curvesは、上記のFcurveになります。)

curves.KeyInsert(FBTime(0, 0, 0, keyframe))

curves.KeyAdd(FBTime(0, 0, 0, keyframe),value)

 

参考

 

今回アニメーションキーをいじるのにあたって参考としたところ

まず言わずもがなのNo More Retakeさん

nomoreretake.net

デジフロさん

dftalk.jp

あとこちら

Alex Forsythe

 

そして公式のサンプルデータと公式リファレンスを参考にしました

MBのAssetBrowser->Scriptsサンプル
FCurve
CopyAnimation

  

Autodesk MotionBuilder SDK Documentation

 

さいごに

 

   しかし、文献がかなりすくないこと、構文がかなりC++に近いことにより全然デザイナーフレンドリーじゃない(すくなくともC++などの経験がないとしんどい)のでこれはどうしたもんでしょう。慣れていないと全然進みません。Mayaで言うと、OpenMayaのような感じですね・・・