﻿#include <stdio.h>
#include <Windows.h>
#include <fbxsdk.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "main.h"
#include "texture2d.h"
#include "CSceneFBX.h"

void CSceneFBX::Init( void )
{
	const char* lFilename = "dude/dude.fbx";

	FbxManager* lSdkManager = FbxManager::Create();

	// Create the IO settings object. 
	FbxIOSettings *ios = FbxIOSettings::Create( lSdkManager, IOSROOT );
	lSdkManager->SetIOSettings( ios );

	// Create an importer using the SDK manager. 
	FbxImporter* lImporter = FbxImporter::Create( lSdkManager, "" );



	// Use the first argument as the filename for the importer. 
	if( !lImporter->Initialize( lFilename, -1, lSdkManager->GetIOSettings() ) )
	{
		char buf[ 256 ];
		sprintf( buf, "Call to FbxImporter::Initialize() failed.\nError returned: %s\n\n", lImporter->GetStatus().GetErrorString() );
		MessageBox( NULL, buf, "error", MB_OK );
		return;
	}

	// Create a new scene so that it can be populated by the imported file. 
	FbxScene* lScene = FbxScene::Create( lSdkManager, "myScene" );


	// Import the contents of the file into the scene. 
	lImporter->Import( lScene );
	FbxGeometryConverter converter( lSdkManager );





	// anime
	int anmimeNum = lImporter->GetAnimStackCount();
	//lScene->GetPoseCount();
	FbxArray<FbxString*> animationNames;
	lScene->FillAnimStackNameArray( animationNames );

	FbxTakeInfo* pTakeInfo = lScene->GetTakeInfo( animationNames[ 0 ]->Buffer() );

	// get start time
	FbxTime startTime = 0;
	FbxTime endTime = 0;
	startTime = pTakeInfo->mLocalTimeSpan.GetStart();
	endTime = pTakeInfo->mLocalTimeSpan.GetStop();



	// 三角ポリゴン化
	converter.Triangulate( lScene, true );

	// 縮退メッシュを削除
	converter.RemoveBadPolygonsFromMeshes( lScene );

	// マテリアルごとにメッシュ分離
	converter.SplitMeshesPerMaterial( lScene, true );

	// 再帰的にノードを漁る
	m_pTopMyNode = myNode::recursiveNode( lSdkManager, lScene->GetRootNode(), false, startTime, endTime );

	lImporter->Destroy();
	lScene->Destroy();
	lSdkManager->Destroy();

}

void CSceneFBX::Uninit( void )
{
	if( m_pV != NULL )
	{
		delete m_pV;
		m_pV = NULL;
	}
	//if( m_pVt != NULL )
	//{
	//	delete m_pVt;
	//	m_pVt = NULL;
	//}
	//if( m_pVn != NULL )
	//{
	//	delete m_pVn;
	//	m_pVn = NULL;
	//}
	if( m_pFace != NULL )
	{
		delete m_pFace;
		m_pFace = NULL;
	}
}

void CSceneFBX::Update( void )
{

}

//void CSceneFBX::Draw( void )
//{
//	glPushMatrix();
//	//glBindTexture( GL_TEXTURE_2D, m_texture );
//
//	glBegin( GL_TRIANGLES );
//	for( int i = 0; i < m_faceCount; i++ )
//	{
//		//glNormal3fv( ( float* ) &m_pVn[ pFace[ i ].vnIndex ] );
//		//glTexCoord2fv( ( float* ) &m_pVt[ pFace[ i ].vtIndex ] );
//		glVertex3fv( ( float* ) &m_pV[ m_pFace[ i ].vIndex ] );
//	}
//	glEnd();
//	glBindTexture( GL_TEXTURE_2D, 0 );
//
//	glPopMatrix();
//}

/**
* Return a string-based representation based on the attribute type.
*/
std::string myNode::GetttributeTypeName( FbxNodeAttribute::EType type )
{
	switch( type )
	{
		case FbxNodeAttribute::eUnknown: return "unidentified";
		case FbxNodeAttribute::eNull: return "null";
		case FbxNodeAttribute::eMarker: return "marker";
		case FbxNodeAttribute::eSkeleton: return "skeleton";
		case FbxNodeAttribute::eMesh: return "mesh";
		case FbxNodeAttribute::eNurbs: return "nurbs";
		case FbxNodeAttribute::ePatch: return "patch";
		case FbxNodeAttribute::eCamera: return "camera";
		case FbxNodeAttribute::eCameraStereo: return "stereo";
		case FbxNodeAttribute::eCameraSwitcher: return "camera switcher";
		case FbxNodeAttribute::eLight: return "light";
		case FbxNodeAttribute::eOpticalReference: return "optical reference";
		case FbxNodeAttribute::eOpticalMarker: return "marker";
		case FbxNodeAttribute::eNurbsCurve: return "nurbs curve";
		case FbxNodeAttribute::eTrimNurbsSurface: return "trim nurbs surface";
		case FbxNodeAttribute::eBoundary: return "boundary";
		case FbxNodeAttribute::eNurbsSurface: return "nurbs surface";
		case FbxNodeAttribute::eShape: return "shape";
		case FbxNodeAttribute::eLODGroup: return "lodgroup";
		case FbxNodeAttribute::eSubDiv: return "subdiv";
		default: return "unknown";
	}
}

//=============================================================================
// 描画処理
//=============================================================================
void myNode::recursiveDraw( int currentFrame )
{
	glPushMatrix();


	glScalef( scaling.x, scaling.y, scaling.z );
	glRotatef( rotation.x, 1, 0, 0 );
	glRotatef( rotation.y, 0, 1, 0 );
	glRotatef( rotation.z, 0, 0, 1 );
	glTranslatef( translation.x, translation.y, translation.z );

	for( auto itm = meshes.begin(); itm != meshes.end(); ++itm )
	{
		// テクスチャ設定
		if( !textures.empty() )
		{
			glBindTexture( GL_TEXTURE_2D, textures[ itm->materialIndex ] );
		}


		// ポリゴン描画
		glBegin( GL_TRIANGLES );


		if( itm->matrixes.empty() )
		{
			// 骨なし（つまり剛体の塊）
			for( size_t i = 0; i < itm->positionIndices.size(); i++ )
			{


				if( !itm->normals.empty() ) glNormal3fv( itm->normals[ itm->normalIndices[ i ] ] );
				if( !itm->texcoords.empty() ) glTexCoord2fv( itm->texcoords[ itm->texcoordIndices[ i ] ] );
				glVertex3fv( itm->points[ itm->positionIndices[ i ] ].positions );

			}

		}
		else
		{
			// 骨あり（つまりワンスキンなど）  

			// 頂点の座標変換
			std::vector<D3DXVECTOR3> positions;
			positions.reserve( itm->points.size() );

			D3DXMATRIX mtx;
			for( auto it = itm->points.begin(); it != itm->points.end(); ++it )
			{
				ZeroMemory( &mtx, sizeof( D3DXMATRIX ) );
				for( auto itb = it->bornRefarences.begin(); itb != it->bornRefarences.end(); ++itb )
				{
					int AllFrame = itm->matrixes[ itb->index ].size();

					mtx += itm->matrixes[ itb->index ][ currentFrame % AllFrame ] * itb->weight;
				}
				D3DXVECTOR3 pos;
				D3DXVec3TransformCoord( &pos, &it->positions, &mtx );
				positions.push_back( pos );
			}
			for( size_t i = 0; i < itm->positionIndices.size(); i++ )
			{
				if( !itm->normals.empty() ) glNormal3fv( itm->normals[ itm->normalIndices[ i ] ] );
				if( !itm->texcoords.empty() ) glTexCoord2fv( itm->texcoords[ itm->texcoordIndices[ i ] ] );
				glVertex3fv( positions[ itm->positionIndices[ i ] ] );
			}
		}
		glEnd();
	}
	std::for_each( children.begin(), children.end(), [ currentFrame ]( myNode* p ) {p->recursiveDraw( currentFrame ); } );
	glPopMatrix();
}

// Get the geometry offset to a node. It is never inherited by the children.
FbxMatrix myNode::GetGeometry( FbxNode* pNode )
{
	const FbxVector4 lT = pNode->GetGeometricTranslation( FbxNode::eSourcePivot );
	const FbxVector4 lR = pNode->GetGeometricRotation( FbxNode::eSourcePivot );
	const FbxVector4 lS = pNode->GetGeometricScaling( FbxNode::eSourcePivot );

	return FbxAMatrix( lT, lR, lS );
}

void myNode::analyzeCluster( FbxMesh* pMesh, FbxTime startTime, FbxTime endTime )
{
	D3DXMATRIX mtxIdentitiy;
	D3DXMatrixIdentity( &mtxIdentitiy );
	FbxTime oneFrameTime;
	oneFrameTime.SetTime( 0, 0, 0, 1, 0, 0, FbxTime::eFrames60 );

	// スキンの数を取得
	int skinCount = pMesh->GetDeformerCount( FbxDeformer::eSkin );
	for( int skinNum = 0; skinNum < skinCount; skinNum++ )
	{

		// スキンを取得
		FbxSkin* pSkin = ( FbxSkin* ) pMesh->GetDeformer( skinNum, FbxDeformer::eSkin );
		// クラスターの数を取得
		int clusterCount = pSkin->GetClusterCount();

		for( int clusterNum = 0; clusterNum < clusterCount; clusterNum++ )
		{
			meshes.back().matrixes.emplace_back( 0 );

			// クラスタを取得
			FbxCluster* pCluster = pSkin->GetCluster( clusterNum );
			// このクラスタが影響を及ぼす頂点インデックスの個数を取得
			int pointIndexCount = pCluster->GetControlPointIndicesCount();
			if( !pointIndexCount )
			{
				// このメッシュにおいて、このクラスタは無視していいと思う...
				meshes.back().matrixes.back().push_back( mtxIdentitiy );
				continue;
			}

			// 初期姿勢行列の取得
			FbxAMatrix lReferenceGlobalInitPosition;
			FbxAMatrix lReferenceGlobalCurrentPosition;
			FbxAMatrix lReferenceGeometry;
			FbxAMatrix lClusterGlobalInitPosition;
			FbxAMatrix lClusterGlobalCurrentPosition;
			FbxAMatrix lClusterRelativeInitPosition;
			FbxAMatrix lClusterRelativeCurrentPositionInverse;


			pCluster->GetTransformMatrix( lReferenceGlobalInitPosition );
			// lReferenceGlobalCurrentPosition = pGlobalPosition; // <- たぶんワールド座標変換行列ではないかと
			// Multiply lReferenceGlobalInitPosition by Geometric Transformation
			( FbxMatrix ) lReferenceGeometry = GetGeometry( pMesh->GetNode() );
			lReferenceGlobalInitPosition *= lReferenceGeometry;


			// Get the link initial global position and the link current global position.
			pCluster->GetTransformLinkMatrix( lClusterGlobalInitPosition );
			// lClusterGlobalCurrentPosition = GetGlobalPosition(pCluster->GetLink(), pTime, pPose); // <- ポーズ行列の取り方？？？
			// 指定時間のボーン姿勢の取得
			// フレーム単位の時間（1/60s）を入れていく

			for( FbxTime currentTime = startTime; currentTime < endTime; currentTime += oneFrameTime )
			{
				lClusterGlobalCurrentPosition = pCluster->GetLink()->EvaluateGlobalTransform( currentTime );

				// Compute the initial position of the link relative to the reference.
				lClusterRelativeInitPosition = lClusterGlobalInitPosition.Inverse() * lReferenceGlobalInitPosition;


				// Compute the current position of the link relative to the reference.
				lClusterRelativeCurrentPositionInverse = lReferenceGlobalCurrentPosition.Inverse() * lClusterGlobalCurrentPosition;

				// Compute the shift of the link relative to the reference.
				FbxAMatrix VertexTransformMatrix = lClusterRelativeCurrentPositionInverse * lClusterRelativeInitPosition;
				// ↑ 初期姿勢行列も考慮されたモーションボーン行列なので、これで頂点座標を変換するだけで良い  
				D3DXMATRIX d3dMtx;
				for( int y = 0; y < 4; y++ )
				{
					for( int x = 0; x < 4; x++ )
					{
						d3dMtx( x, y ) = ( float ) VertexTransformMatrix.Get( x, y );
					}
				}

				//meshes.back().matrixes.emplace_back( d3dMtx ); // vector型最後尾要素
				meshes.back().matrixes.back().push_back( d3dMtx );

			}

			int* pointIndexArray = pCluster->GetControlPointIndices();
			double* weightArray = pCluster->GetControlPointWeights();
			for( int i = 0; i < pointIndexCount; i++ )
			{
				meshes.back().points[ pointIndexArray[ i ] ].bornRefarences.push_back( BornRefarence( clusterNum, static_cast< float >( weightArray[ i ] ) ) );
			}
		}
	}
}


