Do expensive navmesh calls on timer

Reducing the number of them on each frame.
pull/3229/head
elsid 2 years ago
parent d846a9fc15
commit 540ee5399c
No known key found for this signature in database
GPG Key ID: 4DE04C198CBA7625

@ -189,8 +189,17 @@ bool MWMechanics::AiPackage::pathTo(const MWWorld::Ptr& actor, const osg::Vec3f&
= getPointTolerance(actor.getClass().getMaxSpeed(actor), duration, world->getHalfExtents(actor));
static const bool smoothMovement = Settings::Manager::getBool("smooth movement", "Game");
mPathFinder.update(position, pointTolerance, DEFAULT_TOLERANCE,
/*shortenIfAlmostStraight=*/smoothMovement, actorCanMoveByZ, agentBounds, getNavigatorFlags(actor));
PathFinder::UpdateFlags updateFlags{};
if (actorCanMoveByZ)
updateFlags |= PathFinder::UpdateFlag_CanMoveByZ;
if (timerStatus == Misc::TimerStatus::Elapsed && smoothMovement)
updateFlags |= PathFinder::UpdateFlag_ShortenIfAlmostStraight;
if (timerStatus == Misc::TimerStatus::Elapsed)
updateFlags |= PathFinder::UpdateFlag_RemoveLoops;
mPathFinder.update(position, pointTolerance, DEFAULT_TOLERANCE, updateFlags, agentBounds, getNavigatorFlags(actor));
if (isDestReached || mPathFinder.checkPathCompleted()) // if path is finished
{

@ -312,6 +312,13 @@ namespace MWMechanics
completeManualWalking(actor, storage);
}
if (storage.mState == AiWanderStorage::Wander_Walking && mUsePathgrid)
{
const auto agentBounds = MWBase::Environment::get().getWorld()->getPathfindingAgentBounds(actor);
mPathFinder.buildPathByNavMeshToNextPoint(
actor, agentBounds, getNavigatorFlags(actor), getAreaCosts(actor));
}
if (storage.mState == AiWanderStorage::Wander_MoveNow && storage.mCanWanderAlongPathGrid)
{
// Construct a new path if there isn't one
@ -560,13 +567,6 @@ namespace MWMechanics
void AiWander::evadeObstacles(const MWWorld::Ptr& actor, AiWanderStorage& storage)
{
if (mUsePathgrid)
{
const auto agentBounds = MWBase::Environment::get().getWorld()->getPathfindingAgentBounds(actor);
mPathFinder.buildPathByNavMeshToNextPoint(
actor, agentBounds, getNavigatorFlags(actor), getAreaCosts(actor));
}
if (mObstacleCheck.isEvading())
{
// first check if we're walking into a door

@ -313,8 +313,7 @@ namespace MWMechanics
}
void PathFinder::update(const osg::Vec3f& position, float pointTolerance, float destinationTolerance,
bool shortenIfAlmostStraight, bool canMoveByZ, const DetourNavigator::AgentBounds& agentBounds,
const DetourNavigator::Flags flags)
UpdateFlags updateFlags, const DetourNavigator::AgentBounds& agentBounds, DetourNavigator::Flags pathFlags)
{
if (mPath.empty())
return;
@ -323,9 +322,9 @@ namespace MWMechanics
mPath.pop_front();
const IsValidShortcut isValidShortcut{ MWBase::Environment::get().getWorld()->getNavigator(), agentBounds,
flags };
pathFlags };
if (shortenIfAlmostStraight)
if ((updateFlags & UpdateFlag_ShortenIfAlmostStraight) != 0)
{
while (mPath.size() > 2 && isAlmostStraight(mPath[0], mPath[1], mPath[2], pointTolerance)
&& isValidShortcut(mPath[0], mPath[2]))
@ -335,7 +334,7 @@ namespace MWMechanics
mPath.pop_front();
}
if (mPath.size() > 1)
if ((updateFlags & UpdateFlag_RemoveLoops) != 0 && mPath.size() > 1)
{
std::size_t begin = 0;
for (std::size_t i = 1; i < mPath.size(); ++i)
@ -351,7 +350,7 @@ namespace MWMechanics
if (mPath.size() == 1)
{
float distSqr;
if (canMoveByZ)
if ((updateFlags & UpdateFlag_CanMoveByZ) != 0)
distSqr = (mPath.front() - position).length2();
else
distSqr = sqrDistanceIgnoreZ(mPath.front(), position);

@ -82,11 +82,16 @@ namespace MWMechanics
class PathFinder
{
public:
PathFinder()
: mConstructed(false)
, mCell(nullptr)
using UpdateFlags = unsigned;
enum UpdateFlag : UpdateFlags
{
}
UpdateFlag_CanMoveByZ = 1 << 0,
UpdateFlag_ShortenIfAlmostStraight = 1 << 1,
UpdateFlag_RemoveLoops = 1 << 2,
};
PathFinder() = default;
void clearPath()
{
@ -121,8 +126,7 @@ namespace MWMechanics
/// Remove front point if exist and within tolerance
void update(const osg::Vec3f& position, float pointTolerance, float destinationTolerance,
bool shortenIfAlmostStraight, bool canMoveByZ, const DetourNavigator::AgentBounds& agentBounds,
const DetourNavigator::Flags flags);
UpdateFlags updateFlags, const DetourNavigator::AgentBounds& agentBounds, DetourNavigator::Flags pathFlags);
bool checkPathCompleted() const { return mConstructed && mPath.empty(); }
@ -201,10 +205,9 @@ namespace MWMechanics
}
private:
bool mConstructed;
bool mConstructed = false;
std::deque<osg::Vec3f> mPath;
const MWWorld::CellStore* mCell;
const MWWorld::CellStore* mCell = nullptr;
void buildPathByPathgridImpl(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint,
const PathgridGraph& pathgridGraph, std::back_insert_iterator<std::deque<osg::Vec3f>> out);

Loading…
Cancel
Save