p.Chaos.AccelerationStructureSplitStaticDynamic
p.Chaos.AccelerationStructureSplitStaticDynamic
#Overview
name: p.Chaos.AccelerationStructureSplitStaticDynamic
This variable is created as a Console Variable (cvar).
- type:
Var
- help:
Set to 1: Sort Dynamic and Static bodies into seperate acceleration structures, any other value will disable the feature
It is referenced in 15
C++ source files.
#Summary
#Usage in the C++ source code
The purpose of p.Chaos.AccelerationStructureSplitStaticDynamic is to control the sorting of dynamic and static bodies into separate acceleration structures within the Chaos physics system in Unreal Engine 5.
This setting variable is primarily used in the Chaos physics subsystem, which is an experimental physics engine in Unreal Engine 5. It affects how the engine organizes and manages physics objects for efficient collision detection and spatial queries.
The value of this variable is set through the Unreal Engine console variable system. It’s defined as an int32 with a default value of 1, which enables the feature. Any other value disables it.
The associated variable AccelerationStructureSplitStaticAndDynamic interacts directly with p.Chaos.AccelerationStructureSplitStaticDynamic. They share the same value and purpose.
Developers should be aware that:
- When set to 1, the engine separates dynamic and static bodies into different acceleration structures, which can potentially improve performance for scenes with many static objects.
- This setting affects how spatial indices are assigned to physics objects, which in turn influences how these objects are organized and queried in the physics simulation.
- Changing this value may have performance implications, especially in scenes with a mix of static and dynamic objects.
Best practices when using this variable include:
- Test performance with both enabled (1) and disabled (0) settings to determine which works best for your specific scene and use case.
- Be consistent in its usage across your project to avoid unexpected behavior.
- Consider the composition of your scene (ratio of static to dynamic objects) when deciding whether to enable this feature.
The associated variable AccelerationStructureSplitStaticAndDynamic serves the same purpose and is used in the same way as p.Chaos.AccelerationStructureSplitStaticDynamic. It’s the internal representation of the console variable within the Chaos physics code. Developers should treat it with the same considerations as mentioned above.
#References in C++ code
#Callsites
This variable is referenced in the following C++ source code:
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/PBDRigidsEvolution.cpp:37
Scope (from outer to inner):
file
namespace Chaos
Source code excerpt:
CHAOS_API int32 AccelerationStructureSplitStaticAndDynamic = 1;
FAutoConsoleVariableRef CVarAccelerationStructureSplitStaticAndDynamic(TEXT("p.Chaos.AccelerationStructureSplitStaticDynamic"), AccelerationStructureSplitStaticAndDynamic, TEXT("Set to 1: Sort Dynamic and Static bodies into seperate acceleration structures, any other value will disable the feature"));
CHAOS_API int32 AccelerationStructureUseDynamicTree = 1;
FAutoConsoleVariableRef CVarAccelerationStructureUseDynamicTree(TEXT("p.Chaos.AccelerationStructureUseDynamicTree"), AccelerationStructureUseDynamicTree, TEXT("Use a dynamic BVH tree structure for dynamic objects"));
CHAOS_API int32 AccelerationStructureUseDirtyTreeInsteadOfGrid = 1;
FAutoConsoleVariableRef CVarAccelerationStructureUseDirtyTreeInsteadOfGrid(TEXT("p.Chaos.AccelerationStructureUseDirtyTreeInsteadOfGrid"), AccelerationStructureUseDirtyTreeInsteadOfGrid, TEXT("Use a dynamic tree structure for dirty elements instead of a 2D grid"));
#Associated Variable and Callsites
This variable is associated with another variable named AccelerationStructureSplitStaticAndDynamic
. They share the same value. See the following C++ source code.
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/ClusterUnionManager.cpp:330
Scope (from outer to inner):
file
namespace Chaos
function FClusterUnionIndex FClusterUnionManager::CreateNewClusterUnion
Source code excerpt:
NewUnion.InternalCluster->SetInternalCluster(true);
if (AccelerationStructureSplitStaticAndDynamic == 1)
{
NewUnion.InternalCluster->SetSpatialIdx(FSpatialAccelerationIdx{ 0, 1 });
}
else
{
NewUnion.InternalCluster->SetSpatialIdx(FSpatialAccelerationIdx{ 0, 0 });
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/PBDRigidsEvolution.cpp:36
Scope (from outer to inner):
file
namespace Chaos
Source code excerpt:
FAutoConsoleVariableRef CVarAccelerationStructureIsolateQueryOnlyObjects(TEXT("p.Chaos.AccelerationStructureIsolateQueryOnlyObjects"), AccelerationStructureIsolateQueryOnlyObjects, TEXT("Set to 1: QueryOnly Objects will not be moved to acceleration structures on the Physics Thread"));
CHAOS_API int32 AccelerationStructureSplitStaticAndDynamic = 1;
FAutoConsoleVariableRef CVarAccelerationStructureSplitStaticAndDynamic(TEXT("p.Chaos.AccelerationStructureSplitStaticDynamic"), AccelerationStructureSplitStaticAndDynamic, TEXT("Set to 1: Sort Dynamic and Static bodies into seperate acceleration structures, any other value will disable the feature"));
CHAOS_API int32 AccelerationStructureUseDynamicTree = 1;
FAutoConsoleVariableRef CVarAccelerationStructureUseDynamicTree(TEXT("p.Chaos.AccelerationStructureUseDynamicTree"), AccelerationStructureUseDynamicTree, TEXT("Use a dynamic BVH tree structure for dynamic objects"));
CHAOS_API int32 AccelerationStructureUseDirtyTreeInsteadOfGrid = 1;
FAutoConsoleVariableRef CVarAccelerationStructureUseDirtyTreeInsteadOfGrid(TEXT("p.Chaos.AccelerationStructureUseDirtyTreeInsteadOfGrid"), AccelerationStructureUseDirtyTreeInsteadOfGrid, TEXT("Use a dynamic tree structure for dirty elements instead of a 2D grid"));
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/PBDRigidsEvolution.cpp:92
Scope (from outer to inner):
file
namespace Chaos
function TUniquePtr<ISpatialAccelerationCollection<FAccelerationStructureHandle, FReal, 3>> CreateEmptyCollection
Source code excerpt:
// Always create this if QueryOnlyObjects are isolated to ensure all consecutive indices are created (within buckets)
if (AccelerationStructureSplitStaticAndDynamic == 1 || AccelerationStructureIsolateQueryOnlyObjects == 1)
{
// Non static bodies
Collection->AddSubstructure(CreateAccelerationPerBucket_Threaded(Empty, BucketIdx, true, IsDynamicTree(FSpatialAccelerationIdx{BucketIdx, ESpatialAccelerationCollectionBucketInnerIdx::Dynamic }), true), BucketIdx, ESpatialAccelerationCollectionBucketInnerIdx::Dynamic);
}
}
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/PBDRigidsEvolution.cpp:103
Scope (from outer to inner):
file
namespace Chaos
function TUniquePtr<ISpatialAccelerationCollection<FAccelerationStructureHandle, FReal, 3>> CreateEmptyCollection
Source code excerpt:
constexpr uint16 BucketIdx = 0;
Collection->AddSubstructure(CreateAccelerationPerBucket_Threaded(Empty, BucketIdx, true, false, false), BucketIdx, ESpatialAccelerationCollectionBucketInnerIdx::DefaultQueryOnly);
if (AccelerationStructureSplitStaticAndDynamic == 1)
{
// Non static bodies
Collection->AddSubstructure(CreateAccelerationPerBucket_Threaded(Empty, BucketIdx, true, IsDynamicTree(FSpatialAccelerationIdx{ BucketIdx, ESpatialAccelerationCollectionBucketInnerIdx::DynamicQueryOnly }), false), BucketIdx, ESpatialAccelerationCollectionBucketInnerIdx::DynamicQueryOnly);
}
}
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/PBDRigidsEvolution.cpp:383
Scope (from outer to inner):
file
namespace Chaos
function void FPBDRigidsEvolutionBase::FChaosAccelerationStructureTask::UpdateStructure
Source code excerpt:
}
if (CreatingNewTimeSlicedStructures && !SubStructure->ShouldRebuild() && AccelerationStructureSplitStaticAndDynamic == 1)
{
ensure(SubStructure->IsAsyncTimeSlicingComplete());
if (AccelerationSUBStructureCopy)
{
AccelerationSUBStructureCopy->PrepareCopyTimeSliced(*SubStructure);
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/PBDRigidsEvolution.cpp:529
Scope (from outer to inner):
file
namespace Chaos
function void FPBDRigidsEvolutionBase::FChaosAccelerationStructureTask::DoTask
Source code excerpt:
//CSV_SCOPED_TIMING_STAT(ChaosPhysicsTimers, AccelerationStructBuildTask);
#endif
if (AccelerationStructureSplitStaticAndDynamic == 1)
{
UpdateStructure(InternalStructure, ExternalStructure);
}
else
{
//Rebuild both structures. TODO: probably faster to time slice the copy instead of doing two time sliced builds (This happens with AccelerationStructureSplitStaticAndDynamic)
UpdateStructure(InternalStructure);
UpdateStructure(ExternalStructure);
}
}
void FPBDRigidsEvolutionBase::ApplyParticlePendingData(const FPendingSpatialData& SpatialData, FAccelerationStructure& AccelerationStructure, bool bUpdateCache, bool bUpdateDynamicTrees)
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/PBDRigidsEvolution.cpp:771
Scope (from outer to inner):
file
namespace Chaos
function void FPBDRigidsEvolutionBase::ComputeIntermediateSpatialAcceleration
Source code excerpt:
FlushAsyncAccelerationQueue();
if (AccelerationStructureSplitStaticAndDynamic == 1)
{
FlushInternalAccelerationQueue();
}
else
{
//other queues are no longer needed since we've flushed all operations and now have a pristine structure
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/Chaos/PBDRigidsEvolution.cpp:800
Scope (from outer to inner):
file
namespace Chaos
function void FPBDRigidsEvolutionBase::ComputeIntermediateSpatialAcceleration
Source code excerpt:
}
}
if (AccelerationStructureSplitStaticAndDynamic == 1)
{
// If the new InternalAcceleration structure have constituents with no changes, we can copy it to the AsyncInternalAcceleration for reuse
// This step can be left out to remove a copy here, at the cost of an unnecessary recalculation in the ChaosAccelerationStructureTask
// For structures that don't change often both source and destination will be pristine and no copies will be made (most of the time)
//CopyPristineAccelerationStructures(SpatialAccelerationCache, InternalAcceleration, AsyncInternalAcceleration, true);
}
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/PBDRigidsSolver.cpp:920
Scope (from outer to inner):
file
namespace Chaos
function void FPBDRigidsSolver::RegisterObject
Source code excerpt:
if (FPBDRigidParticle* Particle = Proxy->GetParticle_External())
{
if (AccelerationStructureSplitStaticAndDynamic == 1)
{
// It needs to be {0, 1}. Things will crash otherwise. I don't know why.
// Probably similarly to the geometry collection physics proxy.
Particle->SetSpatialIdx(FSpatialAccelerationIdx{ 0, 1 });
}
else
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/PhysicsProxy/GeometryCollectionPhysicsProxy.cpp:67
Scope (from outer to inner):
file
namespace Chaos
Source code excerpt:
namespace Chaos{
extern int32 AccelerationStructureSplitStaticAndDynamic;
extern int32 AccelerationStructureIsolateQueryOnlyObjects;
}
float CollisionParticlesPerObjectFractionDefault = 1.0f;
FAutoConsoleVariableRef CVarCollisionParticlesPerObjectFractionDefault(
TEXT("p.CollisionParticlesPerObjectFractionDefault"),
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Private/PhysicsProxy/GeometryCollectionPhysicsProxy.cpp:802
Scope (from outer to inner):
file
function void FGeometryCollectionPhysicsProxy::CreateGTParticles
Source code excerpt:
P->SetSpatialIdx(Chaos::FSpatialAccelerationIdx{ 0,1 });
if (Chaos::AccelerationStructureSplitStaticAndDynamic == 1)
{
P->SetSpatialIdx(Chaos::FSpatialAccelerationIdx{ 0,1 });
}
else
{
P->SetSpatialIdx(Chaos::FSpatialAccelerationIdx{ 0,0 });
#Loc: <Workspace>/Engine/Source/Runtime/Experimental/Chaos/Public/Chaos/ParticleHandle.h:90
Scope (from outer to inner):
file
namespace Chaos
Source code excerpt:
extern CHAOS_API int32 AccelerationStructureSplitStaticAndDynamic;
template <typename T, int d, typename FConcrete>
void KinematicGeometryParticleDefaultConstruct(FConcrete& Concrete, const FKinematicGeometryParticleParameters& Params)
{
Concrete.SetV(TVector<T, d>(0));
Concrete.SetW(TVector<T, d>(0));
if (AccelerationStructureSplitStaticAndDynamic == 1)
{
Concrete.SetSpatialIdx(FSpatialAccelerationIdx{ 0,1 });
}
else
{
Concrete.SetSpatialIdx(FSpatialAccelerationIdx{ 0,0 });
#Loc: <Workspace>/Engine/Source/Runtime/PhysicsCore/Private/ChaosEngineInterface.cpp:33
Scope (from outer to inner):
file
namespace Chaos
Source code excerpt:
namespace Chaos
{
extern CHAOS_API int32 AccelerationStructureSplitStaticAndDynamic;
extern CHAOS_API int32 AccelerationStructureIsolateQueryOnlyObjects;
extern CHAOS_API int32 SyncKinematicOnGameThread;
}
bool bEnableChaosJointConstraints = true;
FAutoConsoleVariableRef CVarEnableChaosJointConstraints(TEXT("p.ChaosSolverEnableJointConstraints"), bEnableChaosJointConstraints, TEXT("Enable Joint Constraints defined within the Physics Asset Editor"));
#Loc: <Workspace>/Engine/Source/Runtime/PhysicsCore/Private/ChaosEngineInterface.cpp:2083
Scope (from outer to inner):
file
function void FChaosEngineInterface::CreateActor
Source code excerpt:
{
FSpatialAccelerationIdx SpatialIndex{0, ESpatialAccelerationCollectionBucketInnerIdx::Default };
if (AccelerationStructureSplitStaticAndDynamic == 1)
{
if (AccelerationStructureIsolateQueryOnlyObjects == 1)
{
if (InParams.bStatic && InParams.bQueryOnly)
{
SpatialIndex = FSpatialAccelerationIdx{0, ESpatialAccelerationCollectionBucketInnerIdx::DefaultQueryOnly};