« 鳩ぽっぽ完結。 | トップページ | 通常ボーン → Implicit Bone なスクリプト。 »

2010年7月19日 (月)

友愛その9。

いつまでやんの。



今回は Self-installing 形式な話になります。

前回とほぼ同じソースです。違うのは、冒頭の赤字の行だけ。


var oProp = ActiveSceneRoot.AddProperty ( "CustomProperty", false, "hoge" );

oProp.AddParameter2 ( "XRes",  siInt4,  1280 );
oProp.AddParameter2 ( "YRes",  siInt4,  720 );
oProp.AddParameter2 ( "Aspect",  siDouble,  1280/720 );
oProp.AddParameter2 ( "LockAspect",  siBool,  true);

var oLayout, oItem;
oLayout = oProp.PPGLayout;

oLayout.AddRow( );
    oItem = oLayout.AddItem ( "XRes", "X" );
    oItem = oLayout.AddItem ( "YRes", "Y" );
oLayout.EndRow( );

oLayout.AddRow( );
    oItem = oLayout.AddItem ( "Aspect", "Aspect Ratio" );
    oItem = oLayout.AddItem ( "LockAspect", "Lock Aspect Ratio" );
oLayout.EndRow( );

//    Logic
oLayout.Language = "JScript";
oLayout.Logic =    XRes_OnChanged.toString( )+
                     YRes_OnChanged.toString( )+
                     Aspect_OnChanged.toString( )+
                     AspectUpdate.toString( )+
                     LockAspect_OnChanged.toString( )+
                     OnInit.toString( );

function XRes_OnChanged( )
{
    if (PPG.LockAspect.value)
    {
        PPG.YRes.value = PPG.XRes.value / PPG.Aspect.value;
    }
    else
    {
        AspectUpdate( );
    }
}
function YRes_OnChanged( )
{
    if (PPG.LockAspect.value)
    {
        PPG.XRes.value = PPG.YRes.value * PPG.Aspect.value;
    }
    else
    {
        AspectUpdate( );
    }
}
function Aspect_OnChanged( )
{
    PPG.YRes.value = PPG.XRes.value / PPG.Aspect.value;
}
function AspectUpdate( )
{
    PPG.Aspect.value = PPG.XRes.value / PPG.YRes.value;
}
function LockAspect_OnChanged( )
{
    if (PPG.LockAspect.value)
    {
        PPG.Aspect.ReadOnly = true;
    }
    else
    {
        PPG.Aspect.ReadOnly = false;
    }
}
function OnInit( )
{
    LockAspect_OnChanged( );
}

InspectObj ( oProp );


前回のはシーンに実体を残さない Property でしたが、今回は以前にその1とかでやったように、冒頭の赤字の部分で ActiveSceneRoot に対して AddProperty の呪文を唱えているので、シーンの中に実体として Property が出現します。

Explorer で見ると実体として hoge があるのがわかります。
Ui_91

実行した結果出てくる PPG はもちろん前回と同じ。
Ui_83
X と Y の連動や、Lock のオンオフで Aspect の ReadOnly が変わるという機能も生きています。


で、この hoge プロパティは実体があるので、シーンを保存すればもちろん一緒に保存されます。

ということでシーンを保存しましょう。
次に新規シーンを実行するとかして一度クリアし、またそのシーンをロードしてみましょう。
はい、hoge が残っていますね。当たり前です。
hoge をダブルクリックするなりして PPG を開けば、PPG の見た目も、XY 連動の機能なども、そのまんま生きてます。当たり前です。


では、XSI を一度終了させましょう。
そしてまた起動しましょう。
同じシーンをロードしましょう。
hoge は残っていますね? 当たり前です。

で、再び hoge をダブルクリックとかして PPG を表示させてみると・・・・
Ui_92
てめえオラ 配置崩れてるじゃねえかよ AddRow でちゃんと並べただろがドルァ


このように、シーンを保存した時点ではちゃんとしていた配置は崩れ、パラメータ1つにつき1行、タテに順番に並んでいるだけになっちまいました。AddRow の呪文でヨコに並べた効果はもはや失われています。 すでに秩序はなく、テロリズムに支配されています。

