mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-04-28 21:07:59 +03:00
Merge branch 'optimize_off_mesh_connections' into 'master'
Optimize off mesh connections See merge request OpenMW/openmw!969 (cherry picked from commit9dcea247d2
)3e98db8d
Fix styleguide7f65a2c4
Remove unused code81e569c3
Move OffMeshConnectionsManager implementation into cppa8ba9a0e
Cleanup unused tile positions from OffMeshConnectionsManagerff1af5e8
Use only off mesh connections starting or ending in a given tile1552e7e3
Add pathgrid edges as one direction off mesh connection
This commit is contained in:
parent
0394f848cd
commit
c68cecb1eb
5 changed files with 105 additions and 83 deletions
|
@ -183,6 +183,7 @@ add_component_dir(detournavigator
|
|||
raycast
|
||||
navmeshtileview
|
||||
oscillatingrecastmeshobject
|
||||
offmeshconnectionsmanager
|
||||
)
|
||||
|
||||
set (ESM_UI ${CMAKE_SOURCE_DIR}/files/ui/contentselector.ui
|
||||
|
|
|
@ -389,7 +389,7 @@ namespace
|
|||
|
||||
const auto offMeshConVerts = getOffMeshVerts(offMeshConnections);
|
||||
const std::vector<float> offMeshConRad(offMeshConnections.size(), getRadius(settings, agentHalfExtents));
|
||||
const std::vector<unsigned char> offMeshConDir(offMeshConnections.size(), DT_OFFMESH_CON_BIDIR);
|
||||
const std::vector<unsigned char> offMeshConDir(offMeshConnections.size(), 0);
|
||||
const std::vector<unsigned char> offMeshConAreas = getOffMeshConAreas(offMeshConnections);
|
||||
const std::vector<unsigned short> offMeshConFlags = getOffMeshFlags(offMeshConnections);
|
||||
|
||||
|
|
|
@ -55,12 +55,10 @@ namespace DetourNavigator
|
|||
{
|
||||
if (addObject(id, static_cast<const ObjectShapes&>(shapes), transform))
|
||||
{
|
||||
mNavMeshManager.addOffMeshConnection(
|
||||
id,
|
||||
toNavMeshCoordinates(mSettings, shapes.mConnectionStart),
|
||||
toNavMeshCoordinates(mSettings, shapes.mConnectionEnd),
|
||||
AreaType_door
|
||||
);
|
||||
const osg::Vec3f start = toNavMeshCoordinates(mSettings, shapes.mConnectionStart);
|
||||
const osg::Vec3f end = toNavMeshCoordinates(mSettings, shapes.mConnectionEnd);
|
||||
mNavMeshManager.addOffMeshConnection(id, start, end, AreaType_door);
|
||||
mNavMeshManager.addOffMeshConnection(id, end, start, AreaType_door);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
95
components/detournavigator/offmeshconnectionsmanager.cpp
Normal file
95
components/detournavigator/offmeshconnectionsmanager.cpp
Normal file
|
@ -0,0 +1,95 @@
|
|||
#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;
|
||||
}
|
||||
}
|
|
@ -2,16 +2,12 @@
|
|||
#define OPENMW_COMPONENTS_DETOURNAVIGATOR_OFFMESHCONNECTIONSMANAGER_H
|
||||
|
||||
#include "settings.hpp"
|
||||
#include "settingsutils.hpp"
|
||||
#include "tileposition.hpp"
|
||||
#include "objectid.hpp"
|
||||
#include "offmeshconnection.hpp"
|
||||
|
||||
#include <components/misc/guarded.hpp>
|
||||
|
||||
#include <osg/Vec3f>
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
@ -22,73 +18,13 @@ namespace DetourNavigator
|
|||
class OffMeshConnectionsManager
|
||||
{
|
||||
public:
|
||||
OffMeshConnectionsManager(const Settings& settings)
|
||||
: mSettings(settings)
|
||||
{}
|
||||
OffMeshConnectionsManager(const Settings& settings);
|
||||
|
||||
void add(const ObjectId id, const OffMeshConnection& value)
|
||||
{
|
||||
const auto values = mValues.lock();
|
||||
void add(const ObjectId id, const OffMeshConnection& value);
|
||||
|
||||
values->mById.insert(std::make_pair(id, value));
|
||||
std::set<TilePosition> remove(const ObjectId id);
|
||||
|
||||
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> 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);
|
||||
});
|
||||
|
||||
values->mById.erase(byId.first, byId.second);
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
std::vector<OffMeshConnection> 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) { result.push_back(v.second); });
|
||||
});
|
||||
|
||||
std::sort(result.begin(), result.end());
|
||||
|
||||
return result;
|
||||
}
|
||||
std::vector<OffMeshConnection> get(const TilePosition& tilePosition);
|
||||
|
||||
private:
|
||||
struct Values
|
||||
|
@ -99,14 +35,6 @@ namespace DetourNavigator
|
|||
|
||||
const Settings& mSettings;
|
||||
Misc::ScopeGuarded<Values> mValues;
|
||||
|
||||
void removeByTilePosition(std::map<TilePosition, std::unordered_set<ObjectId>>& valuesByTilePosition,
|
||||
const TilePosition& tilePosition, const ObjectId id)
|
||||
{
|
||||
const auto it = valuesByTilePosition.find(tilePosition);
|
||||
if (it != valuesByTilePosition.end())
|
||||
it->second.erase(id);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue