mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-17 19:20:49 +00:00
Merge branch 'relative_move' into 'master'
Relative translation for scripts See merge request OpenMW/openmw!477
This commit is contained in:
commit
d01d5745c6
@ -286,6 +286,9 @@ namespace MWBase
|
||||
virtual MWWorld::Ptr moveObject(const MWWorld::Ptr &ptr, MWWorld::CellStore* newCell, float x, float y, float z, bool movePhysics=true) = 0;
|
||||
///< @return an updated Ptr
|
||||
|
||||
virtual MWWorld::Ptr moveObjectBy(const MWWorld::Ptr &ptr, osg::Vec3f vec) = 0;
|
||||
///< @return an updated Ptr
|
||||
|
||||
virtual void scaleObject (const MWWorld::Ptr& ptr, float scale) = 0;
|
||||
|
||||
virtual void rotateObject(const MWWorld::Ptr& ptr, float x, float y, float z,
|
||||
|
@ -120,6 +120,8 @@ int Actor::getCollisionMask() const
|
||||
|
||||
void Actor::updatePositionUnsafe()
|
||||
{
|
||||
if (!mWorldPositionChanged && mWorldPosition != mPtr.getRefData().getPosition().asVec3())
|
||||
mWorldPositionChanged = true;
|
||||
mWorldPosition = mPtr.getRefData().getPosition().asVec3();
|
||||
}
|
||||
|
||||
@ -153,6 +155,7 @@ void Actor::updateCollisionObjectPositionUnsafe()
|
||||
mLocalTransform.setOrigin(Misc::Convert::toBullet(newPosition));
|
||||
mLocalTransform.setRotation(Misc::Convert::toBullet(mRotation));
|
||||
mCollisionObject->setWorldTransform(mLocalTransform);
|
||||
mWorldPositionChanged = false;
|
||||
}
|
||||
|
||||
void Actor::updateCollisionObjectPosition()
|
||||
@ -167,18 +170,20 @@ osg::Vec3f Actor::getCollisionObjectPosition() const
|
||||
return Misc::Convert::toOsg(mLocalTransform.getOrigin());
|
||||
}
|
||||
|
||||
void Actor::setPosition(const osg::Vec3f& position)
|
||||
bool Actor::setPosition(const osg::Vec3f& position)
|
||||
{
|
||||
std::scoped_lock lock(mPositionMutex);
|
||||
mPreviousPosition = mPosition;
|
||||
mPosition = position;
|
||||
bool hasChanged = mPosition != position || mPositionOffset.length() != 0 || mWorldPositionChanged;
|
||||
mPreviousPosition = mPosition + mPositionOffset;
|
||||
mPosition = position + mPositionOffset;
|
||||
mPositionOffset = osg::Vec3f();
|
||||
return hasChanged;
|
||||
}
|
||||
|
||||
void Actor::adjustPosition(const osg::Vec3f& offset)
|
||||
{
|
||||
std::scoped_lock lock(mPositionMutex);
|
||||
mPosition += offset;
|
||||
mPreviousPosition += offset;
|
||||
mPositionOffset += offset;
|
||||
}
|
||||
|
||||
void Actor::resetPosition()
|
||||
@ -189,6 +194,8 @@ void Actor::resetPosition()
|
||||
mPosition = mWorldPosition;
|
||||
mSimulationPosition = mWorldPosition;
|
||||
updateCollisionObjectPositionUnsafe();
|
||||
mStandingOnPtr = nullptr;
|
||||
mWorldPositionChanged = false;
|
||||
}
|
||||
|
||||
osg::Vec3f Actor::getPosition() const
|
||||
|
@ -90,8 +90,9 @@ namespace MWPhysics
|
||||
|
||||
/**
|
||||
* Store the current position into mPreviousPosition, then move to this position.
|
||||
* Returns true if the new position is different.
|
||||
*/
|
||||
void setPosition(const osg::Vec3f& position);
|
||||
bool setPosition(const osg::Vec3f& position);
|
||||
void resetPosition();
|
||||
void adjustPosition(const osg::Vec3f& offset);
|
||||
|
||||
@ -177,6 +178,8 @@ namespace MWPhysics
|
||||
osg::Vec3f mSimulationPosition;
|
||||
osg::Vec3f mPosition;
|
||||
osg::Vec3f mPreviousPosition;
|
||||
osg::Vec3f mPositionOffset;
|
||||
bool mWorldPositionChanged;
|
||||
btTransform mLocalTransform;
|
||||
mutable std::mutex mPositionMutex;
|
||||
|
||||
|
@ -100,15 +100,6 @@ namespace
|
||||
osg::Vec3f interpolateMovements(MWPhysics::ActorFrameData& actorData, float timeAccum, float 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);
|
||||
}
|
||||
|
||||
@ -511,9 +502,7 @@ namespace MWPhysics
|
||||
{
|
||||
if(const auto actor = actorData.mActor.lock())
|
||||
{
|
||||
bool positionChanged = actorData.mPosition != actorData.mActorRaw->getPosition();
|
||||
actorData.mActorRaw->setPosition(actorData.mPosition);
|
||||
if (positionChanged)
|
||||
if (actor->setPosition(actorData.mPosition))
|
||||
{
|
||||
actor->updateCollisionObjectPosition();
|
||||
mCollisionWorld->updateSingleAabb(actor->getCollisionObject());
|
||||
|
@ -32,11 +32,7 @@ namespace MWScript
|
||||
std::vector<MWWorld::Ptr> actors;
|
||||
MWBase::Environment::get().getWorld()->getActorsStandingOn (ptr, actors);
|
||||
for (auto& actor : actors)
|
||||
{
|
||||
osg::Vec3f actorPos(actor.getRefData().getPosition().asVec3());
|
||||
actorPos += diff;
|
||||
MWBase::Environment::get().getWorld()->moveObject(actor, actorPos.x(), actorPos.y(), actorPos.z());
|
||||
}
|
||||
MWBase::Environment::get().getWorld()->moveObjectBy(actor, diff);
|
||||
}
|
||||
|
||||
template<class R>
|
||||
@ -727,14 +723,12 @@ namespace MWScript
|
||||
return;
|
||||
|
||||
osg::Vec3f diff = ptr.getRefData().getBaseNode()->getAttitude() * posChange;
|
||||
osg::Vec3f worldPos(ptr.getRefData().getPosition().asVec3());
|
||||
worldPos += diff;
|
||||
|
||||
// We should move actors, standing on moving object, too.
|
||||
// This approach can be used to create elevators.
|
||||
moveStandingActors(ptr, diff);
|
||||
dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(ptr,
|
||||
MWBase::Environment::get().getWorld()->moveObject(ptr, worldPos.x(), worldPos.y(), worldPos.z()));
|
||||
MWBase::Environment::get().getWorld()->moveObjectBy(ptr, diff));
|
||||
}
|
||||
};
|
||||
|
||||
@ -755,15 +749,14 @@ namespace MWScript
|
||||
Interpreter::Type_Float movement = (runtime[0].mFloat*MWBase::Environment::get().getFrameDuration());
|
||||
runtime.pop();
|
||||
|
||||
const float *objPos = ptr.getRefData().getPosition().pos;
|
||||
osg::Vec3f diff;
|
||||
|
||||
if (axis == "x")
|
||||
diff.x() += movement;
|
||||
diff.x() = movement;
|
||||
else if (axis == "y")
|
||||
diff.y() += movement;
|
||||
diff.y() = movement;
|
||||
else if (axis == "z")
|
||||
diff.z() += movement;
|
||||
diff.z() = movement;
|
||||
else
|
||||
return;
|
||||
|
||||
@ -771,7 +764,7 @@ namespace MWScript
|
||||
// This approach can be used to create elevators.
|
||||
moveStandingActors(ptr, diff);
|
||||
dynamic_cast<MWScript::InterpreterContext&>(runtime.getContext()).updatePtr(ptr,
|
||||
MWBase::Environment::get().getWorld()->moveObject(ptr, objPos[0]+diff.x(), objPos[1]+diff.y(), objPos[2]+diff.z()));
|
||||
MWBase::Environment::get().getWorld()->moveObjectBy(ptr, diff));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1251,6 +1251,18 @@ namespace MWWorld
|
||||
return moveObjectImp(ptr, x, y, z, true, moveToActive);
|
||||
}
|
||||
|
||||
MWWorld::Ptr World::moveObjectBy(const Ptr& ptr, osg::Vec3f vec)
|
||||
{
|
||||
auto* actor = mPhysics->getActor(ptr);
|
||||
if (actor)
|
||||
{
|
||||
actor->adjustPosition(vec);
|
||||
return ptr;
|
||||
}
|
||||
osg::Vec3f newpos = ptr.getRefData().getPosition().asVec3() + vec;
|
||||
return moveObject(ptr, newpos.x(), newpos.y(), newpos.z());
|
||||
}
|
||||
|
||||
void World::scaleObject (const Ptr& ptr, float scale)
|
||||
{
|
||||
if (mPhysics->getActor(ptr))
|
||||
|
@ -380,6 +380,9 @@ namespace MWWorld
|
||||
MWWorld::Ptr moveObject (const Ptr& ptr, CellStore* newCell, float x, float y, float z, bool movePhysics=true) override;
|
||||
///< @return an updated Ptr
|
||||
|
||||
MWWorld::Ptr moveObjectBy(const Ptr& ptr, osg::Vec3f vec) override;
|
||||
///< @return an updated Ptr
|
||||
|
||||
void scaleObject (const Ptr& ptr, float scale) override;
|
||||
|
||||
/// World rotates object, uses radians
|
||||
|
Loading…
x
Reference in New Issue
Block a user