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
pull/3050/head
fredzio 3 years ago
parent c9d3da498a
commit 31d8ce266b

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