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

Move the moment when the actor origin is saved before simulation so to

be sure the simulation is over. Otherwise, if the simulation is too slow
the position is wrong, and the actors would jump back and forth between
old and new position instead of actually moving.
This commit is contained in:
fredzio 2020-11-28 20:45:23 +01:00
parent 96e22bd44e
commit ea2ba27084
5 changed files with 38 additions and 16 deletions

View file

@ -118,10 +118,15 @@ int Actor::getCollisionMask() const
return collisionMask; return collisionMask;
} }
void Actor::updatePositionUnsafe()
{
mWorldPosition = mPtr.getRefData().getPosition().asVec3();
}
void Actor::updatePosition() void Actor::updatePosition()
{ {
std::scoped_lock lock(mPositionMutex); std::scoped_lock lock(mPositionMutex);
mWorldPosition = mPtr.getRefData().getPosition().asVec3(); updatePositionUnsafe();
} }
osg::Vec3f Actor::getWorldPosition() const osg::Vec3f Actor::getWorldPosition() const
@ -130,19 +135,18 @@ osg::Vec3f Actor::getWorldPosition() const
return mWorldPosition; return mWorldPosition;
} }
void Actor::setNextPosition(const osg::Vec3f& position) void Actor::setSimulationPosition(const osg::Vec3f& position)
{ {
mNextPosition = position; mSimulationPosition = position;
} }
osg::Vec3f Actor::getNextPosition() const osg::Vec3f Actor::getSimulationPosition() const
{ {
return mNextPosition; return mSimulationPosition;
} }
void Actor::updateCollisionObjectPosition() void Actor::updateCollisionObjectPositionUnsafe()
{ {
std::scoped_lock lock(mPositionMutex);
mShape->setLocalScaling(Misc::Convert::toBullet(mScale)); mShape->setLocalScaling(Misc::Convert::toBullet(mScale));
osg::Vec3f scaledTranslation = mRotation * osg::componentMultiply(mMeshTranslation, mScale); osg::Vec3f scaledTranslation = mRotation * osg::componentMultiply(mMeshTranslation, mScale);
osg::Vec3f newPosition = scaledTranslation + mPosition; osg::Vec3f newPosition = scaledTranslation + mPosition;
@ -151,6 +155,12 @@ void Actor::updateCollisionObjectPosition()
mCollisionObject->setWorldTransform(mLocalTransform); mCollisionObject->setWorldTransform(mLocalTransform);
} }
void Actor::updateCollisionObjectPosition()
{
std::scoped_lock lock(mPositionMutex);
updateCollisionObjectPositionUnsafe();
}
osg::Vec3f Actor::getCollisionObjectPosition() const osg::Vec3f Actor::getCollisionObjectPosition() const
{ {
std::scoped_lock lock(mPositionMutex); std::scoped_lock lock(mPositionMutex);
@ -159,23 +169,26 @@ osg::Vec3f Actor::getCollisionObjectPosition() const
void Actor::setPosition(const osg::Vec3f& position) void Actor::setPosition(const osg::Vec3f& position)
{ {
std::scoped_lock lock(mPositionMutex);
mPreviousPosition = mPosition; mPreviousPosition = mPosition;
mPosition = position; mPosition = position;
} }
void Actor::adjustPosition(const osg::Vec3f& offset) void Actor::adjustPosition(const osg::Vec3f& offset)
{ {
std::scoped_lock lock(mPositionMutex);
mPosition += offset; mPosition += offset;
mPreviousPosition += offset; mPreviousPosition += offset;
} }
void Actor::resetPosition() void Actor::resetPosition()
{ {
updatePosition(); std::scoped_lock lock(mPositionMutex);
updatePositionUnsafe();
mPreviousPosition = mWorldPosition; mPreviousPosition = mWorldPosition;
mPosition = mWorldPosition; mPosition = mWorldPosition;
mNextPosition = mWorldPosition; mSimulationPosition = mWorldPosition;
updateCollisionObjectPosition(); updateCollisionObjectPositionUnsafe();
} }
osg::Vec3f Actor::getPosition() const osg::Vec3f Actor::getPosition() const

View file

@ -67,8 +67,8 @@ namespace MWPhysics
* Used by the physics simulation to store the simulation result. Used in conjunction with mWorldPosition * Used by the physics simulation to store the simulation result. Used in conjunction with mWorldPosition
* to account for e.g. scripted movements * to account for e.g. scripted movements
*/ */
void setNextPosition(const osg::Vec3f& position); void setSimulationPosition(const osg::Vec3f& position);
osg::Vec3f getNextPosition() const; osg::Vec3f getSimulationPosition() const;
void updateCollisionObjectPosition(); void updateCollisionObjectPosition();
@ -154,6 +154,8 @@ namespace MWPhysics
void updateCollisionMask(); void updateCollisionMask();
void addCollisionMask(int collisionMask); void addCollisionMask(int collisionMask);
int getCollisionMask() const; int getCollisionMask() const;
void updateCollisionObjectPositionUnsafe();
void updatePositionUnsafe();
bool mCanWaterWalk; bool mCanWaterWalk;
std::atomic<bool> mWalkingOnWater; std::atomic<bool> mWalkingOnWater;
@ -172,7 +174,7 @@ namespace MWPhysics
osg::Vec3f mScale; osg::Vec3f mScale;
osg::Vec3f mRenderingScale; osg::Vec3f mRenderingScale;
osg::Vec3f mWorldPosition; osg::Vec3f mWorldPosition;
osg::Vec3f mNextPosition; osg::Vec3f mSimulationPosition;
osg::Vec3f mPosition; osg::Vec3f mPosition;
osg::Vec3f mPreviousPosition; osg::Vec3f mPreviousPosition;
btTransform mLocalTransform; btTransform mLocalTransform;

View file

@ -219,6 +219,9 @@ namespace MWPhysics
std::unique_lock lock(mSimulationMutex); std::unique_lock lock(mSimulationMutex);
for (auto& data : actorsData)
data.updatePosition();
// start by finishing previous background computation // start by finishing previous background computation
if (mNumThreads != 0) if (mNumThreads != 0)
{ {
@ -233,7 +236,7 @@ namespace MWPhysics
data.mActorRaw->setStandingOnPtr(data.mStandingOn); data.mActorRaw->setStandingOnPtr(data.mStandingOn);
if (mMovementResults.find(data.mPtr) != mMovementResults.end()) if (mMovementResults.find(data.mPtr) != mMovementResults.end())
data.mActorRaw->setNextPosition(mMovementResults[data.mPtr]); data.mActorRaw->setSimulationPosition(mMovementResults[data.mPtr]);
} }
if (mFrameNumber == frameNumber - 1) if (mFrameNumber == frameNumber - 1)
@ -284,7 +287,7 @@ namespace MWPhysics
if (mAdvanceSimulation) if (mAdvanceSimulation)
data.mActorRaw->setStandingOnPtr(data.mStandingOn); data.mActorRaw->setStandingOnPtr(data.mStandingOn);
if (mMovementResults.find(data.mPtr) != mMovementResults.end()) if (mMovementResults.find(data.mPtr) != mMovementResults.end())
data.mActorRaw->setNextPosition(mMovementResults[data.mPtr]); data.mActorRaw->setSimulationPosition(mMovementResults[data.mPtr]);
} }
return mMovementResults; return mMovementResults;
} }

