示例#1
0
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);
	}
}
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;
}
bool UnFbx::FFbxImporter::IsValidAnimationData(TArray<FbxNode*>& SortedLinks, TArray<FbxNode*>& NodeArray, int32& ValidTakeCount)
{
	// If there are no valid links, then we cannot import the anim set
	if(SortedLinks.Num() == 0)
	{
		return false;
	}

	ValidTakeCount = 0;

	int32 AnimStackCount = Scene->GetSrcObjectCount<FbxAnimStack>();

	int32 AnimStackIndex;
	for (AnimStackIndex = 0; AnimStackIndex < AnimStackCount; AnimStackIndex++ )
	{
		FbxAnimStack* CurAnimStack = Scene->GetSrcObject<FbxAnimStack>(AnimStackIndex);
		// set current anim stack
		Scene->SetCurrentAnimationStack(CurAnimStack);

		// debug purpose
		for (int32 BoneIndex = 0; BoneIndex < SortedLinks.Num(); BoneIndex++)
		{
			FString BoneName = UTF8_TO_TCHAR(MakeName(SortedLinks[BoneIndex]->GetName()));
			UE_LOG(LogFbx, Log, TEXT("SortedLinks :(%d) %s"), BoneIndex, *BoneName );
		}

		FbxTimeSpan AnimTimeSpan = GetAnimationTimeSpan(SortedLinks[0], CurAnimStack);
		if (AnimTimeSpan.GetDuration() <= 0)
		{
			AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Warning, FText::Format(LOCTEXT("FBXImport_ZeroLength", "Animation Stack {0} does not contain any valid key. Try different time options when import."), FText::FromString(UTF8_TO_TCHAR(CurAnimStack->GetName())))), FFbxErrors::Animation_ZeroLength);
			continue;
		}

		ValidTakeCount++;
		{
			bool bBlendCurveFound = false;

			for ( int32 NodeIndex = 0; !bBlendCurveFound && 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)
								{
									bBlendCurveFound = true;
									break;
								}
							}
						}
					}
				}
			}
		}
	}		

	return ( ValidTakeCount != 0 );
}
示例#4
0
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));
	}
}