mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-30 16:20:21 +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;
|
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
|
///< @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 scaleObject (const MWWorld::Ptr& ptr, float scale) = 0;
|
||||||
|
|
||||||
virtual void rotateObject(const MWWorld::Ptr& ptr, float x, float y, float z,
|
virtual void rotateObject(const MWWorld::Ptr& ptr, float x, float y, float z,
|
||||||
|
@ -120,6 +120,8 @@ int Actor::getCollisionMask() const
|
|||||||
|
|
||||||
void Actor::updatePositionUnsafe()
|
void Actor::updatePositionUnsafe()
|
||||||
{
|
{
|
||||||
|
if (!mWorldPositionChanged && mWorldPosition != mPtr.getRefData().getPosition().asVec3())
|
||||||
|
mWorldPositionChanged = true;
|
||||||
mWorldPosition = mPtr.getRefData().getPosition().asVec3();
|
mWorldPosition = mPtr.getRefData().getPosition().asVec3();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,6 +155,7 @@ void Actor::updateCollisionObjectPositionUnsafe()
|
|||||||
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);
|
mCollisionObject->setWorldTransform(mLocalTransform);
|
||||||
|
mWorldPositionChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actor::updateCollisionObjectPosition()
|
void Actor::updateCollisionObjectPosition()
|
||||||
@ -167,18 +170,20 @@ osg::Vec3f Actor::getCollisionObjectPosition() const
|
|||||||
return Misc::Convert::toOsg(mLocalTransform.getOrigin());
|
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);
|
std::scoped_lock lock(mPositionMutex);
|
||||||
mPreviousPosition = mPosition;
|
bool hasChanged = mPosition != position || mPositionOffset.length() != 0 || mWorldPositionChanged;
|
||||||
mPosition = position;
|
mPreviousPosition = mPosition + mPositionOffset;
|
||||||
|
mPosition = position + mPositionOffset;
|
||||||
|
mPositionOffset = osg::Vec3f();
|
||||||
|
return hasChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actor::adjustPosition(const osg::Vec3f& offset)
|
void Actor::adjustPosition(const osg::Vec3f& offset)
|
||||||
{
|
{
|
||||||
std::scoped_lock lock(mPositionMutex);
|
std::scoped_lock lock(mPositionMutex);
|
||||||
mPosition += offset;
|
mPositionOffset += offset;
|
||||||
mPreviousPosition += offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actor::resetPosition()
|
void Actor::resetPosition()
|
||||||
@ -189,6 +194,8 @@ void Actor::resetPosition()
|
|||||||
mPosition = mWorldPosition;
|
mPosition = mWorldPosition;
|
||||||
mSimulationPosition = mWorldPosition;
|
mSimulationPosition = mWorldPosition;
|
||||||
updateCollisionObjectPositionUnsafe();
|
updateCollisionObjectPositionUnsafe();
|
||||||
|
mStandingOnPtr = nullptr;
|
||||||
|
mWorldPositionChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Vec3f Actor::getPosition() const
|
osg::Vec3f Actor::getPosition() const
|
||||||
|
@ -90,8 +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.
|
||||||
|
* Returns true if the new position is different.
|
||||||
*/
|
*/
|
||||||
void setPosition(const osg::Vec3f& position);
|
bool setPosition(const osg::Vec3f& position);
|
||||||
void resetPosition();
|
void resetPosition();
|
||||||
void adjustPosition(const osg::Vec3f& offset);
|
void adjustPosition(const osg::Vec3f& offset);
|
||||||
|
|
||||||
@ -177,6 +178,8 @@ namespace MWPhysics
|
|||||||
osg::Vec3f mSimulationPosition;
|
osg::Vec3f mSimulationPosition;
|
||||||
osg::Vec3f mPosition;
|
osg::Vec3f mPosition;
|
||||||
osg::Vec3f mPreviousPosition;
|
osg::Vec3f mPreviousPosition;
|
||||||
|
osg::Vec3f mPositionOffset;
|
||||||
|
bool mWorldPositionChanged;
|
||||||
btTransform mLocalTransform;
|
btTransform mLocalTransform;
|
||||||
mutable std::mutex mPositionMutex;
|
mutable std::mutex mPositionMutex;
|
||||||
|
|
||||||
|
@ -100,15 +100,6 @@ namespace
|
|||||||
osg::Vec3f interpolateMovements(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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -511,9 +502,7 @@ namespace MWPhysics
|
|||||||
{
|
{
|
||||||
if(const auto actor = actorData.mActor.lock())
|
if(const auto actor = actorData.mActor.lock())
|
||||||
{
|
{
|
||||||
bool positionChanged = actorData.mPosition != actorData.mActorRaw->getPosition();
|
if (actor->setPosition(actorData.mPosition))
|
||||||
actorData.mActorRaw->setPosition(actorData.mPosition);
|
|
||||||
if (positionChanged)
|
|
||||||
{
|
{
|
||||||
actor->updateCollisionObjectPosition();
|
actor->updateCollisionObjectPosition();
|
||||||
mCollisionWorld->updateSingleAabb(actor->getCollisionObject());
|
mCollisionWorld->updateSingleAabb(actor->getCollisionObject());
|
||||||
|
@ -32,11 +32,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);
|
||||||
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>
|
||||||
@ -727,14 +723,12 @@ namespace MWScript
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
osg::Vec3f diff = ptr.getRefData().getBaseNode()->getAttitude() * posChange;
|
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.
|
// We should move actors, standing on moving object, too.
|
||||||
// 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()->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());
|
Interpreter::Type_Float movement = (runtime[0].mFloat*MWBase::Environment::get().getFrameDuration());
|
||||||
runtime.pop();
|
runtime.pop();
|
||||||
|
|
||||||
const float *objPos = ptr.getRefData().getPosition().pos;
|
|
||||||
osg::Vec3f diff;
|
osg::Vec3f diff;
|
||||||
|
|
||||||
if (axis == "x")
|
if (axis == "x")
|
||||||
diff.x() += movement;
|
diff.x() = movement;
|
||||||
else if (axis == "y")
|
else if (axis == "y")
|
||||||
diff.y() += movement;
|
diff.y() = movement;
|
||||||
else if (axis == "z")
|
else if (axis == "z")
|
||||||
diff.z() += movement;
|
diff.z() = movement;
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -771,7 +764,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()->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);
|
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)
|
void World::scaleObject (const Ptr& ptr, float scale)
|
||||||
{
|
{
|
||||||
if (mPhysics->getActor(ptr))
|
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;
|
MWWorld::Ptr moveObject (const Ptr& ptr, CellStore* newCell, float x, float y, float z, bool movePhysics=true) override;
|
||||||
///< @return an updated Ptr
|
///< @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;
|
void scaleObject (const Ptr& ptr, float scale) override;
|
||||||
|
|
||||||
/// World rotates object, uses radians
|
/// World rotates object, uses radians
|
||||||
|
Loading…
x
Reference in New Issue
Block a user