mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-20 15:40:32 +00:00
Decouple PathgridGraph generation from cell
This commit is contained in:
parent
cf9d2e0d89
commit
584f112a7b
@ -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<ESM::Pathgrid>().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<int>(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<size_t>(i)]);
|
||||
}
|
||||
|
@ -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<ESM::Pathgrid>().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<ESM::RefId, std::unique_ptr<MWMechanics::PathgridGraph>> CacheMap;
|
||||
static CacheMap cache;
|
||||
CacheMap::iterator found = cache.find(id);
|
||||
static std::map<const ESM::Pathgrid*, std::unique_ptr<MWMechanics::PathgridGraph>> cache;
|
||||
auto found = cache.find(pathgrid);
|
||||
if (found == cache.end())
|
||||
{
|
||||
const ESM::Pathgrid* pathgrid
|
||||
= MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*cell->getCell());
|
||||
std::unique_ptr<MWMechanics::PathgridGraph> ptr;
|
||||
if (pathgrid)
|
||||
ptr = std::make_unique<MWMechanics::PathgridGraph>(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<MWMechanics::PathgridGraph>(*pathgrid)).first;
|
||||
return *found->second.get();
|
||||
}
|
||||
|
||||
bool MWMechanics::AiPackage::shortcutPath(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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<ESM::Pathgrid>().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<ESM::Pathgrid>().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;
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user