目次

015 FBXファイルから情報を取得する

概要

頂点やUVといった情報を比較的楽に取得できます。

頂点の取得

頂点の情報はFbxMesh に格納されています。 FbxMeshはFbxScene::GetRootNode関数で取得したFbxNodeにあります。

FbxNode* pNode = s_pFbxScene->GetRootNode();
FbxMesh* pMesh = _pNode->GetMesh();

このFbxMeshクラス から、各種情報を取得できます。

// 頂点数。
const int sVertexCount = pMesh->GetControlPointsCount();
 
// ポリゴン数。
int sPolygonCount = pMesh->GetPolygonCount();
 
// 頂点、法線を取得。
for( int i = 0; i < sPolygonCount; i++ )
{
	// ポリゴンサイズの取得。(三角形化していれば固定のはず)。
	int sPolygonSize = _pMesh->GetPolygonSize( i );
	for( int pol = 0; pol < sPolygonSize; pol++ )
	{
		// 頂点インデックス。
		int vertex_index = _pMesh->GetPolygonVertex( i, pol );
 
		// 頂点。
		_pMesh->GetControlPointAt( vertex_index );
 
		// 法線。
		_pMesh->GetPolygonVertexNormal( i, pol, normal );
	}
}

UVの取得

UVもFbxMesh から取得できます。

FbxVector2 texCoord;
FbxStringList uvsetName;
pMesh->GetUVSetNames( uvsetName );
 
// UVセット数取得。
int sNumUVSet = uvsetName.GetCount();
 
bool bIsUnmapped = false;
for( int i = 0; i < sNumUVSet; i++ )
{
	for( int j = 0; j < sPolygonCount; j++ )
	{
		int sPolygonsize = pMesh->GetPolygonSize( i );
 
		for( int k = 0; k < sPolygonsize; k++ )
		{
			// UV値取得。
			FbxString name = uvsetName.GetStringAt( i );
			pMesh->GetPolygonVertexUV( j, k, name, texCoord, bIsUnmapped );
		}
	}
}

マテリアルの取得

マテリアルはFbxMesh ではなく、bxSurfaceMaterial クラスから取得できます。 bxSurfaceMaterialもFbxMesh と同じくFbxNodeから取得出来ます。 また、FBXのマテリアルの種類はLambertとPhongだけです。

// マテリアル数取得。
const int sMaterialCount = pNode->GetMaterialCount();
 
// マテリアル取得。
FbxSurfaceMaterial* pMat = _pNode->GetMaterial( material_index );
 
// マテリアルタイプ取得。
enum eMATERIAL_TYPE
{
	MATERIAL_LAMBERT = 0,
	MATERIAL_PHONG,
};
 
eMATERIAL_TYPE mat_type;
if ( pMat->GetClassId().Is( FbxSurfaceLambert::ClassId ) )
{
	mat_type = MATERIAL_LAMBERT;
}
else if ( pMat->GetClassId().Is( FbxSurfacePhong::ClassId ) )
{
	mat_type = MATERIAL_PHONG;
}
 
// プロパティ取得。
const FbxProperty lProperty;
pMat->FindProperty( FbxSurfaceMaterial::sEmissive );
pMat->FindProperty( FbxSurfaceMaterial::lAmbient );
pMat->FindProperty( FbxSurfaceMaterial::sDiffuse );
pMat->FindProperty( FbxSurfaceMaterial::lSpecular );
 
// ファクター取得。
const FbxProperty lFactorProperty;
pMat->FindProperty( FbxSurfaceMaterial::sEmissiveFactor );
pMat->FindProperty( FbxSurfaceMaterial::sAmbientFactor );
pMat->FindProperty( FbxSurfaceMaterial::sDiffuseFactor );
pMat->FindProperty( FbxSurfaceMaterial::sSpecularFactor );
 
// プロパティ、ファクターの値を取得。
FbxDouble3 lResult = lProperty.Get<FbxDouble3>();
double lFactor = lFactorProperty.Get<FbxDouble>();
 
// プロパティが有効か?
lProperty.IsValid();
 
// 透明度。
FbxProperty lTransparencyFactorProperty = pMat->FindProperty( FbxSurfaceMaterial::sTransparencyFactor );
if( lTransparencyFactorProperty.IsValid() )
{
	double lTransparencyFactor = lTransparencyFactorProperty.Get<FbxDouble>();
}
 
// スペキュラ。
FbxProperty lShininessProperty = _pMat->FindProperty( FbxSurfaceMaterial::sShininess );
if( lShininessProperty.IsValid() )
{
	double lShininess = lShininessProperty.Get<FbxDouble>();
}
 
// テクスチャ情報の取得。
{
	const int sTextureCount = lProperty.GetSrcObjectCount<FbxFileTexture>();
	for( int i = 0; i < sTextureCount; i++ )
	{
		FbxFileTexture* pFileTexture = lProperty.GetSrcObject<FbxFileTexture>( i );
		if( !pFileTexture )
		{
			continue;
		}
 
		FbxString uvsetName = pFileTexture->UVSet.Get();
		std::string uvSetString = uvsetName.Buffer();
		std::string filepath = pFileTexture->GetFileName();
	}
 
	const int sLayeredTextureCount = lProperty.GetSrcObjectCount<FbxLayeredTexture>();
	for( int i = 0; i < sLayeredTextureCount; i++ )
	{
		FbxLayeredTexture* lLayeredTexture = lProperty.GetSrcObject<FbxLayeredTexture>( i );
		const int sTextureFileCount = lLayeredTexture->GetSrcObjectCount<FbxFileTexture>();
 
		for( int j = 0; j < sTextureFileCount; j++ )
		{
			FbxFileTexture* pFileTexture = lLayeredTexture->GetSrcObject<FbxFileTexture>( j );
			if( !pFileTexture )
			{
				continue;
			}
 
			FbxString uvsetName = pFileTexture->UVSet.Get();
			std::string uvSetString = uvsetName.Buffer();
			std::string filepath = pFileTexture->GetFileName();
		}
	}
}

これで描画に必要な情報を一通り取得出来ました。