SimpleZSorter
2008/11/07 21:50 - Astro
本日、あるひとつのエントリーが、あたかも燎原の火の如き凄まじい勢いで Flash 使いの人たちのブックマークを駆け巡りました。
- Flash Player 10 Z-Sorting Class ( from TheFlashBlog )
このエントリーは、ご覧のとおり、FlashPlayer10 のネイティブ 3D にZソートを付加するクラスを公開する、というものです。
ネイティブ 3D いいよねー、でもZソートを自前で実装しないといけないからメンドいよねー、というのが大方の意見でしょう。
でもこの SimpleZSorter があればもう安心。 何の憂いもなく DisplayObject.z や DisplayObject.rotation[X|Y|Z] が使いたい放題さ。
早速試してみたサンプルはコレ(要 Flash Player 10)。
ところで皆さんは FP10 ネイティブで 3D 表現をしようとする場合、オブジェクトの構造はどうしますか?
私は Papervision3D でお馴染みの、ルートノードを一つ作って、それの、子オブジェクトとして複数の表示オブジェクトをぶら下げる、という階層構造をネイティブでも採りたい派です。
でもって、表示オブジェクト群を動かしたいときは、ルートノードだけを回転させることで、すべての表示オブジェクトを動かすという手法を採りたい派です。
ところがネイティブでこれをやろうとした場合、Zソートをどのように実装して良いのか分かりませんでした。
仕方なく全ての表示オブジェクトひとつひとつに対して Matrix3D.transformVector で現在座標を計算し、そのZ座標でソートするという、なんとも面倒くさい手法で実装していました(ここいらへんは「Astro de 3D」シリーズで詳述してあります)。
しかしこの SimpleZSorter なら何とビックリ。 たった1行だけで Papervision3D の階層構造および回転方法がおこなえます。 ステキ。
SimpleZSorter.sortClips(ルートノード);
しかも親と子の2階層だけでなく、孫階層、曾孫階層と多重階層構造を採っていてもオッケーっぽい。 ますますステキ!
さて、一体オレのどこがダメだったのかコードを覗いて見ました。
なるほど。DisplayObject.transform.getRelativeMatrix3D() というメソッドを使えば、表示オブジェクトの Matrix3D を取得できたんですね
ところでこのクラスは、Zソートを以下のコードで実現しています。
Array.sortOn("screenZ", Array.NUMERIC | Array.DESCENDING);
私もかつて、上記コードでZソートを実装するということを書いたことがあります。 しかし今見たとおり、FP10 ではこの screenZ という変数は DisplayObject から直接取得できることが分かりました。 ならば screenZ をいったん待避する必要はありません。
そして sortOn() ではなく sort() でZソートが可能です。 なぜ sortOn() ではなく sort() を…… と言うかというと、Vector は sort() だけで sortOn() がないからです。
このあたりは、以前、「Astro ビルトインによる 3D 表現の模索(3)~Zソート<2>~」というエントリーで書いたことがありますが、せっかくの FlashPlayer10 require なら Array ではなく Vector を使った方がそれっぽいですよね(まぁ Vector の速度がどうなのかということを以前検証したことがありますが、とりあえず不問ってことで)。
このアルゴリズムは 旧時代(AS2)のものです。 温故知新とも言いますが、新しい時代には新しい時代のモードというものもあります。
てなわけで、SimpleZSorter にそこいらへんの改変を加えてみました(ソース内の SimpleZSorter2 がそれ)。 この方法だと SimpleZSortVO が不要になります。
でも、オリジナルの SimpleZSorter よりも、この Vector.sort() による改変版の方が遅かったらバカ丸出しですね。
ソースに SimpleZSorter.as、SimpleZSortVO.as、BoxSprite.as は同梱していません。 本家から取得してください。