Example #1
0
		void FbxLoader::ProcessMesh(FbxNode* node, Node& meshNode)
		{
			FbxMesh* currMesh = node->GetMesh();

			if(!currMesh)
				return;

			FbxLayerElementTangent* tangents = nullptr;

			if(useNormalMap) {
				if(currMesh->GetElementTangentCount() < 1) {
					currMesh->GenerateTangentsDataForAllUVSets();
					tangents = currMesh->GetElementTangent();
				}
			}

			std::map<int, std::vector<Vertex>> subMeshes;

			int vertCounter = 0;
			const int polygonCount = currMesh->GetPolygonCount();

			for(int i = 0; i < polygonCount; i++) {
				const int polySize = currMesh->GetPolygonSize(i);
				int nMaterials = node->GetMaterialCount();
				auto elementMaterial = currMesh->GetElementMaterial();
				int mi = 0;
				if(elementMaterial)
					mi = currMesh->GetElementMaterial()->GetIndexArray()[i];

				for(int j = 2; j >= 0; --j) {
					int ctrlIndex = currMesh->GetPolygonVertex(i, j);
					auto& currCtrlPoint = meshNode.controlPoints[ctrlIndex];
					FbxVector4 v4;

					auto& pos = currCtrlPoint.position * factor;
					currMesh->GetPolygonVertexNormal(i, j, v4);
					Vector3 normal = { (float)v4[0], (float)v4[1], (float)v4[2] };
					Vector3 tangent = { 0, 0, 0 };
					if(useNormalMap) {
						ReadTangent(tangents, ctrlIndex, vertCounter, v4);
						tangent = { (float)v4[0], (float)v4[1], (float)v4[2] };
					}
				
					Vector2 uv;
					FbxStringList uvSetNames;
					currMesh->GetUVSetNames(uvSetNames);
					bool unmapped = false;
					// supports one uv set only
					if(uvSetNames.GetCount() > 0) {
						FbxVector2 UV;
						currMesh->GetPolygonVertexUV(i, j, uvSetNames[0], UV, unmapped);
						uv = { (float)UV[0], (float)UV[1] };
					}
				
					if(axismode == eLeftHanded) {
						pos.x *= -1; uv.y = 1 - uv.y;
						normal.x *= -1; tangent.x *= -1;
					}

					Vector4 weights = { 0, 0, 0, 0 };
					Byte4 indices = { 0, 0, 0, 0 };

					int blendCount = (int)min(currCtrlPoint.blendWeigths.size(), 4);
					if(blendCount > 0) {
						meshNode.useSkinnedMesh = true;
						if(currCtrlPoint.blendWeigths.size() > 4)
							sort(currCtrlPoint.blendWeigths.begin(), currCtrlPoint.blendWeigths.end());
						for(int i = 0; i < blendCount; i++) {
							weights[i] = currCtrlPoint.blendWeigths[i].weight;
							indices.m[i] = currCtrlPoint.blendWeigths[i].boneIndex;
						}
					}
	
					Vertex temp = { pos, uv, normal, tangent, indices, weights };
					subMeshes[mi].push_back(temp);
				}
				++vertCounter;
			}

			if(subMeshes.size() > 0) {
				int index = 0;
				meshNode.meshes.reserve(vertCounter);
				meshNode.vertIndices.reserve(vertCounter);
				meshNode.vertexCountOfSubMesh.reserve(subMeshes.size());
				for(auto& pair : subMeshes) {
					auto& m = pair.second;
					for(int i = 0; i < m.size(); ++i)
						meshNode.vertIndices.emplace_back(index++);
					meshNode.vertexCountOfSubMesh.push_back((int)m.size());
					meshNode.meshes.insert(meshNode.meshes.end(), m.begin(), m.end());
				}
			}
			subMeshes.clear();
		}
