diff --git a/DetourCrowd/Include/DetourCrowd.h b/DetourCrowd/Include/DetourCrowd.h index 9f92cdf..d265493 100644 --- a/DetourCrowd/Include/DetourCrowd.h +++ b/DetourCrowd/Include/DetourCrowd.h @@ -121,6 +121,9 @@ struct dtCrowdAgent /// The type of mesh polygon the agent is traversing. (See: #CrowdAgentState) unsigned char state; + /// True if the agent has valid path (targetState == DT_CROWDAGENT_TARGET_VALID) and the path does not lead to the requested position, else false. + bool partial; + /// The path corridor the agent is using. dtPathCorridor corridor; diff --git a/DetourCrowd/Source/DetourCrowd.cpp b/DetourCrowd/Source/DetourCrowd.cpp index 4297b65..35f8ebc 100644 --- a/DetourCrowd/Source/DetourCrowd.cpp +++ b/DetourCrowd/Source/DetourCrowd.cpp @@ -538,6 +538,7 @@ int dtCrowd::addAgent(const float* pos, const dtCrowdAgentParams* params) ag->corridor.reset(ref, nearest); ag->boundary.reset(); + ag->partial = false; updateAgentParameters(idx, params); @@ -746,6 +747,7 @@ void dtCrowd::updateMoveRequest(const float /*dt*/) ag->corridor.setCorridor(reqPos, reqPath, reqPathCount); ag->boundary.reset(); + ag->partial = false; if (reqPath[reqPathCount-1] == ag->targetRef) { @@ -819,7 +821,12 @@ void dtCrowd::updateMoveRequest(const float /*dt*/) status = m_pathq.getPathResult(ag->targetPathqRef, res, &nres, m_maxPathResult); if (dtStatusFailed(status) || !nres) valid = false; - + + if (dtStatusDetail(status, DT_PARTIAL_RESULT)) + ag->partial = true; + else + ag->partial = false; + // Merge result and existing path. // The agent might have moved whilst the request is // being processed, so the path may have changed. @@ -964,6 +971,7 @@ void dtCrowd::checkPathValidity(dtCrowdAgent** agents, const int nagents, const { // Could not find location in navmesh, set state to invalid. ag->corridor.reset(0, agentPos); + ag->partial = false; ag->boundary.reset(); ag->state = DT_CROWDAGENT_STATE_INVALID; continue; @@ -1000,6 +1008,7 @@ void dtCrowd::checkPathValidity(dtCrowdAgent** agents, const int nagents, const { // Failed to reposition target, fail moverequest. ag->corridor.reset(agentRef, agentPos); + ag->partial = false; ag->targetState = DT_CROWDAGENT_TARGET_NONE; } } @@ -1392,6 +1401,7 @@ void dtCrowd::update(const float dt, dtCrowdAgentDebugInfo* debug) if (ag->targetState == DT_CROWDAGENT_TARGET_NONE || ag->targetState == DT_CROWDAGENT_TARGET_VELOCITY) { ag->corridor.reset(ag->corridor.getFirstPoly(), ag->npos); + ag->partial = false; } } diff --git a/DetourCrowd/Source/DetourPathQueue.cpp b/DetourCrowd/Source/DetourPathQueue.cpp index de1862a..1ed0cd7 100644 --- a/DetourCrowd/Source/DetourPathQueue.cpp +++ b/DetourCrowd/Source/DetourPathQueue.cpp @@ -185,6 +185,7 @@ dtStatus dtPathQueue::getPathResult(dtPathQueueRef ref, dtPolyRef* path, int* pa if (m_queue[i].ref == ref) { PathQuery& q = m_queue[i]; + dtStatus details = q.status & DT_STATUS_DETAIL_MASK; // Free request for reuse. q.ref = DT_PATHQ_INVALID; q.status = 0; @@ -192,7 +193,7 @@ dtStatus dtPathQueue::getPathResult(dtPathQueueRef ref, dtPolyRef* path, int* pa int n = dtMin(q.npath, maxPath); memcpy(path, q.path, sizeof(dtPolyRef)*n); *pathSize = n; - return DT_SUCCESS; + return details | DT_SUCCESS; } } return DT_FAILURE;