Merge remote-tracking branch 'scrawl/master'

openmw-38
Marc Zinnschlag 9 years ago
commit 8da04bf76f

@ -515,6 +515,7 @@ namespace MWPhysics
public:
Object(const MWWorld::Ptr& ptr, osg::ref_ptr<Resource::BulletShapeInstance> shapeInstance)
: mShapeInstance(shapeInstance)
, mSolid(true)
{
mPtr = ptr;
@ -549,6 +550,17 @@ namespace MWPhysics
return mCollisionObject.get();
}
/// Return solid flag. Not used by the object itself, true by default.
bool isSolid() const
{
return mSolid;
}
void setSolid(bool solid)
{
mSolid = solid;
}
bool isAnimated() const
{
return !mShapeInstance->mAnimatedShapes.empty();
@ -618,6 +630,7 @@ namespace MWPhysics
private:
std::auto_ptr<btCollisionObject> mCollisionObject;
osg::ref_ptr<Resource::BulletShapeInstance> mShapeInstance;
bool mSolid;
};
// ---------------------------------------------------------------
@ -684,6 +697,35 @@ namespace MWPhysics
return mDebugDrawEnabled;
}
void PhysicsSystem::markAsNonSolid(const MWWorld::Ptr &ptr)
{
ObjectMap::iterator found = mObjects.find(ptr);
if (found == mObjects.end())
return;
found->second->setSolid(false);
}
bool PhysicsSystem::isOnSolidGround (const MWWorld::Ptr& actor) const
{
const Actor* physactor = getActor(actor);
if (!physactor->getOnGround())
return false;
CollisionMap::const_iterator found = mStandingCollisions.find(actor);
if (found == mStandingCollisions.end())
return true; // assume standing on terrain (which is a non-object, so not collision tracked)
ObjectMap::const_iterator foundObj = mObjects.find(found->second);
if (foundObj == mObjects.end())
return false;
if (!foundObj->second->isSolid())
return false;
return true;
}
class DeepestNotMeContactTestResultCallback : public btCollisionWorld::ContactResultCallback
{
const btCollisionObject* mMe;

@ -153,6 +153,12 @@ namespace MWPhysics
bool toggleDebugRendering();
/// Mark the given object as a 'non-solid' object. A non-solid object means that
/// \a isOnSolidGround will return false for actors standing on that object.
void markAsNonSolid (const MWWorld::Ptr& ptr);
bool isOnSolidGround (const MWWorld::Ptr& actor) const;
private:
void updateWater();

@ -2059,11 +2059,10 @@ namespace MWWorld
if (!actor)
throw std::runtime_error("can't find player");
if((!actor->getOnGround()&&actor->getCollisionMode()) || isUnderwater(currentCell, playerPos) || isWalkingOnWater(player))
if ((actor->getCollisionMode() && !mPhysics->isOnSolidGround(player)) || isUnderwater(currentCell, playerPos))
return 2;
if((currentCell->getCell()->mData.mFlags&ESM::Cell::NoSleep) ||
player.getClass().getNpcStats(player).isWerewolf())
if((currentCell->getCell()->mData.mFlags&ESM::Cell::NoSleep) || player.getClass().getNpcStats(player).isWerewolf())
return 1;
return 0;
@ -2155,6 +2154,8 @@ namespace MWWorld
health.setCurrent(health.getCurrent()-healthPerSecond*MWBase::Environment::get().getFrameDuration());
stats.setHealth(health);
mPhysics->markAsNonSolid (object);
if (healthPerSecond > 0.0f)
{
if (actor == getPlayerPtr())
@ -2183,6 +2184,8 @@ namespace MWWorld
health.setCurrent(health.getCurrent()-healthPerSecond*MWBase::Environment::get().getFrameDuration());
stats.setHealth(health);
mPhysics->markAsNonSolid (object);
if (healthPerSecond > 0.0f)
{
if (actor == getPlayerPtr())

Loading…
Cancel
Save