前のエントリで、インタラクティブにする方法が面倒とか何とか書いたが、単にMetasequoia.asの階層化の時におかしなことをしてるだけだったと気付いた。
もう眠いのでとりあえずちょっとだけ書くが、parseFace
関数で、
- face = new Triangle3D(this, [a, b, c], material, [uvA, uvB, uvC]);
としてるところが悪いと判明。何箇所かある。悪いのはthis。
parseFace
関数は、頂点群からTriangle3Dを作ってるんだが、Triangle3D#instance
の値が、上記の書き方だと常に最上位のオブジェクト(=ファイル全体)となる。InteractiveScene3DEventの当たり判定で、イベントをディスパッチする時に取得するDisplayObject3DのインスタンスがこのTriangle3D#instance
の値になるので、どこをクリックしても最上位になっちゃってるんだとわかった。
つまり、こうするべき。
- face = new Triangle3D(obj, [a, b, c], material, [uvA, uvB, uvC]);
obj
は元々無いので、parseFace
関数の引数としてもらうようにする必要がある。
で、parseObjectChunk
関数からparseFace
関数を呼びつける時に、
- parseFace(obj,...);
とする。こうすることで、クリック位置のオブジェクトがイベント時に最上位オブジェクトではなく対象となるチャンクのオブジェクトのみが上手に拾われてくれる。
あとは、イベント設定をしやすいように、
- public function getObjectByName(name:String):Metasequoia {
- //自分の直下の子に該当するオブジェクトが存在するかどうか検索
- var obj:Metasequoia = this.children[name] as Metasequoia;
- if ( obj ) {
- return obj;
- } else {
- //ない場合、子孫を探索
- for (var n:Object in this.children) {
- var mqo:Metasequoia = this.children[n] as Metasequoia;
- if ( mqo ) {
- var obj2:Metasequoia = mqo.getObjectByName(name);
- if ( obj2 ) {
- return obj2;
- }
- }
- }
- }
- return null;
- }
みたいな関数をMetasequoia.as内に定義しておけばよい。この場合、子オブジェクトもMetasequoiaクラスである必要がある。
眠いのでちょっとだけと思ったら、ほぼ全部書いた。