Astro de 3D(5) ~青春の蹉跌 解決編~
2008/06/05 20:55 - Astro
前回は、Papervision3D 的なアプローチを用い、正方形平面6枚を使って立方体を実現しようとするも、孔明の罠に嵌ってZソートが働かず退却の憂き目を見たという話でした。
しかし、こんなこともあろうかとソース中にいろいろなコードを仕込んでおいたのさ。
zsort メソッドの術式を解放。 コメントアウトを消して、trace が機能するようコードを書き換えて今一度コンパイル。
いちいち前回のエントリーに戻ってソースを見るのはめんどくさいので下に再掲しました。
- Main001.as (再掲)
6枚の正方形 Shape には、createCube メソッドのおいて、それぞれ名前を付けています。
その名前と現在の Shape.z プロパティを Event.ENTER_FRAME のタイミングで trace できるようコーディングしていました。 さっそく trace 結果を見てみます。
<trace 結果> back : 50 bottom : 0 left : 0 top : 0 right : 0 front : -50 ----
上記が延々と続きます。いずれの面 Shape も、プロパティ z はずっと同じ値のまま。
createCube メソッドで各面を生成するステップを確認してみます。
面 "back" では face.z が 50、面 "front" では face.z が -50、それ以外の面では face.z を定義していません。つまり 0 になっているということですね。
上記 trace 結果と合致しています。
trace 文を z 座標だけでなく、x、y座標も表示するようにしてもしてみましたが、やはり面オブジェクトの座標値は常に不動です。
<trace 結果> back :[ 0 , 0 , 50 ] bottom :[ 0 , 50 , 0 ] left :[ -50 , 0 , 0 ] top :[ 0 , -50 , 0 ] right :[ 50 , 0 , 0 ] front :[ 0 , 0 , -50 ] ----
つまり親オブジェクトで rotation[X|Y|Z] をいくら実行しようとも、子オブジェクトの座標プロパティには何ら影響を及ぼさないということなのかー。
と、ここでハタと気づきました。
不動だ不動だと言っているのは、3D 表現のための五つの座標のうち、一番最初のローカル座標に着目しているからなんじゃないのか、と。
だったら面オブジェクトの外部で何をしようと座標値が変わるワケがない。 グローバル座標に変換して、その値を参照しないと意味ないじゃん。
てなわけで localToGlobal() の 3D 版みたいなメソッドはあるのかな? と Astro の ASDoc を見てみました。
flash.display.DisplayObject のメソッドとして Flash Player 10 から local3DToGlobal() というメソッドが追加されたとなっています。これだー!!
しかし、ここで再び孔明の罠が発動!
function local3DToGlobal(point3d:Vector3D):Point
local3DToGlobal() メソッドは、引数は Vector3D(三次元座標)ですが、返り値は Point(二次元座標)でした。
使えねー!
今参照したいのはグローバルにおけるz座標なのに、その肝心の値を取得する手段がないことが判明しました。
結局は、三次元変換行列の合成を明示的におこなわなければならない、ということですね。
- 全体を統括する Matrix3D を作って、それに回転を合成
- その全体統括 Matrix3D を各面が持つ Matrix3D に合成する
こういう手順を踏めと。 そう言いたいわけですな。
そんなワケで今回の敗戦の反省の上に立ち、Matrix3D 使用編に移ります。
ところで 3D 表現とは直接関係ないのですが、onEnterFrameHandler メソッドのコメントアウト部を見てください。
このように rootNode.mouse[X|Y] をrootNode.rotation[Y|X] にダイレクトに代入し続けていると、そのうち期待した動きをしなくなることが確認できました(まぁよくよく考えれば当然のことかも知れませんね)。