myNode* myNode::recursiveNode( FbxManager* pManager, FbxNode* pNode, bool bTexcoordVReverse, FbxTime startTime, FbxTime endTime )
{
	myNode* p = NULL;
	if( pNode )
	{
		p = new myNode;
		p->name = pNode->GetName();
		p->translation.x = static_cast< float >( pNode->LclTranslation.Get()[ 0 ] );
		p->translation.y = static_cast< float >( pNode->LclTranslation.Get()[ 1 ] );
		p->translation.z = static_cast< float >( pNode->LclTranslation.Get()[ 2 ] );
		p->rotation.x = static_cast< float >( pNode->LclRotation.Get()[ 0 ] );
		p->rotation.y = static_cast< float >( pNode->LclRotation.Get()[ 1 ] );
		p->rotation.z = static_cast< float >( pNode->LclRotation.Get()[ 2 ] );
		p->scaling.x = static_cast< float >( pNode->LclScaling.Get()[ 0 ] );
		p->scaling.y = static_cast< float >( pNode->LclScaling.Get()[ 1 ] );
		p->scaling.z = static_cast< float >( pNode->LclScaling.Get()[ 2 ] );

		for( int i = 0; i < pNode->GetNodeAttributeCount(); i++ )
		{
			FbxNodeAttribute::EType type = pNode->GetNodeAttributeByIndex( i )->GetAttributeType();
			p->attributeNames.push_back( GetttributeTypeName( type ) );
			if( type == FbxNodeAttribute::eMesh )
			{
				// マテリアル情報の解析（マテリアルリスト化）
				p->analyzeMaterial( pNode );

				p->meshes.push_back( Mesh() );

				// メッシュ情報の取得
				FbxMesh* pMesh = FbxCast<FbxMesh>( pNode->GetNodeAttributeByIndex( i ) );

				// 頂点座標解析
				p->analyzePosition( pMesh );
				// 法線解析
				p->analyzeNormal( pMesh );
				// UV解析
				p->analyzeTexcoord( pMesh, bTexcoordVReverse );
				// マテリアル解析（参照情報の取得）
				p->analyzeMaterial( pMesh );
				//ボーン解析 
				p->analyzeCluster(pMesh, startTime, endTime);
			}
			//else
			//{
		 // // メッシュではないアトリビュート
			//	MessageBoxA( NULL, GetttributeTypeName( type ).c_str(), "アトリビュート", MB_OK );
			//}
		}
		for( int i = 0; i < pNode->GetChildCount(); i++ )
		{
			p->children.push_back( recursiveNode( pManager, pNode->GetChild( i ), bTexcoordVReverse, startTime, endTime ) );
		}
	}
	return p;
}

void myNode::analyzePosition( FbxMesh* pMesh )
{     // コントロールポイント数の取得
	int controlPointsCount = pMesh->GetControlPointsCount();
	  // 頂点座標用コンテナの領域予約
	meshes.back().points.reserve( controlPointsCount );
	  // 頂点データの取得
	FbxVector4* pP = pMesh->GetControlPoints();
	for( int i = 0; i < pMesh->GetControlPointsCount(); i++ )
	{
		meshes.back().points.push_back(
			D3DXVECTOR3( static_cast< float >( pP[ i ][ 0 ] ),
				static_cast< float >( pP[ i ][ 1 ] ),
				static_cast< float >( pP[ i ][ 2 ] ) ) );
	}
	  /* 頂点インデックスの取得 */
	  // インデックス数を取得
	int polygonVertexCount = pMesh->GetPolygonVertexCount();

	  // 頂点座標インデックス用コンテナの領域予約
	meshes.back().positionIndices.reserve( polygonVertexCount );
	// インデックスバッファの取得
	for( int i = 0; i < polygonVertexCount; i++ )
	{
		meshes.back().positionIndices.push_back( static_cast< unsigned short >( pMesh->GetPolygonVertices()[ i ] ) );
	}
}


