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さん
デジフロさん
あとこちら
そして公式のサンプルデータと公式リファレンスを参考にしました
MBのAssetBrowser->Scriptsサンプル
FCurve
CopyAnimation
Autodesk MotionBuilder SDK Documentation
さいごに
しかし、文献がかなりすくないこと、構文がかなりC++に近いことにより全然デザイナーフレンドリーじゃない(すくなくともC++などの経験がないとしんどい)のでこれはどうしたもんでしょう。慣れていないと全然進みません。Mayaで言うと、OpenMayaのような感じですね・・・