108
// This function checks if the path has a small U-turn, that is,
109
// a polygon further in the path is adjacent to the first polygon
110
// in the path. If that happens, a shortcut is taken.
111
// This can happen if the target (T) location is at tile boundary,
112
// and we're (S) approaching it parallel to the tile edge.
113
// The choice at the vertex can be arbitrary,
117
// |:::| | <-- the step can end up in here, resulting U-turn path.
119
static int fixupShortcuts(dtPolyRef* path, int npath, dtNavMeshQuery* navQuery)
124
// Get connected polygons
125
static const int maxNeis = 16;
126
dtPolyRef neis[maxNeis];
129
const dtMeshTile* tile = 0;
130
const dtPoly* poly = 0;
131
if (dtStatusFailed(navQuery->getAttachedNavMesh()->getTileAndPolyByRef(path[0], &tile, &poly)))
134
for (unsigned int k = poly->firstLink; k != DT_NULL_LINK; k = tile->links[k].next)
136
const dtLink* link = &tile->links[k];
140
neis[nneis++] = link->ref;
144
// If any of the neighbour polygons is within the next few polygons
145
// in the path, short cut to that polygon directly.
146
static const int maxLookAhead = 6;
148
for (int i = dtMin(maxLookAhead, npath) - 1; i > 1 && cut == 0; i--) {
149
for (int j = 0; j < nneis; j++)
151
if (path[i] == neis[j]) {
161
for (int i = 1; i < npath; i++)
162
path[i] = path[i+offset];
108
168
static bool getSteerTarget(dtNavMeshQuery* navQuery, const float* startPos, const float* endPos,
109
169
const float minTargetDist,
110
170
const dtPolyRef* path, const int pathSize,
450
510
if (m_pathIterPolyCount)
452
512
// Iterate over the path to find smooth path on the detail mesh surface.
453
m_navQuery->closestPointOnPoly(m_startRef, m_spos, m_iterPos);
454
m_navQuery->closestPointOnPoly(m_pathIterPolys[m_pathIterPolyCount-1], m_epos, m_targetPos);
513
m_navQuery->closestPointOnPoly(m_startRef, m_spos, m_iterPos, 0);
514
m_navQuery->closestPointOnPoly(m_pathIterPolys[m_pathIterPolyCount-1], m_epos, m_targetPos, 0);
456
516
m_nsmoothPath = 0;
507
567
m_navQuery->moveAlongSurface(m_pathIterPolys[0], m_iterPos, moveTgt, &m_filter,
508
568
result, visited, &nvisited, 16);
509
569
m_pathIterPolyCount = fixupCorridor(m_pathIterPolys, m_pathIterPolyCount, MAX_POLYS, visited, nvisited);
570
m_pathIterPolyCount = fixupShortcuts(m_pathIterPolys, m_pathIterPolyCount, m_navQuery);
511
573
m_navQuery->getPolyHeight(m_pathIterPolys[0], result, &h);
593
655
dtVcopy(epos, m_epos);
594
656
if (m_polys[m_npolys-1] != m_endRef)
595
m_navQuery->closestPointOnPoly(m_polys[m_npolys-1], m_epos, epos);
657
m_navQuery->closestPointOnPoly(m_polys[m_npolys-1], m_epos, epos, 0);
597
659
m_navQuery->findStraightPath(m_spos, epos, m_polys, m_npolys,
598
660
m_straightPath, m_straightPathFlags,
599
m_straightPathPolys, &m_nstraightPath, MAX_POLYS);
661
m_straightPathPolys, &m_nstraightPath, MAX_POLYS, DT_STRAIGHTPATH_ALL_CROSSINGS);
602
664
m_pathFindStatus = DT_FAILURE;
657
719
int npolys = m_npolys;
659
721
float iterPos[3], targetPos[3];
660
m_navQuery->closestPointOnPoly(m_startRef, m_spos, iterPos);
661
m_navQuery->closestPointOnPoly(polys[npolys-1], m_epos, targetPos);
722
m_navQuery->closestPointOnPoly(m_startRef, m_spos, iterPos, 0);
723
m_navQuery->closestPointOnPoly(polys[npolys-1], m_epos, targetPos, 0);
663
725
static const float STEP_SIZE = 0.5f;
664
726
static const float SLOP = 0.01f;
687
749
// Find movement delta.
688
750
float delta[3], len;
689
751
dtVsub(delta, steerPos, iterPos);
690
len = dtSqrt(dtVdot(delta,delta));
752
len = dtMathSqrtf(dtVdot(delta, delta));
691
753
// If the steer target is end of path or off-mesh link, do not move past the location.
692
754
if ((endOfPath || offMeshConnection) && len < STEP_SIZE)
702
764
int nvisited = 0;
703
765
m_navQuery->moveAlongSurface(polys[0], iterPos, moveTgt, &m_filter,
704
766
result, visited, &nvisited, 16);
706
768
npolys = fixupCorridor(polys, npolys, MAX_POLYS, visited, nvisited);
769
npolys = fixupShortcuts(polys, npolys, m_navQuery);
708
772
m_navQuery->getPolyHeight(polys[0], result, &h);
796
860
dtVcopy(epos, m_epos);
797
861
if (m_polys[m_npolys-1] != m_endRef)
798
m_navQuery->closestPointOnPoly(m_polys[m_npolys-1], m_epos, epos);
862
m_navQuery->closestPointOnPoly(m_polys[m_npolys-1], m_epos, epos, 0);
800
864
m_navQuery->findStraightPath(m_spos, epos, m_polys, m_npolys,
801
865
m_straightPath, m_straightPathFlags,
821
885
m_nstraightPath = 0;
823
m_pathFindStatus = m_navQuery->initSlicedFindPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter);
887
m_pathFindStatus = m_navQuery->initSlicedFindPath(m_startRef, m_endRef, m_spos, m_epos, &m_filter, DT_FINDPATH_ANY_ANGLE);
857
m_hitPos[0] = m_spos[0] + (m_epos[0] - m_spos[0]) * t;
858
m_hitPos[1] = m_spos[1] + (m_epos[1] - m_spos[1]) * t;
859
m_hitPos[2] = m_spos[2] + (m_epos[2] - m_spos[2]) * t;
863
m_navQuery->getPolyHeight(m_polys[m_npolys-1], m_hitPos, &h);
921
dtVlerp(m_hitPos, m_spos, m_epos, t);
866
922
m_hitResult = true;
928
m_navQuery->getPolyHeight(m_polys[m_npolys-1], m_hitPos, &h);
868
931
dtVcopy(&m_straightPath[3], m_hitPos);
1097
1160
dd.begin(DU_DRAW_POINTS, 6.0f);
1098
1161
for (int i = 0; i < m_nstraightPath; ++i)
1100
unsigned int col = 0;
1101
1164
if (m_straightPathFlags[i] & DT_STRAIGHTPATH_START)
1102
1165
col = startCol;
1103
else if (m_straightPathFlags[i] & DT_STRAIGHTPATH_START)
1166
else if (m_straightPathFlags[i] & DT_STRAIGHTPATH_END)
1105
1168
else if (m_straightPathFlags[i] & DT_STRAIGHTPATH_OFFMESH_CONNECTION)
1106
1169
col = offMeshCol;
1108
1171
col = spathCol;
1109
dd.vertex(m_straightPath[i*3], m_straightPath[i*3+1]+0.4f, m_straightPath[i*3+2], spathCol);
1172
dd.vertex(m_straightPath[i*3], m_straightPath[i*3+1]+0.4f, m_straightPath[i*3+2], col);
1112
1175
dd.depthMask(true);
1302
1365
for (int i = 0; i < m_nrandPoints; i++)
1304
1367
const float* p = &m_randPoints[i*3];
1305
dd.vertex(p[0],p[1]+0.1,p[2], duRGBA(220,32,16,192));
1368
dd.vertex(p[0],p[1]+0.1f,p[2], duRGBA(220,32,16,192));