mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 19:19:56 +00:00
Merge branch 'fix_new_game_guard_3' into 'master'
Fix new game guard 3 (#6126) Closes #6126 See merge request OpenMW/openmw!976 (cherry picked from commit 89ca56632c6bc37f07e430e7f5cd23d855610b19) a3942a1e Remove redundant check for y coordinate in inRange function cc08a45c Move include where it is needed 7e1630a7 Remove redundant getPolyHeight wrapper 793c30ab Check dtNavMeshQuery::getPolyHeight status a54c4bc2 Check dtNavMeshQuery::findStraightPath status 94e460ba Use proper check for distance 5624fe19 Consider path not found when there is navmesh query error
This commit is contained in:
parent
c68cecb1eb
commit
bb393cb91c
4 changed files with 49 additions and 45 deletions
|
@ -369,7 +369,13 @@ namespace MWMechanics
|
|||
mPath.clear();
|
||||
|
||||
// If it's not possible to build path over navmesh due to disabled navmesh generation fallback to straight path
|
||||
if (!buildPathByNavigatorImpl(actor, startPoint, endPoint, halfExtents, flags, areaCosts, std::back_inserter(mPath)))
|
||||
DetourNavigator::Status status = buildPathByNavigatorImpl(actor, startPoint, endPoint, halfExtents, flags,
|
||||
areaCosts, std::back_inserter(mPath));
|
||||
|
||||
if (status != DetourNavigator::Status::Success)
|
||||
mPath.clear();
|
||||
|
||||
if (status == DetourNavigator::Status::NavMeshNotFound)
|
||||
mPath.push_back(endPoint);
|
||||
|
||||
mConstructed = !mPath.empty();
|
||||
|
@ -382,25 +388,33 @@ namespace MWMechanics
|
|||
mPath.clear();
|
||||
mCell = cell;
|
||||
|
||||
bool hasNavMesh = false;
|
||||
DetourNavigator::Status status = DetourNavigator::Status::NavMeshNotFound;
|
||||
|
||||
if (!actor.getClass().isPureWaterCreature(actor) && !actor.getClass().isPureFlyingCreature(actor))
|
||||
hasNavMesh = buildPathByNavigatorImpl(actor, startPoint, endPoint, halfExtents, flags, areaCosts, std::back_inserter(mPath));
|
||||
{
|
||||
status = buildPathByNavigatorImpl(actor, startPoint, endPoint, halfExtents, flags, areaCosts, std::back_inserter(mPath));
|
||||
if (status != DetourNavigator::Status::Success)
|
||||
mPath.clear();
|
||||
}
|
||||
|
||||
if (hasNavMesh && mPath.empty())
|
||||
buildPathByNavigatorImpl(actor, startPoint, endPoint, halfExtents,
|
||||
if (status != DetourNavigator::Status::NavMeshNotFound && mPath.empty())
|
||||
{
|
||||
status = buildPathByNavigatorImpl(actor, startPoint, endPoint, halfExtents,
|
||||
flags | DetourNavigator::Flag_usePathgrid, areaCosts, std::back_inserter(mPath));
|
||||
if (status != DetourNavigator::Status::Success)
|
||||
mPath.clear();
|
||||
}
|
||||
|
||||
if (mPath.empty())
|
||||
buildPathByPathgridImpl(startPoint, endPoint, pathgridGraph, std::back_inserter(mPath));
|
||||
|
||||
if (!hasNavMesh && mPath.empty())
|
||||
if (status == DetourNavigator::Status::NavMeshNotFound && mPath.empty())
|
||||
mPath.push_back(endPoint);
|
||||
|
||||
mConstructed = !mPath.empty();
|
||||
}
|
||||
|
||||
bool PathFinder::buildPathByNavigatorImpl(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint,
|
||||
DetourNavigator::Status PathFinder::buildPathByNavigatorImpl(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint,
|
||||
const osg::Vec3f& endPoint, const osg::Vec3f& halfExtents, const DetourNavigator::Flags flags,
|
||||
const DetourNavigator::AreaCosts& areaCosts, std::back_insert_iterator<std::deque<osg::Vec3f>> out)
|
||||
{
|
||||
|
@ -409,9 +423,6 @@ namespace MWMechanics
|
|||
const auto navigator = world->getNavigator();
|
||||
const auto status = navigator->findPath(halfExtents, stepSize, startPoint, endPoint, flags, areaCosts, out);
|
||||
|
||||
if (status == DetourNavigator::Status::NavMeshNotFound)
|
||||
return false;
|
||||
|
||||
if (status != DetourNavigator::Status::Success)
|
||||
{
|
||||
Log(Debug::Debug) << "Build path by navigator error: \"" << DetourNavigator::getMessage(status)
|
||||
|
@ -420,7 +431,7 @@ namespace MWMechanics
|
|||
<< DetourNavigator::WriteFlags {flags} << ")";
|
||||
}
|
||||
|
||||
return true;
|
||||
return status;
|
||||
}
|
||||
|
||||
void PathFinder::buildPathByNavMeshToNextPoint(const MWWorld::ConstPtr& actor, const osg::Vec3f& halfExtents,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <components/detournavigator/flags.hpp>
|
||||
#include <components/detournavigator/areatype.hpp>
|
||||
#include <components/detournavigator/status.hpp>
|
||||
#include <components/esm/defs.hpp>
|
||||
#include <components/esm/loadpgrd.hpp>
|
||||
|
||||
|
@ -209,9 +210,10 @@ namespace MWMechanics
|
|||
void buildPathByPathgridImpl(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint,
|
||||
const PathgridGraph& pathgridGraph, std::back_insert_iterator<std::deque<osg::Vec3f>> out);
|
||||
|
||||
bool buildPathByNavigatorImpl(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint,
|
||||
const osg::Vec3f& endPoint, const osg::Vec3f& halfExtents, const DetourNavigator::Flags flags,
|
||||
const DetourNavigator::AreaCosts& areaCosts, std::back_insert_iterator<std::deque<osg::Vec3f>> out);
|
||||
[[nodiscard]] DetourNavigator::Status buildPathByNavigatorImpl(const MWWorld::ConstPtr& actor,
|
||||
const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, const osg::Vec3f& halfExtents,
|
||||
const DetourNavigator::Flags flags, const DetourNavigator::AreaCosts& areaCosts,
|
||||
std::back_insert_iterator<std::deque<osg::Vec3f>> out);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "findsmoothpath.hpp"
|
||||
|
||||
#include <components/misc/convert.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
|
||||
|
@ -103,7 +105,7 @@ namespace DetourNavigator
|
|||
return result;
|
||||
}
|
||||
|
||||
std::optional<SteerTarget> getSteerTarget(const dtNavMeshQuery& navQuery, const osg::Vec3f& startPos,
|
||||
std::optional<SteerTarget> getSteerTarget(const dtNavMeshQuery& navMeshQuery, const osg::Vec3f& startPos,
|
||||
const osg::Vec3f& endPos, const float minTargetDist, const std::vector<dtPolyRef>& path)
|
||||
{
|
||||
// Find steer target.
|
||||
|
@ -113,8 +115,11 @@ namespace DetourNavigator
|
|||
std::array<unsigned char, maxSteerPoints> steerPathFlags;
|
||||
std::array<dtPolyRef, maxSteerPoints> steerPathPolys;
|
||||
int nsteerPath = 0;
|
||||
navQuery.findStraightPath(startPos.ptr(), endPos.ptr(), path.data(), int(path.size()), steerPath.data(),
|
||||
steerPathFlags.data(), steerPathPolys.data(), &nsteerPath, maxSteerPoints);
|
||||
const dtStatus status = navMeshQuery.findStraightPath(startPos.ptr(), endPos.ptr(), path.data(),
|
||||
static_cast<int>(path.size()), steerPath.data(), steerPathFlags.data(), steerPathPolys.data(),
|
||||
&nsteerPath, maxSteerPoints);
|
||||
if (dtStatusFailed(status))
|
||||
return std::nullopt;
|
||||
assert(nsteerPath >= 0);
|
||||
if (!nsteerPath)
|
||||
return std::nullopt;
|
||||
|
@ -125,7 +130,7 @@ namespace DetourNavigator
|
|||
{
|
||||
// Stop at Off-Mesh link or when point is further than slop away.
|
||||
if ((steerPathFlags[ns] & DT_STRAIGHTPATH_OFFMESH_CONNECTION) ||
|
||||
!inRange(Misc::Convert::makeOsgVec3f(&steerPath[ns * 3]), startPos, minTargetDist, 1000.0f))
|
||||
!inRange(Misc::Convert::makeOsgVec3f(&steerPath[ns * 3]), startPos, minTargetDist))
|
||||
break;
|
||||
ns++;
|
||||
}
|
||||
|
|
|
@ -14,9 +14,8 @@
|
|||
#include <DetourNavMesh.h>
|
||||
#include <DetourNavMeshQuery.h>
|
||||
|
||||
#include <components/misc/convert.hpp>
|
||||
|
||||
#include <osg/Vec3f>
|
||||
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
|
||||
|
@ -26,10 +25,9 @@ namespace DetourNavigator
|
|||
{
|
||||
struct Settings;
|
||||
|
||||
inline bool inRange(const osg::Vec3f& v1, const osg::Vec3f& v2, const float r, const float h)
|
||||
inline bool inRange(const osg::Vec3f& v1, const osg::Vec3f& v2, const float r)
|
||||
{
|
||||
const auto d = v2 - v1;
|
||||
return (d.x() * d.x() + d.z() * d.z()) < r * r && std::abs(d.y()) < h;
|
||||
return (osg::Vec2f(v1.x(), v1.z()) - osg::Vec2f(v2.x(), v2.z())).length() < r;
|
||||
}
|
||||
|
||||
std::vector<dtPolyRef> fixupCorridor(const std::vector<dtPolyRef>& path, const std::vector<dtPolyRef>& visited);
|
||||
|
@ -143,15 +141,6 @@ namespace DetourNavigator
|
|||
return {std::move(result)};
|
||||
}
|
||||
|
||||
inline std::optional<float> getPolyHeight(const dtNavMeshQuery& navMeshQuery, const dtPolyRef ref, const osg::Vec3f& pos)
|
||||
{
|
||||
float result = 0.0f;
|
||||
const auto status = navMeshQuery.getPolyHeight(ref, pos.ptr(), &result);
|
||||
if (!dtStatusSucceed(status))
|
||||
return {};
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class OutputIterator>
|
||||
Status makeSmoothPath(const dtNavMesh& navMesh, const dtNavMeshQuery& navMeshQuery,
|
||||
const dtQueryFilter& filter, const osg::Vec3f& start, const osg::Vec3f& end, const float stepSize,
|
||||
|
@ -201,13 +190,8 @@ namespace DetourNavigator
|
|||
polygonPath = fixupCorridor(polygonPath, result->mVisited);
|
||||
polygonPath = fixupShortcuts(polygonPath, navMeshQuery);
|
||||
|
||||
float h = 0;
|
||||
navMeshQuery.getPolyHeight(polygonPath.front(), result->mResultPos.ptr(), &h);
|
||||
iterPos = result->mResultPos;
|
||||
iterPos.y() = h;
|
||||
|
||||
// Handle end of path and off-mesh links when close enough.
|
||||
if (endOfPath && inRange(iterPos, steerTarget->steerPos, slop, 1.0f))
|
||||
if (endOfPath && inRange(result->mResultPos, steerTarget->steerPos, slop))
|
||||
{
|
||||
// Reached end of path.
|
||||
iterPos = targetPos;
|
||||
|
@ -215,7 +199,7 @@ namespace DetourNavigator
|
|||
++smoothPathSize;
|
||||
break;
|
||||
}
|
||||
else if (offMeshConnection && inRange(iterPos, steerTarget->steerPos, slop, 1.0f))
|
||||
else if (offMeshConnection && inRange(result->mResultPos, steerTarget->steerPos, slop))
|
||||
{
|
||||
// Advance the path up to and over the off-mesh connection.
|
||||
dtPolyRef prevRef = 0;
|
||||
|
@ -249,16 +233,18 @@ namespace DetourNavigator
|
|||
}
|
||||
|
||||
// Move position at the other side of the off-mesh link.
|
||||
iterPos = endPos;
|
||||
const auto height = getPolyHeight(navMeshQuery, polygonPath.front(), iterPos);
|
||||
|
||||
if (!height)
|
||||
if (dtStatusFailed(navMeshQuery.getPolyHeight(polygonPath.front(), endPos.ptr(), &iterPos.y())))
|
||||
return Status::GetPolyHeightFailed;
|
||||
|
||||
iterPos.y() = *height;
|
||||
iterPos.x() = endPos.x();
|
||||
iterPos.z() = endPos.z();
|
||||
}
|
||||
}
|
||||
|
||||
if (dtStatusFailed(navMeshQuery.getPolyHeight(polygonPath.front(), result->mResultPos.ptr(), &iterPos.y())))
|
||||
return Status::GetPolyHeightFailed;
|
||||
iterPos.x() = result->mResultPos.x();
|
||||
iterPos.z() = result->mResultPos.z();
|
||||
|
||||
// Store results.
|
||||
*out++ = iterPos;
|
||||
++smoothPathSize;
|
||||
|
|
Loading…
Reference in a new issue