void FAnimationRuntime::ExcludeBonesWithNoParents(const TArray<int32> & BoneIndices, const FReferenceSkeleton& RefSkeleton, TArray<int32> & FilteredRequiredBones) { // Filter list, we only want bones that have their parents present in this array. FilteredRequiredBones.Empty(BoneIndices.Num()); for (int32 Index=0; Index<BoneIndices.Num(); Index++) { const int32& BoneIndex = BoneIndices[Index]; // Always add root bone. if( BoneIndex == 0 ) { FilteredRequiredBones.Add(BoneIndex); } else { const int32 ParentBoneIndex = RefSkeleton.GetParentIndex(BoneIndex); if( FilteredRequiredBones.Contains(ParentBoneIndex) ) { FilteredRequiredBones.Add(BoneIndex); } else { UE_LOG(LogAnimation, Warning, TEXT("ExcludeBonesWithNoParents: Filtering out bone (%s) since parent (%s) is missing"), *RefSkeleton.GetBoneName(BoneIndex).ToString(), *RefSkeleton.GetBoneName(ParentBoneIndex).ToString()); } } } }
/** Check that root bone is the same, and that any bones that are common have the correct parent. */ bool SkeletonsAreCompatible( const FReferenceSkeleton& NewSkel, const FReferenceSkeleton& ExistSkel ) { if(NewSkel.GetBoneName(0) != ExistSkel.GetBoneName(0)) { UnFbx::FFbxImporter* FFbxImporter = UnFbx::FFbxImporter::GetInstance(); FFbxImporter->AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Error, FText::Format(LOCTEXT("MeshHasDifferentRoot", "Root Bone is '{0}' instead of '{1}'.\nDiscarding existing LODs."), FText::FromName(NewSkel.GetBoneName(0)), FText::FromName(ExistSkel.GetBoneName(0))))); return false; } for(int32 i=1; i<NewSkel.GetNum(); i++) { // See if bone is in both skeletons. int32 NewBoneIndex = i; FName NewBoneName = NewSkel.GetBoneName(NewBoneIndex); int32 BBoneIndex = ExistSkel.FindBoneIndex(NewBoneName); // If it is, check parents are the same. if(BBoneIndex != INDEX_NONE) { FName NewParentName = NewSkel.GetBoneName( NewSkel.GetParentIndex(NewBoneIndex) ); FName ExistParentName = ExistSkel.GetBoneName( ExistSkel.GetParentIndex(BBoneIndex) ); if(NewParentName != ExistParentName) { UnFbx::FFbxImporter* FFbxImporter = UnFbx::FFbxImporter::GetInstance(); FFbxImporter->AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Error, FText::Format(LOCTEXT("MeshHasDifferentRoot", "Root Bone is '{0}' instead of '{1}'.\nDiscarding existing LODs."), FText::FromName(NewBoneName), FText::FromName(NewParentName)))); return false; } } } return true; }