Restore collision tracker

This commit is contained in:
scrawl 2015-05-30 01:32:00 +02:00
parent b2fe21dd3b
commit cc3bfe2bb2
3 changed files with 58 additions and 76 deletions

View file

@ -231,8 +231,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<std::string, std::string>& collisionTracker
, std::map<std::string, std::string>& standingCollisionTracker)
, std::map<MWWorld::Ptr, MWWorld::Ptr>& collisionTracker
, std::map<MWWorld::Ptr, MWWorld::Ptr>& standingCollisionTracker)
{
const ESM::Position& refpos = ptr.getRefData().getPosition();
osg::Vec3f position(refpos.asVec3());
@ -333,13 +333,10 @@ namespace MWPhysics
}
else
{
/*
const btCollisionObject* standingOn = tracer.mHitObject;
if (const OEngine::Physic::RigidBody* body = dynamic_cast<const OEngine::Physic::RigidBody*>(standingOn))
{
collisionTracker[ptr.getRefData().getHandle()] = body->mName;
}
*/
const PtrHolder* ptrHolder = static_cast<const PtrHolder*>(standingOn->getUserPointer());
if (ptrHolder)
collisionTracker[ptr] = ptrHolder->getPtr();
}
}
else
@ -406,12 +403,9 @@ namespace MWPhysics
&& tracer.mHitObject->getBroadphaseHandle()->m_collisionFilterGroup != CollisionType_Actor)
{
const btCollisionObject* standingOn = tracer.mHitObject;
/*
if (const OEngine::Physic::RigidBody* body = dynamic_cast<const OEngine::Physic::RigidBody*>(standingOn))
{
standingCollisionTracker[ptr.getRefData().getHandle()] = body->mName;
}
*/
const PtrHolder* ptrHolder = static_cast<PtrHolder*>(standingOn->getUserPointer());
if (ptrHolder)
standingCollisionTracker[ptr] = ptrHolder->getPtr();
if (standingOn->getBroadphaseHandle()->m_collisionFilterGroup == CollisionType_Water)
physicActor->setWalkingOnWater(true);
@ -857,6 +851,22 @@ namespace MWPhysics
}
}
void PhysicsSystem::updateCollisionMapPtr(CollisionMap& map, const MWWorld::Ptr &old, const MWWorld::Ptr &updated)
{
CollisionMap::iterator found = map.find(old);
if (found != map.end())
{
map[updated] = found->second;
map.erase(found);
}
for (CollisionMap::iterator it = map.begin(); it != map.end(); ++it)
{
if (it->second == old)
it->second = updated;
}
}
void PhysicsSystem::updatePtr(const MWWorld::Ptr &old, const MWWorld::Ptr &updated)
{
ObjectMap::iterator found = mObjects.find(old);
@ -876,6 +886,9 @@ namespace MWPhysics
mActors.erase(foundActor);
mActors.insert(std::make_pair(updated, actor));
}
updateCollisionMapPtr(mCollisions, old, updated);
updateCollisionMapPtr(mStandingCollisions, old, updated);
}
Actor *PhysicsSystem::getActor(const MWWorld::Ptr &ptr)
@ -1058,62 +1071,40 @@ namespace MWPhysics
bool PhysicsSystem::isActorStandingOn(const MWWorld::Ptr &actor, const MWWorld::Ptr &object) const
{
/*
const std::string& actorHandle = actor.getRefData().getHandle();
const std::string& objectHandle = object.getRefData().getHandle();
for (std::map<std::string, std::string>::const_iterator it = mStandingCollisions.begin();
it != mStandingCollisions.end(); ++it)
for (CollisionMap::const_iterator it = mStandingCollisions.begin(); it != mStandingCollisions.end(); ++it)
{
if (it->first == actorHandle && it->second == objectHandle)
if (it->first == actor && it->second == object)
return true;
}
*/
return false;
}
void PhysicsSystem::getActorsStandingOn(const MWWorld::Ptr &object, std::vector<std::string> &out) const
void PhysicsSystem::getActorsStandingOn(const MWWorld::Ptr &object, std::vector<MWWorld::Ptr> &out) const
{
/*
const std::string& objectHandle = object.getRefData().getHandle();
for (std::map<std::string, std::string>::const_iterator it = mStandingCollisions.begin();
it != mStandingCollisions.end(); ++it)
for (CollisionMap::const_iterator it = mStandingCollisions.begin(); it != mStandingCollisions.end(); ++it)
{
if (it->second == objectHandle)
if (it->second == object)
out.push_back(it->first);
}
*/
}
bool PhysicsSystem::isActorCollidingWith(const MWWorld::Ptr &actor, const MWWorld::Ptr &object) const
{
/*
const std::string& actorHandle = actor.getRefData().getHandle();
const std::string& objectHandle = object.getRefData().getHandle();
for (std::map<std::string, std::string>::const_iterator it = mCollisions.begin();
it != mCollisions.end(); ++it)
for (CollisionMap::const_iterator it = mCollisions.begin(); it != mCollisions.end(); ++it)
{
if (it->first == actorHandle && it->second == objectHandle)
if (it->first == actor && it->second == object)
return true;
}
*/
return false;
}
void PhysicsSystem::getActorsCollidingWith(const MWWorld::Ptr &object, std::vector<std::string> &out) const
void PhysicsSystem::getActorsCollidingWith(const MWWorld::Ptr &object, std::vector<MWWorld::Ptr> &out) const
{
/*
const std::string& objectHandle = object.getRefData().getHandle();
for (std::map<std::string, std::string>::const_iterator it = mCollisions.begin();
it != mCollisions.end(); ++it)
for (CollisionMap::const_iterator it = mCollisions.begin(); it != mCollisions.end(); ++it)
{
if (it->second == objectHandle)
if (it->second == object)
out.push_back(it->first);
}
*/
}
void PhysicsSystem::disableWater()

View file

@ -109,14 +109,14 @@ namespace MWPhysics
bool isActorStandingOn(const MWWorld::Ptr& actor, const MWWorld::Ptr& object) const;
/// Get the handle of all actors standing on \a object in this frame.
void getActorsStandingOn(const MWWorld::Ptr& object, std::vector<std::string>& out) const;
void getActorsStandingOn(const MWWorld::Ptr& object, std::vector<MWWorld::Ptr>& out) const;
/// Return true if \a actor has collided with \a object in this frame.
/// This will detect running into objects, but will not detect climbing stairs, stepping up a small object, etc.
bool isActorCollidingWith(const MWWorld::Ptr& actor, const MWWorld::Ptr& object) const;
/// Get the handle of all actors colliding with \a object in this frame.
void getActorsCollidingWith(const MWWorld::Ptr& object, std::vector<std::string>& out) const;
void getActorsCollidingWith(const MWWorld::Ptr& object, std::vector<MWWorld::Ptr>& out) const;
bool toggleDebugRendering();
@ -142,14 +142,15 @@ namespace MWPhysics
bool mDebugDrawEnabled;
std::map<std::string, std::string> handleToMesh;
// 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.
std::map<std::string, std::string> mCollisions; // FIXME: reimplement
typedef std::map<MWWorld::Ptr, MWWorld::Ptr> CollisionMap;
CollisionMap mCollisions;
CollisionMap mStandingCollisions;
std::map<std::string, std::string> mStandingCollisions; // FIXME: reimplement
// replaces all occurences of 'old' in the map by 'updated', no matter if its a key or value
void updateCollisionMapPtr(CollisionMap& map, const MWWorld::Ptr &old, const MWWorld::Ptr &updated);
PtrVelocityList mMovementQueue;
PtrVelocityList mMovementResults;

View file

@ -2200,27 +2200,27 @@ namespace MWWorld
bool World::getPlayerStandingOn (const MWWorld::Ptr& object)
{
//MWWorld::Ptr player = getPlayerPtr();
return 0;//mPhysics->isActorStandingOn(player, object);
MWWorld::Ptr player = getPlayerPtr();
return mPhysics->isActorStandingOn(player, object);
}
bool World::getActorStandingOn (const MWWorld::Ptr& object)
{
std::vector<std::string> actors;
//mPhysics->getActorsStandingOn(object, actors);
std::vector<MWWorld::Ptr> actors;
mPhysics->getActorsStandingOn(object, actors);
return !actors.empty();
}
bool World::getPlayerCollidingWith (const MWWorld::Ptr& object)
{
//MWWorld::Ptr player = getPlayerPtr();
return 0;//mPhysics->isActorCollidingWith(player, object);
MWWorld::Ptr player = getPlayerPtr();
return mPhysics->isActorCollidingWith(player, object);
}
bool World::getActorCollidingWith (const MWWorld::Ptr& object)
{
std::vector<std::string> actors;
//mPhysics->getActorsCollidingWith(object, actors);
std::vector<MWWorld::Ptr> actors;
mPhysics->getActorsCollidingWith(object, actors);
return !actors.empty();
}
@ -2229,15 +2229,11 @@ namespace MWWorld
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
return;
/*
std::vector<std::string> actors;
std::vector<MWWorld::Ptr> actors;
mPhysics->getActorsStandingOn(object, actors);
for (std::vector<std::string>::iterator it = actors.begin(); it != actors.end(); ++it)
for (std::vector<MWWorld::Ptr>::iterator it = actors.begin(); it != actors.end(); ++it)
{
MWWorld::Ptr actor = searchPtrViaHandle(*it); // Collision events are from the last frame, actor might no longer exist
if (actor.isEmpty())
continue;
MWWorld::Ptr actor = *it;
MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor);
if (stats.isDead())
continue;
@ -2254,7 +2250,6 @@ namespace MWWorld
MWBase::Environment::get().getSoundManager()->playSound3D(actor, "Health Damage", 1.0f, 1.0f);
}
}
*/
}
void World::hurtCollidingActors(const Ptr &object, float healthPerSecond)
@ -2262,15 +2257,11 @@ namespace MWWorld
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
return;
/*
std::vector<std::string> actors;
std::vector<MWWorld::Ptr> actors;
mPhysics->getActorsCollidingWith(object, actors);
for (std::vector<std::string>::iterator it = actors.begin(); it != actors.end(); ++it)
for (std::vector<MWWorld::Ptr>::iterator it = actors.begin(); it != actors.end(); ++it)
{
MWWorld::Ptr actor = searchPtrViaHandle(*it); // Collision events are from the last frame, actor might no longer exist
if (actor.isEmpty())
continue;
MWWorld::Ptr actor = *it;
MWMechanics::CreatureStats& stats = actor.getClass().getCreatureStats(actor);
if (stats.isDead())
continue;
@ -2287,7 +2278,6 @@ namespace MWWorld
MWBase::Environment::get().getSoundManager()->playSound3D(actor, "Health Damage", 1.0f, 1.0f);
}
}
*/
}
float World::getWindSpeed()