mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 21:23:52 +00:00
Close a race between main and physics threads when actor is positioned by scripts.
When a position is forced, the actor position in physics subsystem is overriden. The background physics thread is not made aware of this, its result are simply discarded. There is a short window where this doesn't work (in this example, actor is at A and script moves it to B) 1) actor position is set to B. (among others, Actor::mPosition is set to B) 2) physics thread reset Actor::mPosition with stale value (around A) 3) main thread read simulation result, reset Actor::mSkipSimulation flag => actor is at B 4) physics thread fetch latest Actor::mPosition value, which is around A 5) main thread read simulation result, actor is around A To avoid this situation, do not perform 2) until after 3) occurs. This way, at 4) starts the simulation with up-to-date Actor::mPosition
This commit is contained in:
parent
c9d3da498a
commit
31d8ce266b
1 changed files with 3 additions and 0 deletions
|
@ -174,6 +174,9 @@ osg::Vec3f Actor::getCollisionObjectPosition() const
|
|||
bool Actor::setPosition(const osg::Vec3f& position)
|
||||
{
|
||||
std::scoped_lock lock(mPositionMutex);
|
||||
// position is being forced, ignore simulation results until we sync up
|
||||
if (mSkipSimulation)
|
||||
return false;
|
||||
bool hasChanged = mPosition != position || mPositionOffset.length() != 0 || mWorldPositionChanged;
|
||||
mPreviousPosition = mPosition + mPositionOffset;
|
||||
mPosition = position + mPositionOffset;
|
||||
|
|
Loading…
Reference in a new issue