TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
PathGenerator Class Reference

#include <PathGenerator.h>

Public Member Functions

 PathGenerator (Unit const *owner)
 
 ~PathGenerator ()
 
bool CalculatePath (float destX, float destY, float destZ, bool forceDest=false, bool straightLine=false)
 
void SetUseStraightPath (bool useStraightPath)
 
void SetPathLengthLimit (float distance)
 
G3D::Vector3 constGetStartPosition () const
 
G3D::Vector3 constGetEndPosition () const
 
G3D::Vector3 constGetActualEndPosition () const
 
Movement::PointsArray constGetPath () const
 
PathType GetPathType () const
 
void ReducePathLenghtByDist (float dist)
 

Private Member Functions

void SetStartPosition (G3D::Vector3 const &point)
 
void SetEndPosition (G3D::Vector3 const &point)
 
void SetActualEndPosition (G3D::Vector3 const &point)
 
void NormalizePath ()
 
void Clear ()
 
bool InRange (G3D::Vector3 const &p1, G3D::Vector3 const &p2, float r, float h) const
 
float Dist3DSqr (G3D::Vector3 const &p1, G3D::Vector3 const &p2) const
 
bool InRangeYZX (float const *v1, float const *v2, float r, float h) const
 
dtPolyRef GetPathPolyByPosition (dtPolyRef const *polyPath, uint32 polyPathSize, float const *Point, float *Distance=NULL) const
 
dtPolyRef GetPolyByLocation (float const *Point, float *Distance) const
 
bool HaveTile (G3D::Vector3 const &p) const
 
void BuildPolyPath (G3D::Vector3 const &startPos, G3D::Vector3 const &endPos)
 
void BuildPointPath (float const *startPoint, float const *endPoint)
 
void BuildShortcut ()
 
NavTerrain GetNavTerrain (float x, float y, float z)
 
void CreateFilter ()
 
void UpdateFilter ()
 
uint32 FixupCorridor (dtPolyRef *path, uint32 npath, uint32 maxPath, dtPolyRef const *visited, uint32 nvisited)
 
bool GetSteerTarget (float const *startPos, float const *endPos, float minTargetDist, dtPolyRef const *path, uint32 pathSize, float *steerPos, unsigned char &steerPosFlag, dtPolyRef &steerPosRef)
 
dtStatus FindSmoothPath (float const *startPos, float const *endPos, dtPolyRef const *polyPath, uint32 polyPathSize, float *smoothPath, int *smoothPathSize, uint32 smoothPathMaxSize)
 

Private Attributes

dtPolyRef _pathPolyRefs [MAX_PATH_LENGTH]
 
uint32 _polyLength
 
Movement::PointsArray _pathPoints
 
PathType _type
 
bool _useStraightPath
 
bool _forceDestination
 
uint32 _pointPathLimit
 
bool _straightLine
 
G3D::Vector3 _startPosition
 
G3D::Vector3 _endPosition
 
G3D::Vector3 _actualEndPosition
 
Unit const *const _sourceUnit
 
dtNavMesh const_navMesh
 
dtNavMeshQuery const_navMeshQuery
 
dtQueryFilter _filter
 

Constructor & Destructor Documentation

PathGenerator::PathGenerator ( Unit const owner)
explicit
31  :
36 {
37  memset(_pathPolyRefs, 0, sizeof(_pathPolyRefs));
38 
39  TC_LOG_DEBUG("maps", "++ PathGenerator::PathGenerator for %s", _sourceUnit->GetGUID().ToString().c_str());
40 
41  uint32 mapId = _sourceUnit->GetMapId();
43  {
47  }
48 
49  CreateFilter();
50 }
uint32 _polyLength
Definition: PathGenerator.h:80
bool IsPathfindingEnabled(uint32 mapId)
Definition: DisableMgr.cpp:380
bool _straightLine
Definition: PathGenerator.h:88
dtNavMesh const * _navMesh
Definition: PathGenerator.h:95
std::set< uint32 > const & GetTerrainSwaps() const
Definition: Object.h:466
arena_t NULL
Definition: jemalloc_internal.h:624
Unit const *const _sourceUnit
Definition: PathGenerator.h:94
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:198
dtNavMesh const * GetNavMesh(uint32 mapId, TerrainSet swaps)
Definition: MMapManager.cpp:399
dtNavMeshQuery const * GetNavMeshQuery(uint32 mapId, uint32 instanceId, TerrainSet swaps)
Definition: MMapManager.cpp:408
static const Vector3 & zero()
Definition: Vector3.cpp:119
Definition: PathGenerator.h:43
uint32 GetInstanceId() const
Definition: Object.h:451
uint32_t uint32
Definition: Define.h:150
uint32 GetMapId() const
Definition: Position.h:254
bool _forceDestination
Definition: PathGenerator.h:86
bool _useStraightPath
Definition: PathGenerator.h:85
ObjectGuid const & GetGUID() const
Definition: Object.h:105
Definition: MMapManager.h:93
dtNavMeshQuery const * _navMeshQuery
Definition: PathGenerator.h:96
PathType _type
Definition: PathGenerator.h:83
void CreateFilter()
Definition: PathGenerator.cpp:603
static MMapManager * createOrGetMMapManager()
Definition: MMapFactory.cpp:28
dtPolyRef _pathPolyRefs[MAX_PATH_LENGTH]
Definition: PathGenerator.h:79
#define MAX_POINT_PATH_LENGTH
Definition: PathGenerator.h:33
std::string ToString() const
Definition: ObjectGuid.cpp:99
uint32 _pointPathLimit
Definition: PathGenerator.h:87
G3D::Vector3 _endPosition
Definition: PathGenerator.h:91

+ Here is the call graph for this function:

PathGenerator::~PathGenerator ( )
53 {
54  TC_LOG_DEBUG("maps", "++ PathGenerator::~PathGenerator() for %s", _sourceUnit->GetGUID().ToString().c_str());
55 }
Unit const *const _sourceUnit
Definition: PathGenerator.h:94
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:198
ObjectGuid const & GetGUID() const
Definition: Object.h:105
std::string ToString() const
Definition: ObjectGuid.cpp:99

+ Here is the call graph for this function:

Member Function Documentation

