From cc3bfe2bb216412fe7e5e672bb2e2ca6b0c6af0d Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 30 May 2015 01:32:00 +0200 Subject: [PATCH] Restore collision tracker --- apps/openmw/mwphysics/physicssystem.cpp | 83 +++++++++++-------------- apps/openmw/mwphysics/physicssystem.hpp | 13 ++-- apps/openmw/mwworld/worldimp.cpp | 38 +++++------ 3 files changed, 58 insertions(+), 76 deletions(-) diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 2bd88e6343..8e63fecfbe 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -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& collisionTracker - , std::map& standingCollisionTracker) + , std::map& collisionTracker + , std::map& 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(standingOn)) - { - collisionTracker[ptr.getRefData().getHandle()] = body->mName; - } - */ + const PtrHolder* ptrHolder = static_cast(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(standingOn)) - { - standingCollisionTracker[ptr.getRefData().getHandle()] = body->mName; - } - */ + const PtrHolder* ptrHolder = static_cast(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::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 &out) const + void PhysicsSystem::getActorsStandingOn(const MWWorld::Ptr &object, std::vector &out) const { - /* - const std::string& objectHandle = object.getRefData().getHandle(); - - for (std::map::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::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 &out) const + void PhysicsSystem::getActorsCollidingWith(const MWWorld::Ptr &object, std::vector &out) const { - /* - const std::string& objectHandle = object.getRefData().getHandle(); - - for (std::map::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() diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index 841085f479..2240a51196 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -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& out) const; + void getActorsStandingOn(const MWWorld::Ptr& object, std::vector& 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& out) const; + void getActorsCollidingWith(const MWWorld::Ptr& object, std::vector& out) const; bool toggleDebugRendering(); @@ -142,14 +142,15 @@ namespace MWPhysics bool mDebugDrawEnabled; - std::map handleToMesh; - // Tracks all movement collisions happening during a single frame. // This will detect e.g. running against a vertical wall. It will not detect climbing up stairs, // stepping up small objects, etc. - std::map mCollisions; // FIXME: reimplement + typedef std::map CollisionMap; + CollisionMap mCollisions; + CollisionMap mStandingCollisions; - std::map 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; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 08617d0d6c..39b26c5d22 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -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 actors; - //mPhysics->getActorsStandingOn(object, actors); + std::vector 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 actors; - //mPhysics->getActorsCollidingWith(object, actors); + std::vector actors; + mPhysics->getActorsCollidingWith(object, actors); return !actors.empty(); } @@ -2229,15 +2229,11 @@ namespace MWWorld if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return; - /* - std::vector actors; + std::vector actors; mPhysics->getActorsStandingOn(object, actors); - for (std::vector::iterator it = actors.begin(); it != actors.end(); ++it) + for (std::vector::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 actors; + std::vector actors; mPhysics->getActorsCollidingWith(object, actors); - for (std::vector::iterator it = actors.begin(); it != actors.end(); ++it) + for (std::vector::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()