void USkeleton::HandleSkeletonHierarchyChange() { MarkPackageDirty(); RegenerateGuid(); // Clear exiting MeshLinkUp tables. ClearCacheData(); // Fix up loaded animations (any animations that aren't loaded will be fixed on load) for(TObjectIterator<UAnimationAsset> It; It; ++It) { UAnimationAsset* CurrentAnimation = *It; if (CurrentAnimation->GetSkeleton() == this) { CurrentAnimation->ValidateSkeleton(); } } #if WITH_EDITORONLY_DATA RefreshAllRetargetSources(); #endif OnSkeletonHierarchyChanged.Broadcast(); }
void USkeleton::HandleSkeletonHierarchyChange() { MarkPackageDirty(); RegenerateGuid(); // Fix up loaded animations (any animations that aren't loaded will be fixed on load) for(TObjectIterator<UAnimationAsset> It; It; ++It) { UAnimationAsset* CurrentAnimation = *It; CurrentAnimation->ValidateSkeleton(); } RefreshAllRetargetSources(); OnSkeletonHierarchyChanged.Broadcast(); }
bool USkeleton::MergeBonesToBoneTree(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); MarkPackageDirty(); } } bSuccess = true; } } // if succeed if (bSuccess) { InSkeletalMesh->Skeleton = this; InSkeletalMesh->MarkPackageDirty(); // make sure to refresh all base poses // so that they have same number of bones of ref pose #if WITH_EDITORONLY_DATA RefreshAllRetargetSources(); #endif } return bSuccess; }