void myNode::analyzeNormal( FbxMesh* pMesh )
{
	// レイヤー数の取得
	int layerCount = pMesh->GetLayerCount();

	for( int layer = 0; layer < layerCount; layer++ )
	{
		// 法線の取得
		FbxLayerElementNormal* pElementNormal = pMesh->GetElementNormal( layer );

		if( !pElementNormal )
		{
			continue;
		}
		// 法線数の取得
		int normalCount = pElementNormal->GetDirectArray().GetCount();

		// 法線格納用コンテナの領域予約
		meshes.back().normals.reserve( normalCount );

		// 法線データの取得
		for( int i = 0; i < normalCount; i++ )
		{
			meshes.back().normals.push_back( D3DXVECTOR3(
				static_cast< float >( pElementNormal->GetDirectArray()[ i ][ 0 ] ),
				static_cast< float >( pElementNormal->GetDirectArray()[ i ][ 1 ] ),
				static_cast< float >( pElementNormal->GetDirectArray()[ i ][ 2 ] ) ) );
		}

		// マッピングモード・リファレンスモード取得
		FbxLayerElement::EMappingMode mappingMode = pElementNormal->GetMappingMode();
		FbxLayerElement::EReferenceMode referenceMode = pElementNormal->GetReferenceMode();

		switch( mappingMode )
		{
			case FbxLayerElement::eNone:
				MessageBox( NULL, "Normal MappingMode = mappingMode", "未実装", MB_OK );
				break;
			case FbxLayerElement::eByControlPoint:
				// 頂点バッファと同じインデックスを使用  
				if( referenceMode == FbxLayerElement::eDirect )
				{
					// 法線インデックス格納用コンテナの領域予約
					meshes.back().normalIndices.reserve( meshes.back().points.size() );
					// 頂点バッファと同じインデックスをコピー
					meshes.back().normalIndices.assign( meshes.back().positionIndices.begin(), meshes.back().positionIndices.end() );
				}
				else if( referenceMode == FbxLayerElement::eIndexToDirect
					|| referenceMode == FbxLayerElement::eIndex )
				{
					MessageBox( NULL,
						"Normal ReferenceMode = eIndexToDirect or eIndex, MappingMode = eByControlPoint",
						"未実装", MB_OK );
				}
				break;
			case FbxLayerElement::eByPolygonVertex:
				/* 法線独自のインデックスを使用 */
				if( referenceMode == FbxLayerElement::eDirect )
				{
					// インデックス参照の必要なし => インデックスを作成


					// 法線インデックス格納用コンテナの領域予約
					meshes.back().normalIndices.reserve( normalCount );
					// 法線インデックスの作成
					for( int i = 0; i < normalCount; i++ )
					{
						meshes.back().normalIndices.push_back( i );
					}
				}
				else if( referenceMode == FbxLayerElement::eIndexToDirect
					|| referenceMode == FbxLayerElement::eIndex )
				{


					// 独自インデックスを所持


					// インデックス数の取得
					int normalIndexCount = pElementNormal->GetIndexArray().GetCount();
					// 法線インデックス格納用コンテナの領域予約
					meshes.back().normalIndices.reserve( normalIndexCount );
					// 法線インデックスの取得
					for( int i = 0; i < normalIndexCount; i++ )
					{
						meshes.back().normalIndices.push_back( pElementNormal->GetIndexArray()[ i ] );
					}
				}
				break;
			case FbxLayerElement::eByPolygon:
				MessageBox( NULL, "Normal MappingMode = eByPolygon", "未実装", MB_OK );
				break;
			case FbxLayerElement::eByEdge:
				MessageBox( NULL, "Normal MappingMode = eByEdge", "未実装", MB_OK );
				break;
			case FbxLayerElement::eAllSame:
				MessageBox( NULL, "Normal MappingMode = eAllSame", "未実装", MB_OK );
				break;
			default:
				MessageBox( NULL, "Normal ???", "未実装", MB_OK );
				break;
		}
	}
}

