@@ -53,7 +53,7 @@ namespace spartan
5353{
5454 namespace
5555 {
56- mutex scene_mutex ;
56+ recursive_mutex physx_mutex ;
5757 }
5858
5959 namespace settings
@@ -95,6 +95,7 @@ namespace spartan
9595 PxRaycastBuffer hit;
9696 PxQueryFilterData filter_data (PxQueryFlag::eDYNAMIC); // only pick dynamic bodies - static/kinematic can be moved as per usual from the editor
9797 PxScene* scene = static_cast <PxScene*>(PhysicsWorld::GetScene ());
98+ lock_guard<recursive_mutex> lock (PhysicsWorld::GetMutex ());
9899 if (scene->raycast (origin, direction, 1000 .0f , hit, PxHitFlag::eDEFAULT, filter_data) && hit.hasBlock )
99100 {
100101 PxRigidActor* actor = hit.block .actor ;
@@ -142,6 +143,7 @@ namespace spartan
142143 {
143144 if (picked_body && joint)
144145 {
146+ lock_guard<recursive_mutex> lock (PhysicsWorld::GetMutex ());
145147 joint->release ();
146148 joint = nullptr ;
147149
@@ -178,6 +180,7 @@ namespace spartan
178180 PxVec3 target = origin + direction * pick_distance;
179181
180182 // move dummy actor to target
183+ lock_guard<recursive_mutex> lock (PhysicsWorld::GetMutex ());
181184 dummy_actor->setKinematicTarget (PxTransform (target));
182185 }
183186 }
@@ -319,6 +322,7 @@ namespace spartan
319322 while (accumulated_time >= fixed_time_step)
320323 {
321324 // simulate one fixed time step
325+ lock_guard<recursive_mutex> lock (physx_mutex);
322326 scene->simulate (fixed_time_step);
323327 scene->fetchResults (true ); // block
324328 accumulated_time -= fixed_time_step;
@@ -345,6 +349,8 @@ namespace spartan
345349 // debug visualization (editor only, skip during play)
346350 if (cvar_physics.GetValueAs <bool >() && !Engine::IsFlagSet (EngineMode::Playing))
347351 {
352+ lock_guard<recursive_mutex> lock (physx_mutex);
353+
348354 // run a near-zero step so physx populates the render buffer (physx requires dt > 0)
349355 scene->simulate (numeric_limits<float >::min ());
350356 scene->fetchResults (true );
@@ -369,7 +375,7 @@ namespace spartan
369375 {
370376 if (actor && scene && !actor->getScene ())
371377 {
372- lock_guard<mutex > lock (scene_mutex );
378+ lock_guard<recursive_mutex > lock (physx_mutex );
373379 scene->addActor (*actor);
374380 }
375381 }
@@ -378,7 +384,7 @@ namespace spartan
378384 {
379385 if (actor && scene && actor->getScene () == scene)
380386 {
381- lock_guard<mutex > lock (scene_mutex );
387+ lock_guard<recursive_mutex > lock (physx_mutex );
382388 scene->removeActor (*actor);
383389 }
384390 }
@@ -400,6 +406,11 @@ namespace spartan
400406 {
401407 return static_cast <void *>(physics);
402408 }
409+
410+ recursive_mutex& PhysicsWorld::GetMutex ()
411+ {
412+ return physx_mutex;
413+ }
403414
404415 float PhysicsWorld::GetInterpolationAlpha ()
405416 {
@@ -428,7 +439,7 @@ namespace spartan
428439 PxRaycastBuffer hit;
429440 PxQueryFilterData filter_data (PxQueryFlag::eSTATIC);
430441
431- lock_guard<mutex > lock (scene_mutex );
442+ lock_guard<recursive_mutex > lock (physx_mutex );
432443 if (scene->raycast (px_origin, px_direction, max_distance, hit, PxHitFlag::eDEFAULT, filter_data) && hit.hasBlock )
433444 {
434445 hit_position = Vector3 (hit.block .position .x , hit.block .position .y , hit.block .position .z );
0 commit comments