mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-03 16:45:34 +00:00
Merge branch 'interleaved_movements' into 'master'
Unbreak lifts & conveyors in Sotha Sil Expanded See merge request OpenMW/openmw!410
This commit is contained in:
commit
5362146d24
8 changed files with 91 additions and 94 deletions
|
@ -75,9 +75,10 @@ Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, Physic
|
||||||
updateRotation();
|
updateRotation();
|
||||||
updateScale();
|
updateScale();
|
||||||
updatePosition();
|
updatePosition();
|
||||||
|
setPosition(mWorldPosition, true);
|
||||||
|
|
||||||
addCollisionMask(getCollisionMask());
|
addCollisionMask(getCollisionMask());
|
||||||
commitPositionChange();
|
updateCollisionObjectPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
Actor::~Actor()
|
Actor::~Actor()
|
||||||
|
@ -122,88 +123,77 @@ int Actor::getCollisionMask() const
|
||||||
|
|
||||||
void Actor::updatePosition()
|
void Actor::updatePosition()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
std::scoped_lock lock(mPositionMutex);
|
||||||
osg::Vec3f position = mPtr.getRefData().getPosition().asVec3();
|
mWorldPosition = mPtr.getRefData().getPosition().asVec3();
|
||||||
|
}
|
||||||
|
|
||||||
mPosition = position;
|
osg::Vec3f Actor::getWorldPosition() const
|
||||||
mPreviousPosition = position;
|
{
|
||||||
|
std::scoped_lock lock(mPositionMutex);
|
||||||
|
return mWorldPosition;
|
||||||
|
}
|
||||||
|
|
||||||
mTransformUpdatePending = true;
|
void Actor::setNextPosition(const osg::Vec3f& position)
|
||||||
updateCollisionObjectPosition();
|
{
|
||||||
|
mNextPosition = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::Vec3f Actor::getNextPosition() const
|
||||||
|
{
|
||||||
|
return mNextPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actor::updateCollisionObjectPosition()
|
void Actor::updateCollisionObjectPosition()
|
||||||
{
|
{
|
||||||
|
std::scoped_lock lock(mPositionMutex);
|
||||||
|
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;
|
||||||
mLocalTransform.setOrigin(Misc::Convert::toBullet(newPosition));
|
mLocalTransform.setOrigin(Misc::Convert::toBullet(newPosition));
|
||||||
mLocalTransform.setRotation(Misc::Convert::toBullet(mRotation));
|
mLocalTransform.setRotation(Misc::Convert::toBullet(mRotation));
|
||||||
|
mCollisionObject->setWorldTransform(mLocalTransform);
|
||||||
}
|
|
||||||
|
|
||||||
void Actor::commitPositionChange()
|
|
||||||
{
|
|
||||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
|
||||||
if (mScaleUpdatePending)
|
|
||||||
{
|
|
||||||
mShape->setLocalScaling(Misc::Convert::toBullet(mScale));
|
|
||||||
mScaleUpdatePending = false;
|
|
||||||
}
|
|
||||||
if (mTransformUpdatePending)
|
|
||||||
{
|
|
||||||
mCollisionObject->setWorldTransform(mLocalTransform);
|
|
||||||
mTransformUpdatePending = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Vec3f Actor::getCollisionObjectPosition() const
|
osg::Vec3f Actor::getCollisionObjectPosition() const
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
std::scoped_lock lock(mPositionMutex);
|
||||||
return Misc::Convert::toOsg(mLocalTransform.getOrigin());
|
return Misc::Convert::toOsg(mLocalTransform.getOrigin());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actor::setPosition(const osg::Vec3f &position, bool updateCollisionObject)
|
void Actor::setPosition(const osg::Vec3f& position, bool reset)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
if (reset)
|
||||||
if (mTransformUpdatePending)
|
|
||||||
{
|
{
|
||||||
mCollisionObject->setWorldTransform(mLocalTransform);
|
mPreviousPosition = position;
|
||||||
mTransformUpdatePending = false;
|
mNextPosition = position;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
mPreviousPosition = mPosition;
|
mPreviousPosition = mPosition;
|
||||||
|
mPosition = position;
|
||||||
|
}
|
||||||
|
|
||||||
mPosition = position;
|
void Actor::adjustPosition(const osg::Vec3f& offset)
|
||||||
if (updateCollisionObject)
|
{
|
||||||
{
|
mPosition += offset;
|
||||||
updateCollisionObjectPosition();
|
mPreviousPosition += offset;
|
||||||
mCollisionObject->setWorldTransform(mLocalTransform);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Vec3f Actor::getPosition() const
|
osg::Vec3f Actor::getPosition() const
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
|
||||||
return mPosition;
|
return mPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Vec3f Actor::getPreviousPosition() const
|
osg::Vec3f Actor::getPreviousPosition() const
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
|
||||||
return mPreviousPosition;
|
return mPreviousPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actor::updateRotation ()
|
void Actor::updateRotation ()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
std::scoped_lock lock(mPositionMutex);
|
||||||
if (mRotation == mPtr.getRefData().getBaseNode()->getAttitude())
|
if (mRotation == mPtr.getRefData().getBaseNode()->getAttitude())
|
||||||
return;
|
return;
|
||||||
mRotation = mPtr.getRefData().getBaseNode()->getAttitude();
|
mRotation = mPtr.getRefData().getBaseNode()->getAttitude();
|
||||||
|
|
||||||
mTransformUpdatePending = true;
|
|
||||||
updateCollisionObjectPosition();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Actor::isRotationallyInvariant() const
|
bool Actor::isRotationallyInvariant() const
|
||||||
|
@ -213,37 +203,33 @@ bool Actor::isRotationallyInvariant() const
|
||||||
|
|
||||||
void Actor::updateScale()
|
void Actor::updateScale()
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
std::scoped_lock lock(mPositionMutex);
|
||||||
float scale = mPtr.getCellRef().getScale();
|
float scale = mPtr.getCellRef().getScale();
|
||||||
osg::Vec3f scaleVec(scale,scale,scale);
|
osg::Vec3f scaleVec(scale,scale,scale);
|
||||||
|
|
||||||
mPtr.getClass().adjustScale(mPtr, scaleVec, false);
|
mPtr.getClass().adjustScale(mPtr, scaleVec, false);
|
||||||
mScale = scaleVec;
|
mScale = scaleVec;
|
||||||
mScaleUpdatePending = true;
|
|
||||||
|
|
||||||
scaleVec = osg::Vec3f(scale,scale,scale);
|
scaleVec = osg::Vec3f(scale,scale,scale);
|
||||||
mPtr.getClass().adjustScale(mPtr, scaleVec, true);
|
mPtr.getClass().adjustScale(mPtr, scaleVec, true);
|
||||||
mRenderingScale = scaleVec;
|
mRenderingScale = scaleVec;
|
||||||
|
|
||||||
mTransformUpdatePending = true;
|
|
||||||
updateCollisionObjectPosition();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Vec3f Actor::getHalfExtents() const
|
osg::Vec3f Actor::getHalfExtents() const
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
std::scoped_lock lock(mPositionMutex);
|
||||||
return osg::componentMultiply(mHalfExtents, mScale);
|
return osg::componentMultiply(mHalfExtents, mScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Vec3f Actor::getOriginalHalfExtents() const
|
osg::Vec3f Actor::getOriginalHalfExtents() const
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
std::scoped_lock lock(mPositionMutex);
|
||||||
return mHalfExtents;
|
return mHalfExtents;
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Vec3f Actor::getRenderingHalfExtents() const
|
osg::Vec3f Actor::getRenderingHalfExtents() const
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
std::scoped_lock lock(mPositionMutex);
|
||||||
return osg::componentMultiply(mHalfExtents, mRenderingScale);
|
return osg::componentMultiply(mHalfExtents, mRenderingScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,7 +260,7 @@ void Actor::setWalkingOnWater(bool walkingOnWater)
|
||||||
|
|
||||||
void Actor::setCanWaterWalk(bool waterWalk)
|
void Actor::setCanWaterWalk(bool waterWalk)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(mPositionMutex);
|
std::scoped_lock lock(mPositionMutex);
|
||||||
if (waterWalk != mCanWaterWalk)
|
if (waterWalk != mCanWaterWalk)
|
||||||
{
|
{
|
||||||
mCanWaterWalk = waterWalk;
|
mCanWaterWalk = waterWalk;
|
||||||
|
|
|
@ -57,13 +57,20 @@ namespace MWPhysics
|
||||||
bool isRotationallyInvariant() const;
|
bool isRotationallyInvariant() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set mPosition and mPreviousPosition to the position in the Ptr's RefData. This should be used
|
* Set mWorldPosition to the position in the Ptr's RefData. This is used by the physics simulation to account for
|
||||||
* when an object is "instantly" moved/teleported as opposed to being moved by the physics simulation.
|
* when an object is "instantly" moved/teleported as opposed to being moved by the physics simulation.
|
||||||
*/
|
*/
|
||||||
void updatePosition();
|
void updatePosition();
|
||||||
|
osg::Vec3f getWorldPosition() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 updateCollisionObjectPosition();
|
void updateCollisionObjectPosition();
|
||||||
void commitPositionChange();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the half extents of the collision body (scaled according to collision scale)
|
* Returns the half extents of the collision body (scaled according to collision scale)
|
||||||
|
@ -83,9 +90,9 @@ namespace MWPhysics
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store the current position into mPreviousPosition, then move to this position.
|
* Store the current position into mPreviousPosition, then move to this position.
|
||||||
* Optionally, inform the physics engine about the change of position.
|
|
||||||
*/
|
*/
|
||||||
void setPosition(const osg::Vec3f& position, bool updateCollisionObject=true);
|
void setPosition(const osg::Vec3f& position, bool reset=false);
|
||||||
|
void adjustPosition(const osg::Vec3f& offset);
|
||||||
|
|
||||||
osg::Vec3f getPosition() const;
|
osg::Vec3f getPosition() const;
|
||||||
|
|
||||||
|
@ -159,11 +166,11 @@ namespace MWPhysics
|
||||||
|
|
||||||
osg::Vec3f mScale;
|
osg::Vec3f mScale;
|
||||||
osg::Vec3f mRenderingScale;
|
osg::Vec3f mRenderingScale;
|
||||||
|
osg::Vec3f mWorldPosition;
|
||||||
|
osg::Vec3f mNextPosition;
|
||||||
osg::Vec3f mPosition;
|
osg::Vec3f mPosition;
|
||||||
osg::Vec3f mPreviousPosition;
|
osg::Vec3f mPreviousPosition;
|
||||||
btTransform mLocalTransform;
|
btTransform mLocalTransform;
|
||||||
bool mScaleUpdatePending;
|
|
||||||
bool mTransformUpdatePending;
|
|
||||||
mutable std::mutex mPositionMutex;
|
mutable std::mutex mPositionMutex;
|
||||||
|
|
||||||
osg::Vec3f mForce;
|
osg::Vec3f mForce;
|
||||||
|
|
|
@ -102,9 +102,18 @@ namespace
|
||||||
stats.addToFallHeight(-actorData.mFallHeight);
|
stats.addToFallHeight(-actorData.mFallHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Vec3f interpolateMovements(const MWPhysics::ActorFrameData& actorData, float timeAccum, float physicsDt)
|
osg::Vec3f interpolateMovements(MWPhysics::ActorFrameData& actorData, float timeAccum, float physicsDt)
|
||||||
{
|
{
|
||||||
const float interpolationFactor = timeAccum / physicsDt;
|
const float interpolationFactor = timeAccum / physicsDt;
|
||||||
|
|
||||||
|
// account for force change of actor's position in the main thread
|
||||||
|
const auto correction = actorData.mActorRaw->getWorldPosition() - actorData.mOrigin;
|
||||||
|
if (correction.length() != 0)
|
||||||
|
{
|
||||||
|
actorData.mActorRaw->adjustPosition(correction);
|
||||||
|
actorData.mPosition = actorData.mActorRaw->getPosition();
|
||||||
|
}
|
||||||
|
|
||||||
return actorData.mPosition * interpolationFactor + actorData.mActorRaw->getPreviousPosition() * (1.f - interpolationFactor);
|
return actorData.mPosition * interpolationFactor + actorData.mActorRaw->getPreviousPosition() * (1.f - interpolationFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +191,6 @@ namespace MWPhysics
|
||||||
|
|
||||||
mPostSimBarrier = std::make_unique<Misc::Barrier>(mNumThreads, [&]()
|
mPostSimBarrier = std::make_unique<Misc::Barrier>(mNumThreads, [&]()
|
||||||
{
|
{
|
||||||
udpateActorsAabbs();
|
|
||||||
mNewFrame = false;
|
mNewFrame = false;
|
||||||
if (mLOSCacheExpiry >= 0)
|
if (mLOSCacheExpiry >= 0)
|
||||||
{
|
{
|
||||||
|
@ -229,6 +237,9 @@ namespace MWPhysics
|
||||||
updateMechanics(data);
|
updateMechanics(data);
|
||||||
if (mAdvanceSimulation)
|
if (mAdvanceSimulation)
|
||||||
updateStandingCollision(data, standingCollisions);
|
updateStandingCollision(data, standingCollisions);
|
||||||
|
|
||||||
|
if (mMovementResults.find(data.mPtr) != mMovementResults.end())
|
||||||
|
data.mActorRaw->setNextPosition(mMovementResults[data.mPtr]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,10 +256,6 @@ namespace MWPhysics
|
||||||
if (mAdvanceSimulation)
|
if (mAdvanceSimulation)
|
||||||
mWorldFrameData = std::make_unique<WorldFrameData>();
|
mWorldFrameData = std::make_unique<WorldFrameData>();
|
||||||
|
|
||||||
// update each actor position based on latest data
|
|
||||||
for (auto& data : mActorsFrameData)
|
|
||||||
data.updatePosition();
|
|
||||||
|
|
||||||
// we are asked to skip the simulation (load a savegame for instance)
|
// we are asked to skip the simulation (load a savegame for instance)
|
||||||
// just return the actors' reference position without applying the movements
|
// just return the actors' reference position without applying the movements
|
||||||
if (skipSimulation)
|
if (skipSimulation)
|
||||||
|
@ -256,7 +263,10 @@ namespace MWPhysics
|
||||||
standingCollisions.clear();
|
standingCollisions.clear();
|
||||||
mMovementResults.clear();
|
mMovementResults.clear();
|
||||||
for (const auto& m : mActorsFrameData)
|
for (const auto& m : mActorsFrameData)
|
||||||
mMovementResults[m.mPtr] = m.mPosition;
|
{
|
||||||
|
m.mActorRaw->setPosition(m.mActorRaw->getWorldPosition(), true);
|
||||||
|
mMovementResults[m.mPtr] = m.mActorRaw->getWorldPosition();
|
||||||
|
}
|
||||||
return mMovementResults;
|
return mMovementResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,6 +281,11 @@ namespace MWPhysics
|
||||||
for (auto& data : mActorsFrameData)
|
for (auto& data : mActorsFrameData)
|
||||||
updateStandingCollision(data, standingCollisions);
|
updateStandingCollision(data, standingCollisions);
|
||||||
}
|
}
|
||||||
|
for (auto& data : mActorsFrameData)
|
||||||
|
{
|
||||||
|
if (mMovementResults.find(data.mPtr) != mMovementResults.end())
|
||||||
|
data.mActorRaw->setNextPosition(mMovementResults[data.mPtr]);
|
||||||
|
}
|
||||||
return mMovementResults;
|
return mMovementResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,7 +442,7 @@ namespace MWPhysics
|
||||||
{
|
{
|
||||||
if (const auto actor = std::dynamic_pointer_cast<Actor>(p))
|
if (const auto actor = std::dynamic_pointer_cast<Actor>(p))
|
||||||
{
|
{
|
||||||
actor->commitPositionChange();
|
actor->updateCollisionObjectPosition();
|
||||||
mCollisionWorld->updateSingleAabb(actor->getCollisionObject());
|
mCollisionWorld->updateSingleAabb(actor->getCollisionObject());
|
||||||
}
|
}
|
||||||
else if (const auto object = std::dynamic_pointer_cast<Object>(p))
|
else if (const auto object = std::dynamic_pointer_cast<Object>(p))
|
||||||
|
@ -485,28 +500,17 @@ namespace MWPhysics
|
||||||
{
|
{
|
||||||
if(const auto actor = actorData.mActor.lock())
|
if(const auto actor = actorData.mActor.lock())
|
||||||
{
|
{
|
||||||
if (actorData.mPosition == actor->getPosition())
|
bool positionChanged = actorData.mPosition != actorData.mActorRaw->getPosition();
|
||||||
actor->setPosition(actorData.mPosition, false); // update previous position to make sure interpolation is correct
|
actorData.mActorRaw->setPosition(actorData.mPosition);
|
||||||
else
|
if (positionChanged)
|
||||||
{
|
{
|
||||||
actorData.mPositionChanged = true;
|
actor->updateCollisionObjectPosition();
|
||||||
actor->setPosition(actorData.mPosition);
|
mCollisionWorld->updateSingleAabb(actor->getCollisionObject());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsTaskScheduler::udpateActorsAabbs()
|
|
||||||
{
|
|
||||||
std::unique_lock lock(mCollisionWorldMutex);
|
|
||||||
for (const auto& actorData : mActorsFrameData)
|
|
||||||
if (actorData.mPositionChanged)
|
|
||||||
{
|
|
||||||
if(const auto actor = actorData.mActor.lock())
|
|
||||||
mCollisionWorld->updateSingleAabb(actor->getCollisionObject());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PhysicsTaskScheduler::hasLineOfSight(const Actor* actor1, const Actor* actor2)
|
bool PhysicsTaskScheduler::hasLineOfSight(const Actor* actor1, const Actor* actor2)
|
||||||
{
|
{
|
||||||
btVector3 pos1 = Misc::Convert::toBullet(actor1->getCollisionObjectPosition() + osg::Vec3f(0,0,actor1->getHalfExtents().z() * 0.9)); // eye level
|
btVector3 pos1 = Misc::Convert::toBullet(actor1->getCollisionObjectPosition() + osg::Vec3f(0,0,actor1->getHalfExtents().z() * 0.9)); // eye level
|
||||||
|
@ -538,6 +542,5 @@ namespace MWPhysics
|
||||||
mMovementResults[actorData.mPtr] = interpolateMovements(actorData, mTimeAccum, mPhysicsDt);
|
mMovementResults[actorData.mPtr] = interpolateMovements(actorData, mTimeAccum, mPhysicsDt);
|
||||||
updateMechanics(actorData);
|
updateMechanics(actorData);
|
||||||
}
|
}
|
||||||
udpateActorsAabbs();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,6 @@ namespace MWPhysics
|
||||||
void syncComputation();
|
void syncComputation();
|
||||||
void worker();
|
void worker();
|
||||||
void updateActorsPositions();
|
void updateActorsPositions();
|
||||||
void udpateActorsAabbs();
|
|
||||||
bool hasLineOfSight(const Actor* actor1, const Actor* actor2);
|
bool hasLineOfSight(const Actor* actor1, const Actor* actor2);
|
||||||
void refreshLOSCache();
|
void refreshLOSCache();
|
||||||
void updateAabbs();
|
void updateAabbs();
|
||||||
|
|
|
@ -883,7 +883,7 @@ namespace MWPhysics
|
||||||
ActorFrameData::ActorFrameData(const std::shared_ptr<Actor>& actor, const MWWorld::Ptr character, const MWWorld::Ptr standingOn,
|
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)
|
bool moveToWaterSurface, osg::Vec3f movement, float slowFall, float waterlevel)
|
||||||
: mActor(actor), mActorRaw(actor.get()), mStandingOn(standingOn),
|
: mActor(actor), mActorRaw(actor.get()), mStandingOn(standingOn),
|
||||||
mPositionChanged(false), mDidJump(false), mNeedLand(false), mMoveToWaterSurface(moveToWaterSurface),
|
mDidJump(false), mNeedLand(false), mMoveToWaterSurface(moveToWaterSurface),
|
||||||
mWaterlevel(waterlevel), mSlowFall(slowFall), mOldHeight(0), mFallHeight(0), mMovement(movement), mPosition(), mRefpos()
|
mWaterlevel(waterlevel), mSlowFall(slowFall), mOldHeight(0), mFallHeight(0), mMovement(movement), mPosition(), mRefpos()
|
||||||
{
|
{
|
||||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||||
|
@ -893,10 +893,9 @@ 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();
|
||||||
{
|
mOrigin = mActorRaw->getNextPosition();
|
||||||
mPosition = mActorRaw->getPosition();
|
mPosition = mActorRaw->getPosition();
|
||||||
if (mMoveToWaterSurface)
|
if (mMoveToWaterSurface)
|
||||||
{
|
{
|
||||||
|
|
|
@ -78,14 +78,12 @@ 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;
|
||||||
MWWorld::Ptr mStandingOn;
|
MWWorld::Ptr mStandingOn;
|
||||||
bool mFlying;
|
bool mFlying;
|
||||||
bool mSwimming;
|
bool mSwimming;
|
||||||
bool mPositionChanged;
|
|
||||||
bool mWasOnGround;
|
bool mWasOnGround;
|
||||||
bool mWantJump;
|
bool mWantJump;
|
||||||
bool mDidJump;
|
bool mDidJump;
|
||||||
|
@ -97,6 +95,7 @@ namespace MWPhysics
|
||||||
float mOldHeight;
|
float mOldHeight;
|
||||||
float mFallHeight;
|
float mFallHeight;
|
||||||
osg::Vec3f mMovement;
|
osg::Vec3f mMovement;
|
||||||
|
osg::Vec3f mOrigin;
|
||||||
osg::Vec3f mPosition;
|
osg::Vec3f mPosition;
|
||||||
ESM::Position mRefpos;
|
ESM::Position mRefpos;
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,7 +32,11 @@ namespace MWScript
|
||||||
std::vector<MWWorld::Ptr> actors;
|
std::vector<MWWorld::Ptr> actors;
|
||||||
MWBase::Environment::get().getWorld()->getActorsStandingOn (ptr, actors);
|
MWBase::Environment::get().getWorld()->getActorsStandingOn (ptr, actors);
|
||||||
for (auto& actor : actors)
|
for (auto& actor : actors)
|
||||||
MWBase::Environment::get().getWorld()->queueMovement(actor, diff);
|
{
|
||||||
|
osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3());
|
||||||
|
actorPos += diff;
|
||||||
|
MWBase::Environment::get().getWorld()->moveObject(actor, actorPos.x(), actorPos.y(), actorPos.z());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class R>
|
template<class R>
|
||||||
|
|
|
@ -1504,11 +1504,11 @@ namespace MWWorld
|
||||||
const auto results = mPhysics->applyQueuedMovement(duration, mDiscardMovements);
|
const auto results = mPhysics->applyQueuedMovement(duration, mDiscardMovements);
|
||||||
mDiscardMovements = false;
|
mDiscardMovements = false;
|
||||||
|
|
||||||
for(const auto& result : results)
|
for(const auto& [actor, position]: results)
|
||||||
{
|
{
|
||||||
// Handle player last, in case a cell transition occurs
|
// Handle player last, in case a cell transition occurs
|
||||||
if(result.first != getPlayerPtr())
|
if(actor != getPlayerPtr())
|
||||||
moveObjectImp(result.first, result.second.x(), result.second.y(), result.second.z(), false);
|
moveObjectImp(actor, position.x(), position.y(), position.z(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto player = results.find(getPlayerPtr());
|
const auto player = results.find(getPlayerPtr());
|
||||||
|
|
Loading…
Reference in a new issue