2020-08-11 01:36:57 -04:00
// Copyright Epic Games, Inc. All Rights Reserved.
# include "Chaos/ChaosScene.h"
# include "Async/AsyncWork.h"
# include "Async/ParallelFor.h"
# include "Misc/CoreDelegates.h"
# include "Misc/ScopeLock.h"
# include "ProfilingDebugging/CsvProfiler.h"
# include "ChaosSolversModule.h"
# include "ChaosLog.h"
# include "ChaosStats.h"
2023-04-17 18:20:36 -04:00
# if WITH_CHAOS_VISUAL_DEBUGGER
# include "ChaosVDRuntimeModule.h"
# endif
2020-08-11 01:36:57 -04:00
# include "Field/FieldSystem.h"
# include "PhysicsProxy/PerSolverFieldSystem.h"
# include "PhysicsProxy/GeometryCollectionPhysicsProxy.h"
# include "PhysicsProxy/SingleParticlePhysicsProxy.h"
# include "PhysicsProxy/SkeletalMeshPhysicsProxy.h"
# include "PhysicsProxy/StaticMeshPhysicsProxy.h"
# include "Chaos/UniformGrid.h"
# include "Chaos/BoundingVolume.h"
# include "Chaos/Framework/DebugSubstep.h"
# include "Chaos/PerParticleGravity.h"
# include "PBDRigidActiveParticlesBuffer.h"
# include "Chaos/GeometryParticlesfwd.h"
# include "Chaos/Box.h"
2022-09-09 00:53:22 -04:00
# include "EventsData.h"
# include "EventManager.h"
# include "RewindData.h"
2020-09-24 00:43:27 -04:00
# include "PhysicsSettingsCore.h"
# include "Chaos/PhysicsSolverBaseImpl.h"
2020-08-11 01:36:57 -04:00
2023-04-17 18:20:36 -04:00
# include "ChaosVisualDebugger/ChaosVisualDebuggerTrace.h"
2020-08-11 01:36:57 -04:00
DECLARE_CYCLE_STAT ( TEXT ( " Update Kinematics On Deferred SkelMeshes " ) , STAT_UpdateKinematicsOnDeferredSkelMeshesChaos , STATGROUP_Physics ) ;
CSV_DEFINE_CATEGORY ( ChaosPhysics , true ) ;
2022-01-27 17:02:09 -05:00
CSV_DEFINE_CATEGORY ( AABBTreeExpensiveStats , false ) ;
2020-08-11 01:36:57 -04:00
2021-03-15 19:26:59 -04:00
// Stat Counters
DECLARE_DWORD_ACCUMULATOR_STAT ( TEXT ( " NumDirtyAABBTreeElements " ) , STAT_ChaosCounter_NumDirtyAABBTreeElements , STATGROUP_ChaosCounters ) ;
2021-06-23 06:01:47 -04:00
DECLARE_DWORD_ACCUMULATOR_STAT ( TEXT ( " NumDirtyGridOverflowElements " ) , STAT_ChaosCounter_NumDirtyGridOverflowElements , STATGROUP_ChaosCounters ) ;
DECLARE_DWORD_ACCUMULATOR_STAT ( TEXT ( " NumDirtyElementsTooLargeForGrid " ) , STAT_ChaosCounter_NumDirtyElementsTooLargeForGrid , STATGROUP_ChaosCounters ) ;
DECLARE_DWORD_ACCUMULATOR_STAT ( TEXT ( " NumDirtyNonEmptyCellsInGrid " ) , STAT_ChaosCounter_NumDirtyNonEmptyCellsInGrid , STATGROUP_ChaosCounters ) ;
2021-03-15 19:26:59 -04:00
2020-08-11 01:36:57 -04:00
TAutoConsoleVariable < int32 > CVar_ChaosSimulationEnable ( TEXT ( " P.Chaos.Simulation.Enable " ) , 1 , TEXT ( " Enable / disable chaos simulation. If disabled, physics will not tick. " ) ) ;
2020-09-24 00:43:27 -04:00
TAutoConsoleVariable < int32 > CVar_ApplyProjectSettings ( TEXT ( " p.Chaos.Simulation.ApplySolverProjectSettings " ) , 1 , TEXT ( " Whether to apply the solver project settings on spawning a solver " ) ) ;
2020-08-11 01:36:57 -04:00
FChaosScene : : FChaosScene (
UObject * OwnerPtr
2021-06-14 12:07:24 -04:00
, Chaos : : FReal InAsyncDt
2021-08-03 11:56:47 -04:00
# if CHAOS_DEBUG_NAME
2020-08-11 01:36:57 -04:00
, const FName & DebugName
# endif
)
2020-09-24 00:43:27 -04:00
: SolverAccelerationStructure ( nullptr )
, ChaosModule ( nullptr )
2020-08-11 01:36:57 -04:00
, SceneSolver ( nullptr )
, Owner ( OwnerPtr )
{
2021-12-13 13:05:20 -05:00
LLM_SCOPE ( ELLMTag : : ChaosScene ) ;
2020-08-11 01:36:57 -04:00
ChaosModule = FChaosSolversModule : : GetModule ( ) ;
check ( ChaosModule ) ;
const bool bForceSingleThread = ! ( FApp : : ShouldUseThreadingForPerformance ( ) | | FForkProcessHelper : : SupportsMultithreadingPostFork ( ) ) ;
Chaos : : EThreadingMode ThreadingMode = bForceSingleThread ? Chaos : : EThreadingMode : : SingleThread : Chaos : : EThreadingMode : : TaskGraph ;
2021-06-14 12:07:24 -04:00
SceneSolver = ChaosModule - > CreateSolver ( OwnerPtr , InAsyncDt , ThreadingMode
2021-08-03 11:56:47 -04:00
# if CHAOS_DEBUG_NAME
2020-08-11 01:36:57 -04:00
, DebugName
# endif
) ;
check ( SceneSolver ) ;
2023-04-17 18:20:36 -04:00
# if WITH_CHAOS_VISUAL_DEBUGGER
SceneSolver - > GetChaosVDContextData ( ) . OwnerID = GetChaosVDContextData ( ) . Id ;
SceneSolver - > GetChaosVDContextData ( ) . Id = FChaosVDRuntimeModule : : Get ( ) . GenerateUniqueID ( ) ;
# endif
2020-08-11 01:36:57 -04:00
SceneSolver - > PhysSceneHack = this ;
2020-11-24 18:42:39 -04:00
SimCallback = SceneSolver - > CreateAndRegisterSimCallbackObject_External < FChaosSceneSimCallback > ( ) ;
2020-08-11 01:36:57 -04:00
2023-02-02 18:47:53 -05:00
// Apply project settings to the solver
2020-09-24 00:43:27 -04:00
if ( CVar_ApplyProjectSettings . GetValueOnAnyThread ( ) ! = 0 )
{
UPhysicsSettingsCore * Settings = UPhysicsSettingsCore : : Get ( ) ;
2023-02-02 18:47:53 -05:00
SceneSolver - > RegisterSimOneShotCallback ( [ InSolver = SceneSolver , SolverConfigCopy = Settings - > SolverOptions , bIsDeterministic = Settings - > bEnableEnhancedDeterminism ] ( )
2020-09-24 00:43:27 -04:00
{
InSolver - > ApplyConfig ( SolverConfigCopy ) ;
2023-02-02 18:47:53 -05:00
InSolver - > SetIsDeterministic ( bIsDeterministic ) ;
2020-09-24 00:43:27 -04:00
} ) ;
}
2021-06-07 20:09:45 -04:00
// Make sure we have initialized structure on game thread, evolution has already initialized structure, just need to copy.
CopySolverAccelerationStructure ( ) ;
2020-08-11 01:36:57 -04:00
}
FChaosScene : : ~ FChaosScene ( )
{
if ( ensure ( SceneSolver ) )
{
Chaos : : FEventManager * EventManager = SceneSolver - > GetEventManager ( ) ;
EventManager - > UnregisterHandler ( Chaos : : EEventType : : Collision , this ) ;
2020-11-24 18:42:39 -04:00
SceneSolver - > UnregisterAndFreeSimCallbackObject_External ( SimCallback ) ;
2020-08-11 01:36:57 -04:00
}
if ( ensure ( ChaosModule ) )
{
// Destroy our solver
ChaosModule - > DestroySolver ( GetSolver ( ) ) ;
}
2020-11-24 18:42:39 -04:00
SimCallback = nullptr ;
2020-08-11 01:36:57 -04:00
ChaosModule = nullptr ;
SceneSolver = nullptr ;
}
# if WITH_ENGINE
void FChaosScene : : AddReferencedObjects ( FReferenceCollector & Collector )
{
# if WITH_EDITOR
2023-05-16 10:52:49 -04:00
for ( auto & Obj : PieModifiedObjects )
2020-08-11 01:36:57 -04:00
{
Collector . AddReferencedObject ( Obj ) ;
}
# endif
}
# endif
# if WITH_EDITOR
void FChaosScene : : AddPieModifiedObject ( UObject * InObj )
{
if ( GIsPlayInEditorWorld )
{
2023-05-16 10:52:49 -04:00
PieModifiedObjects . AddUnique ( ObjectPtrWrap ( InObj ) ) ;
2020-08-11 01:36:57 -04:00
}
}
# endif
2021-02-18 18:13:28 -04:00
const Chaos : : ISpatialAcceleration < Chaos : : FAccelerationStructureHandle , Chaos : : FReal , 3 > * FChaosScene : : GetSpacialAcceleration ( ) const
2020-08-11 01:36:57 -04:00
{
2020-09-24 00:43:27 -04:00
return SolverAccelerationStructure ;
2020-08-11 01:36:57 -04:00
}
2021-02-18 18:13:28 -04:00
Chaos : : ISpatialAcceleration < Chaos : : FAccelerationStructureHandle , Chaos : : FReal , 3 > * FChaosScene : : GetSpacialAcceleration ( )
2020-08-11 01:36:57 -04:00
{
2020-09-24 00:43:27 -04:00
return SolverAccelerationStructure ;
2020-08-11 01:36:57 -04:00
}
void FChaosScene : : CopySolverAccelerationStructure ( )
{
2020-10-29 13:38:15 -04:00
using namespace Chaos ;
2020-09-01 14:07:48 -04:00
if ( SceneSolver )
2020-08-11 01:36:57 -04:00
{
2020-10-29 13:38:15 -04:00
FPhysicsSceneGuardScopedWrite ScopedWrite ( SceneSolver - > GetExternalDataLock_External ( ) ) ;
2020-09-01 14:07:48 -04:00
SceneSolver - > UpdateExternalAccelerationStructure_External ( SolverAccelerationStructure ) ;
2020-08-11 01:36:57 -04:00
}
}
2020-12-11 14:21:20 -04:00
void FChaosScene : : Flush ( )
2020-08-11 01:36:57 -04:00
{
check ( IsInGameThread ( ) ) ;
Chaos : : FPBDRigidsSolver * Solver = GetSolver ( ) ;
if ( Solver )
{
//Make sure any dirty proxy data is pushed
Solver - > AdvanceAndDispatch_External ( 0 ) ; //force commands through
Solver - > WaitOnPendingTasks_External ( ) ;
// Populate the spacial acceleration
Chaos : : FPBDRigidsSolver : : FPBDRigidsEvolution * Evolution = Solver - > GetEvolution ( ) ;
if ( Evolution )
{
Evolution - > FlushSpatialAcceleration ( ) ;
}
}
CopySolverAccelerationStructure ( ) ;
}
2021-09-06 12:23:53 -04:00
void FChaosScene : : RemoveActorFromAccelerationStructure ( FPhysicsActorHandle Actor )
2020-08-11 01:36:57 -04:00
{
2020-10-29 13:38:15 -04:00
using namespace Chaos ;
2021-02-03 14:57:28 -04:00
RemoveActorFromAccelerationStructureImp ( Actor - > GetParticle_LowLevel ( ) ) ;
2020-08-11 01:36:57 -04:00
}
2021-05-05 15:07:25 -04:00
void FChaosScene : : RemoveActorFromAccelerationStructureImp ( Chaos : : FGeometryParticle * Particle )
2021-02-03 14:57:28 -04:00
{
using namespace Chaos ;
if ( GetSpacialAcceleration ( ) & & Particle - > UniqueIdx ( ) . IsValid ( ) )
{
FPhysicsSceneGuardScopedWrite ScopedWrite ( SceneSolver - > GetExternalDataLock_External ( ) ) ;
2021-02-18 18:13:28 -04:00
Chaos : : FAccelerationStructureHandle AccelerationHandle ( Particle ) ;
2021-02-03 14:57:28 -04:00
GetSpacialAcceleration ( ) - > RemoveElementFrom ( AccelerationHandle , Particle - > SpatialIdx ( ) ) ;
}
}
2020-08-11 01:36:57 -04:00
void FChaosScene : : UpdateActorInAccelerationStructure ( const FPhysicsActorHandle & Actor )
{
using namespace Chaos ;
if ( GetSpacialAcceleration ( ) )
{
2020-10-29 13:38:15 -04:00
FPhysicsSceneGuardScopedWrite ScopedWrite ( SceneSolver - > GetExternalDataLock_External ( ) ) ;
2020-08-11 01:36:57 -04:00
auto SpatialAcceleration = GetSpacialAcceleration ( ) ;
2021-02-03 14:57:28 -04:00
const Chaos : : FRigidBodyHandle_External & Body_External = Actor - > GetGameThreadAPI ( ) ;
2020-08-11 01:36:57 -04:00
if ( SpatialAcceleration )
{
2021-02-18 18:13:28 -04:00
FAABB3 WorldBounds ;
2021-02-03 14:57:28 -04:00
const bool bHasBounds = Body_External . Geometry ( ) - > HasBoundingBox ( ) ;
2020-08-11 01:36:57 -04:00
if ( bHasBounds )
{
2021-02-18 18:13:28 -04:00
WorldBounds = Body_External . Geometry ( ) - > BoundingBox ( ) . TransformedAABB ( FRigidTransform3 ( Body_External . X ( ) , Body_External . R ( ) ) ) ;
2020-08-11 01:36:57 -04:00
}
2021-02-18 18:13:28 -04:00
Chaos : : FAccelerationStructureHandle AccelerationHandle ( Actor - > GetParticle_LowLevel ( ) ) ;
2021-02-03 14:57:28 -04:00
SpatialAcceleration - > UpdateElementIn ( AccelerationHandle , WorldBounds , bHasBounds , Body_External . SpatialIdx ( ) ) ;
2020-08-11 01:36:57 -04:00
}
2023-04-28 15:58:10 -04:00
GetSolver ( ) - > UpdateParticleInAccelerationStructure_External ( Actor - > GetParticle_LowLevel ( ) , EPendingSpatialDataOperation : : Update ) ;
2020-08-11 01:36:57 -04:00
}
}
void FChaosScene : : UpdateActorsInAccelerationStructure ( const TArrayView < FPhysicsActorHandle > & Actors )
{
using namespace Chaos ;
if ( GetSpacialAcceleration ( ) )
{
2020-10-29 13:38:15 -04:00
FPhysicsSceneGuardScopedWrite ScopedWrite ( SceneSolver - > GetExternalDataLock_External ( ) ) ;
2020-08-11 01:36:57 -04:00
auto SpatialAcceleration = GetSpacialAcceleration ( ) ;
if ( SpatialAcceleration )
{
int32 NumActors = Actors . Num ( ) ;
for ( int32 ActorIndex = 0 ; ActorIndex < NumActors ; + + ActorIndex )
{
const FPhysicsActorHandle & Actor = Actors [ ActorIndex ] ;
2021-02-03 14:57:28 -04:00
if ( Actor )
2020-08-11 01:36:57 -04:00
{
2021-02-10 17:41:44 -04:00
const Chaos : : FRigidBodyHandle_External & Body_External = Actor - > GetGameThreadAPI ( ) ;
2020-08-11 01:36:57 -04:00
// @todo(chaos): dedupe code in UpdateActorInAccelerationStructure
2021-02-18 18:13:28 -04:00
FAABB3 WorldBounds ;
2021-02-03 14:57:28 -04:00
const bool bHasBounds = Body_External . Geometry ( ) - > HasBoundingBox ( ) ;
2020-08-11 01:36:57 -04:00
if ( bHasBounds )
{
2021-02-18 18:13:28 -04:00
WorldBounds = Body_External . Geometry ( ) - > BoundingBox ( ) . TransformedAABB ( FRigidTransform3 ( Body_External . X ( ) , Body_External . R ( ) ) ) ;
2020-08-11 01:36:57 -04:00
}
2021-02-18 18:13:28 -04:00
Chaos : : FAccelerationStructureHandle AccelerationHandle ( Actor - > GetParticle_LowLevel ( ) ) ;
2021-02-03 14:57:28 -04:00
SpatialAcceleration - > UpdateElementIn ( AccelerationHandle , WorldBounds , bHasBounds , Body_External . SpatialIdx ( ) ) ;
2020-08-11 01:36:57 -04:00
}
}
}
2020-09-01 14:07:48 -04:00
for ( int32 ActorIndex = 0 ; ActorIndex < Actors . Num ( ) ; + + ActorIndex )
{
const FPhysicsActorHandle & Actor = Actors [ ActorIndex ] ;
2021-02-03 14:57:28 -04:00
if ( Actor )
2020-09-01 14:07:48 -04:00
{
2023-04-28 15:58:10 -04:00
GetSolver ( ) - > UpdateParticleInAccelerationStructure_External ( Actor - > GetParticle_LowLevel ( ) , EPendingSpatialDataOperation : : Update ) ;
2020-09-01 14:07:48 -04:00
}
}
2020-08-11 01:36:57 -04:00
}
}
void FChaosScene : : AddActorsToScene_AssumesLocked ( TArray < FPhysicsActorHandle > & InHandles , const bool bImmediate )
{
2020-12-17 11:31:47 -04:00
TRACE_CPUPROFILER_EVENT_SCOPE ( FChaosScene : : AddActorsToScene_AssumesLocked )
2020-08-11 01:36:57 -04:00
Chaos : : FPhysicsSolver * Solver = GetSolver ( ) ;
2021-02-18 18:13:28 -04:00
Chaos : : ISpatialAcceleration < Chaos : : FAccelerationStructureHandle , Chaos : : FReal , 3 > * SpatialAcceleration = GetSpacialAcceleration ( ) ;
2020-08-11 01:36:57 -04:00
for ( FPhysicsActorHandle & Handle : InHandles )
{
FChaosEngineInterface : : AddActorToSolver ( Handle , Solver ) ;
// Optionally add this to the game-thread acceleration structure immediately
if ( bImmediate & & SpatialAcceleration )
{
2021-02-03 14:57:28 -04:00
const Chaos : : FRigidBodyHandle_External & Body_External = Handle - > GetGameThreadAPI ( ) ;
2020-08-11 01:36:57 -04:00
// Get the bounding box for the particle if it has one
2021-02-03 14:57:28 -04:00
bool bHasBounds = Body_External . Geometry ( ) - > HasBoundingBox ( ) ;
2021-02-18 18:13:28 -04:00
Chaos : : FAABB3 WorldBounds ;
2020-08-11 01:36:57 -04:00
if ( bHasBounds )
{
2021-02-18 18:13:28 -04:00
const Chaos : : FAABB3 LocalBounds = Body_External . Geometry ( ) - > BoundingBox ( ) ;
WorldBounds = LocalBounds . TransformedAABB ( Chaos : : FRigidTransform3 ( Body_External . X ( ) , Body_External . R ( ) ) ) ;
2020-08-11 01:36:57 -04:00
}
// Insert the particle
2021-02-18 18:13:28 -04:00
Chaos : : FAccelerationStructureHandle AccelerationHandle ( Handle - > GetParticle_LowLevel ( ) ) ;
2021-02-03 14:57:28 -04:00
SpatialAcceleration - > UpdateElementIn ( AccelerationHandle , WorldBounds , bHasBounds , Body_External . SpatialIdx ( ) ) ;
2020-08-11 01:36:57 -04:00
}
}
}
2020-12-11 14:21:20 -04:00
void FChaosSceneSimCallback : : OnPreSimulate_Internal ( )
2020-11-24 18:42:39 -04:00
{
2020-12-11 14:21:20 -04:00
if ( const FChaosSceneCallbackInput * Input = GetConsumerInput_Internal ( ) )
2020-11-24 18:42:39 -04:00
{
2023-01-27 19:27:17 -05:00
// the "main" gravity is index 0
static_cast < Chaos : : FPBDRigidsSolver * > ( GetSolver ( ) ) - > GetEvolution ( ) - > GetGravityForces ( ) . SetAcceleration ( Input - > Gravity , 0 ) ;
2020-11-24 18:42:39 -04:00
}
}
2023-05-12 07:41:52 -04:00
FName FChaosSceneSimCallback : : GetFNameForStatId ( ) const
{
const static FLazyName StaticName ( " FChaosSceneSimCallback " ) ;
return StaticName ;
}
2021-02-03 14:57:28 -04:00
void FChaosScene : : SetGravity ( const Chaos : : FVec3 & Acceleration )
2020-11-24 18:42:39 -04:00
{
SimCallback - > GetProducerInputData_External ( ) - > Gravity = Acceleration ;
}
2021-07-15 04:08:35 -04:00
void FChaosScene : : SetUpForFrame ( const FVector * NewGrav , float InDeltaSeconds /*= 0.0f*/ , float InMinPhysicsDeltaTime /*= 0.0f*/ , float InMaxPhysicsDeltaTime /*= 0.0f*/ , float InMaxSubstepDeltaTime /*= 0.0f*/ , int32 InMaxSubsteps , bool bSubstepping )
2020-08-11 01:36:57 -04:00
{
using namespace Chaos ;
SetGravity ( * NewGrav ) ;
2021-04-12 18:47:39 -04:00
2021-06-22 00:27:54 -04:00
InDeltaSeconds * = MNetworkDeltaTimeScale ;
2021-04-12 18:47:39 -04:00
if ( bSubstepping )
{
MDeltaTime = FMath : : Min ( InDeltaSeconds , InMaxSubsteps * InMaxSubstepDeltaTime ) ;
}
else
{
MDeltaTime = InMaxPhysicsDeltaTime > 0.f ? FMath : : Min ( InDeltaSeconds , InMaxPhysicsDeltaTime ) : InDeltaSeconds ;
}
2020-08-11 01:36:57 -04:00
if ( FPhysicsSolver * Solver = GetSolver ( ) )
{
if ( bSubstepping )
{
2021-04-12 18:47:39 -04:00
Solver - > SetMaxDeltaTime_External ( InMaxSubstepDeltaTime ) ;
Solver - > SetMaxSubSteps_External ( InMaxSubsteps ) ;
}
else
2020-08-11 01:36:57 -04:00
{
2021-04-12 18:47:39 -04:00
Solver - > SetMaxDeltaTime_External ( InMaxPhysicsDeltaTime ) ;
Solver - > SetMaxSubSteps_External ( 1 ) ;
2020-08-11 01:36:57 -04:00
}
2021-07-15 04:08:35 -04:00
Solver - > SetMinDeltaTime_External ( InMinPhysicsDeltaTime ) ;
2020-08-11 01:36:57 -04:00
}
}
void FChaosScene : : StartFrame ( )
{
using namespace Chaos ;
SCOPE_CYCLE_COUNTER ( STAT_Scene_StartFrame ) ;
if ( CVar_ChaosSimulationEnable . GetValueOnGameThread ( ) = = 0 )
{
return ;
}
const float UseDeltaTime = OnStartFrame ( MDeltaTime ) ; ;
TArray < FPhysicsSolverBase * > SolverList ;
ChaosModule - > GetSolversMutable ( Owner , SolverList ) ;
if ( FPhysicsSolver * Solver = GetSolver ( ) )
{
// Make sure our solver is in the list
SolverList . AddUnique ( Solver ) ;
}
for ( FPhysicsSolverBase * Solver : SolverList )
{
2020-09-24 00:43:27 -04:00
CompletionEvents . Add ( Solver - > AdvanceAndDispatch_External ( UseDeltaTime ) ) ;
2020-08-11 01:36:57 -04:00
}
2020-09-24 00:43:27 -04:00
}
2020-12-11 14:21:20 -04:00
void FChaosScene : : OnSyncBodies ( Chaos : : FPhysicsSolverBase * Solver )
2020-09-24 00:43:27 -04:00
{
2023-02-27 16:43:09 -05:00
struct FDispatcher { } Dispatcher ;
Solver - > PullPhysicsStateForEachDirtyProxy_External ( Dispatcher ) ;
2020-09-24 00:43:27 -04:00
}
bool FChaosScene : : AreAnyTasksPending ( ) const
{
const Chaos : : FPBDRigidsSolver * Solver = GetSolver ( ) ;
if ( Solver & & Solver - > AreAnyTasksPending ( ) )
2020-09-01 14:07:48 -04:00
{
2020-09-24 00:43:27 -04:00
return true ;
2020-08-11 01:36:57 -04:00
}
2020-09-01 14:07:48 -04:00
2020-09-24 00:43:27 -04:00
return false ;
2020-08-11 01:36:57 -04:00
}
2020-09-24 00:43:27 -04:00
void FChaosScene : : BeginDestroy ( )
2020-09-01 14:07:48 -04:00
{
2020-09-24 00:43:27 -04:00
Chaos : : FPBDRigidsSolver * Solver = GetSolver ( ) ;
if ( Solver )
2020-09-01 14:07:48 -04:00
{
2020-09-24 00:43:27 -04:00
Solver - > BeginDestroy ( ) ;
2020-09-01 14:07:48 -04:00
}
2020-09-24 00:43:27 -04:00
}
2020-09-01 14:07:48 -04:00
2020-09-24 00:43:27 -04:00
bool FChaosScene : : IsCompletionEventComplete ( ) const
{
for ( FGraphEventRef Event : CompletionEvents )
2020-09-01 14:07:48 -04:00
{
2020-09-24 00:43:27 -04:00
if ( Event & & ! Event - > IsComplete ( ) )
2020-09-01 14:07:48 -04:00
{
2020-09-24 00:43:27 -04:00
return false ;
2020-09-01 14:07:48 -04:00
}
}
2020-09-24 00:43:27 -04:00
return true ;
2020-08-11 01:36:57 -04:00
}
template < typename TSolver >
void FChaosScene : : SyncBodies ( TSolver * Solver )
{
DECLARE_SCOPE_CYCLE_COUNTER ( TEXT ( " SyncBodies " ) , STAT_SyncBodies , STATGROUP_Physics ) ;
2021-06-22 00:27:54 -04:00
CSV_SCOPED_TIMING_STAT_EXCLUSIVE ( SyncBodies ) ;
2020-12-11 14:21:20 -04:00
OnSyncBodies ( Solver ) ;
2020-08-11 01:36:57 -04:00
}
2021-06-23 06:01:47 -04:00
// Accumulate all the AABBTree stats
2021-11-24 00:16:43 -05:00
void GetAABBTreeStats ( Chaos : : ISpatialAccelerationCollection < Chaos : : FAccelerationStructureHandle , Chaos : : FReal , 3 > & Collection , Chaos : : AABBTreeStatistics & OutAABBTreeStatistics , Chaos : : AABBTreeExpensiveStatistics & OutAABBTreeExpensiveStatistics )
2020-08-11 01:36:57 -04:00
{
2022-01-27 17:02:09 -05:00
CSV_SCOPED_TIMING_STAT ( AABBTreeExpensiveStats , GetAABBTreeStats ) ;
2020-08-11 01:36:57 -04:00
using namespace Chaos ;
2021-06-23 06:01:47 -04:00
OutAABBTreeStatistics . Reset ( ) ;
2020-08-11 01:36:57 -04:00
TArray < FSpatialAccelerationIdx > SpatialIndices = Collection . GetAllSpatialIndices ( ) ;
2021-06-23 06:01:47 -04:00
for ( const FSpatialAccelerationIdx SpatialIndex : SpatialIndices )
2020-08-11 01:36:57 -04:00
{
auto SubStructure = Collection . GetSubstructure ( SpatialIndex ) ;
2021-06-23 06:01:47 -04:00
if ( const auto AABBTree = SubStructure - > template As < TAABBTree < FAccelerationStructureHandle , TAABBTreeLeafArray < FAccelerationStructureHandle > > > ( ) )
2020-08-11 01:36:57 -04:00
{
2021-11-24 00:16:43 -05:00
OutAABBTreeStatistics . MergeStatistics ( AABBTree - > GetAABBTreeStatistics ( ) ) ;
# if CSV_PROFILER
if ( FCsvProfiler : : Get ( ) - > IsCapturing ( ) & & FCsvProfiler : : Get ( ) - > IsCategoryEnabled ( CSV_CATEGORY_INDEX ( AABBTreeExpensiveStats ) ) )
{
OutAABBTreeExpensiveStatistics . MergeStatistics ( AABBTree - > GetAABBTreeExpensiveStatistics ( ) ) ;
}
# endif
2021-06-23 06:01:47 -04:00
}
else if ( const auto AABBTreeBV = SubStructure - > template As < TAABBTree < FAccelerationStructureHandle , TBoundingVolume < FAccelerationStructureHandle > > > ( ) )
2020-08-11 01:36:57 -04:00
{
2021-11-24 00:16:43 -05:00
OutAABBTreeStatistics . MergeStatistics ( AABBTreeBV - > GetAABBTreeStatistics ( ) ) ;
2020-08-11 01:36:57 -04:00
}
}
}
void FChaosScene : : EndFrame ( )
{
using namespace Chaos ;
2021-02-18 18:13:28 -04:00
using SpatialAccelerationCollection = ISpatialAccelerationCollection < FAccelerationStructureHandle , FReal , 3 > ;
2020-08-11 01:36:57 -04:00
SCOPE_CYCLE_COUNTER ( STAT_Scene_EndFrame ) ;
if ( CVar_ChaosSimulationEnable . GetValueOnGameThread ( ) = = 0 | | GetSolver ( ) = = nullptr )
{
return ;
}
2022-01-27 17:02:09 -05:00
# if !UE_BUILD_SHIPPING
{
Chaos : : AABBTreeStatistics TreeStats ;
Chaos : : AABBTreeExpensiveStatistics TreeExpensiveStats ;
GetAABBTreeStats ( GetSpacialAcceleration ( ) - > AsChecked < SpatialAccelerationCollection > ( ) , TreeStats , TreeExpensiveStats ) ;
2021-06-23 06:01:47 -04:00
2022-01-27 17:02:09 -05:00
CSV_CUSTOM_STAT ( ChaosPhysics , AABBTreeDirtyElementCount , TreeStats . StatNumDirtyElements , ECsvCustomStatOp : : Set ) ;
SET_DWORD_STAT ( STAT_ChaosCounter_NumDirtyAABBTreeElements , TreeStats . StatNumDirtyElements ) ;
2021-06-23 06:01:47 -04:00
2022-01-27 17:02:09 -05:00
CSV_CUSTOM_STAT ( ChaosPhysics , AABBTreeDirtyGridOverflowCount , TreeStats . StatNumGridOverflowElements , ECsvCustomStatOp : : Set ) ;
SET_DWORD_STAT ( STAT_ChaosCounter_NumDirtyGridOverflowElements , TreeStats . StatNumGridOverflowElements ) ;
2021-06-23 06:01:47 -04:00
2022-01-27 17:02:09 -05:00
CSV_CUSTOM_STAT ( ChaosPhysics , AABBTreeDirtyElementTooLargeCount , TreeStats . StatNumElementsTooLargeForGrid , ECsvCustomStatOp : : Set ) ;
SET_DWORD_STAT ( STAT_ChaosCounter_NumDirtyElementsTooLargeForGrid , TreeStats . StatNumElementsTooLargeForGrid ) ;
2021-06-23 06:01:47 -04:00
2022-01-27 17:02:09 -05:00
CSV_CUSTOM_STAT ( ChaosPhysics , AABBTreeDirtyElementNonEmptyCellCount , TreeStats . StatNumNonEmptyCellsInGrid , ECsvCustomStatOp : : Set ) ;
SET_DWORD_STAT ( STAT_ChaosCounter_NumDirtyNonEmptyCellsInGrid , TreeStats . StatNumNonEmptyCellsInGrid ) ;
2020-08-11 01:36:57 -04:00
2021-11-24 00:16:43 -05:00
# if CSV_PROFILER
2022-01-27 17:02:09 -05:00
if ( FCsvProfiler : : Get ( ) - > IsCapturing ( ) & & FCsvProfiler : : Get ( ) - > IsCategoryEnabled ( CSV_CATEGORY_INDEX ( AABBTreeExpensiveStats ) ) )
{
CSV_CUSTOM_STAT ( AABBTreeExpensiveStats , AABBTreeMaxNumLeaves , TreeExpensiveStats . StatMaxNumLeaves , ECsvCustomStatOp : : Set ) ;
CSV_CUSTOM_STAT ( AABBTreeExpensiveStats , AABBTreeMaxDirtyElements , TreeExpensiveStats . StatMaxDirtyElements , ECsvCustomStatOp : : Set ) ;
CSV_CUSTOM_STAT ( AABBTreeExpensiveStats , AABBTreeMaxTreeDepth , TreeExpensiveStats . StatMaxTreeDepth , ECsvCustomStatOp : : Set ) ;
CSV_CUSTOM_STAT ( AABBTreeExpensiveStats , AABBTreeMaxLeafSize , TreeExpensiveStats . StatMaxLeafSize , ECsvCustomStatOp : : Set ) ;
CSV_CUSTOM_STAT ( AABBTreeExpensiveStats , AABBTreeGlobalPayloadsSize , TreeExpensiveStats . StatGlobalPayloadsSize , ECsvCustomStatOp : : Set ) ;
}
# endif // CSV_PROFILER
2021-11-24 00:16:43 -05:00
}
2022-01-27 17:02:09 -05:00
# endif // UE_BUILD_SHIPPING
2021-11-24 00:16:43 -05:00
2020-09-24 00:43:27 -04:00
check ( IsCompletionEventComplete ( ) )
2020-09-01 14:07:48 -04:00
//check(PhysicsTickTask->IsComplete());
2020-09-24 00:43:27 -04:00
CompletionEvents . Reset ( ) ;
2020-08-11 01:36:57 -04:00
2020-09-01 14:07:48 -04:00
// Make a list of solvers to process. This is a list of all solvers registered to our world
// And our internal base scene solver.
TArray < FPhysicsSolverBase * > SolverList ;
ChaosModule - > GetSolversMutable ( Owner , SolverList ) ;
{
// Make sure our solver is in the list
SolverList . AddUnique ( GetSolver ( ) ) ;
2020-08-11 01:36:57 -04:00
}
2020-09-01 14:07:48 -04:00
// Flip the buffers over to the game thread and sync
2020-08-11 01:36:57 -04:00
{
2020-09-01 14:07:48 -04:00
SCOPE_CYCLE_COUNTER ( STAT_FlipResults ) ;
2020-08-11 01:36:57 -04:00
2020-09-01 14:07:48 -04:00
//update external SQ structure
//for now just copy the whole thing, stomping any changes that came from GT
CopySolverAccelerationStructure ( ) ;
2020-08-11 01:36:57 -04:00
2020-09-01 14:07:48 -04:00
for ( FPhysicsSolverBase * Solver : SolverList )
2020-08-11 01:36:57 -04:00
{
2023-06-30 21:47:40 -04:00
Solver - > CastHelper ( [ & SolverList , Solver , this ] ( auto & Concrete )
2020-08-11 01:36:57 -04:00
{
2020-09-01 14:07:48 -04:00
SyncBodies ( & Concrete ) ;
Concrete . SyncEvents_GameThread ( ) ;
2023-07-18 16:11:02 -04:00
Solver - > FlipEventManagerBuffer ( ) ;
2020-08-11 01:36:57 -04:00
{
2020-09-01 14:07:48 -04:00
SCOPE_CYCLE_COUNTER ( STAT_SqUpdateMaterials ) ;
2020-10-29 13:38:15 -04:00
Concrete . SyncQueryMaterials_External ( ) ;
2020-09-01 14:07:48 -04:00
}
} ) ;
2020-08-11 01:36:57 -04:00
}
}
2020-09-01 14:07:48 -04:00
OnPhysScenePostTick . Broadcast ( this ) ;
2020-08-11 01:36:57 -04:00
}
void FChaosScene : : WaitPhysScenes ( )
{
2020-09-24 00:43:27 -04:00
if ( ! IsCompletionEventComplete ( ) )
2020-08-11 01:36:57 -04:00
{
QUICK_SCOPE_CYCLE_COUNTER ( STAT_FPhysScene_WaitPhysScenes ) ;
2020-09-24 00:43:27 -04:00
FTaskGraphInterface : : Get ( ) . WaitUntilTasksComplete ( CompletionEvents , ENamedThreads : : GameThread ) ;
2020-08-11 01:36:57 -04:00
}
}
2020-09-24 00:43:27 -04:00
FGraphEventArray FChaosScene : : GetCompletionEvents ( )
2020-08-11 01:36:57 -04:00
{
2020-09-24 00:43:27 -04:00
return CompletionEvents ;
2020-08-11 01:36:57 -04:00
}