From a5b3344c1fdcc9f2c161487249865301879b6019 Mon Sep 17 00:00:00 2001 From: ikpil Date: Wed, 14 Feb 2024 01:34:16 +0900 Subject: [PATCH] replace DtPathCorridor comment --- src/DotRecast.Detour.Crowd/DtPathCorridor.cs | 379 +++++++++---------- 1 file changed, 184 insertions(+), 195 deletions(-) diff --git a/src/DotRecast.Detour.Crowd/DtPathCorridor.cs b/src/DotRecast.Detour.Crowd/DtPathCorridor.cs index 3dbdc3b..0a1ba7b 100644 --- a/src/DotRecast.Detour.Crowd/DtPathCorridor.cs +++ b/src/DotRecast.Detour.Crowd/DtPathCorridor.cs @@ -26,66 +26,80 @@ using DotRecast.Core.Numerics; namespace DotRecast.Detour.Crowd { - /** - * Represents a dynamic polygon corridor used to plan agent movement. - * - * The corridor is loaded with a path, usually obtained from a #NavMeshQuery::FindPath() query. The corridor is then - * used to plan local movement, with the corridor automatically updating as needed to deal with inaccurate agent - * locomotion. - * - * Example of a common use case: - * - * -# Construct the corridor object and call -# Obtain a path from a #dtNavMeshQuery object. -# Use #Reset() to set the - * agent's current position. (At the beginning of the path.) -# Use #SetCorridor() to load the path and target. -# Use - * #FindCorners() to plan movement. (This handles dynamic path straightening.) -# Use #MovePosition() to feed agent - * movement back into the corridor. (The corridor will automatically adjust as needed.) -# If the target is moving, use - * #MoveTargetPosition() to update the end of the corridor. (The corridor will automatically adjust as needed.) -# - * Repeat the previous 3 steps to continue to move the agent. - * - * The corridor position and target are always constrained to the navigation mesh. - * - * One of the difficulties in maintaining a path is that floating point errors, locomotion inaccuracies, and/or local - * steering can result in the agent crossing the boundary of the path corridor, temporarily invalidating the path. This - * class uses local mesh queries to detect and update the corridor as needed to handle these types of issues. - * - * The fact that local mesh queries are used to move the position and target locations results in two beahviors that - * need to be considered: - * - * Every time a move function is used there is a chance that the path will become non-optimial. Basically, the further - * the target is moved from its original location, and the further the position is moved outside the original corridor, - * the more likely the path will become non-optimal. This issue can be addressed by periodically running the - * #OptimizePathTopology() and #OptimizePathVisibility() methods. - * - * All local mesh queries have distance limitations. (Review the #dtNavMeshQuery methods for details.) So the most - * accurate use case is to move the position and target in small increments. If a large increment is used, then the - * corridor may not be able to accurately find the new location. Because of this limiation, if a position is moved in a - * large increment, then compare the desired and resulting polygon references. If the two do not match, then path - * replanning may be needed. E.g. If you move the target, check #GetLastPoly() to see if it is the expected polygon. - * - */ + /// Represents a dynamic polygon corridor used to plan agent movement. + /// @ingroup crowd, detour public class DtPathCorridor { private RcVec3f m_pos = new RcVec3f(); private RcVec3f m_target = new RcVec3f(); private List m_path; + private static readonly float MIN_TARGET_DIST = RcMath.Sqr(0.01f); /** - * Allocates the corridor's path buffer. - */ + @class dtPathCorridor + @par + + The corridor is loaded with a path, usually obtained from a #dtNavMeshQuery::findPath() query. The corridor + is then used to plan local movement, with the corridor automatically updating as needed to deal with inaccurate + agent locomotion. + + Example of a common use case: + + -# Construct the corridor object and call #init() to allocate its path buffer. + -# Obtain a path from a #dtNavMeshQuery object. + -# Use #reset() to set the agent's current position. (At the beginning of the path.) + -# Use #setCorridor() to load the path and target. + -# Use #findCorners() to plan movement. (This handles dynamic path straightening.) + -# Use #movePosition() to feed agent movement back into the corridor. (The corridor will automatically adjust as needed.) + -# If the target is moving, use #moveTargetPosition() to update the end of the corridor. + (The corridor will automatically adjust as needed.) + -# Repeat the previous 3 steps to continue to move the agent. + + The corridor position and target are always constrained to the navigation mesh. + + One of the difficulties in maintaining a path is that floating point errors, locomotion inaccuracies, and/or local + steering can result in the agent crossing the boundary of the path corridor, temporarily invalidating the path. + This class uses local mesh queries to detect and update the corridor as needed to handle these types of issues. + + The fact that local mesh queries are used to move the position and target locations results in two beahviors that + need to be considered: + + Every time a move function is used there is a chance that the path will become non-optimial. Basically, the further + the target is moved from its original location, and the further the position is moved outside the original corridor, + the more likely the path will become non-optimal. This issue can be addressed by periodically running the + #optimizePathTopology() and #optimizePathVisibility() methods. + + All local mesh queries have distance limitations. (Review the #dtNavMeshQuery methods for details.) So the most accurate + use case is to move the position and target in small increments. If a large increment is used, then the corridor + may not be able to accurately find the new location. Because of this limiation, if a position is moved in a large + increment, then compare the desired and resulting polygon references. If the two do not match, then path replanning + may be needed. E.g. If you move the target, check #getLastPoly() to see if it is the expected polygon. + */ public DtPathCorridor() { m_path = new List(); } - /** - * Resets the path corridor to the specified position. - * - * @param ref - * The polygon reference containing the position. - * @param pos - * The new position in the corridor. [(x, y, z)] - */ + /// @par + /// + /// @warning Cannot be called more than once. + /// Allocates the corridor's path buffer. + /// @param[in] maxPath The maximum path size the corridor can handle. + /// @return True if the initialization succeeded. + public void Init(int maxPath) + { + // ... + } + + /// @par + /// + /// Essentially, the corridor is set of one polygon in size with the target + /// equal to the position. + /// + /// Resets the path corridor to the specified position. + /// @param[in] ref The polygon reference containing the position. + /// @param[in] pos The new position in the corridor. [(x, y, z)] public void Reset(long refs, RcVec3f pos) { m_path.Clear(); @@ -94,25 +108,27 @@ namespace DotRecast.Detour.Crowd m_target = pos; } - private static readonly float MIN_TARGET_DIST = RcMath.Sqr(0.01f); - /** - * Finds the corners in the corridor from the position toward the target. (The straightened path.) - * - * This is the function used to plan local movement within the corridor. One or more corners can be detected in - * order to plan movement. It performs essentially the same function as #dtNavMeshQuery::findStraightPath. - * - * Due to internal optimizations, the maximum number of corners returned will be (@p maxCorners - 1) For example: If - * the buffers are sized to hold 10 corners, the function will never return more than 9 corners. So if 10 corners - * are needed, the buffers should be sized for 11 corners. - * - * If the target is within range, it will be the last corner and have a polygon reference id of zero. - * - * @param filter - * - * @param[in] navquery The query object used to build the corridor. - * @return Corners - */ + @par + + This is the function used to plan local movement within the corridor. One or more corners can be + detected in order to plan movement. It performs essentially the same function as #dtNavMeshQuery::findStraightPath. + + Due to internal optimizations, the maximum number of corners returned will be (@p maxCorners - 1) + For example: If the buffers are sized to hold 10 corners, the function will never return more than 9 corners. + So if 10 corners are needed, the buffers should be sized for 11 corners. + + If the target is within range, it will be the last corner and have a polygon reference id of zero. + */ + /// Finds the corners in the corridor from the position toward the target. (The straightened path.) + /// @param[out] cornerVerts The corner vertices. [(x, y, z) * cornerCount] [Size: <= maxCorners] + /// @param[out] cornerFlags The flag for each corner. [(flag) * cornerCount] [Size: <= maxCorners] + /// @param[out] cornerPolys The polygon reference for each corner. [(polyRef) * cornerCount] + /// [Size: <= @p maxCorners] + /// @param[in] maxCorners The maximum number of corners the buffers can hold. + /// @param[in] navquery The query object used to build the corridor. + /// @param[in] filter The filter to apply to the operation. + /// @return The number of corners returned in the corner buffers. [0 <= value <= @p maxCorners] public int FindCorners(ref List corners, int maxCorners, DtNavMeshQuery navquery, IDtQueryFilter filter) { var result = navquery.FindStraightPath(m_pos, m_target, m_path, ref corners, maxCorners, 0); @@ -150,32 +166,28 @@ namespace DotRecast.Detour.Crowd } /** - * Attempts to optimize the path if the specified point is visible from the current position. - * - * Inaccurate locomotion or dynamic obstacle avoidance can force the agent position significantly outside the - * original corridor. Over time this can result in the formation of a non-optimal corridor. Non-optimal paths can - * also form near the corners of tiles. - * - * This function uses an efficient local visibility search to try to optimize the corridor between the current - * position and @p next. - * - * The corridor will change only if @p next is visible from the current position and moving directly toward the - * point is better than following the existing path. - * - * The more inaccurate the agent movement, the more beneficial this function becomes. Simply adjust the frequency of - * the call to match the needs to the agent. - * - * This function is not suitable for long distance searches. - * - * @param next - * The point to search toward. [(x, y, z]) - * @param pathOptimizationRange - * The maximum range to search. [Limit: > 0] - * @param navquery - * The query object used to build the corridor. - * @param filter - * The filter to apply to the operation. - */ + @par + + Inaccurate locomotion or dynamic obstacle avoidance can force the argent position significantly outside the + original corridor. Over time this can result in the formation of a non-optimal corridor. Non-optimal paths can + also form near the corners of tiles. + + This function uses an efficient local visibility search to try to optimize the corridor + between the current position and @p next. + + The corridor will change only if @p next is visible from the current position and moving directly toward the point + is better than following the existing path. + + The more inaccurate the agent movement, the more beneficial this function becomes. Simply adjust the frequency + of the call to match the needs to the agent. + + This function is not suitable for long distance searches. + */ + /// Attempts to optimize the path if the specified point is visible from the current position. + /// @param[in] next The point to search toward. [(x, y, z]) + /// @param[in] pathOptimizationRange The maximum range to search. [Limit: > 0] + /// @param[in] navquery The query object used to build the corridor. + /// @param[in] filter The filter to apply to the operation. public void OptimizePathVisibility(RcVec3f next, float pathOptimizationRange, DtNavMeshQuery navquery, IDtQueryFilter filter) { // Clamp the ray to max distance. @@ -206,21 +218,18 @@ namespace DotRecast.Detour.Crowd } /** - * Attempts to optimize the path using a local area search. (Partial replanning.) - * - * Inaccurate locomotion or dynamic obstacle avoidance can force the agent position significantly outside the - * original corridor. Over time this can result in the formation of a non-optimal corridor. This function will use a - * local area path search to try to re-optimize the corridor. - * - * The more inaccurate the agent movement, the more beneficial this function becomes. Simply adjust the frequency of - * the call to match the needs to the agent. - * - * @param navquery - * The query object used to build the corridor. - * @param filter - * The filter to apply to the operation. - * - */ + @par + + Inaccurate locomotion or dynamic obstacle avoidance can force the agent position significantly outside the + original corridor. Over time this can result in the formation of a non-optimal corridor. This function will use a + local area path search to try to re-optimize the corridor. + + The more inaccurate the agent movement, the more beneficial this function becomes. Simply adjust the frequency of + the call to match the needs to the agent. + */ + /// Attempts to optimize the path using a local area search. (Partial replanning.) + /// @param[in] navquery The query object used to build the corridor. + /// @param[in] filter The filter to apply to the operation. public bool OptimizePathTopology(DtNavMeshQuery navquery, IDtQueryFilter filter, int maxIterations) { if (m_path.Count < 3) @@ -277,28 +286,26 @@ namespace DotRecast.Detour.Crowd } /** - * Moves the position from the current location to the desired location, adjusting the corridor as needed to reflect - * the change. - * - * Behavior: - * - * - The movement is constrained to the surface of the navigation mesh. - The corridor is automatically adjusted - * (shorted or lengthened) in order to remain valid. - The new position will be located in the adjusted corridor's - * first polygon. - * - * The expected use case is that the desired position will be 'near' the current corridor. What is considered 'near' - * depends on local polygon density, query search extents, etc. - * - * The resulting position will differ from the desired position if the desired position is not on the navigation - * mesh, or it can't be reached using a local search. - * - * @param npos - * The desired new position. [(x, y, z)] - * @param navquery - * The query object used to build the corridor. - * @param filter - * The filter to apply to the operation. - */ + @par + + Behavior: + + - The movement is constrained to the surface of the navigation mesh. + - The corridor is automatically adjusted (shorted or lengthened) in order to remain valid. + - The new position will be located in the adjusted corridor's first polygon. + + The expected use case is that the desired position will be 'near' the current corridor. What is considered 'near' + depends on local polygon density, query search half extents, etc. + + The resulting position will differ from the desired position if the desired position is not on the navigation mesh, + or it can't be reached using a local search. + */ + /// Moves the position from the current location to the desired location, adjusting the corridor + /// as needed to reflect the change. + /// @param[in] npos The desired new position. [(x, y, z)] + /// @param[in] navquery The query object used to build the corridor. + /// @param[in] filter The filter to apply to the operation. + /// @return Returns true if move succeeded. public bool MovePosition(RcVec3f npos, DtNavMeshQuery navquery, IDtQueryFilter filter) { // Move along navmesh and update new position. @@ -323,22 +330,24 @@ namespace DotRecast.Detour.Crowd } /** - * Moves the target from the curent location to the desired location, adjusting the corridor as needed to reflect - * the change. Behavior: - The movement is constrained to the surface of the navigation mesh. - The corridor is - * automatically adjusted (shorted or lengthened) in order to remain valid. - The new target will be located in the - * adjusted corridor's last polygon. - * - * The expected use case is that the desired target will be 'near' the current corridor. What is considered 'near' - * depends on local polygon density, query search extents, etc. The resulting target will differ from the desired - * target if the desired target is not on the navigation mesh, or it can't be reached using a local search. - * - * @param npos - * The desired new target position. [(x, y, z)] - * @param navquery - * The query object used to build the corridor. - * @param filter - * The filter to apply to the operation. - */ + @par + + Behavior: + + - The movement is constrained to the surface of the navigation mesh. + - The corridor is automatically adjusted (shorted or lengthened) in order to remain valid. + - The new target will be located in the adjusted corridor's last polygon. + + The expected use case is that the desired target will be 'near' the current corridor. What is considered 'near' depends on local polygon density, query search half extents, etc. + + The resulting target will differ from the desired target if the desired target is not on the navigation mesh, or it can't be reached using a local search. + */ + /// Moves the target from the curent location to the desired location, adjusting the corridor + /// as needed to reflect the change. + /// @param[in] npos The desired new target position. [(x, y, z)] + /// @param[in] navquery The query object used to build the corridor. + /// @param[in] filter The filter to apply to the operation. + /// @return Returns true if move succeeded. public bool MoveTargetPosition(RcVec3f npos, DtNavMeshQuery navquery, IDtQueryFilter filter) { // Move along navmesh and update new position. @@ -360,16 +369,16 @@ namespace DotRecast.Detour.Crowd return false; } - /** - * Loads a new path and target into the corridor. The current corridor position is expected to be within the first - * polygon in the path. The target is expected to be in the last polygon. - * - * @warning The size of the path must not exceed the size of corridor's path buffer set during #Init(). - * @param target - * The target location within the last polygon of the path. [(x, y, z)] - * @param path - * The path corridor. - */ + /// @par + /// + /// The current corridor position is expected to be within the first polygon in the path. The target + /// is expected to be in the last polygon. + /// + /// @warning The size of the path must not exceed the size of corridor's path buffer set during #init(). + /// Loads a new path and target into the corridor. + /// @param[in] target The target location within the last polygon of the path. [(x, y, z)] + /// @param[in] path The path corridor. [(polyRef) * @p npolys] + /// @param[in] npath The number of polygons in the path. public void SetCorridor(RcVec3f target, List path) { m_target = target; @@ -427,19 +436,15 @@ namespace DotRecast.Detour.Crowd return true; } - /** - * Checks the current corridor path to see if its polygon references remain valid. The path can be invalidated if - * there are structural changes to the underlying navigation mesh, or the state of a polygon within the path changes - * resulting in it being filtered out. (E.g. An exclusion or inclusion flag changes.) - * - * @param maxLookAhead - * The number of polygons from the beginning of the corridor to search. - * @param navquery - * The query object used to build the corridor. - * @param filter - * The filter to apply to the operation. - * @return - */ + /// @par + /// + /// The path can be invalidated if there are structural changes to the underlying navigation mesh, or the state of + /// a polygon within the path changes resulting in it being filtered out. (E.g. An exclusion or inclusion flag changes.) + /// Checks the current corridor path to see if its polygon references remain valid. + /// + /// @param[in] maxLookAhead The number of polygons from the beginning of the corridor to search. + /// @param[in] navquery The query object used to build the corridor. + /// @param[in] filter The filter to apply to the operation. public bool IsValid(int maxLookAhead, DtNavMeshQuery navquery, IDtQueryFilter filter) { // Check that all polygons still pass query filter. @@ -455,59 +460,43 @@ namespace DotRecast.Detour.Crowd return true; } - /** - * Gets the current position within the corridor. (In the first polygon.) - * - * @return The current position within the corridor. - */ + /// Gets the current position within the corridor. (In the first polygon.) + /// @return The current position within the corridor. public RcVec3f GetPos() { return m_pos; } - /** - * Gets the current target within the corridor. (In the last polygon.) - * - * @return The current target within the corridor. - */ + /// Gets the current target within the corridor. (In the last polygon.) + /// @return The current target within the corridor. public RcVec3f GetTarget() { return m_target; } - /** - * The polygon reference id of the first polygon in the corridor, the polygon containing the position. - * - * @return The polygon reference id of the first polygon in the corridor. (Or zero if there is no path.) - */ + /// The polygon reference id of the first polygon in the corridor, the polygon containing the position. + /// @return The polygon reference id of the first polygon in the corridor. (Or zero if there is no path.) public long GetFirstPoly() { return 0 == m_path.Count ? 0 : m_path[0]; } - /** - * The polygon reference id of the last polygon in the corridor, the polygon containing the target. - * - * @return The polygon reference id of the last polygon in the corridor. (Or zero if there is no path.) - */ + /// The polygon reference id of the last polygon in the corridor, the polygon containing the target. + /// @return The polygon reference id of the last polygon in the corridor. (Or zero if there is no path.) public long GetLastPoly() { return 0 == m_path.Count ? 0 : m_path[m_path.Count - 1]; } - /** - * The corridor's path. - */ + /// The corridor's path. + /// @return The corridor's path. [(polyRef) * #getPathCount()] public List GetPath() { return m_path; } - /** - * The number of polygons in the current corridor path. - * - * @return The number of polygons in the current corridor path. - */ + /// The number of polygons in the current corridor path. + /// @return The number of polygons in the current corridor path. public int GetPathCount() { return m_path.Count;