Merge pull request #1701 from akortunov/standfix

Do not apply queue movement for standing actors
0.6.3
Bret Curtis 7 years ago committed by GitHub
commit da47fc79f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -391,6 +391,7 @@ namespace MWBase
virtual bool isUnderwater(const MWWorld::ConstPtr &object, const float heightRatio) const = 0; virtual bool isUnderwater(const MWWorld::ConstPtr &object, const float heightRatio) const = 0;
virtual bool isWaterWalkingCastableOnTarget(const MWWorld::ConstPtr &target) const = 0; virtual bool isWaterWalkingCastableOnTarget(const MWWorld::ConstPtr &target) const = 0;
virtual bool isOnGround(const MWWorld::Ptr &ptr) const = 0; virtual bool isOnGround(const MWWorld::Ptr &ptr) const = 0;
virtual bool isIdle(const MWWorld::Ptr &ptr) const = 0;
virtual osg::Matrixf getActorHeadTransform(const MWWorld::ConstPtr& actor) const = 0; virtual osg::Matrixf getActorHeadTransform(const MWWorld::ConstPtr& actor) const = 0;

@ -866,8 +866,7 @@ namespace MWMechanics
} }
// place above to prevent moving inside objects, e.g. stairs, because a vector between pathgrids can be underground. // place above to prevent moving inside objects, e.g. stairs, because a vector between pathgrids can be underground.
// Adding 20 in adjustPosition() is not enough. dest.mZ += 80;
dest.mZ += 60;
ToWorldCoordinates(dest, actor.getCell()->getCell()); ToWorldCoordinates(dest, actor.getCell()->getCell());

@ -2036,7 +2036,8 @@ void CharacterController::update(float duration)
moved.z() = 1.0; moved.z() = 1.0;
// Update movement // Update movement
if(mMovementAnimationControlled && mPtr.getClass().isActor()) // We should not apply movement for standing actors
if(mMovementAnimationControlled && mPtr.getClass().isActor() && (movement.length2() > 0.f || !world->isIdle(mPtr)))
world->queueMovement(mPtr, moved); world->queueMovement(mPtr, moved);
mSkipAnim = false; mSkipAnim = false;