View file

@ -877,9 +877,12 @@ namespace MWPhysics
mWantJump = mPtr.getClass().getMovementSettings(mPtr).mPosition[2] != 0; mWantJump = mPtr.getClass().getMovementSettings(mPtr).mPosition[2] != 0;
mIsDead = mPtr.getClass().getCreatureStats(mPtr).isDead(); mIsDead = mPtr.getClass().getCreatureStats(mPtr).isDead();
mWasOnGround = actor->getOnGround(); mWasOnGround = actor->getOnGround();
}
void ActorFrameData::updatePosition()
{
mActorRaw->updatePosition(); mActorRaw->updatePosition();
mOrigin = mActorRaw->getNextPosition(); mOrigin = mActorRaw->getSimulationPosition();
mPosition = mActorRaw->getPosition(); mPosition = mActorRaw->getPosition();
if (mMoveToWaterSurface) if (mMoveToWaterSurface)
{ {

View file

@ -78,6 +78,7 @@ namespace MWPhysics
struct ActorFrameData struct ActorFrameData
{ {
ActorFrameData(const std::shared_ptr<Actor>& actor, const MWWorld::Ptr character, const MWWorld::Ptr standingOn, bool moveToWaterSurface, osg::Vec3f movement, float slowFall, float waterlevel); ActorFrameData(const std::shared_ptr<Actor>& actor, const MWWorld::Ptr character, const MWWorld::Ptr standingOn, bool moveToWaterSurface, osg::Vec3f movement, float slowFall, float waterlevel);
void updatePosition();
std::weak_ptr<Actor> mActor; std::weak_ptr<Actor> mActor;
Actor* mActorRaw; Actor* mActorRaw;
MWWorld::Ptr mPtr; MWWorld::Ptr mPtr;