OpenMW
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
pathfinding.hpp
Go to the documentation of this file.
1 #ifndef GAME_MWMECHANICS_PATHFINDING_H
2 #define GAME_MWMECHANICS_PATHFINDING_H
3 
4 #include <list>
5 #include <cassert>
6 
9 
10 namespace MWWorld
11 {
12  class CellStore;
13 }
14 
15 namespace MWMechanics
16 {
17  class PathgridGraph;
18 
19  float distance(const ESM::Pathgrid::Point& point, float x, float y, float);
20  float distance(const ESM::Pathgrid::Point& a, const ESM::Pathgrid::Point& b);
21  float getZAngleToDir(const osg::Vec3f& dir);
22  float getXAngleToDir(const osg::Vec3f& dir);
23  float getZAngleToPoint(const ESM::Pathgrid::Point &origin, const ESM::Pathgrid::Point &dest);
24  float getXAngleToPoint(const ESM::Pathgrid::Point &origin, const ESM::Pathgrid::Point &dest);
25 
26  const float PATHFIND_Z_REACH = 50.0f;
27  //static const float sMaxSlope = 49.0f; // duplicate as in physicssystem
28  // distance after which actor (failed previously to shortcut) will try again
29  const float PATHFIND_SHORTCUT_RETRY_DIST = 300.0f;
30 
31  // cast up-down ray with some offset from actor position to check for pits/obstacles on the way to target;
32  // magnitude of pits/obstacles is defined by PATHFIND_Z_REACH
33  bool checkWayIsClear(const osg::Vec3f& from, const osg::Vec3f& to, float offsetXY);
34 
35  class PathFinder
36  {
37  public:
38  PathFinder();
39 
40  static const int PathTolerance = 32;
41 
42  static float sgn(float val)
43  {
44  if(val > 0)
45  return 1.0;
46  return -1.0;
47  }
48 
49  static int sgn(int a)
50  {
51  if(a > 0)
52  return 1;
53  return -1;
54  }
55 
56  void clearPath();
57 
58  void buildPath(const ESM::Pathgrid::Point &startPoint, const ESM::Pathgrid::Point &endPoint,
59  const MWWorld::CellStore* cell, const PathgridGraph& pathgridGraph);
60 
61  bool checkPathCompleted(float x, float y, float tolerance = PathTolerance);
63 
65  float getZAngleToNext(float x, float y) const;
66 
67  float getXAngleToNext(float x, float y, float z) const;
68 
69  bool isPathConstructed() const
70  {
71  return !mPath.empty();
72  }
73 
74  int getPathSize() const
75  {
76  return mPath.size();
77  }
78 
79  const std::list<ESM::Pathgrid::Point>& getPath() const
80  {
81  return mPath;
82  }
83 
84  const MWWorld::CellStore* getPathCell() const;
85 
93  void buildSyncedPath(const ESM::Pathgrid::Point &startPoint, const ESM::Pathgrid::Point &endPoint,
94  const MWWorld::CellStore* cell, const PathgridGraph& pathgridGraph);
95 
97  {
98  mPath.push_back(point);
99  }
100 
102  static ESM::Pathgrid::Point MakePathgridPoint(const osg::Vec3f& v)
103  {
104  return ESM::Pathgrid::Point(static_cast<int>(v[0]), static_cast<int>(v[1]), static_cast<int>(v[2]));
105  }
106 
109  {
110  return ESM::Pathgrid::Point(static_cast<int>(p.pos[0]), static_cast<int>(p.pos[1]), static_cast<int>(p.pos[2]));
111  }
112 
113  static osg::Vec3f MakeOsgVec3(const ESM::Pathgrid::Point& p)
114  {
115  return osg::Vec3f(static_cast<float>(p.mX), static_cast<float>(p.mY), static_cast<float>(p.mZ));
116  }
117 
118  // Slightly cheaper version for comparisons.
119  // Caller needs to be careful for very short distances (i.e. less than 1)
120  // or when accumuating the results i.e. (a + b)^2 != a^2 + b^2
121  //
122  static float DistanceSquared(ESM::Pathgrid::Point point, const osg::Vec3f& pos)
123  {
124  return (MWMechanics::PathFinder::MakeOsgVec3(point) - pos).length2();
125  }
126 
127  // Return the closest pathgrid point index from the specified position
128  // coordinates. NOTE: Does not check if there is a sensible way to get there
129  // (e.g. a cliff in front).
130  //
131  // NOTE: pos is expected to be in local coordinates, as is grid->mPoints
132  //
133  static int GetClosestPoint(const ESM::Pathgrid* grid, const osg::Vec3f& pos)
134  {
135  assert(grid && !grid->mPoints.empty());
136 
137  float distanceBetween = DistanceSquared(grid->mPoints[0], pos);
138  int closestIndex = 0;
139 
140  // TODO: if this full scan causes performance problems mapping pathgrid
141  // points to a quadtree may help
142  for(unsigned int counter = 1; counter < grid->mPoints.size(); counter++)
143  {
144  float potentialDistBetween = DistanceSquared(grid->mPoints[counter], pos);
145  if(potentialDistBetween < distanceBetween)
146  {
147  distanceBetween = potentialDistBetween;
148  closestIndex = counter;
149  }
150  }
151 
152  return closestIndex;
153  }
154 
155  private:
156  std::list<ESM::Pathgrid::Point> mPath;
157 
160  };
161 }
162 
163 #endif
const MWWorld::CellStore * getPathCell() const
Definition: pathfinding.cpp:354
float getZAngleToNext(float x, float y) const
In radians.
Definition: pathfinding.cpp:279
float pos[3]
Definition: defs.hpp:40
static int sgn(int a)
Definition: pathfinding.hpp:49
void buildPath(const ESM::Pathgrid::Point &startPoint, const ESM::Pathgrid::Point &endPoint, const MWWorld::CellStore *cell, const PathgridGraph &pathgridGraph)
Definition: pathfinding.cpp:170
PathFinder()
Definition: pathfinding.cpp:122
const std::list< ESM::Pathgrid::Point > & getPath() const
Definition: pathfinding.hpp:79
Definition: pathfinding.hpp:35
static const int PathTolerance
Definition: pathfinding.hpp:40
const MWWorld::CellStore * mCell
Definition: pathfinding.hpp:159
int mX
Definition: loadpgrd.hpp:32
const ESM::Pathgrid * mPathgrid
Definition: pathfinding.hpp:158
PointList mPoints
Definition: loadpgrd.hpp:54
bool isPathConstructed() const
Definition: pathfinding.hpp:69
const float PATHFIND_SHORTCUT_RETRY_DIST
Definition: pathfinding.hpp:29
Mutable state of a cell.
Definition: cellstore.hpp:51
static float sgn(float val)
Definition: pathfinding.hpp:42
bool checkWayIsClear(const osg::Vec3f &from, const osg::Vec3f &to, float offsetXY)
Definition: pathfinding.cpp:108
static osg::Vec3f MakeOsgVec3(const ESM::Pathgrid::Point &p)
Definition: pathfinding.hpp:113
void clearPath()
Definition: pathfinding.cpp:128
float distance(const ESM::Pathgrid::Point &point, float x, float y, float z)
Definition: pathfinding.cpp:69
static ESM::Pathgrid::Point MakePathgridPoint(const osg::Vec3f &v)
utility function to convert a osg::Vec3f to a Pathgrid::Point
Definition: pathfinding.hpp:102
void buildSyncedPath(const ESM::Pathgrid::Point &startPoint, const ESM::Pathgrid::Point &endPoint, const MWWorld::CellStore *cell, const PathgridGraph &pathgridGraph)
Definition: pathfinding.cpp:325
Definition: loadpgrd.hpp:16
void addPointToPath(const ESM::Pathgrid::Point &point)
Definition: pathfinding.hpp:96
static int GetClosestPoint(const ESM::Pathgrid *grid, const osg::Vec3f &pos)
Definition: pathfinding.hpp:133
Definition: defs.hpp:38
int mY
Definition: loadpgrd.hpp:32
float getZAngleToDir(const osg::Vec3f &dir)
Definition: pathfinding.cpp:85
float getXAngleToPoint(const ESM::Pathgrid::Point &origin, const ESM::Pathgrid::Point &dest)
Definition: pathfinding.cpp:102
Definition: pathgrid.hpp:20
static float DistanceSquared(ESM::Pathgrid::Point point, const osg::Vec3f &pos)
Definition: pathfinding.hpp:122
int mZ
Definition: loadpgrd.hpp:32
float getXAngleToDir(const osg::Vec3f &dir)
Definition: pathfinding.cpp:90
Definition: loadpgrd.hpp:30
static ESM::Pathgrid::Point MakePathgridPoint(const ESM::Position &p)
utility function to convert an ESM::Position to a Pathgrid::Point
Definition: pathfinding.hpp:108
float getZAngleToPoint(const ESM::Pathgrid::Point &origin, const ESM::Pathgrid::Point &dest)
Definition: pathfinding.cpp:96
int getPathSize() const
Definition: pathfinding.hpp:74
bool checkPathCompleted(float x, float y, float tolerance=PathTolerance)
true if we are within tolerance units of the last path point.
Definition: pathfinding.cpp:306
std::list< ESM::Pathgrid::Point > mPath
Definition: pathfinding.hpp:156
float getXAngleToNext(float x, float y, float z) const
Definition: pathfinding.cpp:293
const float PATHFIND_Z_REACH
Definition: pathfinding.hpp:26