forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			461 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			461 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Copyright (c) 2009-2010 Mikko Mononen memon@inside.org
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// This software is provided 'as-is', without any express or implied
							 | 
						||
| 
								 | 
							
								// warranty.  In no event will the authors be held liable for any damages
							 | 
						||
| 
								 | 
							
								// arising from the use of this software.
							 | 
						||
| 
								 | 
							
								// Permission is granted to anyone to use this software for any purpose,
							 | 
						||
| 
								 | 
							
								// including commercial applications, and to alter it and redistribute it
							 | 
						||
| 
								 | 
							
								// freely, subject to the following restrictions:
							 | 
						||
| 
								 | 
							
								// 1. The origin of this software must not be misrepresented; you must not
							 | 
						||
| 
								 | 
							
								//    claim that you wrote the original software. If you use this software
							 | 
						||
| 
								 | 
							
								//    in a product, an acknowledgment in the product documentation would be
							 | 
						||
| 
								 | 
							
								//    appreciated but is not required.
							 | 
						||
| 
								 | 
							
								// 2. Altered source versions must be plainly marked as such, and must not be
							 | 
						||
| 
								 | 
							
								//    misrepresented as being the original software.
							 | 
						||
| 
								 | 
							
								// 3. This notice may not be removed or altered from any source distribution.
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef DETOURCROWD_H
							 | 
						||
| 
								 | 
							
								#define DETOURCROWD_H
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "DetourNavMeshQuery.h"
							 | 
						||
| 
								 | 
							
								#include "DetourObstacleAvoidance.h"
							 | 
						||
| 
								 | 
							
								#include "DetourLocalBoundary.h"
							 | 
						||
| 
								 | 
							
								#include "DetourPathCorridor.h"
							 | 
						||
| 
								 | 
							
								#include "DetourProximityGrid.h"
							 | 
						||
| 
								 | 
							
								#include "DetourPathQueue.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// The maximum number of neighbors that a crowd agent can take into account
							 | 
						||
| 
								 | 
							
								/// for steering decisions.
							 | 
						||
| 
								 | 
							
								/// @ingroup crowd
							 | 
						||
| 
								 | 
							
								static const int DT_CROWDAGENT_MAX_NEIGHBOURS = 6;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// The maximum number of corners a crowd agent will look ahead in the path.
							 | 
						||
| 
								 | 
							
								/// This value is used for sizing the crowd agent corner buffers.
							 | 
						||
| 
								 | 
							
								/// Due to the behavior of the crowd manager, the actual number of useful
							 | 
						||
| 
								 | 
							
								/// corners will be one less than this number.
							 | 
						||
| 
								 | 
							
								/// @ingroup crowd
							 | 
						||
| 
								 | 
							
								static const int DT_CROWDAGENT_MAX_CORNERS = 4;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// The maximum number of crowd avoidance configurations supported by the
							 | 
						||
| 
								 | 
							
								/// crowd manager.
							 | 
						||
| 
								 | 
							
								/// @ingroup crowd
							 | 
						||
| 
								 | 
							
								/// @see dtObstacleAvoidanceParams, dtCrowd::setObstacleAvoidanceParams(), dtCrowd::getObstacleAvoidanceParams(),
							 | 
						||
| 
								 | 
							
								///		 dtCrowdAgentParams::obstacleAvoidanceType
							 | 
						||
| 
								 | 
							
								static const int DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS = 8;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// The maximum number of query filter types supported by the crowd manager.
							 | 
						||
| 
								 | 
							
								/// @ingroup crowd
							 | 
						||
| 
								 | 
							
								/// @see dtQueryFilter, dtCrowd::getFilter() dtCrowd::getEditableFilter(),
							 | 
						||
| 
								 | 
							
								///		dtCrowdAgentParams::queryFilterType
							 | 
						||
| 
								 | 
							
								static const int DT_CROWD_MAX_QUERY_FILTER_TYPE = 16;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// Provides neighbor data for agents managed by the crowd.
							 | 
						||
