mirror of
https://github.com/TES3MP/TES3MP.git
synced 2025-09-28 15:41:13 -04:00
Pathfinding Overhaul - Even more cleanup and spacing corrections, small renaming (more to come), removed a few unnecessary actions that wasted CPU time and tmp RAM.
This commit is contained in:
parent
96fdaf7410
commit
7b465ae4f1
@ -10,7 +10,25 @@
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
// helpers functions
|
struct found_path {};
|
||||||
|
|
||||||
|
typedef boost::adjacency_list< boost::vecS, boost::vecS, boost::undirectedS,
|
||||||
|
boost::property<boost::vertex_index_t, int, ESM::Pathgrid::Point>, boost::property<boost::edge_weight_t, float> >
|
||||||
|
PathGridGraph;
|
||||||
|
typedef boost::property_map<PathGridGraph, boost::edge_weight_t>::type WeightMap;
|
||||||
|
typedef PathGridGraph::vertex_descriptor PointID;
|
||||||
|
typedef PathGridGraph::edge_descriptor PointConnectionID;
|
||||||
|
|
||||||
|
class goalVisited : public boost::default_dijkstra_visitor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
goalVisited(PointID goal) {mGoal = goal;};
|
||||||
|
void examine_vertex(PointID u, const PathGridGraph g) {if(u == mGoal) throw found_path();};
|
||||||
|
|
||||||
|
private:
|
||||||
|
PointID mGoal;
|
||||||
|
};
|
||||||
|
|
||||||
float distanceZCorrected(ESM::Pathgrid::Point point, float x, float y, float z)
|
float distanceZCorrected(ESM::Pathgrid::Point point, float x, float y, float z)
|
||||||
{
|
{
|
||||||
return sqrt((point.mX - x) * (point.mX - x) + (point.mY - y) * (point.mY - y) + 0.1 * (point.mZ - z) * (point.mZ - z));
|
return sqrt((point.mX - x) * (point.mX - x) + (point.mY - y) * (point.mY - y) + 0.1 * (point.mZ - z) * (point.mZ - z));
|
||||||
@ -30,89 +48,29 @@ namespace
|
|||||||
{
|
{
|
||||||
if(a > 0)
|
if(a > 0)
|
||||||
return 1.0;
|
return 1.0;
|
||||||
else
|
|
||||||
return -1.0;
|
return -1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getClosestPoint(const ESM::Pathgrid* grid, float x, float y, float z)
|
int getClosestPoint(const ESM::Pathgrid* grid, float x, float y, float z)
|
||||||
{
|
{
|
||||||
if(!grid)
|
if(!grid || grid->mPoints.empty())
|
||||||
return -1;
|
|
||||||
if(grid->mPoints.empty())
|
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
float m = distance(grid->mPoints[0],x,y,z);
|
float distanceBetween = distance(grid->mPoints[0], x, y, z);
|
||||||
int i0 = 0;
|
int closestIndex = 0;
|
||||||
|
|
||||||
for(unsigned int i = 1; i < grid->mPoints.size(); ++i)
|
for(unsigned int counter = 1; counter < grid->mPoints.size(); counter++)
|
||||||
{
|
{
|
||||||
if(distance(grid->mPoints[i],x,y,z) < m)
|
if(distance(grid->mPoints[counter], x, y, z) < distanceBetween)
|
||||||
{
|
{
|
||||||
m = distance(grid->mPoints[i],x,y,z);
|
distanceBetween = distance(grid->mPoints[counter], x, y, z);
|
||||||
i0 = i;
|
closestIndex = counter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return i0;
|
|
||||||
|
return closestIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef boost::adjacency_list<boost::vecS,boost::vecS,boost::undirectedS,
|
|
||||||
boost::property<boost::vertex_index_t,int,ESM::Pathgrid::Point>,boost::property<boost::edge_weight_t,float> > PathGridGraph;
|
|
||||||
typedef boost::property_map<PathGridGraph, boost::edge_weight_t>::type WeightMap;
|
|
||||||
typedef PathGridGraph::vertex_descriptor PointID;
|
|
||||||
typedef PathGridGraph::edge_descriptor PointConnectionID;
|
|
||||||
|
|
||||||
struct found_path {};
|
|
||||||
|
|
||||||
/*class goalVisited : public boost::default_astar_visitor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
goalVisited(PointID goal) : mGoal(goal) {}
|
|
||||||
|
|
||||||
void examine_vertex(PointID u, const PathGridGraph g)
|
|
||||||
{
|
|
||||||
if(u == mGoal)
|
|
||||||
throw found_path();
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
PointID mGoal;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DistanceHeuristic : public boost::atasr_heuristic <PathGridGraph, float>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DistanceHeuristic(const PathGridGraph & l, PointID goal)
|
|
||||||
: mGraph(l), mGoal(goal) {}
|
|
||||||
|
|
||||||
float operator()(PointID u)
|
|
||||||
{
|
|
||||||
const ESM::Pathgrid::Point & U = mGraph[u];
|
|
||||||
const ESM::Pathgrid::Point & V = mGraph[mGoal];
|
|
||||||
float dx = U.mX - V.mX;
|
|
||||||
float dy = U.mY - V.mY;
|
|
||||||
float dz = U.mZ - V.mZ;
|
|
||||||
return sqrt(dx * dx + dy * dy + dz * dz);
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
const PathGridGraph & mGraph;
|
|
||||||
PointID mGoal;
|
|
||||||
};*/
|
|
||||||
|
|
||||||
class goalVisited : public boost::default_dijkstra_visitor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
goalVisited(PointID goal) : mGoal(goal) {}
|
|
||||||
|
|
||||||
void examine_vertex(PointID u, const PathGridGraph g)
|
|
||||||
{
|
|
||||||
if(u == mGoal)
|
|
||||||
throw found_path();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
PointID mGoal;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
PathGridGraph buildGraph(const ESM::Pathgrid* pathgrid, float xCell = 0, float yCell = 0)
|
PathGridGraph buildGraph(const ESM::Pathgrid* pathgrid, float xCell = 0, float yCell = 0)
|
||||||
{
|
{
|
||||||
PathGridGraph graph;
|
PathGridGraph graph;
|
||||||
@ -140,31 +98,30 @@ PointID mGoal;
|
|||||||
return graph;
|
return graph;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::list<ESM::Pathgrid::Point> findPath(PointID start,PointID end,PathGridGraph graph){
|
std::list<ESM::Pathgrid::Point> findPath(PointID start, PointID end, PathGridGraph graph)
|
||||||
|
{
|
||||||
std::vector<PointID> p(boost::num_vertices(graph));
|
std::vector<PointID> p(boost::num_vertices(graph));
|
||||||
std::vector<float> d(boost::num_vertices(graph));
|
std::vector<float> d(boost::num_vertices(graph));
|
||||||
std::list<ESM::Pathgrid::Point> shortest_path;
|
std::list<ESM::Pathgrid::Point> shortest_path;
|
||||||
|
|
||||||
try {
|
try
|
||||||
boost::dijkstra_shortest_paths
|
{
|
||||||
(
|
boost::dijkstra_shortest_paths(graph, start,
|
||||||
graph,
|
boost::predecessor_map(&p[0]).distance_map(&d[0]).visitor(goalVisited(end)));
|
||||||
start,
|
}
|
||||||
boost::predecessor_map(&p[0]).distance_map(&d[0]).visitor(goalVisited(end))//.weight_map(boost::get(&Edge::distance, graph))
|
|
||||||
);
|
|
||||||
|
|
||||||
} catch(found_path fg) {
|
catch(found_path fg)
|
||||||
for(PointID v = end; ; v = p[v]) {
|
{
|
||||||
|
for(PointID v = end; ; v = p[v])
|
||||||
|
{
|
||||||
shortest_path.push_front(graph[v]);
|
shortest_path.push_front(graph[v]);
|
||||||
if(p[v] == v)
|
if(p[v] == v)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return shortest_path;
|
return shortest_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
//end of helpers functions
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
@ -197,6 +154,7 @@ namespace MWMechanics
|
|||||||
mPath = findPath(start, end, graph);
|
mPath = findPath(start, end, graph);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mPath.push_back(endPoint);
|
mPath.push_back(endPoint);
|
||||||
mIsPathConstructed = true;
|
mIsPathConstructed = true;
|
||||||
}
|
}
|
||||||
@ -204,12 +162,13 @@ namespace MWMechanics
|
|||||||
float PathFinder::getZAngleToNext(float x, float y, float z)
|
float PathFinder::getZAngleToNext(float x, float y, float z)
|
||||||
{
|
{
|
||||||
if(mPath.empty())
|
if(mPath.empty())
|
||||||
return 0; /// shouldn't happen!
|
return 0; // shouldn't happen!
|
||||||
|
|
||||||
ESM::Pathgrid::Point nextPoint = *mPath.begin();
|
ESM::Pathgrid::Point nextPoint = *mPath.begin();
|
||||||
float dX = nextPoint.mX - x;
|
float dX = nextPoint.mX - x;
|
||||||
float dY = nextPoint.mY - y;
|
float dY = nextPoint.mY - y;
|
||||||
float h = sqrt(dX * dX + dY * dY);
|
float h = sqrt(dX * dX + dY * dY);
|
||||||
|
|
||||||
return Ogre::Radian(acos(dY / h) * sgn(asin(dX / h))).valueDegrees();
|
return Ogre::Radian(acos(dY / h) * sgn(asin(dX / h))).valueDegrees();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,12 +181,10 @@ namespace MWMechanics
|
|||||||
if(distanceZCorrected(nextPoint, x, y, z) < 20)
|
if(distanceZCorrected(nextPoint, x, y, z) < 20)
|
||||||
{
|
{
|
||||||
mPath.pop_front();
|
mPath.pop_front();
|
||||||
|
|
||||||
if(mPath.empty())
|
if(mPath.empty())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
nextPoint = *mPath.begin();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,8 @@ namespace MWMechanics
|
|||||||
void buildPath(ESM::Pathgrid::Point startPoint,ESM::Pathgrid::Point endPoint,
|
void buildPath(ESM::Pathgrid::Point startPoint,ESM::Pathgrid::Point endPoint,
|
||||||
const ESM::Pathgrid* pathGrid,float xCell = 0,float yCell = 0);
|
const ESM::Pathgrid* pathGrid,float xCell = 0,float yCell = 0);
|
||||||
|
|
||||||
bool checkIfNextPointReached(float x,float y,float z);//returns true if the last point of the path has been reached.
|
bool checkIfNextPointReached(float x,float y,float z);
|
||||||
|
///< \Returns true if the last point of the path has been reached.
|
||||||
float getZAngleToNext(float x,float y,float z);
|
float getZAngleToNext(float x,float y,float z);
|
||||||
|
|
||||||
std::list<ESM::Pathgrid::Point> getPath();
|
std::list<ESM::Pathgrid::Point> getPath();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user