Fix crash in Jolt Physics when switching scenes in editor

Co-authored-by: Jorrit Rouwe <jrouwe@gmail.com>
This commit is contained in:
Mikael Hermansson
2025-06-28 21:45:58 +02:00
parent efb40c1524
commit e2985a2e1f
3 changed files with 12 additions and 2 deletions

View File

@@ -436,6 +436,12 @@ void JoltSpace3D::remove_object(const JPH::BodyID &p_jolt_id) {
} }
body_iface.DestroyBody(p_jolt_id); body_iface.DestroyBody(p_jolt_id);
// If we're never going to step this space, like in the editor viewport, we need to manually clean up Jolt's broad phase instead, otherwise performance can degrade when doing things like switching scenes.
// We'll never actually have zero bodies in any space though, since we always have the default area, so we check if there's one or fewer left instead.
if (!JoltPhysicsServer3D::get_singleton()->is_active() && physics_system->GetNumBodies() <= 1) {
physics_system->OptimizeBroadPhase();
}
} }
void JoltSpace3D::flush_pending_objects() { void JoltSpace3D::flush_pending_objects() {

View File

@@ -73,6 +73,7 @@ void BroadPhaseQuadTree::Optimize()
{ {
JPH_PROFILE_FUNCTION(); JPH_PROFILE_FUNCTION();
// Free the previous tree so we can create a new optimized tree
FrameSync(); FrameSync();
LockModifications(); LockModifications();
@@ -80,7 +81,7 @@ void BroadPhaseQuadTree::Optimize()
for (uint l = 0; l < mNumLayers; ++l) for (uint l = 0; l < mNumLayers; ++l)
{ {
QuadTree &tree = mLayers[l]; QuadTree &tree = mLayers[l];
if (tree.HasBodies()) if (tree.HasBodies() || tree.IsDirty())
{ {
QuadTree::UpdateState update_state; QuadTree::UpdateState update_state;
tree.UpdatePrepare(mBodyManager->GetBodies(), mTracking, update_state, true); tree.UpdatePrepare(mBodyManager->GetBodies(), mTracking, update_state, true);
@@ -90,6 +91,9 @@ void BroadPhaseQuadTree::Optimize()
UnlockModifications(); UnlockModifications();
// Free the tree from before we created a new optimized tree
FrameSync();
mNextLayerToUpdate = 0; mNextLayerToUpdate = 0;
} }

View File

@@ -301,7 +301,7 @@ void QuadTree::UpdatePrepare(const BodyVector &inBodies, TrackingVector &ioTrack
#endif #endif
// Create space for all body ID's // Create space for all body ID's
NodeID *node_ids = new NodeID [mNumBodies]; NodeID *node_ids = mNumBodies > 0? new NodeID [mNumBodies] : nullptr;
NodeID *cur_node_id = node_ids; NodeID *cur_node_id = node_ids;
// Collect all bodies // Collect all bodies