混乱はそこだけに留まりません。 よく見てみれば、パラメータの名前がすべてスクリプトネームになってしまっています。 スクリプトネームというのは、そのパラメータの本当の名前のことです。 AddParameter の呪文で指定した「本名」です。 スクリプティング的に都合の良い本名を付けた場合、必ずしもユーザにとって分かり易いとは限らないので、AddItem の呪文で UI 上に登録する時に 「本名は "XRes" だけど UI 上は "X" と表示しろ」 などと指定していたわけです。 でも XSI を再起動した後は、この UI 上の名前はどこかに消え失せ、本名表示になってしまっています。 個人情報の漏洩です。

混乱は更に続きます。 XRes や YRes の値をいじってみてください。LockAspect のオンオフを切り替えてみてください。 あんなに苦労して Logic の function を書いて、やっとこさ連動の機能やグレー表示切替の機能を追加したのに、Logic の挙動は消え失せてしまい、値の変更を検知する仕事も、検知後に function の中身を実行する仕事も、全て放棄されています。 賃上げ要求のストライキです。


このように一度 XSI を再起動してしまうと、テロや個人情報のダダ漏れやストが起こり、PPG の社会はその秩序を完全に失います。非常事態宣言です。戒厳令です。夜間外出禁止になり、とても不便です。


ということで、PPGLayout を苦労してあれこれいじっても、それは1セッションの間だけ有効であり、再起動後はもう効果が無いんですね。 1セッションというのは、XSI を起動して終了するまでの間のことです。 もちろん再起動後もちゃんとカスタムプロパティとして機能はしますが、AddRow やら AddGroup やらの配置に関する効果、Logic などの効果を含めて PPGLayout に関する効果は全て失われるのです。そういうもんなんです。


この効果を持続させようとすると、もはや Self-installing 形式の Property にするしかありません。たぶん。

Self-installing 形式ってのは何か、と問われると説明できないんですが、いわゆるプラグイン形式のことです。 今までこの友愛シリーズでやってきたのは、スクリプトエディタから走らせるだけのただのスクリプトです。 これに対しプラグインというのは、XSI の起動と同時に XSI の機能の一部として使えるよう勝手にロードされるものです(合ってるかな?)。  「 自分自身を、XSI の起動時に XSI にインストールして、XSI の機能の一部になる 」 みたいな意味で Self-installing と言うのかなあ、などと勝手に想像していますが実のところはわかりません。 SDKガイドの該当箇所読むのめんどくさいので、誰か代わりに読んで教えて下さい。


では、hoge プロパティを、プラグイン形式にしていきましょう。


いつも俺は、空っぽのプラグイン形式プロパティを作って、後は中身を普通にコーティングしていくのですが、今回は一応、Migrate な方法を書いてみます。既存のプロパティを元にしてプラグイン形式のプロパティを作るというやり方です。

まず、既に存在している hoge の PPG を開き、ウインドウの上の方のすき間で右クリックします。 この右クリックの位置が微妙なので、ちょっと探って下さい。

Ui_93
この赤ワクのあたりを右クリックするのです。
で、Migrate to Self-installed を選びます。

あれ? "Self-installing" じゃなくて "Self-installed" か? 過去分詞が正しい? でも マニュアルとか Wiki で Self-installing と書かれている部分もあるような? よくわかんなくなった。まあいいや。とにかくプラグイン形式ということです。

するとこんなメッセージがが出て、
Ui_94
カスタムプロパティの魔法使いさんがお手伝いしまっせー
既存のプロパティにあるパラメータを、そのまんま新しいプロパティに反映させまっせー

とかなんとか言っているだけなので、さっさとOK押して進みましょう。


ちなみにですが、Migrate の元になるプロパティ hoge は、今回はスクリプトを書くことによって作ったわけですが、別にスクリプトを書かなくても XSI の GUI から作ってもいいわけですね。Animate モジュールに Create > Parameter があるじゃないですか。
Ui_94b
この機能を使ってよくカスタムパラメータ作りますよね。 そうやって作られたカスパラを、今回のように Migrate to Self-installed を使ってプラグイン形式に変換するというのが、おそらく XSI 的に想定されている使い方なんだと思います。 

ただし、GUI からカスパラを作ることはできても、その配置やLogic の挙動を定義する方法は GUI に用意されていません。そこはスクリプトを書くしかないわけです。 この友愛シリーズは配置やら Logic やらの話ですので、どのみちスクリプトを書かねばならず、なら最初からスクリプトを使ってプロパティを作ってしまえ、ということだったわけであります。


話がそれてしまった。
さて、魔法使い(SDK Wizard)が降臨して、こういうウインドウが出てきたはずです。
Ui_95
Property Name のところに、新たに作るカスタムプロパティの名前を入れます。その場限りのスクリプトとは違いプラグイン形式なので、XSI が起動されるたびに呼び込まれ、どのシーンに対してもいつでも使うことができるプロパティを作ることになります。それゆえに他のプロパティと名前がかぶることができません。なので名前はあまりにもテキトーにしない方がいいと思います。

あとは Coding Language でお好きなスクリプト言語を。 俺は JScript しか知りませんが。

あとは、Output Directory か。 プラグイン形式のカスタムプロパティを作るということは、当然そのプロパティの内容が記述されたファイルを作ることにもなるんですが、その書き出し先のことです。 デフォルトだと XSI のユーザプラグインフォルダになってますので、とりあえずそのままでいいんじゃないですか。 Workgroup プラグインとして作成したい場合は、既存の Workgroup のプラグインフォルダを指定すればいいです。

それ以外はまあ、とりあえずほっとけば。 見ればわかるだろうし、わかんなきゃマニュアル嫁。


一応、となりのタブ(Add Parameterタブ)も見てみましょう。
Ui_96
ここで、このプロパティが持つパラメータを定義しています。 上の Define Item グループ内をいじって新しいパラメータを追加してもOKですが、今回の場合は Migrate でやっているので元になるプロパティから既にパラメータをゲットしてきており、下の Pamateter タブの中で見ると、最初のスクリプト内で AddParameter2 の呪文によって定義した XRes とかのパラメータが、すでに登録されているのがわかります。 新たにパラメータを追加したいのでなければ、そのまんまほっとけばいいです。

3つ目のタブ(Layouytタブ)も見てみましょう。
Ui_97
このタブで、まさに PPGLayout に関する操作ができるようになっています。
Group も作れます。つまり AddGroup の呪文を、スクリプトのコードを書くことなく、この GUI の操作で作ることができます。 魔法使いさんが GUI で入力された情報をもとに、勝手に AddGroup の呪文をスクリプトに埋め込んでくれるというものです。 Row も同じことができますね。

しかし。
このウィザード内での Group や Row の操作は超わかりにくいというか、激使いにくいです。 こんな所で頑張らないで、スクリプト内に直接コードを書いてしまった方がずっとラクです。 なのでこのタブはまず使いません。 もっと言えば、さっきの2つ目のタブ(AddParameter タブ)も、俺は全く使いません。 Migrate でやる場合でもそうじゃない場合でも、パラメータを追加したければスクリプトの中で AddParameter2 の呪文を唱えればいいだけですから、何もこんな使いにくい GUI と格闘する必要は全くありません。 ということで俺は、ウィザードの機能は雛形の出力としてしか使いません。


で、一番下の Generate Property ボタンを押すと、実際にプロパティを作るためのスクリプトコードが生成されます。そのコードはすぐに、自動的にスクリプトエディタで開かれます。
Ui_98
こんな感じ。

よく見てみると、ちゃんと AddParameter2 の呪文などが埋め込まれているのがわかります。 スクリプトを書いて作った PPG から、リバースエンジニアリングをしてまたコードを生成したという感じになるのかな? 

ともかく、最初にスクリプトで書いていたその場限りのプロパティが、ようやくプラグイン形式のプロパティに生まれ変わりました。( ゚∀゚)


でもまだやることがあります。

まず、どうやってこのプロパティをシーンの中に出現させるかを説明します。今まではスクリプトエディタからスクリプトを実行することによってプロパティを作り出していたわけですが、もはやプラグイン形式になってしまったので、スクリプトエディタから実行できるコードではなくなっています。 スクリプトエディタで実行ボタンを押しても何も起こらないはずです。

思いつくのは2つの方法。まずは、このプラグイン形式のプロパティを降臨させるためのスクリプトを書くというもの。

ActiveSceneRoot.AddProperty( "hoge_Migrated" );


これを実行してみて下さい。シーンルートにプロパティが作られます。


シーンルートではなく選択したオブジェクトにプロパティをぶら下げたいのであれば、

Selection(0).AddProperty( "hoge_Migrated" );

こう書けばいいです。

hoge_Migrated は既にプラグイン形式のプロパティですので、XSI の中では "hoge_Migrated" という名前が与えられて、どのような場面からでも呼び出せるようになっているのです。なので AddProperty の呪文で、どこへでも召還できます。


冗長な説明になりますが、例をあげると、

ActiveSceneRoot.AddProperty( "rendermap" );

これを実行すれば、シーンルートにレンダーマップのプロパティが降臨します。レンダーマップをやる時に必要なアレです。 そして  "rendermap" という名前のプロパティは XSI の標準装備機能として最初から組み込まれているので、このように名前を呼べばどんな場面でも召還できます。 その rendermap を hoge_Migrated に置き換えただけです。 この例を見ても、hoge_Migrated が rendermap などと同じく、XSI に登録された標準装備機能として扱われているのがわかると思います。 これがプラグイン形式です。


もうひとつの方法は、Plug-in Manager からやる方法ですね。
File メニュー > Plug-in Manager を開き、
Ui_99
もしユーザプラグインとして作ったのならこのように User Root の Plug-ins フォルダを開いていくと hoge_Migrated が見つけられます。ワークグループに作ったのなら、ワークグループフォルダの下の Plug-ins です。
そして右クリックすると Create Property というのが出てくるので、これを選ぶと現在選択中のオブジェクトに hoge_Migrated プロパティが降臨します。 何も選んでいない状態でこれをやると、シーンルートに降臨します。


実際には、こんなめんどくさいことしたくないですよね。
なので、ウィザードの段階で登録先のメニューを指定すれば、例えば Get > Property 以下に出現させることができます。 今回のようにウィザードで登録しなかったとしても、後からスクリプトのコードにメニュー登録の呪文を書けば同じことができます。 これはまたそのうち説明するかもしれません。しないかも知れません。知りません。


で、こうしてプラグイン化したプロパティの PPG を表示させてみると、
Ui_99b
やっぱり配置崩れてるじゃねえかよドルァ
ロジックの挙動も消えてるよオルァ


そうなのです。配置もロジックも死んでいます。 配置に関しては、ウィザードの中で指定をしなかったのでこうなっています。配置情報は、元になっているプロパティから自動で拾ってくれないんです。 ロジックに関しては、そもそもウィザードで指定する方法がありません。配置と同じく元のプロパティから拾ってもくれないので、結局手で書き直すことになります。 まあそんなもんです。


配置から直しましょう。
プラグイン形式になったスクリプトファイルのうち、プラグイン名_DefineLayout( in_ctxt ) となっているファンクションを探します。

function hoge_Migrated_DefineLayout( in_ctxt )
{
    var oLayout,oItem;
    oLayout = in_ctxt.Source;
    oLayout.Clear();
    oLayout.AddItem("XRes");
    oLayout.AddItem("YRes");
    oLayout.AddItem("Aspect");
    oLayout.AddItem("LockAspect");
    return true;
}


ここですね。プラグイン形式のプロパティでは、この function の中で配置に関する記述をするのが基本になっています。

現在の状態は、見ての通り、AddItem の呪文があるだけで、AddRow や AddGroup の呪文はありません。なので付け加えればそれでOKです。


