Springhead Users Manual

8.9 メッシュ

メッシュは多面体形状を表現するための描画アイテムです. メッシュのクラスはGRMeshです. メッシュを作成する方法には

の二通りがあります. 後者の方法では,モデリングソフトで作成し,Direct3DのX形式などで出力したファイルから形状をロードすることができます. 詳しくは9章を参照してください. また,メッシュのみをロ ードする簡易機能としてFWObjectIf::LoadMeshが用意されています.

以下では前者の手動構築の方法について説明します. メッシュのディスクリプタは次の通りです.

GRMeshDesc

vector<Vec3f>

vertices

頂点

vector<GRMeshFace>

faces

vector<Vec3f>

normals

法線

vector<GRMeshFace>

faceNormals

面法線

vector<Vec4f>

colors

vector<Vec2f>

texCoords

テクスチャ座標

vector<int>

materialList

マテリアルリスト

vectorC++の可変長配列コンテナです. verticesは頂点座標を格納した配列です. ただし頂点座標を設定しただけでは形状は定義されません. メッシュは面の集合ですので,facesを設定する必要があります. GRMeshFaceの定義は以下の通りです.

GRMeshFace

int

nVertices

頂点数

int

indices[4]

頂点インデックス

nVerticesは1つの面を構成する頂点数で,3か4を設定します. indicesにはnVertices個の頂点インデックスを設定します. このとき

\{begin}{align*}   \texttt {vertices[faces[i].indices[j]]} \{end}{align*}

\( i \)番目の面の\( j \)番目の頂点座標となります.

GRMeshDescのメンバ変数の中でverticesfacesは必須ですが, その他のメンバは必ずしも設定する必要はありません. normalsは各頂点の法線の向きをを格納する配列です. normals[i]vertices[i]の法線を与えます. normalsを省略した場合,法線は自動生成されます. このとき,各頂点の法線はその頂点を共有する面の法線の平均で与えられます.

normalsに加えてfaceNormalsを設定した場合,異なる方法で法線が与えられます. このとき

\{begin}{align*}   \texttt {normals[faceNormals[i].indices[j]]} \{end}{align*}

\( i \)番目の面の\( j \)番目の頂点に対応する法線となります.

colorsは頂点色です.colors[i]\( i \)番目の頂点の色を与えます.

texCoordsは頂点ごとのテクスチャUV座標を与えます. テクスチャを描画するには,メッシュに割り当てるマテリアルにテクスチャファイル名が設定されている必要があります.

materialListは面ごとに異なるマテリアルを割り当てるために用います. materialList[i]\( i \)番目の面のマテリアル番号を与えます. ただし,番号に対応するマテリアルは別途メッシュに割り当てておく必要がありま す.

メッシュへのマテリアルの割当て

ファイルからメッシュをロードする場合,もしファイル中にマテリアル情報が含まれていれば それをもとに自動的にマテリアルがメッシュへ割り当てられます.

手動でメッシュに割り当てるには,AddChildObjectを使います. 以下に例を示します.


     // given GRSceneIf* scene, GRFrameIf* frame
     GRMeshDesc meshDesc;
     // ... setup discriptor here ...


     // create mesh and attach it to frame
     GRMeshIf* mesh = scene->CreateVisual(meshDesc, frame)->Cast();


     GRMaterialDesc matDesc0, matDesc1;
     // ... setup materials here ...
     GRMaterialIf* mat0 = scene->CreateVisual(matDesc0, frame)->Cast();
     GRMaterialIf* mat1 = scene->CreateVisual(matDesc1, frame)->Cast();


     // attach materials to mesh
     mesh->AddChildObject(mat0);             //< material no.0
     mesh->AddChildObject(mat1);             //< material no.1

最初に割り当てられたマテリアルを0番として昇順でマテリアル番号が決まります. 前述のマテリアルリストを用いる場合はこのマテリアル番号を面毎に指定してください.