void myNode::analyzeTexcoord( FbxMesh* pMesh, bool bRevers )
{
	int layerCount = pMesh->GetLayerCount();
	if( !layerCount )
	{
		MessageBox( NULL, "レイヤーを持っていないメッシュを確認", "Analyze Texcoord", MB_OK ); return;
	}
	for( int layer = 0; layer < layerCount; layer++ )
	{
		// UVの取得
		FbxLayerElementUV* pElementUV = pMesh->GetLayer( layer )->GetUVs();
		if( !pElementUV )
		{
			MessageBox( NULL, "...UVのないメッシュレイヤーを確認", "Analyze Texcoord", MB_OK );             continue;
		}
		// UVセット名を取得
		// = pElementUV->GetName();

		// マッピングモード・リファレンスモード取得
		FbxLayerElement::EMappingMode mappingMode = pElementUV->GetMappingMode();
		FbxLayerElement::EReferenceMode referenceMode = pElementUV->GetReferenceMode();
		if( mappingMode == FbxLayerElement::eByPolygonVertex )
		{
			if( referenceMode == FbxLayerElement::eIndexToDirect || referenceMode == FbxLayerElement::eIndex )
			{
				int uvIndexCount = pElementUV->GetIndexArray().GetCount();
				meshes.back().texcoordIndices.reserve( uvIndexCount );
				for( int i = 0; i < uvIndexCount; i++ )
				{
					meshes.back().texcoordIndices.push_back( pElementUV->GetIndexArray().GetAt( i ) );
				}
				int uvCount = pElementUV->GetDirectArray().GetCount();
				meshes.back().texcoords.reserve( uvCount );
				for( int i = 0; i < uvCount; i++ )
				{
					meshes.back().texcoords.push_back( D3DXVECTOR2( static_cast< float >( pElementUV->GetDirectArray().GetAt( i )[ 0 ] ), static_cast< float >( bRevers ? 1 - pElementUV->GetDirectArray().GetAt( i )[ 1 ] : pElementUV->GetDirectArray().GetAt( i )[ 1 ] ) ) );
				}
			}
			else
			{
				MessageBox( NULL, "Texcoord::未対応のリファレンスモードを取得", "FbxLayerElement::eByPolygonVertex", MB_OK );
				break;
			}
		}
		else if( mappingMode == FbxLayerElement::eByControlPoint )
		{
			MessageBox( NULL, "...未対応マッピングモード[eByControlPoint]を取得した", "Analyze Texcoord", MB_OK );
		}
		else if( mappingMode == FbxLayerElement::eByPolygon )
		{
			MessageBox( NULL, "...未対応マッピングモード[eByPolygon]を取得した", "Analyze Texcoord", MB_OK );
		}
		else if( mappingMode == FbxLayerElement::eByEdge )
		{
			MessageBox( NULL, "...未対応マッピングモード[eByEdge]を取得した", "Analyze Texcoord", MB_OK );
		}
		else
		{
			MessageBox( NULL, "...知らないマッピングモードを取得した", "Analyze Texcoord", MB_OK );
		}
		break; // とりあえず１個めだけ
	}
}

void myNode::analyzeMaterial( FbxNode* pNode )
{
	// マテリアル数の取得
	int materialCount = pNode->GetMaterialCount();

	textures.reserve( materialCount );
	for( int i = 0; i < materialCount; i++ )
	{
		// マテリアル情報の取得
		FbxSurfaceMaterial* pMaterial = pNode->GetMaterial( i );

		// ディフューズ情報の取得
		FbxProperty diffuseProperty = pMaterial->FindProperty( FbxSurfaceMaterial::sDiffuse );

		// プロパティが持っているレイヤードテクスチャの枚数をチェック
		int layeredTextureCount = diffuseProperty.GetSrcObjectCount<FbxLayeredTexture>();

		// レイヤードテクスチャが無ければ通常テクスチャ
		if( layeredTextureCount == 0 )
		{


			// 通常テクスチャの枚数をチェック
			int textureCount = diffuseProperty.GetSrcObjectCount<FbxFileTexture>();


			// 各テクスチャについてテクスチャ情報をゲット
			for( int i = 0; i < textureCount; i++ )
			{


				// i番目のテクスチャオブジェクト取得
				FbxFileTexture* pTexture = diffuseProperty.GetSrcObject<FbxFileTexture>( i );


				// テクスチャファイル名の取得

				// std::string fileName = pTexture->GetFileName();
				std::string relFileName = pTexture->GetRelativeFileName();


				// UVSet名の取得
				std::string uvSetName = pTexture->UVSet.Get().Buffer();


				// 辞書登録
				// texfile2UVset[relFileName] = uvSetName;
				std::string strPathName = "data/" + relFileName;
				// テクスチャの読み込みと管理
				textures.push_back( Texture2D::LoadTGA( strPathName.c_str() ) );
			}
		}
		else
		{
			// レイヤードテクスチャあり
			MessageBox( NULL, "レイヤードテクスチャ", "マテリアルの取得", MB_OK );
		}
	}
}


