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