Remove isAreaOccupiedByOtherActor from obstacle.*

It uses functions only from World anyway.
This commit is contained in:
elsid 2025-04-12 12:54:07 +02:00
parent c79b39cf0d
commit ae909d7685
No known key found for this signature in database
GPG Key ID: B845CB9FEE18AB40
9 changed files with 28 additions and 46 deletions

View File

@ -574,8 +574,7 @@ namespace MWBase
virtual bool hasCollisionWithDoor( virtual bool hasCollisionWithDoor(
const MWWorld::ConstPtr& door, const osg::Vec3f& position, const osg::Vec3f& destination) const = 0; const MWWorld::ConstPtr& door, const osg::Vec3f& position, const osg::Vec3f& destination) const = 0;
virtual bool isAreaOccupiedByOtherActor( virtual bool isAreaOccupiedByOtherActor(const MWWorld::ConstPtr& actor, const osg::Vec3f& position) const = 0;
const osg::Vec3f& position, float radius, std::span<const MWWorld::ConstPtr> ignore) const = 0;
virtual void reportStats(unsigned int frameNumber, osg::Stats& stats) const = 0; virtual void reportStats(unsigned int frameNumber, osg::Stats& stats) const = 0;

View File

@ -279,7 +279,9 @@ namespace MWMechanics
getAllowedNodes(actor, storage); 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) if (canActorMoveByZAxis(actor) && mDistance > 0)
{ {
// Typically want to idle for a short time before the next wander // 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 if (storage.mIsWanderingManually && storage.mState == AiWanderStorage::Wander_Walking
&& (mPathFinder.getPathSize() == 0 || isDestinationHidden(actor, mPathFinder.getPath().back()) && (mPathFinder.getPathSize() == 0 || isDestinationHidden(actor, mPathFinder.getPath().back())
|| isAreaOccupiedByOtherActor(actor, mPathFinder.getPath().back()))) || world.isAreaOccupiedByOtherActor(actor, mPathFinder.getPath().back())))
completeManualWalking(actor, storage); completeManualWalking(actor, storage);
return false; // AiWander package not yet completed 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 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 isWaterCreature = actor.getClass().isPureWaterCreature(actor);
const bool isFlyingCreature = actor.getClass().isPureFlyingCreature(actor); const bool isFlyingCreature = actor.getClass().isPureFlyingCreature(actor);
const auto world = MWBase::Environment::get().getWorld(); MWBase::World& world = *MWBase::Environment::get().getWorld();
const auto agentBounds = world->getPathfindingAgentBounds(actor); const auto agentBounds = world.getPathfindingAgentBounds(actor);
const auto navigator = world->getNavigator(); const auto navigator = world.getNavigator();
const DetourNavigator::Flags navigatorFlags = getNavigatorFlags(actor); const DetourNavigator::Flags navigatorFlags = getNavigatorFlags(actor);
const DetourNavigator::AreaCosts areaCosts = getAreaCosts(actor, navigatorFlags); const DetourNavigator::AreaCosts areaCosts = getAreaCosts(actor, navigatorFlags);
auto& prng = MWBase::Environment::get().getWorld()->getPrng(); Misc::Rng::Generator& prng = world.getPrng();
do do
{ {
@ -408,7 +410,7 @@ namespace MWMechanics
if (isDestinationHidden(actor, mDestination)) if (isDestinationHidden(actor, mDestination))
continue; continue;
if (isAreaOccupiedByOtherActor(actor, mDestination)) if (world.isAreaOccupiedByOtherActor(actor, mDestination))
continue; continue;
constexpr float endTolerance = 0; constexpr float endTolerance = 0;

View File

@ -106,15 +106,6 @@ namespace MWMechanics
return visitor.mResult; 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() ObstacleCheck::ObstacleCheck()
: mEvadeDirectionIndex(std::size(evadeDirections) - 1) : mEvadeDirectionIndex(std::size(evadeDirections) - 1)
{ {

View File

@ -22,8 +22,6 @@ namespace MWMechanics
/** \return Pointer to the door, or empty pointer if none exists **/ /** \return Pointer to the door, or empty pointer if none exists **/
const MWWorld::Ptr getNearbyDoor(const MWWorld::Ptr& actor, float minDist); const MWWorld::Ptr getNearbyDoor(const MWWorld::Ptr& actor, float minDist);
bool isAreaOccupiedByOtherActor(const MWWorld::ConstPtr& actor, const osg::Vec3f& destination);
class ObstacleCheck class ObstacleCheck
{ {
public: public:

View File

@ -18,12 +18,11 @@ namespace MWPhysics
return nearest.distance(position) < radius; return nearest.distance(position) < radius;
} }
template <class Ignore>
class HasSphereCollisionCallback final : public btBroadphaseAabbCallback class HasSphereCollisionCallback final : public btBroadphaseAabbCallback
{ {
public: public:
explicit HasSphereCollisionCallback( explicit HasSphereCollisionCallback(const btVector3& position, const btScalar radius, const int mask,
const btVector3& position, const btScalar radius, const int mask, const int group, const Ignore& ignore) const int group, const btCollisionObject* ignore)
: mPosition(position) : mPosition(position)
, mRadius(radius) , mRadius(radius)
, mIgnore(ignore) , mIgnore(ignore)
@ -37,7 +36,7 @@ namespace MWPhysics
if (mResult) if (mResult)
return false; return false;
const auto collisionObject = static_cast<btCollisionObject*>(proxy->m_clientObject); const auto collisionObject = static_cast<btCollisionObject*>(proxy->m_clientObject);
if (mIgnore(collisionObject) || !needsCollision(*proxy) if (mIgnore == collisionObject || !needsCollision(*proxy)
|| !testAabbAgainstSphere(proxy->m_aabbMin, proxy->m_aabbMax, mPosition, mRadius)) || !testAabbAgainstSphere(proxy->m_aabbMin, proxy->m_aabbMax, mPosition, mRadius))
return true; return true;
mResult = true; mResult = true;
@ -49,7 +48,7 @@ namespace MWPhysics
private: private:
btVector3 mPosition; btVector3 mPosition;
btScalar mRadius; btScalar mRadius;
Ignore mIgnore; const btCollisionObject* mIgnore;
int mCollisionFilterMask; int mCollisionFilterMask;
int mCollisionFilterGroup; int mCollisionFilterGroup;
bool mResult = false; bool mResult = false;

View File

@ -850,24 +850,17 @@ namespace MWPhysics
} }
bool PhysicsSystem::isAreaOccupiedByOtherActor( bool PhysicsSystem::isAreaOccupiedByOtherActor(
const osg::Vec3f& position, const float radius, std::span<const MWWorld::ConstPtr> ignore) const const MWWorld::LiveCellRefBase* actor, const osg::Vec3f& position, const float radius) const
{ {
std::vector<const btCollisionObject*> ignoredObjects; const btCollisionObject* ignoredObject = nullptr;
ignoredObjects.reserve(ignore.size()); if (const auto it = mActors.find(actor); it != mActors.end())
for (const auto& v : ignore) ignoredObject = it->second->getCollisionObject();
if (const auto it = mActors.find(v.mRef); it != mActors.end()) const btVector3 bulletPosition = Misc::Convert::toBullet(position);
ignoredObjects.push_back(it->second->getCollisionObject()); const btVector3 aabbMin = bulletPosition - btVector3(radius, radius, radius);
std::sort(ignoredObjects.begin(), ignoredObjects.end()); const btVector3 aabbMax = bulletPosition + btVector3(radius, radius, radius);
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 int mask = MWPhysics::CollisionType_Actor; const int mask = MWPhysics::CollisionType_Actor;
const int group = MWPhysics::CollisionType_AnyPhysical; 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); mTaskScheduler->aabbTest(aabbMin, aabbMax, callback);
return callback.getResult(); return callback.getResult();
} }

View File

@ -282,7 +282,7 @@ namespace MWPhysics
} }
bool isAreaOccupiedByOtherActor( bool isAreaOccupiedByOtherActor(
const osg::Vec3f& position, float radius, std::span<const MWWorld::ConstPtr> ignore) const; const MWWorld::LiveCellRefBase* actor, const osg::Vec3f& position, float radius) const;
void reportStats(unsigned int frameNumber, osg::Stats& stats) const; void reportStats(unsigned int frameNumber, osg::Stats& stats) const;
void reportCollision(const btVector3& position, const btVector3& normal); void reportCollision(const btVector3& position, const btVector3& normal);

View File

@ -3832,10 +3832,11 @@ namespace MWWorld
return btRayAabb(localFrom, localTo, aabbMin, aabbMax, hitDistance, hitNormal); return btRayAabb(localFrom, localTo, aabbMin, aabbMax, hitDistance, hitNormal);
} }
bool World::isAreaOccupiedByOtherActor( bool World::isAreaOccupiedByOtherActor(const MWWorld::ConstPtr& actor, const osg::Vec3f& position) const
const osg::Vec3f& position, const float radius, std::span<const MWWorld::ConstPtr> ignore) 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 void World::reportStats(unsigned int frameNumber, osg::Stats& stats) const

View File

@ -656,8 +656,7 @@ namespace MWWorld
bool hasCollisionWithDoor( bool hasCollisionWithDoor(
const MWWorld::ConstPtr& door, const osg::Vec3f& position, const osg::Vec3f& destination) const override; const MWWorld::ConstPtr& door, const osg::Vec3f& position, const osg::Vec3f& destination) const override;
bool isAreaOccupiedByOtherActor( bool isAreaOccupiedByOtherActor(const MWWorld::ConstPtr& actor, const osg::Vec3f& position) const override;
const osg::Vec3f& position, float radius, std::span<const MWWorld::ConstPtr> ignore) const override;
void reportStats(unsigned int frameNumber, osg::Stats& stats) const override; void reportStats(unsigned int frameNumber, osg::Stats& stats) const override;