DetourTileNavMesh.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. //
  2. // Copyright (c) 2009 Mikko Mononen memon@inside.org
  3. //
  4. // This software is provided 'as-is', without any express or implied
  5. // warranty. In no event will the authors be held liable for any damages
  6. // arising from the use of this software.
  7. // Permission is granted to anyone to use this software for any purpose,
  8. // including commercial applications, and to alter it and redistribute it
  9. // freely, subject to the following restrictions:
  10. // 1. The origin of this software must not be misrepresented; you must not
  11. // claim that you wrote the original software. If you use this software
  12. // in a product, an acknowledgment in the product documentation would be
  13. // appreciated but is not required.
  14. // 2. Altered source versions must be plainly marked as such, and must not be
  15. // misrepresented as being the original software.
  16. // 3. This notice may not be removed or altered from any source distribution.
  17. //
  18. #ifndef DETOURTILENAVMESH_H
  19. #define DETOURTILENAVMESH_H
  20. // Reference to navigation polygon.
  21. typedef unsigned int dtTilePolyRef;
  22. // The bits used in the poly ref.
  23. static const int DT_TILE_REF_SALT_BITS = 12;
  24. static const int DT_TILE_REF_TILE_BITS = 12;
  25. static const int DT_TILE_REF_POLY_BITS = 8;
  26. static const int DT_TILE_REF_SALT_MASK = (1<<DT_TILE_REF_SALT_BITS)-1;
  27. static const int DT_TILE_REF_TILE_MASK = (1<<DT_TILE_REF_TILE_BITS)-1;
  28. static const int DT_TILE_REF_POLY_MASK = (1<<DT_TILE_REF_POLY_BITS)-1;
  29. // Maximum number of vertices per navigation polygon.
  30. static const int DT_TILE_VERTS_PER_POLYGON = 6;
  31. static const int DT_MAX_TILES = 1 << DT_TILE_REF_TILE_BITS;
  32. static const int DT_MAX_POLYGONS = 1 << DT_TILE_REF_POLY_BITS;
  33. static const int DT_TILE_NAVMESH_MAGIC = (('N'<<24) | ('A'<<16) | ('V'<<8) | 'T');
  34. static const int DT_TILE_NAVMESH_VERSION = 2;
  35. // Structure holding the navigation polygon data.
  36. struct dtTilePoly
  37. {
  38. unsigned short v[DT_TILE_VERTS_PER_POLYGON]; // Indices to vertices of the poly.
  39. unsigned short n[DT_TILE_VERTS_PER_POLYGON]; // Refs to neighbours of the poly.
  40. unsigned short links; // Base index to header 'links' array.
  41. unsigned char nlinks; // Number of links for
  42. unsigned char nv; // Number of vertices.
  43. unsigned char flags; // Flags (not used).
  44. };
  45. struct dtTilePolyDetail
  46. {
  47. unsigned short vbase; // Offset to detail vertex array.
  48. unsigned short nverts; // Number of vertices in the detail mesh.
  49. unsigned short tbase; // Offset to detail triangle array.
  50. unsigned short ntris; // Number of triangles.
  51. };
  52. // Stucture holding a link to another polygon.
  53. struct dtTileLink
  54. {
  55. dtTilePolyRef ref; // Neighbour reference.
  56. unsigned short p; // Index to polygon which owns this link.
  57. unsigned char e; // Index to polygon edge which owns this link.
  58. unsigned char side; // If boundary link, defines on which side the link is.
  59. unsigned char bmin, bmax; // If boundary link, defines the sub edge area.
  60. };
  61. struct dtTileHeader
  62. {
  63. int magic; // Magic number, used to identify the data.
  64. int version; // Data version number.
  65. int npolys; // Number of polygons in the tile.
  66. int nverts; // Number of vertices in the tile.
  67. int nlinks; // Number of links in the tile (will be updated when tile is added).
  68. int maxlinks; // Number of allocated links.
  69. int ndmeshes;
  70. int ndverts;
  71. int ndtris;
  72. float bmin[3], bmax[3]; // Bounding box of the tile.
  73. dtTilePoly* polys; // Pointer to the polygons (will be updated when tile is added).
  74. float* verts; // Pointer to the vertices (will be updated when tile added).
  75. dtTileLink* links; // Pointer to the links (will be updated when tile added).
  76. dtTilePolyDetail* dmeshes;
  77. float* dverts;
  78. unsigned char* dtris;
  79. };
  80. struct dtTile
  81. {
  82. int salt; // Counter describing modifications to the tile.
  83. int x,y; // Grid location of the tile.
  84. dtTileHeader* header; // Pointer to tile header.
  85. unsigned char* data; // Pointer to tile data.
  86. int dataSize; // Size of the tile data.
  87. bool ownsData; // Flag indicating of the navmesh should release the data.
  88. dtTile* next; // Next free tile or, next tile in spatial grid.
  89. };
  90. // Encodes a tile id.
  91. inline dtTilePolyRef dtEncodeTileId(unsigned int salt, unsigned int it, unsigned int ip)
  92. {
  93. return (salt << (DT_TILE_REF_POLY_BITS+DT_TILE_REF_TILE_BITS)) | ((it+1) << DT_TILE_REF_POLY_BITS) | ip;
  94. }
  95. // Decodes a tile id.
  96. inline void dtDecodeTileId(dtTilePolyRef ref, unsigned int& salt, unsigned int& it, unsigned int& ip)
  97. {
  98. salt = (ref >> (DT_TILE_REF_POLY_BITS+DT_TILE_REF_TILE_BITS)) & DT_TILE_REF_SALT_MASK;
  99. it = ((ref >> DT_TILE_REF_POLY_BITS) & DT_TILE_REF_TILE_MASK) - 1;
  100. ip = ref & DT_TILE_REF_POLY_MASK;
  101. }
  102. static const int DT_TILE_LOOKUP_SIZE = DT_MAX_TILES/4;
  103. class dtTiledNavMesh
  104. {
  105. public:
  106. dtTiledNavMesh();
  107. ~dtTiledNavMesh();
  108. // Initializes the nav mesh.
  109. // Params:
  110. // orig - (in) origin of the nav mesh tile space.
  111. // tileSiz - (in) size of a tile.
  112. // portalheight - (in) height of the portal region between tiles.
  113. // Returns: True if succeed, else false.
  114. bool init(const float* orig, float tileSize, float portalHeight);
  115. // Adds new tile into the navmesh.
  116. // The add will fail if the data is in wrong format,
  117. // there is not enough tiles left, or if there is a tile already at the location.
  118. // Params:
  119. // x,y - (in) Location of the new tile.
  120. // data - (in) Data of the new tile mesh.
  121. // dataSize - (in) Data size of the new tile mesh.
  122. // ownsData - (in) Flag indicating if the navmesh should own and delete the data.
  123. // Returns: True if tile was added, else false.
  124. bool addTileAt(int x, int y, unsigned char* data, int dataSize, bool ownsData);
  125. // Removes tile at specified location.
  126. // Params:
  127. // x,y - (in) Location of the tile to remove.
  128. // data - (out) Data associated with deleted tile.
  129. // dataSize - (out) Size of the data associated with deleted tile.
  130. // Returns: True if remove suceed, else false.
  131. bool removeTileAt(int x, int y, unsigned char** data, int* dataSize);
  132. // Returns pointer to tile at specified location.
  133. // Params:
  134. // x,y - (in) Location of the tile to get.
  135. // Returns: pointer to tile if tile exists or 0 tile does not exists.
  136. dtTile* getTileAt(int x, int y);
  137. // Returns pointer to tile in the tile array.
  138. // Params:
  139. // i - (in) Index to the tile to retrieve, must be in range [0,DT_MAX_TILES[
  140. // Returns: Pointer to specified tile.
  141. dtTile* getTile(int i);
  142. const dtTile* getTile(int i) const;
  143. // Finds the nearest navigation polygon around the center location.
  144. // Params:
  145. // center - (in) The center of the search box.
  146. // extents - (in) The extents of the search box.
  147. // Returns: Reference identifier for the polygon, or 0 if no polygons found.
  148. dtTilePolyRef findNearestPoly(const float* center, const float* extents);
  149. // Returns polygons which touch the query box.
  150. // Params:
  151. // center - (in) the center of the search box.
  152. // extents - (in) the extents of the search box.
  153. // polys - (out) array holding the search result.
  154. // maxPolys - (in) The max number of polygons the polys array can hold.
  155. // Returns: Number of polygons in search result array.
  156. int queryPolygons(const float* center, const float* extents,
  157. dtTilePolyRef* polys, const int maxPolys);
  158. // Finds path from start polygon to end polygon.
  159. // If target polygon canno be reached through the navigation graph,
  160. // the last node on the array is nearest node to the end polygon.
  161. // Params:
  162. // startRef - (in) ref to path start polygon.
  163. // endRef - (in) ref to path end polygon.
  164. // path - (out) array holding the search result.
  165. // maxPathSize - (in) The max number of polygons the path array can hold.
  166. // Returns: Number of polygons in search result array.
  167. int findPath(dtTilePolyRef startRef, dtTilePolyRef endRef,
  168. const float* startPos, const float* endPos,
  169. dtTilePolyRef* path, const int maxPathSize);
  170. // Finds a straight path from start to end locations within the corridor
  171. // described by the path polygons.
  172. // Start and end locations will be clamped on the corridor.
  173. // Params:
  174. // startPos - (in) Path start location.
  175. // endPos - (in) Path end location.
  176. // path - (in) Array of connected polygons describing the corridor.
  177. // pathSize - (in) Number of polygons in path array.
  178. // straightPath - (out) Points describing the straight path.
  179. // maxStraightPathSize - (in) The max number of points the straight path array can hold.
  180. // Returns: Number of points in the path.
  181. int findStraightPath(const float* startPos, const float* endPos,
  182. const dtTilePolyRef* path, const int pathSize,
  183. float* straightPath, const int maxStraightPathSize);
  184. // Finds intersection againts walls starting from start pos.
  185. // Params:
  186. // startRef - (in) ref to the polygon where the start lies.
  187. // startPos - (in) start position of the query.
  188. // endPos - (in) end position of the query.
  189. // t - (out) hit parameter along the segment, 0 if no hit.
  190. // endRef - (out) ref to the last polygon which was processed.
  191. // Returns: Number of polygons in path or 0 if failed.
  192. int raycast(dtTilePolyRef startRef, const float* startPos, const float* endPos,
  193. float& t, dtTilePolyRef* path, const int pathSize);
  194. // Returns distance to nearest wall from the specified location.
  195. // Params:
  196. // centerRef - (in) ref to the polygon where the center lies.
  197. // centerPos - (in) center if the query circle.
  198. // maxRadius - (in) max search radius.
  199. // hitPos - (out) location of the nearest hit.
  200. // hitNormal - (out) normal of the nearest hit.
  201. // Returns: Distance to nearest wall from the test location.
  202. float findDistanceToWall(dtTilePolyRef centerRef, const float* centerPos, float maxRadius,
  203. float* hitPos, float* hitNormal);
  204. // Finds polygons found along the navigation graph which touch the specified circle.
  205. // Params:
  206. // centerRef - (in) ref to the polygon where the center lies.
  207. // centerPos - (in) center if the query circle
  208. // radius - (in) radius of the query circle
  209. // resultRef - (out, opt) refs to the polygons touched by the circle.
  210. // resultParent - (out, opt) parent of each result polygon.
  211. // resultCost - (out, opt) search cost at each result polygon.
  212. // maxResult - (int) maximum capacity of search results.
  213. // Returns: Number of results.
  214. int findPolysAround(dtTilePolyRef centerRef, const float* centerPos, float radius,
  215. dtTilePolyRef* resultRef, dtTilePolyRef* resultParent, float* resultCost,
  216. const int maxResult);
  217. // Returns closest point on navigation polygon.
  218. // Params:
  219. // ref - (in) ref to the polygon.
  220. // pos - (in) the point to check.
  221. // closest - (out) closest point.
  222. // Returns: true if closest point found.
  223. bool closestPointToPoly(dtTilePolyRef ref, const float* pos, float* closest) const;
  224. // Returns height of the polygon at specified location.
  225. // Params:
  226. // ref - (in) ref to the polygon.
  227. // pos - (in) the point where to locate the height.
  228. // height - (out) height at the location.
  229. // Returns: true if over polygon.
  230. bool getPolyHeight(dtTilePolyRef ref, const float* pos, float* height) const;
  231. // Returns pointer to a polygon based on ref.
  232. const dtTilePoly* getPolyByRef(dtTilePolyRef ref) const;
  233. // Returns pointer to a polygon vertices based on ref.
  234. const float* getPolyVertsByRef(dtTilePolyRef ref) const;
  235. // Returns pointer to a polygon link based on ref.
  236. const dtTileLink* getPolyLinksByRef(dtTilePolyRef ref) const;
  237. private:
  238. // Returns base id for the tile.
  239. dtTilePolyRef getTileId(dtTile* tile);
  240. // Returns neighbour tile based on side.
  241. dtTile* getNeighbourTileAt(int x, int y, int side);
  242. // Returns all polygons in neighbour tile based on portal defined by the segment.
  243. int findConnectingPolys(const float* va, const float* vb,
  244. dtTile* tile, int side,
  245. dtTilePolyRef* con, float* conarea, int maxcon);
  246. // Builds internal polygons links for a tile.
  247. void buildIntLinks(dtTile* tile);
  248. // Builds external polygon links for a tile.
  249. void buildExtLinks(dtTile* tile, dtTile* target, int side);
  250. // Removes external links at specified side.
  251. void removeExtLinks(dtTile* tile, int side);
  252. // Queries polygons within a tile.
  253. int queryTilePolygons(dtTile* tile, const float* qmin, const float* qmax,
  254. dtTilePolyRef* polys, const int maxPolys);
  255. float getCost(dtTilePolyRef prev, dtTilePolyRef from, dtTilePolyRef to) const;
  256. float getFirstCost(const float* pos, dtTilePolyRef from, dtTilePolyRef to) const;
  257. float getLastCost(dtTilePolyRef from, dtTilePolyRef to, const float* pos) const;
  258. float getHeuristic(const float* from, const float* to) const;
  259. // Returns portal points between two polygons.
  260. bool getPortalPoints(dtTilePolyRef from, dtTilePolyRef to, float* left, float* right) const;
  261. // Returns edge mid point between two polygons.
  262. bool getEdgeMidPoint(dtTilePolyRef from, dtTilePolyRef to, float* mid) const;
  263. float m_orig[3];
  264. float m_tileSize;
  265. float m_portalHeight;
  266. dtTile* m_posLookup[DT_TILE_LOOKUP_SIZE];
  267. dtTile* m_nextFree;
  268. dtTile m_tiles[DT_MAX_TILES];
  269. dtTileLink* m_tmpLinks;
  270. int m_ntmpLinks;
  271. class dtNodePool* m_nodePool;
  272. class dtNodeQueue* m_openList;
  273. };
  274. #endif // DETOURTILENAVMESH_H