« GUID でストーク。 | トップページ | 淫さま。 淫スタンスなプラグイン。 »

2008年6月18日 (水)

ClassID でもストーク。

                  
先日の GUID でストーク。 の記事でまたまた有り難い情報を頂きまして、さらに実験してみました。
      
      
以下をコピーしてスクリプトエディタに貼り付けるか、このファイルをダウンロードしてスクリプトエディタで開いて、実行。
      
                                                              
//Yes_Stalker5_GoGo.js
            
// ****** カスタムプロパティ作成
var oCProp = XSIFactory.CreateObject('CustomProperty');
oCProp.name = 'ストーカー ~ あなたを絶対逃がさない ~';
            
// ****** カスタムプロパティにパラメータ作成
oCProp.AddParameter3('sGUID',siString,'');                  //GUIDパラメータ作成
oCProp.AddParameter3('sCLSID',siString,'');                             //CLSIDパラメータ作成
oCProp.AddParameter3('sName',siString,'','','',false,true); //元の名前パラメータ作成
            
// ****** カスタムプロパティのUI 作成
var oLayout = oCProp.PPGLayout;
oLayout.AddItem('sGUID','GUID');                                                          //GUID パラメータを UI に追加
oLayout.AddItem('sCLSID','CLSID');                                                       //CLSIDパラメータを UI に追加
var oItem = oLayout.AddButton('GetGUID','GUID と CLSID取得。'); //ID取得ボタン作成(ボタンにはパラメータは無い)
oItem.SetAttribute(siUICX,300);                                              //ボタンの横幅(ピクセル)
oLayout.AddItem('sName','(元の)名前');                                 //元の名前パラメータを UI に追加
oLayout.AddSpacer(0,10);                                                   //すき間空けただけ
oItem = oLayout.AddButton('Stalk','ストーク。');                            //ストークボタン作成(ボタンにはパラメータは無い)
oItem.SetAttribute(siUICX,300);                                            //ボタンの横幅(ピクセル)
            
// ****** ボタンに機能割り当て
oLayout.Logic = GetGUID_OnClicked.toString()+
               Stalk_OnClicked.toString();
oLayout.Language = 'JScript';
            
// ****** ID取得ボタンをクリックした時に実行されるルーチン
function GetGUID_OnClicked()
{
    if (Selection.count !=0)
    {
        // ****** 選択中のオブジェクト(最初の1個)から GUID と CLSID をゲット
        var oDataRep = XSIUtils.DataRepository;        //DataRepositoryオブジェクトを取得(IDにアクセスするため)
        GUID = oDataRep.GetIdentifier( Selection(0), siObjectGUID ) ;     //GUID取得
        CLSID = oDataRep.GetIdentifier( Selection(0), siObjectCLSID);                //ClassID取得
       
                    // if ( Selection(0).type == "customparamset")
                    // 上のように type で 特定しようとすると、Self-installed 形式のプロパティが customparamset として
                   // 認識されない模様。 従って、下のように、classname を使うと、全てのカスタムプロパティ
                   // (上記 type == "customparamset" でヒットするものも含む)がストークできますた。
            
            
        if (classname(Selection(0)) == 'CustomProperty')
        {
            CLSID = '{76332571-D242-11d0-B69C-00AA003B3EA6}';
        }
       
                     //    一方、Custom Operator の方は・・・・
                    //    classname で CustomOperator とすると、Self-installed オペレータだけでなく、
                   //    普通のスクリプトオペレータもヒットする(当たり前か)。
                    //    しかし、普通のスクリプトオペレータと Self-installing カスタムオペレータ を
                   //    ひとくくりに {72936430-9B0C-4167-8CA7-C30FC2188BB9} としてしまうと
                    //    ストークした時に普通のスクリプトオペレータの方だけ引っかかってくれない。
                    //    なので、
                   //
                    //       1:Self-installing カスタムオペレータの type は、常にオペレータの名前になっているっぽい
                    //       2:普通のスクリプトオペレータの type は、常に ScriptedOp ( = siScriptedOpType) になっているっぽい
                   //
                    //    この2点を利用して、
                   //
                    //        Classname が CustomOperator であり、
                   //        かつ type が siScriptedOpType ではない = それは Self-Installed カスタムオペレータである
                    //        従って CLSID に {72936430-9B0C-4167-8CA7-C30FC2188BB9} を授けよう
                   //
                    //    としたら↓上手く行っているように見えます。
            
            
        if (classname(Selection(0)) == 'CustomOperator' && Selection(0).type != siScriptedOpType)
        {
            CLSID = '{72936430-9B0C-4167-8CA7-C30FC2188BB9}';
        }
       
        PPG.sGUID.value = GUID;                                      //GUIDパラメータに、さっきゲットした GUID の値をぶち込む
        PPG.sCLSID.value = CLSID;                     //CLSIDパラメータに、 さっきゲットした ClassID の値をぶち込む
        PPG.sName.value = Selection(0).fullname;    //名前パラメータに、現在の名前をぶち込む
    }
    else    //何も選んでないくせに ID 取得ボタンを押すアフォな人に向けたメッセージ
    {
        var Msg = XSIUIToolkit.MsgBox('つけまわす人を選んどけっての。( ゚Д゚)オラ!',siMsgOkOnly,'ストークする気あんのかゴルァ');
    }
}
            
