/**
 * 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];
}
Beispiel #2
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);

}