いつも見てくださってありがとうございます。
見に来てくださる人がいるので、記事を更新するモチベーションが今のところ干上がらずに済んでいるyosiです。
第3回は前回取得したノードから頂点座標と頂点インデックスを取得していきます。
メッシュを取得する
ノードからメッシュを取得します。
そのメッシュを用いて、頂点情報を取得していきます。
DisplayIndex(mesh)とDisplayPosition(mesh)は頂点インデックスと頂点座標を取得するための関数で、この後に定義していきます。
#include "stdafx.h"
#include "fbxsdk.h"
#include "iostream"
void DisplayContent(FbxScene* pScene);
void DisplayContent(FbxNode* pNode);
void DisplayMesh(FbxNode* pNode);
void DisplayIndex(FbxMesh* mesh);
void DisplayPosition(FbxMesh* mesh);
int main()
{
//省略 前回までの内容をご覧ください
DisplayContent(scene);
manager->Destroy();
return 0;
}
void DisplayContent(FbxScene* scene)
{
//省略 前回までの内容をご覧ください
}
void DisplayContent(FbxNode* node)
{
FbxNodeAttribute::EType lAttributeType;
if (node->GetNodeAttribute() == NULL)
{
std::cout << "NULL Node Attribute\n\n";
}
else
{
lAttributeType = (node->GetNodeAttribute()->GetAttributeType());
switch (lAttributeType)
{
default:
break;
case FbxNodeAttribute::eMesh:
DisplayMesh(node);
break;
}
}
for (int i = 0; i < node->GetChildCount(); i++)
{
DisplayContent(node->GetChild(i));
}
}
void DisplayMesh(FbxNode* node)
{
FbxMesh* mesh = (FbxMesh*)node->GetNodeAttribute();
std::cout << "\n\nMesh Name: " << (char *)node->GetName() << std::endl;
DisplayIndex(mesh);
DisplayPosition(mesh);
}
頂点インデックスと頂点座標を取得する
取得していくデータについて簡単に説明しますと、3Dデータは複数の頂点(Vertex)から成るポリゴンによって表現されます。
その頂点には頂点座標、法線、テクスチャ座標などがあります。
複数のポリゴン間には重複している頂点があります(下の図の頂点0と2)。
その重複によるメモリの無駄を避けるために、頂点インデックスがあります。
その頂点インデックスを取得していきます。
ここでは基本的に表示のみをしています。
後はこのindexを集めて配列にするなり、ファイルに書き出すなりしてください。
void DisplayIndex(FbxMesh* mesh)
{
//総ポリゴン数
int polygonNum = mesh->GetPolygonCount();
//p個目のポリゴンへの処理
for (int p = 0; p < polygonNum; ++p)
{
//p個目のポリゴンのn個目の頂点への処理
for (int n = 0; n < 3; ++n)
{
int index = mesh->GetPolygonVertex(p, n);
std::cout << "index[" << p+n <<"] : " << index << std::endl;
}
}
}
次に頂点座標を取得していきます。
得られたpositionは大きさ4のベクトルなのですが、実行してみると分かるのですが、多くの場合4つ目の要素(position[i])に0が入っています。
ただ、OpenGLで実行するときには4つ目の要素は0だと描画されないのでたいていは1を指定することになると思います。
void DisplayPosition(FbxMesh* mesh)
{
int positionNum = mesh->GetControlPointsCount(); // 頂点数
FbxVector4* position = mesh->GetControlPoints(); // 頂点座標配列
for (int i = 0; i < positionNum; ++i)
{
std::cout << "position[" << i << "] : ("
<< position[i][0] << ","
<< position[i][1] << ","
<< position[i][2] << ","
<< position[i][3] << ")" << std::endl;
}
}
実行してみると、メッシュ名、頂点インデックス、頂点座標が表示されると思います。
余談ですが、コンソールアプリケーションは実行し終わるとすぐに終了してしまいます。
そんな時は、止めたい行を選択して、カーソルの前まで実行を使うと、その部分で実行が止まるので便利です。