void PathGenerator::BuildPointPath ( float const startPoint,
float const endPoint 
)
private
Todo:
check the exact cases
475 {
476  float pathPoints[MAX_POINT_PATH_LENGTH*VERTEX_SIZE];
477  uint32 pointCount = 0;
478  dtStatus dtResult = DT_FAILURE;
479  if (_straightLine)
480  {
481  dtResult = DT_SUCCESS;
482  pointCount = 1;
483  memcpy(&pathPoints[VERTEX_SIZE * 0], startPoint, sizeof(float)* 3); // first point
484 
485  // path has to be split into polygons with dist SMOOTH_PATH_STEP_SIZE between them
486  G3D::Vector3 startVec = G3D::Vector3(startPoint[0], startPoint[1], startPoint[2]);
487  G3D::Vector3 endVec = G3D::Vector3(endPoint[0], endPoint[1], endPoint[2]);
488  G3D::Vector3 diffVec = (endVec - startVec);
489  G3D::Vector3 prevVec = startVec;
490  float len = diffVec.length();
491  diffVec *= SMOOTH_PATH_STEP_SIZE / len;
492  while (len > SMOOTH_PATH_STEP_SIZE)
493  {
494  len -= SMOOTH_PATH_STEP_SIZE;
495  prevVec += diffVec;
496  pathPoints[VERTEX_SIZE * pointCount + 0] = prevVec.x;
497  pathPoints[VERTEX_SIZE * pointCount + 1] = prevVec.y;
498  pathPoints[VERTEX_SIZE * pointCount + 2] = prevVec.z;
499  ++pointCount;
500  }
501 
502  memcpy(&pathPoints[VERTEX_SIZE * pointCount], endPoint, sizeof(float)* 3); // last point
503  ++pointCount;
504  }
505  else if (_useStraightPath)
506  {
507  dtResult = _navMeshQuery->findStraightPath(
508  startPoint, // start position
509  endPoint, // end position
510  _pathPolyRefs, // current path
511  _polyLength, // lenth of current path
512  pathPoints, // [out] path corner points
513  NULL, // [out] flags
514  NULL, // [out] shortened path
515  (int*)&pointCount,
516  _pointPathLimit); // maximum number of points/polygons to use
517  }
518  else
519  {
520  dtResult = FindSmoothPath(
521  startPoint, // start position
522  endPoint, // end position
523  _pathPolyRefs, // current path
524  _polyLength, // length of current path
525  pathPoints, // [out] path corner points
526  (int*)&pointCount,
527  _pointPathLimit); // maximum number of points
528  }
529 
530  if (pointCount < 2 || dtStatusFailed(dtResult))
531  {
532  // only happens if pass bad data to findStraightPath or navmesh is broken
533  // single point paths can be generated here
535  TC_LOG_DEBUG("maps", "++ PathGenerator::BuildPointPath FAILED! path sized %d returned\n", pointCount);
536  BuildShortcut();
538  return;
539  }
540  else if (pointCount == _pointPathLimit)
541  {
542  TC_LOG_DEBUG("maps", "++ PathGenerator::BuildPointPath FAILED! path sized %d returned, lower than limit set to %d\n", pointCount, _pointPathLimit);
543  BuildShortcut();
545  return;
546  }
547 
548  _pathPoints.resize(pointCount);
549  for (uint32 i = 0; i < pointCount; ++i)
550  _pathPoints[i] = G3D::Vector3(pathPoints[i*VERTEX_SIZE+2], pathPoints[i*VERTEX_SIZE], pathPoints[i*VERTEX_SIZE+1]);
551 
552  NormalizePath();
553 
554  // first point is always our current location - we need the next one
555  SetActualEndPosition(_pathPoints[pointCount-1]);
556 
557  // force the given destination, if needed
558  if (_forceDestination &&
559  (!(_type & PATHFIND_NORMAL) || !InRange(GetEndPosition(), GetActualEndPosition(), 1.0f, 1.0f)))
560  {
561  // we may want to keep partial subpath
563  {
565  _pathPoints[_pathPoints.size()-1] = GetEndPosition();
566  }
567  else
568  {
570  BuildShortcut();
571  }
572 
573  _type = PathType(PATHFIND_NORMAL | PATHFIND_NOT_USING_PATH);
574  }
575 
576  TC_LOG_DEBUG("maps", "++ PathGenerator::BuildPointPath path type %d size %d poly-size %d\n", _type, pointCount, _polyLength);
577 }
uint32 _polyLength
Definition: PathGenerator.h:80
bool InRange(G3D::Vector3 const &p1, G3D::Vector3 const &p2, float r, float h) const
Definition: PathGenerator.cpp:894
float x
Definition: Vector3.h:62
PathType
Definition: PathGenerator.h:41
Definition: PathGenerator.h:47
Definition: PathGenerator.h:44
void SetActualEndPosition(G3D::Vector3 const &point)
Definition: PathGenerator.h:102
bool _straightLine
Definition: PathGenerator.h:88
G3D::Vector3 const & GetEndPosition() const
Definition: PathGenerator.h:68
dtStatus FindSmoothPath(float const *startPos, float const *endPos, dtPolyRef const *polyPath, uint32 polyPathSize, float *smoothPath, int *smoothPathSize, uint32 smoothPathMaxSize)
Definition: PathGenerator.cpp:764
dtStatus findStraightPath(const float *startPos, const float *endPos, const dtPolyRef *path, const int pathSize, float *straightPath, unsigned char *straightPathFlags, dtPolyRef *straightPathRefs, int *straightPathCount, const int maxStraightPath, const int options=0) const
Definition: DetourNavMeshQuery.cpp:1707
static const unsigned int DT_SUCCESS
Definition: DetourStatus.h:26
G3D::Vector3 const & GetActualEndPosition() const
Definition: PathGenerator.h:69
arena_t NULL
Definition: jemalloc_internal.h:624
float Dist3DSqr(G3D::Vector3 const &p1, G3D::Vector3 const &p2) const
Definition: PathGenerator.cpp:900
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:198
G3D::Vector3 const & GetStartPosition() const
Definition: PathGenerator.h:67
unsigned int dtStatus
Definition: DetourStatus.h:22
float y
Definition: Vector3.h:62
float length() const
Definition: Vector3.h:751
Definition: Vector3.h:58
void NormalizePath()
Definition: PathGenerator.cpp:579
uint32_t uint32
Definition: Define.h:150
Movement::PointsArray _pathPoints
Definition: PathGenerator.h:82
bool dtStatusFailed(dtStatus status)
Definition: DetourStatus.h:47
bool _forceDestination
Definition: PathGenerator.h:86
bool _useStraightPath
Definition: PathGenerator.h:85
Definition: PathGenerator.h:49
float z
Definition: Vector3.h:62
Definition: PathGenerator.h:48
dtNavMeshQuery const * _navMeshQuery
Definition: PathGenerator.h:96
PathType _type
Definition: PathGenerator.h:83
void BuildShortcut()
Definition: PathGenerator.cpp:585
#define VERTEX_SIZE
Definition: PathGenerator.h:38
dtPolyRef _pathPolyRefs[MAX_PATH_LENGTH]
Definition: PathGenerator.h:79
#define SMOOTH_PATH_STEP_SIZE
Definition: PathGenerator.h:35
#define MAX_POINT_PATH_LENGTH
Definition: PathGenerator.h:33
uint32 _pointPathLimit
Definition: PathGenerator.h:87
static const unsigned int DT_FAILURE
Definition: DetourStatus.h:25

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void PathGenerator::BuildPolyPath ( G3D::Vector3 const startPos,
G3D::Vector3 const endPos 
)
private
Todo:
we can merge it with getPathPolyByPosition() loop
Todo:
play with the values here
160 {
161  // *** getting start/end poly logic ***
162 
163  float distToStartPoly, distToEndPoly;
164  float startPoint[VERTEX_SIZE] = {startPos.y, startPos.z, startPos.x};
165  float endPoint[VERTEX_SIZE] = {endPos.y, endPos.z, endPos.x};
166 
167  dtPolyRef startPoly = GetPolyByLocation(startPoint, &distToStartPoly);
168  dtPolyRef endPoly = GetPolyByLocation(endPoint, &distToEndPoly);
169 
170  // we have a hole in our mesh
171  // make shortcut path and mark it as NOPATH ( with flying and swimming exception )
172  // its up to caller how he will use this info
173  if (startPoly == INVALID_POLYREF || endPoly == INVALID_POLYREF)
174  {
175  TC_LOG_DEBUG("maps", "++ BuildPolyPath :: (startPoly == 0 || endPoly == 0)\n");
176  BuildShortcut();
177  bool path = _sourceUnit->GetTypeId() == TYPEID_UNIT && _sourceUnit->ToCreature()->CanFly();
178 
179  bool waterPath = _sourceUnit->GetTypeId() == TYPEID_UNIT && _sourceUnit->ToCreature()->CanSwim();
180  if (waterPath)
181  {
182  // Check both start and end points, if they're both in water, then we can *safely* let the creature move
183  for (uint32 i = 0; i < _pathPoints.size(); ++i)
184  {
186  // One of the points is not in the water, cancel movement.
187  if (status == LIQUID_MAP_NO_WATER)
188  {
189  waterPath = false;
190  break;
191  }
192  }
193  }
194 
196  return;
197  }
198 
199  // we may need a better number here
200  bool farFromPoly = (distToStartPoly > 7.0f || distToEndPoly > 7.0f);
201  if (farFromPoly)
202  {
203  TC_LOG_DEBUG("maps", "++ BuildPolyPath :: farFromPoly distToStartPoly=%.3f distToEndPoly=%.3f\n", distToStartPoly, distToEndPoly);
204 
205  bool buildShotrcut = false;
207  {
208  Creature* owner = (Creature*)_sourceUnit;
209 
210  G3D::Vector3 const& p = (distToStartPoly > 7.0f) ? startPos : endPos;
211  if (_sourceUnit->GetBaseMap()->IsUnderWater(p.x, p.y, p.z))
212  {
213  TC_LOG_DEBUG("maps", "++ BuildPolyPath :: underWater case\n");
214  if (owner->CanSwim())
215  buildShotrcut = true;
216  }
217  else
218  {
219  TC_LOG_DEBUG("maps", "++ BuildPolyPath :: flying case\n");
220  if (owner->CanFly())
221  buildShotrcut = true;
222  }
223  }
224 
225  if (buildShotrcut)
226  {
227  BuildShortcut();
229  return;
230  }
231  else
232  {
233  float closestPoint[VERTEX_SIZE];
234  // we may want to use closestPointOnPolyBoundary instead
235  if (dtStatusSucceed(_navMeshQuery->closestPointOnPoly(endPoly, endPoint, closestPoint, NULL)))
236  {
237  dtVcopy(endPoint, closestPoint);
238  SetActualEndPosition(G3D::Vector3(endPoint[2], endPoint[0], endPoint[1]));
239  }
240 
242  }
243  }
244 
245  // *** poly path generating logic ***
246 
247  // start and end are on same polygon
248  // just need to move in straight line
249  if (startPoly == endPoly)
250  {
251  TC_LOG_DEBUG("maps", "++ BuildPolyPath :: (startPoly == endPoly)\n");
252 
253  BuildShortcut();
254 
255  _pathPolyRefs[0] = startPoly;
256  _polyLength = 1;
257 
258  _type = farFromPoly ? PATHFIND_INCOMPLETE : PATHFIND_NORMAL;
259  TC_LOG_DEBUG("maps", "++ BuildPolyPath :: path type %d\n", _type);
260  return;
261  }
262 
263  // look for startPoly/endPoly in current path
265  bool startPolyFound = false;
266  bool endPolyFound = false;
267  uint32 pathStartIndex = 0;
268  uint32 pathEndIndex = 0;
269 
270  if (_polyLength)
271  {
272  for (; pathStartIndex < _polyLength; ++pathStartIndex)
273  {
274  // here to catch few bugs
275  if (_pathPolyRefs[pathStartIndex] == INVALID_POLYREF)
276  {
277  TC_LOG_ERROR("maps", "Invalid poly ref in BuildPolyPath. _polyLength: %u, pathStartIndex: %u,"
278  " startPos: %s, endPos: %s, mapid: %u",
279  _polyLength, pathStartIndex, startPos.toString().c_str(), endPos.toString().c_str(),
280  _sourceUnit->GetMapId());
281 
282  break;
283  }
284 
285  if (_pathPolyRefs[pathStartIndex] == startPoly)
286  {
287  startPolyFound = true;
288  break;
289  }
290  }
291 
292  for (pathEndIndex = _polyLength-1; pathEndIndex > pathStartIndex; --pathEndIndex)
293  if (_pathPolyRefs[pathEndIndex] == endPoly)
294  {
295  endPolyFound = true;
296  break;
297  }
298  }
299 
300  if (startPolyFound && endPolyFound)
301  {
302  TC_LOG_DEBUG("maps", "++ BuildPolyPath :: (startPolyFound && endPolyFound)\n");
303 
304  // we moved along the path and the target did not move out of our old poly-path
305  // our path is a simple subpath case, we have all the data we need
306  // just "cut" it out
307 
308  _polyLength = pathEndIndex - pathStartIndex + 1;
309  memmove(_pathPolyRefs, _pathPolyRefs + pathStartIndex, _polyLength * sizeof(dtPolyRef));
310  }
311  else if (startPolyFound && !endPolyFound)
312  {
313  TC_LOG_DEBUG("maps", "++ BuildPolyPath :: (startPolyFound && !endPolyFound)\n");
314 
315  // we are moving on the old path but target moved out
316  // so we have atleast part of poly-path ready
317 
318  _polyLength -= pathStartIndex;
319 
320  // try to adjust the suffix of the path instead of recalculating entire length
321  // at given interval the target cannot get too far from its last location
322  // thus we have less poly to cover
323  // sub-path of optimal path is optimal
324 
325  // take ~80% of the original length
327  uint32 prefixPolyLength = uint32(_polyLength * 0.8f + 0.5f);
328  memmove(_pathPolyRefs, _pathPolyRefs+pathStartIndex, prefixPolyLength * sizeof(dtPolyRef));
329 
330  dtPolyRef suffixStartPoly = _pathPolyRefs[prefixPolyLength-1];
331 
332  // we need any point on our suffix start poly to generate poly-path, so we need last poly in prefix data
333  float suffixEndPoint[VERTEX_SIZE];
334  if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint, NULL)))
335  {
336  // we can hit offmesh connection as last poly - closestPointOnPoly() don't like that
337  // try to recover by using prev polyref
338  --prefixPolyLength;
339  suffixStartPoly = _pathPolyRefs[prefixPolyLength-1];
340  if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint, NULL)))
341  {
342  // suffixStartPoly is still invalid, error state
343  BuildShortcut();
345  return;
346  }
347  }
348 
349  // generate suffix
350  uint32 suffixPolyLength = 0;
351 
352  dtStatus dtResult;
353  if (_straightLine)
354  {
355  float hit = 0;
356  float hitNormal[3];
357  memset(hitNormal, 0, sizeof(hitNormal));
358 
359  dtResult = _navMeshQuery->raycast(
360  suffixStartPoly,
361  suffixEndPoint,
362  endPoint,
363  &_filter,
364  &hit,
365  hitNormal,
366  _pathPolyRefs + prefixPolyLength - 1,
367  (int*)&suffixPolyLength,
368  MAX_PATH_LENGTH - prefixPolyLength);
369 
370  // raycast() sets hit to FLT_MAX if there is a ray between start and end
371  if (hit != FLT_MAX)
372  {
373  // the ray hit something, return no path instead of the incomplete one
375  return;
376  }
377  }
378  else
379  {
380  dtResult = _navMeshQuery->findPath(
381  suffixStartPoly, // start polygon
382  endPoly, // end polygon
383  suffixEndPoint, // start position
384  endPoint, // end position
385  &_filter, // polygon search filter
386  _pathPolyRefs + prefixPolyLength - 1, // [out] path
387  (int*)&suffixPolyLength,
388  MAX_PATH_LENGTH - prefixPolyLength); // max number of polygons in output path
389  }
390 
391  if (!suffixPolyLength || dtStatusFailed(dtResult))
392  {
393  // this is probably an error state, but we'll leave it
394  // and hopefully recover on the next Update
395  // we still need to copy our preffix
396  TC_LOG_ERROR("maps", "%s's Path Build failed: 0 length path", _sourceUnit->GetGUID().ToString().c_str());
397  }
398 
399  TC_LOG_DEBUG("maps", "++ m_polyLength=%u prefixPolyLength=%u suffixPolyLength=%u \n", _polyLength, prefixPolyLength, suffixPolyLength);
400 
401  // new path = prefix + suffix - overlap
402  _polyLength = prefixPolyLength + suffixPolyLength - 1;
403  }
404  else
405  {
406  TC_LOG_DEBUG("maps", "++ BuildPolyPath :: (!startPolyFound && !endPolyFound)\n");
407 
408  // either we have no path at all -> first run
409  // or something went really wrong -> we aren't moving along the path to the target
410  // just generate new path
411 
412  // free and invalidate old path data
413  Clear();
414 
415  dtStatus dtResult;
416  if (_straightLine)
417  {
418  float hit = 0;
419  float hitNormal[3];
420  memset(hitNormal, 0, sizeof(hitNormal));
421 
422  dtResult = _navMeshQuery->raycast(
423  startPoly,
424  startPoint,
425  endPoint,
426  &_filter,
427  &hit,
428  hitNormal,
430  (int*)&_polyLength,
432 
433  // raycast() sets hit to FLT_MAX if there is a ray between start and end
434  if (hit != FLT_MAX)
435  {
436  // the ray hit something, return no path instead of the incomplete one
438  return;
439  }
440  }
441  else
442  {
443  dtResult = _navMeshQuery->findPath(
444  startPoly, // start polygon
445  endPoly, // end polygon
446  startPoint, // start position
447  endPoint, // end position
448  &_filter, // polygon search filter
449  _pathPolyRefs, // [out] path
450  (int*)&_polyLength,
451  MAX_PATH_LENGTH); // max number of polygons in output path
452  }
453 
454  if (!_polyLength || dtStatusFailed(dtResult))
455  {
456  // only happens if we passed bad data to findPath(), or navmesh is messed up
457  TC_LOG_ERROR("maps", "%s's Path Build failed: 0 length path", _sourceUnit->GetGUID().ToString().c_str());
458  BuildShortcut();
460  return;
461  }
462  }
463 
464  // by now we know what type of path we can get
465  if (_pathPolyRefs[_polyLength - 1] == endPoly && !(_type & PATHFIND_INCOMPLETE))
467  else
469 
470  // generate the point-path out of our up-to-date poly-path
471  BuildPointPath(startPoint, endPoint);
472 }
uint32 _polyLength
Definition: PathGenerator.h:80
float x
Definition: Vector3.h:62
uint64_d dtPolyRef
Definition: DetourNavMesh.h:49
PathType
Definition: PathGenerator.h:41
Definition: PathGenerator.h:47
Definition: PathGenerator.h:44
void SetActualEndPosition(G3D::Vector3 const &point)
Definition: PathGenerator.h:102
dtPolyRef GetPolyByLocation(float const *Point, float *Distance) const
Definition: PathGenerator.cpp:125
bool _straightLine
Definition: PathGenerator.h:88
Definition: ObjectGuid.h:32
arena_t NULL
Definition: jemalloc_internal.h:624
dtStatus raycast(dtPolyRef startRef, const float *startPos, const float *endPos, const dtQueryFilter *filter, float *t, float *hitNormal, dtPolyRef *path, int *pathCount, const int maxPath) const
Definition: DetourNavMeshQuery.cpp:2306
Unit const *const _sourceUnit
Definition: PathGenerator.h:94
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:198
Definition: Creature.h:467
bool CanSwim() const
Definition: Creature.h:499
unsigned int dtStatus
Definition: DetourStatus.h:22
float y
Definition: Vector3.h:62
Definition: Vector3.h:58
dtStatus findPath(dtPolyRef startRef, dtPolyRef endRef, const float *startPos, const float *endPos, const dtQueryFilter *filter, dtPolyRef *path, int *pathCount, const int maxPath) const
Definition: DetourNavMeshQuery.cpp:923
TypeID GetTypeId() const
Definition: Object.h:113
#define INVALID_POLYREF
Definition: PathGenerator.h:39
bool dtStatusSucceed(dtStatus status)
Definition: DetourStatus.h:41
G3D::int16 z
Definition: Vector3int16.h:46
#define MAP_ALL_LIQUIDS
Definition: Map.h:146
uint32_t uint32
Definition: Define.h:150
Movement::PointsArray _pathPoints
Definition: PathGenerator.h:82
G3D::int16 y
Definition: Vector2int16.h:38
bool dtStatusFailed(dtStatus status)
Definition: DetourStatus.h:47
ZLiquidStatus
Definition: Map.h:131
dtQueryFilter _filter
Definition: PathGenerator.h:98
uint32 GetMapId() const
Definition: Position.h:254
bool IsUnderWater(float x, float y, float z) const
Definition: Map.cpp:2622
Definition: PathGenerator.h:46
bool CanFly() const override
Definition: Creature.h:500
void dtVcopy(float *dest, const float *a)
Definition: DetourCommon.h:190
ObjectGuid const & GetGUID() const
Definition: Object.h:105
float z
Definition: Vector3.h:62
Definition: PathGenerator.h:48
Map const * GetBaseMap() const
Definition: Object.cpp:2199
Creature * ToCreature()
Definition: Object.h:194
dtNavMeshQuery const * _navMeshQuery
Definition: PathGenerator.h:96
PathType _type
Definition: PathGenerator.h:83
void BuildShortcut()
Definition: PathGenerator.cpp:585
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
#define VERTEX_SIZE
Definition: PathGenerator.h:38
uint32_t uint32
Definition: g3dmath.h:168
G3D::int16 x
Definition: Vector2int16.h:37
#define MAX_PATH_LENGTH
Definition: PathGenerator.h:32
dtPolyRef _pathPolyRefs[MAX_PATH_LENGTH]
Definition: PathGenerator.h:79
void Clear()
Definition: PathGenerator.h:105
void BuildPointPath(float const *startPoint, float const *endPoint)
Definition: PathGenerator.cpp:474
ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData *data=nullptr) const
Definition: Map.cpp:2497
std::string ToString() const
Definition: ObjectGuid.cpp:99
Definition: Map.h:133
dtStatus closestPointOnPoly(dtPolyRef ref, const float *pos, float *closest, bool *posOverPoly) const
Definition: DetourNavMeshQuery.cpp:505

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void PathGenerator::BuildShortcut ( )
private
586 {
587  TC_LOG_DEBUG("maps", "++ BuildShortcut :: making shortcut\n");
588 
589  Clear();
590 
591  // make two point path, our curr pos is the start, and dest is the end
592  _pathPoints.resize(2);
593 
594  // set start and a default next position
597 
598  NormalizePath();
599 
601 }
Definition: PathGenerator.h:45
G3D::Vector3 const & GetActualEndPosition() const
Definition: PathGenerator.h:69
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:198
G3D::Vector3 const & GetStartPosition() const
Definition: PathGenerator.h:67
void NormalizePath()
Definition: PathGenerator.cpp:579
Movement::PointsArray _pathPoints
Definition: PathGenerator.h:82
PathType _type
Definition: PathGenerator.h:83
void Clear()
Definition: PathGenerator.h:105

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool PathGenerator::CalculatePath ( float  destX,
float  destY,
float  destZ,
bool  forceDest = false,
bool  straightLine = false 
)
58 {
59  float x, y, z;
60  _sourceUnit->GetPosition(x, y, z);
61 
62  if (!Trinity::IsValidMapCoord(destX, destY, destZ) || !Trinity::IsValidMapCoord(x, y, z))
63  return false;
64 
65  G3D::Vector3 dest(destX, destY, destZ);
66  SetEndPosition(dest);
67 
68  G3D::Vector3 start(x, y, z);
69  SetStartPosition(start);
70 
71  _forceDestination = forceDest;
72  _straightLine = straightLine;
73 
74  TC_LOG_DEBUG("maps", "++ PathGenerator::CalculatePath() for %s", _sourceUnit->GetGUID().ToString().c_str());
75 
76  // make sure navMesh works - we can run on map w/o mmap
77  // check if the start and end point have a .mmtile loaded (can we pass via not loaded tile on the way?)
79  !HaveTile(start) || !HaveTile(dest))
80  {
81  BuildShortcut();
83  return true;
84  }
85 
86  UpdateFilter();
87 
88  BuildPolyPath(start, dest);
89  return true;
90 }
PathType
Definition: PathGenerator.h:41
Definition: PathGenerator.h:44
bool HaveTile(G3D::Vector3 const &p) const
Definition: PathGenerator.cpp:666
bool _straightLine
Definition: PathGenerator.h:88
dtNavMesh const * _navMesh
Definition: PathGenerator.h:95
void SetEndPosition(G3D::Vector3 const &point)
Definition: PathGenerator.h:101
Unit const *const _sourceUnit
Definition: PathGenerator.h:94
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:198
Definition: Vector3.h:58
void UpdateFilter()
Definition: PathGenerator.cpp:630
bool IsValidMapCoord(float c)
Definition: GridDefines.h:218
G3D::int16 z
Definition: Vector3int16.h:46
void GetPosition(float &x, float &y) const
Definition: Position.h:109
G3D::int16 y
Definition: Vector2int16.h:38
void BuildPolyPath(G3D::Vector3 const &startPos, G3D::Vector3 const &endPos)
Definition: PathGenerator.cpp:159
bool _forceDestination
Definition: PathGenerator.h:86
ObjectGuid const & GetGUID() const
Definition: Object.h:105
Definition: PathGenerator.h:48
dtNavMeshQuery const * _navMeshQuery
Definition: PathGenerator.h:96
PathType _type
Definition: PathGenerator.h:83
bool HasUnitState(const uint32 f) const
Definition: Unit.h:1395
void BuildShortcut()
Definition: PathGenerator.cpp:585
void SetStartPosition(G3D::Vector3 const &point)
Definition: PathGenerator.h:100
G3D::int16 x
Definition: Vector2int16.h:37
Definition: Unit.h:577
std::string ToString() const
Definition: ObjectGuid.cpp:99

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void PathGenerator::Clear ( )
inlineprivate
106  {
107  _polyLength = 0;
108  _pathPoints.clear();
109  }
uint32 _polyLength
Definition: PathGenerator.h:80
Movement::PointsArray _pathPoints
Definition: PathGenerator.h:82

+ Here is the caller graph for this function:

void PathGenerator::CreateFilter ( )
private
604 {
605  uint16 includeFlags = 0;
606  uint16 excludeFlags = 0;
607 
609  {
610  Creature* creature = (Creature*)_sourceUnit;
611  if (creature->CanWalk())
612  includeFlags |= NAV_GROUND; // walk
613 
614  // creatures don't take environmental damage
615  if (creature->CanSwim())
616  includeFlags |= (NAV_WATER | NAV_MAGMA | NAV_SLIME); // swim
617  }
618  else // assume Player
619  {
620  // perfect support not possible, just stay 'safe'
621  includeFlags |= (NAV_GROUND | NAV_WATER | NAV_MAGMA | NAV_SLIME);
622  }
623 
624  _filter.setIncludeFlags(includeFlags);
625  _filter.setExcludeFlags(excludeFlags);
626 
627  UpdateFilter();
628 }
Definition: MapDefines.h:26
void setIncludeFlags(const unsigned short flags)
Definition: DetourNavMeshQuery.h:107
Definition: MapDefines.h:28
Definition: MapDefines.h:25
Definition: MapDefines.h:27
Definition: ObjectGuid.h:32
Unit const *const _sourceUnit
Definition: PathGenerator.h:94
Definition: Creature.h:467
bool CanSwim() const
Definition: Creature.h:499
void UpdateFilter()
Definition: PathGenerator.cpp:630
TypeID GetTypeId() const
Definition: Object.h:113
uint16_t uint16
Definition: Define.h:151
dtQueryFilter _filter
Definition: PathGenerator.h:98
bool CanWalk() const
Definition: Creature.h:498
void setExcludeFlags(const unsigned short flags)
Definition: DetourNavMeshQuery.h:116

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

