Flash3D/操作の対象
3Dエンジンが行う操作
前回、Papervision3Dのファイル構成を展開して全体像を何となく掴んでみましたが、さて、その内のどこから詳しくみていけばこの一連の仕組みが理解できるでしょう。とりあえず、基本に立ち返って、3Dエンジンが何を行うのか考えてみましょう。
ここでいう3Dは「幅」、「高さ」、「奥行き」の3つのパラメーターをもった立体空間を表現するものです。ですので3Dエンジンがまずできなくてはならないことは、3つのパラメーターを制御することにあります。
しかし、実際にはPCやスマートフォンのディスプレイは平面ですので、立体物を表現することはできません。そこで3D空間を2Dの平面空間に「投影」することで擬似的に3Dを表現する手法が多くとられます。この「投影」という作業が次に3Dエンジンがやらなくてはならないことです。
2D座標に投影された擬似空間を制御するのも3Dエンジンの仕事です。「奥行き」が消えて、「幅」、「高さ」になった2つのパラメータを制御することになります。
それではまず、制御の対象となる3Dと2DがPapervision3Dでどのように表現されているのか調べてみることにしましょう。
2つのパラメーターと3つのパラメーター
2次元や3次元を表すには、実数がそれぞれ2つ、3つ必要ですが、ActionScript3ではそんなクラスは用意されていないようです。なので、Papervision3Dには org.papevision3d.core.math.Number2D と org.papevision3d.core.math.Number3D というクラスが定義されていました。名前から想像がつきますが、実数を表現するNumberクラスを複数持っているクラスです。
それぞれプロパティに「x,y」「x,y,z」というNumberを持っているので、この値がこのクラスの実体になります。
ActionScript3では演算子のオーバーロードができないため、これらのクラスを足したり引いたりするためのメソッドも定義されています。また、このクラス特有の計算メソッドがあります。
何が表現されるのか
2つまたは3つの数を使って表現することができるものがいくつかあります。
まず、座標の中で原点との相対距離をそれぞれの数値にあてはめると「位置」を表現できます。これは物体がどこにあるのかを明確にするのに有効です。また、原点を含め、「点」という0次元のオブジェクトを表現することもできます。さらにベクトルに数値をあてはめれば「向きと強さ」を表現でき、幅や高さ(そして奥行き)に数値を当てはめれば、「長方形や直方体」といった物体を表現できます。
3Dエンジンで表現しようとするものは、およそ「点」の集合でできていますから、その集合の「位置」を示してやればスクリーンに描画できてしまいます。また、その点の集合が移動や回転するアニメーション(運動)も「向きと強さ」を計算すれば表現できます。なお、アニメーションではそれに加えて時間軸という4つ目のパラメータも意識されますが、その辺は必要に応じて考えましょう。
表現の置き換え
2つまたは3つの実数でいろいろ表現できるのはわかりましたが、x,y(,z)座標の値以外にもそれらを表現する方法はあります。例えば、「原点からの角度」と「原点からの距離」で「点」や「位置」を表現することもできます。「向きと強さ」というのはそのまんま角度と距離に置き換えができますね。3次元の点や位置の場合は2つの「角度」と1つの「距離」で表現されます。
この表現方法の置き換えのためのメソッドも用意されて・・・いるっちゃいるようです。Number2Dクラスでは「modulo」と「angle」というメソッドでそれぞれ距離と角度が求められ、Number3Dでは「modulo」で距離が求められます。
操作の内容
実際にNumber2DやNumber3Dであらわされる「点」に対しての操作は「平行移動」、「回転」、「距離の拡大縮小」の組み合わせで行われます。平行移動は「位置」の足し算、引き算で表現されます。「距離の拡大縮小」は掛け算、割り算でできそうです。「回転」は三角関数を使う必要がありますが、角度を指定すれば計算してくれるメソッドが用意されていました。
「ベクトル」を表すときのための操作には、normalizeなんていう処理がありました。これは「向きと強さ」のうち「向き」だけを便利に使うために「強さ」を1にしちゃう処理ですね。強さを1にしておくと、向きだけ変えたいときに掛け算しても強さが変わらなくて済むので便利なんでしょうね。あとはcrossっていう外積(クロス積)を求める処理やdotっていう内積(ドット積)を求める処理がNumber3Dクラスにみつかりました。内積と外積のことをしっかり理解していないのですが、ベクトル同士がどのくらい似ているか、どのくらい違っているかの目安になるんだそうですよ。きっと便利なのだろうなくらいの認識で留めておきます。
Molehillではどうなるの?
こういった基本的な3Dに関するクラスは新しいFlashの3D用のAPI(Molehill)ではどんな扱いになるのでしょう。2011年2月末に開発者向けにFlashPlayerやswcファイルが公開されたようですが、APIのリファレンスがどこにあるのかわからないので、ちゃんと調べてないです。Number2DやNumber3Dのようなクラスは自分で用意する必要はなくなるのかな〜って思ってます。
(追記)
Molehillの資料が見つかったので、ちょろっと眺めてみました。
「flash.display3D」っていうパッケージの中に機能がまとまっているみたいですね。
VertexBuffer3Dというクラスがあったので、点の集合を表現するのはこれかな〜って思いました。パッケージの中のクラス名を眺めていて、はたして自分のやりたいことができるのか心配になってきた次第です。低レベルな部分をGPUに投げて高速化する都合上、できないこともあるかもしれませんね〜。必ずしも3Dのことを知らなくてもある程度できちゃうのかも。Papervision3Dのソースを眺めて、3D表現のことをおさらいするという企画自体があんまり意味なかったりして。