mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-15 13:19:56 +00:00
c68cecb1eb
Optimize off mesh connections See merge request OpenMW/openmw!969 (cherry picked from commit 9dcea247d2cd7d25d719fabc142cef5360233e2a) 3e98db8d Fix styleguide 7f65a2c4 Remove unused code 81e569c3 Move OffMeshConnectionsManager implementation into cpp a8ba9a0e Cleanup unused tile positions from OffMeshConnectionsManager ff1af5e8 Use only off mesh connections starting or ending in a given tile 1552e7e3 Add pathgrid edges as one direction off mesh connection
95 lines
3 KiB
C++
95 lines
3 KiB
C++
#include "offmeshconnectionsmanager.hpp"
|
|
#include "settings.hpp"
|
|
#include "settingsutils.hpp"
|
|
#include "tileposition.hpp"
|
|
#include "objectid.hpp"
|
|
#include "offmeshconnection.hpp"
|
|
|
|
#include <algorithm>
|
|
#include <vector>
|
|
#include <set>
|
|
|
|
namespace DetourNavigator
|
|
{
|
|
OffMeshConnectionsManager::OffMeshConnectionsManager(const Settings& settings)
|
|
: mSettings(settings)
|
|
{}
|
|
|
|
void OffMeshConnectionsManager::add(const ObjectId id, const OffMeshConnection& value)
|
|
{
|
|
const auto values = mValues.lock();
|
|
|
|
values->mById.insert(std::make_pair(id, value));
|
|
|
|
const auto startTilePosition = getTilePosition(mSettings, value.mStart);
|
|
const auto endTilePosition = getTilePosition(mSettings, value.mEnd);
|
|
|
|
values->mByTilePosition[startTilePosition].insert(id);
|
|
|
|
if (startTilePosition != endTilePosition)
|
|
values->mByTilePosition[endTilePosition].insert(id);
|
|
}
|
|
|
|
std::set<TilePosition> OffMeshConnectionsManager::remove(const ObjectId id)
|
|
{
|
|
const auto values = mValues.lock();
|
|
|
|
const auto byId = values->mById.equal_range(id);
|
|
|
|
if (byId.first == byId.second)
|
|
return {};
|
|
|
|
std::set<TilePosition> removed;
|
|
|
|
std::for_each(byId.first, byId.second, [&] (const auto& v) {
|
|
const auto startTilePosition = getTilePosition(mSettings, v.second.mStart);
|
|
const auto endTilePosition = getTilePosition(mSettings, v.second.mEnd);
|
|
|
|
removed.emplace(startTilePosition);
|
|
if (startTilePosition != endTilePosition)
|
|
removed.emplace(endTilePosition);
|
|
});
|
|
|
|
for (const TilePosition& tilePosition : removed)
|
|
{
|
|
const auto it = values->mByTilePosition.find(tilePosition);
|
|
if (it == values->mByTilePosition.end())
|
|
continue;
|
|
it->second.erase(id);
|
|
if (it->second.empty())
|
|
values->mByTilePosition.erase(it);
|
|
}
|
|
|
|
values->mById.erase(byId.first, byId.second);
|
|
|
|
return removed;
|
|
}
|
|
|
|
std::vector<OffMeshConnection> OffMeshConnectionsManager::get(const TilePosition& tilePosition)
|
|
{
|
|
std::vector<OffMeshConnection> result;
|
|
|
|
const auto values = mValues.lock();
|
|
|
|
const auto itByTilePosition = values->mByTilePosition.find(tilePosition);
|
|
|
|
if (itByTilePosition == values->mByTilePosition.end())
|
|
return result;
|
|
|
|
std::for_each(itByTilePosition->second.begin(), itByTilePosition->second.end(),
|
|
[&] (const ObjectId v)
|
|
{
|
|
const auto byId = values->mById.equal_range(v);
|
|
std::for_each(byId.first, byId.second, [&] (const auto& v)
|
|
{
|
|
if (getTilePosition(mSettings, v.second.mStart) == tilePosition
|
|
|| getTilePosition(mSettings, v.second.mEnd) == tilePosition)
|
|
result.push_back(v.second);
|
|
});
|
|
});
|
|
|
|
std::sort(result.begin(), result.end());
|
|
|
|
return result;
|
|
}
|
|
}
|