| 
								 | 
							
								/// @ingroup crowd
							 | 
						||
| 
								 | 
							
								/// @see dtCrowdAgent::neis, dtCrowd
							 | 
						||
| 
								 | 
							
								struct dtCrowdNeighbour
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int idx;		///< The index of the neighbor in the crowd.
							 | 
						||
| 
								 | 
							
									float dist;		///< The distance between the current agent and the neighbor.
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// The type of navigation mesh polygon the agent is currently traversing.
							 | 
						||
| 
								 | 
							
								/// @ingroup crowd
							 | 
						||
| 
								 | 
							
								enum CrowdAgentState
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									DT_CROWDAGENT_STATE_INVALID,		///< The agent is not in a valid state.
							 | 
						||
| 
								 | 
							
									DT_CROWDAGENT_STATE_WALKING,		///< The agent is traversing a normal navigation mesh polygon.
							 | 
						||
| 
								 | 
							
									DT_CROWDAGENT_STATE_OFFMESH,		///< The agent is traversing an off-mesh connection.
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// Configuration parameters for a crowd agent.
							 | 
						||
| 
								 | 
							
								/// @ingroup crowd
							 | 
						||
| 
								 | 
							
								struct dtCrowdAgentParams
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									float radius;						///< Agent radius. [Limit: >= 0]
							 | 
						||
| 
								 | 
							
									float height;						///< Agent height. [Limit: > 0]
							 | 
						||
| 
								 | 
							
									float maxAcceleration;				///< Maximum allowed acceleration. [Limit: >= 0]
							 | 
						||
| 
								 | 
							
									float maxSpeed;						///< Maximum allowed speed. [Limit: >= 0]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// Defines how close a collision element must be before it is considered for steering behaviors. [Limits: > 0]
							 | 
						||
| 
								 | 
							
									float collisionQueryRange;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									float pathOptimizationRange;		///< The path visibility optimization range. [Limit: > 0]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// How aggresive the agent manager should be at avoiding collisions with this agent. [Limit: >= 0]
							 | 
						||
| 
								 | 
							
									float separationWeight;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// Flags that impact steering behavior. (See: #UpdateFlags)
							 | 
						||
| 
								 | 
							
									unsigned char updateFlags;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// The index of the avoidance configuration to use for the agent. 
							 | 
						||
| 
								 | 
							
									/// [Limits: 0 <= value <= #DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS]
							 | 
						||
| 
								 | 
							
									unsigned char obstacleAvoidanceType;	
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// The index of the query filter used by this agent.
							 | 
						||
| 
								 | 
							
									unsigned char queryFilterType;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// User defined data attached to the agent.
							 | 
						||
| 
								 | 
							
									void* userData;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								enum MoveRequestState
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									DT_CROWDAGENT_TARGET_NONE = 0,
							 | 
						||
| 
								 | 
							
									DT_CROWDAGENT_TARGET_FAILED,
							 | 
						||
| 
								 | 
							
									DT_CROWDAGENT_TARGET_VALID,
							 | 
						||
| 
								 | 
							
									DT_CROWDAGENT_TARGET_REQUESTING,
							 | 
						||
| 
								 | 
							
									DT_CROWDAGENT_TARGET_WAITING_FOR_QUEUE,
							 | 
						||
| 
								 | 
							
									DT_CROWDAGENT_TARGET_WAITING_FOR_PATH,
							 | 
						||
| 
								 | 
							
									DT_CROWDAGENT_TARGET_VELOCITY,
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// Represents an agent managed by a #dtCrowd object.
							 | 
						||
| 
								 | 
							
								/// @ingroup crowd
							 | 
						||
| 
								 | 
							
								struct dtCrowdAgent
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									/// True if the agent is active, false if the agent is in an unused slot in the agent pool.
							 | 
						||
| 
								 | 
							
									bool active;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// 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;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// The local boundary data for the agent.
							 | 
						||
| 
								 | 
							
									dtLocalBoundary boundary;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/// Time since the agent's path corridor was optimized.
							 | 
						||
| 
								 | 
							
									float topologyOptTime;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/// The known neighbors of the agent.
							 | 
						||
| 
								 | 
							
									dtCrowdNeighbour neis[DT_CROWDAGENT_MAX_NEIGHBOURS];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// The number of neighbors.
							 | 
						||
| 
								 | 
							
									int nneis;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/// The desired speed.
							 | 
						||
| 
								 | 
							
									float desiredSpeed;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									float npos[3];		///< The current agent position. [(x, y, z)]
							 | 
						||
| 
								 | 
							
									float disp[3];		///< A temporary value used to accumulate agent displacement during iterative collision resolution. [(x, y, z)]
							 | 
						||
| 
								 | 
							
									float dvel[3];		///< The desired velocity of the agent. Based on the current path, calculated from scratch each frame. [(x, y, z)]
							 | 
						||
| 
								 | 
							
									float nvel[3];		///< The desired velocity adjusted by obstacle avoidance, calculated from scratch each frame. [(x, y, z)]
							 | 
						||
| 
								 | 
							
									float vel[3];		///< The actual velocity of the agent. The change from nvel -> vel is constrained by max acceleration. [(x, y, z)]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// The agent's configuration parameters.
							 | 
						||
| 
								 | 
							
									dtCrowdAgentParams params;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// The local path corridor corners for the agent. (Staight path.) [(x, y, z) * #ncorners]
							 | 
						||
| 
								 | 
							
									float cornerVerts[DT_CROWDAGENT_MAX_CORNERS*3];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// The local path corridor corner flags. (See: #dtStraightPathFlags) [(flags) * #ncorners]
							 | 
						||
| 
								 | 
							
									unsigned char cornerFlags[DT_CROWDAGENT_MAX_CORNERS];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// The reference id of the polygon being entered at the corner. [(polyRef) * #ncorners]
							 | 
						||
| 
								 | 
							
									dtPolyRef cornerPolys[DT_CROWDAGENT_MAX_CORNERS];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// The number of corners.
							 | 
						||
| 
								 | 
							
									int ncorners;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									unsigned char targetState;			///< State of the movement request.
							 | 
						||
| 
								 | 
							
									dtPolyRef targetRef;				///< Target polyref of the movement request.
							 | 
						||
| 
								 | 
							
									float targetPos[3];					///< Target position of the movement request (or velocity in case of DT_CROWDAGENT_TARGET_VELOCITY).
							 | 
						||
| 
								 | 
							
									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.
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct dtCrowdAgentAnimation
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									bool active;
							 | 
						||
| 
								 | 
							
									float initPos[3], startPos[3], endPos[3];
							 | 
						||
| 
								 | 
							
									dtPolyRef polyRef;
							 | 
						||
| 
								 | 
							
									float t, tmax;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// Crowd agent update flags.
							 | 
						||
| 
								 | 
							
								/// @ingroup crowd
							 | 
						||
| 
								 | 
							
								/// @see dtCrowdAgentParams::updateFlags
							 | 
						||
| 
								 | 
							
								enum UpdateFlags
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									DT_CROWD_ANTICIPATE_TURNS = 1,
							 | 
						||
| 
								 | 
							
									DT_CROWD_OBSTACLE_AVOIDANCE = 2,
							 | 
						||
| 
								 | 
							
									DT_CROWD_SEPARATION = 4,
							 | 
						||
| 
								 | 
							
									DT_CROWD_OPTIMIZE_VIS = 8,			///< Use #dtPathCorridor::optimizePathVisibility() to optimize the agent path.
							 | 
						||
| 
								 | 
							
									DT_CROWD_OPTIMIZE_TOPO = 16,		///< Use dtPathCorridor::optimizePathTopology() to optimize the agent path.
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								struct dtCrowdAgentDebugInfo
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int idx;
							 | 
						||
| 
								 | 
							
									float optStart[3], optEnd[3];
							 | 
						||
| 
								 | 
							
									dtObstacleAvoidanceDebugData* vod;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// Provides local steering behaviors for a group of agents. 
							 | 
						||
| 
								 | 
							
								/// @ingroup crowd
							 | 
						||
| 
								 | 
							
								class dtCrowd
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									int m_maxAgents;
							 | 
						||
| 
								 | 
							
									dtCrowdAgent* m_agents;
							 | 
						||
| 
								 | 
							
									dtCrowdAgent** m_activeAgents;
							 | 
						||
| 
								 | 
							
									dtCrowdAgentAnimation* m_agentAnims;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									dtPathQueue m_pathq;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									dtObstacleAvoidanceParams m_obstacleQueryParams[DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS];
							 | 
						||
| 
								 | 
							
									dtObstacleAvoidanceQuery* m_obstacleQuery;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									dtProximityGrid* m_grid;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									dtPolyRef* m_pathResult;
							 | 
						||
| 
								 | 
							
									int m_maxPathResult;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									float m_agentPlacementHalfExtents[3];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									dtQueryFilter m_filters[DT_CROWD_MAX_QUERY_FILTER_TYPE];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									float m_maxAgentRadius;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int m_velocitySampleCount;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									dtNavMeshQuery* m_navquery;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void updateTopologyOptimization(dtCrowdAgent** agents, const int nagents, const float dt);
							 | 
						||
| 
								 | 
							
									void updateMoveRequest(const float dt);
							 | 
						||
| 
								 | 
							
									void checkPathValidity(dtCrowdAgent** agents, const int nagents, const float dt);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									inline int getAgentIndex(const dtCrowdAgent* agent) const  { return (int)(agent - m_agents); }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									bool requestMoveTargetReplan(const int idx, dtPolyRef ref, const float* pos);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									void purge();
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
								public:
							 | 
						||
| 
								 | 
							
									dtCrowd();
							 | 
						||
| 
								 | 
							
									~dtCrowd();
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/// Initializes the crowd.  
							 | 
						||
| 
								 | 
							
									///  @param[in]		maxAgents		The maximum number of agents the crowd can manage. [Limit: >= 1]
							 | 
						||
| 
								 | 
							
									///  @param[in]		maxAgentRadius	The maximum radius of any agent that will be added to the crowd. [Limit: > 0]
							 | 
						||
| 
								 | 
							
									///  @param[in]		nav				The navigation mesh to use for planning.
							 | 
						||
| 
								 | 
							
									/// @return True if the initialization succeeded.
							 | 
						||
| 
								 | 
							
									bool init(const int maxAgents, const float maxAgentRadius, dtNavMesh* nav);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/// Sets the shared avoidance configuration for the specified index.
							 | 
						||
| 
								 | 
							
									///  @param[in]		idx		The index. [Limits: 0 <= value < #DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS]
							 | 
						||
| 
								 | 
							
									///  @param[in]		params	The new configuration.
							 | 
						||
| 
								 | 
							
									void setObstacleAvoidanceParams(const int idx, const dtObstacleAvoidanceParams* params);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// Gets the shared avoidance configuration for the specified index.
							 | 
						||
| 
								 | 
							
									///  @param[in]		idx		The index of the configuration to retreive. 
							 | 
						||
| 
								 | 
							
									///							[Limits:  0 <= value < #DT_CROWD_MAX_OBSTAVOIDANCE_PARAMS]
							 | 
						||
| 
								 | 
							
									/// @return The requested configuration.
							 | 
						||
| 
								 | 
							
									const dtObstacleAvoidanceParams* getObstacleAvoidanceParams(const int idx) const;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/// 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);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// Gets the specified agent from the pool.
							 | 
						||
| 
								 | 
							
									///	 @param[in]		idx		The agent index. [Limits: 0 <= value < #getAgentCount()]
							 | 
						||
| 
								 | 
							
									/// @return The requested agent.
							 | 
						||
