mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-03 20:15:33 +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:
parent
a98847e670
commit
5a4872393a
3 changed files with 24 additions and 17 deletions
|
@ -212,7 +212,7 @@ namespace MWPhysics
|
||||||
thread.join();
|
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.
|
// This function run in the main thread.
|
||||||
// While the mSimulationMutex is held, background physics threads can't run.
|
// While the mSimulationMutex is held, background physics threads can't run.
|
||||||
|
@ -263,20 +263,6 @@ namespace MWPhysics
|
||||||
if (mAdvanceSimulation)
|
if (mAdvanceSimulation)
|
||||||
mWorldFrameData = std::make_unique<WorldFrameData>();
|
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)
|
if (mNumThreads == 0)
|
||||||
{
|
{
|
||||||
mMovementResults.clear();
|
mMovementResults.clear();
|
||||||
|
@ -311,6 +297,15 @@ namespace MWPhysics
|
||||||
return mPreviousMovementResults;
|
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
|
void PhysicsTaskScheduler::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const
|
||||||
{
|
{
|
||||||
MaybeSharedLock lock(mCollisionWorldMutex, mThreadSafeBullet);
|
MaybeSharedLock lock(mCollisionWorldMutex, mThreadSafeBullet);
|
||||||
|
|
|
@ -32,7 +32,9 @@ namespace MWPhysics
|
||||||
/// @param timeAccum accumulated time from previous run to interpolate movements
|
/// @param timeAccum accumulated time from previous run to interpolate movements
|
||||||
/// @param actorsData per actor data needed to compute new positions
|
/// @param actorsData per actor data needed to compute new positions
|
||||||
/// @return new position of each actor
|
/// @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
|
// Thread safe wrappers
|
||||||
void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const;
|
void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const;
|
||||||
|
|
|
@ -676,7 +676,17 @@ namespace MWPhysics
|
||||||
|
|
||||||
mTimeAccum -= numSteps * mPhysicsDt;
|
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)
|
std::vector<ActorFrameData> PhysicsSystem::prepareFrameData(int numSteps)
|
||||||
|
|
Loading…
Reference in a new issue