void fbxLoader2::readAnimationTakeData(FbxNode* node)
{
	FbxAnimStack* pAnimStack = FbxCast<FbxAnimStack>(scene->GetSrcObject(FBX_TYPE(FbxAnimStack)));
	FbxAnimLayer* pAnimLayer = pAnimStack->GetMember(FBX_TYPE(FbxAnimLayer));

	FbxAnimCurve* animCv = node->LclTranslation.GetCurve(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_X);

	FbxTimeSpan length = FbxTimeSpan();

	int p = animCv->KeyGetCount();

	const char* nameAnim = animCv->GetName();
	const size_t len = strlen(nameAnim);
	char * new_name = new char[len + 1];
	strncpy(new_name, nameAnim, len);

	animCv->GetTimeInterval(length);

	FbxTime duration = length.GetDuration();
	FbxTime::EMode mode = duration.GetGlobalTimeMode();
	double frameRate = duration.GetFrameRate(mode);

	double startt = length.GetStart().GetMilliSeconds();
	double endt = length.GetStop().GetMilliSeconds();

	int frames = animCv->KeyGetCount();

	animationStructure = new AnimationData(new_name, startt, endt, (int)frameRate, frames);

	for (int i = 0; i< frames; i++)
	{
		SkeletalData *sk = new SkeletalData();
		for(int j = 0; j<skeleton->GetBonesCount(); j++)
		{
			BoneData *bonecopy = new BoneData();
			bonecopy->SetID(skeleton->GetBone(j)->GetID());
			bonecopy->SetName(skeleton->GetBone(j)->GetName());
			bonecopy->SetParent(skeleton->GetBone(j)->GetParent());
			sk->SetBones(bonecopy);
		}
		animationStructure->SetSkeleton(sk, i);
	}
}
bool UnFbx::FFbxImporter::ValidateAnimStack(TArray<FbxNode*>& SortedLinks, TArray<FbxNode*>& NodeArray, FbxAnimStack* CurAnimStack, int32 ResampleRate, bool bImportMorph, FbxTimeSpan &AnimTimeSpan)
{
	// set current anim stack
	Scene->SetCurrentAnimationStack(CurAnimStack);

	UE_LOG(LogFbx, Log, TEXT("Parsing AnimStack %s"),UTF8_TO_TCHAR(CurAnimStack->GetName()));

	// There are a FBX unroll filter bug, so don't bake animation layer at all
	MergeAllLayerAnimation(CurAnimStack, ResampleRate);

	bool bValidAnimStack = true;

	AnimTimeSpan = GetAnimationTimeSpan(SortedLinks[0], CurAnimStack);
	
	// if no duration is found, return false
	if (AnimTimeSpan.GetDuration() <= 0)
	{
		return false;
	}

	const FBXImportOptions* ImportOption = GetImportOptions();
	// only add morph time if not setrange. If Set Range there is no reason to override time
	if ( bImportMorph && ImportOption->AnimationLengthImportType != FBXALIT_SetRange)
	{
		for ( int32 NodeIndex = 0; NodeIndex < NodeArray.Num(); NodeIndex++ )
		{
			// consider blendshape animation curve
			FbxGeometry* Geometry = (FbxGeometry*)NodeArray[NodeIndex]->GetNodeAttribute();
			if (Geometry)
			{
				int32 BlendShapeDeformerCount = Geometry->GetDeformerCount(FbxDeformer::eBlendShape);
				for(int32 BlendShapeIndex = 0; BlendShapeIndex<BlendShapeDeformerCount; ++BlendShapeIndex)
				{
					FbxBlendShape* BlendShape = (FbxBlendShape*)Geometry->GetDeformer(BlendShapeIndex, FbxDeformer::eBlendShape);

					int32 BlendShapeChannelCount = BlendShape->GetBlendShapeChannelCount();
					for(int32 ChannelIndex = 0; ChannelIndex<BlendShapeChannelCount; ++ChannelIndex)
					{
						FbxBlendShapeChannel* Channel = BlendShape->GetBlendShapeChannel(ChannelIndex);

						if(Channel)
						{
							// Get the percentage of influence of the shape.
							FbxAnimCurve* Curve = Geometry->GetShapeChannel(BlendShapeIndex, ChannelIndex, (FbxAnimLayer*)CurAnimStack->GetMember(0));
							if (Curve && Curve->KeyGetCount() > 0)
							{
								FbxTimeSpan TmpAnimSpan;

								if (Curve->GetTimeInterval(TmpAnimSpan))
								{
									bValidAnimStack = true;
									// update animation interval to include morph target range
									AnimTimeSpan.UnionAssignment(TmpAnimSpan);
								}
							}
						}
					}
				}
			}
		}
	}

	return bValidAnimStack;
}
int32 UnFbx::FFbxImporter::GetMaxSampleRate(TArray<FbxNode*>& SortedLinks, TArray<FbxNode*>& NodeArray)
{
	int32 MaxStackResampleRate = 0;

	int32 AnimStackCount = Scene->GetSrcObjectCount<FbxAnimStack>();
	for( int32 AnimStackIndex = 0; AnimStackIndex < AnimStackCount; AnimStackIndex++)
	{
		FbxAnimStack* CurAnimStack = Scene->GetSrcObject<FbxAnimStack>(AnimStackIndex);

		FbxTimeSpan AnimStackTimeSpan = GetAnimationTimeSpan(SortedLinks[0], CurAnimStack);

		double AnimStackStart = AnimStackTimeSpan.GetStart().GetSecondDouble();
		double AnimStackStop = AnimStackTimeSpan.GetStop().GetSecondDouble();

		FbxAnimLayer* AnimLayer = (FbxAnimLayer*)CurAnimStack->GetMember(0);

		for(int32 LinkIndex = 0; LinkIndex < SortedLinks.Num(); ++LinkIndex)
		{
			FbxNode* CurrentLink = SortedLinks[LinkIndex];

			FbxAnimCurve* Curves[6];

			Curves[0] = CurrentLink->LclTranslation.GetCurve(AnimLayer, FBXSDK_CURVENODE_COMPONENT_X, false);
			Curves[1] = CurrentLink->LclTranslation.GetCurve(AnimLayer, FBXSDK_CURVENODE_COMPONENT_Y, false);
			Curves[2] = CurrentLink->LclTranslation.GetCurve(AnimLayer, FBXSDK_CURVENODE_COMPONENT_Z, false);
			Curves[3] = CurrentLink->LclRotation.GetCurve(AnimLayer, FBXSDK_CURVENODE_COMPONENT_X, false);
			Curves[4] = CurrentLink->LclRotation.GetCurve(AnimLayer, FBXSDK_CURVENODE_COMPONENT_Y, false);
			Curves[5] = CurrentLink->LclRotation.GetCurve(AnimLayer, FBXSDK_CURVENODE_COMPONENT_Z, false);

			for(int32 CurveIndex = 0; CurveIndex < 6; ++CurveIndex)
			{
				FbxAnimCurve* CurrentCurve = Curves[CurveIndex];
				if(CurrentCurve)
				{
					int32 KeyCount = CurrentCurve->KeyGetCount();

					FbxTimeSpan TimeInterval(FBXSDK_TIME_INFINITE,FBXSDK_TIME_MINUS_INFINITE);
					bool bValidTimeInterval = CurrentCurve->GetTimeInterval(TimeInterval);

 					if(KeyCount > 1 && bValidTimeInterval)
					{
						double KeyAnimLength = TimeInterval.GetDuration().GetSecondDouble();
						double KeyAnimStart = TimeInterval.GetStart().GetSecondDouble();
						double KeyAnimStop = TimeInterval.GetStop().GetSecondDouble();

						if(KeyAnimLength != 0.0)
						{
							// 30 fps animation has 31 keys because it includes index 0 key for 0.0 second
							int32 NewRate = FPlatformMath::RoundToInt((KeyCount-1) / KeyAnimLength);
							MaxStackResampleRate = FMath::Max(NewRate, MaxStackResampleRate);
						}
					}
				}
			}
		}
	}

	// Make sure we're not hitting 0 for samplerate
	if ( MaxStackResampleRate != 0 )
	{
		return MaxStackResampleRate;
	}

	return DEFAULT_SAMPLERATE;
}
void fbxLoader2::processMesh(FbxNode* node)
{
	FbxMesh* mesh = node->GetMesh();

	this->readAnimationWeigths(mesh);

	if(mesh!=NULL && mesh->IsTriangleMesh())
	{
		for (int i = 0; i<mesh->GetControlPointsCount(); i++)
		{
			readVertex(mesh, i, &vertex[i]);
			vertexArray[i].position = D3DXVECTOR3(vertex[i]);
		}

		int a = mesh->GetPolygonVertexCount();

		for (int i = 0; i<mesh->GetPolygonVertexCount(); i++)
		{
			readUV(mesh, i, 0, &uv[i]);
			readNormal(mesh, i, &normal[i]);
			indices[i].indice = mesh->GetPolygonVertices()[i];
			indices[i].normal1 = normal[i];
			indices[i].uv1 = uv[i];
			indicesMeshCount++;
		}
	}

	//vertexLists.push_back(vertexArray);
	indiceLists.push_back(indices);

	FbxAnimStack* pAnimStack = FbxCast<FbxAnimStack>(scene->GetSrcObject(FBX_TYPE(FbxAnimStack)));
	int numAnimLayers = pAnimStack->GetMemberCount(FBX_TYPE(FbxAnimLayer));

	this->setBindPoseCluster(node);

	for (int i = 0; i < numAnimLayers; i++)
	{
		FbxAnimLayer* pAnimLayer = pAnimStack->GetMember(FBX_TYPE(FbxAnimLayer), i);
		FbxAnimCurve* animCv = this->findSkeletonRootBone(scene->GetRootNode())->GetChild(0)->LclTranslation.GetCurve(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_X);

		if (animCv)
		{
			FbxTimeSpan animationLength;
			int p = animCv->KeyGetCount();
			animCv->GetTimeInterval(animationLength);

			for(int j = 0; j<animationStructure->GetFramesNumber();j++)
			{
				FbxTime timeKey = animCv->KeyGet(j).mTime;
				//FbxTime interval = (duration/p)*j + animationLength.GetStart();

				//int intervalVal = (duration.GetSecondCount()/p)*j + animationLength.GetStart().GetSecondCount();
				const FbxTime pTime = animCv->KeyGet(j).mTime;


				FbxAMatrix pGlobalPos = GetGlobalPosition(node, pTime, scene->GetPose(j));

				ComputeSkinDeformation(pGlobalPos, mesh, timeKey, scene->GetPose(j), j);
			}
		}
	}

	for(int i = 0; i<node->GetChildCount(); i++)
	{
		processMesh(node->GetChild(i));
	}
}