Metasequoiaクラスをインタラクティブにするには、「インタラクティブにイベントを受け取るためだけのMaterial」を作らなきゃダメかも

このエントリをはてなブックマークに追加このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加このエントリをkwoutに追加
2008年2月20日 水曜日1:52:14
さて、人々の弛まぬ努力により、ついにMetasequoia.asに「オブジェクト別読み込み機能」と「インタラクティブ機能」が実装されたわけだが、実はこの2つの機能は全く相反する、というか矛盾する機能なのでは?と気付いた。



なんて感じで、Viewport定義の際にinteractiveプロパティをtrueにして、イベントリスナーを登録したい DisplayObject3Dインスタンスに与えるマテリアルのinteractiveプロパティをtrueに。この状態で DisplayObject3DインスタンスにaddEventListerすればいいと。
note.x | [Papervision3D2.0] InteractiveScene3DEvent
等を見ながら俺も手元のMetasequoia.asを改造してInteractiveScene3DEventの勉強をしつつ、ここをパクってMetasequoiaにインタラクティブ機能を付けてみた。これで、「右腕をクリックしたらネギをブンブン振るミク」が作れる!!

と思ったんだが、・・・

ここでInteractiveScene3DEventが、モデルの一番のレベルにしか働かないという問題が発生。要するに、InteractiveScene3DEventを受け取って処理する場面で、
private function interactiveMouseEventHandler(evt:InteractiveScene3DEvent) {
    var mqo:Metasequoia = evt.displayObject3D as Metasequoia;
}
とやっても、取れるのはいつも最上位オブジェクトだった。俺としては、クリックした部分のモデルがダイレクトで来て欲しかった(例:右腕クリック→右腕オブジェクト)のに~!

でもまぁ、冷静に考えてみれば、モデルをオブジェクト別に読み込んでても、肝心のマテリアルはloadを呼び出したMetasequoiaオブジェクト、つまりモデル全体にしか登録してないからなぁ。木構造的に見て子孫となる、mqoファイル内の各オブジェクト毎にイベントを拾うってのは無理があるか・・・。
てか、都合よく考えすぎてた。俺夢見てたよ。

かと言って子オブジェクト全部にMaterial設定するのは面倒だし、試してないけど処理が重くなりそうな気もするし、それに明らかに無駄だからイヤだ。試したくない。

個人的には、Metasequoiaクラスに
public function addEventListernByName(name:String , type:String , callback:Function) {
    var target:Metasequoia = /* 名前がnameになってる子を探してくる処理 */;
    target.addEventListener(type , callback);
}
てな感じのメソッドを定義して、使う時は
var mqo:Metasequoia;
・・・
mqo.addEventListenerByName("right_arm" , InteractiveScene3DEvent.OBJECT_CLICK , swingNegi);
このようにすると対象となるオブジェクト部分にだけ上手いことイベントが登録されるみたいなのが理想。で、この理想をかなえるためには、InteractiveScene3DEventを発生させるためだけの、透明でかつモデルをキッチリ覆うようなMaterialが必要なんじゃないかな?と思った。ただ、PV3Dがどんな仕組みで立体モデルへのマウスでのアクセスを検知してるのかわからないので、透明でも大丈夫なのかは微妙なところ。要実験。

3 件のコメント »

  1. こんばんは。
    引用していただいたウチのデモは、

    private function mouseOver(event:InteractiveScene3DEvent):void
    {
    Tweener.addTween(
    event.displayObject3D,
    { y:50, time:0.6, transition:"easeoutelastic"}
    );
    }

    とかいう感じで処理してます。
    「event.displayObject3D」で、イベントが発生したdisplayObject3Dインスタンスを取得してるんですけどこの方法じゃダメですかね。

    コメント by rect — 2008年2月20日 水曜日 @ 2:15:02

  2. あぁ、ゴメンなさい。それじゃダメだったって書いてあるのに何を言っているのかオレは…。ただ、ウチのデモも複数のCubeを空のDisplayObject3DにaddChildして階層化した上で上記の記述をして、クリックしたCubeだけが反応してます。マテリアル定義も1つです。

    コメント by rect — 2008年2月20日 水曜日 @ 2:34:31

  3. >rectさん
    おかげさまで、何とかインタラクティブにする方法を調べられました。
    マテリアル定義も1つに出来ました。
    色々とお手数かけて申し訳ありません。

    コメント by 太郎 — 2008年3月5日 水曜日 @ 2:55:59

トラックバック URL :

コメントをどうぞ

HTML convert time: 0.539 sec.