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:
parent
313355cb3d
commit
39c0ce9ddf
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -235,6 +235,8 @@ namespace DetourNavigator
|
||||
const osg::Vec3f& end, const Flags includeFlags) const;
|
||||
|
||||
virtual RecastMeshTiles getRecastMeshTiles() = 0;
|
||||
|
||||
virtual float getMaxNavmeshAreaRealRadius() const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -213,4 +213,10 @@ namespace DetourNavigator
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
float NavigatorImpl::getMaxNavmeshAreaRealRadius() const
|
||||
{
|
||||
const auto& settings = getSettings();
|
||||
return getRealTileSize(settings) * getMaxNavmeshAreaRadius(settings);
|
||||
}
|
||||
}
|
||||
|
@ -60,6 +60,8 @@ namespace DetourNavigator
|
||||
|
||||
RecastMeshTiles getRecastMeshTiles() override;
|
||||
|
||||
float getMaxNavmeshAreaRealRadius() const override;
|
||||
|
||||
private:
|
||||
Settings mSettings;
|
||||
NavMeshManager mNavMeshManager;
|
||||
|
@ -92,6 +92,11 @@ namespace DetourNavigator
|
||||
return {};
|
||||
}
|
||||
|
||||
float getMaxNavmeshAreaRealRadius() const override
|
||||
{
|
||||
return std::numeric_limits<float>::max();
|
||||
}
|
||||
|
||||
private:
|
||||
Settings mDefaultSettings {};
|
||||
SharedNavMeshCacheItem mEmptyNavMeshCacheItem;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user