mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-06 09:39:49 +00:00
Merge branch 'navmesh_disk_rm_unused_tiles' into 'master'
Add navmeshtool flag to remove unused tiles from navmesh disk cache See merge request OpenMW/openmw!1671
This commit is contained in:
commit
b03f9e430c
@ -83,6 +83,9 @@ namespace NavMeshTool
|
|||||||
|
|
||||||
("process-interior-cells", bpo::value<bool>()->implicit_value(true)
|
("process-interior-cells", bpo::value<bool>()->implicit_value(true)
|
||||||
->default_value(false), "build navmesh for interior cells")
|
->default_value(false), "build navmesh for interior cells")
|
||||||
|
|
||||||
|
("remove-unused-tiles", bpo::value<bool>()->implicit_value(true)
|
||||||
|
->default_value(false), "remove tiles from cache that will not be used with current content profile")
|
||||||
;
|
;
|
||||||
Files::ConfigurationManager::addCommonOptions(result);
|
Files::ConfigurationManager::addCommonOptions(result);
|
||||||
|
|
||||||
@ -141,6 +144,7 @@ namespace NavMeshTool
|
|||||||
}
|
}
|
||||||
|
|
||||||
const bool processInteriorCells = variables["process-interior-cells"].as<bool>();
|
const bool processInteriorCells = variables["process-interior-cells"].as<bool>();
|
||||||
|
const bool removeUnusedTiles = variables["remove-unused-tiles"].as<bool>();
|
||||||
|
|
||||||
Fallback::Map::init(variables["fallback"].as<Fallback::FallbackMap>().mMap);
|
Fallback::Map::init(variables["fallback"].as<Fallback::FallbackMap>().mMap);
|
||||||
|
|
||||||
@ -177,7 +181,8 @@ namespace NavMeshTool
|
|||||||
WorldspaceData cellsData = gatherWorldspaceData(navigatorSettings, readers, vfs, bulletShapeManager,
|
WorldspaceData cellsData = gatherWorldspaceData(navigatorSettings, readers, vfs, bulletShapeManager,
|
||||||
esmData, processInteriorCells);
|
esmData, processInteriorCells);
|
||||||
|
|
||||||
generateAllNavMeshTiles(agentHalfExtents, navigatorSettings, threadsNumber, cellsData, std::move(db));
|
generateAllNavMeshTiles(agentHalfExtents, navigatorSettings, threadsNumber, removeUnusedTiles,
|
||||||
|
cellsData, std::move(db));
|
||||||
|
|
||||||
Log(Debug::Info) << "Done";
|
Log(Debug::Info) << "Done";
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
namespace NavMeshTool
|
namespace NavMeshTool
|
||||||
{
|
{
|
||||||
@ -40,6 +41,7 @@ namespace NavMeshTool
|
|||||||
using DetourNavigator::TileId;
|
using DetourNavigator::TileId;
|
||||||
using DetourNavigator::TilePosition;
|
using DetourNavigator::TilePosition;
|
||||||
using DetourNavigator::TileVersion;
|
using DetourNavigator::TileVersion;
|
||||||
|
using DetourNavigator::TilesPositionsRange;
|
||||||
using Sqlite3::Transaction;
|
using Sqlite3::Transaction;
|
||||||
|
|
||||||
void logGeneratedTiles(std::size_t provided, std::size_t expected)
|
void logGeneratedTiles(std::size_t provided, std::size_t expected)
|
||||||
@ -62,8 +64,9 @@ namespace NavMeshTool
|
|||||||
public:
|
public:
|
||||||
std::atomic_size_t mExpected {0};
|
std::atomic_size_t mExpected {0};
|
||||||
|
|
||||||
explicit NavMeshTileConsumer(NavMeshDb&& db)
|
explicit NavMeshTileConsumer(NavMeshDb&& db, bool removeUnusedTiles)
|
||||||
: mDb(std::move(db))
|
: mDb(std::move(db))
|
||||||
|
, mRemoveUnusedTiles(removeUnusedTiles)
|
||||||
, mTransaction(mDb.startTransaction())
|
, mTransaction(mDb.startTransaction())
|
||||||
, mNextTileId(mDb.getMaxTileId() + 1)
|
, mNextTileId(mDb.getMaxTileId() + 1)
|
||||||
, mNextShapeId(mDb.getMaxShapeId() + 1)
|
, mNextShapeId(mDb.getMaxShapeId() + 1)
|
||||||
@ -75,13 +78,19 @@ namespace NavMeshTool
|
|||||||
|
|
||||||
std::size_t getUpdated() const { return mUpdated.load(); }
|
std::size_t getUpdated() const { return mUpdated.load(); }
|
||||||
|
|
||||||
|
std::size_t getDeleted() const
|
||||||
|
{
|
||||||
|
const std::lock_guard lock(mMutex);
|
||||||
|
return mDeleted;
|
||||||
|
}
|
||||||
|
|
||||||
std::int64_t resolveMeshSource(const MeshSource& source) override
|
std::int64_t resolveMeshSource(const MeshSource& source) override
|
||||||
{
|
{
|
||||||
const std::lock_guard lock(mMutex);
|
const std::lock_guard lock(mMutex);
|
||||||
return DetourNavigator::resolveMeshSource(mDb, source, mNextShapeId);
|
return DetourNavigator::resolveMeshSource(mDb, source, mNextShapeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<NavMeshTileInfo> find(const std::string& worldspace, const TilePosition &tilePosition,
|
std::optional<NavMeshTileInfo> find(std::string_view worldspace, const TilePosition &tilePosition,
|
||||||
const std::vector<std::byte> &input) override
|
const std::vector<std::byte> &input) override
|
||||||
{
|
{
|
||||||
std::optional<NavMeshTileInfo> result;
|
std::optional<NavMeshTileInfo> result;
|
||||||
@ -96,11 +105,34 @@ namespace NavMeshTool
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ignore() override { report(); }
|
void ignore(std::string_view worldspace, const TilePosition& tilePosition) override
|
||||||
|
|
||||||
void insert(const std::string& worldspace, const TilePosition& tilePosition, std::int64_t version,
|
|
||||||
const std::vector<std::byte>& input, PreparedNavMeshData& data) override
|
|
||||||
{
|
{
|
||||||
|
if (mRemoveUnusedTiles)
|
||||||
|
{
|
||||||
|
std::lock_guard lock(mMutex);
|
||||||
|
mDeleted += static_cast<std::size_t>(mDb.deleteTilesAt(worldspace, tilePosition));
|
||||||
|
}
|
||||||
|
report();
|
||||||
|
}
|
||||||
|
|
||||||
|
void identity(std::string_view worldspace, const TilePosition& tilePosition, std::int64_t tileId) override
|
||||||
|
{
|
||||||
|
if (mRemoveUnusedTiles)
|
||||||
|
{
|
||||||
|
std::lock_guard lock(mMutex);
|
||||||
|
mDeleted += static_cast<std::size_t>(mDb.deleteTilesAtExcept(worldspace, tilePosition, TileId {tileId}));
|
||||||
|
}
|
||||||
|
report();
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert(std::string_view worldspace, const TilePosition& tilePosition,
|
||||||
|
std::int64_t version, const std::vector<std::byte>& input, PreparedNavMeshData& data) override
|
||||||
|
{
|
||||||
|
if (mRemoveUnusedTiles)
|
||||||
|
{
|
||||||
|
std::lock_guard lock(mMutex);
|
||||||
|
mDeleted += static_cast<std::size_t>(mDb.deleteTilesAt(worldspace, tilePosition));
|
||||||
|
}
|
||||||
data.mUserId = static_cast<unsigned>(mNextTileId);
|
data.mUserId = static_cast<unsigned>(mNextTileId);
|
||||||
{
|
{
|
||||||
std::lock_guard lock(mMutex);
|
std::lock_guard lock(mMutex);
|
||||||
@ -111,11 +143,14 @@ namespace NavMeshTool
|
|||||||
report();
|
report();
|
||||||
}
|
}
|
||||||
|
|
||||||
void update(std::int64_t tileId, std::int64_t version, PreparedNavMeshData& data) override
|
void update(std::string_view worldspace, const TilePosition& tilePosition,
|
||||||
|
std::int64_t tileId, std::int64_t version, PreparedNavMeshData& data) override
|
||||||
{
|
{
|
||||||
data.mUserId = static_cast<unsigned>(tileId);
|
data.mUserId = static_cast<unsigned>(tileId);
|
||||||
{
|
{
|
||||||
std::lock_guard lock(mMutex);
|
std::lock_guard lock(mMutex);
|
||||||
|
if (mRemoveUnusedTiles)
|
||||||
|
mDeleted += static_cast<std::size_t>(mDb.deleteTilesAtExcept(worldspace, tilePosition, TileId {tileId}));
|
||||||
mDb.updateTile(TileId {tileId}, TileVersion {version}, serialize(data));
|
mDb.updateTile(TileId {tileId}, TileVersion {version}, serialize(data));
|
||||||
}
|
}
|
||||||
++mUpdated;
|
++mUpdated;
|
||||||
@ -140,49 +175,66 @@ namespace NavMeshTool
|
|||||||
|
|
||||||
void commit() { mTransaction.commit(); }
|
void commit() { mTransaction.commit(); }
|
||||||
|
|
||||||
|
void vacuum() { mDb.vacuum(); }
|
||||||
|
|
||||||
|
void removeTilesOutsideRange(std::string_view worldspace, const TilesPositionsRange& range)
|
||||||
|
{
|
||||||
|
const std::lock_guard lock(mMutex);
|
||||||
|
mTransaction.commit();
|
||||||
|
Log(Debug::Info) << "Removing tiles outside processed range for worldspace \"" << worldspace << "\"...";
|
||||||
|
mDeleted += static_cast<std::size_t>(mDb.deleteTilesOutsideRange(worldspace, range));
|
||||||
|
mTransaction = mDb.startTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::atomic_size_t mProvided {0};
|
std::atomic_size_t mProvided {0};
|
||||||
std::atomic_size_t mInserted {0};
|
std::atomic_size_t mInserted {0};
|
||||||
std::atomic_size_t mUpdated {0};
|
std::atomic_size_t mUpdated {0};
|
||||||
std::mutex mMutex;
|
std::size_t mDeleted = 0;
|
||||||
|
mutable std::mutex mMutex;
|
||||||
NavMeshDb mDb;
|
NavMeshDb mDb;
|
||||||
|
const bool mRemoveUnusedTiles;
|
||||||
Transaction mTransaction;
|
Transaction mTransaction;
|
||||||
TileId mNextTileId;
|
TileId mNextTileId;
|
||||||
std::condition_variable mHasTile;
|
std::condition_variable mHasTile;
|
||||||
Misc::ProgressReporter<LogGeneratedTiles> mReporter;
|
Misc::ProgressReporter<LogGeneratedTiles> mReporter;
|
||||||
ShapeId mNextShapeId;
|
ShapeId mNextShapeId;
|
||||||
|
std::mutex mReportMutex;
|
||||||
|
|
||||||
void report()
|
void report()
|
||||||
{
|
{
|
||||||
mReporter(mProvided + 1, mExpected);
|
const std::size_t provided = mProvided.fetch_add(1, std::memory_order_relaxed) + 1;
|
||||||
++mProvided;
|
mReporter(provided, mExpected);
|
||||||
mHasTile.notify_one();
|
mHasTile.notify_one();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateAllNavMeshTiles(const osg::Vec3f& agentHalfExtents, const Settings& settings,
|
void generateAllNavMeshTiles(const osg::Vec3f& agentHalfExtents, const Settings& settings,
|
||||||
const std::size_t threadsNumber, WorldspaceData& data, NavMeshDb&& db)
|
std::size_t threadsNumber, bool removeUnusedTiles, WorldspaceData& data, NavMeshDb&& db)
|
||||||
{
|
{
|
||||||
Log(Debug::Info) << "Generating navmesh tiles by " << threadsNumber << " parallel workers...";
|
Log(Debug::Info) << "Generating navmesh tiles by " << threadsNumber << " parallel workers...";
|
||||||
|
|
||||||
SceneUtil::WorkQueue workQueue(threadsNumber);
|
SceneUtil::WorkQueue workQueue(threadsNumber);
|
||||||
auto navMeshTileConsumer = std::make_shared<NavMeshTileConsumer>(std::move(db));
|
auto navMeshTileConsumer = std::make_shared<NavMeshTileConsumer>(std::move(db), removeUnusedTiles);
|
||||||
std::size_t tiles = 0;
|
std::size_t tiles = 0;
|
||||||
std::mt19937_64 random;
|
std::mt19937_64 random;
|
||||||
|
|
||||||
for (const std::unique_ptr<WorldspaceNavMeshInput>& input : data.mNavMeshInputs)
|
for (const std::unique_ptr<WorldspaceNavMeshInput>& input : data.mNavMeshInputs)
|
||||||
{
|
{
|
||||||
|
const auto range = DetourNavigator::makeTilesPositionsRange(
|
||||||
|
Misc::Convert::toOsgXY(input->mAabb.m_min),
|
||||||
|
Misc::Convert::toOsgXY(input->mAabb.m_max),
|
||||||
|
settings.mRecast
|
||||||
|
);
|
||||||
|
|
||||||
|
if (removeUnusedTiles)
|
||||||
|
navMeshTileConsumer->removeTilesOutsideRange(input->mWorldspace, range);
|
||||||
|
|
||||||
std::vector<TilePosition> worldspaceTiles;
|
std::vector<TilePosition> worldspaceTiles;
|
||||||
|
|
||||||
DetourNavigator::getTilesPositions(
|
DetourNavigator::getTilesPositions(range,
|
||||||
DetourNavigator::makeTilesPositionsRange(
|
[&] (const TilePosition& tilePosition) { worldspaceTiles.push_back(tilePosition); });
|
||||||
Misc::Convert::toOsgXY(input->mAabb.m_min),
|
|
||||||
Misc::Convert::toOsgXY(input->mAabb.m_max),
|
|
||||||
settings.mRecast
|
|
||||||
),
|
|
||||||
[&] (const TilePosition& tilePosition) { worldspaceTiles.push_back(tilePosition); }
|
|
||||||
);
|
|
||||||
|
|
||||||
tiles += worldspaceTiles.size();
|
tiles += worldspaceTiles.size();
|
||||||
|
|
||||||
@ -204,8 +256,19 @@ namespace NavMeshTool
|
|||||||
navMeshTileConsumer->wait();
|
navMeshTileConsumer->wait();
|
||||||
navMeshTileConsumer->commit();
|
navMeshTileConsumer->commit();
|
||||||
|
|
||||||
|
const auto inserted = navMeshTileConsumer->getInserted();
|
||||||
|
const auto updated = navMeshTileConsumer->getUpdated();
|
||||||
|
const auto deleted = navMeshTileConsumer->getDeleted();
|
||||||
|
|
||||||
Log(Debug::Info) << "Generated navmesh for " << navMeshTileConsumer->getProvided() << " tiles, "
|
Log(Debug::Info) << "Generated navmesh for " << navMeshTileConsumer->getProvided() << " tiles, "
|
||||||
<< navMeshTileConsumer->getInserted() << " are inserted and "
|
<< inserted << " are inserted, "
|
||||||
<< navMeshTileConsumer->getUpdated() << " updated";
|
<< updated << " updated and "
|
||||||
|
<< deleted << " deleted";
|
||||||
|
|
||||||
|
if (inserted + updated + deleted > 0)
|
||||||
|
{
|
||||||
|
Log(Debug::Info) << "Vacuuming the database...";
|
||||||
|
navMeshTileConsumer->vacuum();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include <osg/Vec3f>
|
#include <osg/Vec3f>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <string_view>
|
|
||||||
|
|
||||||
namespace DetourNavigator
|
namespace DetourNavigator
|
||||||
{
|
{
|
||||||
@ -17,7 +16,8 @@ namespace NavMeshTool
|
|||||||
struct WorldspaceData;
|
struct WorldspaceData;
|
||||||
|
|
||||||
void generateAllNavMeshTiles(const osg::Vec3f& agentHalfExtents, const DetourNavigator::Settings& settings,
|
void generateAllNavMeshTiles(const osg::Vec3f& agentHalfExtents, const DetourNavigator::Settings& settings,
|
||||||
const std::size_t threadsNumber, WorldspaceData& cellsData, DetourNavigator::NavMeshDb&& db);
|
std::size_t threadsNumber, bool removeUnusedTiles, WorldspaceData& cellsData,
|
||||||
|
DetourNavigator::NavMeshDb&& db);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -109,4 +109,61 @@ namespace
|
|||||||
EXPECT_THROW(mDb.insertTile(tileId, worldspace, tilePosition, version, input, data), std::runtime_error);
|
EXPECT_THROW(mDb.insertTile(tileId, worldspace, tilePosition, version, input, data), std::runtime_error);
|
||||||
EXPECT_NO_THROW(insertTile(TileId {54}, version));
|
EXPECT_NO_THROW(insertTile(TileId {54}, version));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(DetourNavigatorNavMeshDbTest, delete_tiles_at_should_remove_all_tiles_with_given_worldspace_and_position)
|
||||||
|
{
|
||||||
|
const TileVersion version {1};
|
||||||
|
const std::string worldspace = "sys::default";
|
||||||
|
const TilePosition tilePosition {3, 4};
|
||||||
|
const std::vector<std::byte> input1 = generateData();
|
||||||
|
const std::vector<std::byte> input2 = generateData();
|
||||||
|
const std::vector<std::byte> data = generateData();
|
||||||
|
ASSERT_EQ(mDb.insertTile(TileId {53}, worldspace, tilePosition, version, input1, data), 1);
|
||||||
|
ASSERT_EQ(mDb.insertTile(TileId {54}, worldspace, tilePosition, version, input2, data), 1);
|
||||||
|
ASSERT_EQ(mDb.deleteTilesAt(worldspace, tilePosition), 2);
|
||||||
|
EXPECT_FALSE(mDb.findTile(worldspace, tilePosition, input1).has_value());
|
||||||
|
EXPECT_FALSE(mDb.findTile(worldspace, tilePosition, input2).has_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DetourNavigatorNavMeshDbTest, delete_tiles_at_except_should_leave_tile_with_given_id)
|
||||||
|
{
|
||||||
|
const TileId leftTileId {53};
|
||||||
|
const TileId removedTileId {54};
|
||||||
|
const TileVersion version {1};
|
||||||
|
const std::string worldspace = "sys::default";
|
||||||
|
const TilePosition tilePosition {3, 4};
|
||||||
|
const std::vector<std::byte> leftInput = generateData();
|
||||||
|
const std::vector<std::byte> removedInput = generateData();
|
||||||
|
const std::vector<std::byte> data = generateData();
|
||||||
|
ASSERT_EQ(mDb.insertTile(leftTileId, worldspace, tilePosition, version, leftInput, data), 1);
|
||||||
|
ASSERT_EQ(mDb.insertTile(removedTileId, worldspace, tilePosition, version, removedInput, data), 1);
|
||||||
|
ASSERT_EQ(mDb.deleteTilesAtExcept(worldspace, tilePosition, leftTileId), 1);
|
||||||
|
const auto left = mDb.findTile(worldspace, tilePosition, leftInput);
|
||||||
|
ASSERT_TRUE(left.has_value());
|
||||||
|
EXPECT_EQ(left->mTileId, leftTileId);
|
||||||
|
EXPECT_FALSE(mDb.findTile(worldspace, tilePosition, removedInput).has_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DetourNavigatorNavMeshDbTest, delete_tiles_outside_range_should_leave_tiles_inside_given_rectangle)
|
||||||
|
{
|
||||||
|
TileId tileId {1};
|
||||||
|
const TileVersion version {1};
|
||||||
|
const std::string worldspace = "sys::default";
|
||||||
|
const std::vector<std::byte> input = generateData();
|
||||||
|
const std::vector<std::byte> data = generateData();
|
||||||
|
for (int x = -2; x <= 2; ++x)
|
||||||
|
{
|
||||||
|
for (int y = -2; y <= 2; ++y)
|
||||||
|
{
|
||||||
|
ASSERT_EQ(mDb.insertTile(tileId, worldspace, TilePosition {x, y}, version, input, data), 1);
|
||||||
|
++tileId.t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const TilesPositionsRange range {TilePosition {-1, -1}, TilePosition {2, 2}};
|
||||||
|
ASSERT_EQ(mDb.deleteTilesOutsideRange(worldspace, range), 16);
|
||||||
|
for (int x = -2; x <= 2; ++x)
|
||||||
|
for (int y = -2; y <= 2; ++y)
|
||||||
|
ASSERT_EQ(mDb.findTile(worldspace, TilePosition {x, y}, input).has_value(),
|
||||||
|
-1 <= x && x <= 1 && -1 <= y && y <= 1) << "x=" << x << " y=" << y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
namespace SerializationTesting
|
namespace SerializationTesting
|
||||||
{
|
{
|
||||||
@ -20,7 +21,7 @@ namespace SerializationTesting
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Enum
|
enum Enum : std::int32_t
|
||||||
{
|
{
|
||||||
A,
|
A,
|
||||||
B,
|
B,
|
||||||
@ -30,7 +31,7 @@ namespace SerializationTesting
|
|||||||
struct Composite
|
struct Composite
|
||||||
{
|
{
|
||||||
short mFloatArray[3] = {0};
|
short mFloatArray[3] = {0};
|
||||||
std::vector<int> mIntVector;
|
std::vector<std::int32_t> mIntVector;
|
||||||
std::vector<Enum> mEnumVector;
|
std::vector<Enum> mEnumVector;
|
||||||
std::vector<Pod> mPodVector;
|
std::vector<Pod> mPodVector;
|
||||||
std::size_t mPodDataSize = 0;
|
std::size_t mPodDataSize = 0;
|
||||||
|
@ -25,12 +25,14 @@ namespace DetourNavigator
|
|||||||
{
|
{
|
||||||
struct Ignore
|
struct Ignore
|
||||||
{
|
{
|
||||||
|
std::string_view mWorldspace;
|
||||||
|
const TilePosition& mTilePosition;
|
||||||
std::shared_ptr<NavMeshTileConsumer> mConsumer;
|
std::shared_ptr<NavMeshTileConsumer> mConsumer;
|
||||||
|
|
||||||
~Ignore() noexcept
|
~Ignore() noexcept
|
||||||
{
|
{
|
||||||
if (mConsumer != nullptr)
|
if (mConsumer != nullptr)
|
||||||
mConsumer->ignore();
|
mConsumer->ignore(mWorldspace, mTilePosition);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -59,7 +61,7 @@ namespace DetourNavigator
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Ignore ignore {consumer};
|
Ignore ignore {mWorldspace, mTilePosition, consumer};
|
||||||
|
|
||||||
const std::shared_ptr<RecastMesh> recastMesh = mRecastMeshProvider.getMesh(mWorldspace, mTilePosition);
|
const std::shared_ptr<RecastMesh> recastMesh = mRecastMeshProvider.getMesh(mWorldspace, mTilePosition);
|
||||||
|
|
||||||
@ -72,7 +74,11 @@ namespace DetourNavigator
|
|||||||
const std::optional<NavMeshTileInfo> info = consumer->find(mWorldspace, mTilePosition, input);
|
const std::optional<NavMeshTileInfo> info = consumer->find(mWorldspace, mTilePosition, input);
|
||||||
|
|
||||||
if (info.has_value() && info->mVersion == mSettings.mNavMeshVersion)
|
if (info.has_value() && info->mVersion == mSettings.mNavMeshVersion)
|
||||||
|
{
|
||||||
|
consumer->identity(mWorldspace, mTilePosition, info->mTileId);
|
||||||
|
ignore.mConsumer = nullptr;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const auto data = prepareNavMeshTileData(*recastMesh, mTilePosition, mAgentHalfExtents, mSettings.mRecast);
|
const auto data = prepareNavMeshTileData(*recastMesh, mTilePosition, mAgentHalfExtents, mSettings.mRecast);
|
||||||
|
|
||||||
@ -80,7 +86,7 @@ namespace DetourNavigator
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (info.has_value())
|
if (info.has_value())
|
||||||
consumer->update(info->mTileId, mSettings.mNavMeshVersion, *data);
|
consumer->update(mWorldspace, mTilePosition, info->mTileId, mSettings.mNavMeshVersion, *data);
|
||||||
else
|
else
|
||||||
consumer->insert(mWorldspace, mTilePosition, mSettings.mNavMeshVersion, input, *data);
|
consumer->insert(mWorldspace, mTilePosition, mSettings.mNavMeshVersion, input, *data);
|
||||||
|
|
||||||
|
@ -36,15 +36,19 @@ namespace DetourNavigator
|
|||||||
|
|
||||||
virtual std::int64_t resolveMeshSource(const MeshSource& source) = 0;
|
virtual std::int64_t resolveMeshSource(const MeshSource& source) = 0;
|
||||||
|
|
||||||
virtual std::optional<NavMeshTileInfo> find(const std::string& worldspace, const TilePosition& tilePosition,
|
virtual std::optional<NavMeshTileInfo> find(std::string_view worldspace, const TilePosition& tilePosition,
|
||||||
const std::vector<std::byte>& input) = 0;
|
const std::vector<std::byte>& input) = 0;
|
||||||
|
|
||||||
virtual void ignore() = 0;
|
virtual void ignore(std::string_view worldspace, const TilePosition& tilePosition) = 0;
|
||||||
|
|
||||||
virtual void insert(const std::string& worldspace, const TilePosition& tilePosition,
|
virtual void identity(std::string_view worldspace, const TilePosition& tilePosition,
|
||||||
|
std::int64_t tileId) = 0;
|
||||||
|
|
||||||
|
virtual void insert(std::string_view worldspace, const TilePosition& tilePosition,
|
||||||
std::int64_t version, const std::vector<std::byte>& input, PreparedNavMeshData& data) = 0;
|
std::int64_t version, const std::vector<std::byte>& input, PreparedNavMeshData& data) = 0;
|
||||||
|
|
||||||
virtual void update(std::int64_t tileId, std::int64_t version, PreparedNavMeshData& data) = 0;
|
virtual void update(std::string_view worldspace, const TilePosition& tilePosition,
|
||||||
|
std::int64_t tileId, std::int64_t version, PreparedNavMeshData& data) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GenerateNavMeshTile final : public SceneUtil::WorkItem
|
class GenerateNavMeshTile final : public SceneUtil::WorkItem
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "tilebounds.hpp"
|
#include "tilebounds.hpp"
|
||||||
#include "tileposition.hpp"
|
#include "tileposition.hpp"
|
||||||
|
#include "tilespositionsrange.hpp"
|
||||||
|
|
||||||
class btVector3;
|
class btVector3;
|
||||||
class btTransform;
|
class btTransform;
|
||||||
@ -17,12 +18,6 @@ namespace DetourNavigator
|
|||||||
{
|
{
|
||||||
struct RecastSettings;
|
struct RecastSettings;
|
||||||
|
|
||||||
struct TilesPositionsRange
|
|
||||||
{
|
|
||||||
TilePosition mBegin;
|
|
||||||
TilePosition mEnd;
|
|
||||||
};
|
|
||||||
|
|
||||||
TilesPositionsRange makeTilesPositionsRange(const osg::Vec2f& aabbMin,
|
TilesPositionsRange makeTilesPositionsRange(const osg::Vec2f& aabbMin,
|
||||||
const osg::Vec2f& aabbMax, const RecastSettings& settings);
|
const osg::Vec2f& aabbMax, const RecastSettings& settings);
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <string>
|
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -35,6 +34,9 @@ namespace DetourNavigator
|
|||||||
CREATE UNIQUE INDEX IF NOT EXISTS index_unique_tiles_by_worldspace_and_tile_position_and_input
|
CREATE UNIQUE INDEX IF NOT EXISTS index_unique_tiles_by_worldspace_and_tile_position_and_input
|
||||||
ON tiles (worldspace, tile_position_x, tile_position_y, input);
|
ON tiles (worldspace, tile_position_x, tile_position_y, input);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS index_tiles_by_worldspace_and_tile_position
|
||||||
|
ON tiles (worldspace, tile_position_x, tile_position_y);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS shapes (
|
CREATE TABLE IF NOT EXISTS shapes (
|
||||||
shape_id INTEGER PRIMARY KEY,
|
shape_id INTEGER PRIMARY KEY,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
@ -83,6 +85,31 @@ namespace DetourNavigator
|
|||||||
WHERE tile_id = :tile_id
|
WHERE tile_id = :tile_id
|
||||||
)";
|
)";
|
||||||
|
|
||||||
|
constexpr std::string_view deleteTilesAtQuery = R"(
|
||||||
|
DELETE FROM tiles
|
||||||
|
WHERE worldspace = :worldspace
|
||||||
|
AND tile_position_x = :tile_position_x
|
||||||
|
AND tile_position_y = :tile_position_y
|
||||||
|
)";
|
||||||
|
|
||||||
|
constexpr std::string_view deleteTilesAtExceptQuery = R"(
|
||||||
|
DELETE FROM tiles
|
||||||
|
WHERE worldspace = :worldspace
|
||||||
|
AND tile_position_x = :tile_position_x
|
||||||
|
AND tile_position_y = :tile_position_y
|
||||||
|
AND tile_id != :exclude_tile_id
|
||||||
|
)";
|
||||||
|
|
||||||
|
constexpr std::string_view deleteTilesOutsideRangeQuery = R"(
|
||||||
|
DELETE FROM tiles
|
||||||
|
WHERE worldspace = :worldspace
|
||||||
|
AND ( tile_position_x < :begin_tile_position_x
|
||||||
|
OR tile_position_y < :begin_tile_position_y
|
||||||
|
OR tile_position_x >= :end_tile_position_x
|
||||||
|
OR tile_position_y >= :end_tile_position_y
|
||||||
|
)
|
||||||
|
)";
|
||||||
|
|
||||||
constexpr std::string_view getMaxShapeIdQuery = R"(
|
constexpr std::string_view getMaxShapeIdQuery = R"(
|
||||||
SELECT max(shape_id) FROM shapes
|
SELECT max(shape_id) FROM shapes
|
||||||
)";
|
)";
|
||||||
@ -99,6 +126,10 @@ namespace DetourNavigator
|
|||||||
INSERT INTO shapes ( shape_id, name, type, hash)
|
INSERT INTO shapes ( shape_id, name, type, hash)
|
||||||
VALUES (:shape_id, :name, :type, :hash)
|
VALUES (:shape_id, :name, :type, :hash)
|
||||||
)";
|
)";
|
||||||
|
|
||||||
|
constexpr std::string_view vacuumQuery = R"(
|
||||||
|
VACUUM;
|
||||||
|
)";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& stream, ShapeType value)
|
std::ostream& operator<<(std::ostream& stream, ShapeType value)
|
||||||
@ -118,9 +149,13 @@ namespace DetourNavigator
|
|||||||
, mGetTileData(*mDb, DbQueries::GetTileData {})
|
, mGetTileData(*mDb, DbQueries::GetTileData {})
|
||||||
, mInsertTile(*mDb, DbQueries::InsertTile {})
|
, mInsertTile(*mDb, DbQueries::InsertTile {})
|
||||||
, mUpdateTile(*mDb, DbQueries::UpdateTile {})
|
, mUpdateTile(*mDb, DbQueries::UpdateTile {})
|
||||||
|
, mDeleteTilesAt(*mDb, DbQueries::DeleteTilesAt {})
|
||||||
|
, mDeleteTilesAtExcept(*mDb, DbQueries::DeleteTilesAtExcept {})
|
||||||
|
, mDeleteTilesOutsideRange(*mDb, DbQueries::DeleteTilesOutsideRange {})
|
||||||
, mGetMaxShapeId(*mDb, DbQueries::GetMaxShapeId {})
|
, mGetMaxShapeId(*mDb, DbQueries::GetMaxShapeId {})
|
||||||
, mFindShapeId(*mDb, DbQueries::FindShapeId {})
|
, mFindShapeId(*mDb, DbQueries::FindShapeId {})
|
||||||
, mInsertShape(*mDb, DbQueries::InsertShape {})
|
, mInsertShape(*mDb, DbQueries::InsertShape {})
|
||||||
|
, mVacuum(*mDb, DbQueries::Vacuum {})
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,7 +171,7 @@ namespace DetourNavigator
|
|||||||
return tileId;
|
return tileId;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<Tile> NavMeshDb::findTile(const std::string& worldspace,
|
std::optional<Tile> NavMeshDb::findTile(std::string_view worldspace,
|
||||||
const TilePosition& tilePosition, const std::vector<std::byte>& input)
|
const TilePosition& tilePosition, const std::vector<std::byte>& input)
|
||||||
{
|
{
|
||||||
Tile result;
|
Tile result;
|
||||||
@ -147,7 +182,7 @@ namespace DetourNavigator
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<TileData> NavMeshDb::getTileData(const std::string& worldspace,
|
std::optional<TileData> NavMeshDb::getTileData(std::string_view worldspace,
|
||||||
const TilePosition& tilePosition, const std::vector<std::byte>& input)
|
const TilePosition& tilePosition, const std::vector<std::byte>& input)
|
||||||
{
|
{
|
||||||
TileData result;
|
TileData result;
|
||||||
@ -159,7 +194,7 @@ namespace DetourNavigator
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int NavMeshDb::insertTile(TileId tileId, const std::string& worldspace, const TilePosition& tilePosition,
|
int NavMeshDb::insertTile(TileId tileId, std::string_view worldspace, const TilePosition& tilePosition,
|
||||||
TileVersion version, const std::vector<std::byte>& input, const std::vector<std::byte>& data)
|
TileVersion version, const std::vector<std::byte>& input, const std::vector<std::byte>& data)
|
||||||
{
|
{
|
||||||
const std::vector<std::byte> compressedInput = Misc::compress(input);
|
const std::vector<std::byte> compressedInput = Misc::compress(input);
|
||||||
@ -173,6 +208,21 @@ namespace DetourNavigator
|
|||||||
return execute(*mDb, mUpdateTile, tileId, version, compressedData);
|
return execute(*mDb, mUpdateTile, tileId, version, compressedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int NavMeshDb::deleteTilesAt(std::string_view worldspace, const TilePosition& tilePosition)
|
||||||
|
{
|
||||||
|
return execute(*mDb, mDeleteTilesAt, worldspace, tilePosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
int NavMeshDb::deleteTilesAtExcept(std::string_view worldspace, const TilePosition& tilePosition, TileId excludeTileId)
|
||||||
|
{
|
||||||
|
return execute(*mDb, mDeleteTilesAtExcept, worldspace, tilePosition, excludeTileId);
|
||||||
|
}
|
||||||
|
|
||||||
|
int NavMeshDb::deleteTilesOutsideRange(std::string_view worldspace, const TilesPositionsRange& range)
|
||||||
|
{
|
||||||
|
return execute(*mDb, mDeleteTilesOutsideRange, worldspace, range);
|
||||||
|
}
|
||||||
|
|
||||||
ShapeId NavMeshDb::getMaxShapeId()
|
ShapeId NavMeshDb::getMaxShapeId()
|
||||||
{
|
{
|
||||||
ShapeId shapeId {0};
|
ShapeId shapeId {0};
|
||||||
@ -180,7 +230,7 @@ namespace DetourNavigator
|
|||||||
return shapeId;
|
return shapeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<ShapeId> NavMeshDb::findShapeId(const std::string& name, ShapeType type,
|
std::optional<ShapeId> NavMeshDb::findShapeId(std::string_view name, ShapeType type,
|
||||||
const Sqlite3::ConstBlob& hash)
|
const Sqlite3::ConstBlob& hash)
|
||||||
{
|
{
|
||||||
ShapeId shapeId;
|
ShapeId shapeId;
|
||||||
@ -189,12 +239,17 @@ namespace DetourNavigator
|
|||||||
return shapeId;
|
return shapeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
int NavMeshDb::insertShape(ShapeId shapeId, const std::string& name, ShapeType type,
|
int NavMeshDb::insertShape(ShapeId shapeId, std::string_view name, ShapeType type,
|
||||||
const Sqlite3::ConstBlob& hash)
|
const Sqlite3::ConstBlob& hash)
|
||||||
{
|
{
|
||||||
return execute(*mDb, mInsertShape, shapeId, name, type, hash);
|
return execute(*mDb, mInsertShape, shapeId, name, type, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NavMeshDb::vacuum()
|
||||||
|
{
|
||||||
|
execute(*mDb, mVacuum);
|
||||||
|
}
|
||||||
|
|
||||||
namespace DbQueries
|
namespace DbQueries
|
||||||
{
|
{
|
||||||
std::string_view GetMaxTileId::text() noexcept
|
std::string_view GetMaxTileId::text() noexcept
|
||||||
@ -207,7 +262,7 @@ namespace DetourNavigator
|
|||||||
return findTileQuery;
|
return findTileQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FindTile::bind(sqlite3& db, sqlite3_stmt& statement, const std::string& worldspace,
|
void FindTile::bind(sqlite3& db, sqlite3_stmt& statement, std::string_view worldspace,
|
||||||
const TilePosition& tilePosition, const std::vector<std::byte>& input)
|
const TilePosition& tilePosition, const std::vector<std::byte>& input)
|
||||||
{
|
{
|
||||||
Sqlite3::bindParameter(db, statement, ":worldspace", worldspace);
|
Sqlite3::bindParameter(db, statement, ":worldspace", worldspace);
|
||||||
@ -221,7 +276,7 @@ namespace DetourNavigator
|
|||||||
return getTileDataQuery;
|
return getTileDataQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetTileData::bind(sqlite3& db, sqlite3_stmt& statement, const std::string& worldspace,
|
void GetTileData::bind(sqlite3& db, sqlite3_stmt& statement, std::string_view worldspace,
|
||||||
const TilePosition& tilePosition, const std::vector<std::byte>& input)
|
const TilePosition& tilePosition, const std::vector<std::byte>& input)
|
||||||
{
|
{
|
||||||
Sqlite3::bindParameter(db, statement, ":worldspace", worldspace);
|
Sqlite3::bindParameter(db, statement, ":worldspace", worldspace);
|
||||||
@ -235,7 +290,7 @@ namespace DetourNavigator
|
|||||||
return insertTileQuery;
|
return insertTileQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InsertTile::bind(sqlite3& db, sqlite3_stmt& statement, TileId tileId, const std::string& worldspace,
|
void InsertTile::bind(sqlite3& db, sqlite3_stmt& statement, TileId tileId, std::string_view worldspace,
|
||||||
const TilePosition& tilePosition, TileVersion version, const std::vector<std::byte>& input,
|
const TilePosition& tilePosition, TileVersion version, const std::vector<std::byte>& input,
|
||||||
const std::vector<std::byte>& data)
|
const std::vector<std::byte>& data)
|
||||||
{
|
{
|
||||||
@ -261,6 +316,48 @@ namespace DetourNavigator
|
|||||||
Sqlite3::bindParameter(db, statement, ":data", data);
|
Sqlite3::bindParameter(db, statement, ":data", data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string_view DeleteTilesAt::text() noexcept
|
||||||
|
{
|
||||||
|
return deleteTilesAtQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeleteTilesAt::bind(sqlite3& db, sqlite3_stmt& statement, std::string_view worldspace,
|
||||||
|
const TilePosition& tilePosition)
|
||||||
|
{
|
||||||
|
Sqlite3::bindParameter(db, statement, ":worldspace", worldspace);
|
||||||
|
Sqlite3::bindParameter(db, statement, ":tile_position_x", tilePosition.x());
|
||||||
|
Sqlite3::bindParameter(db, statement, ":tile_position_y", tilePosition.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view DeleteTilesAtExcept::text() noexcept
|
||||||
|
{
|
||||||
|
return deleteTilesAtExceptQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeleteTilesAtExcept::bind(sqlite3& db, sqlite3_stmt& statement, std::string_view worldspace,
|
||||||
|
const TilePosition& tilePosition, TileId excludeTileId)
|
||||||
|
{
|
||||||
|
Sqlite3::bindParameter(db, statement, ":worldspace", worldspace);
|
||||||
|
Sqlite3::bindParameter(db, statement, ":tile_position_x", tilePosition.x());
|
||||||
|
Sqlite3::bindParameter(db, statement, ":tile_position_y", tilePosition.y());
|
||||||
|
Sqlite3::bindParameter(db, statement, ":exclude_tile_id", excludeTileId);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string_view DeleteTilesOutsideRange::text() noexcept
|
||||||
|
{
|
||||||
|
return deleteTilesOutsideRangeQuery;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeleteTilesOutsideRange::bind(sqlite3& db, sqlite3_stmt& statement, std::string_view worldspace,
|
||||||
|
const TilesPositionsRange& range)
|
||||||
|
{
|
||||||
|
Sqlite3::bindParameter(db, statement, ":worldspace", worldspace);
|
||||||
|
Sqlite3::bindParameter(db, statement, ":begin_tile_position_x", range.mBegin.x());
|
||||||
|
Sqlite3::bindParameter(db, statement, ":begin_tile_position_y", range.mBegin.y());
|
||||||
|
Sqlite3::bindParameter(db, statement, ":end_tile_position_x", range.mEnd.x());
|
||||||
|
Sqlite3::bindParameter(db, statement, ":end_tile_position_y", range.mEnd.y());
|
||||||
|
}
|
||||||
|
|
||||||
std::string_view GetMaxShapeId::text() noexcept
|
std::string_view GetMaxShapeId::text() noexcept
|
||||||
{
|
{
|
||||||
return getMaxShapeIdQuery;
|
return getMaxShapeIdQuery;
|
||||||
@ -271,7 +368,7 @@ namespace DetourNavigator
|
|||||||
return findShapeIdQuery;
|
return findShapeIdQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FindShapeId::bind(sqlite3& db, sqlite3_stmt& statement, const std::string& name,
|
void FindShapeId::bind(sqlite3& db, sqlite3_stmt& statement, std::string_view name,
|
||||||
ShapeType type, const Sqlite3::ConstBlob& hash)
|
ShapeType type, const Sqlite3::ConstBlob& hash)
|
||||||
{
|
{
|
||||||
Sqlite3::bindParameter(db, statement, ":name", name);
|
Sqlite3::bindParameter(db, statement, ":name", name);
|
||||||
@ -284,7 +381,7 @@ namespace DetourNavigator
|
|||||||
return insertShapeQuery;
|
return insertShapeQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InsertShape::bind(sqlite3& db, sqlite3_stmt& statement, ShapeId shapeId, const std::string& name,
|
void InsertShape::bind(sqlite3& db, sqlite3_stmt& statement, ShapeId shapeId, std::string_view name,
|
||||||
ShapeType type, const Sqlite3::ConstBlob& hash)
|
ShapeType type, const Sqlite3::ConstBlob& hash)
|
||||||
{
|
{
|
||||||
Sqlite3::bindParameter(db, statement, ":shape_id", shapeId);
|
Sqlite3::bindParameter(db, statement, ":shape_id", shapeId);
|
||||||
@ -292,5 +389,10 @@ namespace DetourNavigator
|
|||||||
Sqlite3::bindParameter(db, statement, ":type", static_cast<int>(type));
|
Sqlite3::bindParameter(db, statement, ":type", static_cast<int>(type));
|
||||||
Sqlite3::bindParameter(db, statement, ":hash", hash);
|
Sqlite3::bindParameter(db, statement, ":hash", hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string_view Vacuum::text() noexcept
|
||||||
|
{
|
||||||
|
return vacuumQuery;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "tileposition.hpp"
|
#include "tileposition.hpp"
|
||||||
|
|
||||||
|
#include <components/detournavigator/tilespositionsrange.hpp>
|
||||||
|
|
||||||
#include <components/sqlite3/db.hpp>
|
#include <components/sqlite3/db.hpp>
|
||||||
#include <components/sqlite3/statement.hpp>
|
#include <components/sqlite3/statement.hpp>
|
||||||
#include <components/sqlite3/transaction.hpp>
|
#include <components/sqlite3/transaction.hpp>
|
||||||
@ -15,7 +17,6 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@ -64,21 +65,21 @@ namespace DetourNavigator
|
|||||||
struct FindTile
|
struct FindTile
|
||||||
{
|
{
|
||||||
static std::string_view text() noexcept;
|
static std::string_view text() noexcept;
|
||||||
static void bind(sqlite3& db, sqlite3_stmt& statement, const std::string& worldspace,
|
static void bind(sqlite3& db, sqlite3_stmt& statement, std::string_view worldspace,
|
||||||
const TilePosition& tilePosition, const std::vector<std::byte>& input);
|
const TilePosition& tilePosition, const std::vector<std::byte>& input);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GetTileData
|
struct GetTileData
|
||||||
{
|
{
|
||||||
static std::string_view text() noexcept;
|
static std::string_view text() noexcept;
|
||||||
static void bind(sqlite3& db, sqlite3_stmt& statement, const std::string& worldspace,
|
static void bind(sqlite3& db, sqlite3_stmt& statement, std::string_view worldspace,
|
||||||
const TilePosition& tilePosition, const std::vector<std::byte>& input);
|
const TilePosition& tilePosition, const std::vector<std::byte>& input);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InsertTile
|
struct InsertTile
|
||||||
{
|
{
|
||||||
static std::string_view text() noexcept;
|
static std::string_view text() noexcept;
|
||||||
static void bind(sqlite3& db, sqlite3_stmt& statement, TileId tileId, const std::string& worldspace,
|
static void bind(sqlite3& db, sqlite3_stmt& statement, TileId tileId, std::string_view worldspace,
|
||||||
const TilePosition& tilePosition, TileVersion version, const std::vector<std::byte>& input,
|
const TilePosition& tilePosition, TileVersion version, const std::vector<std::byte>& input,
|
||||||
const std::vector<std::byte>& data);
|
const std::vector<std::byte>& data);
|
||||||
};
|
};
|
||||||
@ -90,6 +91,27 @@ namespace DetourNavigator
|
|||||||
const std::vector<std::byte>& data);
|
const std::vector<std::byte>& data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DeleteTilesAt
|
||||||
|
{
|
||||||
|
static std::string_view text() noexcept;
|
||||||
|
static void bind(sqlite3& db, sqlite3_stmt& statement, std::string_view worldspace,
|
||||||
|
const TilePosition& tilePosition);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DeleteTilesAtExcept
|
||||||
|
{
|
||||||
|
static std::string_view text() noexcept;
|
||||||
|
static void bind(sqlite3& db, sqlite3_stmt& statement, std::string_view worldspace,
|
||||||
|
const TilePosition& tilePosition, TileId excludeTileId);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DeleteTilesOutsideRange
|
||||||
|
{
|
||||||
|
static std::string_view text() noexcept;
|
||||||
|
static void bind(sqlite3& db, sqlite3_stmt& statement, std::string_view worldspace,
|
||||||
|
const TilesPositionsRange& range);
|
||||||
|
};
|
||||||
|
|
||||||
struct GetMaxShapeId
|
struct GetMaxShapeId
|
||||||
{
|
{
|
||||||
static std::string_view text() noexcept;
|
static std::string_view text() noexcept;
|
||||||
@ -99,16 +121,22 @@ namespace DetourNavigator
|
|||||||
struct FindShapeId
|
struct FindShapeId
|
||||||
{
|
{
|
||||||
static std::string_view text() noexcept;
|
static std::string_view text() noexcept;
|
||||||
static void bind(sqlite3& db, sqlite3_stmt& statement, const std::string& name,
|
static void bind(sqlite3& db, sqlite3_stmt& statement, std::string_view name,
|
||||||
ShapeType type, const Sqlite3::ConstBlob& hash);
|
ShapeType type, const Sqlite3::ConstBlob& hash);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InsertShape
|
struct InsertShape
|
||||||
{
|
{
|
||||||
static std::string_view text() noexcept;
|
static std::string_view text() noexcept;
|
||||||
static void bind(sqlite3& db, sqlite3_stmt& statement, ShapeId shapeId, const std::string& name,
|
static void bind(sqlite3& db, sqlite3_stmt& statement, ShapeId shapeId, std::string_view name,
|
||||||
ShapeType type, const Sqlite3::ConstBlob& hash);
|
ShapeType type, const Sqlite3::ConstBlob& hash);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Vacuum
|
||||||
|
{
|
||||||
|
static std::string_view text() noexcept;
|
||||||
|
static void bind(sqlite3&, sqlite3_stmt&) {}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class NavMeshDb
|
class NavMeshDb
|
||||||
@ -120,22 +148,30 @@ namespace DetourNavigator
|
|||||||
|
|
||||||
TileId getMaxTileId();
|
TileId getMaxTileId();
|
||||||
|
|
||||||
std::optional<Tile> findTile(const std::string& worldspace,
|
std::optional<Tile> findTile(std::string_view worldspace,
|
||||||
const TilePosition& tilePosition, const std::vector<std::byte>& input);
|
const TilePosition& tilePosition, const std::vector<std::byte>& input);
|
||||||
|
|
||||||
std::optional<TileData> getTileData(const std::string& worldspace,
|
std::optional<TileData> getTileData(std::string_view worldspace,
|
||||||
const TilePosition& tilePosition, const std::vector<std::byte>& input);
|
const TilePosition& tilePosition, const std::vector<std::byte>& input);
|
||||||
|
|
||||||
int insertTile(TileId tileId, const std::string& worldspace, const TilePosition& tilePosition,
|
int insertTile(TileId tileId, std::string_view worldspace, const TilePosition& tilePosition,
|
||||||
TileVersion version, const std::vector<std::byte>& input, const std::vector<std::byte>& data);
|
TileVersion version, const std::vector<std::byte>& input, const std::vector<std::byte>& data);
|
||||||
|
|
||||||
int updateTile(TileId tileId, TileVersion version, const std::vector<std::byte>& data);
|
int updateTile(TileId tileId, TileVersion version, const std::vector<std::byte>& data);
|
||||||
|
|
||||||
|
int deleteTilesAt(std::string_view worldspace, const TilePosition& tilePosition);
|
||||||
|
|
||||||
|
int deleteTilesAtExcept(std::string_view worldspace, const TilePosition& tilePosition, TileId excludeTileId);
|
||||||
|
|
||||||
|
int deleteTilesOutsideRange(std::string_view worldspace, const TilesPositionsRange& range);
|
||||||
|
|
||||||
ShapeId getMaxShapeId();
|
ShapeId getMaxShapeId();
|
||||||
|
|
||||||
std::optional<ShapeId> findShapeId(const std::string& name, ShapeType type, const Sqlite3::ConstBlob& hash);
|
std::optional<ShapeId> findShapeId(std::string_view name, ShapeType type, const Sqlite3::ConstBlob& hash);
|
||||||
|
|
||||||
int insertShape(ShapeId shapeId, const std::string& name, ShapeType type, const Sqlite3::ConstBlob& hash);
|
int insertShape(ShapeId shapeId, std::string_view name, ShapeType type, const Sqlite3::ConstBlob& hash);
|
||||||
|
|
||||||
|
void vacuum();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Sqlite3::Db mDb;
|
Sqlite3::Db mDb;
|
||||||
@ -144,9 +180,13 @@ namespace DetourNavigator
|
|||||||
Sqlite3::Statement<DbQueries::GetTileData> mGetTileData;
|
Sqlite3::Statement<DbQueries::GetTileData> mGetTileData;
|
||||||
Sqlite3::Statement<DbQueries::InsertTile> mInsertTile;
|
Sqlite3::Statement<DbQueries::InsertTile> mInsertTile;
|
||||||
Sqlite3::Statement<DbQueries::UpdateTile> mUpdateTile;
|
Sqlite3::Statement<DbQueries::UpdateTile> mUpdateTile;
|
||||||
|
Sqlite3::Statement<DbQueries::DeleteTilesAt> mDeleteTilesAt;
|
||||||
|
Sqlite3::Statement<DbQueries::DeleteTilesAtExcept> mDeleteTilesAtExcept;
|
||||||
|
Sqlite3::Statement<DbQueries::DeleteTilesOutsideRange> mDeleteTilesOutsideRange;
|
||||||
Sqlite3::Statement<DbQueries::GetMaxShapeId> mGetMaxShapeId;
|
Sqlite3::Statement<DbQueries::GetMaxShapeId> mGetMaxShapeId;
|
||||||
Sqlite3::Statement<DbQueries::FindShapeId> mFindShapeId;
|
Sqlite3::Statement<DbQueries::FindShapeId> mFindShapeId;
|
||||||
Sqlite3::Statement<DbQueries::InsertShape> mInsertShape;
|
Sqlite3::Statement<DbQueries::InsertShape> mInsertShape;
|
||||||
|
Sqlite3::Statement<DbQueries::Vacuum> mVacuum;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,19 +6,20 @@
|
|||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
namespace DetourNavigator
|
namespace DetourNavigator
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
std::optional<ShapeId> findShapeId(NavMeshDb& db, const std::string& name, ShapeType type,
|
std::optional<ShapeId> findShapeId(NavMeshDb& db, std::string_view name, ShapeType type,
|
||||||
const std::string& hash)
|
const std::string& hash)
|
||||||
{
|
{
|
||||||
const Sqlite3::ConstBlob hashData {hash.data(), static_cast<int>(hash.size())};
|
const Sqlite3::ConstBlob hashData {hash.data(), static_cast<int>(hash.size())};
|
||||||
return db.findShapeId(name, type, hashData);
|
return db.findShapeId(name, type, hashData);
|
||||||
}
|
}
|
||||||
|
|
||||||
ShapeId getShapeId(NavMeshDb& db, const std::string& name, ShapeType type,
|
ShapeId getShapeId(NavMeshDb& db, std::string_view name, ShapeType type,
|
||||||
const std::string& hash, ShapeId& nextShapeId)
|
const std::string& hash, ShapeId& nextShapeId)
|
||||||
{
|
{
|
||||||
const Sqlite3::ConstBlob hashData {hash.data(), static_cast<int>(hash.size())};
|
const Sqlite3::ConstBlob hashData {hash.data(), static_cast<int>(hash.size())};
|
||||||
|
15
components/detournavigator/tilespositionsrange.hpp
Normal file
15
components/detournavigator/tilespositionsrange.hpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_TILESPOSITIONSRANGE_H
|
||||||
|
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_TILESPOSITIONSRANGE_H
|
||||||
|
|
||||||
|
#include "tileposition.hpp"
|
||||||
|
|
||||||
|
namespace DetourNavigator
|
||||||
|
{
|
||||||
|
struct TilesPositionsRange
|
||||||
|
{
|
||||||
|
TilePosition mBegin;
|
||||||
|
TilePosition mEnd;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -7,6 +7,7 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
namespace Serialization
|
namespace Serialization
|
||||||
{
|
{
|
||||||
@ -26,7 +27,7 @@ namespace Serialization
|
|||||||
struct IsContiguousContainer<std::array<T, n>> : std::true_type {};
|
struct IsContiguousContainer<std::array<T, n>> : std::true_type {};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
constexpr bool isContiguousContainer = IsContiguousContainer<std::decay_t<T>>::value;
|
inline constexpr bool isContiguousContainer = IsContiguousContainer<std::decay_t<T>>::value;
|
||||||
|
|
||||||
template <Mode mode, class Derived>
|
template <Mode mode, class Derived>
|
||||||
struct Format
|
struct Format
|
||||||
@ -51,13 +52,13 @@ namespace Serialization
|
|||||||
-> std::enable_if_t<isContiguousContainer<T>>
|
-> std::enable_if_t<isContiguousContainer<T>>
|
||||||
{
|
{
|
||||||
if constexpr (mode == Mode::Write)
|
if constexpr (mode == Mode::Write)
|
||||||
visitor(self(), value.size());
|
visitor(self(), static_cast<std::uint64_t>(value.size()));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
static_assert(mode == Mode::Read);
|
static_assert(mode == Mode::Read);
|
||||||
std::size_t size = 0;
|
std::uint64_t size = 0;
|
||||||
visitor(self(), size);
|
visitor(self(), size);
|
||||||
value.resize(size);
|
value.resize(static_cast<std::size_t>(size));
|
||||||
}
|
}
|
||||||
self()(std::forward<Visitor>(visitor), value.data(), value.size());
|
self()(std::forward<Visitor>(visitor), value.data(), value.size());
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user