@ -18,7 +18,7 @@ namespace MWPhysics
Actor::Actor(const MWWorld::Ptr& ptr, osg::ref_ptr<const Resource::BulletShape> shape, btCollisionWorld* world) Actor::Actor(const MWWorld::Ptr& ptr, osg::ref_ptr<const Resource::BulletShape> shape, btCollisionWorld* world)
: mCanWaterWalk(false), mWalkingOnWater(false) : mCanWaterWalk(false), mWalkingOnWater(false)
, mCollisionObject(nullptr), mForce(0.f, 0.f, 0.f), mOnGround(true), mOnSlope(false) , mCollisionObject(nullptr), mForce(0.f, 0.f, 0.f), mOnGround(true), mOnSlope(false), mIdle(true)
, mInternalCollisionMode(true) , mInternalCollisionMode(true)
, mExternalCollisionMode(true) , mExternalCollisionMode(true)
, mCollisionWorld(world) , mCollisionWorld(world)
@ -195,6 +195,11 @@ void Actor::setOnSlope(bool slope)
mOnSlope = slope; mOnSlope = slope;
} }
void Actor::setIdle(bool idle)
{
mIdle = idle;
}
bool Actor::isWalkingOnWater() const bool Actor::isWalkingOnWater() const
{ {
return mWalkingOnWater; return mWalkingOnWater;

@ -139,6 +139,13 @@ namespace MWPhysics
return mInternalCollisionMode && mOnSlope; return mInternalCollisionMode && mOnSlope;
} }
void setIdle(bool idle);
bool getIdle() const
{
return mIdle;
}
btCollisionObject* getCollisionObject() const btCollisionObject* getCollisionObject() const
{ {
return mCollisionObject.get(); return mCollisionObject.get();
@ -179,6 +186,7 @@ namespace MWPhysics
osg::Vec3f mForce; osg::Vec3f mForce;
bool mOnGround; bool mOnGround;
bool mOnSlope; bool mOnSlope;
bool mIdle;
bool mInternalCollisionMode; bool mInternalCollisionMode;
bool mExternalCollisionMode; bool mExternalCollisionMode;

@ -249,7 +249,7 @@ namespace MWPhysics
// Check if we actually found a valid spawn point (use an infinitely thin ray this time). // Check if we actually found a valid spawn point (use an infinitely thin ray this time).
// Required for some broken door destinations in Morrowind.esm, where the spawn point // Required for some broken door destinations in Morrowind.esm, where the spawn point
// intersects with other geometry if the actor's base is taken into account // intersects with other geometry if the actor's base is taken into account
btVector3 from = toBullet(position); btVector3 from = toBullet(position + offset);
btVector3 to = from - btVector3(0,0,maxHeight); btVector3 to = from - btVector3(0,0,maxHeight);
btCollisionWorld::ClosestRayResultCallback resultCallback1(from, to); btCollisionWorld::ClosestRayResultCallback resultCallback1(from, to);
@ -683,6 +683,7 @@ namespace MWPhysics
, mWaterEnabled(false) , mWaterEnabled(false)
, mParentNode(parentNode) , mParentNode(parentNode)
, mPhysicsDt(1.f / 60.f) , mPhysicsDt(1.f / 60.f)
, mIdleUpdateTimer(0)
{ {
mResourceSystem->addResourceManager(mShapeManager.get()); mResourceSystem->addResourceManager(mShapeManager.get());
@ -739,6 +740,18 @@ namespace MWPhysics
delete mBroadphase; delete mBroadphase;
} }
void PhysicsSystem::updateIdle()
{
for (ActorMap::iterator it = mActors.begin(); it != mActors.end(); ++it)
{
osg::Vec3f pos(it->second->getCollisionObjectPosition());
RayResult result = castRay(pos, pos - osg::Vec3f(0, 0, it->second->getHalfExtents().z() + 2), it->second->getPtr(), std::vector<MWWorld::Ptr>(), CollisionType_World|CollisionType_HeightMap|CollisionType_Door);
it->second->setIdle(result.mHit);
}
}
void PhysicsSystem::setUnrefQueue(SceneUtil::UnrefQueue *unrefQueue) void PhysicsSystem::setUnrefQueue(SceneUtil::UnrefQueue *unrefQueue)
{ {
mUnrefQueue = unrefQueue; mUnrefQueue = unrefQueue;
@ -1045,6 +1058,11 @@ namespace MWPhysics
return physactor && physactor->getOnGround(); return physactor && physactor->getOnGround();
} }
bool PhysicsSystem::isIdle(const MWWorld::Ptr &actor)
{
Actor* physactor = getActor(actor);
return physactor && physactor->getIdle();
}
bool PhysicsSystem::canMoveToWaterSurface(const MWWorld::ConstPtr &actor, const float waterlevel) bool PhysicsSystem::canMoveToWaterSurface(const MWWorld::ConstPtr &actor, const float waterlevel)
{ {
const Actor* physicActor = getActor(actor); const Actor* physicActor = getActor(actor);
@ -1337,6 +1355,10 @@ namespace MWPhysics
cmode = !cmode; cmode = !cmode;
found->second->enableCollisionMode(cmode); found->second->enableCollisionMode(cmode);
found->second->enableCollisionBody(cmode); found->second->enableCollisionBody(cmode);
if (cmode)
queueObjectMovement(MWMechanics::getPlayer(), osg::Vec3f(0, 0, -0.1f));
return cmode; return cmode;
} }
@ -1456,6 +1478,13 @@ namespace MWPhysics
for (std::set<Object*>::iterator it = mAnimatedObjects.begin(); it != mAnimatedObjects.end(); ++it) for (std::set<Object*>::iterator it = mAnimatedObjects.begin(); it != mAnimatedObjects.end(); ++it)
(*it)->animateCollisionShapes(mCollisionWorld); (*it)->animateCollisionShapes(mCollisionWorld);
mIdleUpdateTimer -= dt;
if (mIdleUpdateTimer <= 0.f)
{
mIdleUpdateTimer = 0.5f;
updateIdle();
}
#ifndef BT_NO_PROFILE #ifndef BT_NO_PROFILE
CProfileManager::Reset(); CProfileManager::Reset();
CProfileManager::Increment_Frame_Counter(); CProfileManager::Increment_Frame_Counter();

@ -124,6 +124,7 @@ namespace MWPhysics
bool getLineOfSight(const MWWorld::ConstPtr& actor1, const MWWorld::ConstPtr& actor2) const; bool getLineOfSight(const MWWorld::ConstPtr& actor1, const MWWorld::ConstPtr& actor2) const;
bool isOnGround (const MWWorld::Ptr& actor); bool isOnGround (const MWWorld::Ptr& actor);
bool isIdle (const MWWorld::Ptr& actor);
bool canMoveToWaterSurface (const MWWorld::ConstPtr &actor, const float waterlevel); bool canMoveToWaterSurface (const MWWorld::ConstPtr &actor, const float waterlevel);
@ -173,6 +174,7 @@ namespace MWPhysics
private: private:
void updateWater(); void updateWater();
void updateIdle();
osg::ref_ptr<SceneUtil::UnrefQueue> mUnrefQueue; osg::ref_ptr<SceneUtil::UnrefQueue> mUnrefQueue;
@ -221,6 +223,7 @@ namespace MWPhysics
osg::ref_ptr<osg::Group> mParentNode; osg::ref_ptr<osg::Group> mParentNode;
float mPhysicsDt; float mPhysicsDt;
float mIdleUpdateTimer;
PhysicsSystem (const PhysicsSystem&); PhysicsSystem (const PhysicsSystem&);
PhysicsSystem& operator= (const PhysicsSystem&); PhysicsSystem& operator= (const PhysicsSystem&);

@ -701,6 +701,8 @@ namespace MWScript
virtual void execute (Interpreter::Runtime& runtime) virtual void execute (Interpreter::Runtime& runtime)
{ {
MWWorld::Ptr ptr = R()(runtime);
MWBase::Environment::get().getWorld()->queueMovement(ptr, osg::Vec3f(0, 0, -0.1f));
} }
}; };

