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++;
	}
}
Esempio n. 3
0
void NavPath::processTick(const Move *move)
{
   if(!mMesh)
      if(Sim::findObject(mMeshName.c_str(), mMesh))
         plan();
   if(dtStatusInProgress(mStatus))
      update();
}
Esempio n. 4
0
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;
}