Split RecastMesh into tiles
parent
dbb1d99bff
commit
d2fd9abd51
@ -0,0 +1,71 @@
|
||||
#include "tilecachedrecastmeshmanager.hpp"
|
||||
#include "makenavmesh.hpp"
|
||||
#include "gettilespositions.hpp"
|
||||
#include "settingsutils.hpp"
|
||||
|
||||
namespace DetourNavigator
|
||||
{
|
||||
TileCachedRecastMeshManager::TileCachedRecastMeshManager(const Settings& settings)
|
||||
: mSettings(settings)
|
||||
{
|
||||
}
|
||||
|
||||
bool TileCachedRecastMeshManager::addObject(std::size_t id, const btCollisionShape& shape,
|
||||
const btTransform& transform)
|
||||
{
|
||||
bool result = false;
|
||||
auto& tilesPositions = mObjectsTilesPositions[id];
|
||||
const auto border = getBorderSize(mSettings);
|
||||
getTilesPositions(shape, transform, mSettings, [&] (const TilePosition& tilePosition)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mTilesMutex);
|
||||
auto tile = mTiles.find(tilePosition);
|
||||
if (tile == mTiles.end())
|
||||
{
|
||||
auto tileBounds = makeTileBounds(mSettings, tilePosition);
|
||||
tileBounds.mMin -= osg::Vec2f(border, border);
|
||||
tileBounds.mMax += osg::Vec2f(border, border);
|
||||
tile = mTiles.insert(std::make_pair(tilePosition,
|
||||
CachedRecastMeshManager(mSettings, tileBounds))).first;
|
||||
}
|
||||
if (tile->second.addObject(id, shape, transform))
|
||||
{
|
||||
lock.unlock();
|
||||
tilesPositions.push_back(tilePosition);
|
||||
result = true;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
boost::optional<RecastMeshManager::Object> TileCachedRecastMeshManager::removeObject(std::size_t id)
|
||||
{
|
||||
const auto object = mObjectsTilesPositions.find(id);
|
||||
if (object == mObjectsTilesPositions.end())
|
||||
return boost::none;
|
||||
boost::optional<RecastMeshManager::Object> result;
|
||||
for (const auto& tilePosition : object->second)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mTilesMutex);
|
||||
const auto tile = mTiles.find(tilePosition);
|
||||
if (tile == mTiles.end())
|
||||
continue;
|
||||
const auto tileResult = tile->second.removeObject(id);
|
||||
if (tile->second.isEmpty())
|
||||
mTiles.erase(tile);
|
||||
lock.unlock();
|
||||
if (tileResult && !result)
|
||||
result = tileResult;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::shared_ptr<RecastMesh> TileCachedRecastMeshManager::getMesh(const TilePosition& tilePosition)
|
||||
{
|
||||
const std::lock_guard<std::mutex> lock(mTilesMutex);
|
||||
const auto it = mTiles.find(tilePosition);
|
||||
if (it == mTiles.end())
|
||||
return nullptr;
|
||||
return it->second.getMesh();
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
#ifndef OPENMW_COMPONENTS_DETOURNAVIGATOR_TILECACHEDRECASTMESHMANAGER_H
|
||||
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_TILECACHEDRECASTMESHMANAGER_H
|
||||
|
||||
#include "cachedrecastmeshmanager.hpp"
|
||||
#include "tileposition.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
|
||||
namespace DetourNavigator
|
||||
{
|
||||
class TileCachedRecastMeshManager
|
||||
{
|
||||
public:
|
||||
TileCachedRecastMeshManager(const Settings& settings);
|
||||
|
||||
bool addObject(std::size_t id, const btCollisionShape& shape, const btTransform& transform);
|
||||
|
||||
boost::optional<RecastMeshManager::Object> removeObject(std::size_t id);
|
||||
|
||||
std::shared_ptr<RecastMesh> getMesh(const TilePosition& tilePosition);
|
||||
|
||||
private:
|
||||
const Settings& mSettings;
|
||||
std::mutex mTilesMutex;
|
||||
std::map<TilePosition, CachedRecastMeshManager> mTiles;
|
||||
std::unordered_map<std::size_t, std::vector<TilePosition>> mObjectsTilesPositions;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue