forked from LeenkxTeam/LNXSDK
Update Files
This commit is contained in:
@ -0,0 +1,460 @@
|
||||
//
|
||||
// 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.
|
||||
|
||||
*/
|
||||
|
@ -0,0 +1,66 @@
|
||||
//
|
||||
// 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 DETOURLOCALBOUNDARY_H
|
||||
#define DETOURLOCALBOUNDARY_H
|
||||
|
||||
#include "DetourNavMeshQuery.h"
|
||||
|
||||
|
||||
class dtLocalBoundary
|
||||
{
|
||||
static const int MAX_LOCAL_SEGS = 8;
|
||||
static const int MAX_LOCAL_POLYS = 16;
|
||||
|
||||
struct Segment
|
||||
{
|
||||
float s[6]; ///< Segment start/end
|
||||
float d; ///< Distance for pruning.
|
||||
};
|
||||
|
||||
float m_center[3];
|
||||
Segment m_segs[MAX_LOCAL_SEGS];
|
||||
int m_nsegs;
|
||||
|
||||
dtPolyRef m_polys[MAX_LOCAL_POLYS];
|
||||
int m_npolys;
|
||||
|
||||
void addSegment(const float dist, const float* s);
|
||||
|
||||
public:
|
||||
dtLocalBoundary();
|
||||
~dtLocalBoundary();
|
||||
|
||||
void reset();
|
||||
|
||||
void update(dtPolyRef ref, const float* pos, const float collisionQueryRange,
|
||||
dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||
|
||||
bool isValid(dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||
|
||||
inline const float* getCenter() const { return m_center; }
|
||||
inline int getSegmentCount() const { return m_nsegs; }
|
||||
inline const float* getSegment(int i) const { return m_segs[i].s; }
|
||||
|
||||
private:
|
||||
// Explicitly disabled copy constructor and copy assignment operator.
|
||||
dtLocalBoundary(const dtLocalBoundary&);
|
||||
dtLocalBoundary& operator=(const dtLocalBoundary&);
|
||||
};
|
||||
|
||||
#endif // DETOURLOCALBOUNDARY_H
|
@ -0,0 +1,159 @@
|
||||
//
|
||||
// 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 DETOUROBSTACLEAVOIDANCE_H
|
||||
#define DETOUROBSTACLEAVOIDANCE_H
|
||||
|
||||
struct dtObstacleCircle
|
||||
{
|
||||
float p[3]; ///< Position of the obstacle
|
||||
float vel[3]; ///< Velocity of the obstacle
|
||||
float dvel[3]; ///< Velocity of the obstacle
|
||||
float rad; ///< Radius of the obstacle
|
||||
float dp[3], np[3]; ///< Use for side selection during sampling.
|
||||
};
|
||||
|
||||
struct dtObstacleSegment
|
||||
{
|
||||
float p[3], q[3]; ///< End points of the obstacle segment
|
||||
bool touch;
|
||||
};
|
||||
|
||||
|
||||
class dtObstacleAvoidanceDebugData
|
||||
{
|
||||
public:
|
||||
dtObstacleAvoidanceDebugData();
|
||||
~dtObstacleAvoidanceDebugData();
|
||||
|
||||
bool init(const int maxSamples);
|
||||
void reset();
|
||||
void addSample(const float* vel, const float ssize, const float pen,
|
||||
const float vpen, const float vcpen, const float spen, const float tpen);
|
||||
|
||||
void normalizeSamples();
|
||||
|
||||
inline int getSampleCount() const { return m_nsamples; }
|
||||
inline const float* getSampleVelocity(const int i) const { return &m_vel[i*3]; }
|
||||
inline float getSampleSize(const int i) const { return m_ssize[i]; }
|
||||
inline float getSamplePenalty(const int i) const { return m_pen[i]; }
|
||||
inline float getSampleDesiredVelocityPenalty(const int i) const { return m_vpen[i]; }
|
||||
inline float getSampleCurrentVelocityPenalty(const int i) const { return m_vcpen[i]; }
|
||||
inline float getSamplePreferredSidePenalty(const int i) const { return m_spen[i]; }
|
||||
inline float getSampleCollisionTimePenalty(const int i) const { return m_tpen[i]; }
|
||||
|
||||
private:
|
||||
// Explicitly disabled copy constructor and copy assignment operator.
|
||||
dtObstacleAvoidanceDebugData(const dtObstacleAvoidanceDebugData&);
|
||||
dtObstacleAvoidanceDebugData& operator=(const dtObstacleAvoidanceDebugData&);
|
||||
|
||||
int m_nsamples;
|
||||
int m_maxSamples;
|
||||
float* m_vel;
|
||||
float* m_ssize;
|
||||
float* m_pen;
|
||||
float* m_vpen;
|
||||
float* m_vcpen;
|
||||
float* m_spen;
|
||||
float* m_tpen;
|
||||
};
|
||||
|
||||
dtObstacleAvoidanceDebugData* dtAllocObstacleAvoidanceDebugData();
|
||||
void dtFreeObstacleAvoidanceDebugData(dtObstacleAvoidanceDebugData* ptr);
|
||||
|
||||
|
||||
static const int DT_MAX_PATTERN_DIVS = 32; ///< Max numver of adaptive divs.
|
||||
static const int DT_MAX_PATTERN_RINGS = 4; ///< Max number of adaptive rings.
|
||||
|
||||
struct dtObstacleAvoidanceParams
|
||||
{
|
||||
float velBias;
|
||||
float weightDesVel;
|
||||
float weightCurVel;
|
||||
float weightSide;
|
||||
float weightToi;
|
||||
float horizTime;
|
||||
unsigned char gridSize; ///< grid
|
||||
unsigned char adaptiveDivs; ///< adaptive
|
||||
unsigned char adaptiveRings; ///< adaptive
|
||||
unsigned char adaptiveDepth; ///< adaptive
|
||||
};
|
||||
|
||||
class dtObstacleAvoidanceQuery
|
||||
{
|
||||
public:
|
||||
dtObstacleAvoidanceQuery();
|
||||
~dtObstacleAvoidanceQuery();
|
||||
|
||||
bool init(const int maxCircles, const int maxSegments);
|
||||
|
||||
void reset();
|
||||
|
||||
void addCircle(const float* pos, const float rad,
|
||||
const float* vel, const float* dvel);
|
||||
|
||||
void addSegment(const float* p, const float* q);
|
||||
|
||||
int sampleVelocityGrid(const float* pos, const float rad, const float vmax,
|
||||
const float* vel, const float* dvel, float* nvel,
|
||||
const dtObstacleAvoidanceParams* params,
|
||||
dtObstacleAvoidanceDebugData* debug = 0);
|
||||
|
||||
int sampleVelocityAdaptive(const float* pos, const float rad, const float vmax,
|
||||
const float* vel, const float* dvel, float* nvel,
|
||||
const dtObstacleAvoidanceParams* params,
|
||||
dtObstacleAvoidanceDebugData* debug = 0);
|
||||
|
||||
inline int getObstacleCircleCount() const { return m_ncircles; }
|
||||
const dtObstacleCircle* getObstacleCircle(const int i) { return &m_circles[i]; }
|
||||
|
||||
inline int getObstacleSegmentCount() const { return m_nsegments; }
|
||||
const dtObstacleSegment* getObstacleSegment(const int i) { return &m_segments[i]; }
|
||||
|
||||
private:
|
||||
// Explicitly disabled copy constructor and copy assignment operator.
|
||||
dtObstacleAvoidanceQuery(const dtObstacleAvoidanceQuery&);
|
||||
dtObstacleAvoidanceQuery& operator=(const dtObstacleAvoidanceQuery&);
|
||||
|
||||
void prepare(const float* pos, const float* dvel);
|
||||
|
||||
float processSample(const float* vcand, const float cs,
|
||||
const float* pos, const float rad,
|
||||
const float* vel, const float* dvel,
|
||||
const float minPenalty,
|
||||
dtObstacleAvoidanceDebugData* debug);
|
||||
|
||||
dtObstacleAvoidanceParams m_params;
|
||||
float m_invHorizTime;
|
||||
float m_vmax;
|
||||
float m_invVmax;
|
||||
|
||||
int m_maxCircles;
|
||||
dtObstacleCircle* m_circles;
|
||||
int m_ncircles;
|
||||
|
||||
int m_maxSegments;
|
||||
dtObstacleSegment* m_segments;
|
||||
int m_nsegments;
|
||||
};
|
||||
|
||||
dtObstacleAvoidanceQuery* dtAllocObstacleAvoidanceQuery();
|
||||
void dtFreeObstacleAvoidanceQuery(dtObstacleAvoidanceQuery* ptr);
|
||||
|
||||
|
||||
#endif // DETOUROBSTACLEAVOIDANCE_H
|
@ -0,0 +1,151 @@
|
||||
//
|
||||
// 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 DETOUTPATHCORRIDOR_H
|
||||
#define DETOUTPATHCORRIDOR_H
|
||||
|
||||
#include "DetourNavMeshQuery.h"
|
||||
|
||||
/// Represents a dynamic polygon corridor used to plan agent movement.
|
||||
/// @ingroup crowd, detour
|
||||
class dtPathCorridor
|
||||
{
|
||||
float m_pos[3];
|
||||
float m_target[3];
|
||||
|
||||
dtPolyRef* m_path;
|
||||
int m_npath;
|
||||
int m_maxPath;
|
||||
|
||||
public:
|
||||
dtPathCorridor();
|
||||
~dtPathCorridor();
|
||||
|
||||
/// Allocates the corridor's path buffer.
|
||||
/// @param[in] maxPath The maximum path size the corridor can handle.
|
||||
/// @return True if the initialization succeeded.
|
||||
bool init(const int maxPath);
|
||||
|
||||
/// Resets the path corridor to the specified position.
|
||||
/// @param[in] ref The polygon reference containing the position.
|
||||
/// @param[in] pos The new position in the corridor. [(x, y, z)]
|
||||
void reset(dtPolyRef ref, const float* pos);
|
||||
|
||||
/// Finds the corners in the corridor from the position toward the target. (The straightened path.)
|
||||
/// @param[out] cornerVerts The corner vertices. [(x, y, z) * cornerCount] [Size: <= maxCorners]
|
||||
/// @param[out] cornerFlags The flag for each corner. [(flag) * cornerCount] [Size: <= maxCorners]
|
||||
/// @param[out] cornerPolys The polygon reference for each corner. [(polyRef) * cornerCount]
|
||||
/// [Size: <= @p maxCorners]
|
||||
/// @param[in] maxCorners The maximum number of corners the buffers can hold.
|
||||
/// @param[in] navquery The query object used to build the corridor.
|
||||
/// @param[in] filter The filter to apply to the operation.
|
||||
/// @return The number of corners returned in the corner buffers. [0 <= value <= @p maxCorners]
|
||||
int findCorners(float* cornerVerts, unsigned char* cornerFlags,
|
||||
dtPolyRef* cornerPolys, const int maxCorners,
|
||||
dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||
|
||||
/// Attempts to optimize the path if the specified point is visible from the current position.
|
||||
/// @param[in] next The point to search toward. [(x, y, z])
|
||||
/// @param[in] pathOptimizationRange The maximum range to search. [Limit: > 0]
|
||||
/// @param[in] navquery The query object used to build the corridor.
|
||||
/// @param[in] filter The filter to apply to the operation.
|
||||
void optimizePathVisibility(const float* next, const float pathOptimizationRange,
|
||||
dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||
|
||||
/// Attempts to optimize the path using a local area search. (Partial replanning.)
|
||||
/// @param[in] navquery The query object used to build the corridor.
|
||||
/// @param[in] filter The filter to apply to the operation.
|
||||
bool optimizePathTopology(dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||
|
||||
bool moveOverOffmeshConnection(dtPolyRef offMeshConRef, dtPolyRef* refs,
|
||||
float* startPos, float* endPos,
|
||||
dtNavMeshQuery* navquery);
|
||||
|
||||
bool fixPathStart(dtPolyRef safeRef, const float* safePos);
|
||||
|
||||
bool trimInvalidPath(dtPolyRef safeRef, const float* safePos,
|
||||
dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||
|
||||
/// Checks the current corridor path to see if its polygon references remain valid.
|
||||
/// @param[in] maxLookAhead The number of polygons from the beginning of the corridor to search.
|
||||
/// @param[in] navquery The query object used to build the corridor.
|
||||
/// @param[in] filter The filter to apply to the operation.
|
||||
bool isValid(const int maxLookAhead, dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||
|
||||
/// Moves the position from the current location to the desired location, adjusting the corridor
|
||||
/// as needed to reflect the change.
|
||||
/// @param[in] npos The desired new position. [(x, y, z)]
|
||||
/// @param[in] navquery The query object used to build the corridor.
|
||||
/// @param[in] filter The filter to apply to the operation.
|
||||
/// @return Returns true if move succeeded.
|
||||
bool movePosition(const float* npos, dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||
|
||||
/// Moves the target from the curent location to the desired location, adjusting the corridor
|
||||
/// as needed to reflect the change.
|
||||
/// @param[in] npos The desired new target position. [(x, y, z)]
|
||||
/// @param[in] navquery The query object used to build the corridor.
|
||||
/// @param[in] filter The filter to apply to the operation.
|
||||
/// @return Returns true if move succeeded.
|
||||
bool moveTargetPosition(const float* npos, dtNavMeshQuery* navquery, const dtQueryFilter* filter);
|
||||
|
||||
/// Loads a new path and target into the corridor.
|
||||
/// @param[in] target The target location within the last polygon of the path. [(x, y, z)]
|
||||
/// @param[in] path The path corridor. [(polyRef) * @p npolys]
|
||||
/// @param[in] npath The number of polygons in the path.
|
||||
void setCorridor(const float* target, const dtPolyRef* polys, const int npath);
|
||||
|
||||
/// Gets the current position within the corridor. (In the first polygon.)
|
||||
/// @return The current position within the corridor.
|
||||
inline const float* getPos() const { return m_pos; }
|
||||
|
||||
/// Gets the current target within the corridor. (In the last polygon.)
|
||||
/// @return The current target within the corridor.
|
||||
inline const float* getTarget() const { return m_target; }
|
||||
|
||||
/// The polygon reference id of the first polygon in the corridor, the polygon containing the position.
|
||||
/// @return The polygon reference id of the first polygon in the corridor. (Or zero if there is no path.)
|
||||
inline dtPolyRef getFirstPoly() const { return m_npath ? m_path[0] : 0; }
|
||||
|
||||
/// The polygon reference id of the last polygon in the corridor, the polygon containing the target.
|
||||
/// @return The polygon reference id of the last polygon in the corridor. (Or zero if there is no path.)
|
||||
inline dtPolyRef getLastPoly() const { return m_npath ? m_path[m_npath-1] : 0; }
|
||||
|
||||
/// The corridor's path.
|
||||
/// @return The corridor's path. [(polyRef) * #getPathCount()]
|
||||
inline const dtPolyRef* getPath() const { return m_path; }
|
||||
|
||||
/// The number of polygons in the current corridor path.
|
||||
/// @return The number of polygons in the current corridor path.
|
||||
inline int getPathCount() const { return m_npath; }
|
||||
|
||||
private:
|
||||
// Explicitly disabled copy constructor and copy assignment operator.
|
||||
dtPathCorridor(const dtPathCorridor&);
|
||||
dtPathCorridor& operator=(const dtPathCorridor&);
|
||||
};
|
||||
|
||||
int dtMergeCorridorStartMoved(dtPolyRef* path, const int npath, const int maxPath,
|
||||
const dtPolyRef* visited, const int nvisited);
|
||||
|
||||
int dtMergeCorridorEndMoved(dtPolyRef* path, const int npath, const int maxPath,
|
||||
const dtPolyRef* visited, const int nvisited);
|
||||
|
||||
int dtMergeCorridorStartShortcut(dtPolyRef* path, const int npath, const int maxPath,
|
||||
const dtPolyRef* visited, const int nvisited);
|
||||
|
||||
#endif // DETOUTPATHCORRIDOR_H
|
@ -0,0 +1,79 @@
|
||||
//
|
||||
// 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 DETOURPATHQUEUE_H
|
||||
#define DETOURPATHQUEUE_H
|
||||
|
||||
#include "DetourNavMesh.h"
|
||||
#include "DetourNavMeshQuery.h"
|
||||
|
||||
static const unsigned int DT_PATHQ_INVALID = 0;
|
||||
|
||||
typedef unsigned int dtPathQueueRef;
|
||||
|
||||
class dtPathQueue
|
||||
{
|
||||
struct PathQuery
|
||||
{
|
||||
dtPathQueueRef ref;
|
||||
/// Path find start and end location.
|
||||
float startPos[3], endPos[3];
|
||||
dtPolyRef startRef, endRef;
|
||||
/// Result.
|
||||
dtPolyRef* path;
|
||||
int npath;
|
||||
/// State.
|
||||
dtStatus status;
|
||||
int keepAlive;
|
||||
const dtQueryFilter* filter; ///< TODO: This is potentially dangerous!
|
||||
};
|
||||
|
||||
static const int MAX_QUEUE = 8;
|
||||
PathQuery m_queue[MAX_QUEUE];
|
||||
dtPathQueueRef m_nextHandle;
|
||||
int m_maxPathSize;
|
||||
int m_queueHead;
|
||||
dtNavMeshQuery* m_navquery;
|
||||
|
||||
void purge();
|
||||
|
||||
public:
|
||||
dtPathQueue();
|
||||
~dtPathQueue();
|
||||
|
||||
bool init(const int maxPathSize, const int maxSearchNodeCount, dtNavMesh* nav);
|
||||
|
||||
void update(const int maxIters);
|
||||
|
||||
dtPathQueueRef request(dtPolyRef startRef, dtPolyRef endRef,
|
||||
const float* startPos, const float* endPos,
|
||||
const dtQueryFilter* filter);
|
||||
|
||||
dtStatus getRequestStatus(dtPathQueueRef ref) const;
|
||||
|
||||
dtStatus getPathResult(dtPathQueueRef ref, dtPolyRef* path, int* pathSize, const int maxPath);
|
||||
|
||||
inline const dtNavMeshQuery* getNavQuery() const { return m_navquery; }
|
||||
|
||||
private:
|
||||
// Explicitly disabled copy constructor and copy assignment operator.
|
||||
dtPathQueue(const dtPathQueue&);
|
||||
dtPathQueue& operator=(const dtPathQueue&);
|
||||
};
|
||||
|
||||
#endif // DETOURPATHQUEUE_H
|
@ -0,0 +1,74 @@
|
||||
//
|
||||
// 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 DETOURPROXIMITYGRID_H
|
||||
#define DETOURPROXIMITYGRID_H
|
||||
|
||||
class dtProximityGrid
|
||||
{
|
||||
float m_cellSize;
|
||||
float m_invCellSize;
|
||||
|
||||
struct Item
|
||||
{
|
||||
unsigned short id;
|
||||
short x,y;
|
||||
unsigned short next;
|
||||
};
|
||||
Item* m_pool;
|
||||
int m_poolHead;
|
||||
int m_poolSize;
|
||||
|
||||
unsigned short* m_buckets;
|
||||
int m_bucketsSize;
|
||||
|
||||
int m_bounds[4];
|
||||
|
||||
public:
|
||||
dtProximityGrid();
|
||||
~dtProximityGrid();
|
||||
|
||||
bool init(const int poolSize, const float cellSize);
|
||||
|
||||
void clear();
|
||||
|
||||
void addItem(const unsigned short id,
|
||||
const float minx, const float miny,
|
||||
const float maxx, const float maxy);
|
||||
|
||||
int queryItems(const float minx, const float miny,
|
||||
const float maxx, const float maxy,
|
||||
unsigned short* ids, const int maxIds) const;
|
||||
|
||||
int getItemCountAt(const int x, const int y) const;
|
||||
|
||||
inline const int* getBounds() const { return m_bounds; }
|
||||
inline float getCellSize() const { return m_cellSize; }
|
||||
|
||||
private:
|
||||
// Explicitly disabled copy constructor and copy assignment operator.
|
||||
dtProximityGrid(const dtProximityGrid&);
|
||||
dtProximityGrid& operator=(const dtProximityGrid&);
|
||||
};
|
||||
|
||||
dtProximityGrid* dtAllocProximityGrid();
|
||||
void dtFreeProximityGrid(dtProximityGrid* ptr);
|
||||
|
||||
|
||||
#endif // DETOURPROXIMITYGRID_H
|
||||
|
Reference in New Issue
Block a user