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::StartCloth() { FGraphEventArray FinishPrerequisites; if(CVarEnableClothPhysics.GetValueOnGameThread()) { TickPhysScene(PST_Cloth, PhysicsSubsceneCompletion[PST_Cloth]); { if (PhysicsSubsceneCompletion[PST_Cloth].GetReference()) { DECLARE_CYCLE_STAT(TEXT("FDelegateGraphTask.ProcessPhysScene_Cloth"), STAT_FDelegateGraphTask_ProcessPhysScene_Cloth, STATGROUP_TaskGraphTasks); new (FinishPrerequisites)FGraphEventRef( FDelegateGraphTask::CreateAndDispatchWhenReady( FDelegateGraphTask::FDelegate::CreateRaw(this, &FPhysScene::SceneCompletionTask, PST_Cloth), GET_STATID(STAT_FDelegateGraphTask_ProcessPhysScene_Cloth), PhysicsSubsceneCompletion[PST_Cloth], ENamedThreads::GameThread, ENamedThreads::GameThread ) ); } } } //If the async scene is lagged we start it here to make sure any cloth in the async scene is using the results of the previous simulation. 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); FrameLaggedPhysicsSubsceneCompletion[PST_Async] = FDelegateGraphTask::CreateAndDispatchWhenReady( FDelegateGraphTask::FDelegate::CreateRaw(this, &FPhysScene::SceneCompletionTask, PST_Async), GET_STATID(STAT_FDelegateGraphTask_ProcessPhysScene_Async), PhysicsSubsceneCompletion[PST_Async], ENamedThreads::GameThread, ENamedThreads::GameThread ); } } }
void FPhysScene::EndFrame(ULineBatchComponent* InLineBatcher) { PhysicsSceneCompletion = NULL; if (bAsyncSceneEnabled) { SyncComponentsToBodies(PST_Async); } SyncComponentsToBodies(PST_Sync); // Perform any collision notification events DispatchPhysCollisionNotifies(); #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) // Handle debug rendering if (InLineBatcher) { AddDebugLines(PST_Sync, InLineBatcher); if (bAsyncSceneEnabled) { AddDebugLines(PST_Async, InLineBatcher); } } #endif // !(UE_BUILD_SHIPPING || UE_BUILD_TEST) if (FrameLagAsync() && bAsyncSceneEnabled) { TickPhysScene(PST_Async, PhysicsSubsceneCompletion[PST_Async]); if (PhysicsSubsceneCompletion[PST_Async].GetReference()) { FrameLaggedPhysicsSubsceneCompletion[PST_Async] = FDelegateGraphTask::CreateAndDispatchWhenReady(FDelegateGraphTask::FDelegate::CreateRaw(this, &FPhysScene::SceneCompletionTask, PST_Async), TEXT("ProcessPhysScene_Async"), PhysicsSubsceneCompletion[PST_Async], ENamedThreads::GameThread, ENamedThreads::GameThread); } } }
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; }