diff --git a/apps/openmw/mwmechanics/aicombat.cpp b/apps/openmw/mwmechanics/aicombat.cpp index 499bc56fc5..b28d00fdd0 100644 --- a/apps/openmw/mwmechanics/aicombat.cpp +++ b/apps/openmw/mwmechanics/aicombat.cpp @@ -283,7 +283,8 @@ namespace MWMechanics const auto agentBounds = world->getPathfindingAgentBounds(actor); const auto navigatorFlags = getNavigatorFlags(actor); const auto areaCosts = getAreaCosts(actor); - const auto pathGridGraph = getPathGridGraph(actor.getCell()); + const ESM::Pathgrid* pathgrid = world->getStore().get().search(*actor.getCell()->getCell()); + const auto& pathGridGraph = getPathGridGraph(pathgrid); mPathFinder.buildPath(actor, vActorPos, vTargetPos, actor.getCell(), pathGridGraph, agentBounds, navigatorFlags, areaCosts, storage.mAttackRange, PathType::Full); @@ -378,7 +379,7 @@ namespace MWMechanics for (int i = 0; i < static_cast(pathgrid->mPoints.size()); i++) { if (i != closestPointIndex - && getPathGridGraph(storage.mCell).isPointConnected(closestPointIndex, i)) + && getPathGridGraph(pathgrid).isPointConnected(closestPointIndex, i)) { points.push_back(pathgrid->mPoints[static_cast(i)]); } diff --git a/apps/openmw/mwmechanics/aipackage.cpp b/apps/openmw/mwmechanics/aipackage.cpp index 1fe3bcae15..288ba195f2 100644 --- a/apps/openmw/mwmechanics/aipackage.cpp +++ b/apps/openmw/mwmechanics/aipackage.cpp @@ -154,7 +154,9 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f& { if (wasShortcutting || doesPathNeedRecalc(dest, actor)) // if need to rebuild path { - mPathFinder.buildLimitedPath(actor, position, dest, actor.getCell(), getPathGridGraph(actor.getCell()), + const ESM::Pathgrid* pathgrid + = world->getStore().get().search(*actor.getCell()->getCell()); + mPathFinder.buildLimitedPath(actor, position, dest, actor.getCell(), getPathGridGraph(pathgrid), agentBounds, getNavigatorFlags(actor), getAreaCosts(actor), endTolerance, pathType); mRotateOnTheRunChecks = 3; @@ -329,26 +331,16 @@ void MWMechanics::AiPackage::openDoors(const MWWorld::Ptr& actor) } } -const MWMechanics::PathgridGraph& MWMechanics::AiPackage::getPathGridGraph(const MWWorld::CellStore* cell) const +const MWMechanics::PathgridGraph& MWMechanics::AiPackage::getPathGridGraph(const ESM::Pathgrid* pathgrid) const { - const ESM::RefId id = cell->getCell()->getId(); + if (!pathgrid || pathgrid->mPoints.empty()) + return PathgridGraph::sEmpty; // static cache is OK for now, pathgrids can never change during runtime - typedef std::map> CacheMap; - static CacheMap cache; - CacheMap::iterator found = cache.find(id); + static std::map> cache; + auto found = cache.find(pathgrid); if (found == cache.end()) - { - const ESM::Pathgrid* pathgrid - = MWBase::Environment::get().getWorld()->getStore().get().search(*cell->getCell()); - std::unique_ptr ptr; - if (pathgrid) - ptr = std::make_unique(MWMechanics::PathgridGraph(*pathgrid)); - found = cache.emplace(id, std::move(ptr)).first; - } - const MWMechanics::PathgridGraph* graph = found->second.get(); - if (!graph) - return MWMechanics::PathgridGraph::sEmpty; - return *graph; + found = cache.emplace(pathgrid, std::make_unique(*pathgrid)).first; + return *found->second.get(); } bool MWMechanics::AiPackage::shortcutPath(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, diff --git a/apps/openmw/mwmechanics/aipackage.hpp b/apps/openmw/mwmechanics/aipackage.hpp index 3914ce2d3f..c7be6f5dc7 100644 --- a/apps/openmw/mwmechanics/aipackage.hpp +++ b/apps/openmw/mwmechanics/aipackage.hpp @@ -145,7 +145,7 @@ namespace MWMechanics void openDoors(const MWWorld::Ptr& actor); - const PathgridGraph& getPathGridGraph(const MWWorld::CellStore* cell) const; + const PathgridGraph& getPathGridGraph(const ESM::Pathgrid* pathgrid) const; DetourNavigator::Flags getNavigatorFlags(const MWWorld::Ptr& actor) const; diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index b47e04da89..9d8d23a08d 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -210,18 +210,20 @@ namespace MWMechanics // rebuild a path to it if (!mPathFinder.isPathConstructed() && mHasDestination) { + const ESM::Pathgrid* pathgrid + = MWBase::Environment::get().getWorld()->getStore().get().search( + *actor.getCell()->getCell()); if (mUsePathgrid) { mPathFinder.buildPathByPathgrid( - pos.asVec3(), mDestination, actor.getCell(), getPathGridGraph(actor.getCell())); + pos.asVec3(), mDestination, actor.getCell(), getPathGridGraph(pathgrid)); } else { const auto agentBounds = MWBase::Environment::get().getWorld()->getPathfindingAgentBounds(actor); constexpr float endTolerance = 0; - mPathFinder.buildPath(actor, pos.asVec3(), mDestination, actor.getCell(), - getPathGridGraph(actor.getCell()), agentBounds, getNavigatorFlags(actor), getAreaCosts(actor), - endTolerance, PathType::Full); + mPathFinder.buildPath(actor, pos.asVec3(), mDestination, actor.getCell(), getPathGridGraph(pathgrid), + agentBounds, getNavigatorFlags(actor), getAreaCosts(actor), endTolerance, PathType::Full); } if (mPathFinder.isPathConstructed()) @@ -597,15 +599,17 @@ namespace MWMechanics void AiWander::setPathToAnAllowedNode( const MWWorld::Ptr& actor, AiWanderStorage& storage, const ESM::Position& actorPos) { - auto& prng = MWBase::Environment::get().getWorld()->getPrng(); + auto world = MWBase::Environment::get().getWorld(); + auto& prng = world->getPrng(); unsigned int randNode = Misc::Rng::rollDice(storage.mAllowedNodes.size(), prng); const ESM::Pathgrid::Point& dest = storage.mAllowedNodes[randNode]; const osg::Vec3f start = actorPos.asVec3(); // don't take shortcuts for wandering + const ESM::Pathgrid* pathgrid = world->getStore().get().search(*actor.getCell()->getCell()); const osg::Vec3f destVec3f = PathFinder::makeOsgVec3(dest); - mPathFinder.buildPathByPathgrid(start, destVec3f, actor.getCell(), getPathGridGraph(actor.getCell())); + mPathFinder.buildPathByPathgrid(start, destVec3f, actor.getCell(), getPathGridGraph(pathgrid)); if (mPathFinder.isPathConstructed()) { @@ -808,7 +812,7 @@ namespace MWMechanics int index = PathFinder::getClosestPoint(pathgrid, PathFinder::makeOsgVec3(dest)); - getPathGridGraph(currentCell).getNeighbouringPoints(index, points); + getPathGridGraph(pathgrid).getNeighbouringPoints(index, points); } void AiWander::getAllowedNodes(const MWWorld::Ptr& actor, AiWanderStorage& storage) @@ -849,7 +853,7 @@ namespace MWMechanics { osg::Vec3f nodePos(PathFinder::makeOsgVec3(pathgrid->mPoints[counter])); if ((npcPos - nodePos).length2() <= mDistance * mDistance - && getPathGridGraph(cellStore).isPointConnected(closestPointIndex, counter)) + && getPathGridGraph(pathgrid).isPointConnected(closestPointIndex, counter)) { storage.mAllowedNodes.push_back(converter.toWorldPoint(pathgrid->mPoints[counter])); pointIndex = counter; diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index 5b80d90af6..cb1bd46d4b 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -36,7 +36,7 @@ namespace int closestReachableIndex = 0; // TODO: if this full scan causes performance problems mapping pathgrid // points to a quadtree may help - for (unsigned int counter = 0; counter < grid->mPoints.size(); counter++) + for (size_t counter = 0; counter < grid->mPoints.size(); counter++) { float potentialDistBetween = MWMechanics::PathFinder::distanceSquared(grid->mPoints[counter], pos); if (potentialDistBetween < closestDistanceReachable)