void FBXConverter::convert( const char* input , const char* output )
{
	if ( converting ) return;
	converting = true;
	FbxManager* fbxManger = FbxManager::Create();

	FbxIOSettings* ios = FbxIOSettings::Create( fbxManger , IOSROOT );
	fbxManger->SetIOSettings( ios );

	FbxImporter* importer = FbxImporter::Create( fbxManger , "" );

	bool status = importer->Initialize( input , -1 , fbxManger->GetIOSettings() );
	if ( !status )
	{
		std::cout << importer->GetStatus().GetErrorString() << std::endl;
	}

	FbxScene* scene = FbxScene::Create( fbxManger , "theScene" );
	importer->Import( scene );
	importer->Destroy();

	FbxMesh* theMesh = findMesh( scene->GetRootNode() );
	

	if ( theMesh )
	{
		std::vector<VertexData> vertices;
		std::vector<IndexData> indices;

		FbxStringList uvSets;
		theMesh->GetUVSetNames( uvSets );

		processPolygons( theMesh , vertices , indices , uvSets );

		std::vector<JointData> skeleton;
		processSkeletonHierarchy( scene->GetRootNode() , skeleton );
		if ( skeleton.size() ) processAnimations( theMesh->GetNode() , skeleton , vertices , indices );

		std::string modelData;
		for ( unsigned int i = 0; i < vertices.size(); ++i )
		{
			modelData += DATASTRING( vertices[i].position );
			modelData += DATASTRING( vertices[i].uv );
			modelData += DATASTRING( vertices[i].normal );
			modelData += DATASTRING( vertices[i].tangent );
			modelData += DATASTRING( vertices[i].bitangent );
			
			for ( unsigned int j = 0; j < 4 ; ++j )
			{
				if ( j < vertices[i].blendingInfo.size() )
				{
					int blendingIndex = vertices[i].blendingInfo[j].blendingIndex;
					modelData += DATASTRING( blendingIndex );
				}
				else
				{
					int blendingIndex = -1;
					modelData += DATASTRING( blendingIndex );
				}
			}
			for ( unsigned int j = 0; j < 4; ++j )
			{
				if ( j < vertices[i].blendingInfo.size() )
				{
					float blendingIndex = vertices[i].blendingInfo[j].blendingWeight;
					modelData += DATASTRING( blendingIndex );
				}
				else
				{
					float blendingIndex = -1;
					modelData += DATASTRING( blendingIndex );
				}
			}
		}

		for ( unsigned int i = 0; i < indices.size(); ++i)
		{
			modelData += DATASTRING( indices[i].index );
		}

		std::string boneData;
		std::vector<unsigned int> boneChildren;
		std::vector<AnimationData> boneAnimation;
		for ( unsigned int i = 0; i < skeleton.size(); ++i )
		{
			boneData += DATASTRING( skeleton[i].offsetMatrix );
			int childDataStart , childDataEnd , animationDataStart , animationDataEnd;
			if ( skeleton[i].children.size() )
			{
				childDataStart = boneChildren.size();
				for ( unsigned int j = 0; j < skeleton[i].children.size(); ++j )
				{
					boneChildren.push_back( skeleton[i].children[j] );
				}
				childDataEnd = boneChildren.size();
			}
			else
			{
				childDataStart = -1;
				childDataEnd = -1;
			}

			if ( skeleton[i].animation.size() )
			{
				animationDataStart = boneAnimation.size();
				for ( unsigned int j = 0; j < skeleton[i].animation.size(); ++j )
				{
					boneAnimation.push_back( skeleton[i].animation[j] );
				}
				animationDataEnd = boneAnimation.size();
			}
			else
			{
				animationDataStart = -1;
				animationDataEnd = -1;
			}
			boneData += DATASTRING( childDataStart );
			boneData += DATASTRING( childDataEnd );
			boneData += DATASTRING( animationDataStart );
			boneData += DATASTRING( animationDataEnd );
		}
		unsigned int sizeofAnimationRangeInfo;
		AnimationFrameRangeInfo frameRange;
		if ( boneAnimation.size() > 0 )
		{
			sizeofAnimationRangeInfo = 1;
			frameRange.nextAnimationFrameInfo = 0;
			frameRange.firstFrame = 1;
			frameRange.lastFrame = boneAnimation[boneAnimation.size() - 1].frame;
		}
		else
		{
			sizeofAnimationRangeInfo = 0;
		}

		std::fstream stream( output , std::ios_base::binary | std::ios_base::out | std::ios_base::trunc );

		unsigned int sizeofVertices = vertices.size();
		stream.write( reinterpret_cast< char* >( &sizeofVertices ) , sizeof( sizeofVertices ));
		unsigned int sizeofIndices = indices.size();
		stream.write( reinterpret_cast< char* >( &sizeofIndices ) , sizeof( sizeofIndices ) );

		unsigned int sizeofBoneData = skeleton.size();
		stream.write( reinterpret_cast<char*>( &sizeofBoneData ) , sizeof( sizeofBoneData ) );

		unsigned int sizeofBoneChildData = boneChildren.size();
		stream.write( reinterpret_cast< char* >( &sizeofBoneChildData ) , sizeof( sizeofBoneChildData ));

		unsigned int sizeofBoneAnimationData = boneAnimation.size();
		stream.write( reinterpret_cast< char* >( &sizeofBoneAnimationData ) , sizeof( sizeofBoneAnimationData ) );

		stream.write( reinterpret_cast< char* >( &sizeofAnimationRangeInfo ) , sizeof( sizeofAnimationRangeInfo ) );

		stream.write( modelData.c_str() , modelData.size() );

		stream.write( boneData.c_str() , boneData.size() );

		for ( unsigned int i = 0; i < boneChildren.size(); ++i )
		{
			stream.write( reinterpret_cast< char* >( &boneChildren[i] ) , sizeof( boneChildren[i] ) );
		}

		for ( unsigned int i = 0; i < boneAnimation.size(); ++i )
		{
			stream.write( reinterpret_cast< char* >( &boneAnimation[i] ) , sizeof( boneAnimation[i] ) );
		}

		
		if(sizeofAnimationRangeInfo) stream.write( reinterpret_cast< char* >( &frameRange ) , sizeof( frameRange ) );
		stream.close();
	}
	converting = false;
}
Example #3
0
bool FillData(ModelData* someData,FbxNode* aNode, AnimationData* aAnimation)
{
	FbxMesh* mesh = aNode->GetMesh();
	if (mesh == nullptr || !aNode)
		return false;

	const int lPolygonCount = mesh->GetPolygonCount();

	// Count the polygon count of each material
	FbxLayerElementArrayTemplate<int>* lMaterialIndice = NULL;
	FbxGeometryElement::EMappingMode lMaterialMappingMode = FbxGeometryElement::eNone;
	if (mesh->GetElementMaterial())
	{
		lMaterialIndice = &mesh->GetElementMaterial()->GetIndexArray();
		lMaterialMappingMode = mesh->GetElementMaterial()->GetMappingMode();
		if (lMaterialIndice && lMaterialMappingMode == FbxGeometryElement::eByPolygon)
		{
			FBX_ASSERT(lMaterialIndice->GetCount() == lPolygonCount);
			if (lMaterialIndice->GetCount() == lPolygonCount)
			{
				// Count the faces of each material
				for (int lPolygonIndex = 0; lPolygonIndex < lPolygonCount; ++lPolygonIndex)
				{
					const int lMaterialIndex = lMaterialIndice->GetAt(lPolygonIndex);
					lMaterialIndex;
					/*if (someData->mSubMeshes[lMaterialIndex] == NULL)
					{
						someData->mSubMeshes[lMaterialIndex] = new ModelData::SubMesh;
					}
					someData->mSubMeshes[lMaterialIndex]->TriangleCount += 1;*/
				}

				// Make sure we have no "holes" (NULL) in the mSubMeshes table. This can happen
				// if, in the loop above, we resized the mSubMeshes by more than one slot.
					
				/*for (int i = 0; i < someData->mSubMeshes.Count(); i++)
				{
					if (someData->mSubMeshes[i] == NULL)
						someData->mSubMeshes[i] = new ModelData::SubMesh;
				}*/

				// Record the offset (how many vertex)
				const int lMaterialCount = someData->mSubMeshes.Size();
				lMaterialCount;
				int lOffset = 0;
				/*for (int lIndex = 0; lIndex < lMaterialCount; ++lIndex)
				{
					someData->mSubMeshes[lIndex]->IndexOffset = lOffset;
					lOffset += someData->mSubMeshes[lIndex]->TriangleCount * 3;
					// This will be used as counter in the following procedures, reset to zero
					someData->mSubMeshes[lIndex]->TriangleCount = 0;
				}*/
				FBX_ASSERT(lOffset == lPolygonCount * 3);
			}
		}
	}

	// All faces will use the same material.
	if (someData->mSubMeshes.Size() == 0)
	{
		if (someData->mSubMeshes.GetCapacity() == 0)
		{
			someData->mSubMeshes.Init(1);
		}
		someData->mSubMeshes.RemoveAll();
		someData->mSubMeshes.AddEmptyObject();
		someData->mSubMeshes[0] = new ModelData::SubMesh();
	}

		

	bool hasNormalMap = false;

	const int lMaterialCount = aNode->GetMaterialCount();
	for (int lMaterialIndex = 0; lMaterialIndex < lMaterialCount; ++lMaterialIndex)
	{
		FbxSurfaceMaterial * lMaterial = aNode->GetMaterial(lMaterialIndex);
		if (lMaterial && !lMaterial->GetUserDataPtr())
		{
			TextureInfo diffuseInfo;
			GetMaterialProperty(lMaterial,FbxSurfaceMaterial::sDiffuse,FbxSurfaceMaterial::sDiffuseFactor,diffuseInfo.myFileName);
			diffuseInfo.myType = DIFFUSE;
			if(diffuseInfo.myFileName.empty() == false)
			{
				someData->myTextures.push_back(diffuseInfo);
			}

			TextureInfo normalInfo;
			GetMaterialProperty(lMaterial,FbxSurfaceMaterial::sNormalMap,FbxSurfaceMaterial::sBumpFactor,normalInfo.myFileName);
			hasNormalMap = normalInfo.myFileName.empty() == false;
			normalInfo.myType = NORMALMAP;
			if(normalInfo.myFileName.empty() == false)
			{
				someData->myTextures.push_back(normalInfo);
				hasNormalMap = true;
			}

			TextureInfo roughnessInfo;
			GetMaterialProperty(lMaterial,FbxSurfaceMaterial::sSpecular,FbxSurfaceMaterial::sSpecularFactor,roughnessInfo.myFileName);
			roughnessInfo.myType = ROUGHNESS;
			if(roughnessInfo.myFileName.empty() == false)
			{
				someData->myTextures.push_back(roughnessInfo);
			}

			TextureInfo substanceInfo;
			GetMaterialProperty(lMaterial,FbxSurfaceMaterial::sReflection,FbxSurfaceMaterial::sReflectionFactor,substanceInfo.myFileName);
			substanceInfo.myType = SUBSTANCE;
			if(substanceInfo.myFileName.empty() == false)
			{
				someData->myTextures.push_back(substanceInfo);
			}

			TextureInfo ambientInfo;
			GetMaterialProperty(lMaterial, FbxSurfaceMaterial::sAmbient, FbxSurfaceMaterial::sAmbientFactor, ambientInfo.myFileName);
			ambientInfo.myType = AO;
			if (substanceInfo.myFileName.empty() == false)
			{
				someData->myTextures.push_back(ambientInfo);
			}
		}
	}

	// Congregate all the data of a mesh to be cached in VBOs.
	// If normal or UV is by polygon vertex, record all vertex attributes by polygon vertex.'
		
	someData->mHasNormal = mesh->GetElementNormalCount() > 0;
	someData->mHasUV = mesh->GetElementUVCount() > 0;
	someData->myHasBiNormal = mesh->GetElementBinormalCount() > 0;

	FbxSkin * lSkinDeformer = (FbxSkin *)mesh->GetDeformer(0, FbxDeformer::eSkin);
	someData->myHasSkinweights = lSkinDeformer != nullptr;

	if(hasNormalMap && someData->myHasBiNormal == false)
	{
		mesh->GenerateTangentsDataForAllUVSets();
		someData->myHasBiNormal = mesh->GetElementBinormalCount() > 0;
	}
	someData->myHasTangents = mesh->GetElementTangentCount() > 0;
		
	FbxGeometryElement::EMappingMode lNormalMappingMode = FbxGeometryElement::eNone;
	FbxGeometryElement::EMappingMode lUVMappingMode = FbxGeometryElement::eNone;
	if (someData->mHasNormal)
	{
		lNormalMappingMode = mesh->GetElementNormal(0)->GetMappingMode();
		if (lNormalMappingMode == FbxGeometryElement::eNone)
		{
			someData->mHasNormal = false;
		}
		if (someData->mHasNormal && lNormalMappingMode != FbxGeometryElement::eByControlPoint)
		{
			someData->mAllByControlPoint = false;
		}
	}
	if (someData->mHasUV)
	{
		lUVMappingMode = mesh->GetElementUV(0)->GetMappingMode();
		if (lUVMappingMode == FbxGeometryElement::eNone)
		{
			someData->mHasUV = false;
		}
		if (someData->mHasUV && lUVMappingMode != FbxGeometryElement::eByControlPoint)
		{
			someData->mAllByControlPoint = false;
		}
	}

	// Allocate the array memory, by control point or by polygon vertex.
	int lPolygonVertexCount = mesh->GetControlPointsCount();
	//if (!someData->my)
	{
		ModelData::Layout newLayout;
		newLayout.myType = ModelData::VERTEX_POS;
		newLayout.mySize = VERTEX_STRIDE;
		newLayout.myOffset = 0;
		someData->myLayout.Add(newLayout);
		lPolygonVertexCount = lPolygonCount * TRIANGLE_VERTEX_COUNT;
	}
	int stride = VERTEX_STRIDE;
	size_t size = lPolygonVertexCount * VERTEX_STRIDE;
	//float * lVertices = new float[lPolygonVertexCount * VERTEX_STRIDE];
	unsigned int * lIndices = new unsigned int[lPolygonCount * TRIANGLE_VERTEX_COUNT];
	someData->myIndexCount = lPolygonCount * TRIANGLE_VERTEX_COUNT;
	//float * lNormals = NULL;
	if (someData->mHasNormal)
	{
		ModelData::Layout newLayout;
		newLayout.myType = ModelData::VERTEX_NORMAL;
		newLayout.mySize = NORMAL_STRIDE;
		newLayout.myOffset = stride*4;
		someData->myLayout.Add(newLayout);

		stride += NORMAL_STRIDE;
		size += lPolygonVertexCount * NORMAL_STRIDE;
		//lNormals = new float[lPolygonVertexCount * NORMAL_STRIDE];
	}
	//float * lUVs = NULL;
	FbxStringList lUVNames;
	mesh->GetUVSetNames(lUVNames);
	const char * lUVName = NULL;
	if (someData->mHasUV && lUVNames.GetCount())
	{
		ModelData::Layout newLayout;
		newLayout.myType = ModelData::VERTEX_UV;
		newLayout.mySize = UV_STRIDE;
		newLayout.myOffset = stride*4;
		someData->myLayout.Add(newLayout);

		stride += UV_STRIDE;
		size += lPolygonVertexCount * UV_STRIDE;
		//lUVs = new float[lPolygonVertexCount * UV_STRIDE];
		lUVName = lUVNames[0];
	}

	if (someData->myHasBiNormal)
	{
		ModelData::Layout newLayout;
		newLayout.myType = ModelData::VERTEX_BINORMAL;
		newLayout.mySize = BINORMAL_STRIDE;
		newLayout.myOffset = stride*4;
		someData->myLayout.Add(newLayout);

		stride += BINORMAL_STRIDE;
		size += lPolygonVertexCount * BINORMAL_STRIDE;
		//lUVs = new float[lPolygonVertexCount * UV_STRIDE];
	}

	if (someData->myHasTangents)
	{
		ModelData::Layout newLayout;
		newLayout.myType = ModelData::VERTEX_TANGENT;
		newLayout.mySize = TANGENT_STRIDE;
		newLayout.myOffset = stride*4;
		someData->myLayout.Add(newLayout);

		stride += TANGENT_STRIDE;
		size += lPolygonVertexCount * TANGENT_STRIDE;
		//lUVs = new float[lPolygonVertexCount * UV_STRIDE];
	}

	if (someData->myHasSkinweights)
	{
		ModelData::Layout newLayout;
		newLayout.myType = ModelData::VERTEX_SKINWEIGHTS;
		newLayout.mySize = SKINWEIGHT_STRIDE;
		newLayout.myOffset = stride*4;
		someData->myLayout.Add(newLayout);

		stride += SKINWEIGHT_STRIDE;
		size += lPolygonVertexCount * SKINWEIGHT_STRIDE;

		newLayout.myType = ModelData::VERTEX_BONEID;
		newLayout.mySize = BONEID_STRIDE;
		newLayout.myOffset = stride*4;
		someData->myLayout.Add(newLayout);

		stride += BONEID_STRIDE;
		size += lPolygonVertexCount * BONEID_STRIDE;
		//lUVs = new float[lPolygonVertexCount * UV_STRIDE];
	}

	float * lVertices = new float[size];

	FbxAMatrix globalPos;
	FbxVector4* weights = nullptr;
	FbxVectorTemplate4<int>* bones = nullptr;
	FbxTime time = static_cast<FbxTime>(0.0f);
	if(someData->myHasSkinweights)
	{
		weights = new FbxVector4[mesh->GetControlPointsCount()];
		bones = new FbxVectorTemplate4<int>[mesh->GetControlPointsCount()];
		ComputeLinearDeformation(globalPos,mesh,weights,bones,aAnimation);
	}

	const FbxGeometryElementBinormal * lBiNormalElement = NULL;
	const FbxGeometryElementTangent * lTangentElement = NULL;

	if (someData->myHasBiNormal)
	{
		lBiNormalElement = mesh->GetElementBinormal(0);
	}
	if (someData->myHasTangents)
	{
		lTangentElement = mesh->GetElementTangent(0);
	}

	// Populate the array with vertex attribute, if by control point.
	const FbxVector4 * lControlPoints = mesh->GetControlPoints();
	FbxVector4 lCurrentVertex;
	FbxVector4 lCurrentNormal;
	FbxVector4 lCurrentBiNormal;
	FbxVector4 lCurrentTangent;
	FbxVector2 lCurrentUV;
	if (someData->mAllByControlPoint)
	{
		const FbxGeometryElementNormal * lNormalElement = NULL;
		const FbxGeometryElementUV * lUVElement = NULL;
		if (someData->mHasNormal)
		{
			lNormalElement = mesh->GetElementNormal(0);
		}
		if (someData->mHasUV)
		{
			lUVElement = mesh->GetElementUV(0);
		}

		for (int lIndex = 0; lIndex < lPolygonVertexCount; ++lIndex)
		{
			int currentIndex = lIndex * stride;
			int addedSize = VERTEX_STRIDE;
			// Save the vertex position.
			lCurrentVertex = lControlPoints[lIndex];
				
			CU::Vector4f position(static_cast<float>(lCurrentVertex[0]),
					static_cast<float>(lCurrentVertex[1]),
					static_cast<float>(lCurrentVertex[2]),
					1);

			CU::Matrix44f fixMatrix;
			fixMatrix = CU::Matrix44<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1,0,0));
			position = position*fixMatrix;

			lVertices[currentIndex] = position.x;
			lVertices[currentIndex + 1] = position.y;
			lVertices[currentIndex + 2] = position.z;
			lVertices[currentIndex + 3] = 1;


			// Save the normal.
			if (someData->mHasNormal)
			{
				int lNormalIndex = lIndex;
				if (lNormalElement->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
				{
					lNormalIndex = lNormalElement->GetIndexArray().GetAt(lIndex);
				}
				lCurrentNormal = lNormalElement->GetDirectArray().GetAt(lNormalIndex);

				CU::Vector3f normal( static_cast<float>(lCurrentNormal[0]), static_cast<float>(lCurrentNormal[1]), static_cast<float>(lCurrentNormal[2]));
				normal = normal*CU::Matrix33<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1, 0, 0));

				lVertices[currentIndex + addedSize] = normal.x;
				lVertices[currentIndex + addedSize + 1] = normal.y;
				lVertices[currentIndex + addedSize + 2] = normal.z;
				lVertices[currentIndex + addedSize + 3] = 0;
				addedSize += NORMAL_STRIDE;
			}

			// Save the UV.
			if (someData->mHasUV)
			{
				int lUVIndex = lIndex;
				if (lUVElement->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
				{
					lUVIndex = lUVElement->GetIndexArray().GetAt(lIndex);
				}
				lCurrentUV = lUVElement->GetDirectArray().GetAt(lUVIndex);
				lVertices[currentIndex + addedSize] = static_cast<float>(lCurrentUV[0]);
				lVertices[currentIndex + addedSize + 1] = static_cast<float>(lCurrentUV[1])*-1.0f;
				addedSize += 2;
			}

			if (someData->myHasBiNormal)
				{
					int lBinormIndexIndex = lIndex;
					if (lBiNormalElement->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
					{
						lBinormIndexIndex = lBiNormalElement->GetIndexArray().GetAt(lIndex);
					}

					lCurrentBiNormal = lBiNormalElement->GetDirectArray().GetAt(lBinormIndexIndex);
					//mesh->GetElementBinormal(lPolygonIndex, lVerticeIndex, lCurrentNormal);
					//lCurrentNormal = lCurrentNormal
					CU::Vector3f normal( static_cast<float>(lCurrentBiNormal[0]), static_cast<float>(lCurrentBiNormal[1]), static_cast<float>(lCurrentBiNormal[2]));
					normal = normal*CU::Matrix33<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1, 0, 0));
					if (CU::Length(normal) != 0.f)
						CU::Normalize(normal);
					lVertices[currentIndex + addedSize] = normal.x;
					lVertices[currentIndex + addedSize + 1] = normal.y;
					lVertices[currentIndex + addedSize + 2] = normal.z;
					lVertices[currentIndex + addedSize + 3] = 0;
					addedSize += BINORMAL_STRIDE;
				}

				if (someData->myHasTangents)
				{
					int lBinormIndexIndex = lIndex;
					if (lTangentElement->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
					{
						lBinormIndexIndex = lTangentElement->GetIndexArray().GetAt(lIndex);
					}

					lCurrentTangent = lTangentElement->GetDirectArray().GetAt(lBinormIndexIndex);

					//lCurrentNormal = lCurrentNormal
					CU::Vector3f normal( static_cast<float>(lCurrentTangent[0]), static_cast<float>(lCurrentTangent[1]), static_cast<float>(lCurrentTangent[2]));
					normal = normal*CU::Matrix33<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1, 0, 0));
					if (CU::Length(normal) != 0.f)
						CU::Normalize(normal);
					lVertices[currentIndex + addedSize] = normal.x;
					lVertices[currentIndex + addedSize + 1] = normal.y;
					lVertices[currentIndex + addedSize + 2] = normal.z;
					lVertices[currentIndex + addedSize + 3] = 0;
					addedSize += TANGENT_STRIDE;
				}

				if(someData->myHasSkinweights)
				{
					FbxVector4 currentWeights = weights[lIndex];
					//currentWeights.Normalize();

					lVertices[currentIndex + addedSize] = static_cast<float>(currentWeights[0]);
					lVertices[currentIndex + addedSize + 1] = static_cast<float>(currentWeights[1]);
					lVertices[currentIndex + addedSize + 2] = static_cast<float>(currentWeights[2]);
					lVertices[currentIndex + addedSize + 3] = static_cast<float>(currentWeights[3]);
					addedSize += SKINWEIGHT_STRIDE;

					FbxVectorTemplate4<int> currentBones = bones[lIndex];

					lVertices[currentIndex + addedSize] = static_cast<float>(currentBones[0]);
					lVertices[currentIndex + addedSize + 1] = static_cast<float>(currentBones[1]);
					lVertices[currentIndex + addedSize + 2] = static_cast<float>(currentBones[2]);
					lVertices[currentIndex + addedSize + 3] = static_cast<float>(currentBones[3]);
					addedSize += BONEID_STRIDE;
				}
		}

	}

	int lVertexCount = 0;
	for (int lPolygonIndex = 0; lPolygonIndex < lPolygonCount; ++lPolygonIndex)
	{
		// The material for current face.
		int lMaterialIndex = 0;
		if (lMaterialIndice && lMaterialMappingMode == FbxGeometryElement::eByPolygon)
		{
			lMaterialIndex = lMaterialIndice->GetAt(lPolygonIndex);
		}

		// Where should I save the vertex attribute index, according to the material
		const int lIndexOffset = someData->mSubMeshes[lMaterialIndex]->IndexOffset +
			someData->mSubMeshes[lMaterialIndex]->TriangleCount * 3;
		for (int lVerticeIndex = TRIANGLE_VERTEX_COUNT-1; lVerticeIndex > -1; --lVerticeIndex)
		{
			const int lControlPointIndex = mesh->GetPolygonVertex(lPolygonIndex, lVerticeIndex);
				
			int vertexIndex = lIndexOffset + (TRIANGLE_VERTEX_COUNT-1) - lVerticeIndex;
			if (someData->mAllByControlPoint)
			{
				lIndices[vertexIndex] = static_cast<unsigned int>(lControlPointIndex);
			}
			// Populate the array with vertex attribute, if by polygon vertex.
			else
			{
				lIndices[vertexIndex] = static_cast<unsigned int>(lVertexCount);

				lCurrentVertex = lControlPoints[lControlPointIndex];
				int addedSize = VERTEX_STRIDE;
				int currentIndex = lVertexCount * stride;

				CU::Vector4f position(static_cast<float>(lCurrentVertex[0]),
					static_cast<float>(lCurrentVertex[1]),
					static_cast<float>(lCurrentVertex[2]),
					1);

				//fixMatrix
				CU::Matrix44f fixMatrix;
				fixMatrix = CU::Matrix44<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1, 0, 0));
				position = position*fixMatrix;

				lVertices[currentIndex] = position.x;
				lVertices[currentIndex + 1] = position.y;
				lVertices[currentIndex + 2] = position.z;
				lVertices[currentIndex + 3] = 0;

				if (someData->mHasNormal)
				{
					mesh->GetPolygonVertexNormal(lPolygonIndex, lVerticeIndex, lCurrentNormal);
					CU::Vector3f normal( static_cast<float>(lCurrentNormal[0]), static_cast<float>(lCurrentNormal[1]), static_cast<float>(lCurrentNormal[2]));
					normal = normal*CU::Matrix33<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1, 0, 0));
					if (CU::Length(normal) != 0.f)
						CU::Normalize(normal);

					lVertices[currentIndex + addedSize] = normal.x;
					lVertices[currentIndex + addedSize + 1] = normal.y;
					lVertices[currentIndex + addedSize + 2] = normal.z;
					lVertices[currentIndex + addedSize + 3] = 0;
					addedSize += NORMAL_STRIDE;
				}

				if (someData->mHasUV)
				{
					bool lUnmappedUV;
					mesh->GetPolygonVertexUV(lPolygonIndex, lVerticeIndex, lUVName, lCurrentUV, lUnmappedUV);
					lVertices[currentIndex + addedSize] = static_cast<float>(lCurrentUV[0]);
					lVertices[currentIndex + addedSize + 1] = static_cast<float>(lCurrentUV[1])*-1.0f;
					addedSize += UV_STRIDE;
				}
					
				if (someData->myHasBiNormal)
				{
					int lBinormIndexIndex = lVerticeIndex;
					if (lBiNormalElement->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
					{
						lBinormIndexIndex = lBiNormalElement->GetIndexArray().GetAt(lVerticeIndex);
					}

					lCurrentBiNormal = lBiNormalElement->GetDirectArray().GetAt(lBinormIndexIndex);

					CU::Vector3f normal( static_cast<float>(lCurrentBiNormal[0]), static_cast<float>(lCurrentBiNormal[1]), static_cast<float>(lCurrentBiNormal[2]));
					normal = normal*CU::Matrix33<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1, 0, 0));
					if (CU::Length(normal) != 0.f)
						CU::Normalize(normal);
					lVertices[currentIndex + addedSize] = normal.x;
					lVertices[currentIndex + addedSize + 1] = normal.y;
					lVertices[currentIndex + addedSize + 2] = normal.z;
					lVertices[currentIndex + addedSize + 3] = 0;
					addedSize += BINORMAL_STRIDE;
				}

				if (someData->myHasTangents)
				{
					int lBinormIndexIndex = lVerticeIndex;
					if (lTangentElement->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
					{
						lBinormIndexIndex = lTangentElement->GetIndexArray().GetAt(lVerticeIndex);
					}

					lCurrentTangent = lTangentElement->GetDirectArray().GetAt(lBinormIndexIndex);

					mesh->GetPolygonVertexNormal(lPolygonIndex, lVerticeIndex, lCurrentNormal);

					CU::Vector3f normal( static_cast<float>(lCurrentTangent[0]), static_cast<float>(lCurrentTangent[1]), static_cast<float>(lCurrentTangent[2]));
					normal = normal*CU::Matrix33<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1, 0, 0));
					if (CU::Length(normal) != 0.f)
						CU::Normalize(normal);
					lVertices[currentIndex + addedSize] = normal.x;
					lVertices[currentIndex + addedSize + 1] = normal.y;
					lVertices[currentIndex + addedSize + 2] = normal.z;
					lVertices[currentIndex + addedSize + 3] = 0;
					addedSize += TANGENT_STRIDE;
				}

				if(someData->myHasSkinweights)
				{
					FbxVector4 currentWeights = weights[lControlPointIndex];
					FbxVectorTemplate4<int> currentBones = bones[lControlPointIndex];
					for(int l = 0;l < 4;++l)
					{
						if(currentBones[l] == -1)
						{
							currentWeights[l] = 0.0f;
						}
					}
					currentWeights.Normalize();

					lVertices[currentIndex + addedSize] = static_cast<float>(currentWeights[0]);
					lVertices[currentIndex + addedSize + 1] = static_cast<float>(currentWeights[1]);
					lVertices[currentIndex + addedSize + 2] = static_cast<float>(currentWeights[2]);
					lVertices[currentIndex + addedSize + 3] = static_cast<float>(currentWeights[3]);
					addedSize += SKINWEIGHT_STRIDE;

						

					lVertices[currentIndex + addedSize] = *(float*)&currentBones[0];
					lVertices[currentIndex + addedSize + 1] = *(float*)&currentBones[1];
					lVertices[currentIndex + addedSize + 2] = *(float*)&currentBones[2];
					lVertices[currentIndex + addedSize + 3] = *(float*)&currentBones[3];
					addedSize += BONEID_STRIDE;
				}
			}
			++lVertexCount;
		}
		someData->mSubMeshes[lMaterialIndex]->TriangleCount += 1;
	}

	someData->myVertexCount = lVertexCount;
	someData->myVertexStride = stride;

	someData->myVertexBuffer = lVertices;
	someData->myIndicies = lIndices;

	if(weights)
	{
		delete [] weights;
		delete [] bones;
	}

	return true;
}