// // 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" static const int DT_CROWDAGENT_MAX_NEIGHBOURS = 6; static const int DT_CROWDAGENT_MAX_CORNERS = 4; struct dtCrowdNeighbour { int idx; float dist; }; struct dtCrowdAgent { unsigned char active; dtPathCorridor corridor; dtLocalBoundary boundary; float t; float var; float topologyOptTime; dtCrowdNeighbour neis[DT_CROWDAGENT_MAX_NEIGHBOURS]; int nneis; float radius, height; float maxAcceleration; float maxSpeed; float collisionQueryRange; float pathOptimizationRange; float desiredSpeed; float npos[3]; float disp[3]; float dvel[3]; float nvel[3]; float vel[3]; float cornerVerts[DT_CROWDAGENT_MAX_CORNERS*3]; unsigned char cornerFlags[DT_CROWDAGENT_MAX_CORNERS]; dtPolyRef cornerPolys[DT_CROWDAGENT_MAX_CORNERS]; int ncorners; }; enum UpdateFlags { DT_CROWD_ANTICIPATE_TURNS = 1, DT_CROWD_USE_VO = 2, // DT_CROWD_DRUNK = 4, DT_CROWD_OPTIMIZE_VIS = 8, DT_CROWD_OPTIMIZE_TOPO = 16, }; struct dtCrowdAgentParams { float radius; float height; float maxAcceleration; float maxSpeed; float collisionQueryRange; float pathOptimizationRange; }; struct dtCrowdAgentDebugInfo { int idx; float optStart[3], optEnd[3]; dtObstacleAvoidanceDebugData* vod; }; class dtCrowd { int m_maxAgents; dtCrowdAgent* m_agents; dtCrowdAgent** m_activeAgents; dtPathQueue m_pathq; dtObstacleAvoidanceQuery* m_obstacleQuery; dtProximityGrid* m_grid; dtPolyRef* m_pathResult; int m_maxPathResult; float m_ext[3]; dtQueryFilter m_filter; float m_maxAgentRadius; int m_velocitySampleCount; enum MoveRequestState { MR_TARGET_FAILED, MR_TARGET_VALID, MR_TARGET_REQUESTING, MR_TARGET_WAITING_FOR_PATH, MR_TARGET_ADJUST, }; static const int MAX_TEMP_PATH = 32; struct MoveRequest { unsigned char state; // State of the request int idx; // Agent index dtPolyRef ref; // Goal ref float pos[3]; // Goal position dtPathQueueRef pathqRef; // Path find query ref dtPolyRef aref; // Goal adjustment ref float apos[3]; // Goal adjustment pos dtPolyRef temp[MAX_TEMP_PATH]; // Adjusted path to the goal int ntemp; }; MoveRequest* m_moveRequests; int m_moveRequestCount; dtNavMeshQuery* m_navquery; int getNeighbours(const float* pos, const float height, const float range, const dtCrowdAgent* skip, dtCrowdNeighbour* result, const int maxResult); void updateTopologyOptimization(dtCrowdAgent** agents, const int nagents, const float dt); void updateMoveRequest(const float dt); void purge(); public: dtCrowd(); ~dtCrowd(); bool init(const int maxAgents, const float maxAgentRadius, dtNavMesh* nav); const dtCrowdAgent* getAgent(const int idx); const int getAgentCount() const; int addAgent(const float* pos, const dtCrowdAgentParams* params); void removeAgent(const int idx); bool requestMoveTarget(const int idx, dtPolyRef ref, const float* pos); bool adjustMoveTarget(const int idx, dtPolyRef ref, const float* pos); int getActiveAgents(dtCrowdAgent** agents, const int maxAgents); void update(const float dt, unsigned int flags, dtCrowdAgentDebugInfo* debug); const dtQueryFilter* getFilter() const { return &m_filter; } const float* getQueryExtents() const { return m_ext; } inline int getVelocitySampleCount() const { return m_velocitySampleCount; } const dtProximityGrid* getGrid() const { return m_grid; } const dtPathQueue* getPathQueue() const { return &m_pathq; } }; #endif // CROWDMANAGER_H