void myNode::analyzeMaterial( FbxMesh* pMesh )
{
	int layerCount = pMesh->GetLayerCount();
	for( int layer = 0; layer < layerCount; layer++ )
	{
		FbxLayerElementMaterial* pElementMaterial = pMesh->GetLayer( layer )->GetMaterials();
		if( !pElementMaterial )
		{
			continue;
		}
		int materialIndexCount = pElementMaterial->GetIndexArray().GetCount();
		if( materialIndexCount == 0 )
		{
			continue;
		}
		FbxLayerElement::EMappingMode mappingMode = pElementMaterial->GetMappingMode();     FbxLayerElement::EReferenceMode referenceMode = pElementMaterial->GetReferenceMode();
		if( mappingMode == FbxLayerElement::eAllSame )
		{
			if( referenceMode == FbxLayerElement::eIndexToDirect )
			{
				// メッシュ全部がこのマテリアルインデックス
				meshes.back().materialIndex = pElementMaterial->GetIndexArray().GetAt( 0 );
			}
			else
			{
				MessageBox( NULL, "...未対応のリファレンスモードを取得した", "Material MappingMode = eAllSame", MB_OK );
			}
		}
		else if( mappingMode == FbxLayerElement::eByControlPoint )
		{
			MessageBox( NULL, "...未対応のマッピングモード[eByControlPoint]を取得した", "Material MappingMode", MB_OK );
		}
		else if( mappingMode == FbxLayerElement::eByPolygon )
		{
			// マテリアル分割されているはずだから、一番はじめのだけでいい
			meshes.back().materialIndex = pElementMaterial->GetIndexArray().GetAt( 0 );
		}
		else if( mappingMode == FbxLayerElement::eByEdge )
		{
			MessageBox( NULL, "...未対応のマッピングモード[eByEdge]を取得した", "Material MappingMode", MB_OK );
		}
		else
		{
			MessageBox( NULL, "...未対応のマッピングモードを取得した", "Material MappingMode", MB_OK );
		}
	}
}

void CSceneFBX::Draw( int currentFrame )
{
	// マトリクス退避
	glMatrixMode( GL_MODELVIEW );
	glPushMatrix();


	// マテリアル設定
	MATERIAL material;

	material.Diffuse.r = 1.0f;
	material.Diffuse.g = 1.0f;
	material.Diffuse.b = 1.0f;
	material.Diffuse.a = 1.0f;
	material.Ambient.r = 1.0f;
	material.Ambient.g = 1.0f;
	material.Ambient.b = 1.0f;
	material.Ambient.a = 1.0f;
	material.Specular.r = 1.0f;
	material.Specular.g = 1.0f;
	material.Specular.b = 1.0f;
	material.Specular.a = 1.0f;
	material.Emission.r = 0.0f;
	material.Emission.g = 0.0f;
	material.Emission.b = 0.0f;
	material.Emission.a = 1.0f;
	material.Shininess = 0.5f;

	glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, ( float* ) &material.Ambient );
	glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, ( float* ) &material.Diffuse );
	glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, ( float* ) &material.Specular );
	glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, ( float* ) &material.Emission );
	glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, material.Shininess );
	glEnable( GL_LIGHTING );     
	glEnable( GL_LIGHT0 );
	// glScalef(0.1f, 0.1f, 0.1f);  
	glPushMatrix();
	m_pTopMyNode->recursiveDraw( currentFrame );
	glPopMatrix();
	glPopMatrix();
}