1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-03 15:45:34 +00:00

Rework actor position reset. While solving the issue with invalid

position being used under heavy load, I introduced a regression that
prevented the position to be updated in case of teleport.
Move the logic in its own function and decide in PhysicsSystem whether a
reset is needed.
This commit is contained in:
fredzio 2020-12-03 12:57:57 +01:00
parent a98847e670
commit 5a4872393a
3 changed files with 24 additions and 17 deletions

View file

@ -212,7 +212,7 @@ namespace MWPhysics
thread.join();
}
const PtrPositionList& PhysicsTaskScheduler::moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& actorsData, bool skipSimulation, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats)
const PtrPositionList& PhysicsTaskScheduler::moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& actorsData, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats)
{
// This function run in the main thread.
// While the mSimulationMutex is held, background physics threads can't run.
@ -263,20 +263,6 @@ namespace MWPhysics
if (mAdvanceSimulation)
mWorldFrameData = std::make_unique<WorldFrameData>();
// we are asked to skip the simulation (load a savegame for instance)
// just return the actors' reference position without applying the movements
if (skipSimulation)
{
mMovementResults.clear();
for (const auto& m : mActorsFrameData)
{
m.mActorRaw->setStandingOnPtr(nullptr);
m.mActorRaw->resetPosition();
mMovementResults[m.mPtr] = m.mActorRaw->getWorldPosition();
}
return mMovementResults;
}
if (mNumThreads == 0)
{
mMovementResults.clear();
@ -311,6 +297,15 @@ namespace MWPhysics
return mPreviousMovementResults;
}
const PtrPositionList& PhysicsTaskScheduler::resetSimulation()
{
std::unique_lock lock(mSimulationMutex);
mMovementResults.clear();
mPreviousMovementResults.clear();
mActorsFrameData.clear();
return mMovementResults;
}
void PhysicsTaskScheduler::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const
{
MaybeSharedLock lock(mCollisionWorldMutex, mThreadSafeBullet);

View file

@ -32,7 +32,9 @@ 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
const PtrPositionList& moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& actorsData, bool skip, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats);
const PtrPositionList& moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& actorsData, osg::Timer_t frameStart, unsigned int frameNumber, osg::Stats& stats);
const PtrPositionList& resetSimulation();
// Thread safe wrappers
void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const;

View file

@ -676,7 +676,17 @@ namespace MWPhysics
mTimeAccum -= numSteps * mPhysicsDt;
return mTaskScheduler->moveActors(numSteps, mTimeAccum, prepareFrameData(numSteps), skipSimulation, frameStart, frameNumber, stats);
if (skipSimulation)
{
for (auto& [_, actor] : mActors)
{
actor->resetPosition();
actor->setStandingOnPtr(nullptr);
}
return mTaskScheduler->resetSimulation();
}
return mTaskScheduler->moveActors(numSteps, mTimeAccum, prepareFrameData(numSteps), frameStart, frameNumber, stats);
}
std::vector<ActorFrameData> PhysicsSystem::prepareFrameData(int numSteps)