function hoge_Migrated_DefineLayout( in_ctxt )
{
    var oLayout,oItem;
    oLayout = in_ctxt.Source;
    oLayout.Clear();

  
oLayout.AddRow ( );
        oLayout.AddItem("XRes", "X" );
        oLayout.AddItem("YRes", "Y" );

    oLayout.EndRow ( );

   
oLayout.AddRow ( );
        oLayout.AddItem("Aspect", "Aspect Ratio" );
        oLayout.AddItem("LockAspect", "Lock Aspect Ratio" );
   
oLayout.EnddRow ( );

    return true;
}


前にやったのと全く同じように、AddRow と EndRow で囲ってやるだけです。あと、スクリプトネームのままで表示されないように、AddItem の呪文のオプションで表示名を指定しています。


修正後、スクリプトを上書きセーブします。
上書きセーブ後、PPG の上で右クリックし、Refresh してやります。
Ui_910
Migrate の時と同じエリアを右クリックです。

これにより、スクリプトに加えた変更が PPG に反映されます。
Ui_911_2
こうして、プラグイン形式になった hoge_Migrated もめでたく正しい配置になりました。パラメータの名前も、スクリプトネームではなく、指定した表示名になっています。


さあ次にロジックを直しましょう。
と言いたいところですがもう完全にめんどくさくなっているので、今回はここでやめます。
また次回にやります。やらないかも。知りません。


注意しなければならないのは、このように右クリック > Refresh で更新できるのは PPGLayout に関する情報のみ、ということです。 PPGLayout に関する情報=つまり基本的には 「配置関係」 と 「 Logic 」 です。

今回は場合は、hoge_Migrated_DefineLayout( in_ctxt ) このファンクションの中身を書き換えました。 このファンクションの中では配置のこと以外は扱っておらず、パラメータの生成やパラメータの名前決定などは何もしていません。 こういうときは、Refresh さえすれば変更が反映されます。

それに対し、例えばパラメータを追加するなど、そのプロパティの成立に根本から関わる変更を加えたときは、Refresh だけでは反映できません。 パラメータを追加したと仮定します。 しかしこの Refresh という行為はそもそも、既存の PPG をリフレッシュしているだけであります。このプロパティが最初に作られた時点ではまだ新パラメータは存在してなかったわけですから、Refresh しようとしている PPG の中には新パラメータはまだできておらず、それに大して Refresh した所で、新パラメータが現れるはずもありません。

なのでパラメータを追加したり、パラメータの名前を変えたり、パラメータの属性をいじった時などは、一度そのプロパティをシーンから捨てて、また作り直さねばなりません。新たに作り直されたプロパティは、ゼロからそのプロパティを作るので(正確にはそのプロパティのインスタンスを作るので)、変更が加えられたコードを丸ごと読み込むことになります。故にちゃんと変更が反映されます。 今回挙げたやり方で言えば、AddProperty の呪文唱え直すか、Plug-in Manager から右クリック > Create Property をし直せばいいことになります。

今回は配置の部分しかいじってないので、Refresh でOKよ、という所でやめておきます。 次回以降、パラメータに変更を加えたために Refresh だけでは反映させられなくなった時のワークフローを、説明したいと思います。 説明しないかもしれません。 知りません。



ということで、ひとまず配置は直りました。そして一番大事なポイントですが、プラグイン形式になったので、もはや XSI 再起動後でも PPG 内のパラメータの配置は保たれます。 ためしにシーンをセーブして、 XSI を再起動し、PPG を再び開いてみて下さい。 ちゃんと AddRow の呪文でヨコに並べられた配置が生きていると思います。 これがやりたかったんです。そうなんです。





ってことで、

 ・ロジックも修正しなきゃ
 ・パラメータに変更を加えた時の、反映のさせ方

この辺が宿題ということになりますか。

知りません。





ごきげんよう。




.

|

« 鳩ぽっぽ完結。 | トップページ | 通常ボーン → Implicit Bone なスクリプト。 »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック


この記事へのトラックバック一覧です: 友愛その9。:

« 鳩ぽっぽ完結。 | トップページ | 通常ボーン → Implicit Bone なスクリプト。 »