mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-30 07:15:34 +00:00
Merge branch 'reuse_simulations_buffer' into 'master'
Reuse physics simulations buffer (#6588) Closes #6588 See merge request OpenMW/openmw!2374
This commit is contained in:
commit
912a4d69ee
4 changed files with 35 additions and 18 deletions
|
@ -3,6 +3,7 @@
|
|||
#include <optional>
|
||||
#include <shared_mutex>
|
||||
#include <mutex>
|
||||
#include <cassert>
|
||||
|
||||
#include <BulletCollision/BroadphaseCollision/btDbvtBroadphase.h>
|
||||
#include <BulletCollision/CollisionShapes/btCollisionShape.h>
|
||||
|
@ -410,8 +411,10 @@ namespace MWPhysics
|
|||
return std::make_tuple(numSteps, actualDelta);
|
||||
}
|
||||
|
||||
void PhysicsTaskScheduler::applyQueuedMovements(float & timeAccum, std::vector<Simulation>&& simulations, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats)
|
||||
void PhysicsTaskScheduler::applyQueuedMovements(float& timeAccum, std::vector<Simulation>& simulations, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats)
|
||||
{
|
||||
assert(mSimulations != &simulations);
|
||||
|
||||
waitForWorkers();
|
||||
|
||||
// This function run in the main thread.
|
||||
|
@ -444,10 +447,10 @@ namespace MWPhysics
|
|||
mRemainingSteps = numSteps;
|
||||
mTimeAccum = timeAccum;
|
||||
mPhysicsDt = newDelta;
|
||||
mSimulations = std::move(simulations);
|
||||
mSimulations = &simulations;
|
||||
mAdvanceSimulation = (mRemainingSteps != 0);
|
||||
++mFrameCounter;
|
||||
mNumJobs = mSimulations.size();
|
||||
mNumJobs = mSimulations->size();
|
||||
mNextLOS.store(0, std::memory_order_relaxed);
|
||||
mNextJob.store(0, std::memory_order_release);
|
||||
|
||||
|
@ -478,7 +481,11 @@ namespace MWPhysics
|
|||
MaybeExclusiveLock lock(mSimulationMutex, mNumThreads);
|
||||
mBudget.reset(mDefaultPhysicsDt);
|
||||
mAsyncBudget.reset(0.0f);
|
||||
mSimulations.clear();
|
||||
if (mSimulations != nullptr)
|
||||
{
|
||||
mSimulations->clear();
|
||||
mSimulations = nullptr;
|
||||
}
|
||||
for (const auto& [_, actor] : actors)
|
||||
{
|
||||
actor->updatePosition();
|
||||
|
@ -654,7 +661,7 @@ namespace MWPhysics
|
|||
{
|
||||
const Visitors::UpdatePosition impl{mCollisionWorld};
|
||||
const Visitors::WithLockedPtr<Visitors::UpdatePosition, MaybeExclusiveLock> vis{impl, mCollisionWorldMutex, mNumThreads};
|
||||
for (Simulation& sim : mSimulations)
|
||||
for (Simulation& sim : *mSimulations)
|
||||
std::visit(vis, sim);
|
||||
}
|
||||
|
||||
|
@ -682,7 +689,7 @@ namespace MWPhysics
|
|||
const Visitors::Move impl{mPhysicsDt, mCollisionWorld, *mWorldFrameData};
|
||||
const Visitors::WithLockedPtr<Visitors::Move, MaybeLock> vis{impl, mCollisionWorldMutex, mNumThreads};
|
||||
while ((job = mNextJob.fetch_add(1, std::memory_order_relaxed)) < mNumJobs)
|
||||
std::visit(vis, mSimulations[job]);
|
||||
std::visit(vis, (*mSimulations)[job]);
|
||||
|
||||
mPostStepBarrier->wait([this] { afterPostStep(); });
|
||||
}
|
||||
|
@ -724,7 +731,11 @@ namespace MWPhysics
|
|||
{
|
||||
waitForWorkers();
|
||||
std::scoped_lock lock(mSimulationMutex, mUpdateAabbMutex);
|
||||
mSimulations.clear();
|
||||
if (mSimulations != nullptr)
|
||||
{
|
||||
mSimulations->clear();
|
||||
mSimulations = nullptr;
|
||||
}
|
||||
mUpdateAabb.clear();
|
||||
}
|
||||
|
||||
|
@ -735,7 +746,7 @@ namespace MWPhysics
|
|||
return;
|
||||
const Visitors::PreStep impl{mCollisionWorld};
|
||||
const Visitors::WithLockedPtr<Visitors::PreStep, MaybeExclusiveLock> vis{impl, mCollisionWorldMutex, mNumThreads};
|
||||
for (auto& sim : mSimulations)
|
||||
for (auto& sim : *mSimulations)
|
||||
std::visit(vis, sim);
|
||||
}
|
||||
|
||||
|
@ -767,9 +778,13 @@ namespace MWPhysics
|
|||
|
||||
void PhysicsTaskScheduler::syncWithMainThread()
|
||||
{
|
||||
if (mSimulations == nullptr)
|
||||
return;
|
||||
const Visitors::Sync vis{mAdvanceSimulation, mTimeAccum, mPhysicsDt, this};
|
||||
for (auto& sim : mSimulations)
|
||||
for (auto& sim : *mSimulations)
|
||||
std::visit(vis, sim);
|
||||
mSimulations->clear();
|
||||
mSimulations = nullptr;
|
||||
}
|
||||
|
||||
// Attempt to acquire unique lock on mSimulationMutex while not all worker
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace MWPhysics
|
|||
/// @param timeAccum accumulated time from previous run to interpolate movements
|
||||
/// @param actorsData per actor data needed to compute new positions
|
||||
/// @return new position of each actor
|
||||
void applyQueuedMovements(float & timeAccum, std::vector<Simulation>&& simulations, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats);
|
||||
void applyQueuedMovements(float& timeAccum, std::vector<Simulation>& simulations, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats);
|
||||
|
||||
void resetSimulation(const ActorMap& actors);
|
||||
|
||||
|
@ -77,7 +77,7 @@ namespace MWPhysics
|
|||
void waitForWorkers();
|
||||
|
||||
std::unique_ptr<WorldFrameData> mWorldFrameData;
|
||||
std::vector<Simulation> mSimulations;
|
||||
std::vector<Simulation>* mSimulations = nullptr;
|
||||
std::unordered_set<const btCollisionObject*> mCollisionObjects;
|
||||
float mDefaultPhysicsDt;
|
||||
float mPhysicsDt;
|
||||
|
|
|
@ -708,9 +708,9 @@ namespace MWPhysics
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<Simulation> PhysicsSystem::prepareSimulation(bool willSimulate)
|
||||
void PhysicsSystem::prepareSimulation(bool willSimulate, std::vector<Simulation>& simulations)
|
||||
{
|
||||
std::vector<Simulation> simulations;
|
||||
assert(simulations.empty());
|
||||
simulations.reserve(mActors.size() + mProjectiles.size());
|
||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
for (const auto& [ref, physicActor] : mActors)
|
||||
|
@ -754,8 +754,6 @@ namespace MWPhysics
|
|||
{
|
||||
simulations.emplace_back(ProjectileSimulation{projectile, ProjectileFrameData{*projectile}});
|
||||
}
|
||||
|
||||
return simulations;
|
||||
}
|
||||
|
||||
void PhysicsSystem::stepSimulation(float dt, bool skipSimulation, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats)
|
||||
|
@ -786,9 +784,10 @@ namespace MWPhysics
|
|||
mTaskScheduler->resetSimulation(mActors);
|
||||
else
|
||||
{
|
||||
auto simulations = prepareSimulation(mTimeAccum >= mPhysicsDt);
|
||||
std::vector<Simulation>& simulations = mSimulations[mSimulationsCounter++ % mSimulations.size()];
|
||||
prepareSimulation(mTimeAccum >= mPhysicsDt, simulations);
|
||||
// modifies mTimeAccum
|
||||
mTaskScheduler->applyQueuedMovements(mTimeAccum, std::move(simulations), frameStart, frameNumber, stats);
|
||||
mTaskScheduler->applyQueuedMovements(mTimeAccum, simulations, frameStart, frameNumber, stats);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -289,7 +289,7 @@ namespace MWPhysics
|
|||
|
||||
void updateWater();
|
||||
|
||||
std::vector<Simulation> prepareSimulation(bool willSimulate);
|
||||
void prepareSimulation(bool willSimulate, std::vector<Simulation>& simulations);
|
||||
|
||||
std::unique_ptr<btBroadphaseInterface> mBroadphase;
|
||||
std::unique_ptr<btDefaultCollisionConfiguration> mCollisionConfiguration;
|
||||
|
@ -333,6 +333,9 @@ namespace MWPhysics
|
|||
|
||||
DetourNavigator::CollisionShapeType mActorCollisionShapeType;
|
||||
|
||||
std::size_t mSimulationsCounter = 0;
|
||||
std::array<std::vector<Simulation>, 2> mSimulations;
|
||||
|
||||
PhysicsSystem (const PhysicsSystem&);
|
||||
PhysicsSystem& operator= (const PhysicsSystem&);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue