mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-05-02 06:47:59 +03:00
Merge branch 'restrict_navmesh_cache_writes' into 'master'
Do not write shapes to navmeshdb when writing is disabled (#6498) Closes #6498 See merge request OpenMW/openmw!1486
This commit is contained in:
commit
844266b58e
7 changed files with 133 additions and 17 deletions
|
@ -89,7 +89,8 @@ namespace DetourNavigator
|
|||
{
|
||||
if (db == nullptr)
|
||||
return nullptr;
|
||||
return std::make_unique<DbWorker>(updater, std::move(db), TileVersion(settings.mNavMeshVersion), settings.mRecast);
|
||||
return std::make_unique<DbWorker>(updater, std::move(db), TileVersion(settings.mNavMeshVersion),
|
||||
settings.mRecast, settings.mWriteToNavMeshDb);
|
||||
}
|
||||
|
||||
void updateJobs(std::deque<JobIt>& jobs, TilePosition playerTile, int maxTiles)
|
||||
|
@ -704,11 +705,12 @@ namespace DetourNavigator
|
|||
}
|
||||
|
||||
DbWorker::DbWorker(AsyncNavMeshUpdater& updater, std::unique_ptr<NavMeshDb>&& db,
|
||||
TileVersion version, const RecastSettings& recastSettings)
|
||||
TileVersion version, const RecastSettings& recastSettings, bool writeToDb)
|
||||
: mUpdater(updater)
|
||||
, mRecastSettings(recastSettings)
|
||||
, mDb(std::move(db))
|
||||
, mVersion(version)
|
||||
, mWriteToDb(writeToDb)
|
||||
, mNextTileId(mDb->getMaxTileId() + 1)
|
||||
, mNextShapeId(mDb->getMaxShapeId() + 1)
|
||||
, mThread([this] { run(); })
|
||||
|
@ -799,12 +801,23 @@ namespace DetourNavigator
|
|||
if (job->mInput.empty())
|
||||
{
|
||||
Log(Debug::Debug) << "Serializing input for job " << job->mId;
|
||||
const ShapeId shapeId = mNextShapeId;
|
||||
const std::vector<DbRefGeometryObject> objects = makeDbRefGeometryObjects(job->mRecastMesh->getMeshSources(),
|
||||
[&] (const MeshSource& v) { return resolveMeshSource(*mDb, v, mNextShapeId); });
|
||||
if (shapeId != mNextShapeId)
|
||||
++mWrites;
|
||||
job->mInput = serialize(mRecastSettings, *job->mRecastMesh, objects);
|
||||
if (mWriteToDb)
|
||||
{
|
||||
const ShapeId shapeId = mNextShapeId;
|
||||
const auto objects = makeDbRefGeometryObjects(job->mRecastMesh->getMeshSources(),
|
||||
[&] (const MeshSource& v) { return resolveMeshSource(*mDb, v, mNextShapeId); });
|
||||
if (shapeId != mNextShapeId)
|
||||
++mWrites;
|
||||
job->mInput = serialize(mRecastSettings, *job->mRecastMesh, objects);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto objects = makeDbRefGeometryObjects(job->mRecastMesh->getMeshSources(),
|
||||
[&] (const MeshSource& v) { return resolveMeshSource(*mDb, v); });
|
||||
if (!objects.has_value())
|
||||
return;
|
||||
job->mInput = serialize(mRecastSettings, *job->mRecastMesh, *objects);
|
||||
}
|
||||
}
|
||||
|
||||
job->mCachedTileData = mDb->getTileData(job->mWorldspace, job->mChangedTile, job->mInput);
|
||||
|
|
|
@ -136,7 +136,7 @@ namespace DetourNavigator
|
|||
};
|
||||
|
||||
DbWorker(AsyncNavMeshUpdater& updater, std::unique_ptr<NavMeshDb>&& db,
|
||||
TileVersion version, const RecastSettings& recastSettings);
|
||||
TileVersion version, const RecastSettings& recastSettings, bool writeToDb);
|
||||
|
||||
~DbWorker();
|
||||
|
||||
|
@ -153,6 +153,7 @@ namespace DetourNavigator
|
|||
const RecastSettings& mRecastSettings;
|
||||
const std::unique_ptr<NavMeshDb> mDb;
|
||||
const TileVersion mVersion;
|
||||
const bool mWriteToDb;
|
||||
TileId mNextTileId;
|
||||
ShapeId mNextShapeId;
|
||||
DbJobQueue mQueue;
|
||||
|
|
|
@ -4,10 +4,14 @@
|
|||
#include "objecttransform.hpp"
|
||||
#include "recastmesh.hpp"
|
||||
|
||||
#include <components/misc/typetraits.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace DetourNavigator
|
||||
{
|
||||
|
@ -28,16 +32,27 @@ namespace DetourNavigator
|
|||
};
|
||||
|
||||
template <class ResolveMeshSource>
|
||||
inline std::vector<DbRefGeometryObject> makeDbRefGeometryObjects(const std::vector<MeshSource>& meshSources,
|
||||
ResolveMeshSource&& resolveMeshSource)
|
||||
inline auto makeDbRefGeometryObjects(const std::vector<MeshSource>& meshSources, ResolveMeshSource&& resolveMeshSource)
|
||||
-> std::conditional_t<
|
||||
Misc::isOptional<std::decay_t<decltype(resolveMeshSource(meshSources.front()))>>,
|
||||
std::optional<std::vector<DbRefGeometryObject>>,
|
||||
std::vector<DbRefGeometryObject>
|
||||
>
|
||||
{
|
||||
std::vector<DbRefGeometryObject> result;
|
||||
result.reserve(meshSources.size());
|
||||
std::transform(meshSources.begin(), meshSources.end(), std::back_inserter(result),
|
||||
[&] (const MeshSource& meshSource)
|
||||
for (const MeshSource& meshSource : meshSources)
|
||||
{
|
||||
const auto shapeId = resolveMeshSource(meshSource);
|
||||
if constexpr (Misc::isOptional<std::decay_t<decltype(shapeId)>>)
|
||||
{
|
||||
return DbRefGeometryObject {resolveMeshSource(meshSource), meshSource.mObjectTransform};
|
||||
});
|
||||
if (!shapeId.has_value())
|
||||
return std::nullopt;
|
||||
result.push_back(DbRefGeometryObject {*shapeId, meshSource.mObjectTransform});
|
||||
}
|
||||
else
|
||||
result.push_back(DbRefGeometryObject {shapeId, meshSource.mObjectTransform});
|
||||
}
|
||||
std::sort(result.begin(), result.end());
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -5,12 +5,21 @@
|
|||
#include <components/debug/debuglog.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <optional>
|
||||
|
||||
namespace DetourNavigator
|
||||
{
|
||||
namespace
|
||||
{
|
||||
ShapeId getShapeId(NavMeshDb& db, const std::string& name, ShapeType type, const std::string& hash, ShapeId& nextShapeId)
|
||||
std::optional<ShapeId> findShapeId(NavMeshDb& db, const std::string& name, ShapeType type,
|
||||
const std::string& hash)
|
||||
{
|
||||
const Sqlite3::ConstBlob hashData {hash.data(), static_cast<int>(hash.size())};
|
||||
return db.findShapeId(name, type, hashData);
|
||||
}
|
||||
|
||||
ShapeId getShapeId(NavMeshDb& db, const std::string& name, ShapeType type,
|
||||
const std::string& hash, ShapeId& nextShapeId)
|
||||
{
|
||||
const Sqlite3::ConstBlob hashData {hash.data(), static_cast<int>(hash.size())};
|
||||
if (const auto existingShapeId = db.findShapeId(name, type, hashData))
|
||||
|
@ -37,4 +46,18 @@ namespace DetourNavigator
|
|||
return ShapeId(0);
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<ShapeId> resolveMeshSource(NavMeshDb& db, const MeshSource& source)
|
||||
{
|
||||
switch (source.mAreaType)
|
||||
{
|
||||
case AreaType_null:
|
||||
return findShapeId(db, source.mShape->mFileName, ShapeType::Avoid, source.mShape->mFileHash);
|
||||
case AreaType_ground:
|
||||
return findShapeId(db, source.mShape->mFileName, ShapeType::Collision, source.mShape->mFileHash);
|
||||
default:
|
||||
Log(Debug::Warning) << "Trying to resolve recast mesh source with unsupported area type: " << source.mAreaType;
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,15 @@
|
|||
|
||||
#include "navmeshdb.hpp"
|
||||
|
||||
#include <optional>
|
||||
|
||||
namespace DetourNavigator
|
||||
{
|
||||
struct MeshSource;
|
||||
|
||||
ShapeId resolveMeshSource(NavMeshDb& db, const MeshSource& source, ShapeId& nextShapeId);
|
||||
|
||||
std::optional<ShapeId> resolveMeshSource(NavMeshDb& db, const MeshSource& source);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
19
components/misc/typetraits.hpp
Normal file
19
components/misc/typetraits.hpp
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef OPENMW_COMPONENTS_MISC_TYPETRAITS_H
|
||||
#define OPENMW_COMPONENTS_MISC_TYPETRAITS_H
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace Misc
|
||||
{
|
||||
template <class T>
|
||||
struct IsOptional : std::false_type {};
|
||||
|
||||
template <class T>
|
||||
struct IsOptional<std::optional<T>> : std::true_type {};
|
||||
|
||||
template <class T>
|
||||
inline constexpr bool isOptional = IsOptional<T>::value;
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue