From ae909d7685febf8ecee6ac3ed823f19a3bcf4073 Mon Sep 17 00:00:00 2001 From: elsid Date: Sat, 12 Apr 2025 12:54:07 +0200 Subject: [PATCH] Remove isAreaOccupiedByOtherActor from obstacle.* It uses functions only from World anyway. --- apps/openmw/mwbase/world.hpp | 3 +-- apps/openmw/mwmechanics/aiwander.cpp | 16 +++++++------ apps/openmw/mwmechanics/obstacle.cpp | 9 -------- apps/openmw/mwmechanics/obstacle.hpp | 2 -- .../mwphysics/hasspherecollisioncallback.hpp | 9 ++++---- apps/openmw/mwphysics/physicssystem.cpp | 23 +++++++------------ apps/openmw/mwphysics/physicssystem.hpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 7 +++--- apps/openmw/mwworld/worldimp.hpp | 3 +-- 9 files changed, 28 insertions(+), 46 deletions(-) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 9016e23c0e..fea90171ed 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -574,8 +574,7 @@ namespace MWBase virtual bool hasCollisionWithDoor( const MWWorld::ConstPtr& door, const osg::Vec3f& position, const osg::Vec3f& destination) const = 0; - virtual bool isAreaOccupiedByOtherActor( - const osg::Vec3f& position, float radius, std::span ignore) const = 0; + virtual bool isAreaOccupiedByOtherActor(const MWWorld::ConstPtr& actor, const osg::Vec3f& position) const = 0; virtual void reportStats(unsigned int frameNumber, osg::Stats& stats) const = 0; diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 3dacbd167e..5112979c88 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -279,7 +279,9 @@ namespace MWMechanics getAllowedNodes(actor, storage); } - auto& prng = MWBase::Environment::get().getWorld()->getPrng(); + MWBase::World& world = *MWBase::Environment::get().getWorld(); + + auto& prng = world.getPrng(); if (canActorMoveByZAxis(actor) && mDistance > 0) { // Typically want to idle for a short time before the next wander @@ -333,7 +335,7 @@ namespace MWMechanics if (storage.mIsWanderingManually && storage.mState == AiWanderStorage::Wander_Walking && (mPathFinder.getPathSize() == 0 || isDestinationHidden(actor, mPathFinder.getPath().back()) - || isAreaOccupiedByOtherActor(actor, mPathFinder.getPath().back()))) + || world.isAreaOccupiedByOtherActor(actor, mPathFinder.getPath().back()))) completeManualWalking(actor, storage); return false; // AiWander package not yet completed @@ -363,12 +365,12 @@ namespace MWMechanics std::size_t attempts = 10; // If a unit can't wander out of water, don't want to hang here const bool isWaterCreature = actor.getClass().isPureWaterCreature(actor); const bool isFlyingCreature = actor.getClass().isPureFlyingCreature(actor); - const auto world = MWBase::Environment::get().getWorld(); - const auto agentBounds = world->getPathfindingAgentBounds(actor); - const auto navigator = world->getNavigator(); + MWBase::World& world = *MWBase::Environment::get().getWorld(); + const auto agentBounds = world.getPathfindingAgentBounds(actor); + const auto navigator = world.getNavigator(); const DetourNavigator::Flags navigatorFlags = getNavigatorFlags(actor); const DetourNavigator::AreaCosts areaCosts = getAreaCosts(actor, navigatorFlags); - auto& prng = MWBase::Environment::get().getWorld()->getPrng(); + Misc::Rng::Generator& prng = world.getPrng(); do { @@ -408,7 +410,7 @@ namespace MWMechanics if (isDestinationHidden(actor, mDestination)) continue; - if (isAreaOccupiedByOtherActor(actor, mDestination)) + if (world.isAreaOccupiedByOtherActor(actor, mDestination)) continue; constexpr float endTolerance = 0; diff --git a/apps/openmw/mwmechanics/obstacle.cpp b/apps/openmw/mwmechanics/obstacle.cpp index 1112bc49d6..9a66eafb51 100644 --- a/apps/openmw/mwmechanics/obstacle.cpp +++ b/apps/openmw/mwmechanics/obstacle.cpp @@ -106,15 +106,6 @@ namespace MWMechanics return visitor.mResult; } - bool isAreaOccupiedByOtherActor(const MWWorld::ConstPtr& actor, const osg::Vec3f& destination) - { - const auto world = MWBase::Environment::get().getWorld(); - const osg::Vec3f halfExtents = world->getPathfindingAgentBounds(actor).mHalfExtents; - const auto maxHalfExtent = std::max(halfExtents.x(), std::max(halfExtents.y(), halfExtents.z())); - const std::array ignore{ actor }; - return world->isAreaOccupiedByOtherActor(destination, 2 * maxHalfExtent, ignore); - } - ObstacleCheck::ObstacleCheck() : mEvadeDirectionIndex(std::size(evadeDirections) - 1) { diff --git a/apps/openmw/mwmechanics/obstacle.hpp b/apps/openmw/mwmechanics/obstacle.hpp index f3214210b5..a1c973765f 100644 --- a/apps/openmw/mwmechanics/obstacle.hpp +++ b/apps/openmw/mwmechanics/obstacle.hpp @@ -22,8 +22,6 @@ namespace MWMechanics /** \return Pointer to the door, or empty pointer if none exists **/ const MWWorld::Ptr getNearbyDoor(const MWWorld::Ptr& actor, float minDist); - bool isAreaOccupiedByOtherActor(const MWWorld::ConstPtr& actor, const osg::Vec3f& destination); - class ObstacleCheck { public: diff --git a/apps/openmw/mwphysics/hasspherecollisioncallback.hpp b/apps/openmw/mwphysics/hasspherecollisioncallback.hpp index a6563c731a..6270cd3083 100644 --- a/apps/openmw/mwphysics/hasspherecollisioncallback.hpp +++ b/apps/openmw/mwphysics/hasspherecollisioncallback.hpp @@ -18,12 +18,11 @@ namespace MWPhysics return nearest.distance(position) < radius; } - template class HasSphereCollisionCallback final : public btBroadphaseAabbCallback { public: - explicit HasSphereCollisionCallback( - const btVector3& position, const btScalar radius, const int mask, const int group, const Ignore& ignore) + explicit HasSphereCollisionCallback(const btVector3& position, const btScalar radius, const int mask, + const int group, const btCollisionObject* ignore) : mPosition(position) , mRadius(radius) , mIgnore(ignore) @@ -37,7 +36,7 @@ namespace MWPhysics if (mResult) return false; const auto collisionObject = static_cast(proxy->m_clientObject); - if (mIgnore(collisionObject) || !needsCollision(*proxy) + if (mIgnore == collisionObject || !needsCollision(*proxy) || !testAabbAgainstSphere(proxy->m_aabbMin, proxy->m_aabbMax, mPosition, mRadius)) return true; mResult = true; @@ -49,7 +48,7 @@ namespace MWPhysics private: btVector3 mPosition; btScalar mRadius; - Ignore mIgnore; + const btCollisionObject* mIgnore; int mCollisionFilterMask; int mCollisionFilterGroup; bool mResult = false; diff --git a/apps/openmw/mwphysics/physicssystem.cpp b/apps/openmw/mwphysics/physicssystem.cpp index 55a0453bf8..f403f97c2f 100644 --- a/apps/openmw/mwphysics/physicssystem.cpp +++ b/apps/openmw/mwphysics/physicssystem.cpp @@ -850,24 +850,17 @@ namespace MWPhysics } bool PhysicsSystem::isAreaOccupiedByOtherActor( - const osg::Vec3f& position, const float radius, std::span ignore) const + const MWWorld::LiveCellRefBase* actor, const osg::Vec3f& position, const float radius) const { - std::vector ignoredObjects; - ignoredObjects.reserve(ignore.size()); - for (const auto& v : ignore) - if (const auto it = mActors.find(v.mRef); it != mActors.end()) - ignoredObjects.push_back(it->second->getCollisionObject()); - std::sort(ignoredObjects.begin(), ignoredObjects.end()); - ignoredObjects.erase(std::unique(ignoredObjects.begin(), ignoredObjects.end()), ignoredObjects.end()); - const auto ignoreFilter = [&](const btCollisionObject* v) { - return std::binary_search(ignoredObjects.begin(), ignoredObjects.end(), v); - }; - const auto bulletPosition = Misc::Convert::toBullet(position); - const auto aabbMin = bulletPosition - btVector3(radius, radius, radius); - const auto aabbMax = bulletPosition + btVector3(radius, radius, radius); + const btCollisionObject* ignoredObject = nullptr; + if (const auto it = mActors.find(actor); it != mActors.end()) + ignoredObject = it->second->getCollisionObject(); + const btVector3 bulletPosition = Misc::Convert::toBullet(position); + const btVector3 aabbMin = bulletPosition - btVector3(radius, radius, radius); + const btVector3 aabbMax = bulletPosition + btVector3(radius, radius, radius); const int mask = MWPhysics::CollisionType_Actor; const int group = MWPhysics::CollisionType_AnyPhysical; - HasSphereCollisionCallback callback(bulletPosition, radius, mask, group, ignoreFilter); + HasSphereCollisionCallback callback(bulletPosition, radius, mask, group, ignoredObject); mTaskScheduler->aabbTest(aabbMin, aabbMax, callback); return callback.getResult(); } diff --git a/apps/openmw/mwphysics/physicssystem.hpp b/apps/openmw/mwphysics/physicssystem.hpp index 92b37e105a..8a845b4c41 100644 --- a/apps/openmw/mwphysics/physicssystem.hpp +++ b/apps/openmw/mwphysics/physicssystem.hpp @@ -282,7 +282,7 @@ namespace MWPhysics } bool isAreaOccupiedByOtherActor( - const osg::Vec3f& position, float radius, std::span ignore) const; + const MWWorld::LiveCellRefBase* actor, const osg::Vec3f& position, float radius) const; void reportStats(unsigned int frameNumber, osg::Stats& stats) const; void reportCollision(const btVector3& position, const btVector3& normal); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 099c6e403a..c8564a07b5 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -3832,10 +3832,11 @@ namespace MWWorld return btRayAabb(localFrom, localTo, aabbMin, aabbMax, hitDistance, hitNormal); } - bool World::isAreaOccupiedByOtherActor( - const osg::Vec3f& position, const float radius, std::span ignore) const + bool World::isAreaOccupiedByOtherActor(const MWWorld::ConstPtr& actor, const osg::Vec3f& position) const { - return mPhysics->isAreaOccupiedByOtherActor(position, radius, ignore); + const osg::Vec3f halfExtents = getPathfindingAgentBounds(actor).mHalfExtents; + const float maxHalfExtent = std::max(halfExtents.x(), std::max(halfExtents.y(), halfExtents.z())); + return mPhysics->isAreaOccupiedByOtherActor(actor.mRef, position, 2 * maxHalfExtent); } void World::reportStats(unsigned int frameNumber, osg::Stats& stats) const diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index cce9d45e55..ac5e315a58 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -656,8 +656,7 @@ namespace MWWorld bool hasCollisionWithDoor( const MWWorld::ConstPtr& door, const osg::Vec3f& position, const osg::Vec3f& destination) const override; - bool isAreaOccupiedByOtherActor( - const osg::Vec3f& position, float radius, std::span ignore) const override; + bool isAreaOccupiedByOtherActor(const MWWorld::ConstPtr& actor, const osg::Vec3f& position) const override; void reportStats(unsigned int frameNumber, osg::Stats& stats) const override;