Optimize physics transformation updates propagation in async via Job System

This commit is contained in:
Wojtek Figat
2025-06-19 13:57:50 +02:00
parent 6144f6c74e
commit 4ac870f701
2 changed files with 36 additions and 3 deletions

View File

@@ -468,6 +468,14 @@ void RigidBody::OnActiveTransformChanged()
void RigidBody::BeginPlay(SceneBeginData* data)
{
#if USE_EDITOR || !BUILD_RELEASE
// FlushActiveTransforms runs in async for each separate actor thus we don't support two rigidbodies that transformations depend on each other
if (Cast<RigidBody>(GetParent()))
{
LOG(Warning, "Rigid Body '{0}' is attached to other Rigid Body which is not unsupported and might cause physical simulation instability.", GetNamePath());
}
#endif
// Create rigid body
ASSERT(_actor == nullptr);
void* scene = GetPhysicsScene()->GetPhysicsScene();

View File

@@ -1901,6 +1901,23 @@ void PhysicsBackend::StartSimulateScene(void* scene, float dt)
scenePhysX->Stepper.renderDone();
}
PxActor** CachedActiveActors;
int64 CachedActiveActorsCount;
volatile int64 CachedActiveActorIndex;
void FlushActiveTransforms(int32 i)
{
PROFILE_CPU();
int64 index;
while ((index = Platform::InterlockedIncrement(&CachedActiveActorIndex)) < CachedActiveActorsCount)
{
const auto pxActor = (PxRigidActor*)CachedActiveActors[index];
auto actor = static_cast<IPhysicsActor*>(pxActor->userData);
if (actor)
actor->OnActiveTransformChanged();
}
}
void PhysicsBackend::EndSimulateScene(void* scene)
{
PROFILE_MEM(Physics);
@@ -1919,10 +1936,18 @@ void PhysicsBackend::EndSimulateScene(void* scene)
// Gather change info
PxU32 activeActorsCount;
PxActor** activeActors = scenePhysX->Scene->getActiveActors(activeActorsCount);
if (activeActorsCount > 0)
// Update changed transformations
if (activeActorsCount > 50 && JobSystem::GetThreadsCount() > 1)
{
// Run in async via job system
CachedActiveActors = activeActors;
CachedActiveActorsCount = activeActorsCount;
CachedActiveActorIndex = -1;
JobSystem::Execute(FlushActiveTransforms, JobSystem::GetThreadsCount());
}
else
{
// Update changed transformations
// TODO: use jobs system if amount if huge
for (uint32 i = 0; i < activeActorsCount; i++)
{
const auto pxActor = (PxRigidActor*)*activeActors++;