mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 22:56:40 +00:00 
			
		
		
		
	Get rid of the StandingActorsMap. Just embed the necessary info into
Actor class.
This commit is contained in:
		
							parent
							
								
									5362146d24
								
							
						
					
					
						commit
						d64ed6cf53
					
				
					 6 changed files with 40 additions and 64 deletions
				
			
		|  | @ -19,7 +19,7 @@ namespace MWPhysics | |||
| 
 | ||||
| 
 | ||||
| Actor::Actor(const MWWorld::Ptr& ptr, const Resource::BulletShape* shape, PhysicsTaskScheduler* scheduler) | ||||
|   : mCanWaterWalk(false), mWalkingOnWater(false) | ||||
|   : mStandingOnPtr(nullptr), mCanWaterWalk(false), mWalkingOnWater(false) | ||||
|   , mCollisionObject(nullptr), mMeshTranslation(shape->mCollisionBoxTranslate), mHalfExtents(shape->mCollisionBoxHalfExtents) | ||||
|   , mForce(0.f, 0.f, 0.f), mOnGround(true), mOnSlope(false) | ||||
|   , mInternalCollisionMode(true) | ||||
|  | @ -268,4 +268,16 @@ void Actor::setCanWaterWalk(bool waterWalk) | |||
|     } | ||||
| } | ||||
| 
 | ||||
| MWWorld::Ptr Actor::getStandingOnPtr() const | ||||
| { | ||||
|     std::scoped_lock lock(mPositionMutex); | ||||
|     return mStandingOnPtr; | ||||
| } | ||||
| 
 | ||||
| void Actor::setStandingOnPtr(const MWWorld::Ptr& ptr) | ||||
| { | ||||
|     std::scoped_lock lock(mPositionMutex); | ||||
|     mStandingOnPtr = ptr; | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -144,7 +144,11 @@ namespace MWPhysics | |||
|         void setWalkingOnWater(bool walkingOnWater); | ||||
|         bool isWalkingOnWater() const; | ||||
| 
 | ||||
|         MWWorld::Ptr getStandingOnPtr() const; | ||||
|         void setStandingOnPtr(const MWWorld::Ptr& ptr); | ||||
| 
 | ||||
|     private: | ||||
|         MWWorld::Ptr mStandingOnPtr; | ||||
|         /// Removes then re-adds the collision object to the dynamics world
 | ||||
|         void updateCollisionMask(); | ||||
|         void addCollisionMask(int collisionMask); | ||||
|  |  | |||
|  | @ -82,14 +82,6 @@ namespace | |||
|         ptr.getClass().getMovementSettings(ptr).mPosition[2] = 0; | ||||
|     } | ||||
| 
 | ||||
|     void updateStandingCollision(MWPhysics::ActorFrameData& actorData, MWPhysics::CollisionMap& standingCollisions) | ||||
|     { | ||||
|         if (!actorData.mStandingOn.isEmpty()) | ||||
|             standingCollisions[actorData.mPtr] = actorData.mStandingOn; | ||||
|         else | ||||
|             standingCollisions.erase(actorData.mPtr); | ||||
|     } | ||||
| 
 | ||||
|     void updateMechanics(MWPhysics::ActorFrameData& actorData) | ||||
|     { | ||||
|         if (actorData.mDidJump) | ||||
|  | @ -215,7 +207,7 @@ namespace MWPhysics | |||
|             thread.join(); | ||||
|     } | ||||
| 
 | ||||
|     const PtrPositionList& PhysicsTaskScheduler::moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& actorsData, CollisionMap& standingCollisions, bool skipSimulation) | ||||
|     const PtrPositionList& PhysicsTaskScheduler::moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& actorsData, bool skipSimulation) | ||||
|     { | ||||
|         // This function run in the main thread.
 | ||||
|         // While the mSimulationMutex is held, background physics threads can't run.
 | ||||
|  | @ -225,9 +217,6 @@ namespace MWPhysics | |||
|         // start by finishing previous background computation
 | ||||
|         if (mNumThreads != 0) | ||||
|         { | ||||
|             if (mAdvanceSimulation) | ||||
|                 standingCollisions.clear(); | ||||
| 
 | ||||
|             for (auto& data : mActorsFrameData) | ||||
|             { | ||||
|                 // Ignore actors that were deleted while the background thread was running
 | ||||
|  | @ -236,7 +225,7 @@ namespace MWPhysics | |||
| 
 | ||||
|                 updateMechanics(data); | ||||
|                 if (mAdvanceSimulation) | ||||
|                     updateStandingCollision(data, standingCollisions); | ||||
|                     data.mActorRaw->setStandingOnPtr(data.mStandingOn); | ||||
| 
 | ||||
|                 if (mMovementResults.find(data.mPtr) != mMovementResults.end()) | ||||
|                     data.mActorRaw->setNextPosition(mMovementResults[data.mPtr]); | ||||
|  | @ -260,10 +249,10 @@ namespace MWPhysics | |||
|         // just return the actors' reference position without applying the movements
 | ||||
|         if (skipSimulation) | ||||
|         { | ||||
|             standingCollisions.clear(); | ||||
|             mMovementResults.clear(); | ||||
|             for (const auto& m : mActorsFrameData) | ||||
|             { | ||||
|                 m.mActorRaw->setStandingOnPtr(nullptr); | ||||
|                 m.mActorRaw->setPosition(m.mActorRaw->getWorldPosition(), true); | ||||
|                 mMovementResults[m.mPtr] = m.mActorRaw->getWorldPosition(); | ||||
|             } | ||||
|  | @ -275,14 +264,10 @@ namespace MWPhysics | |||
|             mMovementResults.clear(); | ||||
|             syncComputation(); | ||||
| 
 | ||||
|             if (mAdvanceSimulation) | ||||
|             { | ||||
|                 standingCollisions.clear(); | ||||
|                 for (auto& data : mActorsFrameData) | ||||
|                     updateStandingCollision(data, standingCollisions); | ||||
|             } | ||||
|             for (auto& data : mActorsFrameData) | ||||
|             { | ||||
|                 if (mAdvanceSimulation) | ||||
|                     data.mActorRaw->setStandingOnPtr(data.mStandingOn); | ||||
|                 if (mMovementResults.find(data.mPtr) != mMovementResults.end()) | ||||
|                     data.mActorRaw->setNextPosition(mMovementResults[data.mPtr]); | ||||
|             } | ||||
|  |  | |||
|  | @ -30,7 +30,7 @@ namespace MWPhysics | |||
|             /// @param timeAccum accumulated time from previous run to interpolate movements
 | ||||
|             /// @param actorsData per actor data needed to compute new positions
 | ||||
|             /// @return new position of each actor
 | ||||
|             const PtrPositionList& moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& actorsData, CollisionMap& standingCollisions, bool skip); | ||||
|             const PtrPositionList& moveActors(int numSteps, float timeAccum, std::vector<ActorFrameData>&& actorsData, bool skip); | ||||
| 
 | ||||
|             // Thread safe wrappers
 | ||||
|             void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const; | ||||
|  |  | |||
|  | @ -148,11 +148,11 @@ namespace MWPhysics | |||
|         if (!physactor || !physactor->getOnGround()) | ||||
|             return false; | ||||
| 
 | ||||
|         CollisionMap::const_iterator found = mStandingCollisions.find(actor); | ||||
|         if (found == mStandingCollisions.end()) | ||||
|         const auto obj = physactor->getStandingOnPtr(); | ||||
|         if (obj.isEmpty()) | ||||
|             return true; // assume standing on terrain (which is a non-object, so not collision tracked)
 | ||||
| 
 | ||||
|         ObjectMap::const_iterator foundObj = mObjects.find(found->second); | ||||
|         ObjectMap::const_iterator foundObj = mObjects.find(obj); | ||||
|         if (foundObj == mObjects.end()) | ||||
|             return false; | ||||
| 
 | ||||
|  | @ -501,22 +501,6 @@ 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 (auto& collision : map) | ||||
|         { | ||||
|             if (collision.second == old) | ||||
|                 collision.second = updated; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void PhysicsSystem::updatePtr(const MWWorld::Ptr &old, const MWWorld::Ptr &updated) | ||||
|     { | ||||
|         ObjectMap::iterator found = mObjects.find(old); | ||||
|  | @ -537,7 +521,11 @@ namespace MWPhysics | |||
|             mActors.emplace(updated, std::move(actor)); | ||||
|         } | ||||
| 
 | ||||
|         updateCollisionMapPtr(mStandingCollisions, old, updated); | ||||
|         for (auto& [_, actor] : mActors) | ||||
|         { | ||||
|             if (actor->getStandingOnPtr() == old) | ||||
|                 actor->setStandingOnPtr(updated); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     Actor *PhysicsSystem::getActor(const MWWorld::Ptr &ptr) | ||||
|  | @ -675,7 +663,6 @@ namespace MWPhysics | |||
|     void PhysicsSystem::clearQueuedMovement() | ||||
|     { | ||||
|         mMovementQueue.clear(); | ||||
|         mStandingCollisions.clear(); | ||||
|     } | ||||
| 
 | ||||
|     const PtrPositionList& PhysicsSystem::applyQueuedMovement(float dt, bool skipSimulation) | ||||
|  | @ -688,7 +675,7 @@ namespace MWPhysics | |||
| 
 | ||||
|         mTimeAccum -= numSteps * mPhysicsDt; | ||||
| 
 | ||||
|         return mTaskScheduler->moveActors(numSteps, mTimeAccum, prepareFrameData(numSteps), mStandingCollisions, skipSimulation); | ||||
|         return mTaskScheduler->moveActors(numSteps, mTimeAccum, prepareFrameData(numSteps), skipSimulation); | ||||
|     } | ||||
| 
 | ||||
|     std::vector<ActorFrameData> PhysicsSystem::prepareFrameData(int numSteps) | ||||
|  | @ -700,10 +687,8 @@ namespace MWPhysics | |||
|         { | ||||
|             const auto foundActor = mActors.find(character); | ||||
|             if (foundActor == mActors.end()) // actor was already removed from the scene
 | ||||
|             { | ||||
|                 mStandingCollisions.erase(character); | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             auto physicActor = foundActor->second; | ||||
| 
 | ||||
|             float waterlevel = -std::numeric_limits<float>::max(); | ||||
|  | @ -734,7 +719,7 @@ namespace MWPhysics | |||
|             // Ue current value only if we don't advance the simulation. Otherwise we might get a stale value.
 | ||||
|             MWWorld::Ptr standingOn; | ||||
|             if (numSteps == 0) | ||||
|                 standingOn = mStandingCollisions[character]; | ||||
|                 standingOn = physicActor->getStandingOnPtr(); | ||||
| 
 | ||||
|             actorsFrameData.emplace_back(std::move(physicActor), character, standingOn, moveToWaterSurface, movement, slowFall, waterlevel); | ||||
|         } | ||||
|  | @ -774,20 +759,18 @@ namespace MWPhysics | |||
| 
 | ||||
|     bool PhysicsSystem::isActorStandingOn(const MWWorld::Ptr &actor, const MWWorld::ConstPtr &object) const | ||||
|     { | ||||
|         for (const auto& standingActor : mStandingCollisions) | ||||
|         { | ||||
|             if (standingActor.first == actor && standingActor.second == object) | ||||
|                 return true; | ||||
|         } | ||||
|         const auto physActor = mActors.find(actor); | ||||
|         if (physActor != mActors.end()) | ||||
|             return physActor->second->getStandingOnPtr() == object; | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     void PhysicsSystem::getActorsStandingOn(const MWWorld::ConstPtr &object, std::vector<MWWorld::Ptr> &out) const | ||||
|     { | ||||
|         for (const auto& standingActor : mStandingCollisions) | ||||
|         for (const auto& [_, actor] : mActors) | ||||
|         { | ||||
|             if (standingActor.second == object) | ||||
|                 out.push_back(standingActor.first); | ||||
|             if (actor->getStandingOnPtr() == object) | ||||
|                 out.emplace_back(actor->getPtr()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -50,7 +50,6 @@ class btVector3; | |||
| namespace MWPhysics | ||||
| { | ||||
|     using PtrPositionList = std::map<MWWorld::Ptr, osg::Vec3f>; | ||||
|     using CollisionMap = std::map<MWWorld::Ptr, MWWorld::Ptr>; | ||||
| 
 | ||||
|     class HeightField; | ||||
|     class Object; | ||||
|  | @ -272,13 +271,6 @@ namespace MWPhysics | |||
| 
 | ||||
|             bool mDebugDrawEnabled; | ||||
| 
 | ||||
|             // 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.
 | ||||
|             CollisionMap mStandingCollisions; | ||||
| 
 | ||||
|             // replaces all occurrences of 'old' in the map by 'updated', no matter if it's a key or value
 | ||||
|             void updateCollisionMapPtr(CollisionMap& map, const MWWorld::Ptr &old, const MWWorld::Ptr &updated); | ||||
| 
 | ||||
|             using PtrVelocityList = std::vector<std::pair<MWWorld::Ptr, osg::Vec3f>>; | ||||
|             PtrVelocityList mMovementQueue; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue