まずはクラスを作って形だけ表示してみる。
影とかテクスチャはあとから
とりあえずこんな感じ。
ロードして、描画して、片付ける。
#pragma once
#include <d3d11.h>
#include <fbxsdk.h>
#include <string>
#include "Transform.h"
#pragma comment(lib, "LibFbxSDK-MT.lib")
#pragma comment(lib, "LibXml2-MT.lib")
#pragma comment(lib, "zlib-MT.lib")
class Fbx
{
public:
Fbx();
HRESULT Load(std::string fileName);
void Draw(Transform& transform);
void Release();
};
Quadクラスと同じメンバ変数をFbxにも用意する。
これらに関して説明はいらないはずだから、自分でコメントを書き、コンストラクタとReleaseの処理を書いてしまおう。
class Fbx
{
struct CONSTANT_BUFFER
{
XMMATRIX matWVP;
XMMATRIX matNormal;
};
struct VERTEX
{
XMVECTOR position;
};
ID3D11Buffer *pVertexBuffer_;
ID3D11Buffer *pIndexBuffer_;
ID3D11Buffer *pConstantBuffer_;
public:
次は、FBXファイルを扱うために必要になる変数を宣言する。
class Fbx
{
struct CONSTANT_BUFFER
{
XMMATRIX matWVP;
XMMATRIX matW;
};
struct VERTEX
{
XMVECTOR position;
};
int vertexCount_; //頂点数
int polygonCount_; //ポリゴン数
ID3D11Buffer *pVertexBuffer_;
自分で頂点情報を作るわけではないので、頂点数やポリゴン数がいくつになるかはその時にならないとわからない。
それらの値を入れておく変数を用意しておく。
コンストラクタでの初期化を忘れずに。
まずはデータの解析(頂点情報とかインデックス情報とか)は置いといて、データをまるっと読み込む。
HRESULT Fbx::Load(std::string fileName)
{
//マネージャを生成
FbxManager* pFbxManager = FbxManager::Create();
//インポーターを生成
FbxImporter *fbxImporter = FbxImporter::Create(pFbxManager, "imp");
fbxImporter->Initialize(fileName.c_str(), -1, pFbxManager->GetIOSettings());
//シーンオブジェクトにFBXファイルの情報を流し込む
FbxScene* pFbxScene = FbxScene::Create(pFbxManager, "fbxscene");
fbxImporter->Import(pFbxScene);
fbxImporter->Destroy();
//マネージャ解放
pFbxManager->Destroy();
return S_OK;
}
詳しくはこちらがわかりやすい
http://marupeke296.com/FBX2019_No2_LoadAndTerminate.html
FBXの中身は「ノード」と呼ばれる複数の情報がツリー構造になっている。
本来であれば、このツリー構造の中から必要なノードを探さなければならない。
しかし、今回は「オブジェクトは一つに結合されていること」を条件にしているので、必要な情報の場所は確定している。
ルートノードの最初の子供のノードに頂点やインデックス、マテリアルの情報が入っている。
この中の「形に関する情報」をメッシュ情報という。(ノードには他にマテリアルの情報などが入っている)
HRESULT Fbx::Load(std::string fileName)
{
:
:
:
FbxScene* pFbxScene = FbxScene::Create(pFbxManager, "fbxscene");
fbxImporter->Import(pFbxScene);
fbxImporter->Destroy();
//メッシュ情報を取得
FbxNode* rootNode = pFbxScene->GetRootNode();
FbxNode* pNode = rootNode->GetChild(0);
FbxMesh* mesh = pNode->GetMesh();
//各情報の個数を取得
vertexCount_ = mesh->GetControlPointsCount(); //頂点の数
polygonCount_ = mesh->GetPolygonCount(); //ポリゴンの数
//マネージャ解放
pFbxManager->Destroy();
return S_OK;
}
メッシュ情報が取得できたので、ここから頂点情報やインデックス情報を抜き取っていく。
それさえできてしまえば、あとはQuadクラスでポリゴンを表示したのと同じだ。
では、メッシュ情報から頂点情報を抜き取り、頂点バッファを作成しよう。
このままLoad関数に書いていくと長くなるので、まずは関数を分ける。
HRESULT Fbx::Load(std::string fileName)
{
:
:
:
//各情報の個数を取得
vertexCount_ = mesh->GetControlPointsCount(); //頂点の数
polygonCount_ = mesh->GetPolygonCount(); //ポリゴンの数
InitVertex(mesh); //頂点バッファ準備
//マネージャ解放
pFbxManager->Destroy();
return S_OK;
}
//頂点バッファ準備
void Fbx::InitVertex(fbxsdk::FbxMesh * mesh)
{
}
void Fbx::InitVertex(fbxsdk::FbxMesh * mesh)
{
//頂点情報を入れる配列
VERTEX* vertices = new VERTEX[vertexCount_];
//全ポリゴン
for (DWORD poly = 0; poly < polygonCount_; poly++)
{
//3頂点分
for (int vertex = 0; vertex < 3; vertex++)
{
//調べる頂点の番号
int index = mesh->GetPolygonVertex(poly, vertex);
//頂点の位置
FbxVector4 pos = mesh->GetControlPointAt(index);
vertices[index].position = XMVectorSet((float)pos[0], (float)pos[1], (float)pos[2], 0.0f);
}
}
}
頂点の数がvertexCount_に入ってるんで、その分の配列を作成。
全ポリゴンの3頂点それぞれを調べるので二重ループ。
poly番目のポリゴンのvertex番目の頂点の番号を調べ、その位置を配列に入れていく。
ちなみに、MayaとDirectXではZの方向が違うので、鏡と同じように左右反転してしまう。
そこで、Xのの符号を反転させている。
頂点情報が揃ったので、頂点バッファを作成し、そこに情報をセットする。
これはQuadクラスで全く同じことをやってるので、それを参考にしよう。
void Fbx::InitVertex(fbxsdk::FbxMesh * mesh)
{
:
:
:
// 頂点バッファ作成
(自分でやって)
Direct3D::pDevice->CreateBuffer(・・・・・・・・);
}
一点だけ注意が必要。
verticesはポインタで動的配列になったので、sizeof(vertices)では正しくサイズを取得することができない。
この場合はVERTEX型のサイズ*頂点数を指定すればよい。
同じような感じでインデックス情報を取得し、インデックスバッファを作成しよう
HRESULT Fbx::Load(std::string fileName)
{
:
:
:
//各情報の個数を取得
vertexCount_ = mesh->GetControlPointsCount(); //頂点の数
polygonCount_ = mesh->GetPolygonCount(); //ポリゴンの数
InitVertex(mesh); //頂点バッファ準備
InitIndex(mesh); //インデックスバッファ準備
//マネージャ解放
pFbxManager->Destroy();
return S_OK;
}
:
:
:
//インデックスバッファ準備
void Fbx::InitIndex(fbxsdk::FbxMesh * mesh)
{
}
//インデックスバッファ準備
void Fbx::InitIndex(fbxsdk::FbxMesh * mesh)
{
int* index = new int[polygonCount_ * 3];
int count = 0;
//全ポリゴン
for (DWORD poly = 0; poly < polygonCount_; poly++)
{
//3頂点分
for (DWORD vertex = 0; vertex < 3; vertex++)
{
index[count] = mesh->GetPolygonVertex(poly, vertex);
count++;
}
}
}
自力でどうぞ
(ここもデータサイズを指定するところだけ注意)
HRESULT Fbx::Load(std::string fileName)
{
:
:
:
//各情報の個数を取得
vertexCount_ = mesh->GetControlPointsCount(); //頂点の数
polygonCount_ = mesh->GetPolygonCount(); //ポリゴンの数
InitVertex(mesh); //頂点バッファ準備
InitIndex(mesh); //インデックスバッファ準備
IntConstantBuffer(); //コンスタントバッファ準備
Quadクラスと同じなので自分でやって
ここもQuadクラスとほぼ同じ。
最後のDrawIndexed関数の第一引数でインデックス数を指定しなきゃないが、どう書いたらいいか考えてみよう。
それができれば描画できるはず。
Main.cppでFbxクラスのオブジェクトを作成し、モデルを表示してみよう。
シルエットだけ表示されるはず