float PathGenerator::Dist3DSqr ( G3D::Vector3 const p1,
G3D::Vector3 const p2 
) const
private
901 {
902  return (p1 - p2).squaredLength();
903 }

+ Here is the caller graph for this function:

dtStatus PathGenerator::FindSmoothPath ( float const startPos,
float const endPos,
dtPolyRef const polyPath,
uint32  polyPathSize,
float *  smoothPath,
int *  smoothPathSize,
uint32  smoothPathMaxSize 
)
private
767 {
768  *smoothPathSize = 0;
769  uint32 nsmoothPath = 0;
770 
771  dtPolyRef polys[MAX_PATH_LENGTH];
772  memcpy(polys, polyPath, sizeof(dtPolyRef)*polyPathSize);
773  uint32 npolys = polyPathSize;
774 
775  float iterPos[VERTEX_SIZE], targetPos[VERTEX_SIZE];
776  if (dtStatusFailed(_navMeshQuery->closestPointOnPolyBoundary(polys[0], startPos, iterPos)))
777  return DT_FAILURE;
778 
779  if (dtStatusFailed(_navMeshQuery->closestPointOnPolyBoundary(polys[npolys-1], endPos, targetPos)))
780  return DT_FAILURE;
781 
782  dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos);
783  nsmoothPath++;
784 
785  // Move towards target a small advancement at a time until target reached or
786  // when ran out of memory to store the path.
787  while (npolys && nsmoothPath < maxSmoothPathSize)
788  {
789  // Find location to steer towards.
790  float steerPos[VERTEX_SIZE];
791  unsigned char steerPosFlag;
792  dtPolyRef steerPosRef = INVALID_POLYREF;
793 
794  if (!GetSteerTarget(iterPos, targetPos, SMOOTH_PATH_SLOP, polys, npolys, steerPos, steerPosFlag, steerPosRef))
795  break;
796 
797  bool endOfPath = (steerPosFlag & DT_STRAIGHTPATH_END) != 0;
798  bool offMeshConnection = (steerPosFlag & DT_STRAIGHTPATH_OFFMESH_CONNECTION) != 0;
799 
800  // Find movement delta.
801  float delta[VERTEX_SIZE];
802  dtVsub(delta, steerPos, iterPos);
803  float len = dtMathSqrtf(dtVdot(delta, delta));
804  // If the steer target is end of path or off-mesh link, do not move past the location.
805  if ((endOfPath || offMeshConnection) && len < SMOOTH_PATH_STEP_SIZE)
806  len = 1.0f;
807  else
808  len = SMOOTH_PATH_STEP_SIZE / len;
809 
810  float moveTgt[VERTEX_SIZE];
811  dtVmad(moveTgt, iterPos, delta, len);
812 
813  // Move
814  float result[VERTEX_SIZE];
815  const static uint32 MAX_VISIT_POLY = 16;
816  dtPolyRef visited[MAX_VISIT_POLY];
817 
818  uint32 nvisited = 0;
819  _navMeshQuery->moveAlongSurface(polys[0], iterPos, moveTgt, &_filter, result, visited, (int*)&nvisited, MAX_VISIT_POLY);
820  npolys = FixupCorridor(polys, npolys, MAX_PATH_LENGTH, visited, nvisited);
821 
822  _navMeshQuery->getPolyHeight(polys[0], result, &result[1]);
823  result[1] += 0.5f;
824  dtVcopy(iterPos, result);
825 
826  // Handle end of path and off-mesh links when close enough.
827  if (endOfPath && InRangeYZX(iterPos, steerPos, SMOOTH_PATH_SLOP, 1.0f))
828  {
829  // Reached end of path.
830  dtVcopy(iterPos, targetPos);
831  if (nsmoothPath < maxSmoothPathSize)
832  {
833  dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos);
834  nsmoothPath++;
835  }
836  break;
837  }
838  else if (offMeshConnection && InRangeYZX(iterPos, steerPos, SMOOTH_PATH_SLOP, 1.0f))
839  {
840  // Advance the path up to and over the off-mesh connection.
841  dtPolyRef prevRef = INVALID_POLYREF;
842  dtPolyRef polyRef = polys[0];
843  uint32 npos = 0;
844  while (npos < npolys && polyRef != steerPosRef)
845  {
846  prevRef = polyRef;
847  polyRef = polys[npos];
848  npos++;
849  }
850 
851  for (uint32 i = npos; i < npolys; ++i)
852  polys[i-npos] = polys[i];
853 
854  npolys -= npos;
855 
856  // Handle the connection.
857  float connectionStartPos[VERTEX_SIZE], connectionEndPos[VERTEX_SIZE];
858  if (dtStatusSucceed(_navMesh->getOffMeshConnectionPolyEndPoints(prevRef, polyRef, connectionStartPos, connectionEndPos)))
859  {
860  if (nsmoothPath < maxSmoothPathSize)
861  {
862  dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], connectionStartPos);
863  nsmoothPath++;
864  }
865  // Move position at the other side of the off-mesh link.
866  dtVcopy(iterPos, connectionEndPos);
867  _navMeshQuery->getPolyHeight(polys[0], iterPos, &iterPos[1]);
868  iterPos[1] += 0.5f;
869  }
870  }
871 
872  // Store results.
873  if (nsmoothPath < maxSmoothPathSize)
874  {
875  dtVcopy(&smoothPath[nsmoothPath*VERTEX_SIZE], iterPos);
876  nsmoothPath++;
877  }
878  }
879 
880  *smoothPathSize = nsmoothPath;
881 
882  // this is most likely a loop
883  return nsmoothPath < MAX_POINT_PATH_LENGTH ? DT_SUCCESS : DT_FAILURE;
884 }
bool InRangeYZX(float const *v1, float const *v2, float r, float h) const
Definition: PathGenerator.cpp:886
uint64_d dtPolyRef
Definition: DetourNavMesh.h:49
void dtVmad(float *dest, const float *v1, const float *v2, const float s)
Definition: DetourCommon.h:105
dtStatus getOffMeshConnectionPolyEndPoints(dtPolyRef prevRef, dtPolyRef polyRef, float *startPos, float *endPos) const
Definition: DetourNavMesh.cpp:1372
dtNavMesh const * _navMesh
Definition: PathGenerator.h:95
static const unsigned int DT_SUCCESS
Definition: DetourStatus.h:26
dtStatus closestPointOnPolyBoundary(dtPolyRef ref, const float *pos, float *closest) const
Definition: DetourNavMeshQuery.cpp:601
The vertex is the end position in the path.
Definition: DetourNavMesh.h:111
#define INVALID_POLYREF
Definition: PathGenerator.h:39
float dtMathSqrtf(float x)
Definition: DetourMath.h:13
bool dtStatusSucceed(dtStatus status)
Definition: DetourStatus.h:41
uint32_t uint32
Definition: Define.h:150
bool dtStatusFailed(dtStatus status)
Definition: DetourStatus.h:47
dtQueryFilter _filter
Definition: PathGenerator.h:98
float dtVdot(const float *v1, const float *v2)
Definition: DetourCommon.h:95
dtStatus getPolyHeight(dtPolyRef ref, const float *pos, float *height) const
Definition: DetourNavMeshQuery.cpp:653
#define SMOOTH_PATH_SLOP
Definition: PathGenerator.h:36
void dtVcopy(float *dest, const float *a)
Definition: DetourCommon.h:190
uint32 FixupCorridor(dtPolyRef *path, uint32 npath, uint32 maxPath, dtPolyRef const *visited, uint32 nvisited)
Definition: PathGenerator.cpp:682
void dtVsub(float *dest, const float *v1, const float *v2)
Definition: DetourCommon.h:139
bool GetSteerTarget(float const *startPos, float const *endPos, float minTargetDist, dtPolyRef const *path, uint32 pathSize, float *steerPos, unsigned char &steerPosFlag, dtPolyRef &steerPosRef)
Definition: PathGenerator.cpp:727
dtNavMeshQuery const * _navMeshQuery
Definition: PathGenerator.h:96
#define VERTEX_SIZE
Definition: PathGenerator.h:38
#define MAX_PATH_LENGTH
Definition: PathGenerator.h:32
#define SMOOTH_PATH_STEP_SIZE
Definition: PathGenerator.h:35
The vertex is the start of an off-mesh connection.
Definition: DetourNavMesh.h:112
#define MAX_POINT_PATH_LENGTH
Definition: PathGenerator.h:33
dtStatus moveAlongSurface(dtPolyRef startRef, const float *startPos, const float *endPos, const dtQueryFilter *filter, float *resultPos, dtPolyRef *visited, int *visitedCount, const int maxVisitedSize) const
Definition: DetourNavMeshQuery.cpp:1948
static const unsigned int DT_FAILURE
Definition: DetourStatus.h:25

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

uint32 PathGenerator::FixupCorridor ( dtPolyRef path,
uint32  npath,
uint32  maxPath,
dtPolyRef const visited,
uint32  nvisited 
)
private
683 {
684  int32 furthestPath = -1;
685  int32 furthestVisited = -1;
686 
687  // Find furthest common polygon.
688  for (int32 i = npath-1; i >= 0; --i)
689  {
690  bool found = false;
691  for (int32 j = nvisited-1; j >= 0; --j)
692  {
693  if (path[i] == visited[j])
694  {
695  furthestPath = i;
696  furthestVisited = j;
697  found = true;
698  }
699  }
700  if (found)
701  break;
702  }
703 
704  // If no intersection found just return current path.
705  if (furthestPath == -1 || furthestVisited == -1)
706  return npath;
707 
708  // Concatenate paths.
709 
710  // Adjust beginning of the buffer to include the visited.
711  uint32 req = nvisited - furthestVisited;
712  uint32 orig = uint32(furthestPath + 1) < npath ? furthestPath + 1 : npath;
713  uint32 size = npath > orig ? npath - orig : 0;
714  if (req + size > maxPath)
715  size = maxPath-req;
716 
717  if (size)
718  memmove(path + req, path + orig, size * sizeof(dtPolyRef));
719 
720  // Store visited
721  for (uint32 i = 0; i < req; ++i)
722  path[i] = visited[(nvisited - 1) - i];
723 
724  return req+size;
725 }
uint64_d dtPolyRef
Definition: DetourNavMesh.h:49
int32_t int32
Definition: Define.h:146
uint32_t uint32
Definition: Define.h:150
uint32_t uint32
Definition: g3dmath.h:168

+ Here is the caller graph for this function:

G3D::Vector3 const& PathGenerator::GetActualEndPosition ( ) const
inline
69 { return _actualEndPosition; }
G3D::Vector3 _actualEndPosition
Definition: PathGenerator.h:92

+ Here is the caller graph for this function:

G3D::Vector3 const& PathGenerator::GetEndPosition ( ) const
inline
68 { return _endPosition; }
G3D::Vector3 _endPosition
Definition: PathGenerator.h:91

+ Here is the caller graph for this function:

NavTerrain PathGenerator::GetNavTerrain ( float  x,
float  y,
float  z 
)
private
646 {
647  LiquidData data;
648  ZLiquidStatus liquidStatus = _sourceUnit->GetBaseMap()->getLiquidStatus(x, y, z, MAP_ALL_LIQUIDS, &data);
649  if (liquidStatus == LIQUID_MAP_NO_WATER)
650  return NAV_GROUND;
651 
652  switch (data.type_flags)
653  {
656  return NAV_WATER;
658  return NAV_MAGMA;
660  return NAV_SLIME;
661  default:
662  return NAV_GROUND;
663  }
664 }
Definition: MapDefines.h:26
Definition: MapDefines.h:28
Definition: MapDefines.h:25
Definition: Map.h:151
Definition: MapDefines.h:27
Unit const *const _sourceUnit
Definition: PathGenerator.h:94
#define MAP_LIQUID_TYPE_WATER
Definition: Map.h:141
G3D::int16 z
Definition: Vector3int16.h:46
#define MAP_ALL_LIQUIDS
Definition: Map.h:146
G3D::int16 y
Definition: Vector2int16.h:38
ZLiquidStatus
Definition: Map.h:131
#define MAP_LIQUID_TYPE_MAGMA
Definition: Map.h:143
uint32 type_flags
Definition: Map.h:153
Map const * GetBaseMap() const
Definition: Object.cpp:2199
G3D::int16 x
Definition: Vector2int16.h:37
#define MAP_LIQUID_TYPE_SLIME
Definition: Map.h:144
ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData *data=nullptr) const
Definition: Map.cpp:2497
#define MAP_LIQUID_TYPE_OCEAN
Definition: Map.h:142
Definition: Map.h:133

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Movement::PointsArray const& PathGenerator::GetPath ( ) const
inline
71 { return _pathPoints; }
Movement::PointsArray _pathPoints
Definition: PathGenerator.h:82

+ Here is the caller graph for this function:

