diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 8b33095fde..c1a8d09120 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -289,7 +289,7 @@ namespace MWBase virtual MWWorld::Ptr moveObject(const MWWorld::Ptr &ptr, MWWorld::CellStore* newCell, const osg::Vec3f& position, bool movePhysics=true, bool keepActive=false) = 0; ///< @return an updated Ptr - virtual MWWorld::Ptr moveObjectBy(const MWWorld::Ptr &ptr, const osg::Vec3f& vec, bool moveToActive, bool ignoreCollisions) = 0; + virtual MWWorld::Ptr moveObjectBy(const MWWorld::Ptr &ptr, const osg::Vec3f& vec) = 0; ///< @return an updated Ptr virtual void scaleObject (const MWWorld::Ptr& ptr, float scale) = 0; diff --git a/apps/openmw/mwphysics/actor.cpp b/apps/openmw/mwphysics/actor.cpp index 4857339228..4e87f5384f 100644 --- a/apps/openmw/mwphysics/actor.cpp +++ b/apps/openmw/mwphysics/actor.cpp @@ -124,7 +124,6 @@ void Actor::updatePosition() mSimulationPosition = worldPosition; mPositionOffset = osg::Vec3f(); mStandingOnPtr = nullptr; - mSkipCollisions = true; mSkipSimulation = true; } @@ -163,17 +162,19 @@ bool Actor::setPosition(const osg::Vec3f& position) { std::scoped_lock lock(mPositionMutex); applyOffsetChange(); - bool hasChanged = mPosition != position || mWorldPositionChanged; - mPreviousPosition = mPosition; - mPosition = position; + bool hasChanged = (mPosition != position && !mSkipSimulation) || mWorldPositionChanged; + if (!mSkipSimulation) + { + mPreviousPosition = mPosition; + mPosition = position; + } return hasChanged; } -void Actor::adjustPosition(const osg::Vec3f& offset, bool ignoreCollisions) +void Actor::adjustPosition(const osg::Vec3f& offset) { std::scoped_lock lock(mPositionMutex); mPositionOffset += offset; - mSkipCollisions = mSkipCollisions || ignoreCollisions; } void Actor::applyOffsetChange() @@ -274,11 +275,6 @@ void Actor::setStandingOnPtr(const MWWorld::Ptr& ptr) mStandingOnPtr = ptr; } -bool Actor::skipCollisions() -{ - return std::exchange(mSkipCollisions, false); -} - bool Actor::canMoveToWaterSurface(float waterlevel, const btCollisionWorld* world) const { const float halfZ = getHalfExtents().z(); diff --git a/apps/openmw/mwphysics/actor.hpp b/apps/openmw/mwphysics/actor.hpp index eb65928dec..01d8037f6b 100644 --- a/apps/openmw/mwphysics/actor.hpp +++ b/apps/openmw/mwphysics/actor.hpp @@ -89,7 +89,7 @@ namespace MWPhysics void updatePosition(); // register a position offset that will be applied during simulation. - void adjustPosition(const osg::Vec3f& offset, bool ignoreCollisions); + void adjustPosition(const osg::Vec3f& offset); // apply position offset. Can't be called during simulation void applyOffsetChange(); @@ -156,8 +156,6 @@ namespace MWPhysics mLastStuckPosition = position; } - bool skipCollisions(); - bool canMoveToWaterSurface(float waterlevel, const btCollisionWorld* world) const; private: @@ -187,7 +185,6 @@ namespace MWPhysics osg::Vec3f mScale; osg::Vec3f mPositionOffset; bool mWorldPositionChanged; - bool mSkipCollisions; bool mSkipSimulation; mutable std::mutex mPositionMutex; diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 5b00677fce..af6dc109ed 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -941,7 +941,7 @@ namespace MWPhysics , mWasOnGround(actor.getOnGround()) , mIsAquatic(actor.getPtr().getClass().isPureWaterCreature(actor.getPtr())) , mWaterCollision(waterCollision) - , mSkipCollisionDetection(actor.skipCollisions() || !actor.getCollisionMode()) + , mSkipCollisionDetection(!actor.getCollisionMode()) { } @@ -951,8 +951,9 @@ namespace MWPhysics mPosition = actor.getPosition(); if (mWaterCollision && mPosition.z() < mWaterlevel && actor.canMoveToWaterSurface(mWaterlevel, world)) { - mPosition.z() = mWaterlevel; - MWBase::Environment::get().getWorld()->moveObject(actor.getPtr(), mPosition, false); + MWBase::Environment::get().getWorld()->moveObjectBy(actor.getPtr(), osg::Vec3f(0, 0, mWaterlevel - mPosition.z())); + actor.applyOffsetChange(); + mPosition = actor.getPosition(); } mOldHeight = mPosition.z(); const auto rotation = actor.getPtr().getRefData().getPosition().asRotationVec3(); diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 3d00b24ef8..5cfb2b2989 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -32,7 +32,7 @@ namespace MWScript std::vector actors; MWBase::Environment::get().getWorld()->getActorsStandingOn (ptr, actors); for (auto& actor : actors) - MWBase::Environment::get().getWorld()->moveObjectBy(actor, diff, false, false); + MWBase::Environment::get().getWorld()->moveObjectBy(actor, diff); } template @@ -312,7 +312,7 @@ namespace MWScript } dynamic_cast(runtime.getContext()).updatePtr(ptr, - MWBase::Environment::get().getWorld()->moveObjectBy(ptr, newPos - curPos, true, true)); + MWBase::Environment::get().getWorld()->moveObject(ptr, newPos, true, true)); } }; @@ -731,7 +731,7 @@ namespace MWScript // This approach can be used to create elevators. moveStandingActors(ptr, diff); dynamic_cast(runtime.getContext()).updatePtr(ptr, - MWBase::Environment::get().getWorld()->moveObjectBy(ptr, diff, false, true)); + MWBase::Environment::get().getWorld()->moveObjectBy(ptr, diff)); } }; @@ -767,7 +767,7 @@ namespace MWScript // This approach can be used to create elevators. moveStandingActors(ptr, diff); dynamic_cast(runtime.getContext()).updatePtr(ptr, - MWBase::Environment::get().getWorld()->moveObjectBy(ptr, diff, false, true)); + MWBase::Environment::get().getWorld()->moveObjectBy(ptr, diff)); } }; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 21e2d8380a..e860a114c6 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1258,14 +1258,14 @@ namespace MWWorld return moveObject(ptr, cell, position, movePhysics); } - MWWorld::Ptr World::moveObjectBy(const Ptr& ptr, const osg::Vec3f& vec, bool moveToActive, bool ignoreCollisions) + MWWorld::Ptr World::moveObjectBy(const Ptr& ptr, const osg::Vec3f& vec) { auto* actor = mPhysics->getActor(ptr); osg::Vec3f newpos = ptr.getRefData().getPosition().asVec3() + vec; if (actor) - actor->adjustPosition(vec, ignoreCollisions); + actor->adjustPosition(vec); if (ptr.getClass().isActor()) - return moveObject(ptr, newpos, false, moveToActive && ptr != getPlayerPtr()); + return moveObject(ptr, newpos, false, ptr != getPlayerPtr()); return moveObject(ptr, newpos); } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 6e48f045c0..a795b4eafd 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -376,7 +376,7 @@ namespace MWWorld MWWorld::Ptr moveObject (const Ptr& ptr, CellStore* newCell, const osg::Vec3f& position, bool movePhysics=true, bool keepActive=false) override; ///< @return an updated Ptr - MWWorld::Ptr moveObjectBy(const Ptr& ptr, const osg::Vec3f& vec, bool moveToActive, bool ignoreCollisions) override; + MWWorld::Ptr moveObjectBy(const Ptr& ptr, const osg::Vec3f& vec) override; ///< @return an updated Ptr void scaleObject (const Ptr& ptr, float scale) override;