はじめに
この記事では、ゲーム内でプレイヤーがポリゴンを操作してステージを地形変動できるようにつくります。
カメラやプレイヤーの基本的な動作、モデルとの衝突判定等は実装済の状態で始めます。
地形を変動させるのはいろいろ方法がありますが、ひとまず強引にモデルのポリゴンの見た目と衝突判定を変える手法でやってみようと思います。
言語は C++ 、 エンジンを使わず にVisualStudioで、ライブラリは DXライブラリ で制作を進めていきます。
【記事中のコードについての注意事項】
分かりやすさのため実際のものから書き換えている部分や省略している部分があります。
長くなってしまうので、後半部分は記事を分けています。
目次
- モデルの情報を参照し、変数に格納
- ポリゴンとして表示
- ポリゴンを変動することができるようにする
モデルの情報を参照し、変数に格納
元々のステージの描画はこう
モデルを読み込み、大きさを少し変えて描画しています。
ちなみにプレイヤーモデルはMixsamoから拝借しています。
このステージモデルの情報を参照して変数格納します。
これはDXライブラリの関数でMV1GetReferenceMeshを使います。
データ取得前に参照用メッシュの構築(MV1SetupReferenceMesh)を忘れずに。
リファレンス通りに進めていきます。
class Stage
{
//~省略~
private:
//モデル情報
int modelId_;
//格納先変数
MV1_REF_POLYGONLIST polygonList_;
};
void Stage::Init(void)
{
//~省略~
// モデル全体の参照用メッシュを構築
MV1SetupReferenceMesh(modelId_, -1, TRUE);
// 参照用メッシュ情報の取得
polygonList_ = MV1GetReferenceMesh(modelId_, -1, TRUE);
}
void Stage::Draw(void)
{
// ポリゴンの数だけ繰り返し
int i;
for (i = 0; i < polygonList_.PolygonNum; i++)
{
// ポリゴンを形成する三頂点を使用してワイヤーフレームを描画する
// 色は黄色
DrawLine3D(
polygonList_.Vertexs[polygonList_.Polygons[i].VIndex[0]].Position,
polygonList_.Vertexs[polygonList_.Polygons[i].VIndex[1]].Position,
GetColor(255, 255, 0));
DrawLine3D(
polygonList_.Vertexs[polygonList_.Polygons[i].VIndex[1]].Position,
polygonList_.Vertexs[polygonList_.Polygons[i].VIndex[2]].Position,
GetColor(255, 255, 0));
DrawLine3D(
polygonList_.Vertexs[polygonList_.Polygons[i].VIndex[2]].Position,
polygonList_.Vertexs[polygonList_.Polygons[i].VIndex[0]].Position,
GetColor(255, 255, 0));
}
}
今はまだメッシュ表示になっていますが、うまくモデル情報の参照ができていそうです。
ポリゴンとして表示
情報が取れたので、DrawPolygon3Dを使ってポリゴン表示をし、元々のステージのように描画していきたいと思います。
変数を変換
ここで問題が出てきます。DrawPolygon3Dの引数は、
DrawPolygon3D( VERTEX3D *Vertex, int PolygonNum, int GrHandle, int TransFlag )
ですが、先ほどモデル情報を格納した変数はMV1_REF_POLYGONLIST polygon_;
この MV1_REF_POLYGONLIST もDXライブラリの構造体で
MV1_REF_POLYGONLIST
struct MV1_REF_POLYGONLIST
{
// ポリゴンの数
int PolygonNum ;
// 頂点の数
int VertexNum ;
// 頂点座標の最小値
VECTOR MinPosition ;
// 頂点座標の最大値
VECTOR MaxPosition ;
// ポリゴン構造体の配列へのポインタ
MV1_REF_POLYGON *Polygons ;
// 頂点構造体の配列へのポインタ
MV1_REF_VERTEX *Vertexs ;
} ;
になっており、さらに頂点情報を持っている構造体の MV1_REF_VERTEX は
MV1_REF_VERTEX
struct MV1_REF_VERTEX
{
// 位置
VECTOR Position ;
// 法線
VECTOR Normal ;
// テクスチャ座標
UV TexCoord[ 2 ] ;
// ディフューズカラー
COLOR_U8 DiffuseColor ;
// スペキュラカラー
COLOR_U8 SpecularColor ;
} ;
になっています。
もう一度DrawPolygon3Dの引数を確認してみます。
DrawPolygon3D( VERTEX3D *Vertex, int PolygonNum, int GrHandle, int TransFlag )
第2~4引数はMV1_REF_POLYGONLISTやMV1_REF_VERTEXで設定できそうですが、実際にやってみても、第1引数の VERTEX3D *Vertex
はエラーが出ます。
DrawPolygon3Dをするためには、先ほどの変数から一部の情報をVERTEX3D *Vertex
へ変換する必要があるようです。
class Stage
{
//~省略~
private:
//~省略~
//頂点情報の格納
std::vector<VERTEX3D> vertexes_;
};
void Stage::Init(void)
{
//~省略~
//頂点情報へ変換
for (auto& v : vertexes_)
{
for (int i = 0; i < polygonList_.VertexNum; i++)
{
//頂点情報に変換
v.pos = polygonList_.Vertexs[i].Position;
v.dif = polygonList_.Vertexs[i].DiffuseColor;
v.spc = polygonList_.Vertexs[i].SpecularColor;
v.norm = polygonList_.Vertexs[i].Normal;
v.u = polygonList_.Vertexs[i].TexCoord[0].u;
v.v = polygonList_.Vertexs[i].TexCoord[0].v;
//動的配列に格納
vertexes_.emplace_back(v);
}
}
}
void Stage::Draw(void)
{
//~省略~
//ポリゴン描画
DrawPolygon3D(vertexes_.data(), polygonList_.PolygonNum, DX_NONE_GRAPH, FALSE);
}
変換することでDrawPolygon3D
で描画することができました。
うまく表示できていそうですが、左奥のほうをよく見てみると
意図しないものも描画されてしまっています。
「ポリゴン」として表示
原因はVERTEX3D *Vertex
にあります。VERTEX3Dは 頂点座標情報 をもつ構造体です。
VERTEX3Dはモデルから読み込んできた頂点座標情報を保有しているだけで、どの頂点がポリゴンを形成しているのかの情報が欠けています。
ポリゴンは頂点を時計回りに指定し描画します。
欠けているポリゴン情報をVERTEX3Dに指定する必要があります。MV1_REF_POLYGONLIST
から取得して指定します。
void Stage::Init(void)
{
//~省略~
int num = polygonList_.PolygonNum;
for (int i = 0; i < num; i++)
{
auto poly = polygonList_.Polygons[i];
for (int p = 0; p < 3; p++)
{
//頂点の要素番号を取得
int vIndex = poly.VIndex[p];
//取得した頂点の要素番号を使って、頂点情報を取得
auto verRef = polygonList_.Vertexs[vIndex];
//頂点情報へ変換
VERTEX3D v;
v.pos = verRef.Position;
v.dif = verRef.DiffuseColor;
v.spc = verRef.SpecularColor;
v.norm = verRef.Normal;
v.u = verRef.TexCoord[0].u;
v.v = verRef.TexCoord[0].v;
//動的配列に格納
vertexes_.emplace_back(v);
}
}
//~省略~
}
書き換えたあとの出力結果は、
うまくポリゴン描画ができていそうです。
ポリゴンを変動させる
こちらへ続きます。