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