| 
								 | 
							
									dtCrowdAgent* getEditableAgent(const int idx);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// The maximum number of agents that can be managed by the object.
							 | 
						||
| 
								 | 
							
									/// @return The maximum number of agents.
							 | 
						||
| 
								 | 
							
									int getAgentCount() const;
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/// Adds a new agent to the crowd.
							 | 
						||
| 
								 | 
							
									///  @param[in]		pos		The requested position of the agent. [(x, y, z)]
							 | 
						||
| 
								 | 
							
									///  @param[in]		params	The configutation of the agent.
							 | 
						||
| 
								 | 
							
									/// @return The index of the agent in the agent pool. Or -1 if the agent could not be added.
							 | 
						||
| 
								 | 
							
									int addAgent(const float* pos, const dtCrowdAgentParams* params);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// Updates the specified agent's configuration.
							 | 
						||
| 
								 | 
							
									///  @param[in]		idx		The agent index. [Limits: 0 <= value < #getAgentCount()]
							 | 
						||
| 
								 | 
							
									///  @param[in]		params	The new agent configuration.
							 | 
						||
| 
								 | 
							
									void updateAgentParameters(const int idx, const dtCrowdAgentParams* params);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// Removes the agent from the crowd.
							 | 
						||
| 
								 | 
							
									///  @param[in]		idx		The agent index. [Limits: 0 <= value < #getAgentCount()]
							 | 
						||
| 
								 | 
							
									void removeAgent(const int idx);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/// Submits a new move request for the specified agent.
							 | 
						||
| 
								 | 
							
									///  @param[in]		idx		The agent index. [Limits: 0 <= value < #getAgentCount()]
							 | 
						||
| 
								 | 
							
									///  @param[in]		ref		The position's polygon reference.
							 | 
						||
| 
								 | 
							
									///  @param[in]		pos		The position within the polygon. [(x, y, z)]
							 | 
						||
| 
								 | 
							
									/// @return True if the request was successfully submitted.
							 | 
						||
| 
								 | 
							
									bool requestMoveTarget(const int idx, dtPolyRef ref, const float* pos);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// Submits a new move request for the specified agent.
							 | 
						||
| 
								 | 
							
									///  @param[in]		idx		The agent index. [Limits: 0 <= value < #getAgentCount()]
							 | 
						||
| 
								 | 
							
									///  @param[in]		vel		The movement velocity. [(x, y, z)]
							 | 
						||
| 
								 | 
							
									/// @return True if the request was successfully submitted.
							 | 
						||
| 
								 | 
							
									bool requestMoveVelocity(const int idx, const float* vel);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// Resets any request for the specified agent.
							 | 
						||
| 
								 | 
							
									///  @param[in]		idx		The agent index. [Limits: 0 <= value < #getAgentCount()]
							 | 
						||
| 
								 | 
							
									/// @return True if the request was successfully reseted.
							 | 
						||
| 
								 | 
							
									bool resetMoveTarget(const int idx);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// Gets the active agents int the agent pool.
							 | 
						||
| 
								 | 
							
									///  @param[out]	agents		An array of agent pointers. [(#dtCrowdAgent *) * maxAgents]
							 | 
						||
| 
								 | 
							
									///  @param[in]		maxAgents	The size of the crowd agent array.
							 | 
						||
| 
								 | 
							
									/// @return The number of agents returned in @p agents.
							 | 
						||
| 
								 | 
							
									int getActiveAgents(dtCrowdAgent** agents, const int maxAgents);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// Updates the steering and positions of all agents.
							 | 
						||
| 
								 | 
							
									///  @param[in]		dt		The time, in seconds, to update the simulation. [Limit: > 0]
							 | 
						||
| 
								 | 
							
									///  @param[out]	debug	A debug object to load with debug information. [Opt]
							 | 
						||
| 
								 | 
							
									void update(const float dt, dtCrowdAgentDebugInfo* debug);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/// Gets the filter used by the crowd.
							 | 
						||
