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