====== 014 FBXファイルの読み込み ======
===== 概要 =====
FBXフォーマットは、Autodesk Mayaなどで出力できるクロスプラットフォームのファイル形式です。
有名なファイルフォーマットとしてはXファイルがありましたが生みの親であるはずのMicroSoftが手放したため、
これから3DプログラムをするならFBX形式のモデルフォーマットというものを知っておいた方が良いです。
UnityやUnreal Engine 4なんかでも標準で読み込める形式となっています。
==== 環境構築 ====
*まずはSDKを用意します。以下のサイトからダウンロードし、任意の場所にインストールします。
*[[http://usa.autodesk.com/adsk/servlet/pc/item?siteID=123112&id=10775847|Autodesk - Autodesk FBX - FBX Software Development Kit]] ※2013/11/09 14:43 時点の最新環境は FBX SDK 2014.2 です。
* VisualStudio2010のプロジェクト設定を行います。
* 追加のインクルードディレクトリ
* FBX SDK\2014.2\include
* 追加のライブラリディレクトリ
* Debug構成 FBX SDK\2014.2\lib\vs2010\x86\debug
* Release構成 FBX SDK\2014.2\lib\vs2010\x86\release
* 追加の依存ファイル
* マルチスレッド デバッグ DLL(/MDd)
* libfbxsdk-md.lib
* マルチスレッド デバッグ/MTd)
* libfbxsdk-mt.lib
* マルチスレッド DLL(/MD)
* libfbxsdk-md.lib
* マルチスレッド(/MT)
* libfbxsdk-mt.lib
これで環境設定は完了です。
==== ヘッダーファイル ====
#pragma once
#include
class CFBXModel
{
private:
// FBX SDK オブジェクト。
FbxManager* m_pFbxManager;
FbxScene* m_pFbxScene;
FbxImporter* m_pFbxImporter;
public:
//
//! コンストラクタ。
//
CFBXModel();
//
//! デストラクタ。
//
~CFBXModel();
private:
//
//! ポリゴンの三角形化。
//
void TriangulateRecursive( FbxNode* _pNode, FbxScene* _pScene );
//
//! FBX オブジェクトの 初期化。
//
bool InitializeSdkObjects();
public:
//
//! FBX読み込み。
//
bool Load( const char* _pName, FbxAxisSystem _axis );
// 解放。
void Releae();
};
==== ソースファイル ====
//----------------------------------
----------------------------------------------//
// CFBXModel.cpp
//--------------------------------------------------------------------------------//
#include "CFBXModel.h"
// コンストラクタ
CFBXModel::CFBXModel()
{
m_pFbxManager = NULL;
m_pFbxScene = NULL;
m_pFbxImporter = NULL;
}
// デストラクタ
CFBXModel::~CFBXModel()
{
Releae();
}
// FBXデータ解放。
void CFBXModel::Releae()
{
if( m_pFbxImporter )
{
m_pFbxImporter->Destroy();
m_pFbxImporter = NULL;
}
if( m_pFbxScene )
{
m_pFbxScene->Destroy();
m_pFbxScene = NULL;
}
if( m_pFbxManager )
{
m_pFbxManager->Destroy();
m_pFbxManager = NULL;
}
}
// ポリゴンの三角形化。
void CFBXModel::TriangulateRecursive( FbxNode* _pNode, FbxScene* _pScene )
{
FbxNodeAttribute* pNodeAttribute = _pNode->GetNodeAttribute();
if ( pNodeAttribute )
{
FbxNodeAttribute::EType type = pNodeAttribute->GetAttributeType();
if (type == FbxNodeAttribute::eMesh ||
type == FbxNodeAttribute::eNurbs ||
type == FbxNodeAttribute::eNurbsSurface ||
type == FbxNodeAttribute::ePatch)
{
FbxGeometryConverter lConverter( _pNode->GetFbxManager() );
lConverter.Triangulate( _pScene, true );
}
}
const int lChildCount = _pNode->GetChildCount();
for ( int lChildIndex = 0; lChildIndex < lChildCount; ++lChildIndex )
{
// 子ノードを探索。
TriangulateRecursive(_pNode->GetChild( lChildIndex ), _pScene );
}
}
// FBX オブジェクトの 初期化。
bool CFBXModel::InitializeSdkObjects()
{
// マネージャ作成。
m_pFbxManager = FbxManager::Create();
if( !m_pFbxManager )
{
FBXSDK_printf( "Error: Unable to create FBX Manager!\n" );
return false;
}
else
{
FBXSDK_printf( "Autodesk FBX SDK version %s\n", m_pFbxManager->GetVersion() );
}
// IOSettings オブジェクト作成。 このオブジェクトは全てのインポート/エクスポートの設定を保持します。
FbxIOSettings* pIOS = FbxIOSettings::Create( m_pFbxManager, IOSROOT );
m_pFbxManager->SetIOSettings( pIOS );
// 実行可能なディレクトリ(オプション)からプラグインをロードします。
FbxString lPath = FbxGetApplicationDirectory();
m_pFbxManager->LoadPluginsDirectory( lPath.Buffer() );
// シーン作成。
m_pFbxScene = FbxScene::Create( m_pFbxManager, "Scene" );
if( !m_pFbxScene )
{
FBXSDK_printf( "Error: Unable to create FBX scene!\n" );
return false;
}
return true;
}
// FBXファイルの読み込み
bool CFBXModel::Load( const char* _pName, FbxAxisSystem _axis )
{
int sFileFormat = -1;
// FBX SDK オブジェクトの初期化。
InitializeSdkObjects();
// インポータ作成。
m_pFbxImporter = FbxImporter::Create( m_pFbxManager, "Importer" );
if( !m_pFbxImporter )
{
FBXSDK_printf( "Error: Unable to create FBX importer!\n" );
return false;
}
// ファイルを指定したインポート(リーダー)ファイル形式で検出します。
if ( !m_pFbxManager->GetIOPluginRegistry()->DetectReaderFileFormat( _pName, sFileFormat ) )
{
// 検出できないファイル形式です。 FbxImporter::eFBX_BINARY 形式でトライします。
sFileFormat = m_pFbxManager->GetIOPluginRegistry()->FindReaderIDByDescription( "FBX binary (*.fbx)" );
}
// FBXファイルを読み込む。
if( !m_pFbxImporter->Initialize( _pName, sFileFormat ) )
{
FBXSDK_printf( "Error: Unable to create FBX initialize!\n" );
return false;
}
// FBX ファイルのバージョン取得。
int major, minor, revision;
m_pFbxImporter->GetFileVersion( major, minor, revision );
FBXSDK_printf( "FBX VERSION %d %d %d\n", major, minor, revision );
// 読み込んだFBXファイルからシーンデータを取り出す。
if( !m_pFbxImporter->Import( m_pFbxScene ) )
{
FBXSDK_printf( "Error: Unable to create FBX import!\n" );
return false;
}
// 軸の設定。
FbxAxisSystem OurAxisSystem = FbxAxisSystem::DirectX;
if( _axis == FbxAxisSystem::OpenGL )
{
OurAxisSystem = FbxAxisSystem::OpenGL;
}
// DirectX系に変換。
FbxAxisSystem SceneAxisSystem = m_pFbxScene->GetGlobalSettings().GetAxisSystem();
if( SceneAxisSystem != OurAxisSystem )
{
FbxAxisSystem::DirectX.ConvertScene( m_pFbxScene );
}
// 単位系の統一。
FbxSystemUnit SceneSystemUnit = m_pFbxScene->GetGlobalSettings().GetSystemUnit();
if( SceneSystemUnit.GetScaleFactor() != 1.0f )
{
// センチメーター単位にコンバートする。
FbxSystemUnit::cm.ConvertScene( m_pFbxScene );
}
// 三角形化(データによっては、四角形ポリゴンとか混ざっている場合がある)
TriangulateRecursive( m_pFbxScene->GetRootNode(), m_pFbxScene );
return true;
}