DetourTileCache.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. #ifndef DETOURTILECACHE_H
  2. #define DETOURTILECACHE_H
  3. // Modified by Lasse Oorni for Urho3D
  4. #include "DetourStatus.h"
  5. typedef unsigned int dtObstacleRef;
  6. typedef unsigned int dtCompressedTileRef;
  7. /// Flags for addTile
  8. enum dtCompressedTileFlags
  9. {
  10. DT_COMPRESSEDTILE_FREE_DATA = 0x01, ///< Navmesh owns the tile memory and should free it.
  11. };
  12. struct dtCompressedTile
  13. {
  14. unsigned int salt; ///< Counter describing modifications to the tile.
  15. struct dtTileCacheLayerHeader* header;
  16. unsigned char* compressed;
  17. int compressedSize;
  18. unsigned char* data;
  19. int dataSize;
  20. unsigned int flags;
  21. dtCompressedTile* next;
  22. };
  23. enum ObstacleState
  24. {
  25. DT_OBSTACLE_EMPTY,
  26. DT_OBSTACLE_PROCESSING,
  27. DT_OBSTACLE_PROCESSED,
  28. DT_OBSTACLE_REMOVING,
  29. };
  30. enum ObstacleType
  31. {
  32. DT_OBSTACLE_CYLINDER,
  33. DT_OBSTACLE_BOX, // AABB
  34. DT_OBSTACLE_ORIENTED_BOX, // OBB
  35. };
  36. struct dtObstacleCylinder
  37. {
  38. float pos[ 3 ];
  39. float radius;
  40. float height;
  41. };
  42. struct dtObstacleBox
  43. {
  44. float bmin[ 3 ];
  45. float bmax[ 3 ];
  46. };
  47. struct dtObstacleOrientedBox
  48. {
  49. float center[ 3 ];
  50. float halfExtents[ 3 ];
  51. float rotAux[ 2 ]; //{ cos(0.5f*angle)*sin(-0.5f*angle); cos(0.5f*angle)*cos(0.5f*angle) - 0.5 }
  52. };
  53. static const int DT_MAX_TOUCHED_TILES = 8;
  54. struct dtTileCacheObstacle
  55. {
  56. union
  57. {
  58. dtObstacleCylinder cylinder;
  59. dtObstacleBox box;
  60. dtObstacleOrientedBox orientedBox;
  61. };
  62. dtCompressedTileRef touched[DT_MAX_TOUCHED_TILES];
  63. dtCompressedTileRef pending[DT_MAX_TOUCHED_TILES];
  64. unsigned short salt;
  65. unsigned char type;
  66. unsigned char state;
  67. unsigned char ntouched;
  68. unsigned char npending;
  69. dtTileCacheObstacle* next;
  70. };
  71. struct dtTileCacheParams
  72. {
  73. float orig[3];
  74. float cs, ch;
  75. int width, height;
  76. float walkableHeight;
  77. float walkableRadius;
  78. float walkableClimb;
  79. float maxSimplificationError;
  80. int maxTiles;
  81. int maxObstacles;
  82. };
  83. struct dtTileCacheMeshProcess
  84. {
  85. virtual ~dtTileCacheMeshProcess() { }
  86. virtual void process(struct dtNavMeshCreateParams* params,
  87. unsigned char* polyAreas, unsigned short* polyFlags) = 0;
  88. };
  89. class dtTileCache
  90. {
  91. public:
  92. dtTileCache();
  93. ~dtTileCache();
  94. struct dtTileCacheAlloc* getAlloc() { return m_talloc; }
  95. struct dtTileCacheCompressor* getCompressor() { return m_tcomp; }
  96. const dtTileCacheParams* getParams() const { return &m_params; }
  97. inline int getTileCount() const { return m_params.maxTiles; }
  98. inline const dtCompressedTile* getTile(const int i) const { return &m_tiles[i]; }
  99. inline int getObstacleCount() const { return m_params.maxObstacles; }
  100. inline const dtTileCacheObstacle* getObstacle(const int i) const { return &m_obstacles[i]; }
  101. const dtTileCacheObstacle* getObstacleByRef(dtObstacleRef ref);
  102. dtObstacleRef getObstacleRef(const dtTileCacheObstacle* obmin) const;
  103. dtStatus init(const dtTileCacheParams* params,
  104. struct dtTileCacheAlloc* talloc,
  105. struct dtTileCacheCompressor* tcomp,
  106. struct dtTileCacheMeshProcess* tmproc);
  107. int getTilesAt(const int tx, const int ty, dtCompressedTileRef* tiles, const int maxTiles) const ;
  108. dtCompressedTile* getTileAt(const int tx, const int ty, const int tlayer);
  109. dtCompressedTileRef getTileRef(const dtCompressedTile* tile) const;
  110. const dtCompressedTile* getTileByRef(dtCompressedTileRef ref) const;
  111. dtStatus addTile(unsigned char* data, const int dataSize, unsigned char flags, dtCompressedTileRef* result);
  112. dtStatus removeTile(dtCompressedTileRef ref, unsigned char** data, int* dataSize);
  113. // Cylinder obstacle.
  114. dtStatus addObstacle(const float* pos, const float radius, const float height, dtObstacleRef* result);
  115. // Aabb obstacle.
  116. dtStatus addBoxObstacle(const float* bmin, const float* bmax, dtObstacleRef* result);
  117. // Box obstacle: can be rotated in Y.
  118. dtStatus addBoxObstacle(const float* center, const float* halfExtents, const float yRadians, dtObstacleRef* result);
  119. dtStatus removeObstacle(const dtObstacleRef ref);
  120. dtStatus queryTiles(const float* bmin, const float* bmax,
  121. dtCompressedTileRef* results, int* resultCount, const int maxResults) const;
  122. /// Updates the tile cache by rebuilding tiles touched by unfinished obstacle requests.
  123. /// @param[in] dt The time step size. Currently not used.
  124. /// @param[in] navmesh The mesh to affect when rebuilding tiles.
  125. /// @param[out] upToDate Whether the tile cache is fully up to date with obstacle requests and tile rebuilds.
  126. /// If the tile cache is up to date another (immediate) call to update will have no effect;
  127. /// otherwise another call will continue processing obstacle requests and tile rebuilds.
  128. dtStatus update(const float dt, class dtNavMesh* navmesh, bool* upToDate = 0);
  129. dtStatus buildNavMeshTilesAt(const int tx, const int ty, class dtNavMesh* navmesh);
  130. dtStatus buildNavMeshTile(const dtCompressedTileRef ref, class dtNavMesh* navmesh);
  131. void calcTightTileBounds(const struct dtTileCacheLayerHeader* header, float* bmin, float* bmax) const;
  132. void getObstacleBounds(const struct dtTileCacheObstacle* ob, float* bmin, float* bmax) const;
  133. // Urho3D: added function to know when we have too many obstacle requests without update
  134. bool isObstacleQueueFull() const { return m_nreqs >= MAX_REQUESTS; }
  135. /// Encodes a tile id.
  136. inline dtCompressedTileRef encodeTileId(unsigned int salt, unsigned int it) const
  137. {
  138. return ((dtCompressedTileRef)salt << m_tileBits) | (dtCompressedTileRef)it;
  139. }
  140. /// Decodes a tile salt.
  141. inline unsigned int decodeTileIdSalt(dtCompressedTileRef ref) const
  142. {
  143. const dtCompressedTileRef saltMask = ((dtCompressedTileRef)1<<m_saltBits)-1;
  144. return (unsigned int)((ref >> m_tileBits) & saltMask);
  145. }
  146. /// Decodes a tile id.
  147. inline unsigned int decodeTileIdTile(dtCompressedTileRef ref) const
  148. {
  149. const dtCompressedTileRef tileMask = ((dtCompressedTileRef)1<<m_tileBits)-1;
  150. return (unsigned int)(ref & tileMask);
  151. }
  152. /// Encodes an obstacle id.
  153. inline dtObstacleRef encodeObstacleId(unsigned int salt, unsigned int it) const
  154. {
  155. return ((dtObstacleRef)salt << 16) | (dtObstacleRef)it;
  156. }
  157. /// Decodes an obstacle salt.
  158. inline unsigned int decodeObstacleIdSalt(dtObstacleRef ref) const
  159. {
  160. const dtObstacleRef saltMask = ((dtObstacleRef)1<<16)-1;
  161. return (unsigned int)((ref >> 16) & saltMask);
  162. }
  163. /// Decodes an obstacle id.
  164. inline unsigned int decodeObstacleIdObstacle(dtObstacleRef ref) const
  165. {
  166. const dtObstacleRef tileMask = ((dtObstacleRef)1<<16)-1;
  167. return (unsigned int)(ref & tileMask);
  168. }
  169. private:
  170. // Explicitly disabled copy constructor and copy assignment operator.
  171. dtTileCache(const dtTileCache&);
  172. dtTileCache& operator=(const dtTileCache&);
  173. enum ObstacleRequestAction
  174. {
  175. REQUEST_ADD,
  176. REQUEST_REMOVE,
  177. };
  178. struct ObstacleRequest
  179. {
  180. int action;
  181. dtObstacleRef ref;
  182. };
  183. int m_tileLutSize; ///< Tile hash lookup size (must be pot).
  184. int m_tileLutMask; ///< Tile hash lookup mask.
  185. dtCompressedTile** m_posLookup; ///< Tile hash lookup.
  186. dtCompressedTile* m_nextFreeTile; ///< Freelist of tiles.
  187. dtCompressedTile* m_tiles; ///< List of tiles.
  188. unsigned int m_saltBits; ///< Number of salt bits in the tile ID.
  189. unsigned int m_tileBits; ///< Number of tile bits in the tile ID.
  190. dtTileCacheParams m_params;
  191. dtTileCacheAlloc* m_talloc;
  192. dtTileCacheCompressor* m_tcomp;
  193. dtTileCacheMeshProcess* m_tmproc;
  194. dtTileCacheObstacle* m_obstacles;
  195. dtTileCacheObstacle* m_nextFreeObstacle;
  196. static const int MAX_REQUESTS = 64;
  197. ObstacleRequest m_reqs[MAX_REQUESTS];
  198. int m_nreqs;
  199. static const int MAX_UPDATE = 64;
  200. dtCompressedTileRef m_update[MAX_UPDATE];
  201. int m_nupdate;
  202. };
  203. dtTileCache* dtAllocTileCache();
  204. void dtFreeTileCache(dtTileCache* tc);
  205. #endif