Add bWasCreated flag to BindToSkeletalMesh so when we know when we create the sequencer anim instance we should save the pose. This removes the need for control rig to override NativeInitialization. Also add some checks to make sure we save a valid pose.

#jira UE-76569

#rb max.chen

#ROBOMERGE-OWNER: ben.marsh
#ROBOMERGE-AUTHOR: mike.zyracki
#ROBOMERGE-SOURCE: CL 7280102 in //UE4/Release-4.23/... via CL 7280144
#ROBOMERGE-BOT: BUILD (Main -> Dev-Build) (v371-7306989)

[CL 7350675 by mike zyracki in Dev-Build branch]
This commit is contained in:
mike zyracki
2019-07-17 01:10:05 -04:00
parent 0f8dd7bb14
commit 8441bf92a8
9 changed files with 28 additions and 23 deletions

View File

@@ -83,7 +83,8 @@ struct FBindControlRigObjectToken : IMovieSceneExecutionToken
check(ControlRig);
if (USkeletalMeshComponent* SkeletalMeshComponent = Cast<USkeletalMeshComponent>(ControlRig->GetObjectBinding()->GetBoundObject()))
{
if (UControlRigSequencerAnimInstance* AnimInstance = UAnimCustomInstance::BindToSkeletalMeshComponent<UControlRigSequencerAnimInstance>(SkeletalMeshComponent))
bool bWasCreated = false;
if (UControlRigSequencerAnimInstance* AnimInstance = UAnimCustomInstance::BindToSkeletalMeshComponent<UControlRigSequencerAnimInstance>(SkeletalMeshComponent,bWasCreated))
{
AnimInstance->RecalcRequiredBones();
}

View File

@@ -20,9 +20,3 @@ bool UControlRigSequencerAnimInstance::UpdateControlRig(UControlRig* InControlRi
CachedControlRig = InControlRig;
return GetProxyOnGameThread<FControlRigSequencerAnimInstanceProxy>().UpdateControlRig(InControlRig, SequenceId, bAdditive, bApplyBoneFilter, BoneFilter, Weight, bExternalSource);
}
void UControlRigSequencerAnimInstance::NativeInitializeAnimation()
{
//Do nothing since UAnimSequencerInstance save's a pose snapshot which can cause ensure and crash issues
//since it may not have a skeletal mesh or component transform set up yet.
}

View File

@@ -22,5 +22,4 @@ public:
protected:
// UAnimInstance interface
virtual FAnimInstanceProxy* CreateAnimInstanceProxy() override;
virtual void NativeInitializeAnimation() override;
};

View File

@@ -1238,7 +1238,8 @@ void FControlRigEditor::HandlePreviewSceneCreated(const TSharedRef<IPersonaPrevi
UControlRigSkeletalMeshComponent* EditorSkelComp = NewObject<UControlRigSkeletalMeshComponent>(Actor);
EditorSkelComp->SetSkeletalMesh(InPersonaPreviewScene->GetPersonaToolkit()->GetPreviewMesh());
InPersonaPreviewScene->SetPreviewMeshComponent(EditorSkelComp);
UAnimCustomInstance::BindToSkeletalMeshComponent<UControlRigSequencerAnimInstance>(EditorSkelComp);
bool bWasCreated = false;
UAnimCustomInstance::BindToSkeletalMeshComponent<UControlRigSequencerAnimInstance>(EditorSkelComp, bWasCreated);
InPersonaPreviewScene->AddComponent(EditorSkelComp, FTransform::Identity);
// set root component, so we can attach to it.
@@ -1328,7 +1329,8 @@ void FControlRigEditor::RebindToSkeletalMeshComponent()
UDebugSkelMeshComponent* MeshComponent = GetPersonaToolkit()->GetPreviewScene()->GetPreviewMeshComponent();
if (MeshComponent)
{
UAnimCustomInstance::BindToSkeletalMeshComponent<UControlRigSequencerAnimInstance>(MeshComponent);
bool bWasCreated = false;
UAnimCustomInstance::BindToSkeletalMeshComponent<UControlRigSequencerAnimInstance>(MeshComponent , bWasCreated);
}
}

View File

@@ -352,7 +352,8 @@ void FAnimationEditorPreviewScene::RefreshAdditionalMeshes(bool bAllowOverrideBa
}
else
{
UAnimCustomInstance::BindToSkeletalMeshComponent<UAnimPreviewAttacheInstance>(NewComp);
bool bWasCreated = false;
UAnimCustomInstance::BindToSkeletalMeshComponent<UAnimPreviewAttacheInstance>(NewComp,bWasCreated);
}
AdditionalMeshes.Add(NewComp);

View File

@@ -40,12 +40,13 @@ void UAnimSequencerInstance::ResetPose()
GetProxyOnGameThread<FAnimSequencerInstanceProxy>().ResetPose();
}
void UAnimSequencerInstance::NativeInitializeAnimation()
{
SavePose();
}
void UAnimSequencerInstance::SavePose()
{
SavePoseSnapshot(UAnimSequencerInstance::SequencerPoseName);
if (USkeletalMeshComponent* SkeletalMeshComponent = GetSkelMeshComponent())
{
if (SkeletalMeshComponent->SkeletalMesh && SkeletalMeshComponent->GetComponentSpaceTransforms().Num() > 0)
{
SavePoseSnapshot(UAnimSequencerInstance::SequencerPoseName);
}
}
}

View File

@@ -21,8 +21,9 @@ class ANIMGRAPHRUNTIME_API UAnimCustomInstance : public UAnimInstance
* @return the current (or newly created) UAnimCustomInstance
*/
template<typename InstanceClassType>
static InstanceClassType* BindToSkeletalMeshComponent(USkeletalMeshComponent* InSkeletalMeshComponent)
static InstanceClassType* BindToSkeletalMeshComponent(USkeletalMeshComponent* InSkeletalMeshComponent, bool& bOutWasCreated)
{
bOutWasCreated = false;
// make sure to tick and refresh all the time when ticks
// @TODO: this needs restoring post-binding
InSkeletalMeshComponent->VisibilityBasedAnimTickOption = EVisibilityBasedAnimTickOption::AlwaysTickPoseAndRefreshBones;
@@ -50,6 +51,7 @@ class ANIMGRAPHRUNTIME_API UAnimCustomInstance : public UAnimInstance
InstanceClassType* SequencerInstance = NewObject<InstanceClassType>(InSkeletalMeshComponent, InstanceClassType::StaticClass());
InSkeletalMeshComponent->AnimScriptInstance = SequencerInstance;
InSkeletalMeshComponent->AnimScriptInstance->InitializeAnimation();
bOutWasCreated = true;
return SequencerInstance;
}
else

View File

@@ -27,13 +27,14 @@ public:
/** Reset the pose for this instance*/
void ResetPose();
/** Saved the named pose to restore after */
void SavePose();
protected:
// UAnimInstance interface
virtual FAnimInstanceProxy* CreateAnimInstanceProxy() override;
virtual void NativeInitializeAnimation() override;
/** Saved the named pose to restore after */
void SavePose();
public:
static const FName SequencerPoseName;

View File

@@ -236,8 +236,12 @@ namespace MovieScene
OriginalStack.SavePreAnimatedState(Player, *SkeletalMeshComponent, GetAnimControlTypeID(), FPreAnimatedAnimationTokenProducer());
UAnimInstance* ExistingAnimInstance = SkeletalMeshComponent->GetAnimInstance();
UAnimSequencerInstance* SequencerInstance = UAnimCustomInstance::BindToSkeletalMeshComponent<UAnimSequencerInstance>(SkeletalMeshComponent);
bool bWasCreated = false;
UAnimSequencerInstance* SequencerInstance = UAnimCustomInstance::BindToSkeletalMeshComponent<UAnimSequencerInstance>(SkeletalMeshComponent,bWasCreated);
if (bWasCreated)
{
SequencerInstance->SavePose();
}
const bool bPreviewPlayback = ShouldUsePreviewPlayback(Player, *SkeletalMeshComponent);