Update Files

This commit is contained in:
2025-01-22 16:18:30 +01:00
parent ed4603cf95
commit a36294b518
16718 changed files with 2960346 additions and 0 deletions

View File

@ -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.
*/

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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