NavigationMesh.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. //
  2. // Copyright (c) 2008-2015 the Urho3D project.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #pragma once
  23. #include "../Container/ArrayPtr.h"
  24. #include "../Container/HashSet.h"
  25. #include "../Math/BoundingBox.h"
  26. #include "../Math/Matrix3x4.h"
  27. #include "../Scene/Component.h"
  28. #ifdef DT_POLYREF64
  29. typedef uint64_t dtPolyRef;
  30. #else
  31. typedef unsigned int dtPolyRef;
  32. #endif
  33. class dtNavMesh;
  34. class dtNavMeshQuery;
  35. class dtQueryFilter;
  36. namespace Atomic
  37. {
  38. enum NavmeshPartitionType
  39. {
  40. NAVMESH_PARTITION_WATERSHED = 0,
  41. NAVMESH_PARTITION_MONOTONE
  42. };
  43. class Geometry;
  44. struct FindPathData;
  45. struct NavBuildData;
  46. /// Description of a navigation mesh geometry component, with transform and bounds information.
  47. struct NavigationGeometryInfo
  48. {
  49. /// Component.
  50. Component* component_;
  51. /// Geometry LOD level if applicable.
  52. unsigned lodLevel_;
  53. /// Transform relative to the navigation mesh root node.
  54. Matrix3x4 transform_;
  55. /// Bounding box relative to the navigation mesh root node.
  56. BoundingBox boundingBox_;
  57. };
  58. /// Navigation mesh component. Collects the navigation geometry from child nodes with the Navigable component and responds to path queries.
  59. class ATOMIC_API NavigationMesh : public Component
  60. {
  61. OBJECT(NavigationMesh);
  62. friend class CrowdManager;
  63. public:
  64. /// Construct.
  65. NavigationMesh(Context* context);
  66. /// Destruct.
  67. virtual ~NavigationMesh();
  68. /// Register object factory.
  69. static void RegisterObject(Context* context);
  70. /// Visualize the component as debug geometry.
  71. virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
  72. /// Set tile size.
  73. void SetTileSize(int size);
  74. /// Set cell size.
  75. void SetCellSize(float size);
  76. /// Set cell height.
  77. void SetCellHeight(float height);
  78. /// Set navigation agent height.
  79. void SetAgentHeight(float height);
  80. /// Set navigation agent radius.
  81. void SetAgentRadius(float radius);
  82. /// Set navigation agent max vertical climb.
  83. void SetAgentMaxClimb(float maxClimb);
  84. /// Set navigation agent max slope.
  85. void SetAgentMaxSlope(float maxSlope);
  86. /// Set region minimum size.
  87. void SetRegionMinSize(float size);
  88. /// Set region merge size.
  89. void SetRegionMergeSize(float size);
  90. /// Set edge max length.
  91. void SetEdgeMaxLength(float length);
  92. /// Set edge max error.
  93. void SetEdgeMaxError(float error);
  94. /// Set detail sampling distance.
  95. void SetDetailSampleDistance(float distance);
  96. /// Set detail sampling maximum error.
  97. void SetDetailSampleMaxError(float error);
  98. /// Set padding of the navigation mesh bounding box. Having enough padding allows to add geometry on the extremities of the navigation mesh when doing partial rebuilds.
  99. void SetPadding(const Vector3& padding);
  100. /// Set the cost of an area.
  101. void SetAreaCost(unsigned areaID, float cost);
  102. /// Rebuild the navigation mesh. Return true if successful.
  103. virtual bool Build();
  104. /// Rebuild part of the navigation mesh contained by the world-space bounding box. Return true if successful.
  105. virtual bool Build(const BoundingBox& boundingBox);
  106. /// Find the nearest point on the navigation mesh to a given point. Extents specifies how far out from the specified point to check along each axis.
  107. Vector3 FindNearestPoint
  108. (const Vector3& point, const Vector3& extents = Vector3::ONE, const dtQueryFilter* filter = 0, dtPolyRef* nearestRef = 0);
  109. /// Try to move along the surface from one point to another.
  110. Vector3 MoveAlongSurface(const Vector3& start, const Vector3& end, const Vector3& extents = Vector3::ONE, int maxVisited = 3,
  111. const dtQueryFilter* filter = 0);
  112. /// Find a path between world space points. Return non-empty list of points if successful. Extents specifies how far off the navigation mesh the points can be.
  113. void FindPath(PODVector<Vector3>& dest, const Vector3& start, const Vector3& end, const Vector3& extents = Vector3::ONE,
  114. const dtQueryFilter* filter = 0);
  115. /// Return a random point on the navigation mesh.
  116. Vector3 GetRandomPoint(const dtQueryFilter* filter = 0, dtPolyRef* randomRef = 0);
  117. /// Return a random point on the navigation mesh within a circle. The circle radius is only a guideline and in practice the returned point may be further away.
  118. Vector3 GetRandomPointInCircle
  119. (const Vector3& center, float radius, const Vector3& extents = Vector3::ONE, const dtQueryFilter* filter = 0,
  120. dtPolyRef* randomRef = 0);
  121. /// Return distance to wall from a point. Maximum search radius must be specified.
  122. float GetDistanceToWall
  123. (const Vector3& point, float radius, const Vector3& extents = Vector3::ONE, const dtQueryFilter* filter = 0,
  124. Vector3* hitPos = 0, Vector3* hitNormal = 0);
  125. /// Perform a walkability raycast on the navigation mesh between start and end and return the point where a wall was hit, or the end point if no walls.
  126. Vector3 Raycast
  127. (const Vector3& start, const Vector3& end, const Vector3& extents = Vector3::ONE, const dtQueryFilter* filter = 0,
  128. Vector3* hitNormal = 0);
  129. /// Add debug geometry to the debug renderer.
  130. void DrawDebugGeometry(bool depthTest);
  131. /// Return the given name of this navigation mesh.
  132. String GetMeshName() const { return meshName_; }
  133. /// Set the name of this navigation mesh.
  134. void SetMeshName(const String& newName);
  135. /// Return tile size.
  136. int GetTileSize() const { return tileSize_; }
  137. /// Return cell size.
  138. float GetCellSize() const { return cellSize_; }
  139. /// Return cell height.
  140. float GetCellHeight() const { return cellHeight_; }
  141. /// Return navigation agent height.
  142. float GetAgentHeight() const { return agentHeight_; }
  143. /// Return navigation agent radius.
  144. float GetAgentRadius() const { return agentRadius_; }
  145. /// Return navigation agent max vertical climb.
  146. float GetAgentMaxClimb() const { return agentMaxClimb_; }
  147. /// Return navigation agent max slope.
  148. float GetAgentMaxSlope() const { return agentMaxSlope_; }
  149. /// Return region minimum size.
  150. float GetRegionMinSize() const { return regionMinSize_; }
  151. /// Return region merge size.
  152. float GetRegionMergeSize() const { return regionMergeSize_; }
  153. /// Return edge max length.
  154. float GetEdgeMaxLength() const { return edgeMaxLength_; }
  155. /// Return edge max error.
  156. float GetEdgeMaxError() const { return edgeMaxError_; }
  157. /// Return detail sampling distance.
  158. float GetDetailSampleDistance() const { return detailSampleDistance_; }
  159. /// Return detail sampling maximum error.
  160. float GetDetailSampleMaxError() const { return detailSampleMaxError_; }
  161. /// Return navigation mesh bounding box padding.
  162. const Vector3& GetPadding() const { return padding_; }
  163. /// Get the current cost of an area
  164. float GetAreaCost(unsigned areaID) const;
  165. /// Return whether has been initialized with valid navigation data.
  166. bool IsInitialized() const { return navMesh_ != 0; }
  167. /// Return local space bounding box of the navigation mesh.
  168. const BoundingBox& GetBoundingBox() const { return boundingBox_; }
  169. /// Return world space bounding box of the navigation mesh.
  170. BoundingBox GetWorldBoundingBox() const;
  171. /// Return number of tiles.
  172. IntVector2 GetNumTiles() const { return IntVector2(numTilesX_, numTilesZ_); }
  173. /// Set the partition type used for polygon generation.
  174. void SetPartitionType(NavmeshPartitionType aType);
  175. /// Return Partition Type.
  176. NavmeshPartitionType GetPartitionType() const { return partitionType_; }
  177. /// Set navigation data attribute.
  178. virtual void SetNavigationDataAttr(const PODVector<unsigned char>& value);
  179. /// Return navigation data attribute.
  180. virtual PODVector<unsigned char> GetNavigationDataAttr() const;
  181. /// Draw debug geometry for OffMeshConnection components.
  182. void SetDrawOffMeshConnections(bool enable) { drawOffMeshConnections_ = enable; }
  183. /// Return whether to draw OffMeshConnection components.
  184. bool GetDrawOffMeshConnections() const { return drawOffMeshConnections_; }
  185. /// Draw debug geometry for NavArea components.
  186. void SetDrawNavAreas(bool enable) { drawNavAreas_ = enable; }
  187. /// Return whether to draw NavArea components.
  188. bool GetDrawNavAreas() const { return drawNavAreas_; }
  189. protected:
  190. /// Collect geometry from under Navigable components.
  191. void CollectGeometries(Vector<NavigationGeometryInfo>& geometryList);
  192. /// Visit nodes and collect navigable geometry.
  193. void
  194. CollectGeometries(Vector<NavigationGeometryInfo>& geometryList, Node* node, HashSet<Node*>& processedNodes, bool recursive);
  195. /// Get geometry data within a bounding box.
  196. void GetTileGeometry(NavBuildData* build, Vector<NavigationGeometryInfo>& geometryList, BoundingBox& box);
  197. /// Add a triangle mesh to the geometry data.
  198. void AddTriMeshGeometry(NavBuildData* build, Geometry* geometry, const Matrix3x4& transform);
  199. /// Build one tile of the navigation mesh. Return true if successful.
  200. virtual bool BuildTile(Vector<NavigationGeometryInfo>& geometryList, int x, int z);
  201. /// Ensure that the navigation mesh query is initialized. Return true if successful.
  202. bool InitializeQuery();
  203. /// Release the navigation mesh and the query.
  204. virtual void ReleaseNavigationMesh();
  205. /// Identifying name for this navigation mesh.
  206. String meshName_;
  207. /// Detour navigation mesh.
  208. dtNavMesh* navMesh_;
  209. /// Detour navigation mesh query.
  210. dtNavMeshQuery* navMeshQuery_;
  211. /// Detour navigation mesh query filter.
  212. dtQueryFilter* queryFilter_;
  213. /// Temporary data for finding a path.
  214. FindPathData* pathData_;
  215. /// Tile size.
  216. int tileSize_;
  217. /// Cell size.
  218. float cellSize_;
  219. /// Cell height.
  220. float cellHeight_;
  221. /// Navigation agent height.
  222. float agentHeight_;
  223. /// Navigation agent radius.
  224. float agentRadius_;
  225. /// Navigation agent max vertical climb.
  226. float agentMaxClimb_;
  227. /// Navigation agent max slope.
  228. float agentMaxSlope_;
  229. /// Region minimum size.
  230. float regionMinSize_;
  231. /// Region merge size.
  232. float regionMergeSize_;
  233. /// Edge max length.
  234. float edgeMaxLength_;
  235. /// Edge max error.
  236. float edgeMaxError_;
  237. /// Detail sampling distance.
  238. float detailSampleDistance_;
  239. /// Detail sampling maximum error.
  240. float detailSampleMaxError_;
  241. /// Bounding box padding.
  242. Vector3 padding_;
  243. /// Number of tiles in X direction.
  244. int numTilesX_;
  245. /// Number of tiles in Z direction.
  246. int numTilesZ_;
  247. /// Whole navigation mesh bounding box.
  248. BoundingBox boundingBox_;
  249. /// Type of the heightfield partitioning.
  250. NavmeshPartitionType partitionType_;
  251. /// Keep internal build resources for debug draw modes.
  252. bool keepInterResults_;
  253. /// Debug draw OffMeshConnection components.
  254. bool drawOffMeshConnections_;
  255. /// Debug draw NavArea components.
  256. bool drawNavAreas_;
  257. };
  258. /// Register Navigation library objects.
  259. void ATOMIC_API RegisterNavigationLibrary(Context* context);
  260. }