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:
parent
96e22bd44e
commit
ea2ba27084
5 changed files with 38 additions and 16 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue