1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-01 02:45:32 +00:00

Merge branch 'actorpositionagain' into 'master'

Make the physics simulation more robust when overloaded

See merge request OpenMW/openmw!429
This commit is contained in:
psi29a 2020-11-29 13:48:35 +00:00
commit 73ca333c4b
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;