/// <summary> /// Immediately frees all unmanaged resources allocated by the object. /// </summary> public override void RequestDisposal() { // There are no managed or local allocations. if (root != IntPtr.Zero) { mFilter.RequestDisposal(); mFilter = null; mGrid.Dispose(); mGrid = null; mQuery.RequestDisposal(); mQuery = null; mNavmesh = null; mMaxAgentRadius = -1; agentStates = null; for (int i = 0; i < mAgents.Length; i++) { if (mAgents[i] == null) { continue; } mAgents[i].Dispose(); mAgents[i] = null; } CrowdManagerEx.dtcDetourCrowdFree(root); root = IntPtr.Zero; } }
/// <summary> /// Constructor. /// </summary> /// <remarks> /// <para> /// <b>Important:</b> The <see cref="Reset"/> method must be called before the corridor /// can be used. (That is how the position is set.) /// </para> /// <para> /// Due to internal optimizations, the maximum number of detectable corners will be /// <c>(<paramref name="maxCorners"/> - 1)</c>. /// </para> /// <para>The query and filter parameters can be set to null. This supports the ability /// to create pools of re-usable path corridor objects. But it means that care needs to /// be taken not to use the corridor until query and filter objects have been set. /// See <see cref="ReleaseLocals"/> and <see cref="LoadLocals"/> for pool related utility /// functions. /// </para> /// </remarks> /// <param name="maxPathSize"> /// The maximum path size that can be handled by the object. [Limit: >= 1] /// </param> /// <param name="maxCorners"> /// The maximum number of corners the corner buffer can hold. [Limit: >= 2] /// </param> /// <param name="query">The query to be used by the corridor.</param> /// <param name="filter">The query filter to be used by the corridor.</param> public PathCorridor(int maxPathSize, int maxCorners , NavmeshQuery query, NavmeshQueryFilter filter) { maxPathSize = Math.Max(1, maxPathSize); mRoot = PathCorridorEx.dtpcAlloc(maxPathSize); if (mRoot == IntPtr.Zero) { mMaxPathSize = 0; return; } mQuery = query; mFilter = filter; mMaxPathSize = maxPathSize; mCorners = new CornerData(Math.Max(2, maxCorners)); }
/// <summary> /// Sets the specified resources and resets the corridor. /// </summary> /// <remarks> /// <para> /// This method is useful when pooling path corridors for use by mulitple clients. /// </para> /// <para> /// See <see cref="Reset"/> for information on the effect of the reset. /// </para> /// <para> /// Existing references will be replaced by the new references. /// </para> /// <para> /// This method cannot be used to set references to null. Attempting to do so will result /// in a failure. /// </para> /// </remarks> /// <param name="corridor">The corridor to update.</param> /// <param name="position">The position to reset to corridor to.</param> /// <param name="query">The query object to use.</param> /// <param name="filter">The filter object to use.</param> /// <returns>True if successful.</returns> public static bool LoadLocals(PathCorridor corridor, NavmeshPoint position , NavmeshQuery query, NavmeshQueryFilter filter) { // Basic checks first. if (position.polyRef == 0 || corridor == null || query == null || filter == null) { return(false); } // Validate optional parameters. // Assign and reset. corridor.mQuery = query; corridor.mFilter = filter; corridor.Reset(position); return(true); }
private CrowdManager(IntPtr crowd, Navmesh navmesh, int maxAgents, float maxAgentRadius) : base(AllocType.External) { mMaxAgentRadius = maxAgentRadius; mNavmesh = navmesh; root = crowd; mAgents = new CrowdAgent[maxAgents]; agentStates = new CrowdAgentCoreState[maxAgents]; IntPtr ptr = CrowdManagerEx.dtcGetFilter(root); mFilter = new NavmeshQueryFilter(ptr, AllocType.ExternallyManaged); ptr = CrowdManagerEx.dtcGetGrid(root); mGrid = new CrowdProximityGrid(ptr); ptr = CrowdManagerEx.dtcGetNavMeshQuery(root); mQuery = new NavmeshQuery(ptr, true, AllocType.ExternallyManaged); }
/// <summary> /// Creates a new filter with the same state as the current filter. /// </summary> /// <returns>A clone of the current filter.</returns> public NavmeshQueryFilter Clone() { if (IsDisposed) { return(null); } int count = this.AreaCount; NavmeshQueryFilter result = new NavmeshQueryFilter(count); result.ExcludeFlags = this.ExcludeFlags; result.IncludeFlags = this.IncludeFlags; for (int i = 0; i < count; i++) { result[i] = this[i]; } return(result); }
/// <summary> /// Finds the non-overlapping navigation polygons in the local neighborhood around the /// specified point. /// </summary> /// <remarks> /// <para> /// This method is optimized for a small query radius and small number of result polygons. /// </para> /// <para> /// The order of the result is from least to highest cost.</para> /// <para> /// At least one result buffer must be provided.</para> /// <para> /// The primary use case for this method is for performing Dijkstra searches. /// Candidate polygons are found by searching the graph beginning at the start polygon. /// </para> /// <para> /// The same intersection test restrictions that apply to the FindPoly methods apply /// to this method. /// </para> /// <para> /// The value of the center point is used as the start point for cost calculations. /// It is not projected onto the surface of the mesh, so its y-value will effect the costs. /// </para> /// <para> /// Intersection tests occur in 2D. All polygons and the search circle are projected /// onto the xz-plane, so the y-value of the center point does not effect intersection /// tests. /// </para> /// <para> /// If the buffers are is too small to hold the entire result, they will be /// filled to capacity. /// </para> /// </remarks> /// <param name="start"> /// The center point to start from which to start the search. (Must be valid.) /// </param> /// <param name="radius">The radius of the search circle.</param> /// <param name="filter">The filter to apply to the query.</param> /// <param name="resultPolyRefs"> /// The references of the polygons touched by the circle. /// [(polyRef) * resultCount] (Optional) /// </param> /// <param name="resultParentRefs"> /// The references of the parent polygons for each result. /// Zero if a result polygon has no parent. [(parentRef) * resultCount] (Optional) /// </param> /// <param name="resultCount">The number of polygons found.</param> /// <returns>The <see cref="NavStatus" /> flags for the query.</returns> public NavStatus GetPolysLocal(NavmeshPoint start, float radius , NavmeshQueryFilter filter , uint[] resultPolyRefs, uint[] resultParentRefs, out int resultCount) { resultCount = 0; // Set max count to the smallest length. int maxCount = (resultPolyRefs == null ? 0 : resultPolyRefs.Length); maxCount = (resultParentRefs == null ? maxCount : Math.Min(maxCount, resultParentRefs.Length)); if (maxCount == 0) return (NavStatus.Failure | NavStatus.InvalidParam); return NavmeshQueryEx.dtqFindLocalNeighbourhood(root , start.polyRef , ref start.point , radius , filter.root , resultPolyRefs , resultParentRefs , ref resultCount , maxCount); }
/// <summary> /// Finds the navigation polygons within the graph that touch the specified convex polygon. /// </summary> /// <remarks> /// <para> /// The order of the result is from least to highest cost. /// </para> /// <para> /// At least one result buffer must be provided. /// </para> /// <para> /// The primary use case for this method is for performing Dijkstra searches. /// Candidate polygons are found by searching the graph beginning at the start polygon. /// </para> /// <para> /// The same intersection test restrictions that apply to the circle version of this /// method apply to this method. /// </para> /// <para> /// The 3D centroid of the polygon is used as the start position for cost /// calculations. /// </para> /// <para>Intersection tests occur in 2D. All polygons are projected onto the xz-plane, /// so the y-values of the vertices do not effect intersection tests. /// </para> /// <para> /// If the buffers are is too small to hold the entire result, they will be /// filled to capacity. /// </para> /// </remarks> /// <param name="startPolyRef">The reference of the polygon to start the search at.</param> /// <param name="vertices"> /// The vertices of the convex polygon. [Length: vertCount] /// </param> /// <param name="filter">The filter to apply to the query.</param> /// <param name="resultPolyRefs"> /// The references of the polygons touched by the search /// polygon. [(polyRef) * resultCount] (Optional) /// </param> /// <param name="resultParentRefs"> /// The references of the parent polygons for each result. /// Zero if a result polygon has no parent. [(parentRef) * resultCount] (Optional) /// </param> /// <param name="resultCosts"> /// The search cost from the centroid point to the polygon. /// [(cost) * resultCount] (Optional) /// </param> /// <param name="resultCount">The number of polygons found.</param> /// <returns>The <see cref="NavStatus" /> flags for the query.</returns> public NavStatus FindPolys(uint startPolyRef , Vector3[] vertices , NavmeshQueryFilter filter , uint[] resultPolyRefs , uint[] resultParentRefs , float[] resultCosts , out int resultCount) { resultCount = 0; // Set max count to the smallest length. int maxCount = (resultPolyRefs == null ? 0 : resultPolyRefs.Length); maxCount = (resultParentRefs == null ? maxCount : Math.Min(maxCount, resultParentRefs.Length)); maxCount = (resultCosts == null ? maxCount : Math.Min(maxCount, resultCosts.Length)); if (maxCount == 0) return (NavStatus.Failure | NavStatus.InvalidParam); return NavmeshQueryEx.dtqFindPolysAroundShape(root , startPolyRef , vertices , vertices.Length , filter.root , resultPolyRefs , resultParentRefs , resultCosts , ref resultCount , maxCount); }
/// <summary> /// Gets all polygons whose AABB's overlap the search box. /// </summary> /// <remarks> /// <para> /// This is a fast, but inaccurate query since only AABB's are checked. A strict /// polygon-box overlap check is not performed. /// </para> /// <para> /// If no polygons are found, the method will return success with a result count of zero. /// </para> /// <para> /// If the result buffer is too small to hold the entire result then the buffer /// will be filled to capacity. The method of choosing which polygons from the full /// result are included in the partial result is undefined. /// </para> /// </remarks> /// <param name="searchPoint">The center of the query box.</param> /// <param name="extents">The search distance along each axis.</param> /// <param name="filter">The filter to apply to the query.</param> /// <param name="resultPolyRefs"> /// The references of the polygons that overlap the query box. /// [(polyRef) * resultCount] (Out) /// </param> /// <param name="resultCount">The number of polygons found.</param> /// <returns>The <see cref="NavStatus" /> flags for the query.</returns> public NavStatus GetPolys(Vector3 searchPoint , Vector3 extents , NavmeshQueryFilter filter , uint[] resultPolyRefs , out int resultCount) { resultCount = 0; return NavmeshQueryEx.dtqQueryPolygons(root , ref searchPoint , ref extents , filter.root , resultPolyRefs , ref resultCount , resultPolyRefs.Length); }
/// <summary> /// Casts a 'walkability' ray along the surface of the navigation mesh from the start point /// toward the end point. /// </summary> /// <remarks> /// <para> /// This method is meant to be used for quick short distance checks. /// </para> /// <para> /// If the path buffer is too small to hold the result, it will be filled as far as /// possible from the start point toward the end point.</para> /// <para> /// <b>Using the Hit Paramter</b></para> /// <para> /// If the hit parameter is a very high value (>1E38), then the ray has hit the /// end point. In this case the path represents a valid corridor to the end point and /// the value of hitNormal is undefined. /// </para> /// <para> /// If the hit parameter is zero, then the start point is on the border that was hit /// and the value of hitNormal is undefined. /// </para> /// <para> /// If <c>0 < hitParameter < 1.0 </c> then the following applies:</para> /// <code> /// distanceToHitBorder = distanceToEndPoint * hitParameter /// hitPoint = startPoint + (endPoint - startPoint) * hitParameter /// </code> /// <para> /// <b>Use Case Restriction</b> /// </para> /// <para> /// The raycast ignores the y-value of the end point. (2D check) This places /// significant limits on how it can be used. Example scenario:</para> /// <para> /// Consider a scene where there is a main floor with a second floor balcony that /// hangs over the main floor. So the first floor mesh extends below the balcony mesh. /// The start point is somewhere on the first floor. The end point is on the balcony. /// </para> /// <para> /// The raycast will search toward the end point along the first floor mesh. If it /// reaches the end point's xz-coordinates it will indicate 'no hit', meaning it reached /// the end point. /// </para> /// </remarks> /// <param name="start"> /// A point within the start polygon representing the start of the ray. /// </param> /// <param name="end">The point to cast the ray toward.</param> /// <param name="filter">The filter to apply to the query.</param> /// <param name="hitParameter">The hit parameter. (>1E38 if no hit.)</param> /// <param name="hitNormal">The normal of the nearest wall hit.</param> /// <param name="path"> /// The references of the visited polygons. [(polyRef) * pathCount] (Optional) /// </param> /// <param name="pathCount">The number of visited polygons.</param> /// <returns>The <see cref="NavStatus" /> flags for the query.</returns> public NavStatus Raycast(NavmeshPoint start, Vector3 end , NavmeshQueryFilter filter , out float hitParameter, out Vector3 hitNormal , uint[] path, out int pathCount) { pathCount = 0; hitParameter = 0; hitNormal = Vector3Util.Zero; int maxCount = (path == null ? 0 : path.Length); return NavmeshQueryEx.dtqRaycast(root , start , ref end , filter.root , ref hitParameter , ref hitNormal , path , ref pathCount , maxCount); }
/// <summary> /// Finds the polygon path from the start to the end polygon. /// </summary> /// <remarks> /// <para> /// This method is useful if the polygon reference of either the /// <paramref name="start"/> or <paramref name="end"/> point is not known. If both points /// have a polygon reference of zero, then this method is equivalent to the following: /// </para> /// <ol> /// <li> /// Using <see cref="GetNearestPoint(uint, Vector3, out Vector3)"/> with the /// <paramref name="start"/> point to get the start polygon. /// </li> /// <li> /// Using <see cref="GetNearestPoint(uint, Vector3, out Vector3)"/> with the /// <paramref name="end"/> point to get the end polygon. /// </li> /// <li>Calling the normal find path using the two new start and end points.</li> /// </ol> /// <para> /// <em>A point search will only be performed for points with a polygon reference /// of zero.</em> If a point search is required, the point and its polygon reference /// parameter become output parameters and the point will be snapped to the navigation mesh. /// </para> /// <para> /// This method may return a partial result, even if there is a failure. If there is /// no failure, it will at least perform the required point searches. If the point /// searches succeed, then the find path operation will be performed. /// </para> /// <para> /// Checking the return results: /// </para> /// <ul> /// <li>If the <paramref name="pathCount"/> is greater than zero, then the path and all /// required point searches succeeded.</li> /// <li>If the overall operation failed, but a point with an input polygon reference of /// zero has an output polygon reference that is non-zero, then that point's search /// succeeded.</li> /// </ul> /// <para> /// For the path results: /// </para> /// <para> /// If the end polygon cannot be reached, then the last polygon is the nearest one /// found to the end polygon. /// </para> /// <para> /// If the path buffer is to small to hold the result, it will be filled as far as /// possible from the start polygon toward the end polygon.</para> /// <para> /// The start and end points are used to calculate traversal costs. /// (y-values matter.) /// </para> /// </remarks> /// <param name="start"> /// A point within the start polygon. (In) (Out if the polygon reference is zero.) /// </param> /// <param name="end"> /// A point within the end polygon. (In) (Out if the polygon reference is zero.) /// </param> /// <param name="extents"> /// The search extents to use if the start or end point polygon reference is zero. /// </param> /// <param name="filter">The filter to apply to the query.</param> /// <param name="resultPath"> /// An ordered list of polygon references in the path. (Start to end.) (Out) /// [(polyRef) * pathCount] /// </param> /// <param name="pathCount">The number of polygons in the path.</param> /// <returns>The <see cref="NavStatus" /> flags for the query.</returns> public NavStatus FindPath(ref NavmeshPoint start, ref NavmeshPoint end , Vector3 extents, NavmeshQueryFilter filter , uint[] resultPath, out int pathCount) { pathCount = 0; return NavmeshQueryEx.dtqFindPathExt(root , ref start , ref end , ref extents , filter.root , resultPath , ref pathCount , resultPath.Length); }
/// <summary> /// Returns a random point on the navigation mesh. /// </summary> /// <remarks> /// <para> /// The search speed is linear to the number of polygons. /// </para> /// </remarks> /// <param name="filter">The filter to apply to the query.</param> /// <param name="randomPoint">A random point on the navigation mesh.</param> /// <returns>The <see cref="NavStatus" /> flags for the query.</returns> public NavStatus GetRandomPoint(NavmeshQueryFilter filter, out NavmeshPoint randomPoint) { randomPoint = new NavmeshPoint(); return NavmeshQueryEx.dtqFindRandomPoint(root, filter.root, ref randomPoint); }
/// <summary> /// Moves from the start to the end point constrained to the navigation mesh. /// </summary> /// <remarks> /// <para> /// This method is optimized for small delta movement and a small number of polygons. /// If used for too great a distance, the result will form an incomplete path.</para> /// <para> /// The result point will equal the end point if the end is reached. Otherwise the /// closest reachable point will be returned. /// </para> /// <para> /// The result position is not projected to the surface of the navigation mesh. If /// that is needed, use <see cref="GetPolyHeight"/>.</para> /// <para> /// This method treats the end point in the same manner as the <see cref="Raycast"/> /// method. (As a 2D point.) See that method's documentation for details on the impact. /// </para> /// <para> /// If the result buffer is too small to hold the entire result, it will be /// filled as far as possible from the start point toward the end point. /// </para> /// </remarks> /// <param name="start">A position within the start polygon.</param> /// <param name="end">The end position.</param> /// <param name="filter">The filter to apply to the query.</param> /// <param name="resultPoint">The result point from the move.</param> /// <param name="visitedPolyRefs">The references of the polygons /// visited during the move. [(polyRef) * visitedCount]</param> /// <param name="visitedCount">The number of polygons visited during /// the move.</param> /// <returns>The <see cref="NavStatus" /> flags for the query.</returns> public NavStatus MoveAlongSurface(NavmeshPoint start, Vector3 end , NavmeshQueryFilter filter , out Vector3 resultPoint , uint[] visitedPolyRefs, out int visitedCount) { visitedCount = 0; resultPoint = Vector3Util.Zero; return NavmeshQueryEx.dtqMoveAlongSurface(root , start , ref end , filter.root , ref resultPoint , visitedPolyRefs , ref visitedCount , visitedPolyRefs.Length); }
/// <summary> /// Immediately frees all unmanaged resources allocated by the object. /// </summary> public override void RequestDisposal() { // There are no managed or local allocations. if (root != IntPtr.Zero) { mFilter.RequestDisposal(); mFilter = null; mGrid.Dispose(); mGrid = null; mQuery.RequestDisposal(); mQuery = null; mNavmesh = null; mMaxAgentRadius = -1; agentStates = null; for (int i = 0; i < mAgents.Length; i++) { if (mAgents[i] == null) continue; mAgents[i].Dispose(); mAgents[i] = null; } CrowdManagerEx.dtcDetourCrowdFree(root); root = IntPtr.Zero; } }
/// <summary> /// Returns the distance from the specified position to the nearest polygon wall. /// </summary> /// <remarks> /// <para> /// The closest point is not height adjusted using the detail data. /// Use <see cref="GetPolyHeight"/> if needed. /// </para> /// <para> /// The distance will equal the search radius if there is no wall within the radius. /// In this case the values of closestPoint and normal are undefined. /// </para> /// <para> /// The normal will become unpredicable if the distance is a very small number. /// </para> /// </remarks> /// <param name="searchPoint">The center of the search circle.</param> /// <param name="searchRadius">The radius of the search circle.</param> /// <param name="filter">The filter to apply to the query.</param> /// <param name="distance">Distance to nearest wall.</param> /// <param name="closestPoint">The nearest point on the wall.</param> /// <param name="normal"> /// The normalized ray formed from the wall point to the source point. /// </param> /// <returns>The <see cref="NavStatus" /> flags for the query.</returns> public NavStatus FindDistanceToWall(NavmeshPoint searchPoint , float searchRadius , NavmeshQueryFilter filter , out float distance , out Vector3 closestPoint , out Vector3 normal) { distance = 0; closestPoint = Vector3Util.Zero; normal = Vector3Util.Zero; return NavmeshQueryEx.dtqFindDistanceToWall(root , searchPoint , searchRadius , filter.root , ref distance , ref closestPoint , ref normal); }
/// <summary> /// Finds the polygon path from the start to the end polygon. /// </summary> /// <remarks> /// <para> /// If the end polygon cannot be reached, then the last polygon is the nearest one /// found to the end polygon. /// </para> /// <para> /// If the path buffer is to small to hold the result, it will be filled as far as /// possible from the start polygon toward the end polygon. /// </para> /// <para> /// The start and end points are used to calculate traversal costs. (y-values matter.) /// </para> /// </remarks> /// <param name="start">A point within the start polygon.</param> /// <param name="end">A point within the end polygon.</param> /// <param name="filter">The filter to apply to the query.</param> /// <param name="resultPath"> /// An ordered list of polygoon references in the path. (Start to end.) (Out) /// [(polyRef) * pathCount] /// </param> /// <param name="pathCount">The number of polygons in the path.</param> /// <returns>The <see cref="NavStatus" /> flags for the query.</returns> public NavStatus FindPath(NavmeshPoint start, NavmeshPoint end , NavmeshQueryFilter filter , uint[] resultPath, out int pathCount) { pathCount = 0; return NavmeshQueryEx.dtqFindPath(root , start , end , filter.root , resultPath , ref pathCount , resultPath.Length); }
/// <summary> /// Returns a random point within reach of the specified location. /// </summary> /// <remarks> /// <para> /// The result point is constrainted to the polygons overlapped by the circle, not /// the circle itself. The overlap test follows the same rules as the FindPolys method. /// </para> /// <para> /// The search speed is linear to the number of polygons. /// </para> /// </remarks> /// <param name="start">The point to search from.</param> /// <param name="radius">The polygon overlap radius.</param> /// <param name="filter">The filter to apply to the query.</param> /// <param name="randomPoint">A random point within reach of the specified location.</param> /// <returns>The <see cref="NavStatus" /> flags for the query.</returns> public NavStatus GetRandomPoint(NavmeshPoint start, float radius , NavmeshQueryFilter filter , out NavmeshPoint randomPoint) { randomPoint = new NavmeshPoint(); return NavmeshQueryEx.dtqFindRandomPointCircle(root, start, radius , filter.root , ref randomPoint); }
/// <summary> /// Returns true if the polygon reference is valid and passes the filter restrictions. /// </summary> /// <param name="polyRef">The polygon reference.</param> /// <param name="filter">The filter to apply to the query.</param> /// <returns> /// True if the polygon reference is valid and passes the filter restrictions. /// </returns> public bool IsValidPolyRef(uint polyRef, NavmeshQueryFilter filter) { return NavmeshQueryEx.dtqIsValidPolyRef(root, polyRef, filter.root); }
/// <summary> /// Initializes a sliced path find query. /// </summary> /// <remarks> /// <para> /// This method will fail if <see cref="IsRestricted"/> is true. /// </para> /// <para> /// <b>Warning:</b> Calling any other query methods besides the other sliced path methods /// before finalizing this query may result in corrupted data. /// </para> /// <para> /// The filter is stored and used for the duration of the query. /// </para> /// <para> /// The standard use case: /// </para> /// <ol> /// <li>Initialize the sliced path query</li> /// <li>Call <see cref="UpdateSlicedFindPath"/> until its status returns complete.</li> /// <li>Call <see cref="FinalizeSlicedFindPath"/> to get the path.</li> /// </ol> /// </remarks> /// <param name="start">A point within the start polygon.</param> /// <param name="end">A point within the end polygon.</param> /// <param name="filter">The filter to apply to the query.</param> /// <returns>The <see cref="NavStatus" /> flags for the query.</returns> public NavStatus InitSlicedFindPath(NavmeshPoint start, NavmeshPoint end , NavmeshQueryFilter filter) { if (mIsRestricted) return NavStatus.Failure; return NavmeshQueryEx.dtqInitSlicedFindPath(root , start , end , filter.root); }
/// <summary> /// Creates a new filter with the same state as the current filter. /// </summary> /// <returns>A clone of the current filter.</returns> public NavmeshQueryFilter Clone() { if (IsDisposed) return null; int count = this.AreaCount; NavmeshQueryFilter result = new NavmeshQueryFilter(count); result.ExcludeFlags = this.ExcludeFlags; result.IncludeFlags = this.IncludeFlags; for (int i = 0; i < count; i++) { result[i] = this[i]; } return result; }
/// <summary> /// Finds the nearest point on the surface of the navigation mesh. /// </summary> /// <remarks> /// <para> /// If the search box does not intersect any polygons the search will return success, /// but the result polygon reference will be zero. So always check the polygon reference /// before using the point data. /// </para> /// <b>Warning:</b> This function is not suitable for large area searches. If the /// search extents overlaps more than 128 polygons it may return an invalid result. /// <para> /// The detail mesh is used to correct the y-value of result. /// </para> /// </remarks> /// <param name="searchPoint">The center of the search box.</param> /// <param name="extents">The search distance along each axis.</param> /// <param name="filter">The filter to apply to the query.</param> /// <param name="result">The nearest point on the polygon.</param> /// <returns>The <see cref="NavStatus"/> flags for the query.</returns> public NavStatus GetNearestPoint(Vector3 searchPoint, Vector3 extents , NavmeshQueryFilter filter , out NavmeshPoint result) { result = NavmeshPoint.Zero; return NavmeshQueryEx.dtqFindNearestPoly(root , ref searchPoint , ref extents , filter.root , ref result); }
/// <summary> /// Sets the specified resources and resets the corridor. /// </summary> /// <remarks> /// <para> /// This method is useful when pooling path corridors for use by mulitple clients. /// </para> /// <para> /// See <see cref="Reset"/> for information on the effect of the reset. /// </para> /// <para> /// Existing references will be replaced by the new references. /// </para> /// <para> /// This method cannot be used to set references to null. Attempting to do so will result /// in a failure. /// </para> /// </remarks> /// <param name="corridor">The corridor to update.</param> /// <param name="position">The position to reset to corridor to.</param> /// <param name="query">The query object to use.</param> /// <param name="filter">The filter object to use.</param> /// <returns>True if successful.</returns> public static bool LoadLocals(PathCorridor corridor, NavmeshPoint position , NavmeshQuery query, NavmeshQueryFilter filter) { // Basic checks first. if (position.polyRef == 0|| corridor == null|| query == null|| filter == null) return false; // Validate optional parameters. // Assign and reset. corridor.mQuery = query; corridor.mFilter = filter; corridor.Reset(position); return true; }
/// <summary> /// Returns the segments for the specified polygon, optionally excluding portals. /// </summary> /// <remarks> /// <para> /// If the segmentPolyRefs parameter is provided, then all polygon segments will be /// returned. If the parameter is null, then only the wall segments are returned. /// </para> /// <para> /// A segment that is normally a portal will be included in the result as a wall /// if the filter results in the neighbor polygon being considered impassable. /// </para> /// <para> /// The vertex and polyRef buffers must be sized for the maximum segments per polygon of /// the source navigation mesh. /// I.e. <c>(2 * <see cref="Navmesh.MaxAllowedVertsPerPoly"/>)</c> /// </para> /// </remarks> /// <param name="polyRef">The polygon reference.</param> /// <param name="filter">The filter to apply to the query.</param> /// <param name="resultSegments"> /// The segment vertex buffer for all segments. [(vertA, vertB) * segmentCount] /// </param> /// <param name="segmentPolyRefs"> /// Refernce ids of the each segment's neighbor polygon. Or zero if the segment is /// considered impassable. [(polyRef) * segmentCount] (Optional)</param> /// <param name="segmentCount">The number of segments returned.</param> /// <returns>The <see cref="NavStatus" /> flags for the query.</returns> public NavStatus GetPolySegments(uint polyRef , NavmeshQueryFilter filter , Vector3[] resultSegments , uint[] segmentPolyRefs , out int segmentCount) { segmentCount = 0; return NavmeshQueryEx.dtqGetPolyWallSegments(root , polyRef , filter.root , resultSegments , segmentPolyRefs , ref segmentCount , resultSegments.Length / 2); }