自分が今まで色々3DDCCツールを使ってきて、毎回悩む分野の一つにコンストレイント、エクスプレッションやスクリプト等の習得がありました。
この領域はデータ作成の効率化とかに直接関係してくる部分ですが、その分ツール作者達の思想に近い部分でもあるので、ちょっと敷居が高いなと毎回思います。
スクリプトについては、最近各ツール共pythonを使う方向なので、その流れでいずれ統合できるようになって欲しいものです。
最近3DSMAXに触り始めて運良くいろいろ学べ、またいくつかGoogle先生に必死こいて教えてもらった事柄もありましたので、そういった部分をちょこちょこまとめてみます。
とりあえず今回はRigやFカーブ系で使うことの多いエクスプレッションを書こうかと思います。
どう簡潔に書くか悩んだ末にSoftimageと3dsmaxでよく使うエクスプレッション/スクリプトコントローラーの対照表を作りました。
3DSMAXのスクリプトコントローラについては無駄に長々と書いてあるように見えますが、表の後にエクスプレッションを書く時に必要な補足があるので読んでみてください。
この領域はデータ作成の効率化とかに直接関係してくる部分ですが、その分ツール作者達の思想に近い部分でもあるので、ちょっと敷居が高いなと毎回思います。
スクリプトについては、最近各ツール共pythonを使う方向なので、その流れでいずれ統合できるようになって欲しいものです。
最近3DSMAXに触り始めて運良くいろいろ学べ、またいくつかGoogle先生に必死こいて教えてもらった事柄もありましたので、そういった部分をちょこちょこまとめてみます。
とりあえず今回はRigやFカーブ系で使うことの多いエクスプレッションを書こうかと思います。
どう簡潔に書くか悩んだ末にSoftimageと3dsmaxでよく使うエクスプレッション/スクリプトコントローラーの対照表を作りました。
3DSMAXのスクリプトコントローラについては無駄に長々と書いてあるように見えますが、表の後にエクスプレッションを書く時に必要な補足があるので読んでみてください。
挙動説明 | SoftImage (Expression) | 3DSMAX (ScriptController) |
---|---|---|
| null_controller.kine.local.posx | pass_dummy_controller = "" objname_dummy_controller = execute("$" + pass_dummy_controller + "pass_dummy_controller") dependsOn objname_dummy_controller objname_dummy_controller.inode.posInParent.x |
| MIN(0,null_controller.local.rotx ) | pass_dummy_controller = "" objname_dummy_controller = execute("$" + pass_dummy_controller + "pass_dummy_controller") dependsOn objname_dummy_controller degToRad( amax #( 0, obj_dummy_controller.inode.rotInParent.x)) |
//補足
1) 3DSMAXは同一シーン内で同じ名前を付けられます。(モデルIDなどで個体判別は可能です)
2) 3DSMAXでは、スクリプトコントローラーの埋め込まれたオブジェクトの挙動が、どのオブジェクトが動くと再計算されるか明示的に指定する必要があります。
3) SoftImageのローカル座標系は3DSMAXでは傾き自体はローカル座標系で数値は親座標系でみます。
補足1)は Rig等で同名オブジェクトを持つ構造体を同一シーンに読み込んでくる際に厄介です。
SoftImageは名前が同一でない前提でエクスプレッションを組 めますが、3DSMAXで同じ事をやると先に読んだRigの右足を動かすと、後に読んできたRigの右足まで一緒に動く等の不具合が出ます。
問題回避のために、3DSMAXではパス名リテラルを使用して個体判別を行うことができます。
補足2)はコントロールする側のオブジェクト宣言で、スクリプトコントローラ内に dependsOn $オブジェクト名 と書きます。
スクリプトコントローラでは他にも指定方法がありますが、これが一番簡単だと思います。
//例示
下記構造体のr_heelの親X位置をr_heel_controllerの親X位置で動かしたい場合、スクリプトコントローラーには次のように書きます。
pass_r_heel_controller = "c_hip01/"
obj_r_heel_controller = execute("$" + pass_r_heel_controller + "r_heel_controller")
dependsOn obj_r_heel_controller
obj_r_heel_controller.inode.posInParent.x
1行目はr_heelの親までのパス名リテラルを入れる変数と捉えてください。
2行目はパス名リテラル入りのオブジェクト名です。これでオブジェクト名確定です。execute()は文字列をオブジェクト化します。
3行目はコントロールする側のオブジェクト宣言です。
4行目でスクリプトコントローラの実行部分を書きます。
ち なみにパス名リテラルはすべてを省略せずに書かねばなりません。
MAXスクリプトではこれを省略できますがスクリプトコントローラーではできません。
この構造を複数別々で扱いたい場合は一番上のノード名"c_hip01"を "c_hip02"などと変更してからスクリプトコントローラ内の対象文字列もすべてそれに書き換える必要があります。
また文字列ノードはツリー全部を直書きするので、Rig等エクスプレッションを多数扱う構造体を複数同一シーン内に配置する場合、
スクリプトコントローラ内の文字列を自動で書き換えるスクリプト等の支援が必須になると思います。
//
参考文献 :
Softimage SDK プログラミング ガイド
エクスプレッションによるアニメーション
エクスプレッション関数リファレンス
3DSMAXスクリプトヘルプ
パス名リテラル
スクリプト コントローラ用 dependsOn
インタフェース : INode
文字列値
Number値
コレクションのタイプ
0 件のコメント:
コメントを投稿