Metasequoia.asをインタラクティブにする方法がわかった。
前のエントリで、インタラクティブにする方法が面倒とか何とか書いたが、単に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;
}
//自分の直下の子に該当するオブジェクトが存在するかどうか検索
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クラスである必要がある。
眠いのでちょっとだけと思ったら、ほぼ全部書いた。
カテゴリ:ActionScript | Papervision3D




多分、最初に this を引数として渡した人は自分です。すみません…。
コメント by nondelion — 2008年2月29日 金曜日 @ 6:36:58
>nondelionさん
いや、俺自身が階層化を実装した時に気付くべき場所だったわけで、完全に俺のミスです!
悪いのは全部俺です!
コメント by 太郎 — 2008年3月3日 月曜日 @ 0:49:21