飴屋

Flash3D/点の集合

点は0次元

2D平面、3D空間上では点は2つ、または3つの実数で表現されることがわかりました。また、その数字を操作して点を移動できることもわかりました。しかし、点そのものには幅も厚みも高さもありませんので、それ単体ではスクリーンに何も表現できません。点はいくつか集めて使うもののようです。確か学校で「点は0次元」と教わった気がします。その点が横にいくつも連なって1次元の線を構成し、線が縦にいくつも連なって2次元の面を構成し、面が奥にいくつも連なって3次元の立体を構成すると、そんな風に習った気がします。

それではまずは点をたくさん集めて線を作ってみましょう。10cmの線を構成するのにはたしていくつの点が必要でしょう。はい、どんなにたくさん点を並べてもどうしても点と点の間に別の点を入れる隙間があるので、点をいくら集めても線になりませんでした。仮に何億個か点を並べて擬似的に線を表現できたとしても、何億回も行列の計算をしないと線を移動する操作ができないのでは現実的ではありません。なので、線分を表す時には二つの端点のデータだけ持っておいて、中間の点のことは考えないでおくことにします。この3D空間上の端点を2D平面座標に投影してから、間に線をひいてやると線を構成する点の集合全ての点の座標も正しく投影されてくれるのでした。とにかく線分は二つの点の座標で表現できることがわかりました。

二つの点で線分を表せるのなら、平面はどうしましょう。例によって無限に線分を並べるわけには計算機の都合上できかねますので、一番少ない数の線分で最小限の平面を構成して、複雑な平面はその最小限の単純な平面を組み合わせて作るしかありません。線分を連結させて輪を作ると多角形という面ができますので、一番少ない線分でできる多角形の三角形が単純な平面に適しているようです。三角形は3つの点、3つの線分でできているので、取扱いも簡単です。

こうして同じように3次元にも拡張していくと立体を表現するのには四面体を単純な要素と考えて、これをくっつけて複雑さを表現するのがよさそうです。四面体は4つの三角形、6つの線分、4つの点でできています。

ポリゴン

少ない点で立体を表わすには、三角形を作るように点を配置して線分でつなげるのがよさそうだと気づいちゃいました。実際には3Dソフトでは四角形を扱えるものもありますが、四角形も半分に割ってしまえば二つの三角形ですから、四角形が出てきたときには、分割すればいいぐらいに考えておくことにします。初代プレイステーションが出始めた頃に一世を風靡した「ポリゴン」という言葉はこの三角形を含む多角形を意味する言葉ですね。

通常、立体を表現する際には、立体の表面に三角形を一つ作って、近くの表面に点を一つおいて、三角形の二頂点と結んで別の三角形を作って・・・というのを繰り返して、立体の表面を三角形で覆い尽くします。三角形を細かくすればするほど、立体の表面と三角形の集合が作る形状は近似するので、美しい立体造形になりますが、美しくするほど三角形の数が増えるので表示するときの計算量が増えます。いかに美しく、いかに計算量を抑えるかが立体のモデルを作るときの腕の見せ所でして、上手なモデラーさんの作った立体はきれいに見せたいところと、隠れてみえなくてもいいところのポリゴンの量にとてもメリハリがきいてます。
ちなみに立体モデルの表面を覆うだけで、立体の中にポリゴンを入れておく必要はありません。外から見えないからですね。

描画対象の三角形や、線分、点はorg.papervision3d.core.geom.renderablesパッケージ内にIRenderableインターフェイスをもった、Pixel3D(点)クラス、Line3D(線分)クラス、Triangle3D(三角形)クラスとして実装されています。それぞれVertex3D(頂点)クラスを1つ、2つ、3つ持っています。Vertex3Dクラスは座標位置を表すpositionプロパティ(Number3D)を持っているので、行列をかけて頂点を操作することができそうです。

ポリゴンの入れ物

ポリゴンをいっぱいつなげて形状を表すデータをポリゴンメッシュと読んだりします。org.papervision3d.core.geom.TriangleMesh3Dで表せます。ポリゴンをファイルとすると、ポリゴンメッシュはフォルダのようなものでしょうか。ポリゴンメッシュの中に複数のポリゴンを格納しておいて、一括して操作することができます。

これらの入れ物にはジオメトリという形状の状態を表すデータがくっついていたりします。

また、入れ物を入れ子にすることで木構造を作って立体全体を表現することもできます。

  • 全身
    • 右腕
    • 左腕
    • 右足
    • 左足

こんな風にポリゴンをまとめておくと、全身全てを一度に動かすことはもちろん、右腕だけ上げたり、頭をかしげたり、口だけ動かしたりなんて部分的な操作もできます。

シーン

ポリゴンの入れ物の大元、木構造でいえばルート要素になるのがシーンです。シーンを舞台とすれば、大道具や小道具、役者、照明など全ての要素がシーンの子孫要素となります。

org.papervision3d.core.proto.SceneObject3Dクラスがシーンのプロトタイプとなるようです。ポリゴンの入れ物にしろ、シーンにしろDisplayObjectContainer3Dというクラスを継承しています。先ほどの例えで言うとフォルダの役割を持つのがこの既定クラスなんですね。addChildやremoveChildメソッドで立体オブジェクトを追加・削除できます。立体オブジェクトは先ほどの例えでいうとファイルの方ですかね。org.papervision3d.objects.DisplayObject3Dクラスを継承したクラスがそれにあたるようです。

点の集合をこんな風に木構造にまとめあげているということですね。こんなデータ構造をとっているのも計算を減らすのに適しているからなんでしょうね。

Flash3D