NavigationMesh.h 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. //
  2. // Copyright (c) 2008-2014 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 "ArrayPtr.h"
  24. #include "BoundingBox.h"
  25. #include "Component.h"
  26. #include "HashSet.h"
  27. #include "Matrix3x4.h"
  28. class dtNavMesh;
  29. class dtNavMeshQuery;
  30. class dtQueryFilter;
  31. namespace Urho3D
  32. {
  33. class Geometry;
  34. struct FindPathData;
  35. struct NavigationBuildData;
  36. /// Description of a navigation mesh geometry component, with transform and bounds information.
  37. struct NavigationGeometryInfo
  38. {
  39. /// Component.
  40. Component* component_;
  41. /// Geometry LOD level if applicable.
  42. unsigned lodLevel_;
  43. /// Transform relative to the navigation mesh root node.
  44. Matrix3x4 transform_;
  45. /// Bounding box relative to the navigation mesh root node.
  46. BoundingBox boundingBox_;
  47. };
  48. /// Navigation mesh component. Collects the navigation geometry from child nodes with the Navigable component and responds to path queries.
  49. class URHO3D_API NavigationMesh : public Component
  50. {
  51. OBJECT(NavigationMesh);
  52. public:
  53. /// Construct.
  54. NavigationMesh(Context* context);
  55. /// Destruct.
  56. virtual ~NavigationMesh();
  57. /// Register object factory.
  58. static void RegisterObject(Context* context);
  59. /// Visualize the component as debug geometry.
  60. virtual void DrawDebugGeometry(DebugRenderer* debug, bool depthTest);
  61. /// Set tile size.
  62. void SetTileSize(int size);
  63. /// Set cell size.
  64. void SetCellSize(float size);
  65. /// Set cell height.
  66. void SetCellHeight(float height);
  67. /// Set navigation agent height.
  68. void SetAgentHeight(float height);
  69. /// Set navigation agent radius.
  70. void SetAgentRadius(float radius);
  71. /// Set navigation agent max vertical climb.
  72. void SetAgentMaxClimb(float maxClimb);
  73. /// Set navigation agent max slope.
  74. void SetAgentMaxSlope(float maxSlope);
  75. /// Set region minimum size.
  76. void SetRegionMinSize(float size);
  77. /// Set region merge size.
  78. void SetRegionMergeSize(float size);
  79. /// Set edge max length.
  80. void SetEdgeMaxLength(float length);
  81. /// Set edge max error.
  82. void SetEdgeMaxError(float error);
  83. /// Set detail sampling distance.
  84. void SetDetailSampleDistance(float distance);
  85. /// Set detail sampling maximum error.
  86. void SetDetailSampleMaxError(float error);
  87. /// 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.
  88. void SetPadding(const Vector3& padding);
  89. /// Rebuild the navigation mesh. Return true if successful.
  90. bool Build();
  91. /// Rebuild part of the navigation mesh contained by the world-space bounding box. Return true if successful.
  92. bool Build(const BoundingBox& boundingBox);
  93. /// Find the nearest point on the navigation mesh to a given point. Extens specifies how far out from the specified point to check along each axis.
  94. Vector3 FindNearestPoint(const Vector3& point, const Vector3& extents=Vector3::ONE);
  95. /// Try to move along the surface from one point to another
  96. Vector3 MoveAlongSurface(const Vector3& start, const Vector3& end, const Vector3& extents=Vector3::ONE, int maxVisited=3);
  97. /// 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.
  98. void FindPath(PODVector<Vector3>& dest, const Vector3& start, const Vector3& end, const Vector3& extents = Vector3::ONE);
  99. /// Return a random point on the navigation mesh.
  100. Vector3 GetRandomPoint();
  101. /// 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.
  102. Vector3 GetRandomPointInCircle(const Vector3& center, float radius, const Vector3& extents = Vector3::ONE);
  103. /// Return distance to wall from a point. Maximum search radius must be specified.
  104. float GetDistanceToWall(const Vector3& point, float radius, const Vector3& extents = Vector3::ONE);
  105. /// 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.
  106. Vector3 Raycast(const Vector3& start, const Vector3& end, const Vector3& extents = Vector3::ONE);
  107. /// Add debug geometry to the debug renderer.
  108. void DrawDebugGeometry(bool depthTest);
  109. /// Return tile size.
  110. int GetTileSize() const { return tileSize_; }
  111. /// Return cell size.
  112. float GetCellSize() const { return cellSize_; }
  113. /// Return cell height.
  114. float GetCellHeight() const { return cellHeight_; }
  115. /// Return navigation agent height.
  116. float GetAgentHeight() const { return agentHeight_; }
  117. /// Return navigation agent radius.
  118. float GetAgentRadius() const { return agentRadius_; }
  119. /// Return navigation agent max vertical climb.
  120. float GetAgentMaxClimb() const { return agentMaxClimb_; }
  121. /// Return navigation agent max slope.
  122. float GetAgentMaxSlope() const { return agentMaxSlope_; }
  123. /// Return region minimum size.
  124. float GetRegionMinSize() const { return regionMinSize_; }
  125. /// Return region merge size.
  126. float GetRegionMergeSize() const { return regionMergeSize_; }
  127. /// Return edge max length.
  128. float GetEdgeMaxLength() const { return edgeMaxLength_; }
  129. /// Return edge max error.
  130. float GetEdgeMaxError() const { return edgeMaxError_; }
  131. /// Return detail sampling distance.
  132. float GetDetailSampleDistance() const { return detailSampleDistance_; }
  133. /// Return detail sampling maximum error.
  134. float GetDetailSampleMaxError() const { return detailSampleMaxError_; }
  135. /// Return navigation mesh bounding box padding.
  136. const Vector3& GetPadding() const { return padding_; }
  137. /// Return whether has been initialized with valid navigation data.
  138. bool IsInitialized() const { return navMesh_ != 0; }
  139. /// Return local space bounding box of the navigation mesh.
  140. const BoundingBox& GetBoundingBox() const { return boundingBox_; }
  141. /// Return world space bounding box of the navigation mesh.
  142. BoundingBox GetWorldBoundingBox() const;
  143. /// Return number of tiles.
  144. IntVector2 GetNumTiles() const { return IntVector2(numTilesX_, numTilesZ_); }
  145. /// Set navigation data attribute.
  146. void SetNavigationDataAttr(const PODVector<unsigned char>& value);
  147. /// Return navigation data attribute.
  148. PODVector<unsigned char> GetNavigationDataAttr() const;
  149. private:
  150. /// Collect geometry from under Navigable components.
  151. void CollectGeometries(Vector<NavigationGeometryInfo>& geometryList);
  152. /// Visit nodes and collect navigable geometry.
  153. void CollectGeometries(Vector<NavigationGeometryInfo>& geometryList, Node* node, HashSet<Node*>& processedNodes, bool recursive);
  154. /// Get geometry data within a bounding box.
  155. void GetTileGeometry(NavigationBuildData& build, Vector<NavigationGeometryInfo>& geometryList, BoundingBox& box);
  156. /// Add a triangle mesh to the geometry data.
  157. void AddTriMeshGeometry(NavigationBuildData& build, Geometry* geometry, const Matrix3x4& transform);
  158. /// Build one tile of the navigation mesh. Return true if successful.
  159. bool BuildTile(Vector<NavigationGeometryInfo>& geometryList, int x, int z);
  160. /// Ensure that the navigation mesh query is initialized. Return true if successful.
  161. bool InitializeQuery();
  162. /// Release the navigation mesh and the query.
  163. void ReleaseNavigationMesh();
  164. /// Detour navigation mesh.
  165. dtNavMesh* navMesh_;
  166. /// Detour navigation mesh query.
  167. dtNavMeshQuery* navMeshQuery_;
  168. /// Detour navigation mesh query filter.
  169. dtQueryFilter* queryFilter_;
  170. /// Temporary data for finding a path.
  171. FindPathData* pathData_;
  172. /// Tile size.
  173. int tileSize_;
  174. /// Cell size.
  175. float cellSize_;
  176. /// Cell height.
  177. float cellHeight_;
  178. /// Navigation agent height.
  179. float agentHeight_;
  180. /// Navigation agent radius.
  181. float agentRadius_;
  182. /// Navigation agent max vertical climb.
  183. float agentMaxClimb_;
  184. /// Navigation agent max slope.
  185. float agentMaxSlope_;
  186. /// Region minimum size.
  187. float regionMinSize_;
  188. /// Region merge size.
  189. float regionMergeSize_;
  190. /// Edge max length.
  191. float edgeMaxLength_;
  192. /// Edge max error.
  193. float edgeMaxError_;
  194. /// Detail sampling distance.
  195. float detailSampleDistance_;
  196. /// Detail sampling maximum error.
  197. float detailSampleMaxError_;
  198. /// Bounding box padding.
  199. Vector3 padding_;
  200. /// Number of tiles in X direction.
  201. int numTilesX_;
  202. /// Number of tiles in Z direction.
  203. int numTilesZ_;
  204. /// Whole navigation mesh bounding box.
  205. BoundingBox boundingBox_;
  206. };
  207. /// Register Navigation library objects.
  208. void URHO3D_API RegisterNavigationLibrary(Context* context);
  209. }