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:
parent
740a7ba516
commit
0f2b03a8c0
@ -87,6 +87,9 @@ struct dtCrowdAgentParams
|
|||||||
/// [Limits: 0 <= value <= #DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS]
|
/// [Limits: 0 <= value <= #DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS]
|
||||||
unsigned char obstacleAvoidanceType;
|
unsigned char obstacleAvoidanceType;
|
||||||
|
|
||||||
|
// [F]
|
||||||
|
unsigned char queryFilterType;
|
||||||
|
|
||||||
/// User defined data attached to the agent.
|
/// User defined data attached to the agent.
|
||||||
void* userData;
|
void* userData;
|
||||||
};
|
};
|
||||||
@ -102,6 +105,9 @@ enum MoveRequestState
|
|||||||
DT_CROWDAGENT_TARGET_VELOCITY,
|
DT_CROWDAGENT_TARGET_VELOCITY,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// [F]
|
||||||
|
static const int DT_CROWD_MAX_QUERY_FILTER_TYPE = 16;
|
||||||
|
|
||||||
/// Represents an agent managed by a #dtCrowd object.
|
/// Represents an agent managed by a #dtCrowd object.
|
||||||
/// @ingroup crowd
|
/// @ingroup crowd
|
||||||
struct dtCrowdAgent
|
struct dtCrowdAgent
|
||||||
@ -157,6 +163,9 @@ struct dtCrowdAgent
|
|||||||
dtPathQueueRef targetPathqRef; ///< Path finder ref.
|
dtPathQueueRef targetPathqRef; ///< Path finder ref.
|
||||||
bool targetReplan; ///< Flag indicating that the current path is being replanned.
|
bool targetReplan; ///< Flag indicating that the current path is being replanned.
|
||||||
float targetReplanTime; /// <Time since the agent's target was replanned.
|
float targetReplanTime; /// <Time since the agent's target was replanned.
|
||||||
|
|
||||||
|
// [F]
|
||||||
|
unsigned char queryFilterType;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dtCrowdAgentAnimation
|
struct dtCrowdAgentAnimation
|
||||||
@ -190,6 +199,8 @@ struct dtCrowdAgentDebugInfo
|
|||||||
/// @ingroup crowd
|
/// @ingroup crowd
|
||||||
class dtCrowd
|
class dtCrowd
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
int m_maxAgents;
|
int m_maxAgents;
|
||||||
dtCrowdAgent* m_agents;
|
dtCrowdAgent* m_agents;
|
||||||
dtCrowdAgent** m_activeAgents;
|
dtCrowdAgent** m_activeAgents;
|
||||||
@ -206,7 +217,9 @@ class dtCrowd
|
|||||||
int m_maxPathResult;
|
int m_maxPathResult;
|
||||||
|
|
||||||
float m_ext[3];
|
float m_ext[3];
|
||||||
dtQueryFilter m_filter;
|
//dtQueryFilter m_filter;
|
||||||
|
// [F]
|
||||||
|
dtQueryFilter m_filters[DT_CROWD_MAX_QUERY_FILTER_TYPE];
|
||||||
|
|
||||||
float m_maxAgentRadius;
|
float m_maxAgentRadius;
|
||||||
|
|
||||||
@ -249,7 +262,7 @@ public:
|
|||||||
/// Gets the specified agent from the pool.
|
/// Gets the specified agent from the pool.
|
||||||
/// @param[in] idx The agent index. [Limits: 0 <= value < #getAgentCount()]
|
/// @param[in] idx The agent index. [Limits: 0 <= value < #getAgentCount()]
|
||||||
/// @return The requested agent.
|
/// @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.
|
/// The maximum number of agents that can be managed by the object.
|
||||||
/// @return The maximum number of agents.
|
/// @return The maximum number of agents.
|
||||||
@ -301,11 +314,17 @@ public:
|
|||||||
|
|
||||||
/// Gets the filter used by the crowd.
|
/// Gets the filter used by the crowd.
|
||||||
/// @return 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.
|
/// Gets the filter used by the crowd.
|
||||||
/// @return 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.
|
/// 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)]
|
/// @return The search extents used by the crowd. [(x, y, z)]
|
||||||
|
@ -482,8 +482,10 @@ int dtCrowd::getAgentCount() const
|
|||||||
/// @par
|
/// @par
|
||||||
///
|
///
|
||||||
/// Agents in the pool may not be in use. Check #dtCrowdAgent.active before using the returned object.
|
/// 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];
|
return &m_agents[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -514,11 +516,18 @@ int dtCrowd::addAgent(const float* pos, const dtCrowdAgentParams* params)
|
|||||||
|
|
||||||
dtCrowdAgent* ag = &m_agents[idx];
|
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.
|
// Find nearest position on navmesh and place the agent there.
|
||||||
float nearest[3];
|
float nearest[3];
|
||||||
dtPolyRef ref = 0;
|
dtPolyRef ref = 0;
|
||||||
dtVcopy(nearest, pos);
|
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))
|
if (dtStatusFailed(status))
|
||||||
{
|
{
|
||||||
dtVcopy(nearest, pos);
|
dtVcopy(nearest, pos);
|
||||||
@ -691,7 +700,7 @@ void dtCrowd::updateMoveRequest(const float /*dt*/)
|
|||||||
|
|
||||||
// Quick seach towards the goal.
|
// Quick seach towards the goal.
|
||||||
static const int MAX_ITER = 20;
|
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);
|
m_navquery->updateSlicedFindPath(MAX_ITER, 0);
|
||||||
dtStatus status = 0;
|
dtStatus status = 0;
|
||||||
if (ag->targetReplan) // && npath > 10)
|
if (ag->targetReplan) // && npath > 10)
|
||||||
@ -758,7 +767,7 @@ void dtCrowd::updateMoveRequest(const float /*dt*/)
|
|||||||
{
|
{
|
||||||
dtCrowdAgent* ag = queue[i];
|
dtCrowdAgent* ag = queue[i];
|
||||||
ag->targetPathqRef = m_pathq.request(ag->corridor.getLastPoly(), ag->targetRef,
|
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)
|
if (ag->targetPathqRef != DT_PATHQ_INVALID)
|
||||||
ag->targetState = DT_CROWDAGENT_TARGET_WAITING_FOR_PATH;
|
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)
|
for (int i = 0; i < nqueue; ++i)
|
||||||
{
|
{
|
||||||
dtCrowdAgent* ag = queue[i];
|
dtCrowdAgent* ag = queue[i];
|
||||||
ag->corridor.optimizePathTopology(m_navquery, &m_filter);
|
ag->corridor.optimizePathTopology(m_navquery, &m_filters[ag->queryFilterType]);
|
||||||
ag->topologyOptTime = 0;
|
ag->topologyOptTime = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -930,8 +939,9 @@ void dtCrowd::checkPathValidity(dtCrowdAgent** agents, const int nagents, const
|
|||||||
if (ag->state != DT_CROWDAGENT_STATE_WALKING)
|
if (ag->state != DT_CROWDAGENT_STATE_WALKING)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ag->targetState == DT_CROWDAGENT_TARGET_NONE || ag->targetState == DT_CROWDAGENT_TARGET_VELOCITY)
|
// BUG FIX: https://groups.google.com/forum/#!topic/recastnavigation/E6khmmKJkzk
|
||||||
continue;
|
//if (ag->targetState == DT_CROWDAGENT_TARGET_NONE || ag->targetState == DT_CROWDAGENT_TARGET_VELOCITY)
|
||||||
|
// continue;
|
||||||
|
|
||||||
ag->targetReplanTime += dt;
|
ag->targetReplanTime += dt;
|
||||||
|
|
||||||
@ -942,14 +952,14 @@ void dtCrowd::checkPathValidity(dtCrowdAgent** agents, const int nagents, const
|
|||||||
float agentPos[3];
|
float agentPos[3];
|
||||||
dtPolyRef agentRef = ag->corridor.getFirstPoly();
|
dtPolyRef agentRef = ag->corridor.getFirstPoly();
|
||||||
dtVcopy(agentPos, ag->npos);
|
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.
|
// Current location is not valid, try to reposition.
|
||||||
// TODO: this can snap agents, how to handle that?
|
// TODO: this can snap agents, how to handle that?
|
||||||
float nearest[3];
|
float nearest[3];
|
||||||
dtVcopy(nearest, agentPos);
|
dtVcopy(nearest, agentPos);
|
||||||
agentRef = 0;
|
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);
|
dtVcopy(agentPos, nearest);
|
||||||
|
|
||||||
if (!agentRef)
|
if (!agentRef)
|
||||||
@ -971,16 +981,20 @@ void dtCrowd::checkPathValidity(dtCrowdAgent** agents, const int nagents, const
|
|||||||
replan = true;
|
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.
|
// Try to recover move request position.
|
||||||
if (ag->targetState != DT_CROWDAGENT_TARGET_NONE && ag->targetState != DT_CROWDAGENT_TARGET_FAILED)
|
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.
|
// Current target is not valid, try to reposition.
|
||||||
float nearest[3];
|
float nearest[3];
|
||||||
dtVcopy(nearest, ag->targetPos);
|
dtVcopy(nearest, ag->targetPos);
|
||||||
ag->targetRef = 0;
|
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);
|
dtVcopy(ag->targetPos, nearest);
|
||||||
replan = true;
|
replan = true;
|
||||||
}
|
}
|
||||||
@ -993,7 +1007,7 @@ void dtCrowd::checkPathValidity(dtCrowdAgent** agents, const int nagents, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If nearby corridor is not valid, replan.
|
// 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.
|
// Fix current path.
|
||||||
// ag->corridor.trimInvalidPath(agentRef, agentPos, m_navquery, &m_filter);
|
// 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;
|
dtCrowdAgent** agents = m_activeAgents;
|
||||||
int nagents = getActiveAgents(agents, m_maxAgents);
|
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.
|
// Check that all agents still have valid paths.
|
||||||
checkPathValidity(agents, nagents, dt);
|
checkPathValidity(agents, nagents, dt);
|
||||||
|
|
||||||
@ -1060,10 +1081,10 @@ void dtCrowd::update(const float dt, dtCrowdAgentDebugInfo* debug)
|
|||||||
// if it has become invalid.
|
// if it has become invalid.
|
||||||
const float updateThr = ag->params.collisionQueryRange*0.25f;
|
const float updateThr = ag->params.collisionQueryRange*0.25f;
|
||||||
if (dtVdist2DSqr(ag->npos, ag->boundary.getCenter()) > dtSqr(updateThr) ||
|
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,
|
ag->boundary.update(ag->corridor.getFirstPoly(), ag->npos, ag->params.collisionQueryRange,
|
||||||
m_navquery, &m_filter);
|
m_navquery, &m_filters[ag->queryFilterType]);
|
||||||
}
|
}
|
||||||
// Query neighbour agents
|
// Query neighbour agents
|
||||||
ag->nneis = getNeighbours(ag->npos, ag->params.height, ag->params.collisionQueryRange,
|
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
|
// Find corners for steering
|
||||||
ag->ncorners = ag->corridor.findCorners(ag->cornerVerts, ag->cornerFlags, ag->cornerPolys,
|
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,
|
// Check to see if the corner after the next corner is directly visible,
|
||||||
// and short cut to there.
|
// and short cut to there.
|
||||||
if ((ag->params.updateFlags & DT_CROWD_OPTIMIZE_VIS) && ag->ncorners > 0)
|
if ((ag->params.updateFlags & DT_CROWD_OPTIMIZE_VIS) && ag->ncorners > 0)
|
||||||
{
|
{
|
||||||
const float* target = &ag->cornerVerts[dtMin(1,ag->ncorners-1)*3];
|
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.
|
// Copy data for debug purposes.
|
||||||
if (debugIdx == i)
|
if (debugIdx == i)
|
||||||
@ -1264,7 +1285,7 @@ void dtCrowd::update(const float dt, dtCrowdAgentDebugInfo* debug)
|
|||||||
if (debugIdx == i)
|
if (debugIdx == i)
|
||||||
vod = debug->vod;
|
vod = debug->vod;
|
||||||
|
|
||||||
// Sample new safe velocity.
|
// MySample new safe velocity.
|
||||||
bool adaptive = true;
|
bool adaptive = true;
|
||||||
int ns = 0;
|
int ns = 0;
|
||||||
|
|
||||||
@ -1372,7 +1393,7 @@ void dtCrowd::update(const float dt, dtCrowdAgentDebugInfo* debug)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Move along navmesh.
|
// 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.
|
// Get valid constrained position back.
|
||||||
dtVcopy(ag->npos, ag->corridor.getPos());
|
dtVcopy(ag->npos, ag->corridor.getPos());
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user