Beispiel #1
0
//--------------------------------------------------------------------------------
void App::CreateTerrainGeometry()
{
    Log::Get().Write( L"Creating terrain geometry" );

    // Setup actual resource
    m_pTerrainGeometry = NULL;
    m_pTerrainGeometry = GeometryPtr( new GeometryDX11( ) );

    // Create vertex data
    VertexElementDX11 *pPositions = new VertexElementDX11( 3, (TERRAIN_X_LEN + 1) * (TERRAIN_Z_LEN + 1) );
    pPositions->m_SemanticName = "CONTROL_POINT_POSITION";
    pPositions->m_uiSemanticIndex = 0;
    pPositions->m_Format = DXGI_FORMAT_R32G32B32_FLOAT;
    pPositions->m_uiInputSlot = 0;
    pPositions->m_uiAlignedByteOffset = 0;
    pPositions->m_InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
    pPositions->m_uiInstanceDataStepRate = 0;

    VertexElementDX11 *pTexCoords = new VertexElementDX11( 2, (TERRAIN_X_LEN + 1) * (TERRAIN_Z_LEN + 1) );
    pTexCoords->m_SemanticName = "CONTROL_POINT_TEXCOORD";
    pTexCoords->m_uiSemanticIndex = 0;
    pTexCoords->m_Format = DXGI_FORMAT_R32G32_FLOAT;
    pTexCoords->m_uiInputSlot = 0;
    pTexCoords->m_uiAlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
    pTexCoords->m_InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
    pTexCoords->m_uiInstanceDataStepRate = 0;

    Vector3f *pPosData = pPositions->Get3f( 0 );
    Vector2f *pTCData = pTexCoords->Get2f( 0 );

    float fWidth = static_cast< float >( TERRAIN_X_LEN );
    float fHeight = static_cast< float >( TERRAIN_Z_LEN );

    for( int x = 0; x < TERRAIN_X_LEN + 1; ++x )
    {
        for( int z = 0; z < TERRAIN_Z_LEN + 1; ++z )
        {
            float fX = static_cast<float>(x) / fWidth - 0.5f;
            float fZ = static_cast<float>(z) / fHeight - 0.5f;
            pPosData[ x + z * (TERRAIN_X_LEN + 1) ] = Vector3f( fX, 0.0f, fZ );
            pTCData[ x + z * (TERRAIN_X_LEN + 1) ] = Vector2f( fX + 0.5f, fZ + 0.5f );
        }
    }

    m_pTerrainGeometry->AddElement( pPositions );
    m_pTerrainGeometry->AddElement( pTexCoords );

    // Create index data
    for( int x = 0; x < TERRAIN_X_LEN; ++x )
    {
        for( int z = 0; z < TERRAIN_Z_LEN; ++z )
        {
            // Define 12 control points per terrain quad

            // 0-3 are the actual quad vertices
            m_pTerrainGeometry->AddIndex( (z + 0) + (x + 0) * (TERRAIN_X_LEN + 1) );
            m_pTerrainGeometry->AddIndex( (z + 1) + (x + 0) * (TERRAIN_X_LEN + 1) );
            m_pTerrainGeometry->AddIndex( (z + 0) + (x + 1) * (TERRAIN_X_LEN + 1) );
            m_pTerrainGeometry->AddIndex( (z + 1) + (x + 1) * (TERRAIN_X_LEN + 1) );

            // 4-5 are +x
            m_pTerrainGeometry->AddIndex( clamp(z + 0, 0, TERRAIN_Z_LEN) + clamp(x + 2, 0, TERRAIN_X_LEN) * (TERRAIN_X_LEN + 1) );
            m_pTerrainGeometry->AddIndex( clamp(z + 1, 0, TERRAIN_Z_LEN) + clamp(x + 2, 0, TERRAIN_X_LEN) * (TERRAIN_X_LEN + 1) );

            // 6-7 are +z
            m_pTerrainGeometry->AddIndex( clamp(z + 2, 0, TERRAIN_Z_LEN) + clamp(x + 0, 0, TERRAIN_X_LEN) * (TERRAIN_X_LEN + 1) );
            m_pTerrainGeometry->AddIndex( clamp(z + 2, 0, TERRAIN_Z_LEN) + clamp(x + 1, 0, TERRAIN_X_LEN) * (TERRAIN_X_LEN + 1) );

            // 8-9 are -x
            m_pTerrainGeometry->AddIndex( clamp(z + 0, 0, TERRAIN_Z_LEN) + clamp(x - 1, 0, TERRAIN_X_LEN) * (TERRAIN_X_LEN + 1) );
            m_pTerrainGeometry->AddIndex( clamp(z + 1, 0, TERRAIN_Z_LEN) + clamp(x - 1, 0, TERRAIN_X_LEN) * (TERRAIN_X_LEN + 1) );

            // 10-11 are -z
            m_pTerrainGeometry->AddIndex( clamp(z - 1, 0, TERRAIN_Z_LEN) + clamp(x + 0, 0, TERRAIN_X_LEN) * (TERRAIN_X_LEN + 1) );
            m_pTerrainGeometry->AddIndex( clamp(z - 1, 0, TERRAIN_Z_LEN) + clamp(x + 1, 0, TERRAIN_X_LEN) * (TERRAIN_X_LEN + 1) );
        }
    }

    // Move the in-memory geometry to be
    // an actual renderable resource
    m_pTerrainGeometry->LoadToBuffers();
    m_pTerrainGeometry->SetPrimitiveType( D3D11_PRIMITIVE_TOPOLOGY_12_CONTROL_POINT_PATCHLIST );

    Log::Get().Write( L"Created terrain geometry" );
}
//--------------------------------------------------------------------------------
GeometryPtr GeometryLoaderDX11::loadMS3DFileWithAnimation( std::wstring filename, SkinnedActor* pActor )
{
	// Get the file path to the models
	FileSystem fs;
	filename = fs.GetModelsFolder() + filename;

	// Temporary Milkshape structures
	unsigned short usVertexCount = 0;
	unsigned short usTriangleCount = 0;
	unsigned short usGroupCount = 0;
	unsigned short usMaterialCount = 0;
	MS3DVertex* pMS3DVertices = NULL;
	MS3DTriangle* pMS3DTriangles = NULL;
	MS3DGroup* pMS3DGroups = NULL;
	MS3DMaterial* pMS3DMaterials = NULL;

	int i;
	std::ifstream fin;
	MS3DHeader header;

	// Open the file and read the MS3D header data
	fin.open( filename.c_str(),std::ios::binary );
	fin.read((char*)(&(header.id)), sizeof(header.id));
	fin.read((char*)(&(header.version)), sizeof(header.version));
	if (header.version!=3 && header.version!=4)
		return NULL;

	// Load all the vertices
	fin.read((char*)(&usVertexCount), sizeof(unsigned short));
	pMS3DVertices = new MS3DVertex[usVertexCount];
	for (i=0; i < usVertexCount; i++)
	{
		fin.read((char*)&(pMS3DVertices[i].flags), sizeof(unsigned char));
		fin.read((char*)&(pMS3DVertices[i].vertex[0]), sizeof(float));
		fin.read((char*)&(pMS3DVertices[i].vertex[1]), sizeof(float));
		fin.read((char*)&(pMS3DVertices[i].vertex[2]), sizeof(float));
		fin.read((char*)&(pMS3DVertices[i].boneId), sizeof(char));
		fin.read((char*)&(pMS3DVertices[i].referenceCount), sizeof(unsigned char));
	}

	// Load all the triangle indices
	fin.read((char*)(&usTriangleCount), sizeof(unsigned short));
	pMS3DTriangles = new MS3DTriangle[usTriangleCount];
	for (i=0; i < usTriangleCount; i++)
	{
		fin.read((char*)&(pMS3DTriangles[i].flags),sizeof(unsigned short));
		fin.read((char*)&(pMS3DTriangles[i].vertexIndices[0]), sizeof(unsigned short)); //3*sizeof(unsigned short));
		fin.read((char*)&(pMS3DTriangles[i].vertexIndices[1]), sizeof(unsigned short)); //3*sizeof(unsigned short));
		fin.read((char*)&(pMS3DTriangles[i].vertexIndices[2]), sizeof(unsigned short)); //3*sizeof(unsigned short));
		fin.read((char*)&(pMS3DTriangles[i].vertexNormals[0]), 3*sizeof(float));
		fin.read((char*)&(pMS3DTriangles[i].vertexNormals[1]), 3*sizeof(float));
		fin.read((char*)&(pMS3DTriangles[i].vertexNormals[2]), 3*sizeof(float));
		fin.read((char*)&(pMS3DTriangles[i].s), 3*sizeof(float));
		fin.read((char*)&(pMS3DTriangles[i].t), 3*sizeof(float));
		fin.read((char*)&(pMS3DTriangles[i].smoothingGroup), sizeof(unsigned char));
		fin.read((char*)&(pMS3DTriangles[i].groupIndex), sizeof(unsigned char));
	}

	// Load all the group information
	fin.read((char*)(&usGroupCount), sizeof(unsigned short));
	pMS3DGroups = new MS3DGroup[usGroupCount];
	for (i=0; i < usGroupCount; i++)
	{
		fin.read((char*)&(pMS3DGroups[i].flags), sizeof(unsigned char));
		fin.read((char*)&(pMS3DGroups[i].name), sizeof(char[32]));
		fin.read((char*)&(pMS3DGroups[i].numtriangles), sizeof(unsigned short));
		unsigned short triCount = pMS3DGroups[i].numtriangles;
		pMS3DGroups[i].triangleIndices = new unsigned short[triCount];
		fin.read((char*)(pMS3DGroups[i].triangleIndices), sizeof(unsigned short) * triCount);
		fin.read((char*)&(pMS3DGroups[i].materialIndex), sizeof(char));
	}

	// Load all the material information
	fin.read((char*)(&usMaterialCount),sizeof(unsigned short));
	pMS3DMaterials = new MS3DMaterial[usMaterialCount];
	for (i=0; i < usMaterialCount; i++)
	{
		fin.read((char*)&(pMS3DMaterials[i].name), sizeof(char[32]));
		fin.read((char*)&(pMS3DMaterials[i].ambient), 4 * sizeof(float));
		fin.read((char*)&(pMS3DMaterials[i].diffuse), 4 * sizeof(float));
		fin.read((char*)&(pMS3DMaterials[i].specular), 4 * sizeof(float));
		fin.read((char*)&(pMS3DMaterials[i].emissive), 4 * sizeof(float));
		fin.read((char*)&(pMS3DMaterials[i].shininess), sizeof(float));
		fin.read((char*)&(pMS3DMaterials[i].transparency), sizeof(float));
		fin.read((char*)&(pMS3DMaterials[i].mode), sizeof(char));
		fin.read((char*)&(pMS3DMaterials[i].texture), sizeof(char[128]));
		fin.read((char*)&(pMS3DMaterials[i].alphamap), sizeof(char[128]));
	}

	float fAnimationFPS; // 4 bytes
	float fCurrentTime; // 4 bytes
	int iTotalFrames; // 4 bytes
	unsigned short nNumJoints; // 2 bytes

	fin.read((char*)&(fAnimationFPS), sizeof(float));
	fin.read((char*)&(fCurrentTime), sizeof(float));
	fin.read((char*)&(iTotalFrames), sizeof(int));
	fin.read((char*)&(nNumJoints), sizeof(unsigned short));


	MS3DKeyframeJoint* pMS3DJoints = 0;

	if ( nNumJoints > 0 )
		pMS3DJoints = new MS3DKeyframeJoint[nNumJoints];

	for ( i = 0; i < nNumJoints; i++ )
	{
		fin.read((char*)&(pMS3DJoints[i].flags), sizeof(unsigned char));
		fin.read((char*)&(pMS3DJoints[i].name), sizeof(char[32]));
		fin.read((char*)&(pMS3DJoints[i].parentName), sizeof(char[32]));
		fin.read((char*)&(pMS3DJoints[i].rotation[0]), 3 * sizeof(float));
		fin.read((char*)&(pMS3DJoints[i].position[0]), 3 * sizeof(float));
		fin.read((char*)&(pMS3DJoints[i].numKeyFramesRot), sizeof(unsigned short));
		fin.read((char*)&(pMS3DJoints[i].numKeyFramesTrans), sizeof(unsigned short));

		pMS3DJoints[i].keyFramesRot = new MS3DKeyframeRotation[pMS3DJoints[i].numKeyFramesRot];
		pMS3DJoints[i].keyFramesTrans = new MS3DKeyframePosition[pMS3DJoints[i].numKeyFramesTrans];

		for ( int j = 0; j < pMS3DJoints[i].numKeyFramesRot; j++ )
		{
			fin.read((char*)&(pMS3DJoints[i].keyFramesRot[j].time), 1 * sizeof(float));
			fin.read((char*)&(pMS3DJoints[i].keyFramesRot[j].rotation), 3 * sizeof(float));
		}

		for ( int j = 0; j < pMS3DJoints[i].numKeyFramesTrans; j++ )
		{
			fin.read((char*)&(pMS3DJoints[i].keyFramesTrans[j].time), 1 * sizeof(float));
			fin.read((char*)&(pMS3DJoints[i].keyFramesTrans[j].position), 3 * sizeof(float));
		}

		//std::wstringstream s;
		//s << GlyphString::ToUnicode( std::string( pMS3DJoints[i].name ) ) << std::endl;
		//for ( int z = 0; z < pMS3DJoints[i].numKeyFramesRot; z++ )
		//	s << L"rotation: " << pMS3DJoints[i].keyFramesRot[z].time << L" " <<pMS3DJoints[i].keyFramesRot[z].rotation[0] << L" " << pMS3DJoints[i].keyFramesRot[z].rotation[1] << L" " << pMS3DJoints[i].keyFramesRot[z].rotation[2] << std::endl;

		//for ( int z = 0; z < pMS3DJoints[i].numKeyFramesTrans; z++ )
		//	s << L"position: " << pMS3DJoints[i].keyFramesTrans[z].time << L" " <<pMS3DJoints[i].keyFramesTrans[z].position[0] << L" " << pMS3DJoints[i].keyFramesTrans[z].position[1] << L" " << pMS3DJoints[i].keyFramesTrans[z].position[2] << std::endl;

		//Log::Get().Write( s.str() );
	}



	// Close the file (remaining file data unused)
	fin.close();


	// create the vertex element streams
	VertexElementDX11* pPositions = new VertexElementDX11( 3, usTriangleCount*3 );
	pPositions->m_SemanticName = VertexElementDX11::PositionSemantic;
	pPositions->m_uiSemanticIndex = 0;
	pPositions->m_Format = DXGI_FORMAT_R32G32B32_FLOAT;
	pPositions->m_uiInputSlot = 0;
	pPositions->m_uiAlignedByteOffset = 0;
	pPositions->m_InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
	pPositions->m_uiInstanceDataStepRate = 0;

	VertexElementDX11* pBoneIDs = new VertexElementDX11( 1, usTriangleCount*3 );
	pBoneIDs->m_SemanticName = VertexElementDX11::BoneIDSemantic;
	pBoneIDs->m_uiSemanticIndex = 0;
	pBoneIDs->m_Format = DXGI_FORMAT_R32_SINT;
	pBoneIDs->m_uiInputSlot = 0;
	pBoneIDs->m_uiAlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
	pBoneIDs->m_InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
	pBoneIDs->m_uiInstanceDataStepRate = 0;

	VertexElementDX11* pTexcoords = new VertexElementDX11( 2, usTriangleCount*3 );
	pTexcoords->m_SemanticName = VertexElementDX11::TexCoordSemantic;
	pTexcoords->m_uiSemanticIndex = 0;
	pTexcoords->m_Format = DXGI_FORMAT_R32G32_FLOAT;
	pTexcoords->m_uiInputSlot = 0;
	pTexcoords->m_uiAlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
	pTexcoords->m_InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
	pTexcoords->m_uiInstanceDataStepRate = 0;

	VertexElementDX11* pNormals = new VertexElementDX11( 3, usTriangleCount*3 );
	pNormals->m_SemanticName = VertexElementDX11::NormalSemantic;
	pNormals->m_uiSemanticIndex = 0;
	pNormals->m_Format = DXGI_FORMAT_R32G32B32_FLOAT;
	pNormals->m_uiInputSlot = 0;
	pNormals->m_uiAlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
	pNormals->m_InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
	pNormals->m_uiInstanceDataStepRate = 0;

	Vector3f* pPos = pPositions->Get3f( 0 );
	int* pIds = pBoneIDs->Get1i( 0 );
	Vector3f* pNrm = pNormals->Get3f( 0 );
	Vector2f* pTex = pTexcoords->Get2f( 0 );

	// Create the geometry object, and fill it with the data read from the file.

	GeometryPtr MeshPtr = GeometryPtr( new GeometryDX11() );

	TriangleIndices face;

	for ( int i = 0; i < usTriangleCount; i++ )
	{

		face.P1() = 3*i+0;
		face.P2() = 3*i+2;
		face.P3() = 3*i+1;

		pPos[3*i+0].x = pMS3DVertices[pMS3DTriangles[i].vertexIndices[0]].vertex[0];
		pPos[3*i+0].y = pMS3DVertices[pMS3DTriangles[i].vertexIndices[0]].vertex[1];
		pPos[3*i+0].z = -pMS3DVertices[pMS3DTriangles[i].vertexIndices[0]].vertex[2];
		pPos[3*i+1].x = pMS3DVertices[pMS3DTriangles[i].vertexIndices[1]].vertex[0];
		pPos[3*i+1].y = pMS3DVertices[pMS3DTriangles[i].vertexIndices[1]].vertex[1];
		pPos[3*i+1].z = -pMS3DVertices[pMS3DTriangles[i].vertexIndices[1]].vertex[2];
		pPos[3*i+2].x = pMS3DVertices[pMS3DTriangles[i].vertexIndices[2]].vertex[0];
		pPos[3*i+2].y = pMS3DVertices[pMS3DTriangles[i].vertexIndices[2]].vertex[1];
		pPos[3*i+2].z = -pMS3DVertices[pMS3DTriangles[i].vertexIndices[2]].vertex[2];

		pIds[3*i+0] = pMS3DVertices[pMS3DTriangles[i].vertexIndices[0]].boneId;
		pIds[3*i+1] = pMS3DVertices[pMS3DTriangles[i].vertexIndices[1]].boneId;
		pIds[3*i+2] = pMS3DVertices[pMS3DTriangles[i].vertexIndices[2]].boneId;

		pNrm[3*i+0].x = pMS3DTriangles[i].vertexNormals[0][0];
		pNrm[3*i+0].y = pMS3DTriangles[i].vertexNormals[0][1];
		pNrm[3*i+0].z = -pMS3DTriangles[i].vertexNormals[0][2];
		pNrm[3*i+1].x = pMS3DTriangles[i].vertexNormals[1][0];
		pNrm[3*i+1].y = pMS3DTriangles[i].vertexNormals[1][1];
		pNrm[3*i+1].z = -pMS3DTriangles[i].vertexNormals[1][2];
		pNrm[3*i+2].x = pMS3DTriangles[i].vertexNormals[2][0];
		pNrm[3*i+2].y = pMS3DTriangles[i].vertexNormals[2][1];
		pNrm[3*i+2].z = -pMS3DTriangles[i].vertexNormals[2][2];

		pTex[3*i+0].x = pMS3DTriangles[i].s[0];
		pTex[3*i+0].y = pMS3DTriangles[i].t[0];
		pTex[3*i+1].x = pMS3DTriangles[i].s[1];
		pTex[3*i+1].y = pMS3DTriangles[i].t[1];
		pTex[3*i+2].x = pMS3DTriangles[i].s[2];
		pTex[3*i+2].y = pMS3DTriangles[i].t[2];

		MeshPtr->AddFace( face );
	}

	for ( int i = 0; i < usVertexCount; i++ )
	{
		pNrm[i].Normalize();
	}

	MeshPtr->AddElement( pPositions );
	MeshPtr->AddElement( pBoneIDs );
	MeshPtr->AddElement( pTexcoords );
	MeshPtr->AddElement( pNormals );

	// Now set the geometry in the SkinnedActor, and create the bones
	// and add them to the SkinnedActor.

	if ( pActor )
	{
		// Set the geometry in the body of the actor
		pActor->GetBody()->Visual.SetGeometry( MeshPtr );

		// Create an array of nodes, one for each joint.
		std::map<std::string,Node3D*> JointNodes;

		for ( int i = 0; i < nNumJoints; i++ )
		{
			Node3D* pBone = new Node3D();

			Vector3f BindPosition = Vector3f( pMS3DJoints[i].position[0],
			 									pMS3DJoints[i].position[1],
												pMS3DJoints[i].position[2] );

			AnimationStream<Vector3f>* pPosFrames = new AnimationStream<Vector3f>();

			for ( int j = 0; j < pMS3DJoints[i].numKeyFramesTrans; j++ )
			{
				Vector3f p = Vector3f( pMS3DJoints[i].keyFramesTrans[j].position[0],
					pMS3DJoints[i].keyFramesTrans[j].position[1],
					pMS3DJoints[i].keyFramesTrans[j].position[2] );

				pPosFrames->AddState( AnimationState<Vector3f>( pMS3DJoints[i].keyFramesTrans[j].time, p ) ); 
			}

			AnimationStream<Vector3f>* pRotFrames = new AnimationStream<Vector3f>();
			
			Vector3f BindRotation = Vector3f( pMS3DJoints[i].rotation[0] + 6.28f, pMS3DJoints[i].rotation[1] + 6.28f, pMS3DJoints[i].rotation[2] + 6.28f );

			for ( int j = 0; j < pMS3DJoints[i].numKeyFramesRot; j++ )
			{
				Vector3f p = Vector3f( pMS3DJoints[i].keyFramesRot[j].rotation[0] + 6.28f,
					pMS3DJoints[i].keyFramesRot[j].rotation[1] + 6.28f,
					pMS3DJoints[i].keyFramesRot[j].rotation[2] + 6.28f );

				pRotFrames->AddState( AnimationState<Vector3f>( pMS3DJoints[i].keyFramesRot[j].time, p ) ); 
			}

			pActor->AddBoneNode( pBone, BindPosition, BindRotation, pPosFrames, pRotFrames );

			JointNodes[std::string(pMS3DJoints[i].name)] = pBone;
		}

		// Connect up the bones to form the skeleton.
		for ( int i = 0; i < nNumJoints; i++ )
		{
			Node3D* pParent = JointNodes[std::string(pMS3DJoints[i].parentName)];
			Node3D* pChild = JointNodes[std::string(pMS3DJoints[i].name)];

			// If the node has a parent, link them
			if ( pParent && pChild )
				pParent->AttachChild( pChild );

			// If the node has no parent, link it to the root of the skinned actor (for connection
			// to the scene graph).
			if ( !pParent && pChild )
				pActor->GetNode()->AttachChild( pChild );
		}
	}


	// Delete temporary joint information
	if ( pMS3DJoints )
	{
		for ( int i = 0; i < nNumJoints; i++ )
		{
			delete[] pMS3DJoints[i].keyFramesRot;
			delete[] pMS3DJoints[i].keyFramesTrans;
		}
		delete[] pMS3DJoints;
	}


	// Delete temporary materials
	if (pMS3DMaterials != NULL)
	{
		delete[] pMS3DMaterials;
		pMS3DMaterials = NULL;
	}

	// Delete temporary groups and their indices
	if (pMS3DGroups != NULL)
	{
		for (i = 0; i < usGroupCount; i++)
		{
			if (pMS3DGroups[i].triangleIndices != NULL)
			{
				delete[] pMS3DGroups[i].triangleIndices;
				pMS3DGroups[i].triangleIndices = NULL;
			}
		}
		delete[] pMS3DGroups;
		pMS3DGroups = NULL;
	}

	// Delete temporary triangles
	if (pMS3DTriangles != NULL)
	{
		delete[] pMS3DTriangles;
		pMS3DTriangles = NULL;
	}

	// Delete temporary vertices
	if (pMS3DVertices != NULL)
	{
        delete[] pMS3DVertices;
		pMS3DVertices = NULL;
	}

	//MeshPtr->GenerateVertexDeclaration();
	MeshPtr->LoadToBuffers();

	return( MeshPtr );
}
void GeometryLoaderDX11::loadFBXFile( std::string szFilename, std::vector<GeometryPtr>& vGeomVector, std::vector<std::string>& vNames )
{
	FileSystem fs;
	szFilename = fs.GetModelsFolderS() + szFilename;
	pFBXManager = FbxManager::Create();
	if( !pFBXManager )
		Log::Get().Write( L"CGeometryLoader11.cpp: Error creating FBX Manager!" );

	FbxIOSettings* pIOS = FbxIOSettings::Create( pFBXManager, IOSROOT );
	pFBXManager->SetIOSettings( pIOS );

	FbxString lPath = FbxGetApplicationDirectory();
	pFBXManager->LoadPluginsDirectory( lPath.Buffer() );

	FbxScene* pScene = FbxScene::Create( pFBXManager, "" );

	int /*nFileMajor,*/ nFileMinor, nFileRevision;
	int nSDKMajor, nSDKMinor, nSDKRevision;

	int i, /*nAnimationStack,*/ lFileFormat;
	//	bool bStatus;
	//	char szPassword[1024];

	FbxManager::GetFileFormatVersion( nSDKMajor, nSDKMinor, nSDKRevision );

	FbxImporter* pImporter = FbxImporter::Create( pFBXManager, "" );

	if (!pFBXManager->GetIOPluginRegistry()->DetectReaderFileFormat(szFilename.c_str(), lFileFormat) )
	{
		// Unrecognizable file format. Try to fall back to FbxImporter::eFBX_BINARY
		lFileFormat = pFBXManager->GetIOPluginRegistry()->FindReaderIDByDescription( "FBX binary (*.fbx)" );;
	}

	bool ImportStatus = pImporter->Initialize( szFilename.c_str(), lFileFormat, pFBXManager->GetIOSettings() );
	pImporter->GetFileVersion( nFileMinor, nFileMinor, nFileRevision );

	if( !ImportStatus )
	{
		Log::Get().Write( L"CGeometryLoader11.cpp: FbxImporter Initialize failed!" );
		return;
	}

	ImportStatus = pImporter->Import( pScene );

	if( !ImportStatus )
	{
		Log::Get().Write( L"CGeometryLoader11.cpp: FbxImporter failed to import the file to the scene!" );
		return;
	}

	FbxAxisSystem SceneAxisSystem = pScene->GetGlobalSettings().GetAxisSystem();
	FbxAxisSystem AxisSystem( FbxAxisSystem::eYAxis, FbxAxisSystem::eParityOdd, FbxAxisSystem::eLeftHanded );
	if( SceneAxisSystem != AxisSystem )
	{
		AxisSystem.ConvertScene( pScene );
	}

	//FbxSystemUnit SceneSystemUnit = pScene->GetGlobalSettings().GetSystemUnit();
	//if( SceneSystemUnit.GetScaleFactor() != 1.0f )
	//	FbxSystemUnit::cm.ConvertScene( pScene );

	FBXTriangulateRecursive( pScene->GetRootNode() );

	FbxArray<FbxMesh*> vMeshs;
	FBXFillMeshArray( pScene, vMeshs );

	unsigned short usVertexCount = 0;
	unsigned short usTriangleCount = 0;
	unsigned short usGroupCount = 0;
	unsigned short usMaterialCount = 0;
	unsigned short usIndicesCount = 0;

	for( i = 0; i < vMeshs.GetCount(); i++ )
	{
		Log::Get().Write( L"CGeometryLoader11.cpp: Loading File!" );
		std::string name = vMeshs[i]->GetNode()->GetName();
		vNames.push_back( name );
		usVertexCount = vMeshs[i]->GetControlPointsCount();
		if( usVertexCount == 0 )
			continue;

		usTriangleCount = vMeshs[i]->GetPolygonVertexCount() / 3;
		usIndicesCount = vMeshs[i]->GetPolygonVertexCount();

		VertexElementDX11* pPositions = new VertexElementDX11( 3, usTriangleCount * 3 );
		pPositions->m_SemanticName = VertexElementDX11::PositionSemantic;
		pPositions->m_uiSemanticIndex = 0;
		pPositions->m_Format = DXGI_FORMAT_R32G32B32_FLOAT;
		pPositions->m_uiInputSlot = 0;
		pPositions->m_uiAlignedByteOffset = 0;
		pPositions->m_InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
		pPositions->m_uiInstanceDataStepRate = 0;

		VertexElementDX11* pTexCoords = new VertexElementDX11( 2, usTriangleCount * 3 );
		pTexCoords->m_SemanticName = VertexElementDX11::TexCoordSemantic;
		pTexCoords->m_uiSemanticIndex = 0;
		pTexCoords->m_Format = DXGI_FORMAT_R32G32_FLOAT;
		pTexCoords->m_uiInputSlot = 0;
		pTexCoords->m_uiAlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
		pTexCoords->m_InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
		pTexCoords->m_uiInstanceDataStepRate = 0;

		VertexElementDX11* pNormals = new VertexElementDX11( 3, usTriangleCount * 3 );
		pNormals->m_SemanticName = VertexElementDX11::NormalSemantic;
		pNormals->m_uiSemanticIndex = 0;
		pNormals->m_Format = DXGI_FORMAT_R32G32B32_FLOAT;
		pNormals->m_uiInputSlot = 0;
		pNormals->m_uiAlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
		pNormals->m_InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
		pNormals->m_uiInstanceDataStepRate = 0;

		Vector3f* pPos = pPositions->Get3f(0);
		Vector3f* pNorm = pNormals->Get3f(0);
		Vector2f* pTex = pTexCoords->Get2f(0);

		FbxVector4* pFBXVerts = new FbxVector4[usVertexCount];
		memcpy( pFBXVerts, vMeshs[i]->GetControlPoints(), usVertexCount * sizeof(FbxVector4));

		TriangleIndices face;

		GeometryPtr pGeomPointer( new GeometryDX11() );

		for( int j = 0; j < usTriangleCount; j++ )
		{	
			int nIndex = 0;
			FbxVector4 FBXNorm( 0, 0, 0, 0 );
			FbxVector2 FBXUV( 0, 0 );

			face.P1() = nIndex = vMeshs[i]->GetPolygonVertex( j, 0 );
			pPos[nIndex].x = (float)pFBXVerts[ nIndex ][0];
			pPos[nIndex].y = (float)pFBXVerts[ nIndex ][1];
			pPos[nIndex].z = (float)pFBXVerts[ nIndex ][2];
			vMeshs[i]->GetPolygonVertexNormal( j, 0, FBXNorm );
			pNorm[nIndex].x = (float)FBXNorm[0];
			pNorm[nIndex].y = (float)FBXNorm[1];
			pNorm[nIndex].z = (float)FBXNorm[2];
			vMeshs[i]->GetPolygonVertexUV( j, 0, "map1", FBXUV );
			pTex[nIndex].x = (float)FBXUV[0];
			pTex[nIndex].y = (float)FBXUV[1];

			face.P2() = nIndex = vMeshs[i]->GetPolygonVertex( j, 1 );
			pPos[nIndex].x = (float)pFBXVerts[ nIndex ][0];
			pPos[nIndex].y = (float)pFBXVerts[ nIndex ][1];
			pPos[nIndex].z = (float)pFBXVerts[ nIndex ][2];
			vMeshs[i]->GetPolygonVertexNormal( j, 1, FBXNorm );
			pNorm[nIndex].x = (float)FBXNorm[0];
			pNorm[nIndex].y = (float)FBXNorm[1];
			pNorm[nIndex].z = (float)FBXNorm[2];
			vMeshs[i]->GetPolygonVertexUV( j, 1, "map1", FBXUV );
			pTex[nIndex].x = (float)FBXUV[0];
			pTex[nIndex].y = (float)FBXUV[1];

			face.P3() = nIndex = vMeshs[i]->GetPolygonVertex( j, 2 );
			pPos[nIndex].x = (float)pFBXVerts[ nIndex ][0];
			pPos[nIndex].y = (float)pFBXVerts[ nIndex ][1];	
			pPos[nIndex].z = (float)pFBXVerts[ nIndex ][2];
			vMeshs[i]->GetPolygonVertexNormal( j, 2, FBXNorm );
			pNorm[nIndex].x = (float)FBXNorm[0];
			pNorm[nIndex].y = (float)FBXNorm[1];
			pNorm[nIndex].z = (float)FBXNorm[2];
			vMeshs[i]->GetPolygonVertexUV( j, 2, "map1", FBXUV );
			pTex[nIndex].x = (float)FBXUV[0];
			pTex[nIndex].y = (float)FBXUV[1];

			pGeomPointer->AddFace( face );
		}

		for( int j = 0; j < usVertexCount; j++ )
		{
			pNorm[j].Normalize();
		}

		pGeomPointer->AddElement( pPositions );
		pGeomPointer->AddElement( pNormals );
		pGeomPointer->AddElement( pTexCoords );

		delete[] pFBXVerts;
		vGeomVector.push_back( pGeomPointer );

		vMeshs[i]->Destroy();
		vMeshs[i] = NULL;
	}


	pImporter->Destroy();
	pImporter = NULL;

	pScene->Destroy();
	pScene = NULL;

	pIOS->Destroy();
	pIOS = NULL;

	pFBXManager->Destroy();
	pFBXManager = NULL;
}