int32 USkeleton::BuildLinkup(const USkeletalMesh* InSkelMesh) { const FReferenceSkeleton& SkeletonRefSkel = ReferenceSkeleton; const FReferenceSkeleton& MeshRefSkel = InSkelMesh->RefSkeleton; // @todoanim : need to refresh NULL SkeletalMeshes from Cache // since now they're autoweak pointer, they will go away if not used // so whenever map transition happens, this links will need to clear up FSkeletonToMeshLinkup NewMeshLinkup; // First, make sure the Skeleton has all the bones the SkeletalMesh possesses. // This can get out of sync if a mesh was imported on that Skeleton, but the Skeleton was not saved. const int32 NumMeshBones = MeshRefSkel.GetNum(); NewMeshLinkup.MeshToSkeletonTable.Empty(NumMeshBones); NewMeshLinkup.MeshToSkeletonTable.AddUninitialized(NumMeshBones); for (int32 MeshBoneIndex = 0; MeshBoneIndex < NumMeshBones; MeshBoneIndex++) { const FName MeshBoneName = MeshRefSkel.GetBoneName(MeshBoneIndex); int32 SkeletonBoneIndex = SkeletonRefSkel.FindBoneIndex(MeshBoneName); #if WITH_EDITOR // If we're in editor, and skeleton is missing a bone, fix it. // not currently supported in-game. if (SkeletonBoneIndex == INDEX_NONE) { FMessageDialog::Open(EAppMsgType::Ok, FText::Format(LOCTEXT("SkeletonBuildLinkupMissingBones", "The Skeleton {0}, is missing bones that SkeletalMesh {1} needs. They will be added now. Please save the Skeleton!"), FText::FromString(GetNameSafe(this)), FText::FromString(GetNameSafe(InSkelMesh)))); // Re-add all SkelMesh bones to the Skeleton. MergeAllBonesToBoneTree(InSkelMesh); // Fix missing bone. SkeletonBoneIndex = SkeletonRefSkel.FindBoneIndex(MeshBoneName); } #endif NewMeshLinkup.MeshToSkeletonTable[MeshBoneIndex] = SkeletonBoneIndex; } const int32 NumSkeletonBones = SkeletonRefSkel.GetNum(); NewMeshLinkup.SkeletonToMeshTable.Empty(NumSkeletonBones); NewMeshLinkup.SkeletonToMeshTable.AddUninitialized(NumSkeletonBones); for (int32 SkeletonBoneIndex=0; SkeletonBoneIndex<NumSkeletonBones; SkeletonBoneIndex++) { const int32 MeshBoneIndex = MeshRefSkel.FindBoneIndex( SkeletonRefSkel.GetBoneName(SkeletonBoneIndex) ); NewMeshLinkup.SkeletonToMeshTable[SkeletonBoneIndex] = MeshBoneIndex; } int32 NewIndex = LinkupCache.Add(NewMeshLinkup); check (NewIndex != INDEX_NONE); SkelMesh2LinkupCache.Add(InSkelMesh, NewIndex); return NewIndex; }
bool USkeleton::RecreateBoneTree(USkeletalMesh* InSkelMesh) { if( InSkelMesh ) { // regenerate Guid RegenerateGuid(); BoneTree.Empty(); ReferenceSkeleton.Empty(); return MergeAllBonesToBoneTree(InSkelMesh); } return false; }