diff --git a/Detour/Include/DetourCommon.h b/Detour/Include/DetourCommon.h index b64abf0..0a5d2f8 100644 --- a/Detour/Include/DetourCommon.h +++ b/Detour/Include/DetourCommon.h @@ -19,6 +19,12 @@ #ifndef DETOURCOMMON_H #define DETOURCOMMON_H +/** + * @defgroup detour Detour + * Classes and functions related to path planning. + * @note This is a summary list. Use the index or documentation search + * functionality to find minor elements. + */ template inline void dtSwap(T& a, T& b) { T t = a; a = b; b = t; } template inline T dtMin(T a, T b) { return a < b ? a : b; } diff --git a/Detour/Include/DetourNavMesh.h b/Detour/Include/DetourNavMesh.h index fd16754..af9bf6b 100644 --- a/Detour/Include/DetourNavMesh.h +++ b/Detour/Include/DetourNavMesh.h @@ -26,283 +26,453 @@ // Note: If you want to use 64-bit refs, change the types of both dtPolyRef & dtTileRef. // It is also recommended to change dtHashRef() to proper 64-bit hash too. -/// Reference to navigation polygon. +/// A handle to a polygon within a navigation mesh tile. +/// @ingroup detour typedef unsigned int dtPolyRef; -/// Reference to navigation mesh tile. +/// A handle to a tile within a navigation mesh. +/// @ingroup detour typedef unsigned int dtTileRef; -/// Maximum number of vertices per navigation polygon. +/// The maximum number of vertices per navigation polygon. +/// @ingroup detour static const int DT_VERTS_PER_POLYGON = 6; -static const int DT_NAVMESH_MAGIC = 'D'<<24 | 'N'<<16 | 'A'<<8 | 'V'; ///< 'DNAV' +/// @{ +/// @name Tile Serialization Constants +/// These constants are used to detect whether a navigation tile's data +/// and state format is compatible with the current build. +/// + +/// A magic number used to detect compatibility of navigation tile data. +static const int DT_NAVMESH_MAGIC = 'D'<<24 | 'N'<<16 | 'A'<<8 | 'V'; + +/// A version number used to detect compatibility of navigation tile data. static const int DT_NAVMESH_VERSION = 7; -static const int DT_NAVMESH_STATE_MAGIC = 'D'<<24 | 'N'<<16 | 'M'<<8 | 'S'; ///< 'DNMS' +/// A magic number used to detect the compatibility of navigation tile states. +static const int DT_NAVMESH_STATE_MAGIC = 'D'<<24 | 'N'<<16 | 'M'<<8 | 'S'; + +/// A version number used to detect compatibility of navigation tile states. static const int DT_NAVMESH_STATE_VERSION = 1; +/// @} + +/// A flag that indicates that an entity links to an external entity. +/// (E.g. A polygon edge is a portal that links to another polygon.) static const unsigned short DT_EXT_LINK = 0x8000; + +/// A value that indicates the entity does not link to anything. static const unsigned int DT_NULL_LINK = 0xffffffff; + +/// A flag that indicates that an off-mesh connection can be traversed in both directions. (Is bi-directional.) static const unsigned int DT_OFFMESH_CON_BIDIR = 1; +/// The maximum number of user defined area ids. +/// @ingroup detour static const int DT_MAX_AREAS = 64; -/// Flags for addTile +/// Tile flags used for various functions and fields. +/// For an example, see dtNavMesh::addTile(). enum dtTileFlags { - DT_TILE_FREE_DATA = 0x01, ///< Navmesh owns the tile memory and should free it. + /// The navigation mesh owns the tile memory and is responsible for freeing it. + DT_TILE_FREE_DATA = 0x01, }; -/// Flags returned by findStraightPath(). +/// Vertex flags returned by dtNavMeshQuery::findStraightPath. enum dtStraightPathFlags { - DT_STRAIGHTPATH_START = 0x01, ///< The vertex is the start position. - DT_STRAIGHTPATH_END = 0x02, ///< The vertex is the end position. - DT_STRAIGHTPATH_OFFMESH_CONNECTION = 0x04, ///< The vertex is start of an off-mesh link. + DT_STRAIGHTPATH_START = 0x01, ///< The vertex is the start position in the path. + DT_STRAIGHTPATH_END = 0x02, ///< The vertex is the end position in the path. + DT_STRAIGHTPATH_OFFMESH_CONNECTION = 0x04, ///< The vertex is the start of an off-mesh connection. }; -/// Flags describing polygon properties. +/// Flags representing the type of a navigation mesh polygon. enum dtPolyTypes { - DT_POLYTYPE_GROUND = 0, ///< Regular ground polygons. - DT_POLYTYPE_OFFMESH_CONNECTION = 1, ///< Off-mesh connections. + /// The polygon is a standard convex polygon that is part of the surface of the mesh. + DT_POLYTYPE_GROUND = 0, + /// The polygon is an off-mesh connection consisting of two vertices. + DT_POLYTYPE_OFFMESH_CONNECTION = 1, }; -/// Structure describing the navigation polygon data. +/// Defines a polyogn within a dtMeshTile object. +/// @ingroup detour struct dtPoly { - unsigned int firstLink; ///< Index to first link in linked list. - unsigned short verts[DT_VERTS_PER_POLYGON]; ///< Indices to vertices of the poly. - unsigned short neis[DT_VERTS_PER_POLYGON]; ///< Refs to neighbours of the poly. - unsigned short flags; ///< Flags (see dtPolyFlags). - unsigned char vertCount; ///< Number of vertices. - unsigned char areaAndtype; ///< Bit packed: Area ID of the polygon, and Polygon type, see dtPolyTypes.. + /// Index to first link in linked list. (Or #DT_NULL_LINK if there is no link.) + unsigned int firstLink; + + /// The indices of the polygon's vertices. + /// The actual vertices are located in dtMeshTile::verts. + unsigned short verts[DT_VERTS_PER_POLYGON]; + + /// Packed data representing neighbor polygons references and flags for each edge. + unsigned short neis[DT_VERTS_PER_POLYGON]; + + /// The user defined polygon flags. + unsigned short flags; + + /// The number of vertices in the polygon. + unsigned char vertCount; + + /// The bit packed area id and polygon type. + /// @note Use the structure's set and get methods to acess this value. + unsigned char areaAndtype; + + /// Sets the user defined area id. [Limit: < #DT_MAX_AREAS] inline void setArea(unsigned char a) { areaAndtype = (areaAndtype & 0xc0) | (a & 0x3f); } + + /// Sets the polygon type. (See: #dtPolyTypes.) inline void setType(unsigned char t) { areaAndtype = (areaAndtype & 0x3f) | (t << 6); } + + /// Gets the user defined area id. inline unsigned char getArea() const { return areaAndtype & 0x3f; } + + /// Gets the polygon type. (See: #dtPolyTypes) inline unsigned char getType() const { return areaAndtype >> 6; } }; -/// Stucture describing polygon detail triangles. +/// Defines the location of detail sub-mesh data within a dtMeshTile. struct dtPolyDetail { - unsigned int vertBase; ///< Offset to detail vertex array. - unsigned int triBase; ///< Offset to detail triangle array. - unsigned char vertCount; ///< Number of vertices in the detail mesh. - unsigned char triCount; ///< Number of triangles. + unsigned int vertBase; ///< The offset of the vertices in the dtMeshTile::detailVerts array. + unsigned int triBase; ///< The offset of the triangles in the dtMeshTile::detailTris array. + unsigned char vertCount; ///< The number of vertices in the sub-mesh. + unsigned char triCount; ///< The number of triangles in the sub-mesh. }; -/// Stucture describing a link to another polygon. +/// Defines a link between polygons. +/// @note This structure is rarely if ever used by the end user. +/// @see dtMeshTile struct dtLink { - dtPolyRef ref; ///< Neighbour reference. - unsigned int next; ///< Index to next link. - unsigned char edge; ///< Index to polygon edge which owns this link. - unsigned char side; ///< If boundary link, defines on which side the link is. - unsigned char bmin, bmax; ///< If boundary link, defines the sub edge area. + dtPolyRef ref; ///< Neighbour reference. (The neighbor that is linked to.) + unsigned int next; ///< Index of the next link. + unsigned char edge; ///< Index of the polygon edge that owns this link. + unsigned char side; ///< If a boundary link, defines on which side the link is. + unsigned char bmin; ///< If a boundary link, defines the minimum sub-edge area. + unsigned char bmax; ///< If a boundary link, defines the maximum sub-edge area. }; +/// Bounding volume node. +/// @note This structure is rarely if ever used by the end user. +/// @see dtMeshTile struct dtBVNode { - unsigned short bmin[3], bmax[3]; ///< BVnode bounds - int i; ///< Index to item or if negative, escape index. + unsigned short bmin[3]; ///< Minimum bounds of the node's AABB. [(x, y, z)] + unsigned short bmax[3]; ///< Maximum bounds of the node's AABB. [(x, y, z)] + int i; ///< The node's index. (Negative for escape sequence.) }; +/// Defines an navigation mesh off-mesh connection within a dtMeshTile object. +/// An off-mesh connection is a user defined traversable connection made up to two vertices. struct dtOffMeshConnection { - float pos[6]; ///< Both end point locations. - float rad; ///< Link connection radius. - unsigned short poly; ///< Poly Id - unsigned char flags; ///< Link flags - unsigned char side; ///< End point side. - unsigned int userId; ///< User ID to identify this connection. + /// The endpoints of the connection. [(ax, ay, az, bx, by, bz)] + float pos[6]; + + /// The radius of the endpoints. [Limit: >= 0] + float rad; + + /// The polygon reference of the connection within the tile. + unsigned short poly; + + /// Link flags. + /// @note These are not the connection's user defined flags. Those are assigned via the + /// connection's dtPoly definition. These are link flags used for internal purposes. + unsigned char flags; + + /// End point side. + unsigned char side; + + /// The id of the offmesh connection. (User assigned when the navigation mesh is built.) + unsigned int userId; }; +/// Provides high level information related to a dtMeshTile object. +/// @ingroup detour struct dtMeshHeader { - int magic; ///< Magic number, used to identify the data. - int version; ///< Data version number. - int x, y, layer; ///< Location of the tile on the grid. - unsigned int userId; ///< User ID of the tile. - int polyCount; ///< Number of polygons in the tile. - int vertCount; ///< Number of vertices in the tile. - int maxLinkCount; ///< Number of allocated links. - int detailMeshCount; ///< Number of detail meshes. - int detailVertCount; ///< Number of detail vertices. - int detailTriCount; ///< Number of detail triangles. - int bvNodeCount; ///< Number of BVtree nodes. - int offMeshConCount; ///< Number of Off-Mesh links. - int offMeshBase; ///< Index to first polygon which is Off-Mesh link. - float walkableHeight; ///< Height of the agent. - float walkableRadius; ///< Radius of the agent - float walkableClimb; ///< Max climb height of the agent. - float bmin[3], bmax[3]; ///< Bounding box of the tile. - float bvQuantFactor; ///< BVtree quantization factor (world to bvnode coords) + int magic; ///< Tile magic number. (Used to identify the data format.) + int version; ///< Tile data format version number. + int x; ///< The x-position of the tile within the dtNavMesh tile grid. (x, y, layer) + int y; ///< The y-position of the tile within the dtNavMesh tile grid. (x, y, layer) + int layer; ///< The layer of the tile within the dtNavMesh tile grid. (x, y, layer) + unsigned int userId; ///< The user defined id of the tile. + int polyCount; ///< The number of polygons in the tile. + int vertCount; ///< The number of vertices in the tile. + int maxLinkCount; ///< The number of allocated links. + int detailMeshCount; ///< The number of sub-meshes in the detail mesh. + + /// The number of unique vertices in the detail mesh. (In addition to the polygon vertices.) + int detailVertCount; + + int detailTriCount; ///< The number of triangles in the detail mesh. + int bvNodeCount; ///< The number of bounding volume nodes. (Zero if bounding volumes are disabled.) + int offMeshConCount; ///< The number of off-mesh connections. + int offMeshBase; ///< The index of the first polygon which is an off-mesh connection. + float walkableHeight; ///< The height of the agents using the tile. + float walkableRadius; ///< The radius of the agents using the tile. + float walkableClimb; ///< The maximum climb height of the agents using the tile. + float bmin[3]; ///< The minimum bounds of the tile's AABB. [(x, y, z)] + float bmax[3]; ///< The maximum bounds of the tile's AABB. [(x, y, z)] + + /// The bounding volume quantization factor. + float bvQuantFactor; }; +/// Defines a navigation mesh tile. +/// @ingroup detour struct dtMeshTile { unsigned int salt; ///< Counter describing modifications to the tile. - unsigned int linksFreeList; ///< Index to next free link. - dtMeshHeader* header; ///< Pointer to tile header. - dtPoly* polys; ///< Pointer to the polygons (will be updated when tile is added). - float* verts; ///< Pointer to the vertices (will be updated when tile added). - dtLink* links; ///< Pointer to the links (will be updated when tile added). - dtPolyDetail* detailMeshes; ///< Pointer to detail meshes (will be updated when tile added). - float* detailVerts; ///< Pointer to detail vertices (will be updated when tile added). - unsigned char* detailTris; ///< Pointer to detail triangles (will be updated when tile added). - dtBVNode* bvTree; ///< Pointer to BVtree nodes (will be updated when tile added). - dtOffMeshConnection* offMeshCons; ///< Pointer to Off-Mesh links. (will be updated when tile added). + unsigned int linksFreeList; ///< Index to the next free link. + dtMeshHeader* header; ///< The tile header. + dtPoly* polys; ///< The tile polygons. [Size: dtMeshHeader::polyCount] + float* verts; ///< The tile vertices. [Size: dtMeshHeader::vertCount] + dtLink* links; ///< The tile links. [Size: dtMeshHeader::maxLinkCount] + dtPolyDetail* detailMeshes; ///< The tile's detail sub-meshes. [Size: dtMeshHeader::detailMeshCount] + + /// The detail mesh's unique vertices. [(x, y, z) * dtMeshHeader::detailVertCount] + float* detailVerts; + + /// The detail mesh's triangles. [(vertA, vertB, vertC) * dtMeshHeader::detailTriCount] + unsigned char* detailTris; + + /// The tile bounding volume nodes. [Size: dtMeshHeader::bvNodeCount] + /// (Will be null if bounding volumes are disabled.) + dtBVNode* bvTree; + + dtOffMeshConnection* offMeshCons; ///< The tile off-mesh connections. [Size: dtMeshHeader::offMeshConCount] - unsigned char* data; ///< Pointer to tile data. + unsigned char* data; ///< The tile data. (Not directly accessed under normal situations.) int dataSize; ///< Size of the tile data. - int flags; ///< Tile flags, see dtTileFlags. - dtMeshTile* next; ///< Next free tile or, next tile in spatial grid. + int flags; ///< Tile flags. (See: #dtTileFlags) + dtMeshTile* next; ///< The next free tile, or the next tile in the spatial grid. }; +/// Configutration parameters used to define multi-tile navigation meshes. +/// The values are used to allocate space during the initialization of a navigation mesh. +/// @see dtNavMesh::init() +/// @ingroup detour struct dtNavMeshParams { - float orig[3]; ///< Origin of the nav mesh tile space. - float tileWidth, tileHeight; ///< Width and height of each tile. - int maxTiles; ///< Maximum number of tiles the navmesh can contain. - int maxPolys; ///< Maximum number of polygons each tile can contain. + float orig[3]; ///< The world space origin of the navigation mesh's tile space. [(x, y, z)] + float tileWidth; ///< The width of each tile. (Along the x-axis.) + float tileHeight; ///< The height of each tile. (Along the z-axis.) + int maxTiles; ///< The maximum number of tiles the navigation mesh can contain. + int maxPolys; ///< The maximum number of polygons each tile can contain. }; - +/// A navigation mesh based on tiles of convex polygons. +/// @ingroup detour class dtNavMesh { public: dtNavMesh(); ~dtNavMesh(); - /// Initializes the nav mesh for tiled use. - /// @param params [in] navmesh initialization params, see dtNavMeshParams. - /// @return True if succeed, else false. + /// @{ + /// @name Initialization and Tile Management + + /// Initializes the navigation mesh for tiled use. + /// @param[in] params Initialization parameters. + /// @return The status flags for the operation. dtStatus init(const dtNavMeshParams* params); - /// Initializes the nav mesh for single tile use. - /// @param data - [in] Data of the new tile mesh. - /// @param dataSize - [in] Data size of the new tile mesh. - /// @param flags - [in] Tile flags, see dtTileFlags. - /// @return True if succeed, else false. + /// Initializes the navigation mesh for single tile use. + /// @param[in] data Data of the new tile. (See: #dtCreateNavMeshData) + /// @param[in] dataSize The data size of the new tile. + /// @param[in] flags The tile flags. (See: #dtTileFlags) + /// @return The status flags for the operation. + /// @see dtCreateNavMeshData dtStatus init(unsigned char* data, const int dataSize, const int flags); - /// Returns pointer to navmesh initialization params. + /// The navigation mesh initialization params. const dtNavMeshParams* getParams() const; - - /// Adds new tile into the navmesh. - /// The add will fail if the data is in wrong format, - /// there is not enough tiles left, or if there is a tile already at the location. - /// @param data [in] Data of the new tile mesh. - /// @param dataSize [in] Data size of the new tile mesh. - /// @param flags [in] Tile flags, see dtTileFlags. - /// @param lastRef [in,optional] Last tile ref, the tile will be restored so that - /// the reference (as well as poly references) will be the same. Default: 0. - /// @param result [out,optional] tile ref if the tile was succesfully added. + + /// Adds a tile to the navigation mesh. + /// @param[in] data Data for the new tile mesh. (See: #dtCreateNavMeshData) + /// @param[in] dataSize Data size of the new tile mesh. + /// @param[in] flags Tile flags. (See: #dtTileFlags) + /// @param[in] lastRef The desired reference for the tile. (When reloading a tile.) [opt] [Default: 0] + /// @param[out] result The tile reference. (If the tile was succesfully added.) [opt] + /// @return The status flags for the operation. dtStatus addTile(unsigned char* data, int dataSize, int flags, dtTileRef lastRef, dtTileRef* result); - /// Removes specified tile. - /// @param ref [in] Reference to the tile to remove. - /// @param data [out] Data associated with deleted tile. - /// @param dataSize [out] Size of the data associated with deleted tile. + /// Removes the specified tile from the navigation mesh. + /// @param[in] ref The reference of the tile to remove. + /// @param[out] data Data associated with deleted tile. + /// @param[out] dataSize Size of the data associated with deleted tile. + /// @return The status flags for the operation. dtStatus removeTile(dtTileRef ref, unsigned char** data, int* dataSize); - /// Calculates tile location based in input world position. - /// @param pos [in] world position of the query. - /// @param tx [out] tile x location. - /// @param ty [out] tile y location. + /// @} + + /// @{ + /// @name Query Functions + + /// Calculates the tile grid location for the specified world position. + /// @param[in] pos The world position for the query. [(x, y, z)] + /// @param[out] tx The tile's x-location. (x, y) + /// @param[out] ty The tile's y-location. (x, y) void calcTileLoc(const float* pos, int* tx, int* ty) const; - /// Returns pointer to tile at specified location. - /// @param x,y [in] Location of the tile to get. - /// @returns pointer to tile if tile exists or 0 tile does not exists. + /// Gets the tile at the specified grid location. + /// @param[in] x The tile's x-location. (x, y, layer) + /// @param[in] y The tile's y-location. (x, y, layer) + /// @param[in] layer The tile's layer. (x, y, layer) + /// @return The tile, or null if the tile does not exist. const dtMeshTile* getTileAt(const int x, const int y, const int layer) const; + /// Gets all tiles at the specified grid location. (All layers.) + /// @param[in] x The tile's x-location. (x, y) + /// @param[in] y The tile's y-location. (x, y) + /// @param[out] tiles A pointer to an array of tiles that will hold the result. + /// @param[in] maxTiles The maximum tiles the tiles parameter can hold. + /// @return The number of tiles returned in the tiles array. int getTilesAt(const int x, const int y, dtMeshTile const** tiles, const int maxTiles) const; - /// Returns reference to tile at specified location. - /// @param x,y [in] Location of the tile to get. - /// @returns reference to tile if tile exists or 0 tile does not exists. + /// Gets the tile reference for the tile at specified grid location. + /// @param[in] x The tile's x-location. (x, y, layer) + /// @param[in] y The tile's y-location. (x, y, layer) + /// @param[in] layer The tile's layer. (x, y, layer) + /// @return The tile reference of the tile, or 0 if there is none. dtTileRef getTileRefAt(int x, int y, int layer) const; - /// Returns tile references of a tile based on tile pointer. + /// Gets the tile reference for the specified tile. + /// @param[in] tile The tile. + /// @return The tile reference of the tile. dtTileRef getTileRef(const dtMeshTile* tile) const; - /// Returns tile based on references. + /// Gets the tile for the specified tile reference. + /// @param[in] ref The tile reference of the tile to retrieve. + /// @return The tile for the specified reference, or null if the + /// reference is invalid. const dtMeshTile* getTileByRef(dtTileRef ref) const; - /// Returns max number of tiles. + /// The maximum number of tiles supported by the navigation mesh. + /// @return The maximum number of tiles supported by the navigation mesh. int getMaxTiles() const; - /// Returns pointer to tile in the tile array. - /// @param i [in] Index to the tile to retrieve, max index is getMaxTiles()-1. - /// @returns Pointer to specified tile. + /// Gets the tile at the specified index. + /// @param[in] i The tile index. [Limit: 0 >= index < #getMaxTiles()] + /// @return The tile at the specified index. const dtMeshTile* getTile(int i) const; - /// Returns pointer to tile and polygon pointed by the polygon reference. - /// @param ref [in] reference to a polygon. - /// @param tile [out] pointer to the tile containing the polygon. - /// @param poly [out] pointer to the polygon. + /// Gets the tile and polygon for the specified polygon reference. + /// @param[in] ref The reference for the a polygon. + /// @param[out] tile The tile containing the polygon. + /// @param[out] poly The polygon. + /// @return The status flags for the operation. dtStatus getTileAndPolyByRef(const dtPolyRef ref, const dtMeshTile** tile, const dtPoly** poly) const; - /// Returns pointer to tile and polygon pointed by the polygon reference. - /// Note: this function does not check if 'ref' s valid, and is thus faster. Use only with valid refs! - /// - /// @param ref [in] reference to a polygon. - /// @param tile [out] pointer to the tile containing the polygon. - /// @param poly [out] pointer to the polygon. + /// Returns the tile and polygon for the specified polygon reference. + /// @param[in] ref A known valid reference for a polygon. + /// @param[out] tile The tile containing the polygon. + /// @param[out] poly The polygon. void getTileAndPolyByRefUnsafe(const dtPolyRef ref, const dtMeshTile** tile, const dtPoly** poly) const; - /// Returns true if polygon reference points to valid data. + /// Checks the validity of a polygon reference. + /// @param[in] ref The polygon reference to check. + /// @return True if polygon reference is valid for the navigation mesh. bool isValidPolyRef(dtPolyRef ref) const; - /// Returns base poly id for specified tile, polygon refs can be deducted from this. + /// Gets the polygon reference for the tile's base polygon. + /// @param[in] tile The tile. + /// @return The polygon reference for the base polygon in the specified tile. dtPolyRef getPolyRefBase(const dtMeshTile* tile) const; - /// Returns start and end location of an off-mesh link polygon. - /// @param prevRef [in] ref to the polygon before the link (used to select direction). - /// @param polyRef [in] ref to the off-mesh link polygon. - /// @param startPos[3] [out] start point of the link. - /// @param endPos[3] [out] end point of the link. - /// @returns true if link is found. + /// Gets the endpoints for an off-mesh connection, ordered by "direction of travel". + /// @param[in] prevRef The reference of the polygon before the connection. + /// @param[in] polyRef The reference of the off-mesh connection polygon. + /// @param[out] startPos The start position of the off-mesh connection. [(x, y, z)] + /// @param[out] endPos The end position of the off-mesh connection. [(x, y, z)] + /// @return The status flags for the operation. dtStatus getOffMeshConnectionPolyEndPoints(dtPolyRef prevRef, dtPolyRef polyRef, float* startPos, float* endPos) const; - /// Returns pointer to off-mesh connection based on polyref, or null if ref not valid. + /// Gets the specified off-mesh connection. + /// @param[in] ref The polygon reference of the off-mesh connection. + /// @return The specified off-mesh connection, or null if the polygon reference is not valid. const dtOffMeshConnection* getOffMeshConnectionByRef(dtPolyRef ref) const; - /// Sets polygon flags. + /// @} + + /// @{ + /// @name State Management + /// These functions do not effect #dtTileRef or #dtPolyRef's. + + /// Sets the user defined flags for the specified polygon. + /// @param[in] ref The polygon reference. + /// @param[in] flags The new flags for the polygon. + /// @return The status flags for the operation. dtStatus setPolyFlags(dtPolyRef ref, unsigned short flags); - /// Return polygon flags. + /// Gets the user defined flags for the specified polygon. + /// @param[in] ref The polygon reference. + /// @param[out] resultFlags The polygon flags. + /// @return The status flags for the operation. dtStatus getPolyFlags(dtPolyRef ref, unsigned short* resultFlags) const; - /// Set polygon type. + /// Sets the user defined area for the specified polygon. + /// @param[in] ref The polygon reference. + /// @param[in] area The new area id for the polygon. [Limit: < #DT_MAX_AREAS] + /// @return The status flags for the operation. dtStatus setPolyArea(dtPolyRef ref, unsigned char area); - /// Return polygon area type. + /// Gets the user defined area for the specified polygon. + /// @param[in] ref The polygon reference. + /// @param[out] resultArea The area id for the polygon. + /// @return The status flags for the operation. dtStatus getPolyArea(dtPolyRef ref, unsigned char* resultArea) const; - - /// Returns number of bytes required to store tile state. + /// Gets the size of the buffer required by #storeTileState to store the specified tile's state. + /// @param[in] tile The tile. + /// @return The size of the buffer required to store the state. int getTileStateSize(const dtMeshTile* tile) const; - /// Stores tile state to buffer. + /// Stores the non-structural state of the tile in the specified buffer. (Flags, area ids, etc.) + /// @param[in] tile The tile. + /// @param[out] data The buffer to store the tile's state in. + /// @param[in] maxDataSize The size of the data buffer. [Limit: >= #getTileStateSize] + /// @return The status flags for the operation. dtStatus storeTileState(const dtMeshTile* tile, unsigned char* data, const int maxDataSize) const; - /// Restores tile state. + /// Restores the state of the tile. + /// @param[in] tile The tile. + /// @param[in] data The new state. (Obtained from #storeTileState.) + /// @param[in] maxDataSize The size of the state within the data buffer. + /// @return The status flags for the operation. dtStatus restoreTileState(dtMeshTile* tile, const unsigned char* data, const int maxDataSize); + /// @} - /// Encodes a tile id. + /// @{ + /// @name Encoding and Decoding + /// These functions are generally meant for internal use only. + + /// Derives a standard polygon reference. + /// @note This function is generally meant for internal use only. + /// @param[in] salt The tile's salt value. + /// @param[in] it The index of the tile. + /// @param[in] ip The index of the polygon within the tile. inline dtPolyRef encodePolyId(unsigned int salt, unsigned int it, unsigned int ip) const { return ((dtPolyRef)salt << (m_polyBits+m_tileBits)) | ((dtPolyRef)it << m_polyBits) | (dtPolyRef)ip; } - /// Decodes a tile id. + /// Decodes a standard polygon reference. + /// @note This function is generally meant for internal use only. + /// @param[in] ref The polygon reference to decode. + /// @param[out] salt The tile's salt value. + /// @param[out] it The index of the tile. + /// @param[out] ip The index of the polygon within the tile. + /// @see #encodePolyId inline void decodePolyId(dtPolyRef ref, unsigned int& salt, unsigned int& it, unsigned int& ip) const { const dtPolyRef saltMask = ((dtPolyRef)1<> (m_polyBits+m_tileBits)) & saltMask); } - /// Decodes a tile id. + /// Extracts the tile's index from the specified polygon reference. + /// @note This function is generally meant for internal use only. + /// @param[in] ref The polygon reference. + /// @see #encodePolyId inline unsigned int decodePolyIdTile(dtPolyRef ref) const { const dtPolyRef tileMask = ((dtPolyRef)1<> m_polyBits) & tileMask); } - /// Decodes a poly id. + /// Extracts the polygon's index (within its tile) from the specified polygon reference. + /// @note This function is generally meant for internal use only. + /// @param[in] ref The polygon reference. + /// @see #encodePolyId inline unsigned int decodePolyIdPoly(dtPolyRef ref) const { const dtPolyRef polyMask = ((dtPolyRef)1<header->bvQuantFactor; +/// const dtBVNode* n = &tile->bvTree[i]; +/// if (n->i >= 0) +/// { +/// // This is a leaf node. +/// float worldMinX = tile->header->bmin[0] + n->bmin[0]*cs; +/// float worldMinY = tile->header->bmin[0] + n->bmin[1]*cs; +/// // Etc... +/// } +/// @endcode + +/// @struct dtMeshTile +/// @par +/// +/// Tiles generally only exist within the context of a dtNavMesh object. +/// +/// Some tile content is optional. For example, a tile may not contain any +/// off-mesh connections. In this case the associated pointer will be null. +/// +/// If a detail mesh exists it will share vertices with the base polygon mesh. +/// Only the vertices unique to the detail mesh will be stored in #detailVerts. +/// +/// @warning Tiles returned by a dtNavMesh object are not guarenteed to be populated. +/// For example: The tile at a location might not have been loaded yet, or may have been removed. +/// In this case, pointers will be null. So if in doubt, check the polygon count in the +/// tile's header to determine if a tile has polygons defined. + +/// @var float dtOffMeshConnection::pos[6] +/// @par +/// +/// For a properly built navigation mesh, vertex A will always be within the bounds of the mesh. +/// Vertex B is not required to be within the bounds of the mesh. +/// \ No newline at end of file diff --git a/Detour/Include/DetourNavMeshQuery.h b/Detour/Include/DetourNavMeshQuery.h index d178bec..7ca2fca 100644 --- a/Detour/Include/DetourNavMeshQuery.h +++ b/Detour/Include/DetourNavMeshQuery.h @@ -25,34 +25,26 @@ // Define DT_VIRTUAL_QUERYFILTER if you wish to derive a custom filter from dtQueryFilter. // On certain platforms indirect or virtual function call is expensive. The default -// setting is to use non-virtual functions, the actualy implementations of the functions +// setting is to use non-virtual functions, the actual implementations of the functions // are declared as inline for maximum speed. //#define DT_VIRTUAL_QUERYFILTER 1 -/// Class for polygon filtering and cost calculation during query operations. -/// - It is possible to derive a custom query filter from dtQueryFilter by overriding -/// the virtual functions passFilter() and getCost(). -/// - Both functions should be as fast as possible. Use cached local copy of data -/// instead of accessing your own objects where possible. -/// - You do not need to adhere to the flags and cost logic provided by the default -/// implementation. -/// - In order for the A* to work properly, the cost should be proportional to -/// the travel distance. Using cost modifier less than 1.0 is likely to lead -/// to problems during pathfinding. +/// Defines polygon filtering and traversal costs for navigation mesh query operations. +/// @ingroup detour class dtQueryFilter { - float m_areaCost[DT_MAX_AREAS]; ///< Array storing cost per area type, used by default implementation. - unsigned short m_includeFlags; ///< Include poly flags, used by default implementation. - unsigned short m_excludeFlags; ///< Exclude poly flags, used by default implementation. + float m_areaCost[DT_MAX_AREAS]; ///< Cost per area type. (Used by default implementation.) + unsigned short m_includeFlags; ///< Flags for polygons that can be visited. (Used by default implementation.) + unsigned short m_excludeFlags; ///< Flags for polygons that should not be visted. (Used by default implementation.) public: dtQueryFilter(); - /// Returns true if the polygon is can visited. - /// @param ref [in] reference to the polygon test. - /// @param tile [in] pointer to the tile of the polygon test. - /// @param poly [in] pointer to the polygon test. + /// Returns true if the polygon can be visited. (I.e. Is traversable.) + /// @param[in] ref The reference id of the polygon test. + /// @param[in] tile The tile containing the polygon. + /// @param[in] poly The polygon to test. #ifdef DT_VIRTUAL_QUERYFILTER virtual bool passFilter(const dtPolyRef ref, const dtMeshTile* tile, @@ -63,15 +55,19 @@ public: const dtPoly* poly) const; #endif - /// Returns cost to travel from 'pa' to 'pb'.' - /// The segment is fully contained inside 'cur'. - /// 'pa' lies on the edge between 'prev' and 'cur', - /// 'pb' lies on the edge between 'cur' and 'next'. - /// @param pa [in] segment start position. - /// @param pb [in] segment end position. - /// @param prevRef, prevTile, prevPoly [in] data describing the previous polygon, can be null. - /// @param curRef, curTile, curPoly [in] data describing the current polygon. - /// @param nextRef, nextTile, nextPoly [in] data describing the next polygon, can be null. + /// Returns cost to move from the beginning to the end of a line segment + /// that is fully contained within a polygon. + /// @param[in] pa The start position on the edge of the previous and current polygon. [(x, y, z)] + /// @param[in] pb The end position on the edge of the current and next polygon. [(x, y, z)] + /// @param[in] prevRef The reference id of the previous polygon. [opt] + /// @param[in] prevTile The tile containing the previous polygon. [opt] + /// @param[in] prevPoly The previous polygon. [opt] + /// @param[in] curRef The reference id of the current polygon. + /// @param[in] curTile The tile containing the current polygon. + /// @param[in] curPoly The current polygon. + /// @param[in] nextRef The refernece id of the next polygon. [opt] + /// @param[in] nextTile The tile containing the next polygon. [opt] + /// @param[in] nextPoly The next polygon. [opt] #ifdef DT_VIRTUAL_QUERYFILTER virtual float getCost(const float* pa, const float* pb, const dtPolyRef prevRef, const dtMeshTile* prevTile, const dtPoly* prevPoly, @@ -83,260 +79,321 @@ public: const dtPolyRef curRef, const dtMeshTile* curTile, const dtPoly* curPoly, const dtPolyRef nextRef, const dtMeshTile* nextTile, const dtPoly* nextPoly) const; #endif - + /// @name Getters and setters for the default implementation data. ///@{ + + /// Returns the traversal cost of the area. + /// @param[in] i The id of the area. + /// @returns The traversal cost of the area. inline float getAreaCost(const int i) const { return m_areaCost[i]; } + + /// Sets the traversal cost of the area. + /// @param[in] i The id of the area. + /// @param[in] cost The new cost of traversing the area. inline void setAreaCost(const int i, const float cost) { m_areaCost[i] = cost; } + /// Returns the include flags for the filter. + /// Any polygons that include one or more of these flags will be + /// included in the operation. inline unsigned short getIncludeFlags() const { return m_includeFlags; } + + /// Sets the include flags for the filter. + /// @param[in] flags The new flags. inline void setIncludeFlags(const unsigned short flags) { m_includeFlags = flags; } + /// Returns the exclude flags for the filter. + /// Any polygons that include one ore more of these flags will be + /// excluded from the operation. inline unsigned short getExcludeFlags() const { return m_excludeFlags; } + + /// Sets the exclude flags for the filter. + /// @param[in] flags The new flags. inline void setExcludeFlags(const unsigned short flags) { m_excludeFlags = flags; } + ///@} + }; +/// Provides the ability to perform pathfinding related queries against +/// a navigation mesh. +/// @ingroup detour class dtNavMeshQuery { public: dtNavMeshQuery(); ~dtNavMeshQuery(); - /// Initializes the nav mesh query. - /// @param nav [in] pointer to navigation mesh data. - /// @param maxNodes [in] Maximum number of search nodes to use (max 65536). + /// Initializes the query object. + /// @param[in] nav Pointer to the dtNavMesh object to use for all queries. + /// @param[in] maxNodes Maximum number of search nodes. [Limits: 0 < value <= 65536] + /// @returns The status flags for the query. dtStatus init(const dtNavMesh* nav, const int maxNodes); - /// Finds the nearest navigation polygon around the center location. - /// @param center[3] [in] The center of the search box. - /// @param extents[3] [in] The extents of the search box. - /// @param filter [in] path polygon filter. - /// @param nearestRef [out] Reference to the nearest polygon. - /// @param nearestPt[3] [out, opt] The nearest point on found polygon, null if not needed. - dtStatus findNearestPoly(const float* center, const float* extents, - const dtQueryFilter* filter, - dtPolyRef* nearestRef, float* nearestPt) const; - - /// Returns polygons which overlap the query box. - /// @param center[3] [in] the center of the search box. - /// @param extents[3] [in] the extents of the search box. - /// @param filter [in] path polygon filter. - /// @param polys [out] array holding the search result. - /// @param polyCount [out] Number of polygons in search result array. - /// @param maxPolys [in] The max number of polygons the polys array can hold. - dtStatus queryPolygons(const float* center, const float* extents, - const dtQueryFilter* filter, - dtPolyRef* polys, int* polyCount, const int maxPolys) const; - - /// Finds path from start polygon to end polygon. - /// If target polygon canno be reached through the navigation graph, - /// the last node on the array is nearest node to the end polygon. - /// Start end end positions are needed to calculate more accurate - /// traversal cost at start end end polygons. - /// @param startRef [in] ref to path start polygon. - /// @param endRef [in] ref to path end polygon. - /// @param startPos[3] [in] Path start location. - /// @param endPos[3] [in] Path end location. - /// @param filter [in] path polygon filter. - /// @param path [out] array holding the search result. - /// @param pathCount [out] Number of polygons in search result array. - /// @param maxPath [in] The max number of polygons the path array can hold. Must be at least 1. + /// @name Standard Pathfinding Functions + // /@{ + + /// Finds a path from the start polygon to the end polygon. + /// @param[in] startRef The refrence id of the start polygon. + /// @param[in] endRef The reference id of the end polygon. + /// @param[in] startPos A position within the start polygon. [(x, y, z)] + /// @param[in] endPos A position within the end polygon. [(x, y, z)] + /// @param[in] filter The polygon filter to apply to the query. + /// @param[out] path An ordered list of polygon references representing the path. (Start to end.) + /// [(polyRef) * @p pathCount] + /// @param[out] pathCount The number of polygons returned in the @p path array. + /// @param[in] maxPath The maximum number of polygons the @p path array can hold. [Limit: >= 1] dtStatus findPath(dtPolyRef startRef, dtPolyRef endRef, const float* startPos, const float* endPos, const dtQueryFilter* filter, dtPolyRef* path, int* pathCount, const int maxPath) const; - /// Intializes sliced path find query. - /// Note 1: calling any other dtNavMeshQuery method before calling findPathEnd() - /// may results in corrupted data! - /// Note 2: The pointer to filter is store, and used in subsequent - /// calls to updateSlicedFindPath(). - /// @param startRef [in] ref to path start polygon. - /// @param endRef [in] ref to path end polygon. - /// @param startPos[3] [in] Path start location. - /// @param endPos[3] [in] Path end location. - /// @param filter [in] path polygon filter. - dtStatus initSlicedFindPath(dtPolyRef startRef, dtPolyRef endRef, - const float* startPos, const float* endPos, - const dtQueryFilter* filter); - - /// Updates sliced path find query. - /// @param maxIter [in] Max number of iterations to update. - /// @param doneIters [out,opt] Number of iterations done during the update. - /// Returns: Path query state. - dtStatus updateSlicedFindPath(const int maxIter, int* doneIters); - - /// Finalizes sliced path find query and returns found path. - /// @param path [out] array holding the search result. - /// @param pathCount [out] Number of polygons in search result array. - /// @param maxPath [in] The max number of polygons the path array can hold. - dtStatus finalizeSlicedFindPath(dtPolyRef* path, int* pathCount, const int maxPath); - - /// Finalizes partial sliced path find query and returns path to the furthest - /// polygon on the existing path that was visited during the search. - /// @param existing [out] Array of polygons in the existing path. - /// @param existingSize [out] Number of polygons in existing path array. - /// @param path [out] array holding the search result. - /// @param pathCount [out] Number of polygons in search result array. - /// @param maxPath [in] The max number of polygons the path array can hold. - dtStatus finalizeSlicedFindPathPartial(const dtPolyRef* existing, const int existingSize, - dtPolyRef* path, int* pathCount, const int maxPath); - - /// Finds a straight path from start to end locations within the corridor - /// described by the path polygons. - /// Start and end locations will be clamped on the corridor. - /// The returned polygon references are point to polygon which was entered when - /// a path point was added. For the end point, zero will be returned. This allows - /// to match for example off-mesh link points to their representative polygons. - /// @param startPos[3] [in] Path start location. - /// @param endPos[3] [in] Path end location. - /// @param path [in] Array of connected polygons describing the corridor. - /// @param pathSize [in] Number of polygons in path array. - /// @param straightPath [out] Points describing the straight path. - /// @param straightPathFlags [out, opt] Flags describing each point type, see dtStraightPathFlags. - /// @param straightPathRefs [out, opt] References to polygons at point locations. - /// @param straightPathCount [out] Number of points in the path. - /// @param maxStraightPath [in] The max number of points the straight path array can hold. Must be at least 1. + /// Finds the straight path from the start to the end position within the polygon corridor. + /// @param[in] startPos Path start position. [(x, y, z)] + /// @param[in] endPos Path end position. [(x, y, z)] + /// @param[in] path An array of polygon references that represent the path corridor. + /// @param[in] pathSize The number of polygons in the @p path array. + /// @param[out] straightPath Points describing the straight path. [(x, y, z) * @p straightPathCount]. + /// @param[out] straightPathFlags Flags describing each point. (See: #dtStraightPathFlags) [opt] + /// @param[out] straightPathRefs The reference id of the polygon that is being entered at each point. [opt] + /// @param[out] straightPathCount The number of points in the straight path. + /// @param[in] maxStraightPath The maximum number of points the straight path arrays can hold. [Limit: > 0] + /// @returns The status flags for the query. dtStatus findStraightPath(const float* startPos, const float* endPos, const dtPolyRef* path, const int pathSize, float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs, int* straightPathCount, const int maxStraightPath) const; + + ///@} + /// @name Sliced Pathfinding Functions + /// Common use case: + /// -# Call initSlicedFindPath() to initialize the sliced path query. + /// -# Call updateSlicedFindPath() until it returns complete. + /// -# Call finalizeSlicedFindPath() to get the path. + ///@{ + + /// Intializes a sliced path query. + /// @param[in] startRef The refrence id of the start polygon. + /// @param[in] endRef The reference id of the end polygon. + /// @param[in] startPos A position within the start polygon. [(x, y, z)] + /// @param[in] endPos A position within the end polygon. [(x, y, z)] + /// @param[in] filter The polygon filter to apply to the query. + /// @returns The status flags for the query. + dtStatus initSlicedFindPath(dtPolyRef startRef, dtPolyRef endRef, + const float* startPos, const float* endPos, + const dtQueryFilter* filter); + + /// Updates an in-progress sliced path query. + /// @param[in] maxIter The maximum number of iterations to perform. + /// @param[out] doneIters The actual number of iterations completed. [opt] + /// @returns The status flags for the query. + dtStatus updateSlicedFindPath(const int maxIter, int* doneIters); + + /// Finalizes and returns the results of a sliced path query. + /// @param[out] path An ordered list of polygon references representing the path. (Start to end.) + /// [(polyRef) * @p pathCount] + /// @param[out] pathCount The number of polygons returned in the @p path array. + /// @param[in] maxPath The max number of polygons the path array can hold. [Limit: >= 1] + /// @returns The status flags for the query. + dtStatus finalizeSlicedFindPath(dtPolyRef* path, int* pathCount, const int maxPath); - /// Moves from startPos to endPos constrained to the navmesh. - /// If the endPos is reachable, the resultPos will be endPos, - /// or else the resultPos will be the nearest point in navmesh. - /// Note: The resulting point is not projected to the ground, use getPolyHeight() to get height. - /// Note: The algorithm is optimized for small delta movement and small number of polygons. - /// @param startRef [in] ref to the polygon where startPos lies. - /// @param startPos[3] [in] start position of the mover. - /// @param endPos[3] [in] desired end position of the mover. - /// @param filter [in] path polygon filter. - /// @param resultPos[3] [out] new position of the mover. - /// @param visited [out] array of visited polygons. - /// @param visitedCount [out] Number of entries in the visited array. - /// @param maxVisitedSize [in] max number of polygons in the visited array. - dtStatus moveAlongSurface(dtPolyRef startRef, const float* startPos, const float* endPos, - const dtQueryFilter* filter, - float* resultPos, dtPolyRef* visited, int* visitedCount, const int maxVisitedSize) const; - - /// Casts 'walkability' ray along the navmesh surface from startPos towards the endPos. - /// @param startRef [in] ref to the polygon where the start lies. - /// @param startPos[3] [in] start position of the query. - /// @param endPos[3] [in] end position of the query. - /// @param t [out] hit parameter along the segment, FLT_MAX if no hit. - /// @param hitNormal[3] [out] normal of the nearest hit. - /// @param filter [in] path polygon filter. - /// @param path [out,opt] visited path polygons. - /// @param pathCount [out,opt] Number of polygons visited. - /// @param maxPath [in] max number of polygons in the path array. - dtStatus raycast(dtPolyRef startRef, const float* startPos, const float* endPos, - const dtQueryFilter* filter, - float* t, float* hitNormal, dtPolyRef* path, int* pathCount, const int maxPath) const; - - /// Returns distance to nearest wall from the specified location. - /// @param startRef [in] ref to the polygon where the center lies. - /// @param centerPos[3] [in] center if the query circle. - /// @param maxRadius [in] max search radius. - /// @param filter [in] path polygon filter. - /// @param hitDist [out] distance to nearest wall from the test location. - /// @param hitPos[3] [out] location of the nearest hit. - /// @param hitNormal[3] [out] normal of the nearest hit. - dtStatus findDistanceToWall(dtPolyRef startRef, const float* centerPos, const float maxRadius, - const dtQueryFilter* filter, - float* hitDist, float* hitPos, float* hitNormal) const; - - /// Finds polygons found along the navigation graph which touch the specified circle. - /// @param startRef [in] ref to the polygon where the search starts. - /// @param centerPos[3] [in] center if the query circle. - /// @param radius [in] radius of the query circle. - /// @param filter [in] path polygon filter. - /// @param resultRef [out, opt] refs to the polygons touched by the circle. - /// @param resultParent [out, opt] parent of each result polygon. - /// @param resultCost [out, opt] search cost at each result polygon. - /// @param resultCount [out, opt] Number of results. - /// @param maxResult [int] maximum capacity of search results. + /// Finalizes and returns the results of an incomplete sliced path query, returning the path to the furthest + /// polygon on the existing path that was visited during the search. + /// @param[out] existing An array of polygon references for the existing path. + /// @param[out] existingSize The number of polygon in the @p existing array. + /// @param[out] path An ordered list of polygon references representing the path. (Start to end.) + /// [(polyRef) * @p pathCount] + /// @param[out] pathCount The number of polygons returned in the @p path array. + /// @param[in] maxPath The max number of polygons the @p path array can hold. [Limit: >= 1] + /// @returns The status flags for the query. + dtStatus finalizeSlicedFindPathPartial(const dtPolyRef* existing, const int existingSize, + dtPolyRef* path, int* pathCount, const int maxPath); + + ///@} + /// @name Dijkstra Search Functions + /// @{ + + /// Finds the polygons along the navigation graph that touch the specified circle. + /// @param[in] startRef The reference id of the polygon where the search starts. + /// @param[in] centerPos The center of the search circle. [(x, y, z)] + /// @param[in] radius The radius of the search circle. + /// @param[in] filter The polygon filter to apply to the query. + /// @param[out] resultRef The reference ids of the polygons touched by the circle. [opt] + /// @param[out] resultParent The reference ids of the parent polygons for each result. + /// Zero if a result polygon has no parent. [opt] + /// @param[out] resultCost The search cost from @p centerPos to the polygon. [opt] + /// @param[out] resultCount The number of polygons found. [opt] + /// @param[in] maxResult The maximum number of polygons the result arrays can hold. + /// @returns The status flags for the query. dtStatus findPolysAroundCircle(dtPolyRef startRef, const float* centerPos, const float radius, const dtQueryFilter* filter, dtPolyRef* resultRef, dtPolyRef* resultParent, float* resultCost, int* resultCount, const int maxResult) const; - /// Finds polygons found along the navigation graph which touch the convex polygon shape. - /// @param startRef [in] ref to the polygon where the search starts. - /// @param verts[3*n] [in] vertices describing convex polygon shape (CCW). - /// @param nverts [in] number of vertices in the polygon. - /// @param filter [in] path polygon filter. - /// @param resultRef [out, opt] refs to the polygons touched by the circle. - /// @param resultParent [out, opt] parent of each result polygon. - /// @param resultCost [out, opt] search cost at each result polygon. - /// @param resultCount [out] number of results. - /// @param maxResult [int] maximum capacity of search results. + /// Finds the polygons along the naviation graph that touch the specified convex polygon. + /// @param[in] startRef The reference id of the polygon where the search starts. + /// @param[in] verts The vertices describing the convex polygon. (CCW) + /// [(x, y, z) * @p nverts] + /// @param[in] nverts The number of vertices in the polygon. + /// @param[in] filter The polygon filter to apply to the query. + /// @param[out] resultRef The reference ids of the polygons touched by the search polygon. [opt] + /// @param[out] resultParent The reference ids of the parent polygons for each result. Zero if a + /// result polygon has no parent. [opt] + /// @param[out] resultCost The search cost from the centroid point to the polygon. [opt] + /// @param[out] resultCount The number of polygons found. + /// @param[in] maxResult The maximum number of polygons the result arrays can hold. + /// @returns The status flags for the query. dtStatus findPolysAroundShape(dtPolyRef startRef, const float* verts, const int nverts, const dtQueryFilter* filter, dtPolyRef* resultRef, dtPolyRef* resultParent, float* resultCost, int* resultCount, const int maxResult) const; - /// Finds non-overlapping local neighbourhood around center location. - /// Note: The algorithm is optimized for small query radius and small number of polygons. - /// @param startRef [in] ref to the polygon where the search starts. - /// @param centerPos[3] [in] center if the query circle. - /// @param radius [in] radius of the query circle. - /// @param filter [in] path polygon filter. - /// @param resultRef [out] refs to the polygons touched by the circle. - /// @param resultParent [out, opt] parent of each result polygon. - /// @param resultCount [out] number of results. - /// @param maxResult [int] maximum capacity of search results. + /// @} + /// @name Local Query Functions + ///@{ + + /// Finds the polygon nearest to the specified center point. + /// @param[in] center The center of the search box. [(x, y, z)] + /// @param[in] extents The search distance along each axis. [(x, y, z)] + /// @param[in] filter The polygon filter to apply to the query. + /// @param[out] nearestRef The reference id of the nearest polygon. + /// @param[out] nearestPt The nearest point on the polygon. [opt] [(x, y, z)] + /// @returns The status flags for the query. + dtStatus findNearestPoly(const float* center, const float* extents, + const dtQueryFilter* filter, + dtPolyRef* nearestRef, float* nearestPt) const; + + /// Finds polygons that overlap the search box. + /// @param[in] center The center of the search box. [(x, y, z)] + /// @param[in] extents The search distance along each axis. [(x, y, z)] + /// @param[in] filter The polygon filter to apply to the query. + /// @param[out] polys The reference ids of the polygons that overlap the query box. + /// @param[out] polyCount The number of polygons in the search result. + /// @param[in] maxPolys The maximum number of polygons the search result can hold. + /// @returns The status flags for the query. + dtStatus queryPolygons(const float* center, const float* extents, + const dtQueryFilter* filter, + dtPolyRef* polys, int* polyCount, const int maxPolys) const; + + /// Finds the non-overlapping navigation polygons in the local neighbourhood around the center position. + /// @param[in] startRef The reference id of the polygon where the search starts. + /// @param[in] centerPos The center of the query circle. [(x, y, z)] + /// @param[in] radius The radius of the query circle. + /// @param[in] filter The polygon filter to apply to the query. + /// @param[out] resultRef The reference ids of the polygons touched by the circle. + /// @param[out] resultParent The reference ids of the parent polygons for each result. + /// Zero if a result polygon has no parent. [opt] + /// @param[out] resultCount The number of polygons found. + /// @param[in] maxResult The maximum number of polygons the result arrays can hold. + /// @returns The status flags for the query. dtStatus findLocalNeighbourhood(dtPolyRef startRef, const float* centerPos, const float radius, const dtQueryFilter* filter, dtPolyRef* resultRef, dtPolyRef* resultParent, int* resultCount, const int maxResult) const; + + /// Moves from the start to the end position constrained to the navigation mesh. + /// @param[in] startRef The reference id of the start polygon. + /// @param[in] startPos A position of the mover within the start polygon. [(x, y, x)] + /// @param[in] endPos The desired end position of the mover. [(x, y, z)] + /// @param[in] filter The polygon filter to apply to the query. + /// @param[out] resultPos The result position of the mover. [(x, y, z)] + /// @param[out] visited The reference ids of the polygons visited during the move. + /// @param[out] visitedCount The number of polygons visited during the move. + /// @param[in] maxVisitedSize The maximum number of polygons the @p visited array can hold. + /// @returns The status flags for the query. + dtStatus moveAlongSurface(dtPolyRef startRef, const float* startPos, const float* endPos, + const dtQueryFilter* filter, + float* resultPos, dtPolyRef* visited, int* visitedCount, const int maxVisitedSize) const; - /// Returns wall segments of specified polygon. - /// If 'segmentRefs' is specified, both the wall and portal segments are returned. - /// Wall segments will have null (0) polyref, and portal segments store the polygon they lead to. - /// @param ref [in] ref to the polygon. - /// @param filter [in] path polygon filter. - /// @param segmentVerts[6*maxSegments] [out] wall segments (2 endpoints per segment). - /// @param segmentRefs[maxSegments] [out,opt] reference to a neighbour. - /// @param segmentCount [out] number of wall segments. - /// @param maxSegments [in] max number of segments that can be stored in 'segments'. + /// Casts a 'walkability' ray along the surface of the navigation mesh from + /// the start position toward the end position. + /// @param[in] startRef The reference id of the start polygon. + /// @param[in] startPos A position within the start polygon representing + /// the start of the ray. [(x, y, z)] + /// @param[in] endPos The position to cast the ray toward. [(x, y, z)] + /// @param[out] t The hit parameter. (FLT_MAX if no wall hit.) + /// @param[out] hitNormal The normal of the nearest wall hit. [(x, y, z)] + /// @param[in] filter The polygon filter to apply to the query. + /// @param[out] path The reference ids of the visited polygons. [opt] + /// @param[out] pathCount The number of visited polygons. [opt] + /// @param[in] maxPath The maximum number of polygons the @p path array can hold. + /// @returns The status flags for the query. + dtStatus raycast(dtPolyRef startRef, const float* startPos, const float* endPos, + const dtQueryFilter* filter, + float* t, float* hitNormal, dtPolyRef* path, int* pathCount, const int maxPath) const; + + /// Finds the distance from the specified position to the nearest polygon wall. + /// @param[in] startRef The reference id of the polygon containing @p centerPos. + /// @param[in] centerPos The center of the search circle. [(x, y, z)] + /// @param[in] maxRadius The radius of the search circle. + /// @param[in] filter The polygon filter to apply to the query. + /// @param[out] hitDist The distance to the nearest wall from @p centerPos. + /// @param[out] hitPos The nearest position on the wall that was hit. [(x, y, z)] + /// @param[out] hitNormal The normalized ray formed from the wall point to the + /// source point. [(x, y, z)] + /// @returns The status flags for the query. + dtStatus findDistanceToWall(dtPolyRef startRef, const float* centerPos, const float maxRadius, + const dtQueryFilter* filter, + float* hitDist, float* hitPos, float* hitNormal) const; + + /// Returns the segments for the specified polygon, optionally including portals. + /// @param[in] ref The reference id of the polygon. + /// @param[in] filter The polygon filter to apply to the query. + /// @param[out] segmentVerts The segments. [(ax, ay, az, bx, by, bz) * segmentCount] + /// @param[out] segmentRefs The reference ids of each segment's neighbor polygon. + /// Or zero if the segment is a wall. [opt] [(parentRef) * @p segmentCount] + /// @param[out] segmentCount The number of segments returned. + /// @param[in] maxSegments The maximum number of segments the result arrays can hold. + /// @returns The status flags for the query. dtStatus getPolyWallSegments(dtPolyRef ref, const dtQueryFilter* filter, float* segmentVerts, dtPolyRef* segmentRefs, int* segmentCount, const int maxSegments) const; - /// Returns closest point on navigation polygon. - /// Uses detail polygons to find the closest point to the navigation polygon surface. - /// @param ref [in] ref to the polygon. - /// @param pos[3] [in] the point to check. - /// @param closest[3] [out] closest point. - /// @returns true if closest point found. + /// Finds the closest point on the specified polygon. + /// @param[in] ref The reference id of the polygon. + /// @param[in] pos The position to check. [(x, y, z)] + /// @param[out] closest The closest point on the polygon. [(x, y, z)] + /// @returns The status flags for the query. dtStatus closestPointOnPoly(dtPolyRef ref, const float* pos, float* closest) const; - /// Returns closest point on navigation polygon boundary. - /// Uses the navigation polygon boundary to snap the point to poly boundary - /// if it is outside the polygon. Much faster than closestPointToPoly. Does not affect height. - /// @param ref [in] ref to the polygon. - /// @param pos[3] [in] the point to check. - /// @param closest[3] [out] closest point. - /// @returns true if closest point found. + /// Returns a point on the boundary closest to the source point if the source point is outside the + /// polygon's xz-bounds. + /// @param[in] ref The reference id to the polygon. + /// @param[in] pos The position to check. [(x, y, z)] + /// @param[out] closest The closest point. [(x, y, z)] + /// @returns The status flags for the query. dtStatus closestPointOnPolyBoundary(dtPolyRef ref, const float* pos, float* closest) const; - /// Returns height of the polygon at specified location. - /// @param ref [in] ref to the polygon. - /// @param pos[3] [in] the point where to locate the height. - /// @param height [out] height at the location. - /// @returns true if over polygon. + /// Gets the height of the polygon at the provided position using the height detail. (Most accurate.) + /// @param[in] ref The reference id of the polygon. + /// @param[in] pos A position within the xz-bounds of the polygon. [(x, y, z)] + /// @param[out] height The height at the surface of the polygon. + /// @returns The status flags for the query. dtStatus getPolyHeight(dtPolyRef ref, const float* pos, float* height) const; - - // Returns true if polygon reference points to valid data and passes the filter. - bool isValidPolyRef(dtPolyRef ref, const dtQueryFilter* filter) const; - - // Returns true if poly reference ins in closed list. + + /// @} + /// @name Miscellaneous Functions + /// @{ + + /// Returns true if the polygon reference is valid and passes the filter restrictions. + /// @param[in] ref The polygon reference to check. + /// @param[in] filter The filter to apply. + bool isValidPolyRef(dtPolyRef ref, const dtQueryFilter* filter) const; + + /// Returns true if the polygon reference is in the closed list. + /// @param[in] ref The reference id of the polygon to check. + /// @returns True if the polygon is in closed list. bool isInClosedList(dtPolyRef ref) const; + /// Gets the node pool. + /// @returns The node pool. class dtNodePool* getNodePool() const { return m_nodePool; } + /// Gets the navigation mesh the query object is using. + /// @return The navigation mesh the query object is using. const dtNavMesh* getAttachedNavMesh() const { return m_nav; } + + /// @} private: @@ -383,8 +440,14 @@ private: class dtNodeQueue* m_openList; ///< Pointer to open list queue. }; -/// Helper function to allocate navmesh query class using Detour allocator. +/// Allocates a query object using the Detour allocator. +/// @return An allocated query object, or null on failure. +/// @ingroup detour dtNavMeshQuery* dtAllocNavMeshQuery(); + +/// Frees the specified query object using the Detour allocator. +/// @param[in] query A query object allocated using #dtAllocNavMeshQuery +/// @ingroup detour void dtFreeNavMeshQuery(dtNavMeshQuery* query); #endif // DETOURNAVMESHQUERY_H diff --git a/Detour/Source/DetourNavMesh.cpp b/Detour/Source/DetourNavMesh.cpp index 0a84e37..8587c62 100644 --- a/Detour/Source/DetourNavMesh.cpp +++ b/Detour/Source/DetourNavMesh.cpp @@ -142,6 +142,10 @@ dtNavMesh* dtAllocNavMesh() return new(mem) dtNavMesh; } +/// @par +/// +/// This function will only free the memory for tiles with the #DT_TILE_FREE_DATA +/// flag set. void dtFreeNavMesh(dtNavMesh* navmesh) { if (!navmesh) return; @@ -150,6 +154,19 @@ void dtFreeNavMesh(dtNavMesh* navmesh) } ////////////////////////////////////////////////////////////////////////////////////////// + +/// @class dtNavMesh +/// +/// This class is usually used in conjunction with the dtNavMeshQuery class. +/// +/// Technically, all navigation meshes are tiled. A 'solo' mesh is simply a navigation mesh initialized +/// to have only a single tile. +/// +/// This class does not implement any asynchronous methods. So the ::dtStatus result of all methods will +/// always contain either a success or failure flag. +/// +/// @see dtNavMeshQuery, dtCreateNavMeshData(), dtNavMeshCreateParams, #dtAllocNavMesh, #dtFreeNavMesh + dtNavMesh::dtNavMesh() : m_tileWidth(0), m_tileHeight(0), @@ -246,6 +263,10 @@ dtStatus dtNavMesh::init(unsigned char* data, const int dataSize, const int flag return addTile(data, dataSize, flags, 0, 0); } +/// @par +/// +/// @note The parameters are created automatically when the single tile +/// initialization is performed. const dtNavMeshParams* dtNavMesh::getParams() const { return &m_params; @@ -726,6 +747,17 @@ int dtNavMesh::queryPolygonsInTile(const dtMeshTile* tile, const float* qmin, co } } +/// @par +/// +/// The add operation will fail if the data is in the wrong format, the allocated tile +/// space is full, or there is a tile already at the specified reference. +/// +/// The lastRef parameter is used to restore a tile with the same tile +/// reference it had previously used. In this case the #dtPolyRef's for the +/// tile will be restored to the same values they were before the tile was +/// removed. +/// +/// @see dtCreateNavMeshData, #removeTile dtStatus dtNavMesh::addTile(unsigned char* data, int dataSize, int flags, dtTileRef lastRef, dtTileRef* result) { @@ -922,6 +954,10 @@ int dtNavMesh::getTilesAt(const int x, const int y, dtMeshTile** tiles, const in return n; } +/// @par +/// +/// This function will not fail if the tiles array is too small to hold the +/// entire result set. It will simply fill the array to capacity. int dtNavMesh::getTilesAt(const int x, const int y, dtMeshTile const** tiles, const int maxTiles) const { int n = 0; @@ -1012,6 +1048,11 @@ dtStatus dtNavMesh::getTileAndPolyByRef(const dtPolyRef ref, const dtMeshTile** return DT_SUCCESS; } +/// @par +/// +/// @warning Only use this function if it is known that the provided polygon +/// reference is valid. This function is faster than #getTileAndPolyByRef, but +/// it does not validate the reference. void dtNavMesh::getTileAndPolyByRefUnsafe(const dtPolyRef ref, const dtMeshTile** tile, const dtPoly** poly) const { unsigned int salt, it, ip; @@ -1031,6 +1072,12 @@ bool dtNavMesh::isValidPolyRef(dtPolyRef ref) const return true; } +/// @par +/// +/// This function returns the data for the tile so that, if desired, +/// it can be added back to the navigation mesh at a later point. +/// +/// @see #addTile dtStatus dtNavMesh::removeTile(dtTileRef ref, unsigned char** data, int* dataSize) { if (!ref) @@ -1130,6 +1177,20 @@ dtTileRef dtNavMesh::getTileRef(const dtMeshTile* tile) const return (dtTileRef)encodePolyId(tile->salt, it, 0); } +/// @par +/// +/// Example use case: +/// @code +/// +/// const dtPolyRef base = navmesh->getPolyRefBase(tile); +/// for (int i = 0; i < tile->header->polyCount; ++i) +/// { +/// const dtPoly* p = &tile->polys[i]; +/// const dtPolyRef ref = base | (dtPolyRef)i; +/// +/// // Use the reference to access the polygon data. +/// } +/// @endcode dtPolyRef dtNavMesh::getPolyRefBase(const dtMeshTile* tile) const { if (!tile) return 0; @@ -1150,6 +1211,7 @@ struct dtPolyState unsigned char area; // Area ID of the polygon. }; +/// @see #storeTileState int dtNavMesh::getTileStateSize(const dtMeshTile* tile) const { if (!tile) return 0; @@ -1158,6 +1220,11 @@ int dtNavMesh::getTileStateSize(const dtMeshTile* tile) const return headerSize + polyStateSize; } +/// @par +/// +/// Tile state includes non-structural data such as polygon flags, area ids, etc. +/// @note The state data is only valid until the tile reference changes. +/// @see #getTileStateSize, #restoreTileState dtStatus dtNavMesh::storeTileState(const dtMeshTile* tile, unsigned char* data, const int maxDataSize) const { // Make sure there is enough space to store the state. @@ -1185,6 +1252,11 @@ dtStatus dtNavMesh::storeTileState(const dtMeshTile* tile, unsigned char* data, return DT_SUCCESS; } +/// @par +/// +/// Tile state includes non-structural data such as polygon flags, area ids, etc. +/// @note This function does not impact the tile's #dtTileRef and #dtPolyRef's. +/// @see #storeTileState dtStatus dtNavMesh::restoreTileState(dtMeshTile* tile, const unsigned char* data, const int maxDataSize) { // Make sure there is enough space to store the state. @@ -1215,7 +1287,13 @@ dtStatus dtNavMesh::restoreTileState(dtMeshTile* tile, const unsigned char* data return DT_SUCCESS; } -// Returns start and end location of an off-mesh link polygon. +/// @par +/// +/// Off-mesh connections are stored in the navigation mesh as special 2-vertex +/// polygons with a single edge. At least one of the vertices is expected to be +/// inside a normal polygon. So an off-mesh connection is "entered" from a +/// normal polygon at one of its endpoints. This is the polygon identified by +/// the prevRef parameter. dtStatus dtNavMesh::getOffMeshConnectionPolyEndPoints(dtPolyRef prevRef, dtPolyRef polyRef, float* startPos, float* endPos) const { unsigned int salt, it, ip; diff --git a/Detour/Source/DetourNavMeshQuery.cpp b/Detour/Source/DetourNavMeshQuery.cpp index 48b6bb4..af2eee4 100644 --- a/Detour/Source/DetourNavMeshQuery.cpp +++ b/Detour/Source/DetourNavMeshQuery.cpp @@ -27,6 +27,38 @@ #include "DetourAssert.h" #include +/// @class dtQueryFilter +/// +/// The Default Implmentation +/// +/// At construction: All area costs default to 1.0. All flags are included +/// and none are excluded. +/// +/// If a polygon has both an include and an exclude flag, it will be excluded. +/// +/// The way filtering works, a navigation mesh polygon must have at least one flag +/// set to ever be considered by a query. So a polygon with no flags will never +/// be considered. +/// +/// Setting the include flags to 0 will result in all polygons being excluded. +/// +/// Custom Implementations +/// +/// DT_VIRTUAL_QUERYFILTER must be defined in order to extend this class. +/// +/// Implement a custom query filter by overriding the virtual passFilter() +/// and getCost() functions. If this is done, both functions should be as +/// fast as possible. Use cached local copies of data rather than accessing +/// your own objects where possible. +/// +/// Custom implementations do not need to adhere to the flags or cost logic +/// used by the default implementation. +/// +/// In order for A* searches to work properly, the cost should be proportional to +/// the travel distance. Implementing a cost modifier less than 1.0 is likely +/// to lead to problems during pathfinding. +/// +/// @see dtNavMeshQuery dtQueryFilter::dtQueryFilter() : m_includeFlags(0xffff), @@ -86,6 +118,23 @@ void dtFreeNavMeshQuery(dtNavMeshQuery* navmesh) } ////////////////////////////////////////////////////////////////////////////////////////// + +/// @class dtNavMeshQuery +/// +/// For methods that support undersized buffers, if the buffer is too small +/// to hold the entire result set the return status of the method will include +/// the #DT_BUFFER_TOO_SMALL flag. +/// +/// Constant member functions can be used by multiple clients without side +/// effects. (E.g. No change to the closed list. No impact on an in-progress +/// sliced path query. Etc.) +/// +/// Walls and portals: A @e wall is a polygon segment that is +/// considered impassable. A @e portal is a passable segment between polygons. +/// A portal may be treated as a wall based on the dtQueryFilter used for a query. +/// +/// @see dtNavMesh, dtQueryFilter, #dtAllocNavMeshQuery(), #dtAllocNavMeshQuery() + dtNavMeshQuery::dtNavMeshQuery() : m_tinyNodePool(0), m_nodePool(0), @@ -107,6 +156,12 @@ dtNavMeshQuery::~dtNavMeshQuery() dtFree(m_openList); } +/// @par +/// +/// Must be the first function called after construction, before other +/// functions are used. +/// +/// This function can be used multiple times. dtStatus dtNavMeshQuery::init(const dtNavMesh* nav, const int maxNodes) { m_nav = nav; @@ -161,6 +216,15 @@ dtStatus dtNavMeshQuery::init(const dtNavMesh* nav, const int maxNodes) } ////////////////////////////////////////////////////////////////////////////////////////// + +/// @par +/// +/// Uses the detail polygons to find the surface height. (Most accurate.) +/// +/// @p pos does not have to be within the bounds of the polygon or navigation mesh. +/// +/// See closestPointOnPolyBoundary() for a limited but faster option. +/// dtStatus dtNavMeshQuery::closestPointOnPoly(dtPolyRef ref, const float* pos, float* closest) const { dtAssert(m_nav); @@ -257,6 +321,17 @@ void dtNavMeshQuery::closestPointOnPolyInTile(const dtMeshTile* tile, const dtPo } } +/// @par +/// +/// Much faster than closestPointOnPoly(). +/// +/// If the provided position lies within the polygon's xz-bounds (above or below), +/// then @p pos and @p closest will be equal. +/// +/// The height of @p closest will be the polygon boundary. The height detail is not used. +/// +/// @p pos does not have to be within the bounds of the polybon or the navigation mesh. +/// dtStatus dtNavMeshQuery::closestPointOnPolyBoundary(dtPolyRef ref, const float* pos, float* closest) const { dtAssert(m_nav); @@ -304,7 +379,11 @@ dtStatus dtNavMeshQuery::closestPointOnPolyBoundary(dtPolyRef ref, const float* return DT_SUCCESS; } - +/// @par +/// +/// Will return #DT_FAILURE if the provided position is outside the xz-bounds +/// of the polygon. +/// dtStatus dtNavMeshQuery::getPolyHeight(dtPolyRef ref, const float* pos, float* height) const { dtAssert(m_nav); @@ -353,6 +432,12 @@ dtStatus dtNavMeshQuery::getPolyHeight(dtPolyRef ref, const float* pos, float* h return DT_FAILURE | DT_INVALID_PARAM; } +/// @par +/// +/// @note If the search box does not intersect any polygons the search will +/// return #DT_SUCCESS, but @p nearestRef will be zero. So if in doubt, check +/// @p nearestRef before using @p nearestPt. +/// dtStatus dtNavMeshQuery::findNearestPoly(const float* center, const float* extents, const dtQueryFilter* filter, dtPolyRef* nearestRef, float* nearestPt) const @@ -519,6 +604,15 @@ int dtNavMeshQuery::queryPolygonsInTile(const dtMeshTile* tile, const float* qmi } } +/// @par +/// +/// If no polygons are found, the function will return #DT_SUCCESS with a +/// @p polyCount of zero. +/// +/// If @p polys is too small to hold the entire result set, then the array will +/// be filled to capacity. The method of choosing which polygons from the +/// full set are included in the partial result set is undefined. +/// dtStatus dtNavMeshQuery::queryPolygons(const float* center, const float* extents, const dtQueryFilter* filter, dtPolyRef* polys, int* polyCount, const int maxPolys) const @@ -559,6 +653,17 @@ dtStatus dtNavMeshQuery::queryPolygons(const float* center, const float* extents return DT_SUCCESS; } +/// @par +/// +/// If the end polygon cannot be reached through the navigation graph, +/// the last polygon in the path will be the nearest the end polygon. +/// +/// If the path array is to small to hold the full result, it will be filled as +/// far as possible from the start polygon toward the end polygon. +/// +/// The start and end positions are used to calculate traversal costs. +/// (The y-values impact the result.) +/// dtStatus dtNavMeshQuery::findPath(dtPolyRef startRef, dtPolyRef endRef, const float* startPos, const float* endPos, const dtQueryFilter* filter, @@ -769,6 +874,14 @@ dtStatus dtNavMeshQuery::findPath(dtPolyRef startRef, dtPolyRef endRef, return status; } +/// @par +/// +/// @warning Calling any non-slice methods before calling finalizeSlicedFindPath() +/// or finalizeSlicedFindPathPartial() may result in corrupted data! +/// +/// The @p filter pointer is stored and used for the duration of the sliced +/// path query. +/// dtStatus dtNavMeshQuery::initSlicedFindPath(dtPolyRef startRef, dtPolyRef endRef, const float* startPos, const float* endPos, const dtQueryFilter* filter) @@ -1134,7 +1247,23 @@ dtStatus dtNavMeshQuery::finalizeSlicedFindPathPartial(const dtPolyRef* existing return DT_SUCCESS | details; } - +/// @par +/// +/// This method peforms what is often called 'string pulling'. +/// +/// The start position is clamped to the first polygon in the path, and the +/// end position is clamped to the last. So the start and end positions should +/// normally be within or very near the first and last polygons respectively. +/// +/// The returned polygon references represent the reference id of the polygon +/// that is entered at the associated path position. The reference id associated +/// with the end point will always be zero. This allows, for example, matching +/// off-mesh link points to their representative polygons. +/// +/// If the provided result buffers are too small for the entire result set, +/// they will be filled as far as possible from the start toward the end +/// position. +/// dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* endPos, const dtPolyRef* path, const int pathSize, float* straightPath, unsigned char* straightPathFlags, dtPolyRef* straightPathRefs, @@ -1378,6 +1507,26 @@ dtStatus dtNavMeshQuery::findStraightPath(const float* startPos, const float* en return DT_SUCCESS | ((n >= maxStraightPath) ? DT_BUFFER_TOO_SMALL : 0); } +/// @par +/// +/// This method is optimized for small delta movement and a small number of +/// polygons. If used for too great a distance, the result set will form an +/// incomplete path. +/// +/// @p resultPos will equal the @p endPos if the end is reached. +/// Otherwise the closest reachable position will be returned. +/// +/// @p resultPos is not projected onto the surface of the navigation +/// mesh. Use #getPolyHeight if this is needed. +/// +/// This method treats the end position in the same manner as +/// the #raycast method. (As a 2D point.) See that method's documentation +/// for details. +/// +/// If the @p visited array is too small to hold the entire result set, it will +/// be filled as far as possible from the start position toward the end +/// position. +/// dtStatus dtNavMeshQuery::moveAlongSurface(dtPolyRef startRef, const float* startPos, const float* endPos, const dtQueryFilter* filter, float* resultPos, dtPolyRef* visited, int* visitedCount, const int maxVisitedSize) const @@ -1696,6 +1845,44 @@ dtStatus dtNavMeshQuery::getEdgeMidPoint(dtPolyRef from, const dtPoly* fromPoly, return DT_SUCCESS; } +/// @par +/// +/// This method is meant to be used for quick, short distance checks. +/// +/// If the path array is too small to hold the result, it will be filled as +/// far as possible from the start postion toward the end position. +/// +/// Using the Hit Parameter (t) +/// +/// If the hit parameter is a very high value (FLT_MAX), then the ray has hit +/// the end position. In this case the path represents a valid corridor to the +/// end position and the value of @p hitNormal is undefined. +/// +/// If the hit parameter is zero, then the start position is on the wall that +/// was hit and the value of @p hitNormal is undefined. +/// +/// If 0 < t < 1.0 then the following applies: +/// +/// @code +/// distanceToHitBorder = distanceToEndPosition * t +/// hitPoint = startPos + (endPos - startPos) * t +/// @endcode +/// +/// Use Case Restriction +/// +/// The raycast ignores the y-value of the end position. (2D check.) This +/// places significant limits on how it can be used. For example: +/// +/// Consider a scene where there is a main floor with a second floor balcony +/// that hangs over the main floor. So the first floor mesh extends below the +/// balcony mesh. The start position is somewhere on the first floor. The end +/// position is on the balcony. +/// +/// The raycast will search toward the end position along the first floor mesh. +/// If it reaches the end position's xz-coordinates it will indicate FLT_MAX +/// (no wall hit), meaning it reached the end position. This is one example of why +/// this method is meant for short distance checks. +/// dtStatus dtNavMeshQuery::raycast(dtPolyRef startRef, const float* startPos, const float* endPos, const dtQueryFilter* filter, float* t, float* hitNormal, dtPolyRef* path, int* pathCount, const int maxPath) const @@ -1877,6 +2064,35 @@ dtStatus dtNavMeshQuery::raycast(dtPolyRef startRef, const float* startPos, cons return status; } +/// @par +/// +/// At least one result array must be provided. +/// +/// The order of the result set is from least to highest cost to reach the polygon. +/// +/// A common use case for this method is to perform Dijkstra searches. +/// Candidate polygons are found by searching the graph beginning at the start polygon. +/// +/// If a polygon is not found via the graph search, even if it intersects the +/// search circle, it will not be included in the result set. For example: +/// +/// polyA is the start polygon. +/// polyB shares an edge with polyA. (Is adjacent.) +/// polyC shares an edge with polyB, but not with polyA +/// Even if the search circle overlaps polyC, it will not be included in the +/// result set unless polyB is also in the set. +/// +/// The value of the center point is used as the start position for cost +/// calculations. It is not projected onto the surface of the mesh, so its +/// y-value will effect the costs. +/// +/// Intersection tests occur in 2D. All polygons and the search circle are +/// projected onto the xz-plane. So the y-value of the center point does not +/// effect intersection tests. +/// +/// If the result arrays are to small to hold the entire result set, they will be +/// filled to capacity. +/// dtStatus dtNavMeshQuery::findPolysAroundCircle(dtPolyRef startRef, const float* centerPos, const float radius, const dtQueryFilter* filter, dtPolyRef* resultRef, dtPolyRef* resultParent, float* resultCost, @@ -2030,6 +2246,28 @@ dtStatus dtNavMeshQuery::findPolysAroundCircle(dtPolyRef startRef, const float* return status; } +/// @par +/// +/// The order of the result set is from least to highest cost. +/// +/// At least one result array must be provided. +/// +/// A common use case for this method is to perform Dijkstra searches. +/// Candidate polygons are found by searching the graph beginning at the start +/// polygon. +/// +/// The same intersection test restrictions that apply to findPolysAroundCircle() +/// method apply to this method. +/// +/// The 3D centroid of the search polygon is used as the start position for cost +/// calculations. +/// +/// Intersection tests occur in 2D. All polygons are projected onto the +/// xz-plane. So the y-values of the vertices do not effect intersection tests. +/// +/// If the result arrays are is too small to hold the entire result set, they will +/// be filled to capacity. +/// dtStatus dtNavMeshQuery::findPolysAroundShape(dtPolyRef startRef, const float* verts, const int nverts, const dtQueryFilter* filter, dtPolyRef* resultRef, dtPolyRef* resultParent, float* resultCost, @@ -2188,6 +2426,28 @@ dtStatus dtNavMeshQuery::findPolysAroundShape(dtPolyRef startRef, const float* v return status; } +/// @par +/// +/// This method is optimized for a small search radius and small number of result +/// polygons. +/// +/// Candidate polygons are found by searching the navigation graph beginning at +/// the start polygon. +/// +/// The same intersection test restrictions that apply to the findPolysAroundCircle +/// mehtod applies to this method. +/// +/// The value of the center point is used as the start point for cost calculations. +/// It is not projected onto the surface of the mesh, so its y-value will effect +/// the costs. +/// +/// Intersection tests occur in 2D. All polygons and the search circle are +/// projected onto the xz-plane. So the y-value of the center point does not +/// effect intersection tests. +/// +/// If the result arrays are is too small to hold the entire result set, they will +/// be filled to capacity. +/// dtStatus dtNavMeshQuery::findLocalNeighbourhood(dtPolyRef startRef, const float* centerPos, const float radius, const dtQueryFilter* filter, dtPolyRef* resultRef, dtPolyRef* resultParent, @@ -2392,6 +2652,17 @@ static void insertInterval(dtSegInterval* ints, int& nints, const int maxInts, nints++; } +/// @par +/// +/// If the @p segmentRefs parameter is provided, then all polygon segments will be returned. +/// Otherwise only the wall segments are returned. +/// +/// A segment that is normally a portal will be included in the result set as a +/// wall if the @p filter results in the neighbor polygon becoomming impassable. +/// +/// The @p segmentVerts and @p segmentRefs buffers should normally be sized for the +/// maximum segments per polygon of the source navigation mesh. +/// dtStatus dtNavMeshQuery::getPolyWallSegments(dtPolyRef ref, const dtQueryFilter* filter, float* segmentVerts, dtPolyRef* segmentRefs, int* segmentCount, const int maxSegments) const @@ -2532,6 +2803,16 @@ dtStatus dtNavMeshQuery::getPolyWallSegments(dtPolyRef ref, const dtQueryFilter* return status; } +/// @par +/// +/// @p hitPos is not adjusted using the height detail data. +/// +/// @p hitDist will equal the search radius if there is no wall within the +/// radius. In this case the values of @p hitPos and @p hitNormal are +/// undefined. +/// +/// The normal will become unpredicable if @p hitDist is a very small number. +/// dtStatus dtNavMeshQuery::findDistanceToWall(dtPolyRef startRef, const float* centerPos, const float maxRadius, const dtQueryFilter* filter, float* hitDist, float* hitPos, float* hitNormal) const @@ -2728,6 +3009,11 @@ bool dtNavMeshQuery::isValidPolyRef(dtPolyRef ref, const dtQueryFilter* filter) return true; } +/// @par +/// +/// The closed list is the list of polygons that were fully evaluated during +/// the last navigation graph search. (A* or Dijkstra) +/// bool dtNavMeshQuery::isInClosedList(dtPolyRef ref) const { if (!m_nodePool) return false;