// ****** ストークボタンをクリックした時に実行されるルーチン
function Stalk_OnClicked()
{
    if (PPG.sGUID.value != '' && PPG.sCLSID != '')
    {
        //    FindObjects コマンドを使って、シーン中 Class ID が一致するものだけを oFindColl に格納 (XSICollection)
        var oFindColl = FindObjects( null, PPG.sCLSID.value );
        var oDataRep = XSIUtils.DataRepository;
        Flag = 0;                                           //発見フラグ初期化
        for (var i=0; i<oFindColl.count; i++)
        {
            //oFindColl の中身をループ。ひとつずつ GUID の値を変数 CurrItemGUID にぶち込む
           CurrItemGUID = oDataRep.GetIdentifier( oFindColl(i), siObjectGUID ) ;
            
                        //    すでに Class ID が一致するものだけに絞り込まれている。後は GUID が一致すれば桶。
                        //    でもこれって、FindObjects コマンドが Class ID だけじゃなくて、
                       //    直接 GUID を受け付けてくれればもっと楽なんじゃなかろか?
            if (PPG.sGUID.value == CurrItemGUID)
            {
              Flag ++;                              //    発見フラグ勃起 ピコーン
              SelectObj(oFindColl(i));                      //    選ぶ
              InspectObj(oFindColl(i));        //    表示する
              CenterSelection(null,true);    //    ビューの中央に持ってくる
              FrameSelection(null,true);    //    しかも寄る
              Msg = 'みーつーけーたーわーよー   ヽ(°▽、°)ノエヘヘヘヘ';
               
               //    名前が変わっていた場合
              if (oFindColl(i).fullname != PPG.sName.value)
              {
                   Msg += '\r\n\r\n' + '名前を変えても無駄よう~   ヽ(°▽、°)ノ ケケケケケケ';
                   Msg += '\r\n\r\n' + '元の名前 = ' + PPG.sName.value;
                   Msg += '\r\n'     + '今の名前 = ' + oFindColl(i).fullname;
              }
              else
               {
                   Msg += '\r\n\r\n' + oFindColl(i).fullname;
               }
              var Msg = XSIUIToolkit.MsgBox(Msg,siMsgInformation ,'ストーク成功。');
              break;
            }
        }
        if (Flag == 0)  //発見フラグが立たない=死亡。
        {
            var Msg = XSIUIToolkit.MsgBox('・゚・(つД`)・゚・  どこへ行ったのっ !!!',siMsgCritical,'あなたの大切な人は死にますた。');
        }
    }
    else    //ID を取得してないのにストーク。ボタンを押すアフォな人に向けたメッセージ
    {
        var Msg = XSIUIToolkit.MsgBox('つけまわす人を決めとけっての。(#゚Д゚)ドルァ!!',siMsgExclamation,'ストーク する気あんのかゴルァ');
    }
}
            
InspectObj(oCProp,null,null,siLock);
            
            
      
前回のスクリプトでは ActiveSceneRoot.FindChildren としていましたが、前回も書いたとおり、このメソッドは X3DObject に対するメソッドであり、返ってくる値も X3DObjectCollection です。 つまり、ストーク対象が3Dオブジェクトに限られるわけで、3Dオブジェクトではない Group やら Pass やら Visibility(プロパティ)やらなんやらは、せっかく固有の GUID を持っているのにストークできないことになります。もしこういう人たちを好きになってしまったらどうすればいいのでしょう。 ストークできないなら死んだ ほうがマシです。
      
というのが問題だったわけですが。
      
      
有り難き情報を元に、頂いたスクリプトを若干いじってこのようにしました。
      

Yes_stalker5_gogo_ppg

要は、FincChildren メソッドの代わりに、FindObjects コマンドを使えばいい、ということですよね?
ね? ね? そういうことですよね? 勘違いしてませんよね?
      
