Utils3D.projectVectors で 3D 表現の次なるステージへ(3)
2009/10/30 20:35 - AS3.0
今回はいよいよこのシリーズの本題。 Utils3D.projectVectors を使った遠近表現とZソートについての話です。
前回解説した Matrix3D.transformVector() と、今シリーズの主人公 Utils3D.projectVectors との違いは、一度に一つの三次元座標しか扱えないか、それとも複数の三次元座標を扱うことができるか、という点です。
ここで再び、Utils3D.projectVectors の書式を見てみます。
Utils3D.projectVectors は4つの引数をとります。
第1引数は三次元座標に適用させる変換行列 Matrix3D です。
第2引数は、第1引数の変換行列を適用させる三次元座標群を XYZ の順に一次配列 Vector として格納したものです。
第3引数は、第1引数と第2引数によって得られる変換行列適用後の座標で、第2引数同様、一次配列 Vector です。 ここで注意が必要なのは、第3引数は、XY の順で座標値が格納される、二次元座標であるという点です。
つまり Utils3D.projectVectors はワールド座標をプロジェクション座標に変換するんですが、そうすると困ることがあります。
変換後座標が二次元になってしまうということは、Zソートも遠近表現もできないことになってしまいます。
となると 3D 表現としてはかなり限定的な使い方しかできないわけで、それじゃあ使えないなぁ、と私は思ってしまい、それ以上細かくヘルプを読むことをやめてしまったんですが、それが間違いの元。 ヘルプは最後までちゃんと読め、ってことでした。
ポイントとなるのは第4引数です。
uvts という名称だったので、drawTriangles の同名の引数と同じ目的のものだと思い込んで放置してしまったんですが、この第4引数 uvts は Utils3D.projectVectors メソッド実行後に値が更新されます。
uvt という文字から分かるとおり、これは三次元 XYZ の値を持ちます。 データの格納のされ方は第2、第3引数と同じ。ということは3つ毎にイテレートすればZ座標が得られるということじゃあないですか。
つまり第3引数では失ってしまう変換行列適用後のZ座標は、第4引数 uvts から取得できるわけです。
といっても、Z座標値がそのまま保持されているわけではありません。
どうも、前回説明した遠近表現の公式 1 / (1 + z) に該当する値が保持されていると見做せるようです。 Utils3D.projectVectors 実行前に、Matrix3D に対して appendTranslation(0, 0, OFFSET_Z) を適用していた場合、uvts で得られるZ座標関連値に OFFSET_Z を掛けると、前回説明した Vector3D の w プロパティに格納した値と同機能の値が得られます。 それならストレートに遠近表現に使えるし、Zソートもできる。
先般、wonderfl に投稿されたコードを読んで、Utils3D.projectVectors に対する勝手な思い込みが解けました。 ありがとうActionSnippet の先生! ありがとうカヤック!
なお、Utils3D.projectVectors による 3D 表現の雛形を wonderfl に投稿したので、よろしければご参考にどうぞ。
と、このシリーズはここで話が終わるはずでしたが、新たなる敵が立ちはだかった!
前回、Matrix3D.transformVector() を見ていて、直下に Matrix3D.transformVectors() というメソッドがあるのを発見しました。
最後に s が付いていることから推測できるとおり、いちどきに複数の三次元座標を変換行列に適用させることができるメソッドだそうです。 つまり前回、Matrix3D.transformVector() の欠点として挙げた点がクリアされるわけです変換後のZ座標が得られるわけです。
ってことは今書いたこのエントリーは全くのムダ足? 次回は急遽番外編として Matrix3D.transformVectors について見てみます。
シリーズ
- Utils3D.projectVectors で 3D 表現の次なるステージへ(4)
- Utils3D.projectVectors で 3D 表現の次なるステージへ(2)
- Utils3D.projectVectors で 3D 表現の次なるステージへ(1)