1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-03 11:45:34 +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;
}
void Actor::updatePositionUnsafe()
{
mWorldPosition = mPtr.getRefData().getPosition().asVec3();
}
void Actor::updatePosition()
{
std::scoped_lock lock(mPositionMutex);
mWorldPosition = mPtr.getRefData().getPosition().asVec3();
updatePositionUnsafe();
}
osg::Vec3f Actor::getWorldPosition() const
@ -130,19 +135,18 @@ osg::Vec3f Actor::getWorldPosition() const
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));
osg::Vec3f scaledTranslation = mRotation * osg::componentMultiply(mMeshTranslation, mScale);
osg::Vec3f newPosition = scaledTranslation + mPosition;
@ -151,6 +155,12 @@ void Actor::updateCollisionObjectPosition()
mCollisionObject->setWorldTransform(mLocalTransform);
}
void Actor::updateCollisionObjectPosition()
{
std::scoped_lock lock(mPositionMutex);
updateCollisionObjectPositionUnsafe();
}
osg::Vec3f Actor::getCollisionObjectPosition() const
{
std::scoped_lock lock(mPositionMutex);
@ -159,23 +169,26 @@ osg::Vec3f Actor::getCollisionObjectPosition() const
void Actor::setPosition(const osg::Vec3f& position)
{
std::scoped_lock lock(mPositionMutex);
mPreviousPosition = mPosition;
mPosition = position;
}
void Actor::adjustPosition(const osg::Vec3f& offset)
{
std::scoped_lock lock(mPositionMutex);
mPosition += offset;
mPreviousPosition += offset;
}
void Actor::resetPosition()
{
updatePosition();
std::scoped_lock lock(mPositionMutex);
updatePositionUnsafe();
mPreviousPosition = mWorldPosition;
mPosition = mWorldPosition;
mNextPosition = mWorldPosition;
updateCollisionObjectPosition();
mSimulationPosition = mWorldPosition;
updateCollisionObjectPositionUnsafe();
}
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
* to account for e.g. scripted movements
*/
void setNextPosition(const osg::Vec3f& position);
osg::Vec3f getNextPosition() const;
void setSimulationPosition(const osg::Vec3f& position);
osg::Vec3f getSimulationPosition() const;
void updateCollisionObjectPosition();
@ -154,6 +154,8 @@ namespace MWPhysics
void updateCollisionMask();
void addCollisionMask(int collisionMask);
int getCollisionMask() const;
void updateCollisionObjectPositionUnsafe();
void updatePositionUnsafe();
bool mCanWaterWalk;
std::atomic<bool> mWalkingOnWater;
@ -172,7 +174,7 @@ namespace MWPhysics
osg::Vec3f mScale;
osg::Vec3f mRenderingScale;
osg::Vec3f mWorldPosition;
osg::Vec3f mNextPosition;
osg::Vec3f mSimulationPosition;
osg::Vec3f mPosition;
osg::Vec3f mPreviousPosition;
btTransform mLocalTransform;

View file

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

View file

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

View file

@ -78,6 +78,7 @@ namespace MWPhysics
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);
void updatePosition();
std::weak_ptr<Actor> mActor;
Actor* mActorRaw;
MWWorld::Ptr mPtr;