mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-16 15:29:55 +00:00
Remove macroses to check recastnavigation functions result
This commit is contained in:
parent
ed73d130f9
commit
fb655cb04f
4 changed files with 179 additions and 77 deletions
|
@ -1,8 +1,6 @@
|
||||||
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_DTSTATUS_H
|
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_DTSTATUS_H
|
||||||
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_DTSTATUS_H
|
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_DTSTATUS_H
|
||||||
|
|
||||||
#include "exceptions.hpp"
|
|
||||||
|
|
||||||
#include <DetourStatus.h>
|
#include <DetourStatus.h>
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
@ -35,32 +33,6 @@ namespace DetourNavigator
|
||||||
stream << status.second << " ";
|
stream << status.second << " ";
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void checkDtStatus(dtStatus status, const char* call, int line)
|
|
||||||
{
|
|
||||||
if (!dtStatusSucceed(status))
|
|
||||||
{
|
|
||||||
std::ostringstream message;
|
|
||||||
message << call << " failed with status=" << WriteDtStatus {status} << " at " __FILE__ ":" << line;
|
|
||||||
throw NavigatorException(message.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void checkDtResult(bool result, const char* call, int line)
|
|
||||||
{
|
|
||||||
if (!result)
|
|
||||||
{
|
|
||||||
std::ostringstream message;
|
|
||||||
message << call << " failed at " __FILE__ ":" << line;
|
|
||||||
throw NavigatorException(message.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OPENMW_CHECK_DT_STATUS(call) \
|
|
||||||
do { DetourNavigator::checkDtStatus((call), #call, __LINE__); } while (false)
|
|
||||||
|
|
||||||
#define OPENMW_CHECK_DT_RESULT(call) \
|
|
||||||
do { DetourNavigator::checkDtResult((call), #call, __LINE__); } while (false)
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "flags.hpp"
|
#include "flags.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
#include "settingsutils.hpp"
|
#include "settingsutils.hpp"
|
||||||
|
#include "debug.hpp"
|
||||||
|
|
||||||
#include <DetourCommon.h>
|
#include <DetourCommon.h>
|
||||||
#include <DetourNavMesh.h>
|
#include <DetourNavMesh.h>
|
||||||
|
@ -97,6 +98,73 @@ namespace DetourNavigator
|
||||||
const Settings& mSettings;
|
const Settings& mSettings;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline void initNavMeshQuery(dtNavMeshQuery& value, const dtNavMesh& navMesh, const int maxNodes)
|
||||||
|
{
|
||||||
|
const auto status = value.init(&navMesh, maxNodes);
|
||||||
|
if (!dtStatusSucceed(status))
|
||||||
|
throw NavigatorException("Failed to init navmesh query");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MoveAlongSurfaceResult
|
||||||
|
{
|
||||||
|
osg::Vec3f mResultPos;
|
||||||
|
std::vector<dtPolyRef> mVisited;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline MoveAlongSurfaceResult moveAlongSurface(const dtNavMeshQuery& navMeshQuery, const dtPolyRef startRef,
|
||||||
|
const osg::Vec3f& startPos, const osg::Vec3f& endPos, const dtQueryFilter& filter,
|
||||||
|
const std::size_t maxVisitedSize)
|
||||||
|
{
|
||||||
|
MoveAlongSurfaceResult result;
|
||||||
|
result.mVisited.resize(maxVisitedSize);
|
||||||
|
int visitedNumber = 0;
|
||||||
|
const auto status = navMeshQuery.moveAlongSurface(startRef, startPos.ptr(), endPos.ptr(),
|
||||||
|
&filter, result.mResultPos.ptr(), result.mVisited.data(), &visitedNumber, static_cast<int>(maxVisitedSize));
|
||||||
|
if (!dtStatusSucceed(status))
|
||||||
|
{
|
||||||
|
std::ostringstream message;
|
||||||
|
message << "Failed to move along surface from " << startPos << " to " << endPos;
|
||||||
|
throw NavigatorException(message.str());
|
||||||
|
}
|
||||||
|
assert(visitedNumber >= 0);
|
||||||
|
assert(visitedNumber <= static_cast<int>(maxVisitedSize));
|
||||||
|
result.mVisited.resize(static_cast<std::size_t>(visitedNumber));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::vector<dtPolyRef> findPath(const dtNavMeshQuery& navMeshQuery, const dtPolyRef startRef,
|
||||||
|
const dtPolyRef endRef, const osg::Vec3f& startPos, const osg::Vec3f& endPos, const dtQueryFilter& queryFilter,
|
||||||
|
const std::size_t maxSize)
|
||||||
|
{
|
||||||
|
int pathLen = 0;
|
||||||
|
std::vector<dtPolyRef> result(maxSize);
|
||||||
|
const auto status = navMeshQuery.findPath(startRef, endRef, startPos.ptr(), endPos.ptr(), &queryFilter,
|
||||||
|
result.data(), &pathLen, static_cast<int>(maxSize));
|
||||||
|
if (!dtStatusSucceed(status))
|
||||||
|
{
|
||||||
|
std::ostringstream message;
|
||||||
|
message << "Failed to find path over polygons from " << startRef << " to " << endRef;
|
||||||
|
throw NavigatorException(message.str());
|
||||||
|
}
|
||||||
|
assert(pathLen >= 0);
|
||||||
|
assert(static_cast<std::size_t>(pathLen) <= maxSize);
|
||||||
|
result.resize(static_cast<std::size_t>(pathLen));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline 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))
|
||||||
|
{
|
||||||
|
std::ostringstream message;
|
||||||
|
message << "Failed to get polygon height ref=" << ref << " pos=" << pos;
|
||||||
|
throw NavigatorException(message.str());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
template <class OutputIterator>
|
template <class OutputIterator>
|
||||||
OutputIterator makeSmoothPath(const dtNavMesh& navMesh, const dtNavMeshQuery& navMeshQuery,
|
OutputIterator makeSmoothPath(const dtNavMesh& navMesh, const dtNavMeshQuery& navMeshQuery,
|
||||||
const dtQueryFilter& filter, const osg::Vec3f& start, const osg::Vec3f& end,
|
const dtQueryFilter& filter, const osg::Vec3f& start, const osg::Vec3f& end,
|
||||||
|
@ -139,25 +207,15 @@ namespace DetourNavigator
|
||||||
len = STEP_SIZE / len;
|
len = STEP_SIZE / len;
|
||||||
|
|
||||||
const osg::Vec3f moveTgt = iterPos + delta * len;
|
const osg::Vec3f moveTgt = iterPos + delta * len;
|
||||||
|
const auto result = moveAlongSurface(navMeshQuery, polygonPath.front(), iterPos, moveTgt, filter, 16);
|
||||||
|
|
||||||
// Move
|
polygonPath = fixupCorridor(polygonPath, result.mVisited);
|
||||||
osg::Vec3f result;
|
|
||||||
std::vector<dtPolyRef> visited(16);
|
|
||||||
int nvisited = 0;
|
|
||||||
OPENMW_CHECK_DT_STATUS(navMeshQuery.moveAlongSurface(polygonPath.front(), iterPos.ptr(), moveTgt.ptr(),
|
|
||||||
&filter, result.ptr(), visited.data(), &nvisited, int(visited.size())));
|
|
||||||
|
|
||||||
assert(nvisited >= 0);
|
|
||||||
assert(nvisited <= int(visited.size()));
|
|
||||||
visited.resize(static_cast<std::size_t>(nvisited));
|
|
||||||
|
|
||||||
polygonPath = fixupCorridor(polygonPath, visited);
|
|
||||||
polygonPath = fixupShortcuts(polygonPath, navMeshQuery);
|
polygonPath = fixupShortcuts(polygonPath, navMeshQuery);
|
||||||
|
|
||||||
float h = 0;
|
float h = 0;
|
||||||
navMeshQuery.getPolyHeight(polygonPath.front(), result.ptr(), &h);
|
navMeshQuery.getPolyHeight(polygonPath.front(), result.mResultPos.ptr(), &h);
|
||||||
result.y() = h;
|
iterPos = result.mResultPos;
|
||||||
iterPos = result;
|
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(iterPos, steerTarget->steerPos, SLOP, 1.0f))
|
||||||
|
@ -203,9 +261,7 @@ 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;
|
iterPos = endPos;
|
||||||
float eh = 0.0f;
|
iterPos.y() = getPolyHeight(navMeshQuery, polygonPath.front(), iterPos);
|
||||||
OPENMW_CHECK_DT_STATUS(navMeshQuery.getPolyHeight(polygonPath.front(), iterPos.ptr(), &eh));
|
|
||||||
iterPos.y() = eh;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,7 +279,7 @@ namespace DetourNavigator
|
||||||
const Settings& settings, OutputIterator out)
|
const Settings& settings, OutputIterator out)
|
||||||
{
|
{
|
||||||
dtNavMeshQuery navMeshQuery;
|
dtNavMeshQuery navMeshQuery;
|
||||||
OPENMW_CHECK_DT_STATUS(navMeshQuery.init(&navMesh, settings.mMaxNavMeshQueryNodes));
|
initNavMeshQuery(navMeshQuery, navMesh, settings.mMaxNavMeshQueryNodes);
|
||||||
|
|
||||||
dtQueryFilter queryFilter;
|
dtQueryFilter queryFilter;
|
||||||
queryFilter.setIncludeFlags(includeFlags);
|
queryFilter.setIncludeFlags(includeFlags);
|
||||||
|
@ -239,7 +295,7 @@ namespace DetourNavigator
|
||||||
}
|
}
|
||||||
|
|
||||||
if (startRef == 0)
|
if (startRef == 0)
|
||||||
throw NavigatorException("start polygon is not found at " __FILE__ ":" + std::to_string(__LINE__));
|
throw NavigatorException("Navmesh polygon for start point is not found");
|
||||||
|
|
||||||
dtPolyRef endRef = 0;
|
dtPolyRef endRef = 0;
|
||||||
osg::Vec3f endPolygonPosition;
|
osg::Vec3f endPolygonPosition;
|
||||||
|
@ -252,16 +308,10 @@ namespace DetourNavigator
|
||||||
}
|
}
|
||||||
|
|
||||||
if (endRef == 0)
|
if (endRef == 0)
|
||||||
throw NavigatorException("end polygon is not found at " __FILE__ ":" + std::to_string(__LINE__));
|
throw NavigatorException("Navmesh polygon for end polygon is not found");
|
||||||
|
|
||||||
std::vector<dtPolyRef> polygonPath(settings.mMaxPolygonPathSize);
|
const auto polygonPath = findPath(navMeshQuery, startRef, endRef, start, end, queryFilter,
|
||||||
int pathLen = 0;
|
settings.mMaxPolygonPathSize);
|
||||||
OPENMW_CHECK_DT_STATUS(navMeshQuery.findPath(startRef, endRef, start.ptr(), end.ptr(), &queryFilter,
|
|
||||||
polygonPath.data(), &pathLen, static_cast<int>(polygonPath.size())));
|
|
||||||
|
|
||||||
assert(pathLen >= 0);
|
|
||||||
|
|
||||||
polygonPath.resize(static_cast<std::size_t>(pathLen));
|
|
||||||
|
|
||||||
if (polygonPath.empty() || polygonPath.back() != endRef)
|
if (polygonPath.empty() || polygonPath.back() != endRef)
|
||||||
return out;
|
return out;
|
||||||
|
|
|
@ -102,6 +102,77 @@ namespace
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void createHeightfield(rcContext& context, rcHeightfield& solid, int width, int height, const float* bmin,
|
||||||
|
const float* bmax, const float cs, const float ch)
|
||||||
|
{
|
||||||
|
const auto result = rcCreateHeightfield(&context, solid, width, height, bmin, bmax, cs, ch);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
throw NavigatorException("Failed to create heightfield for navmesh");
|
||||||
|
}
|
||||||
|
|
||||||
|
void buildCompactHeightfield(rcContext& context, const int walkableHeight, const int walkableClimb,
|
||||||
|
rcHeightfield& solid, rcCompactHeightfield& compact)
|
||||||
|
{
|
||||||
|
const auto result = rcBuildCompactHeightfield(&context, walkableHeight,
|
||||||
|
walkableClimb, solid, compact);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
throw NavigatorException("Failed to build compact heightfield for navmesh");
|
||||||
|
}
|
||||||
|
|
||||||
|
void erodeWalkableArea(rcContext& context, int walkableRadius, rcCompactHeightfield& compact)
|
||||||
|
{
|
||||||
|
const auto result = rcErodeWalkableArea(&context, walkableRadius, compact);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
throw NavigatorException("Failed to erode walkable area for navmesh");
|
||||||
|
}
|
||||||
|
|
||||||
|
void buildDistanceField(rcContext& context, rcCompactHeightfield& compact)
|
||||||
|
{
|
||||||
|
const auto result = rcBuildDistanceField(&context, compact);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
throw NavigatorException("Failed to build distance field for navmesh");
|
||||||
|
}
|
||||||
|
|
||||||
|
void buildRegions(rcContext& context, rcCompactHeightfield& compact, const int borderSize,
|
||||||
|
const int minRegionArea, const int mergeRegionArea)
|
||||||
|
{
|
||||||
|
const auto result = rcBuildRegions(&context, compact, borderSize, minRegionArea, mergeRegionArea);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
throw NavigatorException("Failed to build distance field for navmesh");
|
||||||
|
}
|
||||||
|
|
||||||
|
void buildContours(rcContext& context, rcCompactHeightfield& compact, const float maxError, const int maxEdgeLen,
|
||||||
|
rcContourSet& contourSet, const int buildFlags = RC_CONTOUR_TESS_WALL_EDGES)
|
||||||
|
{
|
||||||
|
const auto result = rcBuildContours(&context, compact, maxError, maxEdgeLen, contourSet, buildFlags);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
throw NavigatorException("Failed to build contours for navmesh");
|
||||||
|
}
|
||||||
|
|
||||||
|
void buildPolyMesh(rcContext& context, rcContourSet& contourSet, const int maxVertsPerPoly, rcPolyMesh& polyMesh)
|
||||||
|
{
|
||||||
|
const auto result = rcBuildPolyMesh(&context, contourSet, maxVertsPerPoly, polyMesh);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
throw NavigatorException("Failed to build poly mesh for navmesh");
|
||||||
|
}
|
||||||
|
|
||||||
|
void buildPolyMeshDetail(rcContext& context, const rcPolyMesh& polyMesh, const rcCompactHeightfield& compact,
|
||||||
|
const float sampleDist, const float sampleMaxError, rcPolyMeshDetail& polyMeshDetail)
|
||||||
|
{
|
||||||
|
const auto result = rcBuildPolyMeshDetail(&context, polyMesh, compact, sampleDist, sampleMaxError,
|
||||||
|
polyMeshDetail);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
throw NavigatorException("Failed to build detail poly mesh for navmesh");
|
||||||
|
}
|
||||||
|
|
||||||
NavMeshData makeNavMeshTileData(const osg::Vec3f& agentHalfExtents, const RecastMesh& recastMesh,
|
NavMeshData makeNavMeshTileData(const osg::Vec3f& agentHalfExtents, const RecastMesh& recastMesh,
|
||||||
const std::vector<OffMeshConnection>& offMeshConnections, const int tileX, const int tileY,
|
const std::vector<OffMeshConnection>& offMeshConnections, const int tileX, const int tileY,
|
||||||
const osg::Vec3f& boundsMin, const osg::Vec3f& boundsMax, const Settings& settings)
|
const osg::Vec3f& boundsMin, const osg::Vec3f& boundsMax, const Settings& settings)
|
||||||
|
@ -133,8 +204,7 @@ namespace
|
||||||
config.bmax[2] += getBorderSize(settings);
|
config.bmax[2] += getBorderSize(settings);
|
||||||
|
|
||||||
rcHeightfield solid;
|
rcHeightfield solid;
|
||||||
OPENMW_CHECK_DT_RESULT(rcCreateHeightfield(nullptr, solid, config.width, config.height,
|
createHeightfield(context, solid, config.width, config.height, config.bmin, config.bmax, config.cs, config.ch);
|
||||||
config.bmin, config.bmax, config.cs, config.ch));
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const auto& chunkyMesh = recastMesh.getChunkyTriMesh();
|
const auto& chunkyMesh = recastMesh.getChunkyTriMesh();
|
||||||
|
@ -181,7 +251,7 @@ namespace
|
||||||
areas.data()
|
areas.data()
|
||||||
);
|
);
|
||||||
|
|
||||||
OPENMW_CHECK_DT_RESULT(rcRasterizeTriangles(
|
const auto trianglesRasterized = rcRasterizeTriangles(
|
||||||
&context,
|
&context,
|
||||||
recastMesh.getVertices().data(),
|
recastMesh.getVertices().data(),
|
||||||
static_cast<int>(recastMesh.getVerticesCount()),
|
static_cast<int>(recastMesh.getVerticesCount()),
|
||||||
|
@ -190,7 +260,10 @@ namespace
|
||||||
static_cast<int>(chunk.mSize),
|
static_cast<int>(chunk.mSize),
|
||||||
solid,
|
solid,
|
||||||
config.walkableClimb
|
config.walkableClimb
|
||||||
));
|
);
|
||||||
|
|
||||||
|
if (!trianglesRasterized)
|
||||||
|
throw NavigatorException("Failed to create rasterize triangles from recast mesh for navmesh");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,7 +304,7 @@ namespace
|
||||||
0, 2, 3,
|
0, 2, 3,
|
||||||
}};
|
}};
|
||||||
|
|
||||||
OPENMW_CHECK_DT_RESULT(rcRasterizeTriangles(
|
const auto trianglesRasterized = rcRasterizeTriangles(
|
||||||
&context,
|
&context,
|
||||||
convertedVertices.data(),
|
convertedVertices.data(),
|
||||||
static_cast<int>(convertedVertices.size() / 3),
|
static_cast<int>(convertedVertices.size() / 3),
|
||||||
|
@ -240,7 +313,10 @@ namespace
|
||||||
static_cast<int>(areas.size()),
|
static_cast<int>(areas.size()),
|
||||||
solid,
|
solid,
|
||||||
config.walkableClimb
|
config.walkableClimb
|
||||||
));
|
);
|
||||||
|
|
||||||
|
if (!trianglesRasterized)
|
||||||
|
throw NavigatorException("Failed to create rasterize water triangles for navmesh");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,24 +330,22 @@ namespace
|
||||||
const PolyMeshDetailStackPtr polyMeshDetailPtr(&polyMeshDetail);
|
const PolyMeshDetailStackPtr polyMeshDetailPtr(&polyMeshDetail);
|
||||||
{
|
{
|
||||||
rcCompactHeightfield compact;
|
rcCompactHeightfield compact;
|
||||||
|
buildCompactHeightfield(context, config.walkableHeight, config.walkableClimb, solid, compact);
|
||||||
|
|
||||||
OPENMW_CHECK_DT_RESULT(rcBuildCompactHeightfield(&context, config.walkableHeight, config.walkableClimb,
|
erodeWalkableArea(context, config.walkableRadius, compact);
|
||||||
solid, compact));
|
buildDistanceField(context, compact);
|
||||||
OPENMW_CHECK_DT_RESULT(rcErodeWalkableArea(&context, config.walkableRadius, compact));
|
buildRegions(context, compact, config.borderSize, config.minRegionArea, config.mergeRegionArea);
|
||||||
OPENMW_CHECK_DT_RESULT(rcBuildDistanceField(&context, compact));
|
|
||||||
OPENMW_CHECK_DT_RESULT(rcBuildRegions(&context, compact, config.borderSize, config.minRegionArea,
|
|
||||||
config.mergeRegionArea));
|
|
||||||
|
|
||||||
rcContourSet contourSet;
|
rcContourSet contourSet;
|
||||||
OPENMW_CHECK_DT_RESULT(rcBuildContours(&context, compact, config.maxSimplificationError, config.maxEdgeLen,
|
buildContours(context, compact, config.maxSimplificationError, config.maxEdgeLen, contourSet);
|
||||||
contourSet));
|
|
||||||
|
|
||||||
if (contourSet.nconts == 0)
|
if (contourSet.nconts == 0)
|
||||||
return NavMeshData();
|
return NavMeshData();
|
||||||
|
|
||||||
OPENMW_CHECK_DT_RESULT(rcBuildPolyMesh(&context, contourSet, config.maxVertsPerPoly, polyMesh));
|
buildPolyMesh(context, contourSet, config.maxVertsPerPoly, polyMesh);
|
||||||
OPENMW_CHECK_DT_RESULT(rcBuildPolyMeshDetail(&context, polyMesh, compact, config.detailSampleDist,
|
|
||||||
config.detailSampleMaxError, polyMeshDetail));
|
buildPolyMeshDetail(context, polyMesh, compact, config.detailSampleDist, config.detailSampleMaxError,
|
||||||
|
polyMeshDetail);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < polyMesh.npolys; ++i)
|
for (int i = 0; i < polyMesh.npolys; ++i)
|
||||||
|
@ -323,7 +397,10 @@ namespace
|
||||||
|
|
||||||
unsigned char* navMeshData;
|
unsigned char* navMeshData;
|
||||||
int navMeshDataSize;
|
int navMeshDataSize;
|
||||||
OPENMW_CHECK_DT_RESULT(dtCreateNavMeshData(¶ms, &navMeshData, &navMeshDataSize));
|
const auto navMeshDataCreated = dtCreateNavMeshData(¶ms, &navMeshData, &navMeshDataSize);
|
||||||
|
|
||||||
|
if (!navMeshDataCreated)
|
||||||
|
throw NavigatorException("Failed to create navmesh tile data");
|
||||||
|
|
||||||
return NavMeshData(navMeshData, navMeshDataSize);
|
return NavMeshData(navMeshData, navMeshDataSize);
|
||||||
}
|
}
|
||||||
|
@ -360,7 +437,10 @@ namespace DetourNavigator
|
||||||
params.maxPolys = maxPolysPerTile;
|
params.maxPolys = maxPolysPerTile;
|
||||||
|
|
||||||
NavMeshPtr navMesh(dtAllocNavMesh(), &dtFreeNavMesh);
|
NavMeshPtr navMesh(dtAllocNavMesh(), &dtFreeNavMesh);
|
||||||
OPENMW_CHECK_DT_STATUS(navMesh->init(¶ms));
|
const auto status = navMesh->init(¶ms);
|
||||||
|
|
||||||
|
if (!dtStatusSucceed(status))
|
||||||
|
throw NavigatorException("Failed to init navmesh");
|
||||||
|
|
||||||
return navMesh;
|
return navMesh;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace DetourNavigator
|
||||||
, mChunkyTriMesh(mVertices, mIndices, mAreaTypes, trianglesPerChunk)
|
, mChunkyTriMesh(mVertices, mIndices, mAreaTypes, trianglesPerChunk)
|
||||||
{
|
{
|
||||||
if (getTrianglesCount() != mAreaTypes.size())
|
if (getTrianglesCount() != mAreaTypes.size())
|
||||||
throw InvalidArgument("number of flags doesn't match number of triangles: triangles="
|
throw InvalidArgument("Number of flags doesn't match number of triangles: triangles="
|
||||||
+ std::to_string(getTrianglesCount()) + ", areaTypes=" + std::to_string(mAreaTypes.size()));
|
+ std::to_string(getTrianglesCount()) + ", areaTypes=" + std::to_string(mAreaTypes.size()));
|
||||||
if (getVerticesCount())
|
if (getVerticesCount())
|
||||||
rcCalcBounds(mVertices.data(), static_cast<int>(getVerticesCount()), mBoundsMin.ptr(), mBoundsMax.ptr());
|
rcCalcBounds(mVertices.data(), static_cast<int>(getVerticesCount()), mBoundsMin.ptr(), mBoundsMax.ptr());
|
||||||
|
|
Loading…
Reference in a new issue