サイトのトップへ戻る

libGDX ドキュメント 日本語訳

サイト内検索

ModelBuilderと MeshBuilder と MeshPartBuilder



ModelBuilder

ModelBuilder (コード)はコード上から models を作成することができるユーティリティクラスです。 ModelBuilderではmodelに1つ以上の nodesを含めることができ、各 node は1つ以上のpartsによって構成されます。 しかし、ノード階層(子ノード)の構築はサポートしていませんん。 コード上でmodelを構築するのは負荷のかかる操作であり、ガベージコレクターを引き起こす可能性があるので注意してください。



modelを構築する

modelの構築を開始するには、 begin() メソッドを使用します。 その後、modelの構築が完了したら end() を呼び出す必要があります。 end() メソッドは新たに作成されたmodelを戻り値として返します。 同じModelBuilderを使って複数のmodelを構築することはできますが、同時にはできません。例えば:

ModelBuilder modelBuilder = new ModelBuilder();

modelBuilder.begin();
... //build one or more nodes
Model model1 = modelBuilder.end();

modelBuilder.begin();
... //build one or more nodes
Model model2 = modelBuilder.end();


リソースを管理する

modelは1つ以上のメッシュを含んでいるので、 破棄をする必要があるということを覚えておいてください。 ModelBuilder を使用して構築されたmodelは常に、自身が保持している全てのメッシュの破棄に対して責任を負っています。あなた自身がmodelにメッシュを渡していた場合でさえもです。 Mesh を複数のModelで共有しないでください。

ModelBuilder を使用して構築されたmodelは、 materialに含まれているテクスチャやその他リソースの破棄に対しては責任を負っていません。 しかし、 manage(disposable)メソッドを使ってmodelに対してこれらリソースを破棄する責任を負わせることができます。例えば:

ModelBuilder modelBuilder = new ModelBuilder();
modelBuilder.begin();
Texture texture = new Texture(...);
modelBuilder.manage(texture);
... //build one or more nodes
Model model = modelBuilder.end();
... //use the model and when done:
model.dispose(); // this will dispose the texture as well


ノードを作成する

Model は1つ以上の nodesによって構成されています。 model 内で新しいnodeの構築を開始するには、node() メソッドを使用できます。 このメソッドは新規ノードを追加して、それを構築のためのアクティブ化します。 またこのメソッドはNodeを戻り値として返すので、 後で使用するためにそれを参照することができます。例えば、ノードにidを設定するなど。

ModelBuilder modelBuilder = new ModelBuilder();
modelBuilder.begin();
Node node1 = modelBuilder.node();
node1.id = "node1";
node1.translation.set(1, 2, 3);
...//build node1
Node node2 = modelBuilder.node();
node2.id = "node2";
...//build node2
Model model = modelBuilder.end();

ノードのIDはmodel内で重複しないようにする必要があるので注意してください。一般的な使用例は以下の通りです:

ModelBuilder modelBuilder = new ModelBuilder();
modelBuilder.begin();
modelBuilder.node().id = "node1";
...//build node1
modelBuilder.node().id = "node2";
...//build node2
Model model = modelBuilder.end();

一つ目のノードで node() メソッドを使用するかどうかは任意です。 例えば、1つのノードだけで構成されているモデルの場合、 node()メソッドを呼び出さなくても即座にノードパーツの作成を開始することができます。

構築のためにアクティブ化できるNodeは一度につき1つだけです。 node() メソッドを呼び出すと前のノードの構築は中断され(構築中であれば)、新しいノードの構築が開始されます。 ただし、ノードが有効(構築完了)となるのはModel の構築が完了した( end()の呼び出しが行われた )後です。



ノードパーツを作成する

Node には1つ以上のパーツを含めることができます。 ノードの各パーツは同じ場所に描写されますが(ノード変換)、異なる material (例えばシェーダーのユニフォーム値など)や mesh (例えば、シェーダーの (頂点) 属性など)で構成することができます。

NodePart はModelで最小のrenderable パーツです。 表示されている各NodePart ごとに描写呼び出し (もしくは、 "ドローコール"と言い換えても良いです)が実行されてということを意味しています。 描写呼び出しの回数を減らすと、モデルを描写するのにかかる時間を減らすことができます。 したがって、可能であれば複数のパーツは1つのパーツに組み合わせるよう心がけることをお勧めします。

NodePart を現在のノードに追加するには、part(...) メソッドのうちどれか1つを使用できます。 NodePartは、基本的には MeshPartMaterialの組み合わせです。 part(...) メソッドのうちのどれか1つを実行する時には、常にマテリアルを引数として渡す必要があります。 ただしMeshPartの場合、ModelBuilderを使ってmesh (のパーツ)をあなた自身で指定するか、MeshPartBuilderを使ってMeshPart の構築を開始できます。

パーツを作成するのに使用したメソッドに関わらず、Modelは常に Meshを破棄する責任を負っていることを覚えておいてください。

MeshPartBuilder はメッシュを作成するための様々なヘルパークラスを持っているインタフェース (MeshBuilderの実装については下記参照)です。 MeshPartBuilderでMeshPartのインスタンスを作成する際にpart(...)メソッドを使用している場合、ModelBuilderは複数のパーツを同一Meshに結合しようとします。 ほとんどの場合、これによりMeshの紐付け回数が減ります。 これは、パーツが同一の頂点属性を使用して構成されている場合にのみ可能です。例えば:

ModelBuilder modelBuilder = new ModelBuilder();
modelBuilder.begin();
MeshPartBuilder meshBuilder;
meshBuilder = modelBuilder.part("part1", GL20.GL_TRIANGLES, Usage.Position | Usage.Normal, new Material());
meshBuilder.cone(5, 5, 5, 10);
Node node = modelBuilder.node();
node.translation.set(10,0,0);
meshBuilder = modelBuilder.part("part2", GL20.GL_TRIANGLES, Usage.Position | Usage.Normal, new Material());
meshBuilder.sphere(5, 5, 5, 10, 10);
Model model = modelBuilder.end();

これにより、二つのノードで構成されるモデルが作成されます。 各ノードは1つのパーツで構成されています。 両方のパーツのMeshは共有されるので、このModel用に作成されるMeshは1つだけです。 この例ではビットマスクを使って頂点属性を設定しているので、 それによりModelBuilder が既定の (3D) VertexAttributesを作成しているということに注意してください。 VertexAttributes をあなたが自分で設定することもできます。

ModelBuilderは複数のパーツでMeshPartBuilder インスタンスを再利用するため、同時に複数のパーツを構築することはできません。 ModelBuilderごとに、ModelNodeMeshPartは任意の時点では1つだけ構築できます。 part(...) メソッドを呼び出すと、前回までの MeshPartBuilder は無効になります。

MeshPartBuilder を使ってパーツの形状を作成する方法の詳細については、後述するMeshPartBuilderの項目を参照してください。



MeshBuilder

MeshBuilder (コード) は1つ以上の meshを作成するためにユーティリティクラスです。メッシュは、必要に応じて1つ以上のMeshPartsで構成します。 MeshBuilder は通常だとModelBuilderModelBuilder#part(...)メソッドを使って構築と管理が行われますが、 ModelBuilderを使わずに MeshBuilderを使うことができます。 このため、begin(...)メソッドを使ってメッシュの構築を開始することができ、その後メッシュの構築が完了したらend()メソッドを呼び出す必要があります。 beginメソッドは、頂点属性を指定するための様々な引数を受け取ります。必要に応じてプリミティブ型の引数(メッシュパーツを作成しない時に必要)も受け取ります。 end() メソッドは新たしく作成されたMeshを戻り値として返します。 同一のMeshBuilder インスタンスを使って複数のメッシュを構築することはできますが、同時に構築することはできません:

MeshBuilder meshBuilder = new MeshBuilder();
meshBuilder.begin(Usage.Position | Usage.Normal, GL20.GL_TRIANGLES);
...//build the first mesh
Mesh mesh1 = meshBuilder.end();

meshBuilder.begin(Usage.Position | Usage.Normal | Usage.ColorPacked, GL20.GL_TRIANGLES);
...//build the second mesh
Mesh mesh2 = meshBuilder.end();

Mesh は不要になったら破棄しなければならないということを忘れないでください。

複数のパーツで構成されたMeshを構築するには、part(...) メソッドを使用します。 part(...) メソッドを使うと新規にMeshPartが作成され、それが構築のためにアクティブ化されます。

MeshBuilder meshBuilder = new MeshBuilder();
meshBuilder.begin(Usage.Position | Usage.Normal);
MeshPart part1 = meshBuilder.part("part1", GL20.GL_TRIANGLES);
... // build the first part
MeshPart part2 = meshBuilder.part("part2", GL20.GL_TRIANGLES);
... // build the second part
Mesh mesh = meshBuilder.end();

part(...) メソッドはMeshPartを戻り値として返すので後で使用する際に参照することができますが、 このMeshPartend()メソッドが呼び出されるまで有効にはなりません。 MeshPart は一度に1つしか作成できません。part(...)メソッドを呼び出すと、前のパーツの構築が停止して新しいパーツの構築が開始されます。、

同じ Meshのパーツは全て、同じ VertexAttributesを共有します。 プリミティブ型はパーツごとに異なることがあります。例えば、以下のコードではそれぞれプリミティブ型が違う二つのパーツを作成していますが、メッシュは同じものを共有します。:

meshBuilder.begin(Usage.Position | Usage.Normal);
MeshPart part1 = meshBuilder.part("part1", GL20.GL_TRIANGLES);
... // build the first part
MeshPart part2 = meshBuilder.part("part2", GL20.GL_TRIANGLE_STRIP);
... // build the second part
Mesh mesh = meshBuilder.end();

MeshBuilderMeshPartBuilderを実装しています。メッシュ(のパーツ)の実際の形状の作成については、MeshPartBuilderの項目で説明します。



MeshPartBuilder

MeshPartBuilder (コード)はメッシュ(のパーツ)を作成するための様々なメソッドが用意されたユーティリティインタフェースです。 ModelBuilder.part(...)を使用するか、MeshBuilderのインスタンスを作成することで、MeshPartBuilderを取得することができます。 MeshPartBuilderインタフェースのメソッドは全て、MeshPartを作成している間(一般的には、 part(...)メソッドを呼び出してから、次のpart(...) を呼び出すか ModelBuilder もしくは MeshBuilderend() メソッドを呼び出すまでの間)に限り呼び出すことができます。

現在作成しているMeshPartを取得するには getMeshPart()メソッドを使用します。 作成しているMeshVertexAttributesを取得するには getAttributes() メソッドを使用します。

Usage.PositionVertexAttribute (2D か 3Dのどちらか)が必要です。 指定する頂点属性にはそれ以外の制限はありません。 しかし、ほとんどの(特に上位の)メソッドでは 位置と法線と色 (パックかアンパックのどちらか) とテクスチャ座標の属性のみが実装されています。 他の属性を使用する場合、既知値(通常は0)が使用されます。

ほとんどのメソッドでは、複数のシグネチャで頂点属性の値を指定できます。 小さなヘルパークラス VertexInfo を使って、頂点ごとのこれらの値を指定できます。 例えば、rect(...)メソッドは各角のVertexInfo を受け取ります。 各角の頂点値ごとの考えられる全ての組み合わせや引数を受け取るメソッドは使用しません。 VertexInfoは特定の値が設定されてたかどうかを追尾し続けるため、常にsetXXX メソッドを使用する必要があるので気をつけてください。 値の設定を解除したい場合は nullを使用します。

Use the setColor(...) method to specify the default color that will be used when the VertexAttributes contain a color VertexAttribute, but no color is set in e.g. the VertexInfo. 例:

meshPartBuilder.setColor(Color.RED);
VertexInfo v1 = new VertexInfo().setPos(0, 0, 0).setNor(0, 0, 1).setCol(null).setUV(0.5f, 0.0f);
VertexInfo v2 = new VertexInfo().setPos(3, 0, 0).setNor(0, 0, 1).setCol(null).setUV(0.0f, 0.0f);
VertexInfo v3 = new VertexInfo().setPos(3, 3, 0).setNor(0, 0, 1).setCol(null).setUV(0.0f, 0.5f);
VertexInfo v4 = new VertexInfo().setPos(0, 3, 0).setNor(0, 0, 1).setCol(null).setUV(0.5f, 0.5f);
meshPartBuilder.rect(v1, v2, v3, v4);

上記の例では、setCol(null)によってVertexInfoはカラーセットを持たないので、既定値が使用されて赤色に設定されます。

テクスチャ座標が指定されていない場合に使われる既定のテクスチャ座標の範囲を指定するには、setUVRangeを使用します。 Along with the default color, this is especially useful for simple shapes where only positions are needed and other vertex information can be derived from the shape. 例えば:

meshPartBuilder.setColor(Color.RED);
meshPartBuilder.setUVRange(0.5f, 0f, 0f, 0.5f);
meshPartBuilder.rect(0,0,0, 3,0,0, 3,3,0, 0,3,0, 0,0,1); // the last three arguments specify the normal

変換行列を渡すには setVertexTransform(...)メソッドを使用します。 このメソッドを呼び出した後に設定される全ての頂点に変換行列が適用されます。