From ea2ba27084c38485ee3ad5fb2fa27e370e9e0e82 Mon Sep 17 00:00:00 2001 From: fredzio Date: Sat, 28 Nov 2020 20:45:23 +0100 Subject: [PATCH] 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. --- apps/openmw/mwphysics/actor.cpp | 33 +++++++++++++++++-------- apps/openmw/mwphysics/actor.hpp | 8 +++--- apps/openmw/mwphysics/mtphysics.cpp | 7 ++++-- apps/openmw/mwphysics/physicssystem.cpp | 5 +++- apps/openmw/mwphysics/physicssystem.hpp | 1 + 5 files changed, 38 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 430bd4dee..0e557378d 100644 --- a/apps/openmw/mwphysics/actor.cpp +++ b/apps/openmw/mwphysics/actor.cpp @@ -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 diff --git a/apps/openmw/mwphysics/actor.hpp b/apps/openmw/mwphysics/actor.hpp index 3d6f93ae0..07a9bebd2 100644 --- a/apps/openmw/mwphysics/actor.hpp +++ b/apps/openmw/mwphysics/actor.hpp @@ -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 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; diff --git a/apps/openmw/mwphysics/mtphysics.cpp b/apps/openmw/mwphysics/mtphysics.cpp index 8c06e0140..2d4009e7d 100644 --- a/apps/openmw/mwphysics/mtphysics.cpp +++ b/apps/openmw/mwphysics/mtphysics.cpp @@ -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; } diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 1ceba2f31..7aa1f5914 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -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) { diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index 379aea1dd..03ae78993 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -78,6 +78,7 @@ namespace MWPhysics struct ActorFrameData { ActorFrameData(const std::shared_ptr& actor, const MWWorld::Ptr character, const MWWorld::Ptr standingOn, bool moveToWaterSurface, osg::Vec3f movement, float slowFall, float waterlevel); + void updatePosition(); std::weak_ptr mActor; Actor* mActorRaw; MWWorld::Ptr mPtr;