void FPhysScene::WaitPhysScenes() { FGraphEventArray ThingsToComplete; if (PhysicsSceneCompletion.GetReference()) { ThingsToComplete.Add(PhysicsSceneCompletion); } // Loop through scene types to get all scenes // we just wait on everything, though some of these are redundant for (uint32 SceneType = 0; SceneType < NumPhysScenes; ++SceneType) { if (PhysicsSubsceneCompletion[SceneType].GetReference()) { ThingsToComplete.Add(PhysicsSubsceneCompletion[SceneType]); } if (FrameLaggedPhysicsSubsceneCompletion[SceneType].GetReference()) { ThingsToComplete.Add(FrameLaggedPhysicsSubsceneCompletion[SceneType]); } } if (ThingsToComplete.Num()) { QUICK_SCOPE_CYCLE_COUNTER(STAT_FPhysScene_WaitPhysScenes); FTaskGraphInterface::Get().WaitUntilTasksComplete(ThingsToComplete, ENamedThreads::GameThread); } }
void FPhysScene::WaitClothScene() { FGraphEventArray ThingsToComplete; if (PhysicsSubsceneCompletion[PST_Cloth].GetReference()) { ThingsToComplete.Add(PhysicsSubsceneCompletion[PST_Cloth]); } if (ThingsToComplete.Num()) { FTaskGraphInterface::Get().WaitUntilTasksComplete(ThingsToComplete, ENamedThreads::GameThread); } }
void USkeletalMeshComponent::BlendInPhysics(FTickFunction& ThisTickFunction) { check(IsInGameThread()); // Can't do anything without a SkeletalMesh if( !SkeletalMesh ) { return; } // We now have all the animations blended together and final relative transforms for each bone. // If we don't have or want any physics, we do nothing. if( Bodies.Num() > 0 ) { HandleExistingParallelEvaluationTask(/*bBlockOnTask = */ true, /*bPerformPostAnimEvaluation =*/ true); // start parallel work check(!IsValidRef(ParallelAnimationEvaluationTask)); const bool bParallelBlend = !!CVarUseParallelBlendPhysics.GetValueOnGameThread() && FApp::ShouldUseThreadingForPerformance(); if(bParallelBlend) { if (SkeletalMesh->RefSkeleton.GetNum() != AnimEvaluationContext.LocalAtoms.Num()) { // Initialize Parallel Task arrays AnimEvaluationContext.SpaceBases = GetSpaceBases(); } AnimEvaluationContext.LocalAtoms.Reset(LocalAtoms.Num()); AnimEvaluationContext.LocalAtoms.Append(LocalAtoms); ParallelAnimationEvaluationTask = TGraphTask<FParallelBlendPhysicsTask>::CreateTask().ConstructAndDispatchWhenReady(this); // set up a task to run on the game thread to accept the results FGraphEventArray Prerequistes; Prerequistes.Add(ParallelAnimationEvaluationTask); check(!IsValidRef(ParallelBlendPhysicsCompletionTask)); ParallelBlendPhysicsCompletionTask = TGraphTask<FParallelBlendPhysicsCompletionTask>::CreateTask(&Prerequistes).ConstructAndDispatchWhenReady(this); ThisTickFunction.GetCompletionHandle()->DontCompleteUntil(ParallelBlendPhysicsCompletionTask); } else { PerformBlendPhysicsBones(RequiredBones, LocalAtoms); PostBlendPhysics(); } } }
void FPhysScene::StartFrame() { FGraphEventArray FinishPrerequisites; // Run the sync scene TickPhysScene(PST_Sync, PhysicsSubsceneCompletion[PST_Sync]); { FGraphEventArray MainScenePrerequisites; if (FrameLagAsync() && bAsyncSceneEnabled) { if (FrameLaggedPhysicsSubsceneCompletion[PST_Async].GetReference() && !FrameLaggedPhysicsSubsceneCompletion[PST_Async]->IsComplete()) { MainScenePrerequisites.Add(FrameLaggedPhysicsSubsceneCompletion[PST_Async]); FinishPrerequisites.Add(FrameLaggedPhysicsSubsceneCompletion[PST_Async]); } } if (PhysicsSubsceneCompletion[PST_Sync].GetReference()) { MainScenePrerequisites.Add(PhysicsSubsceneCompletion[PST_Sync]); new (FinishPrerequisites) FGraphEventRef(FDelegateGraphTask::CreateAndDispatchWhenReady(FDelegateGraphTask::FDelegate::CreateRaw(this, &FPhysScene::SceneCompletionTask, PST_Sync), TEXT("ProcessPhysScene_Sync"), &MainScenePrerequisites, ENamedThreads::GameThread, ENamedThreads::GameThread)); } } if (!FrameLagAsync() && bAsyncSceneEnabled) { TickPhysScene(PST_Async, PhysicsSubsceneCompletion[PST_Async]); if (PhysicsSubsceneCompletion[PST_Async].GetReference()) { new (FinishPrerequisites) FGraphEventRef(FDelegateGraphTask::CreateAndDispatchWhenReady(FDelegateGraphTask::FDelegate::CreateRaw(this, &FPhysScene::SceneCompletionTask, PST_Async), TEXT("ProcessPhysScene_Async"), PhysicsSubsceneCompletion[PST_Async], ENamedThreads::GameThread, ENamedThreads::GameThread)); } } check(!PhysicsSceneCompletion.GetReference()); // this should have been cleared if (FinishPrerequisites.Num()) { if (FinishPrerequisites.Num() > 1) // we don't need to create a new task if we only have one prerequisite { PhysicsSceneCompletion = TGraphTask<FNullGraphTask>::CreateTask(&FinishPrerequisites, ENamedThreads::GameThread).ConstructAndDispatchWhenReady(TEXT("ProcessPhysScene_Join"), PhysSingleThreadedMode() ? ENamedThreads::GameThread : ENamedThreads::AnyThread); } else { PhysicsSceneCompletion = FinishPrerequisites[0]; // we don't need a join } } // Record the sync tick time for use with the async tick SyncDeltaSeconds = DeltaSeconds; }
void FPhysScene::StartFrame() { FGraphEventArray FinishPrerequisites; //Update the collision disable table before ticking FlushDeferredCollisionDisableTableQueue(); #if WITH_PHYSX // Flush list of deferred actors to add to the scene FlushDeferredActors(); #endif // Run the sync scene TickPhysScene(PST_Sync, PhysicsSubsceneCompletion[PST_Sync]); { FGraphEventArray MainScenePrerequisites; if (FrameLagAsync() && bAsyncSceneEnabled) { if (FrameLaggedPhysicsSubsceneCompletion[PST_Async].GetReference() && !FrameLaggedPhysicsSubsceneCompletion[PST_Async]->IsComplete()) { MainScenePrerequisites.Add(FrameLaggedPhysicsSubsceneCompletion[PST_Async]); FinishPrerequisites.Add(FrameLaggedPhysicsSubsceneCompletion[PST_Async]); } } if (PhysicsSubsceneCompletion[PST_Sync].GetReference()) { MainScenePrerequisites.Add(PhysicsSubsceneCompletion[PST_Sync]); DECLARE_CYCLE_STAT(TEXT("FDelegateGraphTask.ProcessPhysScene_Sync"), STAT_FDelegateGraphTask_ProcessPhysScene_Sync, STATGROUP_TaskGraphTasks); new (FinishPrerequisites)FGraphEventRef( FDelegateGraphTask::CreateAndDispatchWhenReady( FDelegateGraphTask::FDelegate::CreateRaw(this, &FPhysScene::SceneCompletionTask, PST_Sync), GET_STATID(STAT_FDelegateGraphTask_ProcessPhysScene_Sync), &MainScenePrerequisites, ENamedThreads::GameThread, ENamedThreads::GameThread ) ); } } if (!FrameLagAsync() && bAsyncSceneEnabled) { TickPhysScene(PST_Async, PhysicsSubsceneCompletion[PST_Async]); if (PhysicsSubsceneCompletion[PST_Async].GetReference()) { DECLARE_CYCLE_STAT(TEXT("FDelegateGraphTask.ProcessPhysScene_Async"), STAT_FDelegateGraphTask_ProcessPhysScene_Async, STATGROUP_TaskGraphTasks); new (FinishPrerequisites)FGraphEventRef( FDelegateGraphTask::CreateAndDispatchWhenReady( FDelegateGraphTask::FDelegate::CreateRaw(this, &FPhysScene::SceneCompletionTask, PST_Async), GET_STATID(STAT_FDelegateGraphTask_ProcessPhysScene_Async), PhysicsSubsceneCompletion[PST_Async], ENamedThreads::GameThread, ENamedThreads::GameThread ) ); } } check(!PhysicsSceneCompletion.GetReference()); // this should have been cleared if (FinishPrerequisites.Num()) { if (FinishPrerequisites.Num() > 1) // we don't need to create a new task if we only have one prerequisite { DECLARE_CYCLE_STAT(TEXT("FNullGraphTask.ProcessPhysScene_Join"), STAT_FNullGraphTask_ProcessPhysScene_Join, STATGROUP_TaskGraphTasks); PhysicsSceneCompletion = TGraphTask<FNullGraphTask>::CreateTask(&FinishPrerequisites, ENamedThreads::GameThread).ConstructAndDispatchWhenReady( GET_STATID(STAT_FNullGraphTask_ProcessPhysScene_Join), PhysSingleThreadedMode() ? ENamedThreads::GameThread : ENamedThreads::AnyThread); } else { PhysicsSceneCompletion = FinishPrerequisites[0]; // we don't need a join } } // Record the sync tick time for use with the async tick SyncDeltaSeconds = DeltaSeconds; }