1 #ifndef OPENMW_MWPHYSICS_MTPHYSICS_H 2 #define OPENMW_MWPHYSICS_MTPHYSICS_H 3 4 #include <atomic> 5 #include <condition_variable> 6 #include <optional> 7 #include <shared_mutex> 8 #include <thread> 9 10 #include <BulletCollision/CollisionDispatch/btCollisionWorld.h> 11 12 #include <osg/Timer> 13 14 #include "physicssystem.hpp" 15 #include "ptrholder.hpp" 16 #include "components/misc/budgetmeasurement.hpp" 17 18 namespace Misc 19 { 20 class Barrier; 21 } 22 23 namespace MWRender 24 { 25 class DebugDrawer; 26 } 27 28 namespace MWPhysics 29 { 30 class PhysicsTaskScheduler 31 { 32 public: 33 PhysicsTaskScheduler(float physicsDt, btCollisionWorld* collisionWorld, MWRender::DebugDrawer* debugDrawer); 34 ~PhysicsTaskScheduler(); 35 36 /// @brief move actors taking into account desired movements and collisions 37 /// @param numSteps how much simulation step to run 38 /// @param timeAccum accumulated time from previous run to interpolate movements 39 /// @param actorsData per actor data needed to compute new positions 40 /// @return new position of each actor 41 const std::vector<MWWorld::Ptr>& moveActors(float & timeAccum, std::vector<ActorFrameData>&& actorsData, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats); 42 43 const std::vector<MWWorld::Ptr>& resetSimulation(const ActorMap& actors); 44 45 // Thread safe wrappers 46 void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const; 47 void convexSweepTest(const btConvexShape* castShape, const btTransform& from, const btTransform& to, btCollisionWorld::ConvexResultCallback& resultCallback) const; 48 void contactTest(btCollisionObject* colObj, btCollisionWorld::ContactResultCallback& resultCallback); 49 std::optional<btVector3> getHitPoint(const btTransform& from, btCollisionObject* target); 50 void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback); 51 void getAabb(const btCollisionObject* obj, btVector3& min, btVector3& max); 52 void setCollisionFilterMask(btCollisionObject* collisionObject, int collisionFilterMask); 53 void addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup, int collisionFilterMask); 54 void removeCollisionObject(btCollisionObject* collisionObject); 55 void updateSingleAabb(std::weak_ptr<PtrHolder> ptr, bool immediate=false); 56 bool getLineOfSight(const std::weak_ptr<Actor>& actor1, const std::weak_ptr<Actor>& actor2); 57 void debugDraw(); 58 59 private: 60 void syncComputation(); 61 void worker(); 62 void updateActorsPositions(); 63 bool hasLineOfSight(const Actor* actor1, const Actor* actor2); 64 void refreshLOSCache(); 65 void updateAabbs(); 66 void updatePtrAabb(const std::weak_ptr<PtrHolder>& ptr); 67 void updateStats(osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats); 68 std::tuple<int, float> calculateStepConfig(float timeAccum) const; 69 void afterPreStep(); 70 void afterPostStep(); 71 void afterPostSim(); 72 73 std::unique_ptr<WorldFrameData> mWorldFrameData; 74 std::vector<ActorFrameData> mActorsFrameData; 75 std::vector<MWWorld::Ptr> mMovedActors; 76 float mDefaultPhysicsDt; 77 float mPhysicsDt; 78 float mTimeAccum; 79 btCollisionWorld* mCollisionWorld; 80 MWRender::DebugDrawer* mDebugDrawer; 81 std::vector<LOSRequest> mLOSCache; 82 std::set<std::weak_ptr<PtrHolder>, std::owner_less<std::weak_ptr<PtrHolder>>> mUpdateAabb; 83 84 // TODO: use std::experimental::flex_barrier or std::barrier once it becomes a thing 85 std::unique_ptr<Misc::Barrier> mPreStepBarrier; 86 std::unique_ptr<Misc::Barrier> mPostStepBarrier; 87 std::unique_ptr<Misc::Barrier> mPostSimBarrier; 88 89 int mNumThreads; 90 int mNumJobs; 91 int mRemainingSteps; 92 int mLOSCacheExpiry; 93 bool mDeferAabbUpdate; 94 bool mNewFrame; 95 bool mAdvanceSimulation; 96 bool mThreadSafeBullet; 97 bool mQuit; 98 std::atomic<int> mNextJob; 99 std::atomic<int> mNextLOS; 100 std::vector<std::thread> mThreads; 101 102 mutable std::shared_mutex mSimulationMutex; 103 mutable std::shared_mutex mCollisionWorldMutex; 104 mutable std::shared_mutex mLOSCacheMutex; 105 mutable std::mutex mUpdateAabbMutex; 106 std::condition_variable_any mHasJob; 107 108 unsigned int mFrameNumber; 109 const osg::Timer* mTimer; 110 111 int mPrevStepCount; 112 Misc::BudgetMeasurement mBudget; 113 Misc::BudgetMeasurement mAsyncBudget; 114 unsigned int mBudgetCursor; 115 osg::Timer_t mAsyncStartTime; 116 osg::Timer_t mTimeBegin; 117 osg::Timer_t mTimeEnd; 118 osg::Timer_t mFrameStart; 119 }; 120 121 } 122 #endif 123