mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-03 07:09:40 +00:00
Split navigator settings into subtypes
Mostly to distinguish settings that affect properties of the generated navmesh.
This commit is contained in:
parent
33bb18850d
commit
01c712d5f1
38 changed files with 327 additions and 304 deletions
|
@ -4,6 +4,7 @@
|
|||
#include <components/sceneutil/agentpath.hpp>
|
||||
#include <components/resource/resourcesystem.hpp>
|
||||
#include <components/resource/scenemanager.hpp>
|
||||
#include <components/detournavigator/settings.hpp>
|
||||
|
||||
#include <osg/PositionAttitudeTransform>
|
||||
|
||||
|
@ -47,7 +48,7 @@ namespace MWRender
|
|||
if (group != mGroups.end())
|
||||
mRootNode->removeChild(group->second);
|
||||
|
||||
const auto newGroup = SceneUtil::createAgentPathGroup(path, halfExtents, start, end, settings);
|
||||
const auto newGroup = SceneUtil::createAgentPathGroup(path, halfExtents, start, end, settings.mRecast);
|
||||
if (newGroup)
|
||||
{
|
||||
MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(newGroup, "debug");
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace MWRender
|
|||
if (it->second.mGeneration != tile->second->getGeneration()
|
||||
|| it->second.mRevision != tile->second->getRevision())
|
||||
{
|
||||
const auto group = SceneUtil::createRecastMeshGroup(*tile->second, settings);
|
||||
const auto group = SceneUtil::createRecastMeshGroup(*tile->second, settings.mRecast);
|
||||
MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(group, "debug");
|
||||
group->setNodeMask(Mask_Debug);
|
||||
mRootNode->removeChild(it->second.mValue);
|
||||
|
@ -71,7 +71,7 @@ namespace MWRender
|
|||
{
|
||||
if (mGroups.count(tile.first))
|
||||
continue;
|
||||
const auto group = SceneUtil::createRecastMeshGroup(*tile.second, settings);
|
||||
const auto group = SceneUtil::createRecastMeshGroup(*tile.second, settings.mRecast);
|
||||
MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(group, "debug");
|
||||
group->setNodeMask(Mask_Debug);
|
||||
mGroups.emplace(tile.first, Group {tile.second->getGeneration(), tile.second->getRevision(), group});
|
||||
|
|
|
@ -186,7 +186,7 @@ namespace MWWorld
|
|||
if (Settings::Manager::getBool("enable", "Navigator"))
|
||||
{
|
||||
auto navigatorSettings = DetourNavigator::makeSettingsFromSettingsManager();
|
||||
navigatorSettings.mSwimHeightScale = mSwimHeightScale;
|
||||
navigatorSettings.mRecast.mSwimHeightScale = mSwimHeightScale;
|
||||
mNavigator = DetourNavigator::makeNavigator(navigatorSettings);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace
|
|||
|
||||
struct DetourNavigatorGetTilesPositionsTest : Test
|
||||
{
|
||||
Settings mSettings;
|
||||
RecastSettings mSettings;
|
||||
std::vector<TilePosition> mTilesPositions;
|
||||
CollectTilesPositions mCollect {mTilesPositions};
|
||||
|
||||
|
|
|
@ -63,28 +63,28 @@ namespace
|
|||
mSettings.mEnableWriteNavMeshToFile = false;
|
||||
mSettings.mEnableRecastMeshFileNameRevision = false;
|
||||
mSettings.mEnableNavMeshFileNameRevision = false;
|
||||
mSettings.mBorderSize = 16;
|
||||
mSettings.mCellHeight = 0.2f;
|
||||
mSettings.mCellSize = 0.2f;
|
||||
mSettings.mDetailSampleDist = 6;
|
||||
mSettings.mDetailSampleMaxError = 1;
|
||||
mSettings.mMaxClimb = 34;
|
||||
mSettings.mMaxSimplificationError = 1.3f;
|
||||
mSettings.mMaxSlope = 49;
|
||||
mSettings.mRecastScaleFactor = 0.017647058823529415f;
|
||||
mSettings.mSwimHeightScale = 0.89999997615814208984375f;
|
||||
mSettings.mMaxEdgeLen = 12;
|
||||
mSettings.mMaxNavMeshQueryNodes = 2048;
|
||||
mSettings.mMaxVertsPerPoly = 6;
|
||||
mSettings.mRegionMergeSize = 20;
|
||||
mSettings.mRegionMinSize = 8;
|
||||
mSettings.mTileSize = 64;
|
||||
mSettings.mRecast.mBorderSize = 16;
|
||||
mSettings.mRecast.mCellHeight = 0.2f;
|
||||
mSettings.mRecast.mCellSize = 0.2f;
|
||||
mSettings.mRecast.mDetailSampleDist = 6;
|
||||
mSettings.mRecast.mDetailSampleMaxError = 1;
|
||||
mSettings.mRecast.mMaxClimb = 34;
|
||||
mSettings.mRecast.mMaxSimplificationError = 1.3f;
|
||||
mSettings.mRecast.mMaxSlope = 49;
|
||||
mSettings.mRecast.mRecastScaleFactor = 0.017647058823529415f;
|
||||
mSettings.mRecast.mSwimHeightScale = 0.89999997615814208984375f;
|
||||
mSettings.mRecast.mMaxEdgeLen = 12;
|
||||
mSettings.mDetour.mMaxNavMeshQueryNodes = 2048;
|
||||
mSettings.mRecast.mMaxVertsPerPoly = 6;
|
||||
mSettings.mRecast.mRegionMergeArea = 400;
|
||||
mSettings.mRecast.mRegionMinArea = 64;
|
||||
mSettings.mRecast.mTileSize = 64;
|
||||
mSettings.mWaitUntilMinDistanceToPlayer = std::numeric_limits<int>::max();
|
||||
mSettings.mAsyncNavMeshUpdaterThreads = 1;
|
||||
mSettings.mMaxNavMeshTilesCacheSize = 1024 * 1024;
|
||||
mSettings.mMaxPolygonPathSize = 1024;
|
||||
mSettings.mMaxSmoothPathSize = 1024;
|
||||
mSettings.mMaxPolys = 4096;
|
||||
mSettings.mDetour.mMaxPolygonPathSize = 1024;
|
||||
mSettings.mDetour.mMaxSmoothPathSize = 1024;
|
||||
mSettings.mDetour.mMaxPolys = 4096;
|
||||
mSettings.mMaxTilesNumber = 512;
|
||||
mSettings.mMinUpdateInterval = std::chrono::milliseconds(50);
|
||||
mNavigator.reset(new NavigatorImpl(mSettings));
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace
|
|||
|
||||
struct DetourNavigatorGetTilePositionTest : Test
|
||||
{
|
||||
Settings mSettings;
|
||||
RecastSettings mSettings;
|
||||
|
||||
DetourNavigatorGetTilePositionTest()
|
||||
{
|
||||
|
@ -47,7 +47,7 @@ namespace
|
|||
|
||||
struct DetourNavigatorMakeTileBoundsTest : Test
|
||||
{
|
||||
Settings mSettings;
|
||||
RecastSettings mSettings;
|
||||
|
||||
DetourNavigatorMakeTileBoundsTest()
|
||||
{
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace
|
|||
|
||||
struct DetourNavigatorTileCachedRecastMeshManagerTest : Test
|
||||
{
|
||||
Settings mSettings;
|
||||
RecastSettings mSettings;
|
||||
std::vector<TilePosition> mChangedTiles;
|
||||
const ObjectTransform mObjectTransform {ESM::Position {{0, 0, 0}, {0, 0, 0}}, 0.0f};
|
||||
const osg::ref_ptr<const Resource::BulletShape> mShape = new Resource::BulletShape;
|
||||
|
|
|
@ -404,7 +404,7 @@ namespace DetourNavigator
|
|||
}
|
||||
if (recastMesh && mSettings.get().mEnableWriteRecastMeshToFile)
|
||||
writeToFile(*recastMesh, mSettings.get().mRecastMeshPathPrefix + std::to_string(job.mChangedTile.x())
|
||||
+ "_" + std::to_string(job.mChangedTile.y()) + "_", recastMeshRevision, mSettings);
|
||||
+ "_" + std::to_string(job.mChangedTile.y()) + "_", recastMeshRevision, mSettings.get().mRecast);
|
||||
if (mSettings.get().mEnableWriteNavMeshToFile)
|
||||
if (const auto shared = job.mNavMeshCacheItem.lock())
|
||||
writeToFile(shared->lockConst()->getImpl(), mSettings.get().mNavMeshPathPrefix, navMeshRevision);
|
||||
|
|
|
@ -11,7 +11,8 @@
|
|||
|
||||
namespace DetourNavigator
|
||||
{
|
||||
void writeToFile(const RecastMesh& recastMesh, const std::string& pathPrefix, const std::string& revision, const Settings& settings)
|
||||
void writeToFile(const RecastMesh& recastMesh, const std::string& pathPrefix,
|
||||
const std::string& revision, const RecastSettings& settings)
|
||||
{
|
||||
const auto path = pathPrefix + "recastmesh" + revision + ".obj";
|
||||
boost::filesystem::ofstream file(boost::filesystem::path(path), std::ios::out);
|
||||
|
|
|
@ -70,9 +70,10 @@ namespace DetourNavigator
|
|||
}
|
||||
|
||||
class RecastMesh;
|
||||
struct Settings;
|
||||
struct RecastSettings;
|
||||
|
||||
void writeToFile(const RecastMesh& recastMesh, const std::string& pathPrefix, const std::string& revision, const Settings& settings);
|
||||
void writeToFile(const RecastMesh& recastMesh, const std::string& pathPrefix,
|
||||
const std::string& revision, const RecastSettings& settings);
|
||||
void writeToFile(const dtNavMesh& navMesh, const std::string& pathPrefix, const std::string& revision);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
namespace DetourNavigator
|
||||
{
|
||||
std::optional<osg::Vec3f> findRandomPointAroundCircle(const dtNavMesh& navMesh, const osg::Vec3f& halfExtents,
|
||||
const osg::Vec3f& start, const float maxRadius, const Flags includeFlags, const Settings& settings)
|
||||
const osg::Vec3f& start, const float maxRadius, const Flags includeFlags, const DetourSettings& settings)
|
||||
{
|
||||
dtNavMeshQuery navMeshQuery;
|
||||
if (!initNavMeshQuery(navMeshQuery, navMesh, settings.mMaxNavMeshQueryNodes))
|
||||
|
|
|
@ -10,10 +10,10 @@ class dtNavMesh;
|
|||
|
||||
namespace DetourNavigator
|
||||
{
|
||||
struct Settings;
|
||||
struct DetourSettings;
|
||||
|
||||
std::optional<osg::Vec3f> findRandomPointAroundCircle(const dtNavMesh& navMesh, const osg::Vec3f& halfExtents,
|
||||
const osg::Vec3f& start, const float maxRadius, const Flags includeFlags, const Settings& settings);
|
||||
const osg::Vec3f& start, const float maxRadius, const Flags includeFlags, const DetourSettings& settings);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace DetourNavigator
|
|||
class OutputTransformIterator
|
||||
{
|
||||
public:
|
||||
OutputTransformIterator(OutputIterator& impl, const Settings& settings)
|
||||
explicit OutputTransformIterator(OutputIterator& impl, const RecastSettings& settings)
|
||||
: mImpl(impl), mSettings(settings)
|
||||
{
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ namespace DetourNavigator
|
|||
|
||||
private:
|
||||
std::reference_wrapper<OutputIterator> mImpl;
|
||||
std::reference_wrapper<const Settings> mSettings;
|
||||
std::reference_wrapper<const RecastSettings> mSettings;
|
||||
};
|
||||
|
||||
inline bool initNavMeshQuery(dtNavMeshQuery& value, const dtNavMesh& navMesh, const int maxNodes)
|
||||
|
@ -261,7 +261,7 @@ namespace DetourNavigator
|
|||
const Settings& settings, float endTolerance, OutputIterator& out)
|
||||
{
|
||||
dtNavMeshQuery navMeshQuery;
|
||||
if (!initNavMeshQuery(navMeshQuery, navMesh, settings.mMaxNavMeshQueryNodes))
|
||||
if (!initNavMeshQuery(navMeshQuery, navMesh, settings.mDetour.mMaxNavMeshQueryNodes))
|
||||
return Status::InitNavMeshQueryFailed;
|
||||
|
||||
dtQueryFilter queryFilter;
|
||||
|
@ -283,7 +283,7 @@ namespace DetourNavigator
|
|||
if (endRef == 0)
|
||||
return Status::EndPolygonNotFound;
|
||||
|
||||
std::vector<dtPolyRef> polygonPath(settings.mMaxPolygonPathSize);
|
||||
std::vector<dtPolyRef> polygonPath(settings.mDetour.mMaxPolygonPathSize);
|
||||
const auto polygonPathSize = findPath(navMeshQuery, startRef, endRef, start, end, queryFilter,
|
||||
polygonPath.data(), polygonPath.size());
|
||||
|
||||
|
@ -294,9 +294,9 @@ namespace DetourNavigator
|
|||
return Status::Success;
|
||||
|
||||
const bool partialPath = polygonPath[*polygonPathSize - 1] != endRef;
|
||||
auto outTransform = OutputTransformIterator<OutputIterator>(out, settings);
|
||||
auto outTransform = OutputTransformIterator<OutputIterator>(out, settings.mRecast);
|
||||
const Status smoothStatus = makeSmoothPath(navMesh, navMeshQuery, queryFilter, start, end, stepSize,
|
||||
polygonPath, *polygonPathSize, settings.mMaxSmoothPathSize, outTransform);
|
||||
polygonPath, *polygonPathSize, settings.mDetour.mMaxSmoothPathSize, outTransform);
|
||||
|
||||
if (smoothStatus != Status::Success)
|
||||
return smoothStatus;
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace DetourNavigator
|
|||
{
|
||||
template <class Callback>
|
||||
void getTilesPositions(const osg::Vec3f& aabbMin, const osg::Vec3f& aabbMax,
|
||||
const Settings& settings, Callback&& callback)
|
||||
const RecastSettings& settings, Callback&& callback)
|
||||
{
|
||||
auto min = toNavMeshCoordinates(settings, aabbMin);
|
||||
auto max = toNavMeshCoordinates(settings, aabbMax);
|
||||
|
@ -40,7 +40,7 @@ namespace DetourNavigator
|
|||
|
||||
template <class Callback>
|
||||
void getTilesPositions(const btCollisionShape& shape, const btTransform& transform,
|
||||
const Settings& settings, Callback&& callback)
|
||||
const RecastSettings& settings, Callback&& callback)
|
||||
{
|
||||
btVector3 aabbMin;
|
||||
btVector3 aabbMax;
|
||||
|
@ -51,7 +51,7 @@ namespace DetourNavigator
|
|||
|
||||
template <class Callback>
|
||||
void getTilesPositions(const int cellSize, const btVector3& shift,
|
||||
const Settings& settings, Callback&& callback)
|
||||
const RecastSettings& settings, Callback&& callback)
|
||||
{
|
||||
using Misc::Convert::toOsg;
|
||||
|
||||
|
|
|
@ -36,32 +36,6 @@ namespace
|
|||
float mHeight;
|
||||
};
|
||||
|
||||
Rectangle getSwimRectangle(const CellWater& water, const Settings& settings, const osg::Vec3f& agentHalfExtents)
|
||||
{
|
||||
if (water.mWater.mCellSize == std::numeric_limits<int>::max())
|
||||
{
|
||||
return Rectangle {
|
||||
TileBounds {
|
||||
osg::Vec2f(-std::numeric_limits<float>::max(), -std::numeric_limits<float>::max()),
|
||||
osg::Vec2f(std::numeric_limits<float>::max(), std::numeric_limits<float>::max())
|
||||
},
|
||||
toNavMeshCoordinates(settings, getSwimLevel(settings, water.mWater.mLevel, agentHalfExtents.z()))
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
const osg::Vec2f shift = getWaterShift2d(water.mCellPosition, water.mWater.mCellSize);
|
||||
const float halfCellSize = water.mWater.mCellSize / 2.0f;
|
||||
return Rectangle {
|
||||
TileBounds{
|
||||
toNavMeshCoordinates(settings, shift + osg::Vec2f(-halfCellSize, -halfCellSize)),
|
||||
toNavMeshCoordinates(settings, shift + osg::Vec2f(halfCellSize, halfCellSize))
|
||||
},
|
||||
toNavMeshCoordinates(settings, getSwimLevel(settings, water.mWater.mLevel, agentHalfExtents.z()))
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<float> getOffMeshVerts(const std::vector<OffMeshConnection>& connections)
|
||||
{
|
||||
std::vector<float> result;
|
||||
|
@ -120,52 +94,46 @@ namespace
|
|||
return result;
|
||||
}
|
||||
|
||||
rcConfig makeConfig(const osg::Vec3f& agentHalfExtents, const TilePosition& tile, float minZ, float maxZ,
|
||||
const Settings& settings)
|
||||
float getHeight(const RecastSettings& settings,const osg::Vec3f& agentHalfExtents)
|
||||
{
|
||||
rcConfig config;
|
||||
|
||||
config.cs = settings.mCellSize;
|
||||
config.ch = settings.mCellHeight;
|
||||
config.walkableSlopeAngle = settings.mMaxSlope;
|
||||
config.walkableHeight = static_cast<int>(std::ceil(getHeight(settings, agentHalfExtents) / config.ch));
|
||||
config.walkableClimb = static_cast<int>(std::floor(getMaxClimb(settings) / config.ch));
|
||||
config.walkableRadius = static_cast<int>(std::ceil(getRadius(settings, agentHalfExtents) / config.cs));
|
||||
config.maxEdgeLen = static_cast<int>(std::round(settings.mMaxEdgeLen / config.cs));
|
||||
config.maxSimplificationError = settings.mMaxSimplificationError;
|
||||
config.minRegionArea = settings.mRegionMinSize * settings.mRegionMinSize;
|
||||
config.mergeRegionArea = settings.mRegionMergeSize * settings.mRegionMergeSize;
|
||||
config.maxVertsPerPoly = settings.mMaxVertsPerPoly;
|
||||
config.detailSampleDist = settings.mDetailSampleDist < 0.9f ? 0 : config.cs * settings.mDetailSampleDist;
|
||||
config.detailSampleMaxError = config.ch * settings.mDetailSampleMaxError;
|
||||
config.borderSize = settings.mBorderSize;
|
||||
config.tileSize = settings.mTileSize;
|
||||
const int size = config.tileSize + config.borderSize * 2;
|
||||
config.width = size;
|
||||
config.height = size;
|
||||
const float halfBoundsSize = size * config.cs * 0.5f;
|
||||
const osg::Vec2f shift = osg::Vec2f(tile.x() + 0.5f, tile.y() + 0.5f) * getTileSize(settings);
|
||||
config.bmin[0] = shift.x() - halfBoundsSize;
|
||||
config.bmin[1] = minZ;
|
||||
config.bmin[2] = shift.y() - halfBoundsSize;
|
||||
config.bmax[0] = shift.x() + halfBoundsSize;
|
||||
config.bmax[1] = maxZ;
|
||||
config.bmax[2] = shift.y() + halfBoundsSize;
|
||||
|
||||
return config;
|
||||
return 2.0f * agentHalfExtents.z() * settings.mRecastScaleFactor;
|
||||
}
|
||||
|
||||
void createHeightfield(rcContext& context, rcHeightfield& solid, int width, int height, const float* bmin,
|
||||
const float* bmax, const float cs, const float ch)
|
||||
float getMaxClimb(const RecastSettings& settings)
|
||||
{
|
||||
const auto result = rcCreateHeightfield(&context, solid, width, height, bmin, bmax, cs, ch);
|
||||
return settings.mMaxClimb * settings.mRecastScaleFactor;
|
||||
}
|
||||
|
||||
float getRadius(const RecastSettings& settings, const osg::Vec3f& agentHalfExtents)
|
||||
{
|
||||
return std::max(agentHalfExtents.x(), agentHalfExtents.y()) * std::sqrt(2) * settings.mRecastScaleFactor;
|
||||
}
|
||||
|
||||
float getSwimLevel(const RecastSettings& settings, const float waterLevel, const float agentHalfExtentsZ)
|
||||
{
|
||||
return waterLevel - settings.mSwimHeightScale * agentHalfExtentsZ - agentHalfExtentsZ;;
|
||||
}
|
||||
|
||||
void initHeightfield(rcContext& context, const TilePosition& tilePosition, float minZ, float maxZ,
|
||||
const RecastSettings& settings, rcHeightfield& solid)
|
||||
{
|
||||
const int size = settings.mTileSize + settings.mBorderSize * 2;
|
||||
const int width = size;
|
||||
const int height = size;
|
||||
const float halfBoundsSize = size * settings.mCellSize * 0.5f;
|
||||
const osg::Vec2f shift = osg::Vec2f(tilePosition.x() + 0.5f, tilePosition.y() + 0.5f) * getTileSize(settings);
|
||||
const osg::Vec3f bmin(shift.x() - halfBoundsSize, minZ, shift.y() - halfBoundsSize);
|
||||
const osg::Vec3f bmax(shift.x() + halfBoundsSize, maxZ, shift.y() + halfBoundsSize);
|
||||
|
||||
const auto result = rcCreateHeightfield(&context, solid, width, height, bmin.ptr(), bmax.ptr(),
|
||||
settings.mCellSize, settings.mCellHeight);
|
||||
|
||||
if (!result)
|
||||
throw NavigatorException("Failed to create heightfield for navmesh");
|
||||
}
|
||||
|
||||
bool rasterizeTriangles(rcContext& context, const Mesh& mesh, const Settings& settings, const rcConfig& config,
|
||||
rcHeightfield& solid)
|
||||
bool rasterizeTriangles(rcContext& context, const Mesh& mesh, const RecastSettings& settings,
|
||||
const RecastParams& params, rcHeightfield& solid)
|
||||
{
|
||||
std::vector<unsigned char> areas(mesh.getAreaTypes().begin(), mesh.getAreaTypes().end());
|
||||
std::vector<float> vertices = mesh.getVertices();
|
||||
|
@ -179,7 +147,7 @@ namespace
|
|||
|
||||
rcClearUnwalkableTriangles(
|
||||
&context,
|
||||
config.walkableSlopeAngle,
|
||||
settings.mMaxSlope,
|
||||
vertices.data(),
|
||||
static_cast<int>(mesh.getVerticesCount()),
|
||||
mesh.getIndices().data(),
|
||||
|
@ -195,30 +163,18 @@ namespace
|
|||
areas.data(),
|
||||
static_cast<int>(areas.size()),
|
||||
solid,
|
||||
config.walkableClimb
|
||||
params.mWalkableClimb
|
||||
);
|
||||
}
|
||||
|
||||
bool rasterizeTriangles(rcContext& context, const Rectangle& rectangle, const rcConfig& config,
|
||||
AreaType areaType, rcHeightfield& solid)
|
||||
bool rasterizeTriangles(rcContext& context, const Rectangle& rectangle, AreaType areaType,
|
||||
const RecastParams& params, rcHeightfield& solid)
|
||||
{
|
||||
const osg::Vec2f tileBoundsMin(
|
||||
std::clamp(rectangle.mBounds.mMin.x(), config.bmin[0], config.bmax[0]),
|
||||
std::clamp(rectangle.mBounds.mMin.y(), config.bmin[2], config.bmax[2])
|
||||
);
|
||||
const osg::Vec2f tileBoundsMax(
|
||||
std::clamp(rectangle.mBounds.mMax.x(), config.bmin[0], config.bmax[0]),
|
||||
std::clamp(rectangle.mBounds.mMax.y(), config.bmin[2], config.bmax[2])
|
||||
);
|
||||
|
||||
if (tileBoundsMax == tileBoundsMin)
|
||||
return true;
|
||||
|
||||
const std::array vertices {
|
||||
tileBoundsMin.x(), rectangle.mHeight, tileBoundsMin.y(),
|
||||
tileBoundsMin.x(), rectangle.mHeight, tileBoundsMax.y(),
|
||||
tileBoundsMax.x(), rectangle.mHeight, tileBoundsMax.y(),
|
||||
tileBoundsMax.x(), rectangle.mHeight, tileBoundsMin.y(),
|
||||
rectangle.mBounds.mMin.x(), rectangle.mHeight, rectangle.mBounds.mMin.y(),
|
||||
rectangle.mBounds.mMin.x(), rectangle.mHeight, rectangle.mBounds.mMax.y(),
|
||||
rectangle.mBounds.mMax.x(), rectangle.mHeight, rectangle.mBounds.mMax.y(),
|
||||
rectangle.mBounds.mMax.x(), rectangle.mHeight, rectangle.mBounds.mMin.y(),
|
||||
};
|
||||
|
||||
const std::array indices {
|
||||
|
@ -236,31 +192,42 @@ namespace
|
|||
areas.data(),
|
||||
static_cast<int>(areas.size()),
|
||||
solid,
|
||||
config.walkableClimb
|
||||
params.mWalkableClimb
|
||||
);
|
||||
}
|
||||
|
||||
bool rasterizeTriangles(rcContext& context, const osg::Vec3f& agentHalfExtents, const std::vector<CellWater>& water,
|
||||
const Settings& settings, const rcConfig& config, rcHeightfield& solid)
|
||||
const RecastSettings& settings, const RecastParams& params, const TileBounds& realTileBounds, rcHeightfield& solid)
|
||||
{
|
||||
for (const CellWater& cellWater : water)
|
||||
{
|
||||
const Rectangle rectangle = getSwimRectangle(cellWater, settings, agentHalfExtents);
|
||||
if (!rasterizeTriangles(context, rectangle, config, AreaType_water, solid))
|
||||
return false;
|
||||
const TileBounds cellTileBounds = maxCellTileBounds(cellWater.mCellPosition, cellWater.mWater.mCellSize);
|
||||
if (auto intersection = getIntersection(realTileBounds, cellTileBounds))
|
||||
{
|
||||
const Rectangle rectangle {
|
||||
toNavMeshCoordinates(settings, *intersection),
|
||||
toNavMeshCoordinates(settings, getSwimLevel(settings, cellWater.mWater.mLevel, agentHalfExtents.z()))
|
||||
};
|
||||
if (!rasterizeTriangles(context, rectangle, AreaType_water, params, solid))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rasterizeTriangles(rcContext& context, const TileBounds& tileBounds, const std::vector<FlatHeightfield>& heightfields,
|
||||
const Settings& settings, const rcConfig& config, rcHeightfield& solid)
|
||||
bool rasterizeTriangles(rcContext& context, const TileBounds& realTileBounds, const std::vector<FlatHeightfield>& heightfields,
|
||||
const RecastSettings& settings, const RecastParams& params, rcHeightfield& solid)
|
||||
{
|
||||
for (const FlatHeightfield& heightfield : heightfields)
|
||||
{
|
||||
if (auto intersection = getIntersection(tileBounds, maxCellTileBounds(heightfield.mCellPosition, heightfield.mCellSize)))
|
||||
const TileBounds cellTileBounds = maxCellTileBounds(heightfield.mCellPosition, heightfield.mCellSize);
|
||||
if (auto intersection = getIntersection(realTileBounds, cellTileBounds))
|
||||
{
|
||||
const Rectangle rectangle {*intersection, toNavMeshCoordinates(settings, heightfield.mHeight)};
|
||||
if (!rasterizeTriangles(context, rectangle, config, AreaType_ground, solid))
|
||||
const Rectangle rectangle {
|
||||
toNavMeshCoordinates(settings, *intersection),
|
||||
toNavMeshCoordinates(settings, heightfield.mHeight)
|
||||
};
|
||||
if (!rasterizeTriangles(context, rectangle, AreaType_ground, params, solid))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -268,27 +235,25 @@ namespace
|
|||
}
|
||||
|
||||
bool rasterizeTriangles(rcContext& context, const std::vector<Heightfield>& heightfields,
|
||||
const Settings& settings, const rcConfig& config, rcHeightfield& solid)
|
||||
const RecastSettings& settings, const RecastParams& params, rcHeightfield& solid)
|
||||
{
|
||||
using BulletHelpers::makeProcessTriangleCallback;
|
||||
|
||||
for (const Heightfield& heightfield : heightfields)
|
||||
{
|
||||
const Mesh mesh = makeMesh(heightfield);
|
||||
if (!rasterizeTriangles(context, mesh, settings, config, solid))
|
||||
if (!rasterizeTriangles(context, mesh, settings, params, solid))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rasterizeTriangles(rcContext& context, const TilePosition& tilePosition, const osg::Vec3f& agentHalfExtents,
|
||||
const RecastMesh& recastMesh, const rcConfig& config, const Settings& settings, rcHeightfield& solid)
|
||||
const RecastMesh& recastMesh, const RecastSettings& settings, const RecastParams& params, rcHeightfield& solid)
|
||||
{
|
||||
return rasterizeTriangles(context, recastMesh.getMesh(), settings, config, solid)
|
||||
&& rasterizeTriangles(context, agentHalfExtents, recastMesh.getWater(), settings, config, solid)
|
||||
&& rasterizeTriangles(context, recastMesh.getHeightfields(), settings, config, solid)
|
||||
&& rasterizeTriangles(context, makeRealTileBoundsWithBorder(settings, tilePosition),
|
||||
recastMesh.getFlatHeightfields(), settings, config, solid);
|
||||
const TileBounds realTileBounds = makeRealTileBoundsWithBorder(settings, tilePosition);
|
||||
return rasterizeTriangles(context, recastMesh.getMesh(), settings, params, solid)
|
||||
&& rasterizeTriangles(context, agentHalfExtents, recastMesh.getWater(), settings, params, realTileBounds, solid)
|
||||
&& rasterizeTriangles(context, recastMesh.getHeightfields(), settings, params, solid)
|
||||
&& rasterizeTriangles(context, realTileBounds, recastMesh.getFlatHeightfields(), settings, params, solid);
|
||||
}
|
||||
|
||||
void buildCompactHeightfield(rcContext& context, const int walkableHeight, const int walkableClimb,
|
||||
|
@ -359,27 +324,25 @@ namespace
|
|||
polyMesh.flags[i] = getFlag(static_cast<AreaType>(polyMesh.areas[i]));
|
||||
}
|
||||
|
||||
bool fillPolyMesh(rcContext& context, const rcConfig& config, rcHeightfield& solid, rcPolyMesh& polyMesh,
|
||||
rcPolyMeshDetail& polyMeshDetail)
|
||||
bool fillPolyMesh(rcContext& context, const RecastSettings& settings, const RecastParams& params,
|
||||
rcHeightfield& solid, rcPolyMesh& polyMesh, rcPolyMeshDetail& polyMeshDetail)
|
||||
{
|
||||
rcCompactHeightfield compact;
|
||||
compact.dist = nullptr;
|
||||
buildCompactHeightfield(context, config.walkableHeight, config.walkableClimb, solid, compact);
|
||||
buildCompactHeightfield(context, params.mWalkableHeight, params.mWalkableClimb, solid, compact);
|
||||
|
||||
erodeWalkableArea(context, config.walkableRadius, compact);
|
||||
erodeWalkableArea(context, params.mWalkableRadius, compact);
|
||||
buildDistanceField(context, compact);
|
||||
buildRegions(context, compact, config.borderSize, config.minRegionArea, config.mergeRegionArea);
|
||||
buildRegions(context, compact, settings.mBorderSize, settings.mRegionMinArea, settings.mRegionMergeArea);
|
||||
|
||||
rcContourSet contourSet;
|
||||
buildContours(context, compact, config.maxSimplificationError, config.maxEdgeLen, contourSet);
|
||||
buildContours(context, compact, settings.mMaxSimplificationError, params.mMaxEdgeLen, contourSet);
|
||||
|
||||
if (contourSet.nconts == 0)
|
||||
return false;
|
||||
|
||||
buildPolyMesh(context, contourSet, config.maxVertsPerPoly, polyMesh);
|
||||
buildPolyMesh(context, contourSet, settings.mMaxVertsPerPoly, polyMesh);
|
||||
|
||||
buildPolyMeshDetail(context, polyMesh, compact, config.detailSampleDist, config.detailSampleMaxError,
|
||||
polyMeshDetail);
|
||||
buildPolyMeshDetail(context, polyMesh, compact, params.mSampleDist, params.mSampleMaxError, polyMeshDetail);
|
||||
|
||||
setPolyMeshFlags(polyMesh);
|
||||
|
||||
|
@ -395,7 +358,7 @@ namespace
|
|||
return power;
|
||||
}
|
||||
|
||||
std::pair<float, float> getBoundsByZ(const RecastMesh& recastMesh, const osg::Vec3f& agentHalfExtents, const Settings& settings)
|
||||
std::pair<float, float> getBoundsByZ(const RecastMesh& recastMesh, const osg::Vec3f& agentHalfExtents, const RecastSettings& settings)
|
||||
{
|
||||
float minZ = 0;
|
||||
float maxZ = 0;
|
||||
|
@ -436,39 +399,54 @@ namespace
|
|||
|
||||
namespace DetourNavigator
|
||||
{
|
||||
RecastParams makeRecastParams(const RecastSettings& settings, const osg::Vec3f& agentHalfExtents)
|
||||
{
|
||||
RecastParams result;
|
||||
|
||||
result.mWalkableHeight = static_cast<int>(std::ceil(getHeight(settings, agentHalfExtents) / settings.mCellHeight));
|
||||
result.mWalkableClimb = static_cast<int>(std::floor(getMaxClimb(settings) / settings.mCellHeight));
|
||||
result.mWalkableRadius = static_cast<int>(std::ceil(getRadius(settings, agentHalfExtents) / settings.mCellSize));
|
||||
result.mMaxEdgeLen = static_cast<int>(std::round(static_cast<float>(settings.mMaxEdgeLen) / settings.mCellSize));
|
||||
result.mSampleDist = settings.mDetailSampleDist < 0.9f ? 0 : settings.mCellSize * settings.mDetailSampleDist;
|
||||
result.mSampleMaxError = settings.mCellHeight * settings.mDetailSampleMaxError;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::unique_ptr<PreparedNavMeshData> prepareNavMeshTileData(const RecastMesh& recastMesh,
|
||||
const TilePosition& tilePosition, const osg::Vec3f& agentHalfExtents, const Settings& settings)
|
||||
const TilePosition& tilePosition, const osg::Vec3f& agentHalfExtents, const RecastSettings& settings)
|
||||
{
|
||||
const auto [minZ, maxZ] = getBoundsByZ(recastMesh, agentHalfExtents, settings);
|
||||
|
||||
rcContext context;
|
||||
const auto config = makeConfig(agentHalfExtents, tilePosition, toNavMeshCoordinates(settings, minZ),
|
||||
toNavMeshCoordinates(settings, maxZ), settings);
|
||||
|
||||
rcHeightfield solid;
|
||||
createHeightfield(context, solid, config.width, config.height, config.bmin, config.bmax, config.cs, config.ch);
|
||||
initHeightfield(context, tilePosition, toNavMeshCoordinates(settings, minZ),
|
||||
toNavMeshCoordinates(settings, maxZ), settings, solid);
|
||||
|
||||
if (!rasterizeTriangles(context, tilePosition, agentHalfExtents, recastMesh, config, settings, solid))
|
||||
const RecastParams params = makeRecastParams(settings, agentHalfExtents);
|
||||
|
||||
if (!rasterizeTriangles(context, tilePosition, agentHalfExtents, recastMesh, settings, params, solid))
|
||||
return nullptr;
|
||||
|
||||
rcFilterLowHangingWalkableObstacles(&context, config.walkableClimb, solid);
|
||||
rcFilterLedgeSpans(&context, config.walkableHeight, config.walkableClimb, solid);
|
||||
rcFilterWalkableLowHeightSpans(&context, config.walkableHeight, solid);
|
||||
rcFilterLowHangingWalkableObstacles(&context, params.mWalkableClimb, solid);
|
||||
rcFilterLedgeSpans(&context, params.mWalkableHeight, params.mWalkableClimb, solid);
|
||||
rcFilterWalkableLowHeightSpans(&context, params.mWalkableHeight, solid);
|
||||
|
||||
std::unique_ptr<PreparedNavMeshData> result = std::make_unique<PreparedNavMeshData>();
|
||||
|
||||
if (!fillPolyMesh(context, config, solid, result->mPolyMesh, result->mPolyMeshDetail))
|
||||
if (!fillPolyMesh(context, settings, params, solid, result->mPolyMesh, result->mPolyMeshDetail))
|
||||
return nullptr;
|
||||
|
||||
result->mCellSize = config.cs;
|
||||
result->mCellHeight = config.ch;
|
||||
result->mCellSize = settings.mCellSize;
|
||||
result->mCellHeight = settings.mCellHeight;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NavMeshData makeNavMeshTileData(const PreparedNavMeshData& data,
|
||||
const std::vector<OffMeshConnection>& offMeshConnections, const osg::Vec3f& agentHalfExtents,
|
||||
const TilePosition& tile, const Settings& settings)
|
||||
const TilePosition& tile, const RecastSettings& settings)
|
||||
{
|
||||
const auto offMeshConVerts = getOffMeshVerts(offMeshConnections);
|
||||
const std::vector<float> offMeshConRad(offMeshConnections.size(), getRadius(settings, agentHalfExtents));
|
||||
|
@ -524,7 +502,7 @@ namespace DetourNavigator
|
|||
// Max tiles and max polys affect how the tile IDs are caculated.
|
||||
// There are 22 bits available for identifying a tile and a polygon.
|
||||
const int polysAndTilesBits = 22;
|
||||
const auto polysBits = getMinValuableBitsNumber(settings.mMaxPolys);
|
||||
const auto polysBits = getMinValuableBitsNumber(settings.mDetour.mMaxPolys);
|
||||
|
||||
if (polysBits >= polysAndTilesBits)
|
||||
throw InvalidArgument("Too many polygons per tile");
|
||||
|
@ -533,8 +511,8 @@ namespace DetourNavigator
|
|||
|
||||
dtNavMeshParams params;
|
||||
std::fill_n(params.orig, 3, 0.0f);
|
||||
params.tileWidth = settings.mTileSize * settings.mCellSize;
|
||||
params.tileHeight = settings.mTileSize * settings.mCellSize;
|
||||
params.tileWidth = settings.mRecast.mTileSize * settings.mRecast.mCellSize;
|
||||
params.tileHeight = settings.mRecast.mTileSize * settings.mRecast.mCellSize;
|
||||
params.maxTiles = 1 << tilesBits;
|
||||
params.maxPolys = 1 << polysBits;
|
||||
|
||||
|
@ -558,9 +536,9 @@ namespace DetourNavigator
|
|||
{
|
||||
Log(Debug::Debug) << std::fixed << std::setprecision(2) <<
|
||||
"Update NavMesh with multiple tiles:" <<
|
||||
" agentHeight=" << getHeight(settings, agentHalfExtents) <<
|
||||
" agentMaxClimb=" << getMaxClimb(settings) <<
|
||||
" agentRadius=" << getRadius(settings, agentHalfExtents) <<
|
||||
" agentHeight=" << getHeight(settings.mRecast, agentHalfExtents) <<
|
||||
" agentMaxClimb=" << getMaxClimb(settings.mRecast) <<
|
||||
" agentRadius=" << getRadius(settings.mRecast, agentHalfExtents) <<
|
||||
" changedTile=(" << changedTile << ")" <<
|
||||
" playerTile=(" << playerTile << ")" <<
|
||||
" changedTileDistance=" << getDistance(changedTile, playerTile);
|
||||
|
@ -591,7 +569,7 @@ namespace DetourNavigator
|
|||
|
||||
if (!cachedNavMeshData)
|
||||
{
|
||||
auto prepared = prepareNavMeshTileData(*recastMesh, changedTile, agentHalfExtents, settings);
|
||||
auto prepared = prepareNavMeshTileData(*recastMesh, changedTile, agentHalfExtents, settings.mRecast);
|
||||
|
||||
if (prepared == nullptr)
|
||||
{
|
||||
|
@ -601,7 +579,7 @@ namespace DetourNavigator
|
|||
|
||||
if (updateType == UpdateType::Temporary)
|
||||
return navMeshCacheItem->lock()->updateTile(changedTile, NavMeshTilesCache::Value(),
|
||||
makeNavMeshTileData(*prepared, offMeshConnections, agentHalfExtents, changedTile, settings));
|
||||
makeNavMeshTileData(*prepared, offMeshConnections, agentHalfExtents, changedTile, settings.mRecast));
|
||||
|
||||
cachedNavMeshData = navMeshTilesCache.set(agentHalfExtents, changedTile, *recastMesh, std::move(prepared));
|
||||
|
||||
|
@ -609,12 +587,12 @@ namespace DetourNavigator
|
|||
{
|
||||
Log(Debug::Debug) << "Navigator cache overflow";
|
||||
return navMeshCacheItem->lock()->updateTile(changedTile, NavMeshTilesCache::Value(),
|
||||
makeNavMeshTileData(*prepared, offMeshConnections, agentHalfExtents, changedTile, settings));
|
||||
makeNavMeshTileData(*prepared, offMeshConnections, agentHalfExtents, changedTile, settings.mRecast));
|
||||
}
|
||||
}
|
||||
|
||||
const auto updateStatus = navMeshCacheItem->lock()->updateTile(changedTile, std::move(cachedNavMeshData),
|
||||
makeNavMeshTileData(cachedNavMeshData.get(), offMeshConnections, agentHalfExtents, changedTile, settings));
|
||||
makeNavMeshTileData(cachedNavMeshData.get(), offMeshConnections, agentHalfExtents, changedTile, settings.mRecast));
|
||||
|
||||
return UpdateNavMeshStatusBuilder(updateStatus).cached(cached).getResult();
|
||||
}
|
||||
|
|
|
@ -22,6 +22,16 @@ namespace DetourNavigator
|
|||
struct PreparedNavMeshData;
|
||||
struct NavMeshData;
|
||||
|
||||
struct RecastParams
|
||||
{
|
||||
float mSampleDist = 0;
|
||||
float mSampleMaxError = 0;
|
||||
int mMaxEdgeLen = 0;
|
||||
int mWalkableClimb = 0;
|
||||
int mWalkableHeight = 0;
|
||||
int mWalkableRadius = 0;
|
||||
};
|
||||
|
||||
inline float getLength(const osg::Vec2i& value)
|
||||
{
|
||||
return std::sqrt(float(osg::square(value.x()) + osg::square(value.y())));
|
||||
|
@ -38,12 +48,14 @@ namespace DetourNavigator
|
|||
return expectedTilesCount <= maxTiles;
|
||||
}
|
||||
|
||||
RecastParams makeRecastParams(const RecastSettings& settings, const osg::Vec3f& agentHalfExtents);
|
||||
|
||||
std::unique_ptr<PreparedNavMeshData> prepareNavMeshTileData(const RecastMesh& recastMesh, const TilePosition& tile,
|
||||
const Bounds& bounds, const osg::Vec3f& agentHalfExtents, const Settings& settings);
|
||||
|
||||
NavMeshData makeNavMeshTileData(const PreparedNavMeshData& data,
|
||||
const std::vector<OffMeshConnection>& offMeshConnections, const osg::Vec3f& agentHalfExtents,
|
||||
const TilePosition& tile, const Settings& settings);
|
||||
const TilePosition& tile, const RecastSettings& settings);
|
||||
|
||||
NavMeshPtr makeEmptyNavMesh(const Settings& settings);
|
||||
|
||||
|
|
|
@ -53,8 +53,8 @@ namespace DetourNavigator
|
|||
{
|
||||
if (addObject(id, static_cast<const ObjectShapes&>(shapes), transform))
|
||||
{
|
||||
const osg::Vec3f start = toNavMeshCoordinates(mSettings, shapes.mConnectionStart);
|
||||
const osg::Vec3f end = toNavMeshCoordinates(mSettings, shapes.mConnectionEnd);
|
||||
const osg::Vec3f start = toNavMeshCoordinates(mSettings.mRecast, shapes.mConnectionStart);
|
||||
const osg::Vec3f end = toNavMeshCoordinates(mSettings.mRecast, shapes.mConnectionEnd);
|
||||
mNavMeshManager.addOffMeshConnection(id, start, end, AreaType_door);
|
||||
mNavMeshManager.addOffMeshConnection(id, end, start, AreaType_door);
|
||||
return true;
|
||||
|
@ -126,8 +126,8 @@ namespace DetourNavigator
|
|||
const auto dst = Misc::Convert::makeOsgVec3f(converter.toWorldPoint(pathgrid.mPoints[edge.mV1]));
|
||||
mNavMeshManager.addOffMeshConnection(
|
||||
ObjectId(&pathgrid),
|
||||
toNavMeshCoordinates(mSettings, src),
|
||||
toNavMeshCoordinates(mSettings, dst),
|
||||
toNavMeshCoordinates(mSettings.mRecast, src),
|
||||
toNavMeshCoordinates(mSettings.mRecast, dst),
|
||||
AreaType_pathgrid
|
||||
);
|
||||
}
|
||||
|
@ -149,7 +149,7 @@ namespace DetourNavigator
|
|||
|
||||
void NavigatorImpl::updatePlayerPosition(const osg::Vec3f& playerPosition)
|
||||
{
|
||||
const TilePosition tilePosition = getTilePosition(mSettings, toNavMeshCoordinates(mSettings, playerPosition));
|
||||
const TilePosition tilePosition = getTilePosition(mSettings.mRecast, toNavMeshCoordinates(mSettings.mRecast, playerPosition));
|
||||
if (mLastPlayerPosition.has_value() && *mLastPlayerPosition == tilePosition)
|
||||
return;
|
||||
update(playerPosition);
|
||||
|
@ -225,6 +225,6 @@ namespace DetourNavigator
|
|||
float NavigatorImpl::getMaxNavmeshAreaRealRadius() const
|
||||
{
|
||||
const auto& settings = getSettings();
|
||||
return getRealTileSize(settings) * getMaxNavmeshAreaRadius(settings);
|
||||
return getRealTileSize(settings.mRecast) * getMaxNavmeshAreaRadius(settings);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,11 +13,11 @@ namespace DetourNavigator
|
|||
return std::nullopt;
|
||||
const auto settings = navigator.getSettings();
|
||||
const auto result = DetourNavigator::findRandomPointAroundCircle(navMesh->lockConst()->getImpl(),
|
||||
toNavMeshCoordinates(settings, agentHalfExtents), toNavMeshCoordinates(settings, start),
|
||||
toNavMeshCoordinates(settings, maxRadius), includeFlags, settings);
|
||||
toNavMeshCoordinates(settings.mRecast, agentHalfExtents), toNavMeshCoordinates(settings.mRecast, start),
|
||||
toNavMeshCoordinates(settings.mRecast, maxRadius), includeFlags, settings.mDetour);
|
||||
if (!result)
|
||||
return std::nullopt;
|
||||
return std::optional<osg::Vec3f>(fromNavMeshCoordinates(settings, *result));
|
||||
return std::optional<osg::Vec3f>(fromNavMeshCoordinates(settings.mRecast, *result));
|
||||
}
|
||||
|
||||
std::optional<osg::Vec3f> raycast(const Navigator& navigator, const osg::Vec3f& agentHalfExtents, const osg::Vec3f& start,
|
||||
|
@ -28,10 +28,10 @@ namespace DetourNavigator
|
|||
return std::nullopt;
|
||||
const auto settings = navigator.getSettings();
|
||||
const auto result = DetourNavigator::raycast(navMesh->lockConst()->getImpl(),
|
||||
toNavMeshCoordinates(settings, agentHalfExtents), toNavMeshCoordinates(settings, start),
|
||||
toNavMeshCoordinates(settings, end), includeFlags, settings);
|
||||
toNavMeshCoordinates(settings.mRecast, agentHalfExtents), toNavMeshCoordinates(settings.mRecast, start),
|
||||
toNavMeshCoordinates(settings.mRecast, end), includeFlags, settings.mDetour);
|
||||
if (!result)
|
||||
return std::nullopt;
|
||||
return fromNavMeshCoordinates(settings, *result);
|
||||
return fromNavMeshCoordinates(settings.mRecast, *result);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,9 +37,9 @@ namespace DetourNavigator
|
|||
if (navMesh == nullptr)
|
||||
return Status::NavMeshNotFound;
|
||||
const auto settings = navigator.getSettings();
|
||||
return findSmoothPath(navMesh->lockConst()->getImpl(), toNavMeshCoordinates(settings, agentHalfExtents),
|
||||
toNavMeshCoordinates(settings, stepSize), toNavMeshCoordinates(settings, start),
|
||||
toNavMeshCoordinates(settings, end), includeFlags, areaCosts, settings, endTolerance, out);
|
||||
return findSmoothPath(navMesh->lockConst()->getImpl(), toNavMeshCoordinates(settings.mRecast, agentHalfExtents),
|
||||
toNavMeshCoordinates(settings.mRecast, stepSize), toNavMeshCoordinates(settings.mRecast, start),
|
||||
toNavMeshCoordinates(settings.mRecast, end), includeFlags, areaCosts, settings, endTolerance, out);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -43,8 +43,8 @@ namespace DetourNavigator
|
|||
{
|
||||
NavMeshManager::NavMeshManager(const Settings& settings)
|
||||
: mSettings(settings)
|
||||
, mRecastMeshManager(settings)
|
||||
, mOffMeshConnectionsManager(settings)
|
||||
, mRecastMeshManager(mSettings.mRecast)
|
||||
, mOffMeshConnectionsManager(mSettings.mRecast)
|
||||
, mAsyncNavMeshUpdater(settings, mRecastMeshManager, mOffMeshConnectionsManager)
|
||||
{}
|
||||
|
||||
|
@ -140,8 +140,8 @@ namespace DetourNavigator
|
|||
{
|
||||
mOffMeshConnectionsManager.add(id, OffMeshConnection {start, end, areaType});
|
||||
|
||||
const auto startTilePosition = getTilePosition(mSettings, start);
|
||||
const auto endTilePosition = getTilePosition(mSettings, end);
|
||||
const auto startTilePosition = getTilePosition(mSettings.mRecast, start);
|
||||
const auto endTilePosition = getTilePosition(mSettings.mRecast, end);
|
||||
|
||||
addChangedTile(startTilePosition, ChangeType::add);
|
||||
|
||||
|
@ -158,7 +158,7 @@ namespace DetourNavigator
|
|||
|
||||
void NavMeshManager::update(const osg::Vec3f& playerPosition, const osg::Vec3f& agentHalfExtents)
|
||||
{
|
||||
const auto playerTile = getTilePosition(mSettings, toNavMeshCoordinates(mSettings, playerPosition));
|
||||
const auto playerTile = getTilePosition(mSettings.mRecast, toNavMeshCoordinates(mSettings.mRecast, playerPosition));
|
||||
auto& lastRevision = mLastRecastMeshManagerRevision[agentHalfExtents];
|
||||
auto lastPlayerTile = mPlayerTile.find(agentHalfExtents);
|
||||
if (lastRevision == mRecastMeshManager.getRevision() && lastPlayerTile != mPlayerTile.end()
|
||||
|
@ -251,7 +251,7 @@ namespace DetourNavigator
|
|||
void NavMeshManager::addChangedTiles(const btCollisionShape& shape, const btTransform& transform,
|
||||
const ChangeType changeType)
|
||||
{
|
||||
getTilesPositions(shape, transform, mSettings,
|
||||
getTilesPositions(shape, transform, mSettings.mRecast,
|
||||
[&] (const TilePosition& v) { addChangedTile(v, changeType); });
|
||||
}
|
||||
|
||||
|
@ -261,7 +261,7 @@ namespace DetourNavigator
|
|||
if (cellSize == std::numeric_limits<int>::max())
|
||||
return;
|
||||
|
||||
getTilesPositions(cellSize, shift, mSettings,
|
||||
getTilesPositions(cellSize, shift, mSettings.mRecast,
|
||||
[&] (const TilePosition& v) { addChangedTile(v, changeType); });
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
namespace DetourNavigator
|
||||
{
|
||||
OffMeshConnectionsManager::OffMeshConnectionsManager(const Settings& settings)
|
||||
OffMeshConnectionsManager::OffMeshConnectionsManager(const RecastSettings& settings)
|
||||
: mSettings(settings)
|
||||
{}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace DetourNavigator
|
|||
class OffMeshConnectionsManager
|
||||
{
|
||||
public:
|
||||
OffMeshConnectionsManager(const Settings& settings);
|
||||
explicit OffMeshConnectionsManager(const RecastSettings& settings);
|
||||
|
||||
void add(const ObjectId id, const OffMeshConnection& value);
|
||||
|
||||
|
@ -33,7 +33,7 @@ namespace DetourNavigator
|
|||
std::map<TilePosition, std::unordered_set<ObjectId>> mByTilePosition;
|
||||
};
|
||||
|
||||
const Settings& mSettings;
|
||||
const RecastSettings& mSettings;
|
||||
Misc::ScopeGuarded<Values> mValues;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
namespace DetourNavigator
|
||||
{
|
||||
std::optional<osg::Vec3f> raycast(const dtNavMesh& navMesh, const osg::Vec3f& halfExtents,
|
||||
const osg::Vec3f& start, const osg::Vec3f& end, const Flags includeFlags, const Settings& settings)
|
||||
const osg::Vec3f& start, const osg::Vec3f& end, const Flags includeFlags, const DetourSettings& settings)
|
||||
{
|
||||
dtNavMeshQuery navMeshQuery;
|
||||
if (!initNavMeshQuery(navMeshQuery, navMesh, settings.mMaxNavMeshQueryNodes))
|
||||
|
|
|
@ -10,10 +10,10 @@ class dtNavMesh;
|
|||
|
||||
namespace DetourNavigator
|
||||
{
|
||||
struct Settings;
|
||||
struct DetourSettings;
|
||||
|
||||
std::optional<osg::Vec3f> raycast(const dtNavMesh& navMesh, const osg::Vec3f& halfExtents,
|
||||
const osg::Vec3f& start, const osg::Vec3f& end, const Flags includeFlags, const Settings& settings);
|
||||
const osg::Vec3f& start, const osg::Vec3f& end, const Flags includeFlags, const DetourSettings& settings);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,43 +3,65 @@
|
|||
#include <components/settings/settings.hpp>
|
||||
#include <components/misc/constants.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace DetourNavigator
|
||||
{
|
||||
RecastSettings makeRecastSettingsFromSettingsManager()
|
||||
{
|
||||
constexpr float epsilon = std::numeric_limits<float>::epsilon();
|
||||
|
||||
RecastSettings result;
|
||||
|
||||
result.mBorderSize = std::max(0, ::Settings::Manager::getInt("border size", "Navigator"));
|
||||
result.mCellHeight = std::max(epsilon, ::Settings::Manager::getFloat("cell height", "Navigator"));
|
||||
result.mCellSize = std::max(epsilon, ::Settings::Manager::getFloat("cell size", "Navigator"));
|
||||
result.mDetailSampleDist = std::max(0.0f, ::Settings::Manager::getFloat("detail sample dist", "Navigator"));
|
||||
result.mDetailSampleMaxError = std::max(0.0f, ::Settings::Manager::getFloat("detail sample max error", "Navigator"));
|
||||
result.mMaxClimb = Constants::sStepSizeUp;
|
||||
result.mMaxSimplificationError = std::max(0.0f, ::Settings::Manager::getFloat("max simplification error", "Navigator"));
|
||||
result.mMaxSlope = Constants::sMaxSlope;
|
||||
result.mRecastScaleFactor = std::max(epsilon, ::Settings::Manager::getFloat("recast scale factor", "Navigator"));
|
||||
result.mSwimHeightScale = 0;
|
||||
result.mMaxEdgeLen = std::max(0, ::Settings::Manager::getInt("max edge len", "Navigator"));
|
||||
result.mMaxVertsPerPoly = std::max(3, ::Settings::Manager::getInt("max verts per poly", "Navigator"));
|
||||
result.mRegionMergeArea = std::max(0, ::Settings::Manager::getInt("region merge area", "Navigator"));
|
||||
result.mRegionMinArea = std::max(0, ::Settings::Manager::getInt("region min area", "Navigator"));
|
||||
result.mTileSize = std::max(1, ::Settings::Manager::getInt("tile size", "Navigator"));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DetourSettings makeDetourSettingsFromSettingsManager()
|
||||
{
|
||||
DetourSettings result;
|
||||
|
||||
result.mMaxNavMeshQueryNodes = std::clamp(::Settings::Manager::getInt("max nav mesh query nodes", "Navigator"), 1, 65535);
|
||||
result.mMaxPolys = std::clamp(::Settings::Manager::getInt("max polygons per tile", "Navigator"), 1, (1 << 22) - 1);
|
||||
result.mMaxPolygonPathSize = static_cast<std::size_t>(std::max(0, ::Settings::Manager::getInt("max polygon path size", "Navigator")));
|
||||
result.mMaxSmoothPathSize = static_cast<std::size_t>(std::max(0, ::Settings::Manager::getInt("max smooth path size", "Navigator")));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Settings makeSettingsFromSettingsManager()
|
||||
{
|
||||
Settings navigatorSettings;
|
||||
Settings result;
|
||||
|
||||
navigatorSettings.mBorderSize = ::Settings::Manager::getInt("border size", "Navigator");
|
||||
navigatorSettings.mCellHeight = ::Settings::Manager::getFloat("cell height", "Navigator");
|
||||
navigatorSettings.mCellSize = ::Settings::Manager::getFloat("cell size", "Navigator");
|
||||
navigatorSettings.mDetailSampleDist = ::Settings::Manager::getFloat("detail sample dist", "Navigator");
|
||||
navigatorSettings.mDetailSampleMaxError = ::Settings::Manager::getFloat("detail sample max error", "Navigator");
|
||||
navigatorSettings.mMaxClimb = Constants::sStepSizeUp;
|
||||
navigatorSettings.mMaxSimplificationError = ::Settings::Manager::getFloat("max simplification error", "Navigator");
|
||||
navigatorSettings.mMaxSlope = Constants::sMaxSlope;
|
||||
navigatorSettings.mRecastScaleFactor = ::Settings::Manager::getFloat("recast scale factor", "Navigator");
|
||||
navigatorSettings.mSwimHeightScale = 0;
|
||||
navigatorSettings.mMaxEdgeLen = ::Settings::Manager::getInt("max edge len", "Navigator");
|
||||
navigatorSettings.mMaxNavMeshQueryNodes = ::Settings::Manager::getInt("max nav mesh query nodes", "Navigator");
|
||||
navigatorSettings.mMaxPolys = ::Settings::Manager::getInt("max polygons per tile", "Navigator");
|
||||
navigatorSettings.mMaxTilesNumber = ::Settings::Manager::getInt("max tiles number", "Navigator");
|
||||
navigatorSettings.mMaxVertsPerPoly = ::Settings::Manager::getInt("max verts per poly", "Navigator");
|
||||
navigatorSettings.mRegionMergeSize = ::Settings::Manager::getInt("region merge size", "Navigator");
|
||||
navigatorSettings.mRegionMinSize = ::Settings::Manager::getInt("region min size", "Navigator");
|
||||
navigatorSettings.mTileSize = ::Settings::Manager::getInt("tile size", "Navigator");
|
||||
navigatorSettings.mWaitUntilMinDistanceToPlayer = ::Settings::Manager::getInt("wait until min distance to player", "Navigator");
|
||||
navigatorSettings.mAsyncNavMeshUpdaterThreads = static_cast<std::size_t>(::Settings::Manager::getInt("async nav mesh updater threads", "Navigator"));
|
||||
navigatorSettings.mMaxNavMeshTilesCacheSize = static_cast<std::size_t>(::Settings::Manager::getInt("max nav mesh tiles cache size", "Navigator"));
|
||||
navigatorSettings.mMaxPolygonPathSize = static_cast<std::size_t>(::Settings::Manager::getInt("max polygon path size", "Navigator"));
|
||||
navigatorSettings.mMaxSmoothPathSize = static_cast<std::size_t>(::Settings::Manager::getInt("max smooth path size", "Navigator"));
|
||||
navigatorSettings.mEnableWriteRecastMeshToFile = ::Settings::Manager::getBool("enable write recast mesh to file", "Navigator");
|
||||
navigatorSettings.mEnableWriteNavMeshToFile = ::Settings::Manager::getBool("enable write nav mesh to file", "Navigator");
|
||||
navigatorSettings.mRecastMeshPathPrefix = ::Settings::Manager::getString("recast mesh path prefix", "Navigator");
|
||||
navigatorSettings.mNavMeshPathPrefix = ::Settings::Manager::getString("nav mesh path prefix", "Navigator");
|
||||
navigatorSettings.mEnableRecastMeshFileNameRevision = ::Settings::Manager::getBool("enable recast mesh file name revision", "Navigator");
|
||||
navigatorSettings.mEnableNavMeshFileNameRevision = ::Settings::Manager::getBool("enable nav mesh file name revision", "Navigator");
|
||||
navigatorSettings.mMinUpdateInterval = std::chrono::milliseconds(::Settings::Manager::getInt("min update interval ms", "Navigator"));
|
||||
result.mRecast = makeRecastSettingsFromSettingsManager();
|
||||
result.mDetour = makeDetourSettingsFromSettingsManager();
|
||||
result.mMaxTilesNumber = std::max(0, ::Settings::Manager::getInt("max tiles number", "Navigator"));
|
||||
result.mWaitUntilMinDistanceToPlayer = ::Settings::Manager::getInt("wait until min distance to player", "Navigator");
|
||||
result.mAsyncNavMeshUpdaterThreads = static_cast<std::size_t>(std::max(0, ::Settings::Manager::getInt("async nav mesh updater threads", "Navigator")));
|
||||
result.mMaxNavMeshTilesCacheSize = static_cast<std::size_t>(std::max(std::int64_t {0}, ::Settings::Manager::getInt64("max nav mesh tiles cache size", "Navigator")));
|
||||
result.mEnableWriteRecastMeshToFile = ::Settings::Manager::getBool("enable write recast mesh to file", "Navigator");
|
||||
result.mEnableWriteNavMeshToFile = ::Settings::Manager::getBool("enable write nav mesh to file", "Navigator");
|
||||
result.mRecastMeshPathPrefix = ::Settings::Manager::getString("recast mesh path prefix", "Navigator");
|
||||
result.mNavMeshPathPrefix = ::Settings::Manager::getString("nav mesh path prefix", "Navigator");
|
||||
result.mEnableRecastMeshFileNameRevision = ::Settings::Manager::getBool("enable recast mesh file name revision", "Navigator");
|
||||
result.mEnableNavMeshFileNameRevision = ::Settings::Manager::getBool("enable nav mesh file name revision", "Navigator");
|
||||
result.mMinUpdateInterval = std::chrono::milliseconds(::Settings::Manager::getInt("min update interval ms", "Navigator"));
|
||||
|
||||
return navigatorSettings;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,12 +6,8 @@
|
|||
|
||||
namespace DetourNavigator
|
||||
{
|
||||
struct Settings
|
||||
struct RecastSettings
|
||||
{
|
||||
bool mEnableWriteRecastMeshToFile = false;
|
||||
bool mEnableWriteNavMeshToFile = false;
|
||||
bool mEnableRecastMeshFileNameRevision = false;
|
||||
bool mEnableNavMeshFileNameRevision = false;
|
||||
float mCellHeight = 0;
|
||||
float mCellSize = 0;
|
||||
float mDetailSampleDist = 0;
|
||||
|
@ -23,23 +19,41 @@ namespace DetourNavigator
|
|||
float mSwimHeightScale = 0;
|
||||
int mBorderSize = 0;
|
||||
int mMaxEdgeLen = 0;
|
||||
int mMaxNavMeshQueryNodes = 0;
|
||||
int mMaxPolys = 0;
|
||||
int mMaxTilesNumber = 0;
|
||||
int mMaxVertsPerPoly = 0;
|
||||
int mRegionMergeSize = 0;
|
||||
int mRegionMinSize = 0;
|
||||
int mRegionMergeArea = 0;
|
||||
int mRegionMinArea = 0;
|
||||
int mTileSize = 0;
|
||||
int mWaitUntilMinDistanceToPlayer = 0;
|
||||
std::size_t mAsyncNavMeshUpdaterThreads = 0;
|
||||
std::size_t mMaxNavMeshTilesCacheSize = 0;
|
||||
};
|
||||
|
||||
struct DetourSettings
|
||||
{
|
||||
int mMaxPolys = 0;
|
||||
int mMaxNavMeshQueryNodes = 0;
|
||||
std::size_t mMaxPolygonPathSize = 0;
|
||||
std::size_t mMaxSmoothPathSize = 0;
|
||||
};
|
||||
|
||||
struct Settings
|
||||
{
|
||||
bool mEnableWriteRecastMeshToFile = false;
|
||||
bool mEnableWriteNavMeshToFile = false;
|
||||
bool mEnableRecastMeshFileNameRevision = false;
|
||||
bool mEnableNavMeshFileNameRevision = false;
|
||||
RecastSettings mRecast;
|
||||
DetourSettings mDetour;
|
||||
int mWaitUntilMinDistanceToPlayer = 0;
|
||||
int mMaxTilesNumber = 0;
|
||||
std::size_t mAsyncNavMeshUpdaterThreads = 0;
|
||||
std::size_t mMaxNavMeshTilesCacheSize = 0;
|
||||
std::string mRecastMeshPathPrefix;
|
||||
std::string mNavMeshPathPrefix;
|
||||
std::chrono::milliseconds mMinUpdateInterval;
|
||||
};
|
||||
|
||||
RecastSettings makeRecastSettingsFromSettingsManager();
|
||||
|
||||
DetourSettings makeDetourSettingsFromSettingsManager();
|
||||
|
||||
Settings makeSettingsFromSettingsManager();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,12 +4,8 @@
|
|||
#include "settings.hpp"
|
||||
#include "tilebounds.hpp"
|
||||
#include "tileposition.hpp"
|
||||
#include "tilebounds.hpp"
|
||||
|
||||
#include <LinearMath/btTransform.h>
|
||||
|
||||
#include <osg/Vec2f>
|
||||
#include <osg/Vec2i>
|
||||
#include <osg/Vec3f>
|
||||
|
||||
#include <algorithm>
|
||||
|
@ -17,38 +13,31 @@
|
|||
|
||||
namespace DetourNavigator
|
||||
{
|
||||
inline float getHeight(const Settings& settings,const osg::Vec3f& agentHalfExtents)
|
||||
{
|
||||
return 2.0f * agentHalfExtents.z() * settings.mRecastScaleFactor;
|
||||
}
|
||||
|
||||
inline float getMaxClimb(const Settings& settings)
|
||||
{
|
||||
return settings.mMaxClimb * settings.mRecastScaleFactor;
|
||||
}
|
||||
|
||||
inline float getRadius(const Settings& settings, const osg::Vec3f& agentHalfExtents)
|
||||
{
|
||||
return std::max(agentHalfExtents.x(), agentHalfExtents.y()) * std::sqrt(2) * settings.mRecastScaleFactor;
|
||||
}
|
||||
|
||||
inline float toNavMeshCoordinates(const Settings& settings, float value)
|
||||
inline float toNavMeshCoordinates(const RecastSettings& settings, float value)
|
||||
{
|
||||
return value * settings.mRecastScaleFactor;
|
||||
}
|
||||
|
||||
inline osg::Vec2f toNavMeshCoordinates(const Settings& settings, osg::Vec2f position)
|
||||
inline osg::Vec2f toNavMeshCoordinates(const RecastSettings& settings, osg::Vec2f position)
|
||||
{
|
||||
return position * settings.mRecastScaleFactor;
|
||||
}
|
||||
|
||||
inline osg::Vec3f toNavMeshCoordinates(const Settings& settings, osg::Vec3f position)
|
||||
inline osg::Vec3f toNavMeshCoordinates(const RecastSettings& settings, osg::Vec3f position)
|
||||
{
|
||||
std::swap(position.y(), position.z());
|
||||
return position * settings.mRecastScaleFactor;
|
||||
}
|
||||
|
||||
inline osg::Vec3f fromNavMeshCoordinates(const Settings& settings, osg::Vec3f position)
|
||||
inline TileBounds toNavMeshCoordinates(const RecastSettings& settings, const TileBounds& value)
|
||||
{
|
||||
return TileBounds {
|
||||
toNavMeshCoordinates(settings, value.mMin),
|
||||
toNavMeshCoordinates(settings, value.mMax)
|
||||
};
|
||||
}
|
||||
|
||||
inline osg::Vec3f fromNavMeshCoordinates(const RecastSettings& settings, osg::Vec3f position)
|
||||
{
|
||||
const auto factor = 1.0f / settings.mRecastScaleFactor;
|
||||
position *= factor;
|
||||
|
@ -56,12 +45,12 @@ namespace DetourNavigator
|
|||
return position;
|
||||
}
|
||||
|
||||
inline float getTileSize(const Settings& settings)
|
||||
inline float getTileSize(const RecastSettings& settings)
|
||||
{
|
||||
return static_cast<float>(settings.mTileSize) * settings.mCellSize;
|
||||
}
|
||||
|
||||
inline TilePosition getTilePosition(const Settings& settings, const osg::Vec3f& position)
|
||||
inline TilePosition getTilePosition(const RecastSettings& settings, const osg::Vec3f& position)
|
||||
{
|
||||
return TilePosition(
|
||||
static_cast<int>(std::floor(position.x() / getTileSize(settings))),
|
||||
|
@ -69,7 +58,7 @@ namespace DetourNavigator
|
|||
);
|
||||
}
|
||||
|
||||
inline TileBounds makeTileBounds(const Settings& settings, const TilePosition& tilePosition)
|
||||
inline TileBounds makeTileBounds(const RecastSettings& settings, const TilePosition& tilePosition)
|
||||
{
|
||||
return TileBounds {
|
||||
osg::Vec2f(tilePosition.x(), tilePosition.y()) * getTileSize(settings),
|
||||
|
@ -77,17 +66,12 @@ namespace DetourNavigator
|
|||
};
|
||||
}
|
||||
|
||||
inline float getBorderSize(const Settings& settings)
|
||||
inline float getBorderSize(const RecastSettings& settings)
|
||||
{
|
||||
return static_cast<float>(settings.mBorderSize) * settings.mCellSize;
|
||||
}
|
||||
|
||||
inline float getSwimLevel(const Settings& settings, const float waterLevel, const float agentHalfExtentsZ)
|
||||
{
|
||||
return waterLevel - settings.mSwimHeightScale * agentHalfExtentsZ - agentHalfExtentsZ;;
|
||||
}
|
||||
|
||||
inline float getRealTileSize(const Settings& settings)
|
||||
inline float getRealTileSize(const RecastSettings& settings)
|
||||
{
|
||||
return settings.mTileSize * settings.mCellSize / settings.mRecastScaleFactor;
|
||||
}
|
||||
|
@ -97,7 +81,7 @@ namespace DetourNavigator
|
|||
return std::floor(std::sqrt(settings.mMaxTilesNumber / osg::PI)) - 1;
|
||||
}
|
||||
|
||||
inline TileBounds makeRealTileBoundsWithBorder(const Settings& settings, const TilePosition& tilePosition)
|
||||
inline TileBounds makeRealTileBoundsWithBorder(const RecastSettings& settings, const TilePosition& tilePosition)
|
||||
{
|
||||
TileBounds result = makeTileBounds(settings, tilePosition);
|
||||
const float border = getBorderSize(settings);
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
namespace DetourNavigator
|
||||
{
|
||||
TileCachedRecastMeshManager::TileCachedRecastMeshManager(const Settings& settings)
|
||||
TileCachedRecastMeshManager::TileCachedRecastMeshManager(const RecastSettings& settings)
|
||||
: mSettings(settings)
|
||||
{}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace DetourNavigator
|
|||
class TileCachedRecastMeshManager
|
||||
{
|
||||
public:
|
||||
TileCachedRecastMeshManager(const Settings& settings);
|
||||
explicit TileCachedRecastMeshManager(const RecastSettings& settings);
|
||||
|
||||
bool addObject(const ObjectId id, const CollisionShape& shape, const btTransform& transform,
|
||||
const AreaType areaType);
|
||||
|
@ -102,7 +102,7 @@ namespace DetourNavigator
|
|||
private:
|
||||
using TilesMap = std::map<TilePosition, std::shared_ptr<CachedRecastMeshManager>>;
|
||||
|
||||
const Settings& mSettings;
|
||||
const RecastSettings& mSettings;
|
||||
Misc::ScopeGuarded<TilesMap> mTiles;
|
||||
std::unordered_map<ObjectId, std::vector<TilePosition>> mObjectsTilesPositions;
|
||||
std::map<osg::Vec2i, std::vector<TilePosition>> mWaterTilesPositions;
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace SceneUtil
|
|||
{
|
||||
osg::ref_ptr<osg::Group> createAgentPathGroup(const std::deque<osg::Vec3f>& path,
|
||||
const osg::Vec3f& halfExtents, const osg::Vec3f& start, const osg::Vec3f& end,
|
||||
const DetourNavigator::Settings& settings)
|
||||
const DetourNavigator::RecastSettings& settings)
|
||||
{
|
||||
using namespace DetourNavigator;
|
||||
|
||||
|
|
|
@ -13,14 +13,14 @@ namespace osg
|
|||
|
||||
namespace DetourNavigator
|
||||
{
|
||||
struct Settings;
|
||||
struct RecastSettings;
|
||||
}
|
||||
|
||||
namespace SceneUtil
|
||||
{
|
||||
osg::ref_ptr<osg::Group> createAgentPathGroup(const std::deque<osg::Vec3f>& path,
|
||||
const osg::Vec3f& halfExtents, const osg::Vec3f& start, const osg::Vec3f& end,
|
||||
const DetourNavigator::Settings& settings);
|
||||
const DetourNavigator::RecastSettings& settings);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -254,9 +254,9 @@ namespace SceneUtil
|
|||
osg::ref_ptr<osg::Group> group(new osg::Group);
|
||||
group->setStateSet(groupStateSet);
|
||||
constexpr float shift = 10.0f;
|
||||
DebugDraw debugDraw(*group, debugDrawStateSet, osg::Vec3f(0, 0, shift), 1.0f / settings.mRecastScaleFactor);
|
||||
DebugDraw debugDraw(*group, debugDrawStateSet, osg::Vec3f(0, 0, shift), 1.0f / settings.mRecast.mRecastScaleFactor);
|
||||
dtNavMeshQuery navMeshQuery;
|
||||
navMeshQuery.init(&navMesh, settings.mMaxNavMeshQueryNodes);
|
||||
navMeshQuery.init(&navMesh, settings.mDetour.mMaxNavMeshQueryNodes);
|
||||
drawMeshTile(&debugDraw, navMesh, &navMeshQuery, &meshTile, DU_DRAWNAVMESH_OFFMESHCONS | DU_DRAWNAVMESH_CLOSEDLIST);
|
||||
|
||||
return group;
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace
|
|||
namespace SceneUtil
|
||||
{
|
||||
osg::ref_ptr<osg::Group> createRecastMeshGroup(const DetourNavigator::RecastMesh& recastMesh,
|
||||
const DetourNavigator::Settings& settings)
|
||||
const DetourNavigator::RecastSettings& settings)
|
||||
{
|
||||
using namespace DetourNavigator;
|
||||
|
||||
|
|
|
@ -11,13 +11,13 @@ namespace osg
|
|||
namespace DetourNavigator
|
||||
{
|
||||
class RecastMesh;
|
||||
struct Settings;
|
||||
struct RecastSettings;
|
||||
}
|
||||
|
||||
namespace SceneUtil
|
||||
{
|
||||
osg::ref_ptr<osg::Group> createRecastMeshGroup(const DetourNavigator::RecastMesh& recastMesh,
|
||||
const DetourNavigator::Settings& settings);
|
||||
const DetourNavigator::RecastSettings& settings);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -79,6 +79,15 @@ int Manager::getInt (const std::string& setting, const std::string& category)
|
|||
return number;
|
||||
}
|
||||
|
||||
std::int64_t Manager::getInt64 (const std::string& setting, const std::string& category)
|
||||
{
|
||||
const std::string& value = getString(setting, category);
|
||||
std::stringstream stream(value);
|
||||
std::size_t number = 0;
|
||||
stream >> number;
|
||||
return number;
|
||||
}
|
||||
|
||||
bool Manager::getBool (const std::string& setting, const std::string& category)
|
||||
{
|
||||
const std::string& string = getString(setting, category);
|
||||
|
|
|
@ -51,6 +51,7 @@ namespace Settings
|
|||
///< returns the list of changed settings intersecting with the filter
|
||||
|
||||
static int getInt (const std::string& setting, const std::string& category);
|
||||
static std::int64_t getInt64 (const std::string& setting, const std::string& category);
|
||||
static float getFloat (const std::string& setting, const std::string& category);
|
||||
static double getDouble (const std::string& setting, const std::string& category);
|
||||
static std::string getString (const std::string& setting, const std::string& category);
|
||||
|
|
|
@ -365,20 +365,20 @@ max verts per poly
|
|||
|
||||
The maximum number of vertices allowed for polygons generated during the contour to polygon conversion process.
|
||||
|
||||
region merge size
|
||||
region merge area
|
||||
-----------------
|
||||
|
||||
:Type: integer
|
||||
:Range: >= 0
|
||||
:Default: 20
|
||||
:Default: 400
|
||||
|
||||
Any regions with a span count smaller than this value will, if possible, be merged with larger regions.
|
||||
|
||||
region min size
|
||||
region min area
|
||||
---------------
|
||||
|
||||
:Type: integer
|
||||
:Range: >= 0
|
||||
:Default: 8
|
||||
:Default: 64
|
||||
|
||||
The minimum number of cells allowed to form isolated island areas.
|
||||
|
|
|
@ -876,10 +876,10 @@ max polygons per tile = 4096
|
|||
max verts per poly = 6
|
||||
|
||||
# Any regions with a span count smaller than this value will, if possible, be merged with larger regions. (value >= 0)
|
||||
region merge size = 20
|
||||
region merge area = 400
|
||||
|
||||
# The minimum number of cells allowed to form isolated island areas. (value >= 0)
|
||||
region min size = 8
|
||||
region min area = 64
|
||||
|
||||
# Number of background threads to update nav mesh (value >= 1)
|
||||
async nav mesh updater threads = 1
|
||||
|
|
Loading…
Reference in a new issue