FindObjects コマンドの説明は、以下(SDKマニュアルよりコピペ)。
----------------------------------------------------------------------------------------
      説明
      
オブジェクトをタイプで検索します。
      
      スクリプト構文
      
      
        FindObjects ( [Path],  [Type] )
      
      パラメータ       
                                                                                                                                                                                                              
 
            
パラメータ
            
            
            
            
説明
            
            
Path
            
            
String             
            
            
オブジェクトのパス名(実装されていません)
            
            
Type
            
            
String             
            
            
オブジェクトのクラスID。このGUIDは、各オブジェクトのタイプをユニーク に識別します。たとえば、Phongシェーダの各インスタンスは同じクラスIDを持ちます。このIDはLambertシェーダのIDとは異なります。クラ スIDは、SPDLファイルのReference行またはDataRepository.GetIdentifierか ら特定できます。
            
      
      
      

戻り値

      

検出されたオブジェクトを持つXSICollectionオ ブジェクトを戻します。

----------------------------------------------------------------------------------------
      
      
1つ目のパラメータが「実装されていません」ってのが謎というかアフォですが。
      

で、どうやらこのコマンドは、シーンの中から、指定した ClassID を持っている人を探してくれるらしい。 ならば、先にストークしたい人の ClassID をゲットしておいて、実際にストークする段階でこの FindObjects コマンドを使ってその ClassID を持つ人だけに絞り込み、その中から GUID が一致する人を探せばいいということですよね? ね? ね? そういうことですよね? 勘違いしてませんよね?
      
FindChildren メソッドは X3DObject に限られるのに対し、FindObjects は ClassID という、X3DObject 以外の人たちでも必ず持っている ID を元に検索をかけるので、あらゆるものが検索対象になり、結果も X3DObjectCollection ではなく XSICollection として返してくれる、とゆーことだと理解しました。 ね? ね? そういうことですよね? 勘違いしてませんよね?
      
でも、上記スクリプトのコメントの中にも書きましたが、もしこの FindObject コマンドが ClassID だけではなく GUID を受け付けてくれれば、いちいち絞り込みすることなくいきなり FindObjects(null, GUID); ってやれば一発で1つのものを特定できるような気がするんですが、どうですかね。 その場合、ヒットするものは唯一無二の物のはずなので、戻り値は Collection じゃなくて SceneItem になるのかな?  ま、現在このコマンドはそういう仕様になっていないのでダメなわけですが。
      
      


それと、これも上記スクリプトの中のコメントに詳細を書いていますが、Self-Installed 形式のプロパティだけは Type == "custompset" で識別できませんでした。 Self-Installed 形式ではなく、シーンの中で手動で作ったカスタムプロパティはこれで認識できましたけど。 なので Type をやめて Classname == "CustomProperty" を使ってみたら、Self-installed もそうじゃないのもちゃんとストークできました。ううむ。これでいいんだろうか。
      


一方、カスタムオペレータの方は・・・。
      
SDK Explorer などで見てもわかりますが、Self-Installed 形式のカスタムオペレータも、Self-Installed 形式ではない通常のスクリプトオペレータも、 Classname は CustomOperator になっています(下の画像線)。
      

Customopclassnameortype


しかし、これを利用して Classname == "CustomOperator " とくくってしまうと、後で FindObjects コマンドでストークした時に、通常のスクリプトオペレータの方だけが引っかかってくれません。つまり通常のスクリプトオペレータの ClassID は{72936430-9B0C-4167-8CA7-C30FC2188BB9} ではない、ということになると思います。 ううむ。なんでですか。
      
そこで他に両者の違う点を探してみると、Classname は同じ CustomOperator でも Type は違っていることに気づき(上の画像の黄色線)、カスタムオペレータを作る別のプラグイン(デュアルQとか)で試しても常にこの結果になるように見えたの で、判別するときに Classname だけでなく Type も併用することにしました。すると、ちゃんとストークできるようになりました。 ううむ。これでいいんだろうか。
      
と、なんだか暗中模索状態ですが、ともかく前回のように3Dオブジェクトに限定されるようなことはなくなったので、進歩したと思います。氏に感謝いたしま す。
      
でも基本的にシロートが十分とは言えない質と量で実験した結果をもとに書いていますので、何かとんでもない落とし穴や勘違いがあるかもしれません。そうい う場合は是非指摘して下さい。
      
      
      
      
      

|

« GUID でストーク。 | トップページ | 淫さま。 淫スタンスなプラグイン。 »

コメント

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: ClassID でもストーク。:

« GUID でストーク。 | トップページ | 淫さま。 淫スタンスなプラグイン。 »