dtPolyRef PathGenerator::GetPathPolyByPosition ( dtPolyRef const polyPath,
uint32  polyPathSize,
float const Point,
float *  Distance = NULL 
) const
private
93 {
94  if (!polyPath || !polyPathSize)
95  return INVALID_POLYREF;
96 
97  dtPolyRef nearestPoly = INVALID_POLYREF;
98  float minDist2d = FLT_MAX;
99  float minDist3d = 0.0f;
100 
101  for (uint32 i = 0; i < polyPathSize; ++i)
102  {
103  float closestPoint[VERTEX_SIZE];
104  if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(polyPath[i], point, closestPoint, NULL)))
105  continue;
106 
107  float d = dtVdist2DSqr(point, closestPoint);
108  if (d < minDist2d)
109  {
110  minDist2d = d;
111  nearestPoly = polyPath[i];
112  minDist3d = dtVdistSqr(point, closestPoint);
113  }
114 
115  if (minDist2d < 1.0f) // shortcut out - close enough for us
116  break;
117  }
118 
119  if (distance)
120  *distance = dtMathSqrtf(minDist3d);
121 
122  return (minDist2d < 3.0f) ? nearestPoly : INVALID_POLYREF;
123 }
uint64_d dtPolyRef
Definition: DetourNavMesh.h:49
arena_t NULL
Definition: jemalloc_internal.h:624
double distance(double x, double y)
Definition: g3dmath.h:731
#define INVALID_POLYREF
Definition: PathGenerator.h:39
float dtMathSqrtf(float x)
Definition: DetourMath.h:13
uint32_t uint32
Definition: Define.h:150
bool dtStatusFailed(dtStatus status)
Definition: DetourStatus.h:47
float dtVdistSqr(const float *v1, const float *v2)
Definition: DetourCommon.h:229
dtNavMeshQuery const * _navMeshQuery
Definition: PathGenerator.h:96
#define VERTEX_SIZE
Definition: PathGenerator.h:38
float dtVdist2DSqr(const float *v1, const float *v2)
Definition: DetourCommon.h:254
dtStatus closestPointOnPoly(dtPolyRef ref, const float *pos, float *closest, bool *posOverPoly) const
Definition: DetourNavMeshQuery.cpp:505

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

PathType PathGenerator::GetPathType ( ) const
inline
73 { return _type; }
PathType _type
Definition: PathGenerator.h:83

+ Here is the caller graph for this function:

dtPolyRef PathGenerator::GetPolyByLocation ( float const Point,
float *  Distance 
) const
private
126 {
127  // first we check the current path
128  // if the current path doesn't contain the current poly,
129  // we need to use the expensive navMesh.findNearestPoly
131  if (polyRef != INVALID_POLYREF)
132  return polyRef;
133 
134  // we don't have it in our old path
135  // try to get it by findNearestPoly()
136  // first try with low search box
137  float extents[VERTEX_SIZE] = {3.0f, 5.0f, 3.0f}; // bounds of poly search area
138  float closestPoint[VERTEX_SIZE] = {0.0f, 0.0f, 0.0f};
139  if (dtStatusSucceed(_navMeshQuery->findNearestPoly(point, extents, &_filter, &polyRef, closestPoint)) && polyRef != INVALID_POLYREF)
140  {
141  *distance = dtVdist(closestPoint, point);
142  return polyRef;
143  }
144 
145  // still nothing ..
146  // try with bigger search box
147  // Note that the extent should not overlap more than 128 polygons in the navmesh (see dtNavMeshQuery::findNearestPoly)
148  extents[1] = 50.0f;
149 
150  if (dtStatusSucceed(_navMeshQuery->findNearestPoly(point, extents, &_filter, &polyRef, closestPoint)) && polyRef != INVALID_POLYREF)
151  {
152  *distance = dtVdist(closestPoint, point);
153  return polyRef;
154  }
155 
156  return INVALID_POLYREF;
157 }
uint32 _polyLength
Definition: PathGenerator.h:80
uint64_d dtPolyRef
Definition: DetourNavMesh.h:49
float dtVdist(const float *v1, const float *v2)
Definition: DetourCommon.h:217
dtPolyRef GetPathPolyByPosition(dtPolyRef const *polyPath, uint32 polyPathSize, float const *Point, float *Distance=NULL) const
Definition: PathGenerator.cpp:92
double distance(double x, double y)
Definition: g3dmath.h:731
#define INVALID_POLYREF
Definition: PathGenerator.h:39
bool dtStatusSucceed(dtStatus status)
Definition: DetourStatus.h:41
dtQueryFilter _filter
Definition: PathGenerator.h:98
dtStatus findNearestPoly(const float *center, const float *extents, const dtQueryFilter *filter, dtPolyRef *nearestRef, float *nearestPt) const
Definition: DetourNavMeshQuery.cpp:710
dtNavMeshQuery const * _navMeshQuery
Definition: PathGenerator.h:96
#define VERTEX_SIZE
Definition: PathGenerator.h:38
dtPolyRef _pathPolyRefs[MAX_PATH_LENGTH]
Definition: PathGenerator.h:79

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

G3D::Vector3 const& PathGenerator::GetStartPosition ( ) const
inline
67 { return _startPosition; }
G3D::Vector3 _startPosition
Definition: PathGenerator.h:90

+ Here is the caller graph for this function:

bool PathGenerator::GetSteerTarget ( float const startPos,
float const endPos,
float  minTargetDist,
dtPolyRef const path,
uint32  pathSize,
float *  steerPos,
unsigned char &  steerPosFlag,
dtPolyRef steerPosRef 
)
private
730 {
731  // Find steer target.
732  static const uint32 MAX_STEER_POINTS = 3;
733  float steerPath[MAX_STEER_POINTS*VERTEX_SIZE];
734  unsigned char steerPathFlags[MAX_STEER_POINTS];
735  dtPolyRef steerPathPolys[MAX_STEER_POINTS];
736  uint32 nsteerPath = 0;
737  dtStatus dtResult = _navMeshQuery->findStraightPath(startPos, endPos, path, pathSize,
738  steerPath, steerPathFlags, steerPathPolys, (int*)&nsteerPath, MAX_STEER_POINTS);
739  if (!nsteerPath || dtStatusFailed(dtResult))
740  return false;
741 
742  // Find vertex far enough to steer to.
743  uint32 ns = 0;
744  while (ns < nsteerPath)
745  {
746  // Stop at Off-Mesh link or when point is further than slop away.
747  if ((steerPathFlags[ns] & DT_STRAIGHTPATH_OFFMESH_CONNECTION) ||
748  !InRangeYZX(&steerPath[ns*VERTEX_SIZE], startPos, minTargetDist, 1000.0f))
749  break;
750  ns++;
751  }
752  // Failed to find good point to steer to.
753  if (ns >= nsteerPath)
754  return false;
755 
756  dtVcopy(steerPos, &steerPath[ns*VERTEX_SIZE]);
757  steerPos[1] = startPos[1]; // keep Z value
758  steerPosFlag = steerPathFlags[ns];
759  steerPosRef = steerPathPolys[ns];
760 
761  return true;
762 }
bool InRangeYZX(float const *v1, float const *v2, float r, float h) const
Definition: PathGenerator.cpp:886
uint64_d dtPolyRef
Definition: DetourNavMesh.h:49
dtStatus findStraightPath(const float *startPos, const float *endPos, const dtPolyRef *path, const int pathSize, float *straightPath, unsigned char *straightPathFlags, dtPolyRef *straightPathRefs, int *straightPathCount, const int maxStraightPath, const int options=0) const
Definition: DetourNavMeshQuery.cpp:1707
unsigned int dtStatus
Definition: DetourStatus.h:22
uint32_t uint32
Definition: Define.h:150
bool dtStatusFailed(dtStatus status)
Definition: DetourStatus.h:47
void dtVcopy(float *dest, const float *a)
Definition: DetourCommon.h:190
dtNavMeshQuery const * _navMeshQuery
Definition: PathGenerator.h:96
#define VERTEX_SIZE
Definition: PathGenerator.h:38
The vertex is the start of an off-mesh connection.
Definition: DetourNavMesh.h:112

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool PathGenerator::HaveTile ( G3D::Vector3 const p) const
private

