1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2024-12-29 03:19:44 +00:00

Build limited path for far destinations

When distance between start and end point is greater than max radius of area
possibly covered by navmesh there is no way to find path via navmesh. Also if
distance is greater than cell size navmesh might not exists withing mentioned
area because cell is not loaded therefore navmesh is not generated. So minumum
of these values is used to limit max path distance. Assuming that path
actually exists it's possible to build path to the edge of a circle. When
actor reaches initial edge path is built further. However it will not be
optimal.
This commit is contained in:
elsid 2021-03-23 23:15:13 +01:00
parent 313355cb3d
commit 39c0ce9ddf
No known key found for this signature in database
GPG Key ID: B845CB9FEE18AB40
8 changed files with 48 additions and 2 deletions

View File

@ -114,7 +114,7 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f&
if (wasShortcutting || doesPathNeedRecalc(dest, actor)) // if need to rebuild path
{
const auto pathfindingHalfExtents = world->getPathfindingHalfExtents(actor);
mPathFinder.buildPath(actor, position, dest, actor.getCell(), getPathGridGraph(actor.getCell()),
mPathFinder.buildLimitedPath(actor, position, dest, actor.getCell(), getPathGridGraph(actor.getCell()),
pathfindingHalfExtents, getNavigatorFlags(actor), getAreaCosts(actor));
mRotateOnTheRunChecks = 3;

View File

@ -442,4 +442,21 @@ namespace MWMechanics
std::copy(prePath.rbegin(), prePath.rend(), std::front_inserter(mPath));
}
void PathFinder::buildLimitedPath(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint, const osg::Vec3f& endPoint,
const MWWorld::CellStore* cell, const PathgridGraph& pathgridGraph, const osg::Vec3f& halfExtents,
const DetourNavigator::Flags flags, const DetourNavigator::AreaCosts& areaCosts)
{
const auto navigator = MWBase::Environment::get().getWorld()->getNavigator();
const auto maxDistance = std::min(
navigator->getMaxNavmeshAreaRealRadius(),
static_cast<float>(Constants::CellSizeInUnits)
);
const auto startToEnd = endPoint - startPoint;
const auto distance = startToEnd.length();
if (distance <= maxDistance)
return buildPath(actor, startPoint, endPoint, cell, pathgridGraph, halfExtents, flags, areaCosts);
const auto end = startPoint + startToEnd * maxDistance / distance;
buildPath(actor, startPoint, end, cell, pathgridGraph, halfExtents, flags, areaCosts);
}
}

View File

@ -101,6 +101,10 @@ namespace MWMechanics
void buildPathByNavMeshToNextPoint(const MWWorld::ConstPtr& actor, const osg::Vec3f& halfExtents,
const DetourNavigator::Flags flags, const DetourNavigator::AreaCosts& areaCosts);
void buildLimitedPath(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint, const osg::Vec3f& endPoint,
const MWWorld::CellStore* cell, const PathgridGraph& pathgridGraph, const osg::Vec3f& halfExtents,
const DetourNavigator::Flags flags, const DetourNavigator::AreaCosts& areaCosts);
/// Remove front point if exist and within tolerance
void update(const osg::Vec3f& position, float pointTolerance, float destinationTolerance,
bool shortenIfAlmostStraight, bool canMoveByZ);

View File

@ -235,6 +235,8 @@ namespace DetourNavigator
const osg::Vec3f& end, const Flags includeFlags) const;
virtual RecastMeshTiles getRecastMeshTiles() = 0;
virtual float getMaxNavmeshAreaRealRadius() const = 0;
};
}

View File

@ -213,4 +213,10 @@ namespace DetourNavigator
++it;
}
}
float NavigatorImpl::getMaxNavmeshAreaRealRadius() const
{
const auto& settings = getSettings();
return getRealTileSize(settings) * getMaxNavmeshAreaRadius(settings);
}
}

View File

@ -60,6 +60,8 @@ namespace DetourNavigator
RecastMeshTiles getRecastMeshTiles() override;
float getMaxNavmeshAreaRealRadius() const override;
private:
Settings mSettings;
NavMeshManager mNavMeshManager;

View File

@ -92,6 +92,11 @@ namespace DetourNavigator
return {};
}
float getMaxNavmeshAreaRealRadius() const override
{
return std::numeric_limits<float>::max();
}
private:
Settings mDefaultSettings {};
SharedNavMeshCacheItem mEmptyNavMeshCacheItem;

View File

@ -1,4 +1,4 @@
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_SETTINGSUTILS_H
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_SETTINGSUTILS_H
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_SETTINGSUTILS_H
#include "settings.hpp"
@ -89,6 +89,16 @@ namespace DetourNavigator
transform.getOrigin() + btVector3(0, 0, getSwimLevel(settings, agentHalfExtentsZ) - agentHalfExtentsZ)
);
}
inline float getRealTileSize(const Settings& settings)
{
return settings.mTileSize * settings.mCellSize / settings.mRecastScaleFactor;
}
inline float getMaxNavmeshAreaRadius(const Settings& settings)
{
return std::floor(std::sqrt(settings.mMaxTilesNumber / osg::PI)) - 1;
}
}
#endif