diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 430bd4deef..0e557378df 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 3d6f93ae05..07a9bebd28 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 8c06e01403..2d4009e7d8 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 1ceba2f315..7aa1f59141 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 379aea1dd4..03ae789934 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;