スポンサーサイト

    上記の広告は1ヶ月以上更新のないブログに表示されています。
    新しい記事を書く事で広告が消せます。

    Maya Matrix覚書

     今お世話になっている会社ではよくmatrixに関するノードを使用します。
     特にdecomposeMatrixとmultMatrixのボクの中での使用頻度は郡を抜いてるなぁと。

     しかしこのmatrix、理解すれば非常にリギングの高速化に貢献するすばらしいヤツなんですが、概念が非常に理解しづらいです。少なくともボクはしょっちゅう忘れます・・・(汗
     なので一度Mayaにおけるmatrixの簡単な概念をまとめておこうかと思います。ちなみにコレはお馬鹿な管理人の独自解釈によるまとめですので、間違ってる場合はご指摘頂けると助かります・・・(^^;


    ■あの数字の羅列は何を表しているのか


     まず適当なnullでもなんでもtransformノードを作ります。それを選んで
    getAttr .matrix;
    と入力すると
    // Result: 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1
    と返ってきます。これがmayaで扱われているmatrixなのですが、この数字の意味やいったい・・・?と言うのが今回のテーマ。

     これは全部で16個の数列ですが、まずは4つずつに区切ってみます。すると
    1 0 0 0
    0 1 0 0
    0 0 1 0
    0 0 0 1
    えぇ、まだ意味不明です。実はこれは1行1行がtransformに関する情報を保有しています。


    まず、一番手っ取り早くわかり易いのが4行目。結論から言うと4行目の頭3つはtransformノードのX,Y,Zの位置座標を表しています。試しにさっき作ったtransformノードの位置を10, 5, 0に動かしてからmatrixを取ると
    1 0 0 0
    0 1 0 0
    0 0 1 0
    10 5 0 1
    に変わってます!
     これは比較的わかりやすいですね。4行目4番目の数字については後ほど。


     さて、次に注目するのが左上から3×3の部分
    1 0 0 0
    0 1 0 0
    0 0 1 0
    0 0 0 1
    これをさらに一行ずつ解体すると・・・
    1 0 0
    0 1 0
    0 0 1
     またまた結論から言うと、この各行の3つの数字がそれぞれX、Y、Z各軸の方向を表すベクトルになっています。1行目は1、0、0なのでX軸はX方向に1の向き、2行目は0,1,0なのでY軸はY軸方向に1の向き、3行目は0,0,1なのでZ軸はZ軸方向に1の向き・・・といった具合です。

     試しにZ軸で+45°まわしてmatrixをとると
    0.707107 0.707107 0 0
    -0.707107 0.707107 0 0
    0 0 1 0
    0 0 0 1
    となり、
     一行目では0.707107, 0.707107, 0でX軸が右斜め上を向き、2行目は-0.707107 0.707107 0なのでY軸が左斜め上を向き、3行目は0,0,1なので変わらず。つまり軸が+45°傾いた状態を表しています。

     
     回転を元に戻し、今度はスケールYを2にしてmatrixをとると
    1 0 0 0
    0 2 0 0
    0 0 1 0
    0 0 0 1
    となり、2行目のY軸だけがY方向に2倍になっているのがわかります。
     因みにshearXYを1にすると
    1 0 0 0
    1 1 0 0
    0 0 1 0
    0 0 0 1
    となり、Y軸だけが斜めになっていることがわかります。結果このノードの形状がY軸で斜めになるわけです。
     昔から、なぜTransformの中にshearが入っていたのかが、浮いている気がして不思議だったんですが、この理論があるからtransformノードはshearもサポートしてたんですね。う~ん、考えたヤツ天才すぎる。

     最後に。各行の頭3列までの情報はわかったのですが、どの行も4列目だけは使用しませんでした。実際基本的にはMayaでは使用しないようです。
     では、使わないのに何故4行目の四列目の数字だけ1なのか? それは、そうすることによってこの行列が単位行列(identity matrix)になるからだそうです。昨日知りましたw(^^;)

     まぁ他にも深い理由がいっぱいあるのかもしれませんが、納得できる理由をゲットできたんで良しとします。
     ↑ほんま適当やな

    最近のMaya2011

     仕事ではMaya2010なのと、グラボがもはや死亡フラグ立ちまくりのロートルでMaya2011があんまり快適に動作しなかったってのもあっってMaya2011をあまり使用してなかったのですが、最近グラボを買い替え~の、友どちからMaya2011で動作しなくなったツールを対応してくれと頼まれ~の、知人から以前頼んでたガンダムのモデルどうなりました?と聞かれ~の、とMaya2011を触る機会が増えました。

     そしたらまぁ、今まで目を瞑ってたんですが色々自作ツールが動かんですな・・・
     UV編集しようと思ったらUVeditor拡張パックまで動かんしまつ・・・コレないとワシは作業できないんで、前回のrandamizerに引き続きこちらもPythonで一から作り直すことにしました。
     が、今回はちょっと作業量が重いなぁ・・・
    uvEditorPlus001.jpg
     とりあえずパッと見のGUI作成はほぼ完了。色々改良を加えつつ、まぁ取りあえず欲しい機能は8割ほど揃ったんで、UV編集の作業はとりかかれそう。


    んで、触りついでに新機能を改めて見てみたら、いつのまにかポリゴンフェースへのコンストレインがついてるじゃないですか!
     これからはpontOnSurfaceやconstrainを駆使した激重技や、follicleを使ってのいらないアトリビュートがついてなんか気持ち悪いなんちゃってコンストレイン使わなくてすみそうです。
     あんま触ってないからわからんですが、ディフォルトではポリゴンのUV座標(0,0)に近い座標にコンストレインされるため、コンストレイン前の位置に近い部分に適応するには、一度nearestPointOnMeshなどで被コンストレインオブジェクトのワールド座標から一番近いUV座標を割り出してやる必要がありそうです。

     nearestPointOnMeshと言えば、もうひとつ加わったコンストレイン(最近接のポイントコンストレイン)はこのnearestPointOnMeshを使用してますね。実際にはコンストレインノードを使用してないのでこのカテゴリに入れるのはどうかと思いますが・・・
     フェースへのコンストレイン時にUV座標を逐一探すのが面倒な方はスクリプトでやっちゃうか、一度このコンストレインを実行して、ロケータを任意の位置へ動かし、これにつながっているnearestPointOnMeshのUV座標をメモっておいて、フェースへのコンストレイン実行後にコンストレインノードのUV座標を入れてやるといいかもしれません。

     色々パワーアップを果たしてるMaya2011、見た目もかっこよくなったし言うことないんですが、ただ一つGUIが重くないっすか・・・?
     グラボ変えたのにまだ重いぜよ・・・

    汎用プロジェクトマネージャ考察2 - シーケンス編

    汎用プロジェクトマネージャ考察1の続き

    ■では具体的にどう定義するか

     ディレクトリ構造の定義を同じディレクトリを作成しそれを参照するようにするとして、では具体的にどうするか?
     以下考え中の構造のサンプルを書きます。
     ・まずプロジェクトルートを指定。ここはもうアドミニ権限の人が手動設定で。
     ・そしてプロジェクトのルートを作成(名前はプロジェクト名)
     ・その下に例えばdefineみたいなディレクトリを作成。
     ・さらにその下にasset(element?)、seq(Sequence?)を作成。
    ここまでは決め打ちでいいかなと思ってます。
     ツールはあらかじめ指定されたプロジェクトルートの下の階層をプロジェクトディレクトリとして認識し、ユーザはそこから一覧を選択。すると、今度はプロジェクトディレクトリの下のdefineディレクトリを見に行き、その下を階層定義ディレクトリとして解析、または参照にかかると。

    こんな感じ
    [ Project Root ]
    |_[ Project ]     ←ここはアドミニが指定
    |_[ define ]    ←名前決め打ち
    |_[ asset ]  ←名前決め打ち
    |_[ seq ]   ←名前決め打ち
    ん、でもassetとseqを決め打ちにしちゃうと、elementとかshotって名前がいいって場合対応できないか・・・
    かと言って定義ファイルを作るとディレクトリ構造から解析すると言う趣旨から外れるので、やはりディレクトリ名から解析したい・・・


    ■ディレクトリ名で定義する

     と言うことで
    [ Project Root ]
    |_[ Project ]     ←ここはアドミニが指定
    |_[ define ]    ←名前決め打ち
    と、ここまでを決め打ちにし、ここから先は名前によって解析するのがいいのではないかと思います。例えばこんな感じ
    名前.カテゴリ
     さすがに普通の命名規則でディレクトリにドットを入れるなって言う縛りくらいは許容範囲ではないかと考えたのですがどうでしょう。
     上記の場合、名前はお好きな名前を管理者が決め、ドットから先は定義済みカテゴリ指定文字列を入れると。例えばオブジェクトを格納するディレクトリをElement、シーケンスを格納するディレクトリをShotとしたい場合
    [ Project Root ]
    |_[ Project ]     ←ここはアドミニが指定
    |_[ define ]    ←名前決め打ち
    |_[ Element.asset ]
    |_[ Shot.seq ]
    こんな感じで。.assetはこのディレクトリがオブジェクトを格納している事を表す定義済み文字列、.seqは同様にシーケンスを格納している事を表す定義済み文字列とします。
     こうすれば、ここから下のディレクトリも同様に定義できるのかも
    [ Project Root ]
    |_[ Project ]     ←ここはアドミニが指定
    |_[ define ]    ←名前決め打ち
    |_[ Element.asset ]
    |_[ Shot.seq ]
       |_[ EP.seq ]
         |_[ Scene.seq ]
           |_[ Cut.seq ]
             |_[ Cut.seq ]
               |_[ publish.master ]
               |_[ work.work ]
                 |_[ anm.animation ]
                 |_[ sim.simulation ]
                 |_[ vfx.vfx ]
                 |_[ lighting.light ]
                 |_[ cam.camera ]

     このように階層構造をディレクトリによって定義し、マネージャはプロジェクト選択時にこの階層を一度解析、その後解析結果を元にブラウザ状のGUIを構築するようにすれば、ある程度の仕様には耐えられるのではないかと。
     勿論このマネージャを使用する時点である程度の縛りは作られますが(必ずWorkとMasterを作成するとか、アセットとシーケンスを分けとくとか)、Aのプロジェクトは映画だからシーケンスの下はシーンとカットだけでいいとか、Bはアニメだから話数(EP)とシーンとカットが必要などの変更にはフレキシブルに対応できるのではないかと思ってます。

     と言うか、前回のプロジェクト(凍結したけど)ではこういったデータにアクセスするブラウザからしてなかったので(正確には個人用には作成中だったのですが、決め打ちで作ってしまったため使えなかった)、こういうものがあれば便利かなぁ~、と思った次第であります。


     ま、今のところただの妄想なんですがw

    汎用プロジェクトマネージャ考察1

    ■プロジェクトマネージャ

     Mayaでプロジェクトを運用するときに、ある程度の規模になると必ず必要になるのがファイルマネージャですよね。
     当然各会社によってディレクトリ構造が違うので会社によってそれぞれのマネージャが存在します。また、場合によってはマネージャが存在しない会社もたくさんあります。
     以前ボクがお邪魔してたスタジオでは、完全新規プロジェクトだったこともあり何もありませんでした。ってかそれを作るのがボクの仕事だったんですがw

     しかし、こういったマネージャ関連は作成するにはそれなりの時間を要します。しかも、大なり小なり違いはあれど大体求められる機能は一緒なんですよね。ぶっちゃけ、とりあえず深いディレクトリツリーを効率よく回れれば、あとはデータをシェア領域にリリースする機能さえあればなんとかなるもんですし。(たぶん)
     最近のCG業界ではPythonが共通言語としての役割を果たすようになってきているので、ここで一個Pythonで汎用プロジェクトマネージャを作れば、この先なんかあったときに、とりあえずお茶を濁せるのでは?などと思ってます。(考えが浅いかなぁ・・・)

     業界標準規格ができれば、ひとつのマネージャで全部管理できるんでどこへ行っても戸惑わなくてすむのですが(ここらへんの話は一部の方が提唱されてるみたいですね)、やはり映画のような長尺からショートストーリーやゲームのデモムービー、アニメなど分野によってそれぞれ最適な構造があるのと、日本と言う国の体質上難しそうだなと思うのですが、そこらへんどうなんでしょう。


    ■汎用ディレクトリ構造の定義

     で、汎用となるとプロジェクトによって変わるだろうディレクトリ構造を、ある程度簡単に定義できるようになればそれだけで汎用性ができるのではないかと。
     だいたい、昨今のCG業界でのディレクトリツリーは
    ■エレメント・アセット(キャラやプロップ、背景なんかを格納する)
      -カテゴリ(キャラとかプロップとか)
        -グループ(味方・敵・銃・車みたいな感じ)
          -固有名(キャラの名前、車の名前)
            -バリエーション ←これはここに入れるか、某■みたいにショット依存にするか悩みどころ
              -LOD
    ■シーケンス
      -シーン・カット・ショット ←ここの階層はプロジェクトによって異なる可能性大
        -各カテゴリ(アニメ、カメラ、シミュレーション、エフェクト、ライティングなど)
    大雑把に言うとこんな感じではないかと。個人製作領域となるworkをどこに設定するかが会社によって変わってきそうですが。

     何社か見てきたところエレメントとシーケンスの2種類はほぼ間違いなく存在してるようです。そこから下の管理をどう柔軟に定義するかを管理者が決める・・・こういった流れにすればある程度融通がきくのかな。
     とくに、シーケンス直下はたとえば映画や比較的長尺のムービーなら
      ・シーン/カット/
    アニメやテレビなどの連続ものなら
      ・エピソード/シーン/カット/
    短編なら
      ・カット/
    みたいな感じで結構バラつきそうですよね。別に一番階層の深い「エピソード/シーン/カット/」に合わせてもいいですが、ムービー専門のスタジオで意味もなく毎回エピソード1個分余計に階層を作るのもどうかと思うと、ここから下を定義する必要がありそうです。


    ■階層の定義方法

     問題はどうやって定義するのかです。
      1) テキストに構造を何らかのデータとして記述し、そのデータを参照する。
      2) 同じディレクトリ階層のリファレンスを作成し、その構造を参照する。
     1の場合、ひとつのテキストにすべての情報をぶっこんじゃえば、非常にスマートに行く反面、テキストデータですので、せいぜい階層構造くらいしかデータとして持てないのが欠点です。もちろん特定の挙動と関連付けなどもできますが、するとテキストの中身が非常に複雑になってしまいまいす・・・

     2はディレクトリ構造をどっか別の場所にマスターとして作って、それをツールが見ると言う方法。
     この方法は以前某■にいたときに、エレメント管理ツールの中でやっていた方法なのですが、当時は練り込みが甘く汎用性と言う意味では微妙だったのですが、作ったディレクトリと同じ構造が量産できると言うわかりやすさと、ディレクトリ以外のデータを入れることにより、拡張がしやすいと言う意味ではこちらの方が個人的にはプッシュしたい方法です。
     具体的に言うならばPythonの__init__,pyみたいに、そのファイルがいればPythonはそのディレクトリ全体をモジュールとして見てくれる・・・みたいに、特定の名前のファイルによってディレクトリの意味をツールが解釈するようにすれば、拡張性・汎用性ともに優れたものができそうな気がします。


     なんか長くなりそうなので、実際の具体的な方法は次の記事で。(果たして続くのか? 需要はあるのか?)

    $gMainPane

     3DCGソフトには非常に多くの機能が組み込まれており、それらにアクセスするのにショートカットキーだけでは全然足りないですよね。
     Mayaにはキーボードショートカット以外にホットボックスと言う選択肢もあるのですが、それでも全然足りないです。

     そこでウチでは、キーボードショートカット+マーキングメニューと言う組み合わせを使う事により一気に瞬時にアクセスできる数を増やしております。

    例えば
    マーキングメニュー
    Ctrl + A + 左クリックでアトリビュートやコンポーネントに関するウィンドウを開くマーキングメニューが開き
    アトリビュートエディタ
    Ctrl + Aを押すだけだとアトリビュートエディタが開くと言った感じです。

     これだとひとつのキーボードボタンで最大9種類の機能にアクセスできます(試したら右ボタンはMayaの右クリックメニューがでてしまうので基本左ボタンだけになりそうです)
     Mayaで使用できるキーボードボタンは全部で68種類(たぶん)なので、それにShiftやCtrlを押した時の挙動も加えると
     68×4×9=2448種類の機能に瞬時にアクセスできる計算になります(もっとも設定が若干面倒なので、全部にこんな面倒な仕組みを入れてませんが・・・)


    上記の仕組みは非常に簡単で、例えば上記のCtrl+Aの挙動は
    • Ctrl+AのpressCommandにマーキングメニューを表示するスクリプトを設定
    • Ctrl+AのreleaseCommandにアトリビュートエディタを開くコマンドを設定
    するだけです。
     ただし、マーキングメニューのメニュー内のコマンドを実行すると、グローバル変数か何かにコマンドを実行したことを伝える指示を出し、releaseCommandの方では前述したグローバル変数にコマンド実行の支持があった場合はアトリビュートエディタを開かないようにしておく必要があります。
     もちろん、releaseCommandの方ではpressCommandの方で作ったマーキングメニューを削除するコマンドも入れておきます。

     さて、ここから本題です(超長い前置き・・・)。
     上記のpressCommandでマーキングメニューを作るときに、どこを親にするかが最大の問題になります。
    MoveToolContext(Wキーを押したとき)やRotate、ScaleToolContextは$gMainPane(用はMayaのビューポートの親のレイアウト)を親にしてマーキングメニューを作成してるようなのですが、これだと例えばカスタムで作成したフローティングタイプのビューポート上では使用できません。
     まぁそういうのに目をつむってもいいんですが、一応カスタムウィンドウ上でも動作するようにMaya2011以前のバージョンでは、一度
    string $parent = `getPanel -wf`;
    でフォーカスされたパネルを検出し、これを親にしてマーキングメニューを作成していました。
    ところが!
     Maya2011ではこれでは誤動作を起こします!アクセスできるにはできるんですが、マーキングメニューが3回くらい描画されて非常に使いづらいです。ってかお話になりませんorz

     色々検証してみた結果、どうやら親を上記getPanelで取ってきてたのが悪かったようです。ヲイヲイ、これじゃぁカスタムウィンドウ上じゃぁ動作しねぇじゃねぇかよぉ
    しょうがないので、MoveToolContext同様$gMainPaneを親にしてみたところ、無事普通に動作しました。

     同じようなことをしてる皆様、お気をつけ下さいませ。
    あと、もっとスマートな方法がありましたらお知らせくださると幸いです(^Д^)⊃エヘ
    プロフィール

    Eske

    Author:Eske
    萌えイラストレーターを目指す3DCGイラストレーター。
    現在ポケモンカードゲーム、ガンダムトライエイジ、ガンダムコンクエスト、妖怪ウォッチとりつきカードゲームなどで3DCGを使用したイラストレーターとして参加中。

    主にここでは日々気づいたメモなんかを残してます。
    イラストのお仕事も受け付けております。ココからアクセスできますので、お気軽にご相談下さい。

    最新記事
    最新コメント
    カテゴリ
    最新トラックバック
    月別アーカイブ
    検索フォーム
    リンク
    QRコード
    QR
    上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。