| 
								 | 
							
									/// @return The filter used by the crowd.
							 | 
						||
| 
								 | 
							
									inline const dtQueryFilter* getFilter(const int i) 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.
							 | 
						||
| 
								 | 
							
									inline dtQueryFilter* getEditableFilter(const int i) { return (i >= 0 && i < DT_CROWD_MAX_QUERY_FILTER_TYPE) ? &m_filters[i] : 0; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// Gets the search halfExtents [(x, y, z)] used by the crowd for query operations. 
							 | 
						||
| 
								 | 
							
									/// @return The search halfExtents used by the crowd. [(x, y, z)]
							 | 
						||
| 
								 | 
							
									const float* getQueryHalfExtents() const { return m_agentPlacementHalfExtents; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// Same as getQueryHalfExtents. Left to maintain backwards compatibility.
							 | 
						||
| 
								 | 
							
									/// @return The search halfExtents used by the crowd. [(x, y, z)]
							 | 
						||
| 
								 | 
							
									const float* getQueryExtents() const { return m_agentPlacementHalfExtents; }
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/// Gets the velocity sample count.
							 | 
						||
| 
								 | 
							
									/// @return The velocity sample count.
							 | 
						||
| 
								 | 
							
									inline int getVelocitySampleCount() const { return m_velocitySampleCount; }
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									/// Gets the crowd's proximity grid.
							 | 
						||
| 
								 | 
							
									/// @return The crowd's proximity grid.
							 | 
						||
| 
								 | 
							
									const dtProximityGrid* getGrid() const { return m_grid; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// Gets the crowd's path request queue.
							 | 
						||
| 
								 | 
							
									/// @return The crowd's path request queue.
							 | 
						||
| 
								 | 
							
									const dtPathQueue* getPathQueue() const { return &m_pathq; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									/// Gets the query object used by the crowd.
							 | 
						||
| 
								 | 
							
									const dtNavMeshQuery* getNavMeshQuery() const { return m_navquery; }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								private:
							 | 
						||
| 
								 | 
							
									// Explicitly disabled copy constructor and copy assignment operator.
							 | 
						||
| 
								 | 
							
									dtCrowd(const dtCrowd&);
							 | 
						||
| 
								 | 
							
									dtCrowd& operator=(const dtCrowd&);
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// Allocates a crowd object using the Detour allocator.
							 | 
						||
| 
								 | 
							
								/// @return A crowd object that is ready for initialization, or null on failure.
							 | 
						||
| 
								 | 
							
								///  @ingroup crowd
							 | 
						||
| 
								 | 
							
								dtCrowd* dtAllocCrowd();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// Frees the specified crowd object using the Detour allocator.
							 | 
						||
| 
								 | 
							
								///  @param[in]		ptr		A crowd object allocated using #dtAllocCrowd
							 | 
						||
| 
								 | 
							
								///  @ingroup crowd
							 | 
						||
| 
								 | 
							
								void dtFreeCrowd(dtCrowd* ptr);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#endif // DETOURCROWD_H
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								///////////////////////////////////////////////////////////////////////////
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// This section contains detailed documentation for members that don't have
							 | 
						||
| 
								 | 
							
								// a source file. It reduces clutter in the main section of the header.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@defgroup crowd Crowd
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Members in this module implement local steering and dynamic avoidance features.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The crowd is the big beast of the navigation features. It not only handles a 
							 | 
						||
| 
								 | 
							
								lot of the path management for you, but also local steering and dynamic 
							 | 
						||
| 
								 | 
							
								avoidance between members of the crowd. I.e. It can keep your agents from 
							 | 
						||
| 
								 | 
							
								running into each other.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Main class: #dtCrowd
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The #dtNavMeshQuery and #dtPathCorridor classes provide perfectly good, easy 
							 | 
						||
| 
								 | 
							
								to use path planning features. But in the end they only give you points that 
							 | 
						||
| 
								 | 
							
								your navigation client should be moving toward. When it comes to deciding things 
							 | 
						||
| 
								 | 
							
								like agent velocity and steering to avoid other agents, that is up to you to 
							 | 
						||
| 
								 | 
							
								implement. Unless, of course, you decide to use #dtCrowd.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Basically, you add an agent to the crowd, providing various configuration 
							 | 
						||
| 
								 | 
							
								settings such as maximum speed and acceleration. You also provide a local 
							 | 
						||
| 
								 | 
							
								target to more toward. The crowd manager then provides, with every update, the 
							 | 
						||
| 
								 | 
							
								new agent position and velocity for the frame. The movement will be 
							 | 
						||
| 
								 | 
							
								constrained to the navigation mesh, and steering will be applied to ensure 
							 | 
						||
| 
								 | 
							
								agents managed by the crowd do not collide with each other.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This is very powerful feature set. But it comes with limitations.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The biggest limitation is that you must give control of the agent's position 
							 | 
						||
| 
								 | 
							
								completely over to the crowd manager. You can update things like maximum speed 
							 | 
						||
| 
								 | 
							
								and acceleration. But in order for the crowd manager to do its thing, it can't 
							 | 
						||
| 
								 | 
							
								allow you to constantly be giving it overrides to position and velocity. So 
							 | 
						||
| 
								 | 
							
								you give up direct control of the agent's movement. It belongs to the crowd.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								The second biggest limitation revolves around the fact that the crowd manager 
							 | 
						||
| 
								 | 
							
								deals with local planning. So the agent's target should never be more than 
							 | 
						||
| 
								 | 
							
								256 polygons aways from its current position. If it is, you risk 
							 | 
						||
| 
								 | 
							
								your agent failing to reach its target. So you may still need to do long 
							 | 
						||
| 
								 | 
							
								distance planning and provide the crowd manager with intermediate targets.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Other significant limitations:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								- All agents using the crowd manager will use the same #dtQueryFilter.
							 | 
						||
| 
								 | 
							
								- Crowd management is relatively expensive. The maximum agents under crowd 
							 | 
						||
| 
								 | 
							
								  management at any one time is between 20 and 30.  A good place to start
							 | 
						||
| 
								 | 
							
								  is a maximum of 25 agents for 0.5ms per frame.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@note This is a summary list of members.  Use the index or search 
							 | 
						||
| 
								 | 
							
								feature to find minor members.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@struct dtCrowdAgentParams
							 | 
						||
| 
								 | 
							
								@see dtCrowdAgent, dtCrowd::addAgent(), dtCrowd::updateAgentParameters()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@var dtCrowdAgentParams::obstacleAvoidanceType
							 | 
						||
| 
								 | 
							
								@par
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#dtCrowd permits agents to use different avoidance configurations.  This value 
							 | 
						||
| 
								 | 
							
								is the index of the #dtObstacleAvoidanceParams within the crowd.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@see dtObstacleAvoidanceParams, dtCrowd::setObstacleAvoidanceParams(), 
							 | 
						||
| 
								 | 
							
									 dtCrowd::getObstacleAvoidanceParams()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@var dtCrowdAgentParams::collisionQueryRange
							 | 
						||
| 
								 | 
							
								@par
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Collision elements include other agents and navigation mesh boundaries.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This value is often based on the agent radius and/or maximum speed. E.g. radius * 8
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@var dtCrowdAgentParams::pathOptimizationRange
							 | 
						||
| 
								 | 
							
								@par
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								Only applicalbe if #updateFlags includes the #DT_CROWD_OPTIMIZE_VIS flag.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This value is often based on the agent radius. E.g. radius * 30
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@see dtPathCorridor::optimizePathVisibility()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								@var dtCrowdAgentParams::separationWeight
							 | 
						||
| 
								 | 
							
								@par
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								A higher value will result in agents trying to stay farther away from each other at 
							 | 
						||
| 
								 | 
							
								the cost of more difficult steering in tight spaces.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 |