예제 #1
0
        /// <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;
            }
        }
예제 #2
0
        /// <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));
        }
예제 #3
0
        /// <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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
        /// <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);
        }
예제 #7
0
        /// <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);
        }
예제 #8
0
        /// <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);
        }
예제 #9
0
        /// <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));
        }
예제 #10
0
        /// <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 &lt; hitParameter &lt; 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);
        }
예제 #11
0
        /// <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);
        }
예제 #12
0
        /// <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);
        }
예제 #13
0
        /// <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;
            }
        }
        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);
        }
예제 #16
0
        /// <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);
        }
예제 #17
0
        /// <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);
        }
예제 #18
0
        /// <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);
        }
예제 #19
0
 /// <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);
 }
예제 #20
0
        /// <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);
        }
예제 #21
0
        /// <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;
        }
예제 #22
0
        /// <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);
        }
예제 #23
0
        /// <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;
        }
예제 #24
0
        /// <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);
        }