NavigationMesh.h 9.3 KB

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