I would like to submit a query filter for each agent type:

https://groups.google.com/forum/#!searchin/recastnavigation/dtQueryFilter|sort:relevance|spell:false/recastnavigation/t-rFg2Ku9IY/PJNNkCjARccJ

Search on
queryFilterType and m_filters to see the changes.

Also in this code there are bugfixes, that have already been submitted
as issues. They can be ignored.

Possible bug with requestMoveVelocity and navmesh regeneration
https://groups.google.com/forum/#!topic/recastnavigation/E6khmmKJkzk

Bug fix for No guard on dtCrowd::getAgent?
https://groups.google.com/forum/#!topic/recastnavigation/yJ1EEVbOaKg
This commit is contained in:
JimmyJames707 2014-04-11 16:50:57 +10:00
parent 740a7ba516
commit 0f2b03a8c0
2 changed files with 63 additions and 23 deletions

View File

@ -87,6 +87,9 @@ struct dtCrowdAgentParams
/// [Limits: 0 <= value <= #DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS]
unsigned char obstacleAvoidanceType;
// [F]
unsigned char queryFilterType;
/// User defined data attached to the agent.
void* userData;
};
@ -102,6 +105,9 @@ enum MoveRequestState
DT_CROWDAGENT_TARGET_VELOCITY,
};
// [F]
static const int DT_CROWD_MAX_QUERY_FILTER_TYPE = 16;
/// Represents an agent managed by a #dtCrowd object.
/// @ingroup crowd
struct dtCrowdAgent
@ -157,6 +163,9 @@ struct dtCrowdAgent
dtPathQueueRef targetPathqRef; ///< Path finder ref.
bool targetReplan; ///< Flag indicating that the current path is being replanned.
float targetReplanTime; /// <Time since the agent's target was replanned.
// [F]
unsigned char queryFilterType;
};
struct dtCrowdAgentAnimation
@ -190,6 +199,8 @@ struct dtCrowdAgentDebugInfo
/// @ingroup crowd
class dtCrowd
{
public:
int m_maxAgents;
dtCrowdAgent* m_agents;
dtCrowdAgent** m_activeAgents;
@ -206,7 +217,9 @@ class dtCrowd
int m_maxPathResult;
float m_ext[3];
dtQueryFilter m_filter;
//dtQueryFilter m_filter;
// [F]
dtQueryFilter m_filters[DT_CROWD_MAX_QUERY_FILTER_TYPE];
float m_maxAgentRadius;
@ -249,7 +262,7 @@ public:
/// Gets the specified agent from the pool.
/// @param[in] idx The agent index. [Limits: 0 <= value < #getAgentCount()]
/// @return The requested agent.
const dtCrowdAgent* getAgent(const int idx);
dtCrowdAgent* getAgent(const int idx);
/// The maximum number of agents that can be managed by the object.
/// @return The maximum number of agents.
@ -301,11 +314,17 @@ public:
/// Gets the filter used by the crowd.
/// @return The filter used by the crowd.
const dtQueryFilter* getFilter() const { return &m_filter; }
//const dtQueryFilter* getFilter() const { return &m_filter; }
// [F]
//const dtQueryFilter* getFilter() const {return &m_filters[0];}
const dtQueryFilter* getIndexedFilter(const int i = 0) const { return (i >= 0 && i < DT_CROWD_MAX_QUERY_FILTER_TYPE) ? &m_filters[i] : 0; }
/// Gets the filter used by the crowd.
/// @return The filter used by the crowd.
dtQueryFilter* getEditableFilter() { return &m_filter; }
//dtQueryFilter* getEditableFilter() { return &m_filter; }
// [F]
//dtQueryFilter* getEditableFilter() {return &m_filters[0];}
dtQueryFilter* getIndexedEditableFilter(const int i = 0) { return (i >= 0 && i < DT_CROWD_MAX_QUERY_FILTER_TYPE) ? &m_filters[i] : 0; }
/// Gets the search extents [(x, y, z)] used by the crowd for query operations.
/// @return The search extents used by the crowd. [(x, y, z)]

View File

@ -482,8 +482,10 @@ int dtCrowd::getAgentCount() const
/// @par
///
/// Agents in the pool may not be in use. Check #dtCrowdAgent.active before using the returned object.
const dtCrowdAgent* dtCrowd::getAgent(const int idx)
dtCrowdAgent* dtCrowd::getAgent(const int idx)
{
if (idx < 0 || idx >= m_maxAgents)
return 0;
return &m_agents[idx];
}
@ -514,11 +516,18 @@ int dtCrowd::addAgent(const float* pos, const dtCrowdAgentParams* params)
dtCrowdAgent* ag = &m_agents[idx];
// [F]
if (params->queryFilterType < DT_CROWD_MAX_QUERY_FILTER_TYPE)
ag->queryFilterType = params->queryFilterType;
else
ag->queryFilterType = 0;
// Find nearest position on navmesh and place the agent there.
float nearest[3];
dtPolyRef ref = 0;
dtVcopy(nearest, pos);
dtStatus status = m_navquery->findNearestPoly(pos, m_ext, &m_filter, &ref, nearest);
dtStatus status = m_navquery->findNearestPoly(pos, m_ext, &m_filters[ag->queryFilterType], &ref, nearest);
if (dtStatusFailed(status))
{
dtVcopy(nearest, pos);
@ -691,7 +700,7 @@ void dtCrowd::updateMoveRequest(const float /*dt*/)
// Quick seach towards the goal.
static const int MAX_ITER = 20;
m_navquery->initSlicedFindPath(path[0], ag->targetRef, ag->npos, ag->targetPos, &m_filter);
m_navquery->initSlicedFindPath(path[0], ag->targetRef, ag->npos, ag->targetPos, &m_filters[ag->queryFilterType]);
m_navquery->updateSlicedFindPath(MAX_ITER, 0);
dtStatus status = 0;
if (ag->targetReplan) // && npath > 10)
@ -758,7 +767,7 @@ void dtCrowd::updateMoveRequest(const float /*dt*/)
{
dtCrowdAgent* ag = queue[i];
ag->targetPathqRef = m_pathq.request(ag->corridor.getLastPoly(), ag->targetRef,
ag->corridor.getTarget(), ag->targetPos, &m_filter);
ag->corridor.getTarget(), ag->targetPos, &m_filters[ag->queryFilterType]);
if (ag->targetPathqRef != DT_PATHQ_INVALID)
ag->targetState = DT_CROWDAGENT_TARGET_WAITING_FOR_PATH;
}
@ -912,7 +921,7 @@ void dtCrowd::updateTopologyOptimization(dtCrowdAgent** agents, const int nagent
for (int i = 0; i < nqueue; ++i)
{
dtCrowdAgent* ag = queue[i];
ag->corridor.optimizePathTopology(m_navquery, &m_filter);
ag->corridor.optimizePathTopology(m_navquery, &m_filters[ag->queryFilterType]);
ag->topologyOptTime = 0;
}
@ -930,8 +939,9 @@ void dtCrowd::checkPathValidity(dtCrowdAgent** agents, const int nagents, const
if (ag->state != DT_CROWDAGENT_STATE_WALKING)
continue;
if (ag->targetState == DT_CROWDAGENT_TARGET_NONE || ag->targetState == DT_CROWDAGENT_TARGET_VELOCITY)
continue;
// BUG FIX: https://groups.google.com/forum/#!topic/recastnavigation/E6khmmKJkzk
//if (ag->targetState == DT_CROWDAGENT_TARGET_NONE || ag->targetState == DT_CROWDAGENT_TARGET_VELOCITY)
// continue;
ag->targetReplanTime += dt;
@ -942,14 +952,14 @@ void dtCrowd::checkPathValidity(dtCrowdAgent** agents, const int nagents, const
float agentPos[3];
dtPolyRef agentRef = ag->corridor.getFirstPoly();
dtVcopy(agentPos, ag->npos);
if (!m_navquery->isValidPolyRef(agentRef, &m_filter))
if (!m_navquery->isValidPolyRef(agentRef, &m_filters[ag->queryFilterType]))
{
// Current location is not valid, try to reposition.
// TODO: this can snap agents, how to handle that?
float nearest[3];
dtVcopy(nearest, agentPos);
agentRef = 0;
m_navquery->findNearestPoly(ag->npos, m_ext, &m_filter, &agentRef, nearest);
m_navquery->findNearestPoly(ag->npos, m_ext, &m_filters[ag->queryFilterType], &agentRef, nearest);
dtVcopy(agentPos, nearest);
if (!agentRef)
@ -971,16 +981,20 @@ void dtCrowd::checkPathValidity(dtCrowdAgent** agents, const int nagents, const
replan = true;
}
// Davo BUG FIX: https://groups.google.com/forum/#!topic/recastnavigation/E6khmmKJkzk
if (ag->targetState == DT_CROWDAGENT_TARGET_NONE || ag->targetState == DT_CROWDAGENT_TARGET_VELOCITY)
continue;
// Try to recover move request position.
if (ag->targetState != DT_CROWDAGENT_TARGET_NONE && ag->targetState != DT_CROWDAGENT_TARGET_FAILED)
{
if (!m_navquery->isValidPolyRef(ag->targetRef, &m_filter))
if (!m_navquery->isValidPolyRef(ag->targetRef, &m_filters[ag->queryFilterType]))
{
// Current target is not valid, try to reposition.
float nearest[3];
dtVcopy(nearest, ag->targetPos);
ag->targetRef = 0;
m_navquery->findNearestPoly(ag->targetPos, m_ext, &m_filter, &ag->targetRef, nearest);
m_navquery->findNearestPoly(ag->targetPos, m_ext, &m_filters[ag->queryFilterType], &ag->targetRef, nearest);
dtVcopy(ag->targetPos, nearest);
replan = true;
}
@ -993,7 +1007,7 @@ void dtCrowd::checkPathValidity(dtCrowdAgent** agents, const int nagents, const
}
// If nearby corridor is not valid, replan.
if (!ag->corridor.isValid(CHECK_LOOKAHEAD, m_navquery, &m_filter))
if (!ag->corridor.isValid(CHECK_LOOKAHEAD, m_navquery, &m_filters[ag->queryFilterType]))
{
// Fix current path.
// ag->corridor.trimInvalidPath(agentRef, agentPos, m_navquery, &m_filter);
@ -1030,6 +1044,13 @@ void dtCrowd::update(const float dt, dtCrowdAgentDebugInfo* debug)
dtCrowdAgent** agents = m_activeAgents;
int nagents = getActiveAgents(agents, m_maxAgents);
// [F]
for (int i = 0; i < nagents; ++i)
{
dtCrowdAgent* ag = agents[i];
ag->queryFilterType = ag->params.queryFilterType;
}
// Check that all agents still have valid paths.
checkPathValidity(agents, nagents, dt);
@ -1060,10 +1081,10 @@ void dtCrowd::update(const float dt, dtCrowdAgentDebugInfo* debug)
// if it has become invalid.
const float updateThr = ag->params.collisionQueryRange*0.25f;
if (dtVdist2DSqr(ag->npos, ag->boundary.getCenter()) > dtSqr(updateThr) ||
!ag->boundary.isValid(m_navquery, &m_filter))
!ag->boundary.isValid(m_navquery, &m_filters[ag->queryFilterType]))
{
ag->boundary.update(ag->corridor.getFirstPoly(), ag->npos, ag->params.collisionQueryRange,
m_navquery, &m_filter);
m_navquery, &m_filters[ag->queryFilterType]);
}
// Query neighbour agents
ag->nneis = getNeighbours(ag->npos, ag->params.height, ag->params.collisionQueryRange,
@ -1085,14 +1106,14 @@ void dtCrowd::update(const float dt, dtCrowdAgentDebugInfo* debug)
// Find corners for steering
ag->ncorners = ag->corridor.findCorners(ag->cornerVerts, ag->cornerFlags, ag->cornerPolys,
DT_CROWDAGENT_MAX_CORNERS, m_navquery, &m_filter);
DT_CROWDAGENT_MAX_CORNERS, m_navquery, &m_filters[ag->queryFilterType]);
// Check to see if the corner after the next corner is directly visible,
// and short cut to there.
if ((ag->params.updateFlags & DT_CROWD_OPTIMIZE_VIS) && ag->ncorners > 0)
{
const float* target = &ag->cornerVerts[dtMin(1,ag->ncorners-1)*3];
ag->corridor.optimizePathVisibility(target, ag->params.pathOptimizationRange, m_navquery, &m_filter);
ag->corridor.optimizePathVisibility(target, ag->params.pathOptimizationRange, m_navquery, &m_filters[ag->queryFilterType]);
// Copy data for debug purposes.
if (debugIdx == i)
@ -1264,7 +1285,7 @@ void dtCrowd::update(const float dt, dtCrowdAgentDebugInfo* debug)
if (debugIdx == i)
vod = debug->vod;
// Sample new safe velocity.
// MySample new safe velocity.
bool adaptive = true;
int ns = 0;
@ -1372,7 +1393,7 @@ void dtCrowd::update(const float dt, dtCrowdAgentDebugInfo* debug)
continue;
// Move along navmesh.
ag->corridor.movePosition(ag->npos, m_navquery, &m_filter);
ag->corridor.movePosition(ag->npos, m_navquery, &m_filters[ag->queryFilterType]);
// Get valid constrained position back.
dtVcopy(ag->npos, ag->corridor.getPos());