bool USkeleton::MergeBonesToBoneTree(const USkeletalMesh* InSkeletalMesh, const TArray<int32> & RequiredRefBones) { // see if it needs all animation data to remap - only happens when bone structure CHANGED - added bool bSuccess = false; // clear cache data since it won't work anymore once this is done ClearCacheData(); // if it's first time if( BoneTree.Num() == 0 ) { bSuccess = CreateReferenceSkeletonFromMesh(InSkeletalMesh, RequiredRefBones); } else { // can we play? - hierarchy matches if( IsCompatibleMesh(InSkeletalMesh) ) { // Exclude bones who do not have a parent. TArray<int32> FilteredRequiredBones; FAnimationRuntime::ExcludeBonesWithNoParents(RequiredRefBones, InSkeletalMesh->RefSkeleton, FilteredRequiredBones); for (int32 Index=0; Index<FilteredRequiredBones.Num(); Index++) { const int32& MeshBoneIndex = FilteredRequiredBones[Index]; const int32& SkeletonBoneIndex = ReferenceSkeleton.FindBoneIndex(InSkeletalMesh->RefSkeleton.GetBoneName(MeshBoneIndex)); // Bone doesn't already exist. Add it. if( SkeletonBoneIndex == INDEX_NONE ) { FMeshBoneInfo NewMeshBoneInfo = InSkeletalMesh->RefSkeleton.GetRefBoneInfo()[MeshBoneIndex]; // Fix up ParentIndex for our new Skeleton. if( ReferenceSkeleton.GetNum() == 0 ) { NewMeshBoneInfo.ParentIndex = INDEX_NONE; // root } else { NewMeshBoneInfo.ParentIndex = ReferenceSkeleton.FindBoneIndex(InSkeletalMesh->RefSkeleton.GetBoneName(InSkeletalMesh->RefSkeleton.GetParentIndex(MeshBoneIndex))); } ReferenceSkeleton.Add(NewMeshBoneInfo, InSkeletalMesh->RefSkeleton.GetRefBonePose()[MeshBoneIndex]); BoneTree.AddZeroed(1); } } bSuccess = true; } } // if succeed if (bSuccess) { #if WITH_EDITOR HandleSkeletonHierarchyChange(); #endif } return bSuccess; }
void USkeleton::RemoveBonesFromSkeleton( const TArray<FName>& BonesToRemove, bool bRemoveChildBones ) { TArray<int32> BonesRemoved = ReferenceSkeleton.RemoveBonesByName(BonesToRemove); if(BonesRemoved.Num() > 0) { BonesRemoved.Sort(); for(int32 Index = BonesRemoved.Num()-1; Index >=0; --Index) { BoneTree.RemoveAt(Index); } HandleSkeletonHierarchyChange(); } }