예제 #1
0
void fbxLoader2::buildSkeleton(FbxNode *node)
{
	std::string s2("Nub");
	std::string s3("Footsteps");
	std::string s1(node->GetName());
	int found = s1.find(s2);
	int found2 = s1.find(s3);

	if( node->GetNodeAttribute())
	{
		switch(node->GetNodeAttribute()->GetAttributeType())
		{
		case FbxNodeAttribute::eSkeleton:
			if (found == std::string::npos && found2 == std::string::npos)
			{
				FbxSkeleton *skeletalMesh = node->GetSkeleton();
				if( !skeletalMesh ) return;
				FbxNode* boneNode = skeletalMesh->GetNode();
				buildSkeletonCycle(boneNode, -1);
					//rootbone1 = true;
			}
			break;

		}
	}

	for (int i = 0; i<node->GetChildCount(); i++)
	{
		FbxNode *child = node->GetChild(i);
		//buildSkeleton(child);
	}

	
}
/**
 * Adds FBX skeleton nodes to the FbxScene based on the skeleton in the given USkeletalMesh, and fills
 * the given array with the nodes created
 */
FbxNode* FFbxExporter::CreateSkeleton(const USkeletalMesh* SkelMesh, TArray<FbxNode*>& BoneNodes)
{
	const FReferenceSkeleton& RefSkeleton= SkelMesh->RefSkeleton;

	if(RefSkeleton.GetNum() == 0)
	{
		return NULL;
	}

	// Create a list of the nodes we create for each bone, so that children can 
	// later look up their parent
	BoneNodes.Reserve(RefSkeleton.GetNum());

	for(int32 BoneIndex = 0; BoneIndex < RefSkeleton.GetNum(); ++BoneIndex)
	{
		const FMeshBoneInfo& CurrentBone = RefSkeleton.GetRefBoneInfo()[BoneIndex];
		const FTransform& BoneTransform = RefSkeleton.GetRefBonePose()[BoneIndex];

		FbxString BoneName = Converter.ConvertToFbxString(CurrentBone.ExportName);


		// Create the node's attributes
		FbxSkeleton* SkeletonAttribute = FbxSkeleton::Create(Scene, BoneName.Buffer());
		if(BoneIndex)
		{
			SkeletonAttribute->SetSkeletonType(FbxSkeleton::eLimbNode);
			//SkeletonAttribute->Size.Set(1.0);
		}
		else
		{
			SkeletonAttribute->SetSkeletonType(FbxSkeleton::eRoot);
			//SkeletonAttribute->Size.Set(1.0);
		}
		

		// Create the node
		FbxNode* BoneNode = FbxNode::Create(Scene, BoneName.Buffer());
		BoneNode->SetNodeAttribute(SkeletonAttribute);

		// Set the bone node's local orientation
		FVector UnrealRotation = BoneTransform.GetRotation().Euler();
		FbxVector4 LocalPos = Converter.ConvertToFbxPos(BoneTransform.GetTranslation());
		FbxVector4 LocalRot = Converter.ConvertToFbxRot(UnrealRotation);

		BoneNode->LclTranslation.Set(LocalPos);
		BoneNode->LclRotation.Set(LocalRot);


		// If this is not the root bone, attach it to its parent
		if(BoneIndex)
		{
			BoneNodes[CurrentBone.ParentIndex]->AddChild(BoneNode);
		}


		// Add the node to the list of nodes, in bone order
		BoneNodes.Push(BoneNode);
	}

	return BoneNodes[0];
}
예제 #3
0
void LoadAnimation(AnimationData& aAnimation,FbxNode* aNode,FbxAMatrix& aParentOrientation, FbxPose* aPose, FbxAnimLayer* aCurrentAnimLayer, int parentBone)
{
	FbxAMatrix lGlobalPosition = GetGlobalPosition(aNode, static_cast<FbxTime>(0.0f), aPose, &aParentOrientation);
	FbxNodeAttribute* lNodeAttribute = aNode->GetNodeAttribute();
	int boneId = -1;
	if (lNodeAttribute)
	{
		if(lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eSkeleton)
		{
			Bone newBone;
			newBone.myAnimationTime = GetAnimationTime(aNode,aCurrentAnimLayer);
			float oneFrameTime = 1.0f/24.0f;
				
			CU::Matrix44f fixMatrix;
			fixMatrix.myMatrix[0] = -1;
			FbxAMatrix lLocalTransform = aNode->EvaluateLocalTransform();
			newBone.myBaseOrientation = fixMatrix * CreateMatrix(lLocalTransform) * fixMatrix;

			char buffer[32];
			_itoa_s<32>(parentBone,buffer,10);
			newBone.myName = aNode->GetName();	
			newBone.myName += buffer;

			int lNodeIndex = aPose->Find(aNode);
			auto bindPoseMatrix = aPose->GetMatrix(lNodeIndex);

			FbxAMatrix bindMatrix;
			memcpy((double*)bindMatrix, (double*)bindPoseMatrix, sizeof(bindMatrix.mData));

			FbxAMatrix localPosOffset;
				
			memcpy((double*)localPosOffset, (double*)bindPoseMatrix, sizeof(localPosOffset.mData));
			localPosOffset =  localPosOffset * aParentOrientation.Inverse();

			newBone.myBindMatrix = fixMatrix * CreateMatrix(lGlobalPosition.Inverse()) * fixMatrix;

			CU::Matrix44f localStartOffset = CreateMatrix(bindMatrix.Inverse());
			for(float currentFrameTime = 0.0f;currentFrameTime < newBone.myAnimationTime;currentFrameTime+= oneFrameTime)
			{
				KeyFrame keyFrame;
				keyFrame.myTime = currentFrameTime;

				FbxTime time;
				time.SetSecondDouble(currentFrameTime);
				keyFrame.myMatrix = fixMatrix * CreateMatrix(aNode->EvaluateLocalTransform(time)) * fixMatrix;
				newBone.myFrames.push_back(keyFrame);
			}
			FbxAMatrix animationMatrix;

			FbxSkeleton* sekeleton = aNode->GetSkeleton();
			if(sekeleton->IsSkeletonRoot())
			{
				aAnimation.myBindMatrix = CU::Matrix44<float>();
				aAnimation.myRootBone = aAnimation.myBones.size();
			}
			boneId = aAnimation.myBones.size();
			aNode->SetUserDataPtr((void*)boneId);

			if(parentBone != -1)
			{
				aAnimation.myBones[parentBone].myChilds.push_back(boneId);
			}
			newBone.myId = boneId;
			aAnimation.myBones.push_back(newBone);
		}
	}

	const int lChildCount = aNode->GetChildCount();
	for (int lChildIndex = 0; lChildIndex < lChildCount; ++lChildIndex)
	{
		LoadAnimation( aAnimation, aNode->GetChild(lChildIndex), lGlobalPosition , aPose, aCurrentAnimLayer, boneId);
	}
}
예제 #4
0
void ExportBones(const Value& obj)
{
	const Value& boneName = obj["BoneName"];
	if (boneName.IsNull())
	{
		return;
	}

	//string name = obj["Name"].GetString();

	const Value& parentIndex = obj["ParentIndex"];
	const Value& boneTransform = obj["BoneTransform"];

	fbxBones.resize(boneName.Size());
	for (uint32_t i = 0; i < fbxBones.size(); i++)
	{
		FbxNode* boneNode = FbxNode::Create(pScene, boneName[i].GetString());
		fbxBones[i] = boneNode;
		double x, y, z, w;
		x = boneTransform[i * 7 + 0].GetDouble();
		x = -x;
		y = boneTransform[i * 7 + 1].GetDouble();
		z = boneTransform[i * 7 + 2].GetDouble();
		boneNode->LclTranslation.Set(FbxDouble3(x, y, z));

		x = boneTransform[i * 7 + 3].GetDouble();
		y = boneTransform[i * 7 + 4].GetDouble();
		z = boneTransform[i * 7 + 5].GetDouble();
		w = boneTransform[i * 7 + 6].GetDouble();

		FbxSkeleton* pSkeleton = FbxSkeleton::Create(pScene, boneName[i].GetString());
		int parent = parentIndex[i].GetInt();
		if (parent == -1) {
			pSkeleton->SetSkeletonType(FbxSkeleton::eRoot);
		}
		else {
			pSkeleton->SetSkeletonType(FbxSkeleton::eLimbNode);
			pSkeleton->Size.Set(0.1);
		}

		boneNode->SetNodeAttribute(pSkeleton);
	}

	for (uint32_t i = 0; i < fbxBones.size(); i++) {
		int parent = parentIndex[i].GetInt();
		if (parent == -1) {
			pScene->GetRootNode()->AddChild(fbxBones[i]);
		}
		else {
			fbxBones[parent]->AddChild(fbxBones[i]);
		}
	}

	FbxPose* lPose = FbxPose::Create(pScene, boneName[0].GetString());
	// default pose type is rest pose, so we need to set the type as bind pose
	lPose->SetIsBindPose(true);

	for (uint32_t i = 0; i < fbxBones.size(); i++) {
		FbxNode*  lKFbxNode = fbxBones[i];
		FbxMatrix lBindMatrix = lKFbxNode->EvaluateGlobalTransform();
		lPose->Add(lKFbxNode, lBindMatrix);
	}

	pScene->AddPose(lPose);

}