From b58244ac26f3fa970863c2fc713de3368cba3e7f Mon Sep 17 00:00:00 2001 From: fredzio Date: Fri, 26 Mar 2021 23:45:56 +0100 Subject: [PATCH] Guard the Bullet drawing method with a read lock on the btCollisionWorld. It closes a race on the collision shapes coordinates. --- apps/openmw/mwphysics/mtphysics.cpp | 10 +++++++++- apps/openmw/mwphysics/mtphysics.hpp | 9 ++++++++- apps/openmw/mwphysics/physicssystem.cpp | 4 ++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwphysics/mtphysics.cpp b/apps/openmw/mwphysics/mtphysics.cpp index 209c5aa653..4be8b2396f 100644 --- a/apps/openmw/mwphysics/mtphysics.cpp +++ b/apps/openmw/mwphysics/mtphysics.cpp @@ -9,6 +9,7 @@ #include "components/settings/settings.hpp" #include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/movement.hpp" +#include "../mwrender/bulletdebugdraw.hpp" #include "../mwworld/class.hpp" #include "../mwworld/player.hpp" @@ -137,11 +138,12 @@ namespace namespace MWPhysics { - PhysicsTaskScheduler::PhysicsTaskScheduler(float physicsDt, btCollisionWorld *collisionWorld) + PhysicsTaskScheduler::PhysicsTaskScheduler(float physicsDt, btCollisionWorld *collisionWorld, MWRender::DebugDrawer* debugDrawer) : mDefaultPhysicsDt(physicsDt) , mPhysicsDt(physicsDt) , mTimeAccum(0.f) , mCollisionWorld(collisionWorld) + , mDebugDrawer(debugDrawer) , mNumJobs(0) , mRemainingSteps(0) , mLOSCacheExpiry(Settings::Manager::getInt("lineofsight keep inactive cache", "Physics")) @@ -626,4 +628,10 @@ namespace MWPhysics mTimeBegin = mTimer->tick(); mFrameNumber = frameNumber; } + + void PhysicsTaskScheduler::debugDraw() + { + std::shared_lock lock(mCollisionWorldMutex); + mDebugDrawer->step(); + } } diff --git a/apps/openmw/mwphysics/mtphysics.hpp b/apps/openmw/mwphysics/mtphysics.hpp index 22cab3241d..6d2c392c09 100644 --- a/apps/openmw/mwphysics/mtphysics.hpp +++ b/apps/openmw/mwphysics/mtphysics.hpp @@ -20,12 +20,17 @@ namespace Misc class Barrier; } +namespace MWRender +{ + class DebugDrawer; +} + namespace MWPhysics { class PhysicsTaskScheduler { public: - PhysicsTaskScheduler(float physicsDt, btCollisionWorld* collisionWorld); + PhysicsTaskScheduler(float physicsDt, btCollisionWorld* collisionWorld, MWRender::DebugDrawer* debugDrawer); ~PhysicsTaskScheduler(); /// @brief move actors taking into account desired movements and collisions @@ -49,6 +54,7 @@ namespace MWPhysics void removeCollisionObject(btCollisionObject* collisionObject); void updateSingleAabb(std::weak_ptr ptr, bool immediate=false); bool getLineOfSight(const std::weak_ptr& actor1, const std::weak_ptr& actor2); + void debugDraw(); private: void syncComputation(); @@ -68,6 +74,7 @@ namespace MWPhysics float mPhysicsDt; float mTimeAccum; btCollisionWorld* mCollisionWorld; + MWRender::DebugDrawer* mDebugDrawer; std::vector mLOSCache; std::set, std::owner_less>> mUpdateAabb; diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index f93ffe76d8..ac8dd92f86 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -97,8 +97,8 @@ namespace MWPhysics } } - mTaskScheduler = std::make_unique(mPhysicsDt, mCollisionWorld.get()); mDebugDrawer = std::make_unique(mParentNode, mCollisionWorld.get(), mDebugDrawEnabled); + mTaskScheduler = std::make_unique(mPhysicsDt, mCollisionWorld.get(), mDebugDrawer.get()); } PhysicsSystem::~PhysicsSystem() @@ -827,7 +827,7 @@ namespace MWPhysics void PhysicsSystem::debugDraw() { if (mDebugDrawEnabled) - mDebugDrawer->step(); + mTaskScheduler->debugDraw(); } bool PhysicsSystem::isActorStandingOn(const MWWorld::Ptr &actor, const MWWorld::ConstPtr &object) const