Workaround For some reason, often the tx and ty variables wont get a valid value Use this check to prevent getting negative tile coords and crashing on getTileAt

667 {
668  int tx = -1, ty = -1;
669  float point[VERTEX_SIZE] = {p.y, p.z, p.x};
670 
671  _navMesh->calcTileLoc(point, &tx, &ty);
672 
676  if (tx < 0 || ty < 0)
677  return false;
678 
679  return (_navMesh->getTileAt(tx, ty, 0) != NULL);
680 }
dtNavMesh const * _navMesh
Definition: PathGenerator.h:95
arena_t NULL
Definition: jemalloc_internal.h:624
void calcTileLoc(const float *pos, int *tx, int *ty) const
Definition: DetourNavMesh.cpp:1107
#define VERTEX_SIZE
Definition: PathGenerator.h:38
const dtMeshTile * getTileAt(const int x, const int y, const int layer) const
Definition: DetourNavMesh.cpp:973

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool PathGenerator::InRange ( G3D::Vector3 const p1,
G3D::Vector3 const p2,
float  r,
float  h 
) const
private
895 {
896  G3D::Vector3 d = p1 - p2;
897  return (d.x * d.x + d.y * d.y) < r * r && fabsf(d.z) < h;
898 }
float x
Definition: Vector3.h:62
float y
Definition: Vector3.h:62
Definition: Vector3.h:58
float z
Definition: Vector3.h:62

+ Here is the caller graph for this function:

bool PathGenerator::InRangeYZX ( float const v1,
float const v2,
float  r,
float  h 
) const
private
887 {
888  const float dx = v2[0] - v1[0];
889  const float dy = v2[1] - v1[1]; // elevation
890  const float dz = v2[2] - v1[2];
891  return (dx * dx + dz * dz) < r * r && fabsf(dy) < h;
892 }

+ Here is the caller graph for this function:

void PathGenerator::NormalizePath ( )
private
580 {
581  for (uint32 i = 0; i < _pathPoints.size(); ++i)
583 }
void UpdateAllowedPositionZ(float x, float y, float &z) const
Definition: Object.cpp:1834
Unit const *const _sourceUnit
Definition: PathGenerator.h:94
uint32_t uint32
Definition: Define.h:150
Movement::PointsArray _pathPoints
Definition: PathGenerator.h:82

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void PathGenerator::ReducePathLenghtByDist ( float  dist)
906 {
907  if (GetPathType() == PATHFIND_BLANK)
908  {
909  TC_LOG_ERROR("maps", "PathGenerator::ReducePathLenghtByDist called before path was built");
910  return;
911  }
912 
913  if (_pathPoints.size() < 2) // path building failure
914  return;
915 
916  uint32 i = _pathPoints.size();
917  G3D::Vector3 nextVec = _pathPoints[--i];
918  while (i > 0)
919  {
920  G3D::Vector3 currVec = _pathPoints[--i];
921  G3D::Vector3 diffVec = (nextVec - currVec);
922  float len = diffVec.length();
923  if (len > dist)
924  {
925  float step = dist / len;
926  // same as nextVec
927  _pathPoints[i + 1] -= diffVec * step;
929  _pathPoints.resize(i + 2);
930  break;
931  }
932  else if (i == 0) // at second point
933  {
934  _pathPoints[1] = _pathPoints[0];
935  _pathPoints.resize(2);
936  break;
937  }
938 
939  dist -= len;
940  nextVec = currVec; // we're going backwards
941  }
942 }
void UpdateAllowedPositionZ(float x, float y, float &z) const
Definition: Object.cpp:1834
Unit const *const _sourceUnit
Definition: PathGenerator.h:94
float length() const
Definition: Vector3.h:751
Definition: Vector3.h:58
Definition: PathGenerator.h:43
G3D::int16 z
Definition: Vector3int16.h:46
uint32_t uint32
Definition: Define.h:150
Movement::PointsArray _pathPoints
Definition: PathGenerator.h:82
G3D::int16 y
Definition: Vector2int16.h:38
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:207
G3D::int16 x
Definition: Vector2int16.h:37
PathType GetPathType() const
Definition: PathGenerator.h:73

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void PathGenerator::SetActualEndPosition ( G3D::Vector3 const point)
inlineprivate
102 { _actualEndPosition = point; }
G3D::Vector3 _actualEndPosition
Definition: PathGenerator.h:92

+ Here is the caller graph for this function:

void PathGenerator::SetEndPosition ( G3D::Vector3 const point)
inlineprivate
101 { _actualEndPosition = point; _endPosition = point; }
G3D::Vector3 _actualEndPosition
Definition: PathGenerator.h:92
G3D::Vector3 _endPosition
Definition: PathGenerator.h:91

+ Here is the caller graph for this function:

void PathGenerator::SetPathLengthLimit ( float  distance)
inline
double distance(double x, double y)
Definition: g3dmath.h:731
uint32_t uint32
Definition: g3dmath.h:168
#define SMOOTH_PATH_STEP_SIZE
Definition: PathGenerator.h:35
#define MAX_POINT_PATH_LENGTH
Definition: PathGenerator.h:33
uint32 _pointPathLimit
Definition: PathGenerator.h:87

+ Here is the caller graph for this function:

void PathGenerator::SetStartPosition ( G3D::Vector3 const point)
inlineprivate
100 { _startPosition = point; }
G3D::Vector3 _startPosition
Definition: PathGenerator.h:90

+ Here is the caller graph for this function:

void PathGenerator::SetUseStraightPath ( bool  useStraightPath)
inline
63 { _useStraightPath = useStraightPath; }
bool _useStraightPath
Definition: PathGenerator.h:85

+ Here is the caller graph for this function:

void PathGenerator::UpdateFilter ( )
private
631 {
632  // allow creatures to cheat and use different movement types if they are moved
633  // forcefully into terrain they can't normally move in
635  {
636  uint16 includedFlags = _filter.getIncludeFlags();
637  includedFlags |= GetNavTerrain(_sourceUnit->GetPositionX(),
640 
641  _filter.setIncludeFlags(includedFlags);
642  }
643 }
void setIncludeFlags(const unsigned short flags)
Definition: DetourNavMeshQuery.h:107
Unit const *const _sourceUnit
Definition: PathGenerator.h:94
NavTerrain GetNavTerrain(float x, float y, float z)
Definition: PathGenerator.cpp:645
virtual bool IsUnderWater() const
Definition: Unit.cpp:2969
unsigned short getIncludeFlags() const
Definition: DetourNavMeshQuery.h:103
float GetPositionY() const
Definition: Position.h:105
float GetPositionZ() const
Definition: Position.h:106
uint16_t uint16
Definition: Define.h:151
dtQueryFilter _filter
Definition: PathGenerator.h:98
virtual bool IsInWater() const
Definition: Unit.cpp:2964
float GetPositionX() const
Definition: Position.h:104

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Member Data Documentation

G3D::Vector3 PathGenerator::_actualEndPosition
private
G3D::Vector3 PathGenerator::_endPosition
private
dtQueryFilter PathGenerator::_filter
private
bool PathGenerator::_forceDestination
private
dtNavMesh const* PathGenerator::_navMesh
private
dtNavMeshQuery const* PathGenerator::_navMeshQuery
private
Movement::PointsArray PathGenerator::_pathPoints
private
dtPolyRef PathGenerator::_pathPolyRefs[MAX_PATH_LENGTH]
private
uint32 PathGenerator::_pointPathLimit
private
uint32 PathGenerator::_polyLength
private
Unit const* const PathGenerator::_sourceUnit
private
G3D::Vector3 PathGenerator::_startPosition
private
bool PathGenerator::_straightLine
private
PathType PathGenerator::_type
private
bool PathGenerator::_useStraightPath
private

The documentation for this class was generated from the following files: