Metasequoia.asをインタラクティブにする方法がわかった。

  • このエントリーをはてなブックマークに追加
  • 0

前のエントリで、インタラクティブにする方法が面倒とか何とか書いたが、単にMetasequoia.asの階層化の時におかしなことをしてるだけだったと気付いた。
もう眠いのでとりあえずちょっとだけ書くが、parseFace関数で、

ActionScript

  1. face = new Triangle3D(this, [a, b, c], material, [uvA, uvB, uvC]);

としてるところが悪いと判明。何箇所かある。悪いのはthis。

parseFace関数は、頂点群からTriangle3Dを作ってるんだが、Triangle3D#instanceの値が、上記の書き方だと常に最上位のオブジェクト(=ファイル全体)となる。InteractiveScene3DEventの当たり判定で、イベントをディスパッチする時に取得するDisplayObject3DのインスタンスがこのTriangle3D#instanceの値になるので、どこをクリックしても最上位になっちゃってるんだとわかった。
つまり、こうするべき。

ActionScript

  1. face = new Triangle3D(obj, [a, b, c], material, [uvA, uvB, uvC]);

objは元々無いので、parseFace関数の引数としてもらうようにする必要がある。
で、parseObjectChunk関数からparseFace関数を呼びつける時に、

ActionScript

  1. parseFace(obj,...);

とする。こうすることで、クリック位置のオブジェクトがイベント時に最上位オブジェクトではなく対象となるチャンクのオブジェクトのみが上手に拾われてくれる。

あとは、イベント設定をしやすいように、

ActionScript

  1. public function getObjectByName(name:String):Metasequoia {
  2.     //自分の直下の子に該当するオブジェクトが存在するかどうか検索
  3.     var obj:Metasequoia = this.children[name] as Metasequoia;
  4.     if ( obj ) {
  5.         return obj;
  6.     } else {
  7.         //ない場合、子孫を探索
  8.         for (var n:Object in this.children) {
  9.             var mqo:Metasequoia = this.children[n] as Metasequoia;
  10.             if ( mqo ) {
  11.                 var obj2:Metasequoia = mqo.getObjectByName(name);
  12.                 if ( obj2 ) {
  13.                     return obj2;
  14.                 }
  15.             }
  16.         }
  17.     }
  18.     return null;
  19.    
  20. }

みたいな関数をMetasequoia.as内に定義しておけばよい。この場合、子オブジェクトもMetasequoiaクラスである必要がある。

眠いのでちょっとだけと思ったら、ほぼ全部書いた。

スポンサーリンク
スポンサーリンク
  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク
スポンサーリンク