mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-23 16:23:54 +00:00
refactoring
This commit is contained in:
parent
e150e22652
commit
63424ade56
5 changed files with 245 additions and 169 deletions
|
@ -65,7 +65,7 @@ add_openmw_dir (mwclass
|
||||||
add_openmw_dir (mwmechanics
|
add_openmw_dir (mwmechanics
|
||||||
mechanicsmanagerimp stat character creaturestats magiceffects movement actors activators
|
mechanicsmanagerimp stat character creaturestats magiceffects movement actors activators
|
||||||
drawstate spells activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow
|
drawstate spells activespells npcstats aipackage aisequence alchemy aiwander aitravel aifollow
|
||||||
aiescort aiactivate repair
|
aiescort aiactivate repair pathfinding
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwbase
|
add_openmw_dir (mwbase
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include "boost/tuple/tuple.hpp"
|
#include "boost/tuple/tuple.hpp"
|
||||||
|
|
||||||
MWMechanics::AiTravel::AiTravel(float x, float y, float z)
|
MWMechanics::AiTravel::AiTravel(float x, float y, float z)
|
||||||
: mX(x),mY(y),mZ(z),isPathConstructed(false)
|
: mX(x),mY(y),mZ(z),mPathFinder()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,146 +23,12 @@ MWMechanics::AiTravel * MWMechanics::AiTravel::clone() const
|
||||||
return new AiTravel(*this);
|
return new AiTravel(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
|
||||||
|
|
||||||
float distance(ESM::Pathgrid::Point point,float x,float y,float z)
|
|
||||||
{
|
|
||||||
return sqrt((point.mX - x)*(point.mX - x)+(point.mY - y)*(point.mY - y)+(point.mZ - z)*(point.mZ - z));
|
|
||||||
}
|
|
||||||
|
|
||||||
float distance(ESM::Pathgrid::Point a,ESM::Pathgrid::Point b)
|
|
||||||
{
|
|
||||||
return sqrt(float(a.mX - b.mX)*(a.mX - b.mX)+(a.mY - b.mY)*(a.mY - b.mY)+(a.mZ - b.mZ)*(a.mZ - b.mZ));
|
|
||||||
}
|
|
||||||
|
|
||||||
int getClosestPoint(const ESM::Pathgrid* grid,float x,float y,float z)
|
|
||||||
{
|
|
||||||
if(!grid) return -1;
|
|
||||||
if(grid->mPoints.empty()) return -1;
|
|
||||||
|
|
||||||
float m = distance(grid->mPoints[0],x,y,z);
|
|
||||||
int i0 = 0;
|
|
||||||
|
|
||||||
for(unsigned int i=1; i<grid->mPoints.size();++i)
|
|
||||||
{
|
|
||||||
if(distance(grid->mPoints[i],x,y,z)<m)
|
|
||||||
{
|
|
||||||
m = distance(grid->mPoints[i],x,y,z);
|
|
||||||
i0 = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return i0;
|
|
||||||
}
|
|
||||||
|
|
||||||
float sgn(float a)
|
float sgn(float a)
|
||||||
{
|
{
|
||||||
if(a>0) return 1.;
|
if(a>0) return 1.;
|
||||||
else return -1.;
|
else return -1.;
|
||||||
}
|
}
|
||||||
|
|
||||||
float getZAngle(float dX,float dY)
|
|
||||||
{
|
|
||||||
float h = sqrt(dX*dX+dY*dY);
|
|
||||||
return Ogre::Radian(acos(dY/h)*sgn(asin(dX/h))).valueDegrees();
|
|
||||||
}
|
|
||||||
|
|
||||||
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::astar_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;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::list<ESM::Pathgrid::Point> getPath(PointID start,PointID end,PathGridGraph graph){
|
|
||||||
std::vector<PointID> p(boost::num_vertices(graph));
|
|
||||||
std::vector<float> d(boost::num_vertices(graph));
|
|
||||||
std::list<ESM::Pathgrid::Point> shortest_path;
|
|
||||||
|
|
||||||
try {
|
|
||||||
boost::astar_search
|
|
||||||
(
|
|
||||||
graph,
|
|
||||||
start,
|
|
||||||
DistanceHeuristic(graph,end),
|
|
||||||
boost::predecessor_map(&p[0]).distance_map(&d[0]).visitor(goalVisited(end))//.weight_map(boost::get(&Edge::distance, graph))
|
|
||||||
);
|
|
||||||
|
|
||||||
} catch(found_path fg) {
|
|
||||||
for(PointID v = end;; v = p[v]) {
|
|
||||||
shortest_path.push_front(graph[v]);
|
|
||||||
if(p[v] == v)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return shortest_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
PathGridGraph buildGraph(const ESM::Pathgrid* pathgrid,float xCell = 0,float yCell = 0)
|
|
||||||
{
|
|
||||||
PathGridGraph graph;
|
|
||||||
|
|
||||||
for(unsigned int i = 0;i<pathgrid->mPoints.size();++i)
|
|
||||||
{
|
|
||||||
PointID pID = boost::add_vertex(graph);
|
|
||||||
graph[pID].mX = pathgrid->mPoints[i].mX + xCell;
|
|
||||||
graph[pID].mY = pathgrid->mPoints[i].mY + yCell;
|
|
||||||
graph[pID].mZ = pathgrid->mPoints[i].mZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(unsigned int i = 0;i<pathgrid->mEdges.size();++i)
|
|
||||||
{
|
|
||||||
PointID u = pathgrid->mEdges[i].mV0;
|
|
||||||
PointID v = pathgrid->mEdges[i].mV1;
|
|
||||||
|
|
||||||
PointConnectionID edge;
|
|
||||||
bool done;
|
|
||||||
boost::tie(edge,done) = boost::add_edge(u,v,graph);
|
|
||||||
WeightMap weightmap = boost::get(boost::edge_weight, graph);
|
|
||||||
weightmap[edge] = distance(graph[u],graph[v]);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return graph;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MWMechanics::AiTravel::execute (const MWWorld::Ptr& actor)
|
bool MWMechanics::AiTravel::execute (const MWWorld::Ptr& actor)
|
||||||
{
|
{
|
||||||
const ESM::Pathgrid *pathgrid =
|
const ESM::Pathgrid *pathgrid =
|
||||||
|
@ -193,7 +59,7 @@ bool MWMechanics::AiTravel::execute (const MWWorld::Ptr& actor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!isPathConstructed ||cellChange)
|
if(!mPathFinder.mIsPathConstructed ||cellChange)
|
||||||
{
|
{
|
||||||
cellX = actor.getCell()->mCell->mData.mX;
|
cellX = actor.getCell()->mCell->mData.mX;
|
||||||
cellY = actor.getCell()->mCell->mData.mY;
|
cellY = actor.getCell()->mCell->mData.mY;
|
||||||
|
@ -205,43 +71,26 @@ bool MWMechanics::AiTravel::execute (const MWWorld::Ptr& actor)
|
||||||
yCell = actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE;
|
yCell = actor.getCell()->mCell->mData.mY * ESM::Land::REAL_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int start = getClosestPoint(pathgrid,pos.pos[0] - xCell,pos.pos[1] - yCell,pos.pos[2]);
|
|
||||||
int end = getClosestPoint(pathgrid,mX - xCell,mY - yCell,mZ);
|
|
||||||
|
|
||||||
if(start != -1 && end != -1)
|
|
||||||
{
|
|
||||||
PathGridGraph graph = buildGraph(pathgrid,xCell,yCell);
|
|
||||||
mPath = getPath(start,end,graph);
|
|
||||||
}
|
|
||||||
|
|
||||||
ESM::Pathgrid::Point dest;
|
ESM::Pathgrid::Point dest;
|
||||||
dest.mX = mX;
|
dest.mX = mX;
|
||||||
dest.mY = mY;
|
dest.mY = mY;
|
||||||
dest.mZ = mZ;
|
dest.mZ = mZ;
|
||||||
mPath.push_back(dest);
|
|
||||||
isPathConstructed = true;
|
ESM::Pathgrid::Point start;
|
||||||
|
dest.mX = pos.pos[0];
|
||||||
|
dest.mY = pos.pos[1];
|
||||||
|
dest.mZ = pos.pos[2];
|
||||||
|
|
||||||
|
mPathFinder.findPath(start,dest,pathgrid,xCell,yCell);
|
||||||
}
|
}
|
||||||
if(mPath.empty())
|
if(mPathFinder.checkIfNextPointReached(pos.pos[0],pos.pos[1],pos.pos[2]))
|
||||||
{
|
{
|
||||||
MWWorld::Class::get(actor).getMovementSettings(actor).mForwardBackward = 0;
|
MWWorld::Class::get(actor).getMovementSettings(actor).mForwardBackward = 0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
ESM::Pathgrid::Point nextPoint = *mPath.begin();
|
|
||||||
if(distanceZCorrected(nextPoint,pos.pos[0],pos.pos[1],pos.pos[2]) < 20)
|
|
||||||
{
|
|
||||||
mPath.pop_front();
|
|
||||||
if(mPath.empty())
|
|
||||||
{
|
|
||||||
MWWorld::Class::get(actor).getMovementSettings(actor).mForwardBackward = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
nextPoint = *mPath.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
float dX = nextPoint.mX - pos.pos[0];
|
float zAngle = mPathFinder.getZAngleToNext(pos.pos[0],pos.pos[1],pos.pos[2]);
|
||||||
float dY = nextPoint.mY - pos.pos[1];
|
MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,zAngle,false);
|
||||||
|
|
||||||
MWBase::Environment::get().getWorld()->rotateObject(actor,0,0,getZAngle(dX,dY),false);
|
|
||||||
MWWorld::Class::get(actor).getMovementSettings(actor).mForwardBackward = 1;
|
MWWorld::Class::get(actor).getMovementSettings(actor).mForwardBackward = 1;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
#define GAME_MWMECHANICS_AITRAVEL_H
|
#define GAME_MWMECHANICS_AITRAVEL_H
|
||||||
|
|
||||||
#include "aipackage.hpp"
|
#include "aipackage.hpp"
|
||||||
#include <components/esm/loadpgrd.hpp>
|
#include "pathfinding.hpp"
|
||||||
#include <list>
|
|
||||||
|
|
||||||
namespace MWMechanics
|
namespace MWMechanics
|
||||||
{
|
{
|
||||||
|
@ -26,8 +25,9 @@ namespace MWMechanics
|
||||||
int cellX;
|
int cellX;
|
||||||
int cellY;
|
int cellY;
|
||||||
|
|
||||||
bool isPathConstructed;
|
//bool isPathConstructed;
|
||||||
std::list<ESM::Pathgrid::Point> mPath;
|
//std::list<ESM::Pathgrid::Point> mPath;
|
||||||
|
PathFinder mPathFinder;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
201
apps/openmw/mwmechanics/pathfinding.cpp
Normal file
201
apps/openmw/mwmechanics/pathfinding.cpp
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
#include "pathfinding.hpp"
|
||||||
|
#include <boost/graph/astar_search.hpp>
|
||||||
|
#include <boost/graph/adjacency_list.hpp>
|
||||||
|
#include "boost/tuple/tuple.hpp"
|
||||||
|
#include "OgreMath.h"
|
||||||
|
|
||||||
|
namespace MWMechanics
|
||||||
|
{
|
||||||
|
|
||||||
|
//helpers functions
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
float distance(ESM::Pathgrid::Point point,float x,float y,float z)
|
||||||
|
{
|
||||||
|
return sqrt((point.mX - x)*(point.mX - x)+(point.mY - y)*(point.mY - y)+(point.mZ - z)*(point.mZ - z));
|
||||||
|
}
|
||||||
|
|
||||||
|
float distance(ESM::Pathgrid::Point a,ESM::Pathgrid::Point b)
|
||||||
|
{
|
||||||
|
return sqrt(float(a.mX - b.mX)*(a.mX - b.mX)+(a.mY - b.mY)*(a.mY - b.mY)+(a.mZ - b.mZ)*(a.mZ - b.mZ));
|
||||||
|
}
|
||||||
|
|
||||||
|
float sgn(float a)
|
||||||
|
{
|
||||||
|
if(a>0) return 1.;
|
||||||
|
else return -1.;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getClosestPoint(const ESM::Pathgrid* grid,float x,float y,float z)
|
||||||
|
{
|
||||||
|
if(!grid) return -1;
|
||||||
|
if(grid->mPoints.empty()) return -1;
|
||||||
|
|
||||||
|
float m = distance(grid->mPoints[0],x,y,z);
|
||||||
|
int i0 = 0;
|
||||||
|
|
||||||
|
for(unsigned int i=1; i<grid->mPoints.size();++i)
|
||||||
|
{
|
||||||
|
if(distance(grid->mPoints[i],x,y,z)<m)
|
||||||
|
{
|
||||||
|
m = distance(grid->mPoints[i],x,y,z);
|
||||||
|
i0 = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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::astar_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;
|
||||||
|
};
|
||||||
|
|
||||||
|
PathGridGraph buildGraph(const ESM::Pathgrid* pathgrid,float xCell = 0,float yCell = 0)
|
||||||
|
{
|
||||||
|
PathGridGraph graph;
|
||||||
|
|
||||||
|
for(unsigned int i = 0;i<pathgrid->mPoints.size();++i)
|
||||||
|
{
|
||||||
|
PointID pID = boost::add_vertex(graph);
|
||||||
|
graph[pID].mX = pathgrid->mPoints[i].mX + xCell;
|
||||||
|
graph[pID].mY = pathgrid->mPoints[i].mY + yCell;
|
||||||
|
graph[pID].mZ = pathgrid->mPoints[i].mZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned int i = 0;i<pathgrid->mEdges.size();++i)
|
||||||
|
{
|
||||||
|
PointID u = pathgrid->mEdges[i].mV0;
|
||||||
|
PointID v = pathgrid->mEdges[i].mV1;
|
||||||
|
|
||||||
|
PointConnectionID edge;
|
||||||
|
bool done;
|
||||||
|
boost::tie(edge,done) = boost::add_edge(u,v,graph);
|
||||||
|
WeightMap weightmap = boost::get(boost::edge_weight, graph);
|
||||||
|
weightmap[edge] = distance(graph[u],graph[v]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<ESM::Pathgrid::Point> getPath(PointID start,PointID end,PathGridGraph graph){
|
||||||
|
std::vector<PointID> p(boost::num_vertices(graph));
|
||||||
|
std::vector<float> d(boost::num_vertices(graph));
|
||||||
|
std::list<ESM::Pathgrid::Point> shortest_path;
|
||||||
|
|
||||||
|
try {
|
||||||
|
boost::astar_search
|
||||||
|
(
|
||||||
|
graph,
|
||||||
|
start,
|
||||||
|
DistanceHeuristic(graph,end),
|
||||||
|
boost::predecessor_map(&p[0]).distance_map(&d[0]).visitor(goalVisited(end))//.weight_map(boost::get(&Edge::distance, graph))
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch(found_path fg) {
|
||||||
|
for(PointID v = end;; v = p[v]) {
|
||||||
|
shortest_path.push_front(graph[v]);
|
||||||
|
if(p[v] == v)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return shortest_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
//end of helpers functions
|
||||||
|
|
||||||
|
PathFinder::PathFinder()
|
||||||
|
{
|
||||||
|
mIsPathConstructed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<ESM::Pathgrid::Point> PathFinder::findPath(ESM::Pathgrid::Point startPoint,ESM::Pathgrid::Point endPoint,
|
||||||
|
const ESM::Pathgrid* pathGrid,float xCell,float yCell)
|
||||||
|
{
|
||||||
|
int start = getClosestPoint(pathGrid,startPoint.mX - xCell,startPoint.mY - yCell,startPoint.mZ);
|
||||||
|
int end = getClosestPoint(pathGrid,endPoint.mX - xCell,endPoint.mY - yCell,endPoint.mZ);
|
||||||
|
|
||||||
|
if(start != -1 && end != -1)
|
||||||
|
{
|
||||||
|
PathGridGraph graph = buildGraph(pathGrid,xCell,yCell);
|
||||||
|
mPath = getPath(start,end,graph);
|
||||||
|
}
|
||||||
|
|
||||||
|
mPath.push_back(endPoint);
|
||||||
|
mIsPathConstructed = true;
|
||||||
|
|
||||||
|
return mPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
float PathFinder::getZAngleToNext(float x,float y,float z)
|
||||||
|
{
|
||||||
|
if(mPath.empty())
|
||||||
|
{
|
||||||
|
return 0;/// shouldn't happen!
|
||||||
|
}
|
||||||
|
ESM::Pathgrid::Point nextPoint = *mPath.begin();
|
||||||
|
float dX = nextPoint.mX - x;
|
||||||
|
float dY = nextPoint.mY - y;
|
||||||
|
float h = sqrt(dX*dX+dY*dY);
|
||||||
|
return Ogre::Radian(acos(dY/h)*sgn(asin(dX/h))).valueDegrees();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PathFinder::checkIfNextPointReached(float x,float y,float z)
|
||||||
|
{
|
||||||
|
if(mPath.empty())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
ESM::Pathgrid::Point nextPoint = *mPath.begin();
|
||||||
|
if(distanceZCorrected(nextPoint,x,y,z) < 20)
|
||||||
|
{
|
||||||
|
mPath.pop_front();
|
||||||
|
if(mPath.empty())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
nextPoint = *mPath.begin();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
26
apps/openmw/mwmechanics/pathfinding.hpp
Normal file
26
apps/openmw/mwmechanics/pathfinding.hpp
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef GAME_MWMECHANICS_PATHFINDING_H
|
||||||
|
#define GAME_MWMECHANICS_PATHFINDING_H
|
||||||
|
|
||||||
|
#include <components/esm/loadpgrd.hpp>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
namespace MWMechanics
|
||||||
|
{
|
||||||
|
class PathFinder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PathFinder();
|
||||||
|
|
||||||
|
std::list<ESM::Pathgrid::Point> findPath(ESM::Pathgrid::Point startPoint,ESM::Pathgrid::Point endPoint,
|
||||||
|
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.
|
||||||
|
float getZAngleToNext(float x,float y,float z);
|
||||||
|
|
||||||
|
|
||||||
|
std::list<ESM::Pathgrid::Point> mPath;
|
||||||
|
bool mIsPathConstructed;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue