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,
|
static osg::Vec3f move(const MWWorld::Ptr &ptr, Actor* physicActor, const osg::Vec3f &movement, float time,
|
||||||
bool isFlying, float waterlevel, float slowFall, btCollisionWorld* collisionWorld
|
bool isFlying, float waterlevel, float slowFall, btCollisionWorld* collisionWorld,
|
||||||
, std::map<MWWorld::Ptr, MWWorld::Ptr>& collisionTracker
|
std::map<MWWorld::Ptr, MWWorld::Ptr>& standingCollisionTracker)
|
||||||
, std::map<MWWorld::Ptr, MWWorld::Ptr>& standingCollisionTracker)
|
|
||||||
{
|
{
|
||||||
const ESM::Position& refpos = ptr.getRefData().getPosition();
|
const ESM::Position& refpos = ptr.getRefData().getPosition();
|
||||||
osg::Vec3f position(refpos.asVec3());
|
osg::Vec3f position(refpos.asVec3());
|
||||||
|
@ -345,13 +344,6 @@ namespace MWPhysics
|
||||||
newPosition = tracer.mEndPos; // ok to move, so set newPosition
|
newPosition = tracer.mEndPos; // ok to move, so set newPosition
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
const btCollisionObject* standingOn = tracer.mHitObject;
|
|
||||||
const PtrHolder* ptrHolder = static_cast<const PtrHolder*>(standingOn->getUserPointer());
|
|
||||||
if (ptrHolder)
|
|
||||||
collisionTracker[ptr] = ptrHolder->getPtr();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
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;
|
btCollisionObject* me = NULL;
|
||||||
|
|
||||||
ObjectMap::iterator found = mObjects.find(ptr);
|
ObjectMap::const_iterator found = mObjects.find(ptr);
|
||||||
if (found != mObjects.end())
|
if (found != mObjects.end())
|
||||||
me = found->second->getCollisionObject();
|
me = found->second->getCollisionObject();
|
||||||
else
|
else
|
||||||
|
@ -1081,7 +1073,6 @@ namespace MWPhysics
|
||||||
mActors.insert(std::make_pair(updated, actor));
|
mActors.insert(std::make_pair(updated, actor));
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCollisionMapPtr(mCollisions, old, updated);
|
|
||||||
updateCollisionMapPtr(mStandingCollisions, old, updated);
|
updateCollisionMapPtr(mStandingCollisions, old, updated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1197,7 +1188,6 @@ namespace MWPhysics
|
||||||
void PhysicsSystem::clearQueuedMovement()
|
void PhysicsSystem::clearQueuedMovement()
|
||||||
{
|
{
|
||||||
mMovementQueue.clear();
|
mMovementQueue.clear();
|
||||||
mCollisions.clear();
|
|
||||||
mStandingCollisions.clear();
|
mStandingCollisions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1209,7 +1199,6 @@ namespace MWPhysics
|
||||||
if(mTimeAccum >= 1.0f/60.0f)
|
if(mTimeAccum >= 1.0f/60.0f)
|
||||||
{
|
{
|
||||||
// Collision events should be available on every frame
|
// Collision events should be available on every frame
|
||||||
mCollisions.clear();
|
|
||||||
mStandingCollisions.clear();
|
mStandingCollisions.clear();
|
||||||
|
|
||||||
const MWBase::World *world = MWBase::Environment::get().getWorld();
|
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,
|
osg::Vec3f newpos = MovementSolver::move(iter->first, physicActor, iter->second, mTimeAccum,
|
||||||
world->isFlying(iter->first),
|
world->isFlying(iter->first),
|
||||||
waterlevel, slowFall, mCollisionWorld, mCollisions, mStandingCollisions);
|
waterlevel, slowFall, mCollisionWorld, mStandingCollisions);
|
||||||
|
|
||||||
float heightDiff = newpos.z() - oldHeight;
|
float heightDiff = newpos.z() - oldHeight;
|
||||||
|
|
||||||
|
@ -1296,21 +1285,14 @@ namespace MWPhysics
|
||||||
|
|
||||||
bool PhysicsSystem::isActorCollidingWith(const MWWorld::Ptr &actor, const MWWorld::Ptr &object) const
|
bool PhysicsSystem::isActorCollidingWith(const MWWorld::Ptr &actor, const MWWorld::Ptr &object) const
|
||||||
{
|
{
|
||||||
for (CollisionMap::const_iterator it = mCollisions.begin(); it != mCollisions.end(); ++it)
|
std::vector<MWWorld::Ptr> collisions = getCollisions(object, CollisionType_World, CollisionType_Actor);
|
||||||
{
|
return (std::find(collisions.begin(), collisions.end(), actor) != collisions.end());
|
||||||
if (it->first == actor && it->second == object)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsSystem::getActorsCollidingWith(const MWWorld::Ptr &object, std::vector<MWWorld::Ptr> &out) const
|
void PhysicsSystem::getActorsCollidingWith(const MWWorld::Ptr &object, std::vector<MWWorld::Ptr> &out) const
|
||||||
{
|
{
|
||||||
for (CollisionMap::const_iterator it = mCollisions.begin(); it != mCollisions.end(); ++it)
|
std::vector<MWWorld::Ptr> collisions = getCollisions(object, CollisionType_World, CollisionType_Actor);
|
||||||
{
|
out.insert(out.end(), collisions.begin(), collisions.end());
|
||||||
if (it->second == object)
|
|
||||||
out.push_back(it->first);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsSystem::disableWater()
|
void PhysicsSystem::disableWater()
|
||||||
|
|
|
@ -81,7 +81,7 @@ namespace MWPhysics
|
||||||
void stepSimulation(float dt);
|
void stepSimulation(float dt);
|
||||||
void debugDraw();
|
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);
|
osg::Vec3f traceDown(const MWWorld::Ptr &ptr, float maxHeight);
|
||||||
|
|
||||||
std::pair<MWWorld::Ptr, osg::Vec3f> getHitContact(const MWWorld::Ptr& actor,
|
std::pair<MWWorld::Ptr, osg::Vec3f> getHitContact(const MWWorld::Ptr& actor,
|
||||||
|
@ -174,11 +174,9 @@ namespace MWPhysics
|
||||||
|
|
||||||
bool mDebugDrawEnabled;
|
bool mDebugDrawEnabled;
|
||||||
|
|
||||||
// Tracks all movement collisions happening during a single frame. <actor handle, collided handle>
|
// Tracks standing 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,
|
// This will detect standing on an object, but won't detect running e.g. against a wall.
|
||||||
// stepping up small objects, etc.
|
|
||||||
typedef std::map<MWWorld::Ptr, MWWorld::Ptr> CollisionMap;
|
typedef std::map<MWWorld::Ptr, MWWorld::Ptr> CollisionMap;
|
||||||
CollisionMap mCollisions;
|
|
||||||
CollisionMap mStandingCollisions;
|
CollisionMap mStandingCollisions;
|
||||||
|
|
||||||
// replaces all occurences of 'old' in the map by 'updated', no matter if its a key or value
|
// replaces all occurences of 'old' in the map by 'updated', no matter if its a key or value
|
||||||
|
|
Loading…
Reference in a new issue