頂点座標と頂点インデックスを取得しよう

連載一覧 "FBX SDKを使ってファイルからデータを取得しよう"

いつも見てくださってありがとうございます。

見に来てくださる人がいるので、記事を更新するモチベーションが今のところ干上がらずに済んでいる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][3])に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;
}
}

実行してみると、メッシュ名、頂点インデックス、頂点座標が表示されると思います。

余談ですが、コンソールアプリケーションは実行し終わるとすぐに終了してしまいます。

そんな時は、止めたい行を選択して、カーソルの前まで実行を使うと、その部分で実行が止まるので便利です。

連載一覧 "FBX SDKを使ってファイルからデータを取得しよう"

あわせて読みたい