void NavMeshTesterTool::handleUpdate(const float /*dt*/) { if (m_toolMode == TOOLMODE_PATHFIND_SLICED) { if (dtStatusInProgress(m_pathFindStatus)) { m_pathFindStatus = m_navQuery->updateSlicedFindPath(1,0); } if (dtStatusSucceed(m_pathFindStatus)) { m_navQuery->finalizeSlicedFindPath(m_polys, &m_npolys, MAX_POLYS); m_nstraightPath = 0; if (m_npolys) { // In case of partial path, make sure the end point is clamped to the last polygon. float epos[3]; dtVcopy(epos, m_epos); if (m_polys[m_npolys-1] != m_endRef) m_navQuery->closestPointOnPoly(m_polys[m_npolys-1], m_epos, epos); m_navQuery->findStraightPath(m_spos, epos, m_polys, m_npolys, m_straightPath, m_straightPathFlags, m_straightPathPolys, &m_nstraightPath, MAX_POLYS); } m_pathFindStatus = DT_FAILURE; } } }
void dtPathQueue::update(const int maxIters) { static const int MAX_KEEP_ALIVE = 2; // in update ticks. // Update path request until there is nothing to update // or upto maxIters pathfinder iterations has been consumed. int iterCount = maxIters; for (int i = 0; i < MAX_QUEUE; ++i) { PathQuery& q = m_queue[m_queueHead % MAX_QUEUE]; // Skip inactive requests. if (q.ref == DT_PATHQ_INVALID) { m_queueHead++; continue; } // Handle completed request. if (dtStatusSucceed(q.status) || dtStatusFailed(q.status)) { // If the path result has not been read in few frames, free the slot. q.keepAlive++; if (q.keepAlive > MAX_KEEP_ALIVE) { q.ref = DT_PATHQ_INVALID; q.status = 0; } m_queueHead++; continue; } m_navquery->updateLinkFilter(q.linkFilter.Get()); // Handle query start. if (q.status == 0) { q.status = m_navquery->initSlicedFindPath(q.startRef, q.endRef, q.startPos, q.endPos, q.filter); } // Handle query in progress. if (dtStatusInProgress(q.status)) { int iters = 0; q.status = m_navquery->updateSlicedFindPath(iterCount, &iters); iterCount -= iters; } if (dtStatusSucceed(q.status)) { q.status = m_navquery->finalizeSlicedFindPath(q.path, &q.npath, m_maxPathSize); } if (iterCount <= 0) break; m_queueHead++; } }
void NavPath::processTick(const Move *move) { if(!mMesh) if(Sim::findObject(mMeshName.c_str(), mMesh)) plan(); if(dtStatusInProgress(mStatus)) update(); }
bool NavPath::update() { if(dtStatusInProgress(mStatus)) mStatus = mQuery->updateSlicedFindPath(mMaxIterations, NULL); if(dtStatusSucceed(mStatus)) { // Add points from this leg. dtPolyRef path[MaxPathLen]; S32 pathLen; mStatus = mQuery->finalizeSlicedFindPath(path, &pathLen, MaxPathLen); if(dtStatusSucceed(mStatus) && pathLen) { F32 straightPath[MaxPathLen * 3]; S32 straightPathLen; dtPolyRef straightPathPolys[MaxPathLen]; U8 straightPathFlags[MaxPathLen]; U32 s = mVisitPoints.size(); Point3F start = mVisitPoints[s-1]; Point3F end = mVisitPoints[s-2]; F32 from[] = {start.x, start.z, -start.y}; F32 to[] = {end.x, end.z, -end.y}; mQuery->findStraightPath(from, to, path, pathLen, straightPath, straightPathFlags, straightPathPolys, &straightPathLen, MaxPathLen); s = mPoints.size(); mPoints.increment(straightPathLen); mFlags.increment(straightPathLen); for(U32 i = 0; i < straightPathLen; i++) { F32 *f = straightPath + i * 3; mPoints[s + i] = RCtoDTS(f); mMesh->getNavMesh()->getPolyFlags(straightPathPolys[i], &mFlags[s + i]); // Add to length if(s > 0 || i > 0) mLength += (mPoints[s+i] - mPoints[s+i-1]).len(); } if(isServerObject()) setMaskBits(PathMask); } else return false; // Check to see where we still need to visit. if(mVisitPoints.size() > 1) { //Next leg of the journey. mVisitPoints.pop_back(); return visitNext(); } else { // Finished! return false; } } else if(dtStatusFailed(mStatus)) { // Something went wrong in planning. return false; } return true; }