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

連載一覧 "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を使ってファイルからデータを取得しよう"

あわせて読みたい