1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-03-31 14:36:39 +00:00

Merge branch '1372_for_048' into 'openmw-48'

MR 1372 for 0.48. Unbreak boats mods and scripted transformations

See merge request OpenMW/openmw!2841
This commit is contained in:
psi29a 2023-03-19 10:04:06 +00:00
commit 3f19dc62e5
8 changed files with 31 additions and 32 deletions

View file

@ -305,7 +305,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; 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 ///< @return an updated Ptr
virtual MWWorld::Ptr moveObjectBy(const MWWorld::Ptr &ptr, const osg::Vec3f& vec) = 0; virtual MWWorld::Ptr moveObjectBy(const MWWorld::Ptr& ptr, const osg::Vec3f& vec, bool moveToActive) = 0;
///< @return an updated Ptr ///< @return an updated Ptr
virtual void scaleObject (const MWWorld::Ptr& ptr, float scale, bool force = false) = 0; virtual void scaleObject (const MWWorld::Ptr& ptr, float scale, bool force = false) = 0;

View file

@ -176,8 +176,6 @@ void Actor::updateCollisionObjectPosition()
trans.setOrigin(Misc::Convert::toBullet(newPosition)); trans.setOrigin(Misc::Convert::toBullet(newPosition));
trans.setRotation(Misc::Convert::toBullet(mRotation)); trans.setRotation(Misc::Convert::toBullet(mRotation));
mCollisionObject->setWorldTransform(trans); mCollisionObject->setWorldTransform(trans);
mWorldPositionChanged = false;
} }
osg::Vec3f Actor::getCollisionObjectPosition() const osg::Vec3f Actor::getCollisionObjectPosition() const
@ -189,14 +187,13 @@ osg::Vec3f Actor::getCollisionObjectPosition() const
bool Actor::setPosition(const osg::Vec3f& position) bool Actor::setPosition(const osg::Vec3f& position)
{ {
std::scoped_lock lock(mPositionMutex); std::scoped_lock lock(mPositionMutex);
const bool worldPositionChanged = mPositionOffset.length2() != 0;
applyOffsetChange(); applyOffsetChange();
bool hasChanged = (mPosition.operator!=(position) && !mSkipSimulation) || mWorldPositionChanged; if (worldPositionChanged || mSkipSimulation)
if (!mSkipSimulation) return true;
{
mPreviousPosition = mPosition; mPreviousPosition = mPosition;
mPosition = position; mPosition = position;
} return mPreviousPosition != mPosition;
return hasChanged;
} }
void Actor::adjustPosition(const osg::Vec3f& offset) void Actor::adjustPosition(const osg::Vec3f& offset)
@ -205,15 +202,16 @@ void Actor::adjustPosition(const osg::Vec3f& offset)
mPositionOffset += offset; mPositionOffset += offset;
} }
void Actor::applyOffsetChange() osg::Vec3f Actor::applyOffsetChange()
{ {
if (mPositionOffset.length() == 0) if (mPositionOffset.length2() != 0)
return; {
mPosition += mPositionOffset; mPosition += mPositionOffset;
mPreviousPosition += mPositionOffset; mPreviousPosition += mPositionOffset;
mSimulationPosition += mPositionOffset; mSimulationPosition += mPositionOffset;
mPositionOffset = osg::Vec3f(); mPositionOffset = osg::Vec3f();
mWorldPositionChanged = true; }
return mPosition;
} }
void Actor::setRotation(osg::Quat quat) void Actor::setRotation(osg::Quat quat)

View file

@ -95,7 +95,7 @@ namespace MWPhysics
void adjustPosition(const osg::Vec3f& offset); void adjustPosition(const osg::Vec3f& offset);
// apply position offset. Can't be called during simulation // apply position offset. Can't be called during simulation
void applyOffsetChange(); osg::Vec3f applyOffsetChange();
/** /**
* Returns the half extents of the collision body (scaled according to rendering scale) * Returns the half extents of the collision body (scaled according to rendering scale)
@ -189,7 +189,6 @@ namespace MWPhysics
osg::Vec3f mScale; osg::Vec3f mScale;
osg::Vec3f mPositionOffset; osg::Vec3f mPositionOffset;
bool mWorldPositionChanged;
bool mSkipSimulation; bool mSkipSimulation;
mutable std::mutex mPositionMutex; mutable std::mutex mPositionMutex;

View file

@ -452,6 +452,9 @@ namespace MWPhysics
if(actor.mSkipCollisionDetection) // noclipping/tcl if(actor.mSkipCollisionDetection) // noclipping/tcl
return; return;
if (actor.mMovement.length2() == 0) // no AI nor player attempted to move, current position is assumed correct
return;
auto tempPosition = actor.mPosition; auto tempPosition = actor.mPosition;
if(actor.mStuckFrames >= 10) if(actor.mStuckFrames >= 10)

View file

@ -167,15 +167,14 @@ namespace
return; return;
auto& [actor, frameDataRef] = *locked; auto& [actor, frameDataRef] = *locked;
auto& frameData = frameDataRef.get(); auto& frameData = frameDataRef.get();
actor->applyOffsetChange(); frameData.mPosition = actor->applyOffsetChange();
frameData.mPosition = actor->getPosition();
if (frameData.mWaterCollision && frameData.mPosition.z() < frameData.mWaterlevel && actor->canMoveToWaterSurface(frameData.mWaterlevel, mCollisionWorld)) if (frameData.mWaterCollision && frameData.mPosition.z() < frameData.mWaterlevel && actor->canMoveToWaterSurface(frameData.mWaterlevel, mCollisionWorld))
{ {
const auto offset = osg::Vec3f(0, 0, frameData.mWaterlevel - frameData.mPosition.z()); const auto offset = osg::Vec3f(0, 0, frameData.mWaterlevel - frameData.mPosition.z());
MWBase::Environment::get().getWorld()->moveObjectBy(actor->getPtr(), offset); MWBase::Environment::get().getWorld()->moveObjectBy(actor->getPtr(), offset, false);
actor->applyOffsetChange(); frameData.mPosition = actor->applyOffsetChange();
frameData.mPosition = actor->getPosition();
} }
actor->updateCollisionObjectPosition();
frameData.mOldHeight = frameData.mPosition.z(); frameData.mOldHeight = frameData.mPosition.z();
const auto rotation = actor->getPtr().getRefData().getPosition().asRotationVec3(); const auto rotation = actor->getPtr().getRefData().getPosition().asRotationVec3();
frameData.mRotation = osg::Vec2f(rotation.x(), rotation.z()); frameData.mRotation = osg::Vec2f(rotation.x(), rotation.z());

View file

@ -33,7 +33,7 @@ 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()->moveObjectBy(actor, diff); MWBase::Environment::get().getWorld()->moveObjectBy(actor, diff, false);
} }
template<class R> template<class R>
@ -328,7 +328,7 @@ namespace MWScript
} }
dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(ptr, dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(ptr,
MWBase::Environment::get().getWorld()->moveObject(ptr, newPos, true, true)); MWBase::Environment::get().getWorld()->moveObjectBy(ptr, newPos - curPos, true));
} }
}; };
@ -757,7 +757,7 @@ namespace MWScript
// This approach can be used to create elevators. // This approach can be used to create elevators.
moveStandingActors(ptr, diff); moveStandingActors(ptr, diff);
dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(ptr, dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(ptr,
MWBase::Environment::get().getWorld()->moveObjectBy(ptr, diff)); MWBase::Environment::get().getWorld()->moveObjectBy(ptr, diff, false));
} }
}; };
@ -793,7 +793,7 @@ namespace MWScript
// This approach can be used to create elevators. // This approach can be used to create elevators.
moveStandingActors(ptr, diff); moveStandingActors(ptr, diff);
dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(ptr, dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(ptr,
MWBase::Environment::get().getWorld()->moveObjectBy(ptr, diff)); MWBase::Environment::get().getWorld()->moveObjectBy(ptr, diff, false));
} }
}; };

View file

@ -1276,14 +1276,14 @@ namespace MWWorld
return moveObject(ptr, cell, position, movePhysics); return moveObject(ptr, cell, position, movePhysics);
} }
MWWorld::Ptr World::moveObjectBy(const Ptr& ptr, const osg::Vec3f& vec) MWWorld::Ptr World::moveObjectBy(const Ptr& ptr, const osg::Vec3f& vec, bool moveToActive)
{ {
auto* actor = mPhysics->getActor(ptr); auto* actor = mPhysics->getActor(ptr);
osg::Vec3f newpos = ptr.getRefData().getPosition().asVec3() + vec; osg::Vec3f newpos = ptr.getRefData().getPosition().asVec3() + vec;
if (actor) if (actor)
actor->adjustPosition(vec); actor->adjustPosition(vec);
if (ptr.getClass().isActor()) if (ptr.getClass().isActor())
return moveObject(ptr, newpos, false, ptr != getPlayerPtr()); return moveObject(ptr, newpos, false, moveToActive && ptr != getPlayerPtr());
return moveObject(ptr, newpos); return moveObject(ptr, newpos);
} }

View file

@ -394,7 +394,7 @@ namespace MWWorld
MWWorld::Ptr moveObject (const Ptr& ptr, CellStore* newCell, const osg::Vec3f& position, bool movePhysics=true, bool keepActive=false) override; MWWorld::Ptr moveObject (const Ptr& ptr, CellStore* newCell, const osg::Vec3f& position, bool movePhysics=true, bool keepActive=false) override;
///< @return an updated Ptr ///< @return an updated Ptr
MWWorld::Ptr moveObjectBy(const Ptr& ptr, const osg::Vec3f& vec) override; MWWorld::Ptr moveObjectBy(const Ptr& ptr, const osg::Vec3f& vec, bool moveToActive) override;
///< @return an updated Ptr ///< @return an updated Ptr
void scaleObject (const Ptr& ptr, float scale, bool force = false) override; void scaleObject (const Ptr& ptr, float scale, bool force = false) override;