mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-04-11 00:44:33 +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
This commit is contained in:
commit
89ca56632c
@ -369,7 +369,13 @@ namespace MWMechanics
|
|||||||
mPath.clear();
|
mPath.clear();
|
||||||
|
|
||||||
// If it's not possible to build path over navmesh due to disabled navmesh generation fallback to straight path
|
// 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);
|
mPath.push_back(endPoint);
|
||||||
|
|
||||||
mConstructed = !mPath.empty();
|
mConstructed = !mPath.empty();
|
||||||
@ -382,25 +388,33 @@ namespace MWMechanics
|
|||||||
mPath.clear();
|
mPath.clear();
|
||||||
mCell = cell;
|
mCell = cell;
|
||||||
|
|
||||||
bool hasNavMesh = false;
|
DetourNavigator::Status status = DetourNavigator::Status::NavMeshNotFound;
|
||||||
|
|
||||||
if (!actor.getClass().isPureWaterCreature(actor) && !actor.getClass().isPureFlyingCreature(actor))
|
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())
|
if (status != DetourNavigator::Status::NavMeshNotFound && mPath.empty())
|
||||||
buildPathByNavigatorImpl(actor, startPoint, endPoint, halfExtents,
|
{
|
||||||
|
status = buildPathByNavigatorImpl(actor, startPoint, endPoint, halfExtents,
|
||||||
flags | DetourNavigator::Flag_usePathgrid, areaCosts, std::back_inserter(mPath));
|
flags | DetourNavigator::Flag_usePathgrid, areaCosts, std::back_inserter(mPath));
|
||||||
|
if (status != DetourNavigator::Status::Success)
|
||||||
|
mPath.clear();
|
||||||
|
}
|
||||||
|
|
||||||
if (mPath.empty())
|
if (mPath.empty())
|
||||||
buildPathByPathgridImpl(startPoint, endPoint, pathgridGraph, std::back_inserter(mPath));
|
buildPathByPathgridImpl(startPoint, endPoint, pathgridGraph, std::back_inserter(mPath));
|
||||||
|
|
||||||
if (!hasNavMesh && mPath.empty())
|
if (status == DetourNavigator::Status::NavMeshNotFound && mPath.empty())
|
||||||
mPath.push_back(endPoint);
|
mPath.push_back(endPoint);
|
||||||
|
|
||||||
mConstructed = !mPath.empty();
|
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 osg::Vec3f& endPoint, const osg::Vec3f& halfExtents, const DetourNavigator::Flags flags,
|
||||||
const DetourNavigator::AreaCosts& areaCosts, std::back_insert_iterator<std::deque<osg::Vec3f>> out)
|
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 navigator = world->getNavigator();
|
||||||
const auto status = navigator->findPath(halfExtents, stepSize, startPoint, endPoint, flags, areaCosts, out);
|
const auto status = navigator->findPath(halfExtents, stepSize, startPoint, endPoint, flags, areaCosts, out);
|
||||||
|
|
||||||
if (status == DetourNavigator::Status::NavMeshNotFound)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (status != DetourNavigator::Status::Success)
|
if (status != DetourNavigator::Status::Success)
|
||||||
{
|
{
|
||||||
Log(Debug::Debug) << "Build path by navigator error: \"" << DetourNavigator::getMessage(status)
|
Log(Debug::Debug) << "Build path by navigator error: \"" << DetourNavigator::getMessage(status)
|
||||||
@ -420,7 +431,7 @@ namespace MWMechanics
|
|||||||
<< DetourNavigator::WriteFlags {flags} << ")";
|
<< DetourNavigator::WriteFlags {flags} << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathFinder::buildPathByNavMeshToNextPoint(const MWWorld::ConstPtr& actor, const osg::Vec3f& halfExtents,
|
void PathFinder::buildPathByNavMeshToNextPoint(const MWWorld::ConstPtr& actor, const osg::Vec3f& halfExtents,
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include <components/detournavigator/flags.hpp>
|
#include <components/detournavigator/flags.hpp>
|
||||||
#include <components/detournavigator/areatype.hpp>
|
#include <components/detournavigator/areatype.hpp>
|
||||||
|
#include <components/detournavigator/status.hpp>
|
||||||
#include <components/esm/defs.hpp>
|
#include <components/esm/defs.hpp>
|
||||||
#include <components/esm/loadpgrd.hpp>
|
#include <components/esm/loadpgrd.hpp>
|
||||||
|
|
||||||
@ -209,9 +210,10 @@ namespace MWMechanics
|
|||||||
void buildPathByPathgridImpl(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint,
|
void buildPathByPathgridImpl(const osg::Vec3f& startPoint, const osg::Vec3f& endPoint,
|
||||||
const PathgridGraph& pathgridGraph, std::back_insert_iterator<std::deque<osg::Vec3f>> out);
|
const PathgridGraph& pathgridGraph, std::back_insert_iterator<std::deque<osg::Vec3f>> out);
|
||||||
|
|
||||||
bool buildPathByNavigatorImpl(const MWWorld::ConstPtr& actor, const osg::Vec3f& startPoint,
|
[[nodiscard]] DetourNavigator::Status buildPathByNavigatorImpl(const MWWorld::ConstPtr& actor,
|
||||||
const osg::Vec3f& endPoint, const osg::Vec3f& halfExtents, const DetourNavigator::Flags flags,
|
const osg::Vec3f& startPoint, const osg::Vec3f& endPoint, const osg::Vec3f& halfExtents,
|
||||||
const DetourNavigator::AreaCosts& areaCosts, std::back_insert_iterator<std::deque<osg::Vec3f>> out);
|
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 "findsmoothpath.hpp"
|
||||||
|
|
||||||
|
#include <components/misc/convert.hpp>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
@ -103,7 +105,7 @@ namespace DetourNavigator
|
|||||||
return result;
|
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)
|
const osg::Vec3f& endPos, const float minTargetDist, const std::vector<dtPolyRef>& path)
|
||||||
{
|
{
|
||||||
// Find steer target.
|
// Find steer target.
|
||||||
@ -113,8 +115,11 @@ namespace DetourNavigator
|
|||||||
std::array<unsigned char, maxSteerPoints> steerPathFlags;
|
std::array<unsigned char, maxSteerPoints> steerPathFlags;
|
||||||
std::array<dtPolyRef, maxSteerPoints> steerPathPolys;
|
std::array<dtPolyRef, maxSteerPoints> steerPathPolys;
|
||||||
int nsteerPath = 0;
|
int nsteerPath = 0;
|
||||||
navQuery.findStraightPath(startPos.ptr(), endPos.ptr(), path.data(), int(path.size()), steerPath.data(),
|
const dtStatus status = navMeshQuery.findStraightPath(startPos.ptr(), endPos.ptr(), path.data(),
|
||||||
steerPathFlags.data(), steerPathPolys.data(), &nsteerPath, maxSteerPoints);
|
static_cast<int>(path.size()), steerPath.data(), steerPathFlags.data(), steerPathPolys.data(),
|
||||||
|
&nsteerPath, maxSteerPoints);
|
||||||
|
if (dtStatusFailed(status))
|
||||||
|
return std::nullopt;
|
||||||
assert(nsteerPath >= 0);
|
assert(nsteerPath >= 0);
|
||||||
if (!nsteerPath)
|
if (!nsteerPath)
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
@ -125,7 +130,7 @@ namespace DetourNavigator
|
|||||||
{
|
{
|
||||||
// Stop at Off-Mesh link or when point is further than slop away.
|
// Stop at Off-Mesh link or when point is further than slop away.
|
||||||
if ((steerPathFlags[ns] & DT_STRAIGHTPATH_OFFMESH_CONNECTION) ||
|
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;
|
break;
|
||||||
ns++;
|
ns++;
|
||||||
}
|
}
|
||||||
|
@ -14,9 +14,8 @@
|
|||||||
#include <DetourNavMesh.h>
|
#include <DetourNavMesh.h>
|
||||||
#include <DetourNavMeshQuery.h>
|
#include <DetourNavMeshQuery.h>
|
||||||
|
|
||||||
#include <components/misc/convert.hpp>
|
|
||||||
|
|
||||||
#include <osg/Vec3f>
|
#include <osg/Vec3f>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -26,10 +25,9 @@ namespace DetourNavigator
|
|||||||
{
|
{
|
||||||
struct Settings;
|
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 (osg::Vec2f(v1.x(), v1.z()) - osg::Vec2f(v2.x(), v2.z())).length() < r;
|
||||||
return (d.x() * d.x() + d.z() * d.z()) < r * r && std::abs(d.y()) < h;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<dtPolyRef> fixupCorridor(const std::vector<dtPolyRef>& path, const std::vector<dtPolyRef>& visited);
|
std::vector<dtPolyRef> fixupCorridor(const std::vector<dtPolyRef>& path, const std::vector<dtPolyRef>& visited);
|
||||||
@ -143,15 +141,6 @@ namespace DetourNavigator
|
|||||||
return {std::move(result)};
|
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>
|
template <class OutputIterator>
|
||||||
Status makeSmoothPath(const dtNavMesh& navMesh, const dtNavMeshQuery& navMeshQuery,
|
Status makeSmoothPath(const dtNavMesh& navMesh, const dtNavMeshQuery& navMeshQuery,
|
||||||
const dtQueryFilter& filter, const osg::Vec3f& start, const osg::Vec3f& end, const float stepSize,
|
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 = fixupCorridor(polygonPath, result->mVisited);
|
||||||
polygonPath = fixupShortcuts(polygonPath, navMeshQuery);
|
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.
|
// 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.
|
// Reached end of path.
|
||||||
iterPos = targetPos;
|
iterPos = targetPos;
|
||||||
@ -215,7 +199,7 @@ namespace DetourNavigator
|
|||||||
++smoothPathSize;
|
++smoothPathSize;
|
||||||
break;
|
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.
|
// Advance the path up to and over the off-mesh connection.
|
||||||
dtPolyRef prevRef = 0;
|
dtPolyRef prevRef = 0;
|
||||||
@ -249,16 +233,18 @@ namespace DetourNavigator
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Move position at the other side of the off-mesh link.
|
// Move position at the other side of the off-mesh link.
|
||||||
iterPos = endPos;
|
if (dtStatusFailed(navMeshQuery.getPolyHeight(polygonPath.front(), endPos.ptr(), &iterPos.y())))
|
||||||
const auto height = getPolyHeight(navMeshQuery, polygonPath.front(), iterPos);
|
|
||||||
|
|
||||||
if (!height)
|
|
||||||
return Status::GetPolyHeightFailed;
|
return Status::GetPolyHeightFailed;
|
||||||
|
iterPos.x() = endPos.x();
|
||||||
iterPos.y() = *height;
|
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.
|
// Store results.
|
||||||
*out++ = iterPos;
|
*out++ = iterPos;
|
||||||
++smoothPathSize;
|
++smoothPathSize;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user