forked from mirror/openmw-tes3mp
Use a contactTest for collision script functions
The previous method didn't work for stationary actors. This change fixes the grinder in "Sotha Sil, Dome of Kasia" not registering collisions if the player stands still. (Fixes #1934)
This commit is contained in:
parent
9fce428929
commit
a49058721e
2 changed files with 12 additions and 32 deletions
|
@ -234,9 +234,8 @@ namespace MWPhysics
|
|||
}
|
||||
|
||||
static osg::Vec3f move(const MWWorld::Ptr &ptr, Actor* physicActor, const osg::Vec3f &movement, float time,
|
||||
bool isFlying, float waterlevel, float slowFall, btCollisionWorld* collisionWorld
|
||||
, std::map<MWWorld::Ptr, MWWorld::Ptr>& collisionTracker
|
||||
, std::map<MWWorld::Ptr, MWWorld::Ptr>& standingCollisionTracker)
|
||||
bool isFlying, float waterlevel, float slowFall, btCollisionWorld* collisionWorld,
|
||||
std::map<MWWorld::Ptr, MWWorld::Ptr>& standingCollisionTracker)
|
||||
{
|
||||
const ESM::Position& refpos = ptr.getRefData().getPosition();
|
||||
osg::Vec3f position(refpos.asVec3());
|
||||
|
@ -345,13 +344,6 @@ namespace MWPhysics
|
|||
newPosition = tracer.mEndPos; // ok to move, so set newPosition
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
const btCollisionObject* standingOn = tracer.mHitObject;
|
||||
const PtrHolder* ptrHolder = static_cast<const PtrHolder*>(standingOn->getUserPointer());
|
||||
if (ptrHolder)
|
||||
collisionTracker[ptr] = ptrHolder->getPtr();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -968,11 +960,11 @@ namespace MWPhysics
|
|||
}
|
||||
};
|
||||
|
||||
std::vector<MWWorld::Ptr> PhysicsSystem::getCollisions(const MWWorld::Ptr &ptr, int collisionGroup, int collisionMask)
|
||||
std::vector<MWWorld::Ptr> PhysicsSystem::getCollisions(const MWWorld::Ptr &ptr, int collisionGroup, int collisionMask) const
|
||||
{
|
||||
btCollisionObject* me = NULL;
|
||||
|
||||
ObjectMap::iterator found = mObjects.find(ptr);
|
||||
ObjectMap::const_iterator found = mObjects.find(ptr);
|
||||
if (found != mObjects.end())
|
||||
me = found->second->getCollisionObject();
|
||||
else
|
||||
|
@ -1081,7 +1073,6 @@ namespace MWPhysics
|
|||
mActors.insert(std::make_pair(updated, actor));
|
||||
}
|
||||
|
||||
updateCollisionMapPtr(mCollisions, old, updated);
|
||||
updateCollisionMapPtr(mStandingCollisions, old, updated);
|
||||
}
|
||||
|
||||
|
@ -1197,7 +1188,6 @@ namespace MWPhysics
|
|||
void PhysicsSystem::clearQueuedMovement()
|
||||
{
|
||||
mMovementQueue.clear();
|
||||
mCollisions.clear();
|
||||
mStandingCollisions.clear();
|
||||
}
|
||||
|
||||
|
@ -1209,7 +1199,6 @@ namespace MWPhysics
|
|||
if(mTimeAccum >= 1.0f/60.0f)
|
||||
{
|
||||
// Collision events should be available on every frame
|
||||
mCollisions.clear();
|
||||
mStandingCollisions.clear();
|
||||
|
||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
||||
|
@ -1243,7 +1232,7 @@ namespace MWPhysics
|
|||
|
||||
osg::Vec3f newpos = MovementSolver::move(iter->first, physicActor, iter->second, mTimeAccum,
|
||||
world->isFlying(iter->first),
|
||||
waterlevel, slowFall, mCollisionWorld, mCollisions, mStandingCollisions);
|
||||
waterlevel, slowFall, mCollisionWorld, mStandingCollisions);
|
||||
|
||||
float heightDiff = newpos.z() - oldHeight;
|
||||
|
||||
|
@ -1296,21 +1285,14 @@ namespace MWPhysics
|
|||
|
||||
bool PhysicsSystem::isActorCollidingWith(const MWWorld::Ptr &actor, const MWWorld::Ptr &object) const
|
||||
{
|
||||
for (CollisionMap::const_iterator it = mCollisions.begin(); it != mCollisions.end(); ++it)
|
||||
{
|
||||
if (it->first == actor && it->second == object)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
std::vector<MWWorld::Ptr> collisions = getCollisions(object, CollisionType_World, CollisionType_Actor);
|
||||
return (std::find(collisions.begin(), collisions.end(), actor) != collisions.end());
|
||||
}
|
||||
|
||||
void PhysicsSystem::getActorsCollidingWith(const MWWorld::Ptr &object, std::vector<MWWorld::Ptr> &out) const
|
||||
{
|
||||
for (CollisionMap::const_iterator it = mCollisions.begin(); it != mCollisions.end(); ++it)
|
||||
{
|
||||
if (it->second == object)
|
||||
out.push_back(it->first);
|
||||
}
|
||||
std::vector<MWWorld::Ptr> collisions = getCollisions(object, CollisionType_World, CollisionType_Actor);
|
||||
out.insert(out.end(), collisions.begin(), collisions.end());
|
||||
}
|
||||
|
||||
void PhysicsSystem::disableWater()
|
||||
|
|
|
@ -81,7 +81,7 @@ namespace MWPhysics
|
|||
void stepSimulation(float dt);
|
||||
void debugDraw();
|
||||
|
||||
std::vector<MWWorld::Ptr> getCollisions(const MWWorld::Ptr &ptr, int collisionGroup, int collisionMask); ///< get handles this object collides with
|
||||
std::vector<MWWorld::Ptr> getCollisions(const MWWorld::Ptr &ptr, int collisionGroup, int collisionMask) const; ///< get handles this object collides with
|
||||
osg::Vec3f traceDown(const MWWorld::Ptr &ptr, float maxHeight);
|
||||
|
||||
std::pair<MWWorld::Ptr, osg::Vec3f> getHitContact(const MWWorld::Ptr& actor,
|
||||
|
@ -174,11 +174,9 @@ namespace MWPhysics
|
|||
|
||||
bool mDebugDrawEnabled;
|
||||
|
||||
// Tracks all movement collisions happening during a single frame. <actor handle, collided handle>
|
||||
// This will detect e.g. running against a vertical wall. It will not detect climbing up stairs,
|
||||
// stepping up small objects, etc.
|
||||
// Tracks standing collisions happening during a single frame. <actor handle, collided handle>
|
||||
// This will detect standing on an object, but won't detect running e.g. against a wall.
|
||||
typedef std::map<MWWorld::Ptr, MWWorld::Ptr> CollisionMap;
|
||||
CollisionMap mCollisions;
|
||||
CollisionMap mStandingCollisions;
|
||||
|
||||
// replaces all occurences of 'old' in the map by 'updated', no matter if its a key or value
|
||||
|
|
Loading…
Reference in a new issue