@ -506,7 +506,7 @@ void MWState::StateManager::loadGame (const Character *character, const std::str
if (firstPersonCam != MWBase::Environment::get().getWorld()->isFirstPerson()) if (firstPersonCam != MWBase::Environment::get().getWorld()->isFirstPerson())
MWBase::Environment::get().getWorld()->togglePOV(); MWBase::Environment::get().getWorld()->togglePOV();
MWWorld::ConstPtr ptr = MWMechanics::getPlayer(); const MWWorld::Ptr ptr = MWMechanics::getPlayer();
if (ptr.isInCell()) if (ptr.isInCell())
{ {
@ -538,6 +538,9 @@ void MWState::StateManager::loadGame (const Character *character, const std::str
// Since we passed "changeEvent=false" to changeCell, we shouldn't have triggered the cell change flag. // Since we passed "changeEvent=false" to changeCell, we shouldn't have triggered the cell change flag.
// But make sure the flag is cleared anyway in case it was set from an earlier game. // But make sure the flag is cleared anyway in case it was set from an earlier game.
MWBase::Environment::get().getWorld()->markCellAsUnchanged(); MWBase::Environment::get().getWorld()->markCellAsUnchanged();
// Workaround to fix camera position upon game load
MWBase::Environment::get().getWorld()->queueMovement(ptr, osg::Vec3f(0, 0, 0));
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {

@ -1314,8 +1314,6 @@ namespace MWWorld
if (pos.z() < terrainHeight) if (pos.z() < terrainHeight)
pos.z() = terrainHeight; pos.z() = terrainHeight;
pos.z() += 20; // place slightly above. will snap down to ground with code below
if (force || !isFlying(ptr)) if (force || !isFlying(ptr))
{ {
osg::Vec3f traced = mPhysics->traceDown(ptr, pos, 500); osg::Vec3f traced = mPhysics->traceDown(ptr, pos, 500);
@ -2162,6 +2160,11 @@ namespace MWWorld
return mPhysics->isOnGround(ptr); return mPhysics->isOnGround(ptr);
} }
bool World::isIdle(const MWWorld::Ptr &ptr) const
{
return mPhysics->isIdle(ptr);
}
void World::togglePOV() void World::togglePOV()
{ {
mRendering->togglePOV(); mRendering->togglePOV();

@ -489,6 +489,7 @@ namespace MWWorld
bool isWading(const MWWorld::ConstPtr &object) const override; bool isWading(const MWWorld::ConstPtr &object) const override;
bool isWaterWalkingCastableOnTarget(const MWWorld::ConstPtr &target) const override; bool isWaterWalkingCastableOnTarget(const MWWorld::ConstPtr &target) const override;
bool isOnGround(const MWWorld::Ptr &ptr) const override; bool isOnGround(const MWWorld::Ptr &ptr) const override;
bool isIdle(const MWWorld::Ptr &ptr) const override;
osg::Matrixf getActorHeadTransform(const MWWorld::ConstPtr& actor) const override; osg::Matrixf getActorHeadTransform(const MWWorld::ConstPtr& actor) const override;

Loading…
Cancel
Save