Reuse physics simulations buffer

To avoid redundant allocations.

Use 2 buffers to make sure there is no overlap between main and the background
threads.
crashfix_debugdraw
elsid 2 years ago
parent c4d357df0f
commit 277211c5b4
No known key found for this signature in database
GPG Key ID: 4DE04C198CBA7625

@ -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…
Cancel
Save