Explorar o código

Added expanded structure for path calculation and appropriate FindPath
method.

Nick Royer %!s(int64=10) %!d(string=hai) anos
pai
achega
bab7daa211

+ 54 - 0
Source/Urho3D/Navigation/NavigationMesh.cpp

@@ -570,6 +570,60 @@ void NavigationMesh::FindPath(PODVector<Vector3>& dest, const Vector3& start, co
         dest.Push(transform * pathData_->pathPoints_[i]);
 }
 
+void NavigationMesh::FindPath(NavigationPathData& dest, const Vector3& start, const Vector3& end, const Vector3& extents,
+    const dtQueryFilter* filter)
+{
+    URHO3D_PROFILE(FindPath);
+
+    dest.pathPoints_.Clear();
+    dest.pathFlags_.Clear();
+    dest.pathAreas_.Clear();
+
+    if (!InitializeQuery())
+        return;
+
+    // Navigation data is in local space. Transform path points from world to local
+    const Matrix3x4& transform = node_->GetWorldTransform();
+    Matrix3x4 inverse = transform.Inverse();
+
+    Vector3 localStart = inverse * start;
+    Vector3 localEnd = inverse * end;
+
+    const dtQueryFilter* queryFilter = filter ? filter : queryFilter_;
+    dtPolyRef startRef;
+    dtPolyRef endRef;
+    navMeshQuery_->findNearestPoly(&localStart.x_, &extents.x_, queryFilter, &startRef, 0);
+    navMeshQuery_->findNearestPoly(&localEnd.x_, &extents.x_, queryFilter, &endRef, 0);
+
+    if (!startRef || !endRef)
+        return;
+
+    int numPolys = 0;
+    int numPathPoints = 0;
+
+    navMeshQuery_->findPath(startRef, endRef, &localStart.x_, &localEnd.x_, queryFilter, pathData_->polys_, &numPolys,
+        MAX_POLYS);
+    if (!numPolys)
+        return;
+
+    Vector3 actualLocalEnd = localEnd;
+
+    // If full path was not found, clamp end point to the end polygon
+    if (pathData_->polys_[numPolys - 1] != endRef)
+        navMeshQuery_->closestPointOnPoly(pathData_->polys_[numPolys - 1], &localEnd.x_, &actualLocalEnd.x_, 0);
+
+    navMeshQuery_->findStraightPath(&localStart.x_, &actualLocalEnd.x_, pathData_->polys_, numPolys,
+        &pathData_->pathPoints_[0].x_, pathData_->pathFlags_, pathData_->pathPolys_, &numPathPoints, MAX_POLYS);
+
+    // Transform path result back to world space
+    for (int i = 0; i < numPathPoints; ++i)
+    {
+        dest.pathPoints_.Push(transform * pathData_->pathPoints_[i]);
+        dest.pathAreas_.Push(pathData_->pathAreras_[i]);
+        dest.pathFlags_.Push(pathData_->pathFlags_[i]);
+    }
+}
+
 Vector3 NavigationMesh::GetRandomPoint(const dtQueryFilter* filter, dtPolyRef* randomRef)
 {
     if (!InitializeQuery())

+ 14 - 0
Source/Urho3D/Navigation/NavigationMesh.h

@@ -65,6 +65,15 @@ struct NavigationGeometryInfo
     BoundingBox boundingBox_;
 };
 
+struct URHO3D_API NavigationPathData
+{
+    PODVector<Vector3> pathPoints_;
+    // Flags on the path.
+    PODVector<unsigned char> pathFlags_;
+    // Area Ids on the path.
+    PODVector<unsigned char> pathAreas_;
+};
+
 /// Navigation mesh component. Collects the navigation geometry from child nodes with the Navigable component and responds to path queries.
 class URHO3D_API NavigationMesh : public Component
 {
@@ -126,6 +135,11 @@ public:
     /// 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.
     void FindPath(PODVector<Vector3>& dest, const Vector3& start, const Vector3& end, const Vector3& extents = Vector3::ONE,
         const dtQueryFilter* filter = 0);
+
+    /// Find a path between world space points. Returns a NavigationPathData structure. Extents specifies how far off the navigaion mesh the points can be.
+    void FindPath(NavigationPathData& dest, const Vector3& start, const Vector3& end, const Vector3& extents = Vector3::ONE,
+        const dtQueryFilter* filter = 0);
+
     /// Return a random point on the navigation mesh.
     Vector3 GetRandomPoint(const dtQueryFilter* filter = 0, dtPolyRef* randomRef = 0);
     /// 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.