mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-07 02:15:32 +00:00
Do not use NavMesh to find changed tiles
This commit is contained in:
parent
d1e71f9322
commit
ed3a255f65
13 changed files with 200 additions and 54 deletions
|
@ -166,6 +166,7 @@ namespace MWWorld
|
||||||
mPhysics.reset(new MWPhysics::PhysicsSystem(resourceSystem, rootNode));
|
mPhysics.reset(new MWPhysics::PhysicsSystem(resourceSystem, rootNode));
|
||||||
|
|
||||||
DetourNavigator::Settings navigatorSettings;
|
DetourNavigator::Settings navigatorSettings;
|
||||||
|
navigatorSettings.mBorderSize = Settings::Manager::getInt("border size", "Navigator");
|
||||||
navigatorSettings.mCellHeight = Settings::Manager::getFloat("cell height", "Navigator");
|
navigatorSettings.mCellHeight = Settings::Manager::getFloat("cell height", "Navigator");
|
||||||
navigatorSettings.mCellSize = Settings::Manager::getFloat("cell size", "Navigator");
|
navigatorSettings.mCellSize = Settings::Manager::getFloat("cell size", "Navigator");
|
||||||
navigatorSettings.mDetailSampleDist = Settings::Manager::getFloat("detail sample dist", "Navigator");
|
navigatorSettings.mDetailSampleDist = Settings::Manager::getFloat("detail sample dist", "Navigator");
|
||||||
|
|
|
@ -21,6 +21,7 @@ if (GTEST_FOUND AND GMOCK_FOUND)
|
||||||
detournavigator/navigator.cpp
|
detournavigator/navigator.cpp
|
||||||
detournavigator/settingsutils.cpp
|
detournavigator/settingsutils.cpp
|
||||||
detournavigator/recastmeshbuilder.cpp
|
detournavigator/recastmeshbuilder.cpp
|
||||||
|
detournavigator/gettilespositions.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
source_group(apps\\openmw_test_suite FILES openmw_test_suite.cpp ${UNITTEST_SRC_FILES})
|
source_group(apps\\openmw_test_suite FILES openmw_test_suite.cpp ${UNITTEST_SRC_FILES})
|
||||||
|
|
104
apps/openmw_test_suite/detournavigator/gettilespositions.cpp
Normal file
104
apps/openmw_test_suite/detournavigator/gettilespositions.cpp
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
#include <components/detournavigator/gettilespositions.hpp>
|
||||||
|
#include <components/detournavigator/debug.hpp>
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <gmock/gmock.h>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
using namespace testing;
|
||||||
|
using namespace DetourNavigator;
|
||||||
|
|
||||||
|
struct CollectTilesPositions
|
||||||
|
{
|
||||||
|
std::vector<TilePosition>& mTilesPositions;
|
||||||
|
|
||||||
|
void operator ()(const TilePosition& value)
|
||||||
|
{
|
||||||
|
mTilesPositions.push_back(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DetourNavigatorGetTilesPositionsTest : Test
|
||||||
|
{
|
||||||
|
Settings mSettings;
|
||||||
|
std::vector<TilePosition> mTilesPositions;
|
||||||
|
CollectTilesPositions mCollect {mTilesPositions};
|
||||||
|
|
||||||
|
DetourNavigatorGetTilesPositionsTest()
|
||||||
|
{
|
||||||
|
mSettings.mBorderSize = 0;
|
||||||
|
mSettings.mCellSize = 0.5;
|
||||||
|
mSettings.mRecastScaleFactor = 1;
|
||||||
|
mSettings.mTileSize = 64;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(DetourNavigatorGetTilesPositionsTest, for_object_in_single_tile_should_return_one_tile)
|
||||||
|
{
|
||||||
|
getTilesPositions(osg::Vec3f(2, 2, 0), osg::Vec3f(31, 31, 1), mSettings, mCollect);
|
||||||
|
|
||||||
|
EXPECT_THAT(mTilesPositions, ElementsAre(TilePosition(0, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DetourNavigatorGetTilesPositionsTest, for_object_with_x_bounds_in_two_tiles_should_return_two_tiles)
|
||||||
|
{
|
||||||
|
getTilesPositions(osg::Vec3f(0, 0, 0), osg::Vec3f(32, 31, 1), mSettings, mCollect);
|
||||||
|
|
||||||
|
EXPECT_THAT(mTilesPositions, ElementsAre(TilePosition(0, 0), TilePosition(1, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DetourNavigatorGetTilesPositionsTest, for_object_with_y_bounds_in_two_tiles_should_return_two_tiles)
|
||||||
|
{
|
||||||
|
getTilesPositions(osg::Vec3f(0, 0, 0), osg::Vec3f(31, 32, 1), mSettings, mCollect);
|
||||||
|
|
||||||
|
EXPECT_THAT(mTilesPositions, ElementsAre(TilePosition(0, 0), TilePosition(0, 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DetourNavigatorGetTilesPositionsTest, tiling_works_only_for_x_and_y_coordinates)
|
||||||
|
{
|
||||||
|
getTilesPositions(osg::Vec3f(0, 0, 0), osg::Vec3f(31, 31, 32), mSettings, mCollect);
|
||||||
|
|
||||||
|
EXPECT_THAT(mTilesPositions, ElementsAre(TilePosition(0, 0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DetourNavigatorGetTilesPositionsTest, tiling_should_work_with_negative_coordinates)
|
||||||
|
{
|
||||||
|
getTilesPositions(osg::Vec3f(-31, -31, 0), osg::Vec3f(31, 31, 1), mSettings, mCollect);
|
||||||
|
|
||||||
|
EXPECT_THAT(mTilesPositions, ElementsAre(
|
||||||
|
TilePosition(-1, -1),
|
||||||
|
TilePosition(-1, 0),
|
||||||
|
TilePosition(0, -1),
|
||||||
|
TilePosition(0, 0)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DetourNavigatorGetTilesPositionsTest, border_size_should_extend_tile_bounds)
|
||||||
|
{
|
||||||
|
mSettings.mBorderSize = 1;
|
||||||
|
|
||||||
|
getTilesPositions(osg::Vec3f(0, 0, 0), osg::Vec3f(31.5, 31.5, 1), mSettings, mCollect);
|
||||||
|
|
||||||
|
EXPECT_THAT(mTilesPositions, ElementsAre(
|
||||||
|
TilePosition(-1, -1),
|
||||||
|
TilePosition(-1, 0),
|
||||||
|
TilePosition(-1, 1),
|
||||||
|
TilePosition(0, -1),
|
||||||
|
TilePosition(0, 0),
|
||||||
|
TilePosition(0, 1),
|
||||||
|
TilePosition(1, -1),
|
||||||
|
TilePosition(1, 0),
|
||||||
|
TilePosition(1, 1)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DetourNavigatorGetTilesPositionsTest, should_apply_recast_scale_factor)
|
||||||
|
{
|
||||||
|
mSettings.mRecastScaleFactor = 0.5;
|
||||||
|
|
||||||
|
getTilesPositions(osg::Vec3f(0, 0, 0), osg::Vec3f(32, 32, 1), mSettings, mCollect);
|
||||||
|
|
||||||
|
EXPECT_THAT(mTilesPositions, ElementsAre(TilePosition(0, 0)));
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,6 +37,7 @@ namespace
|
||||||
mSettings.mEnableWriteNavMeshToFile = false;
|
mSettings.mEnableWriteNavMeshToFile = false;
|
||||||
mSettings.mEnableRecastMeshFileNameRevision = false;
|
mSettings.mEnableRecastMeshFileNameRevision = false;
|
||||||
mSettings.mEnableNavMeshFileNameRevision = false;
|
mSettings.mEnableNavMeshFileNameRevision = false;
|
||||||
|
mSettings.mBorderSize = 16;
|
||||||
mSettings.mCellHeight = 0.2f;
|
mSettings.mCellHeight = 0.2f;
|
||||||
mSettings.mCellSize = 0.2f;
|
mSettings.mCellSize = 0.2f;
|
||||||
mSettings.mDetailSampleDist = 6;
|
mSettings.mDetailSampleDist = 6;
|
||||||
|
|
55
components/detournavigator/gettilespositions.hpp
Normal file
55
components/detournavigator/gettilespositions.hpp
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_GETTILESPOSITIONS_H
|
||||||
|
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_GETTILESPOSITIONS_H
|
||||||
|
|
||||||
|
#include "settings.hpp"
|
||||||
|
#include "settingsutils.hpp"
|
||||||
|
|
||||||
|
#include <BulletCollision/CollisionShapes/btCollisionShape.h>
|
||||||
|
|
||||||
|
#include <osg/Vec3f>
|
||||||
|
|
||||||
|
namespace DetourNavigator
|
||||||
|
{
|
||||||
|
inline osg::Vec3f makeOsgVec3f(const btVector3& value)
|
||||||
|
{
|
||||||
|
return osg::Vec3f(value.x(), value.y(), value.z());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Callback>
|
||||||
|
void getTilesPositions(const osg::Vec3f& aabbMin, const osg::Vec3f& aabbMax,
|
||||||
|
const Settings& settings, Callback&& callback)
|
||||||
|
{
|
||||||
|
auto min = toNavMeshCoordinates(settings, aabbMin);
|
||||||
|
auto max = toNavMeshCoordinates(settings, aabbMax);
|
||||||
|
|
||||||
|
const auto border = getBorderSize(settings);
|
||||||
|
min -= osg::Vec3f(border, border, border);
|
||||||
|
max += osg::Vec3f(border, border, border);
|
||||||
|
|
||||||
|
auto minTile = getTilePosition(settings, min);
|
||||||
|
auto maxTile = getTilePosition(settings, max);
|
||||||
|
|
||||||
|
if (minTile.x() > maxTile.x())
|
||||||
|
std::swap(minTile.x(), maxTile.x());
|
||||||
|
|
||||||
|
if (minTile.y() > maxTile.y())
|
||||||
|
std::swap(minTile.y(), maxTile.y());
|
||||||
|
|
||||||
|
for (int tileX = minTile.x(); tileX <= maxTile.x(); ++tileX)
|
||||||
|
for (int tileY = minTile.y(); tileY <= maxTile.y(); ++tileY)
|
||||||
|
callback(TilePosition {tileX, tileY});
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Callback>
|
||||||
|
void getTilesPositions(const btCollisionShape& shape, const btTransform& transform,
|
||||||
|
const Settings& settings, Callback&& callback)
|
||||||
|
{
|
||||||
|
btVector3 aabbMin;
|
||||||
|
btVector3 aabbMax;
|
||||||
|
shape.getAabb(transform, aabbMin, aabbMax);
|
||||||
|
|
||||||
|
getTilesPositions(makeOsgVec3f(aabbMin), makeOsgVec3f(aabbMax), settings, std::forward<Callback>(callback));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -82,15 +82,15 @@ namespace
|
||||||
config.maxVertsPerPoly = settings.mMaxVertsPerPoly;
|
config.maxVertsPerPoly = settings.mMaxVertsPerPoly;
|
||||||
config.detailSampleDist = settings.mDetailSampleDist < 0.9f ? 0 : config.cs * settings.mDetailSampleDist;
|
config.detailSampleDist = settings.mDetailSampleDist < 0.9f ? 0 : config.cs * settings.mDetailSampleDist;
|
||||||
config.detailSampleMaxError = config.ch * settings.mDetailSampleMaxError;
|
config.detailSampleMaxError = config.ch * settings.mDetailSampleMaxError;
|
||||||
config.borderSize = config.walkableRadius + 3;
|
config.borderSize = settings.mBorderSize;
|
||||||
config.width = settings.mTileSize + config.borderSize * 2;
|
config.width = settings.mTileSize + config.borderSize * 2;
|
||||||
config.height = settings.mTileSize + config.borderSize * 2;
|
config.height = settings.mTileSize + config.borderSize * 2;
|
||||||
rcVcopy(config.bmin, boundsMin.ptr());
|
rcVcopy(config.bmin, boundsMin.ptr());
|
||||||
rcVcopy(config.bmax, boundsMax.ptr());
|
rcVcopy(config.bmax, boundsMax.ptr());
|
||||||
config.bmin[0] -= config.borderSize * config.cs;
|
config.bmin[0] -= getBorderSize(settings);
|
||||||
config.bmin[2] -= config.borderSize * config.cs;
|
config.bmin[2] -= getBorderSize(settings);
|
||||||
config.bmax[0] += config.borderSize * config.cs;
|
config.bmax[0] += getBorderSize(settings);
|
||||||
config.bmax[2] += config.borderSize * config.cs;
|
config.bmax[2] += getBorderSize(settings);
|
||||||
|
|
||||||
rcHeightfield solid;
|
rcHeightfield solid;
|
||||||
OPENMW_CHECK_DT_RESULT(rcCreateHeightfield(nullptr, solid, config.width, config.height,
|
OPENMW_CHECK_DT_RESULT(rcCreateHeightfield(nullptr, solid, config.width, config.height,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_MAKENAVMESH_H
|
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_MAKENAVMESH_H
|
||||||
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_MAKENAVMESH_H
|
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_MAKENAVMESH_H
|
||||||
|
|
||||||
|
#include "settings.hpp"
|
||||||
#include "tileposition.hpp"
|
#include "tileposition.hpp"
|
||||||
|
|
||||||
#include <osg/Vec3f>
|
#include <osg/Vec3f>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "navmeshmanager.hpp"
|
#include "navmeshmanager.hpp"
|
||||||
#include "debug.hpp"
|
#include "debug.hpp"
|
||||||
#include "exceptions.hpp"
|
#include "exceptions.hpp"
|
||||||
|
#include "gettilespositions.hpp"
|
||||||
#include "makenavmesh.hpp"
|
#include "makenavmesh.hpp"
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
#include "sharednavmesh.hpp"
|
#include "sharednavmesh.hpp"
|
||||||
|
@ -63,12 +64,10 @@ namespace DetourNavigator
|
||||||
const auto changedTiles = mChangedTiles.find(agentHalfExtents);
|
const auto changedTiles = mChangedTiles.find(agentHalfExtents);
|
||||||
if (changedTiles != mChangedTiles.end())
|
if (changedTiles != mChangedTiles.end())
|
||||||
{
|
{
|
||||||
TilePosition playerTile;
|
|
||||||
playerPosition *= mSettings.mRecastScaleFactor;
|
playerPosition *= mSettings.mRecastScaleFactor;
|
||||||
std::swap(playerPosition.y(), playerPosition.z());
|
std::swap(playerPosition.y(), playerPosition.z());
|
||||||
cached->mValue.raw()->calcTileLoc(playerPosition.ptr(), &playerTile.x(), &playerTile.y());
|
mAsyncNavMeshUpdater.post(agentHalfExtents, mRecastMeshManager.getMesh(), cached,
|
||||||
mAsyncNavMeshUpdater.post(agentHalfExtents, mRecastMeshManager.getMesh(), cached, playerTile,
|
getTilePosition(mSettings, playerPosition), changedTiles->second);
|
||||||
changedTiles->second);
|
|
||||||
mChangedTiles.erase(changedTiles);
|
mChangedTiles.erase(changedTiles);
|
||||||
log("cache update posted for agent=", agentHalfExtents);
|
log("cache update posted for agent=", agentHalfExtents);
|
||||||
}
|
}
|
||||||
|
@ -91,39 +90,11 @@ namespace DetourNavigator
|
||||||
|
|
||||||
void NavMeshManager::addChangedTiles(const btCollisionShape& shape, const btTransform& transform)
|
void NavMeshManager::addChangedTiles(const btCollisionShape& shape, const btTransform& transform)
|
||||||
{
|
{
|
||||||
btVector3 aabbMin;
|
getTilesPositions(shape, transform, mSettings, [&] (const TilePosition& v) {
|
||||||
btVector3 aabbMax;
|
for (const auto& cached : mCache)
|
||||||
shape.getAabb(transform, aabbMin, aabbMax);
|
if (cached.second)
|
||||||
osg::Vec3f min(aabbMin.x(), aabbMin.z(), aabbMin.y());
|
mChangedTiles[cached.first].insert(v);
|
||||||
osg::Vec3f max(aabbMax.x(), aabbMax.z(), aabbMax.y());
|
});
|
||||||
min *= mSettings.mRecastScaleFactor;
|
|
||||||
max *= mSettings.mRecastScaleFactor;
|
|
||||||
|
|
||||||
for (auto& v : mCache)
|
|
||||||
{
|
|
||||||
if (const auto& item = v.second)
|
|
||||||
{
|
|
||||||
auto& changedTiles = mChangedTiles[v.first];
|
|
||||||
|
|
||||||
int minTileX;
|
|
||||||
int minTileY;
|
|
||||||
item->mValue.raw()->calcTileLoc(min.ptr(), &minTileX, &minTileY);
|
|
||||||
|
|
||||||
int maxTileX;
|
|
||||||
int maxTileY;
|
|
||||||
item->mValue.raw()->calcTileLoc(max.ptr(), &maxTileX, &maxTileY);
|
|
||||||
|
|
||||||
if (minTileX > maxTileX)
|
|
||||||
std::swap(minTileX, maxTileX);
|
|
||||||
|
|
||||||
if (minTileY > maxTileY)
|
|
||||||
std::swap(minTileY, maxTileY);
|
|
||||||
|
|
||||||
for (int tileX = minTileX; tileX <= maxTileX; ++tileX)
|
|
||||||
for (int tileY = minTileY; tileY <= maxTileY; ++tileY)
|
|
||||||
changedTiles.insert(TilePosition {tileX, tileY});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::shared_ptr<NavMeshCacheItem>& NavMeshManager::getCached(const osg::Vec3f& agentHalfExtents) const
|
const std::shared_ptr<NavMeshCacheItem>& NavMeshManager::getCached(const osg::Vec3f& agentHalfExtents) const
|
||||||
|
|
|
@ -7,7 +7,8 @@ namespace DetourNavigator
|
||||||
RecastMeshManager::RecastMeshManager(const Settings& settings)
|
RecastMeshManager::RecastMeshManager(const Settings& settings)
|
||||||
: mShouldRebuild(false)
|
: mShouldRebuild(false)
|
||||||
, mMeshBuilder(settings)
|
, mMeshBuilder(settings)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
bool RecastMeshManager::addObject(std::size_t id, const btCollisionShape& shape, const btTransform& transform)
|
bool RecastMeshManager::addObject(std::size_t id, const btCollisionShape& shape, const btTransform& transform)
|
||||||
{
|
{
|
||||||
|
@ -40,12 +41,7 @@ namespace DetourNavigator
|
||||||
return;
|
return;
|
||||||
mMeshBuilder.reset();
|
mMeshBuilder.reset();
|
||||||
for (const auto& v : mObjects)
|
for (const auto& v : mObjects)
|
||||||
{
|
mMeshBuilder.addObject(*v.second.mShape, v.second.mTransform);
|
||||||
if (v.second.mShape->getShapeType() == TERRAIN_SHAPE_PROXYTYPE)
|
|
||||||
mMeshBuilder.addObject(*static_cast<const btHeightfieldTerrainShape*>(v.second.mShape), v.second.mTransform);
|
|
||||||
else if (v.second.mShape->isConcave())
|
|
||||||
mMeshBuilder.addObject(*static_cast<const btConcaveShape*>(v.second.mShape), v.second.mTransform);
|
|
||||||
}
|
|
||||||
mShouldRebuild = false;
|
mShouldRebuild = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace DetourNavigator
|
||||||
float mMaxSimplificationError;
|
float mMaxSimplificationError;
|
||||||
float mMaxSlope;
|
float mMaxSlope;
|
||||||
float mRecastScaleFactor;
|
float mRecastScaleFactor;
|
||||||
|
int mBorderSize;
|
||||||
int mMaxEdgeLen;
|
int mMaxEdgeLen;
|
||||||
int mMaxNavMeshQueryNodes;
|
int mMaxNavMeshQueryNodes;
|
||||||
int mMaxVertsPerPoly;
|
int mMaxVertsPerPoly;
|
||||||
|
|
|
@ -60,6 +60,11 @@ namespace DetourNavigator
|
||||||
osg::Vec2f(tilePosition.x() + 1, tilePosition.y() + 1) * getTileSize(settings),
|
osg::Vec2f(tilePosition.x() + 1, tilePosition.y() + 1) * getTileSize(settings),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline float getBorderSize(const Settings& settings)
|
||||||
|
{
|
||||||
|
return settings.mBorderSize * settings.mCellSize;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -44,11 +44,6 @@ namespace DetourNavigator
|
||||||
return LockedSharedNavMesh(*mMutex, mValue);
|
return LockedSharedNavMesh(*mMutex, mValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
NavMeshPtr raw() const
|
|
||||||
{
|
|
||||||
return mValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<std::mutex> mMutex;
|
std::shared_ptr<std::mutex> mMutex;
|
||||||
NavMeshPtr mValue;
|
NavMeshPtr mValue;
|
||||||
|
|
|
@ -567,6 +567,9 @@ max simplification error = 1.3
|
||||||
# The width and height of each tile. (value > 0)
|
# The width and height of each tile. (value > 0)
|
||||||
tile size = 64
|
tile size = 64
|
||||||
|
|
||||||
|
# The size of the non-navigable border around the heightfield. (value >= 0)
|
||||||
|
border size = 16
|
||||||
|
|
||||||
# The maximum allowed length for contour edges along the border of the mesh. (value >= 0)
|
# The maximum allowed length for contour edges along the border of the mesh. (value >= 0)
|
||||||
max edge len = 12
|
max edge len = 12
|
||||||
|
|
||||||
|
@ -593,9 +596,21 @@ triangles per chunk = 256
|
||||||
|
|
||||||
# Enable debug log (true, false)
|
# Enable debug log (true, false)
|
||||||
enable log = false
|
enable log = false
|
||||||
|
|
||||||
|
# Write recast mesh to file in .obj format for each use to update nav mesh (true, false)
|
||||||
enable write recast mesh to file = false
|
enable write recast mesh to file = false
|
||||||
|
|
||||||
|
# Write NavMesh to file to be able to open by RecastDemo (true, false)
|
||||||
enable write nav mesh to file = false
|
enable write nav mesh to file = false
|
||||||
|
|
||||||
|
# Write each recast mesh file with revision in name. Otherwise will rewrite same file. (true, false)
|
||||||
enable recast mesh file name revision = false
|
enable recast mesh file name revision = false
|
||||||
|
|
||||||
|
# Write each nav mesh file with revision in name. Otherwise will rewrite same file. (true, false)
|
||||||
enable nav mesh file name revision = false
|
enable nav mesh file name revision = false
|
||||||
|
|
||||||
|
# Write recast mesh file at path with this prefix
|
||||||
recast mesh path prefix =
|
recast mesh path prefix =
|
||||||
|
|
||||||
|
# Write nav mesh file at path with this prefix
|
||||||
nav mesh path prefix =
|
nav mesh path prefix =
|
||||||
|
|
Loading…
Reference in a new issue