From 6f5c9f9b82418efc44b85974e604095b95354ada Mon Sep 17 00:00:00 2001 From: Stephen Pratt Date: Mon, 29 Aug 2011 23:03:16 +0000 Subject: [PATCH] Recast: Detail API documentation for the members declared in Recast.h. (Complete) Recast.h: Completed rcPolyMeshDetail through end, plus updates to existing documentation. Configuration: Removed DebugUtils directory from the document build. Configuration: Fixed issue 179. (Backslashes) --- Docs/Extern/Recast_api.txt | 176 +++++- Doxyfile | 5 +- Recast/Include/Recast.h | 821 ++++++++++++++++---------- Recast/Include/RecastAlloc.h | 2 +- Recast/Source/Recast.cpp | 42 +- Recast/Source/RecastArea.cpp | 34 +- Recast/Source/RecastContour.cpp | 13 + Recast/Source/RecastFilter.cpp | 30 +- Recast/Source/RecastLayers.cpp | 6 +- Recast/Source/RecastMesh.cpp | 8 +- Recast/Source/RecastMeshDetail.cpp | 8 +- Recast/Source/RecastRasterization.cpp | 27 + Recast/Source/RecastRegion.cpp | 49 +- 13 files changed, 891 insertions(+), 330 deletions(-) diff --git a/Docs/Extern/Recast_api.txt b/Docs/Extern/Recast_api.txt index bde5a0388..f6ff06444 100644 --- a/Docs/Extern/Recast_api.txt +++ b/Docs/Extern/Recast_api.txt @@ -2,9 +2,36 @@ // elements defined in the Recast.h. /** - + +@defgroup recast Recast + +Members in this module are used to create mesh data that is then +used to create Detour navigation meshes. + +The are a large number of possible ways to building navigation mesh data. +One of the simple piplines is as follows: + +-# Prepare the input triangle mesh. +-# Build a #rcHeightfield. +-# Build a #rcCompactHeightfield. +-# Build a #rcContourSet. +-# Build a #rcPolyMesh. +-# Build a #rcPolyMeshDetail. +-# Use the rcPolyMesh and rcPolyMeshDetail to build a Detour navigation mesh + tile. + +The general life-cycle of the main classes is as follows: + +-# Allocate the object using the Recast allocator. (E.g. #rcAllocHeightfield) +-# Initialize or build the object. (E.g. #rcCreateHeightfield) +-# Update the object as needed. (E.g. #rcRasterizeTriangles) +-# Use the object as part of the pipeline. +-# Free the object using the Recast allocator. (E.g. #rcFreeHeightField) + +@note This is a summary list of members. Use the index or search +feature to find minor members. + @struct rcConfig -@ingroup recast @par The is a convenience structure that represents an aggregation of parameters @@ -107,7 +134,6 @@ is limited to <= #DT_VERTS_PER_POLYGON. @struct rcHeightfield -@ingroup recast @par The grid of a heightfield is layed out on the xz-plane based on the @@ -180,7 +206,6 @@ Useful instances of this type can only by obtained from a #rcCompactHeightfield @struct rcCompactHeightfield -@ingroup recast @par For this type of heightfield, the spans represent the open (unobstructed) @@ -267,7 +292,6 @@ for (int y = 0; y < chf.height; ++y) @see rcAllocCompactHeightfield, rcFreeCompactHeightfield, rcBuildCompactHeightfield @struct rcContour -@ingroup recast @par A contour only exists within the context of a #rcContourSet object. @@ -320,18 +344,16 @@ if (r & RC_AREA_BORDER) See #verts for information on element layout. @struct rcContourSet -@ingroup recast @par All contours within the set share the minimum bounds and cell sizes of the set. The standard process for building a contour set is to allocate it -using #rcAllocContourSet, then initialize is using #rcBuildContours. +using #rcAllocContourSet, then initialize it using #rcBuildContours. @see rcAllocContourSet, rcFreeContourSet, rcBuildContours @struct rcPolyMesh -@ingroup recast @par A mesh of potentially overlapping convex polygons of between three @@ -424,4 +446,142 @@ Edges 3->4 and 4->8 are border edges not shared with any other polygon. The standard build process assigns the value of #RC_WALKABLE_AREA to all walkable polygons. This value can then be changed to meet user requirements. +@struct rcPolyMeshDetail +@par + +The detail mesh is made up of triangle sub-meshes that provide extra +height detail for each polygon in its assoicated polygon mesh. + +The standard process for building a detail mesh is to allocate it +using #rcAllocPolyMeshDetail, then build it using #rcBuildPolyMeshDetail. + +See the individual field definitions for details realted to the structure +the mesh. + +@see rcAllocPolyMeshDetail, rcFreePolyMeshDetail, rcBuildPolyMeshDetail, rcPolyMesh + +@var rcPolyMeshDetail::meshes +@par + +[(baseVertIndex, vertCount, baseTriIndex, triCount) * #nmeshes] + +Maximum number of vertices per sub-mesh: 127
+Maximum number of triangles per sub-mesh: 255 + +The sub-meshes are stored in the same order as the polygons from the +rcPolyMesh they represent. E.g. rcPolyMeshDetail sub-mesh 5 is associated +with #rcPolyMesh polygon 5. + +Example of iterating the triangles in a sub-mesh. + +@code +// Where dmesh is a reference to a rcPolyMeshDetail object. + +// Iterate the sub-meshes. (One for each source polygon.) +for (int i = 0; i < dmesh.nmeshes; ++i) +{ + const unsigned int* meshDef = &dmesh.meshes[i*4]; + const unsigned int baseVerts = meshDef[0]; + const unsigned int baseTri = meshDef[2]; + const int ntris = (int)meshDef[3]; + + const float* verts = &dmesh.verts[baseVerts*3]; + const unsigned char* tris = &dmesh.tris[baseTri*4]; + + // Iterate the sub-mesh's triangles. + for (int j = 0; j < ntris; ++j) + { + const float x = verts[tris[j*4+0]*3]; + const float y = verts[tris[j*4+1]*3]; + const float z = verts[tris[j*4+2]*3]; + // Do something with the vertex. + } +} +@endcode + +@var rcPolyMeshDetail::verts +@par + +[(x, y, z) * #nverts] + +The vertices are grouped by sub-mesh and will contain duplicates since +each sub-mesh is independently defined. + +The first group of vertices for each sub-mesh are in the same order as +the vertices for the sub-mesh's associated PolyMesh polygon. These +vertices are followed by any additional detail vertices. So it the +associated polygon has 5 vertices, the sub-mesh will have a minimum +of 5 vertices and the first 5 vertices will be equivalent to the 5 +polygon vertices. + +@var rcPolyMeshDetail::tris +@par + +[(vertIndexA, vertIndexB, vertIndexC, flags) * #ntris] + +The triangles are grouped by sub-mesh. + +Vertex Indices + +The vertex indices in the triangle array are local to the sub-mesh, not global. +To translate into an global index in the vertices array, the values must be +offset by the sub-mesh's base vertex index. + +Example: If the baseVertexIndex for the sub-mesh is 5 and the triangle entry +is (4, 8, 7, 0), then the actual indices for the vertices are (4 + 5, 8 + 5, 7 + 5). + +@b Flags + +The flags entry indicates which edges are internal and which are external to +the sub-mesh. Internal edges connect to other triangles within the same sub-mesh. +External edges represent portals to other sub-meshes or the null region. + +Each flag is stored in a 2-bit position. Where position 0 is the lowest 2-bits +and position 4 is the highest 2-bits: + + +Position 0: Edge AB (>> 0)
+Position 1: Edge BC (>> 2)
+Position 2: Edge CA (>> 4)
+Position 4: Unused
+
+ +Testing can be performed as follows: + +@code +if (((flags >> 2) & 0x3) != 0) +{ + // Edge BC is an external edge. +} +@endcode + +@fn void rcSetCon(rcCompactSpan &s, int dir, int i) +@par + +This function is used by the build process. It is rarely of use to end users. + +@see #rcCompactHeightfield, #rcCompactSpan + +@fn int rcGetCon(const rcCompactSpan &s, int dir) +@par + +Can be used to locate neighbor spans in a compact heightfield. See the +#rcCompactHeightfield documentation for details on its use. + +@see #rcCompactHeightfield, #rcCompactSpan + +@fn int rcGetDirOffsetX(int dir) +@par + +The value of @p dir will be automatically wrapped. So a value of 6 will be interpreted as 2. + +See the #rcCompactHeightfield documentation for usage details. + +@fn int rcGetDirOffsetY(int dir) +@par + +The value of @p dir will be automatically wrapped. So a value of 6 will be interpreted as 2. + +See the #rcCompactHeightfield documentation for usage details. + */ diff --git a/Doxyfile b/Doxyfile index c2cb0300e..a464bf9c4 100644 --- a/Doxyfile +++ b/Doxyfile @@ -613,12 +613,11 @@ WARN_LOGFILE = # with spaces. INPUT = Detour \ - DebugUtils \ DetourCrowd \ DetourTileCache \ Recast \ - Docs\Conceptual \ - Docs\Extern + Docs/Conceptual \ + Docs/Extern # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is diff --git a/Recast/Include/Recast.h b/Recast/Include/Recast.h index 16d72b902..64f70e416 100644 --- a/Recast/Include/Recast.h +++ b/Recast/Include/Recast.h @@ -19,17 +19,10 @@ #ifndef RECAST_H #define RECAST_H -/** - * @defgroup recast Recast - * Elements related to path planning. - * @note This list is not yet complete. (The documentation effort is still underway.) - */ - /// The value of PI used by Recast. static const float RC_PI = 3.14159265f; /// Recast log categories. -/// @ingroup recast /// @see rcContext enum rcLogCategory { @@ -39,7 +32,6 @@ enum rcLogCategory }; /// Recast performance timer categories. -/// @ingroup recast /// @see rcContext enum rcTimerLabel { @@ -105,6 +97,7 @@ enum rcTimerLabel /// Provides an interface for optional logging and performance tracking of the Recast /// build process. +/// @ingroup recast class rcContext { public: @@ -148,11 +141,6 @@ class rcContext protected: - /// @name Custom implementation functions. - /// Logging and timer functionality must be provided by a concrete - /// implementation of these functions. This class does not implement these functions. - ///@{ - /// Clears all log entries. virtual void doResetLog() {} @@ -177,8 +165,6 @@ class rcContext /// @param[in] label The category of the timer. /// @return The accumulated time of the timer, or -1 if timers are disabled or the timer has never been started. virtual int doGetAccumulatedTime(const rcTimerLabel /*label*/) const { return -1; } - - ///@} /// True if logging is enabled. bool m_logEnabled; @@ -188,6 +174,7 @@ class rcContext }; /// Specifies a configuration to use when performing Recast builds. +/// @ingroup recast struct rcConfig { /// The width of the field along the x-axis. [Limit: >= 0] [Units: vx] @@ -235,10 +222,10 @@ struct rcConfig /// the original raw contour. [Limit: >=0] [Units: wu] float maxSimplificationError; - /// The minimum number of cells allowed to form isolated island regions. [Limit: >=0] [Units: vx] + /// The minimum number of cells allowed to form isolated island areas. [Limit: >=0] [Units: vx] int minRegionArea; - /// Any regions with a cell count smaller than this value will, if possible, + /// Any regions with a span count smaller than this value will, if possible, /// be merged with larger regions. [Limit: >=0] [Units: vx] int mergeRegionArea; @@ -255,25 +242,25 @@ struct rcConfig float detailSampleMaxError; }; -/// Defines number of bits in rcSpan::smin and rcSpan::smax. +/// Defines the number of bits allocated to rcSpan::smin and rcSpan::smax. static const int RC_SPAN_HEIGHT_BITS = 13; /// Defines the maximum value for rcSpan::smin and rcSpan::smax. static const int RC_SPAN_MAX_HEIGHT = (1<> shift) & 0x3f; -} - -inline int rcGetDirOffsetX(int dir) -{ - const int offset[4] = { -1, 0, 1, 0, }; - return offset[dir&0x03]; -} +/// @name General helper functions +/// @{ -inline int rcGetDirOffsetY(int dir) -{ - const int offset[4] = { 0, 1, 0, -1 }; - return offset[dir&0x03]; -} - -/// @name Common helper functions -///@{ +/// Swaps the values of the two parameters. +/// @param[in,out] a Value A +/// @param[in,out] b Value B template inline void rcSwap(T& a, T& b) { T t = a; a = b; b = t; } + +/// Returns the minimum of two values. +/// @param[in] a Value A +/// @param[in] b Value B +/// @return The minimum of the two values. template inline T rcMin(T a, T b) { return a < b ? a : b; } + +/// Returns the maximum of two values. +/// @param[in] a Value A +/// @param[in] b Value B +/// @return The maximum of the two values. template inline T rcMax(T a, T b) { return a > b ? a : b; } + +/// Returns the absolute value. +/// @param[in] a The value. +/// @return The absolute value of the specified value. template inline T rcAbs(T a) { return a < 0 ? -a : a; } + +/// Return the square of a value. +/// @param[in] a The value. +/// @return The square of the value. template inline T rcSqr(T a) { return a*a; } + +/// Clamps the value to the specified range. +/// @param[in] v The value to clamp. +/// @param[in] mn The minimum permitted return value. +/// @param[in] mx The maximum permitted return value. +/// @return The value, clamped to the specified range. template inline T rcClamp(T v, T mn, T mx) { return v < mn ? mn : (v > mx ? mx : v); } + +/// Returns the square root of the value. +/// @param[in] x The value. +/// @return The square root of the vlaue. float rcSqrt(float x); + +/// Not documented. Internal use only. +/// @param[in] x Not documented. +/// @return Not documented. inline int rcAlign4(int x) { return (x+3) & ~3; } -///@} -/// @name Common vector helper functions. -///@{ +/// @} +/// @name Vector helper functions. +/// @{ + +/// Derives the cross product of two vectors. (v1 x v2) +/// @param[out] dest The cross product. [(x, y, z)] +/// @param[in] v1 A Vector [(x, y, z)] +/// @param[in] v2 A vector [(x, y, z)] inline void rcVcross(float* dest, const float* v1, const float* v2) { dest[0] = v1[1]*v2[2] - v1[2]*v2[1]; @@ -565,11 +608,20 @@ inline void rcVcross(float* dest, const float* v1, const float* v2) dest[2] = v1[0]*v2[1] - v1[1]*v2[0]; } +/// Derives the dot product of two vectors. (v1 . v2) +/// @param[in] v1 A Vector [(x, y, z)] +/// @param[in] v2 A vector [(x, y, z)] +/// @return The dot product. inline float rcVdot(const float* v1, const float* v2) { return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; } +/// Performs a scaled vector addition. (v1 + (v2 * s)) +/// @param[out] dest The result vector. [(x, y, z)] +/// @param[in] v1 The base vector [(x, y, z)] +/// @param[in] v2 The vector to scale and add to @p v1. [(x, y, z)] +/// @param[in] s The amount to scale @p v2 by before adding to @p v1. inline void rcVmad(float* dest, const float* v1, const float* v2, const float s) { dest[0] = v1[0]+v2[0]*s; @@ -577,6 +629,10 @@ inline void rcVmad(float* dest, const float* v1, const float* v2, const float s) dest[2] = v1[2]+v2[2]*s; } +/// Performs a vector addition. (@p v1 + @p v2) +/// @param[out] dest The result vector. [(x, y, z)] +/// @param[in] v1 The base vector [(x, y, z)] +/// @param[in] v2 The vector to add to @p v1. [(x, y, z)] inline void rcVadd(float* dest, const float* v1, const float* v2) { dest[0] = v1[0]+v2[0]; @@ -584,6 +640,10 @@ inline void rcVadd(float* dest, const float* v1, const float* v2) dest[2] = v1[2]+v2[2]; } +/// Performs a vector subtraction. (@p v1 - @p v2) +/// @param[out] dest The result vector. [(x, y, z)] +/// @param[in] v1 The base vector [(x, y, z)] +/// @param[in] v2 The vector to subtract from @p v1. [(x, y, z)] inline void rcVsub(float* dest, const float* v1, const float* v2) { dest[0] = v1[0]-v2[0]; @@ -591,6 +651,9 @@ inline void rcVsub(float* dest, const float* v1, const float* v2) dest[2] = v1[2]-v2[2]; } +/// Selects the minimum value of each element from the specified vectors. +/// @param[in, out] mn A vector. (Will be updated with the result.) [(x, y, z)] +/// @param[in] v A vector. [(x, y, z)] inline void rcVmin(float* mn, const float* v) { mn[0] = rcMin(mn[0], v[0]); @@ -598,6 +661,9 @@ inline void rcVmin(float* mn, const float* v) mn[2] = rcMin(mn[2], v[2]); } +/// Selects the maximum value of each element from the specified vectors. +/// @param[in, out] mx A vector. (Will be updated with the result.) [(x, y, z)] +/// @param[in] v A vector. [(x, y, z)] inline void rcVmax(float* mx, const float* v) { mx[0] = rcMax(mx[0], v[0]); @@ -605,6 +671,9 @@ inline void rcVmax(float* mx, const float* v) mx[2] = rcMax(mx[2], v[2]); } +/// Performs a vector copy. +/// @param[out] dest The result. [(x, y, z)] +/// @param[in] v The vector to copy [(x, y, z)] inline void rcVcopy(float* dest, const float* v) { dest[0] = v[0]; @@ -612,6 +681,10 @@ inline void rcVcopy(float* dest, const float* v) dest[2] = v[2]; } +/// Returns the distance between two points. +/// @param[in] v1 A point. [(x, y, z)] +/// @param[in] v2 A point. [(x, y, z)] +/// @return The distance between the two points. inline float rcVdist(const float* v1, const float* v2) { float dx = v2[0] - v1[0]; @@ -620,6 +693,10 @@ inline float rcVdist(const float* v1, const float* v2) return rcSqrt(dx*dx + dy*dy + dz*dz); } +/// Returns the square of the distance between two points. +/// @param[in] v1 A point. [(x, y, z)] +/// @param[in] v2 A point. [(x, y, z)] +/// @return The square of the distance between the two points. inline float rcVdistSqr(const float* v1, const float* v2) { float dx = v2[0] - v1[0]; @@ -628,6 +705,8 @@ inline float rcVdistSqr(const float* v1, const float* v2) return dx*dx + dy*dy + dz*dz; } +/// Normalizes the vector. +/// @param[in,out] v The vector to normalize. [(x, y, z)] inline void rcVnormalize(float* v) { float d = 1.0f / rcSqrt(rcSqr(v[0]) + rcSqr(v[1]) + rcSqr(v[2])); @@ -636,269 +715,407 @@ inline void rcVnormalize(float* v) v[2] *= d; } +/// Not documented. Internal use only. +/// @param[in] p0 Not documented. +/// @param[in] p1 Not documented. +/// @return Not documented. inline bool rcVequal(const float* p0, const float* p1) { static const float thr = rcSqr(1.0f/16384.0f); const float d = rcVdistSqr(p0, p1); return d < thr; } -///@} -/// Calculated bounding box of array of vertices. -/// @param verts [in] array of vertices -/// @param nv [in] vertex count -/// @param bmin,bmax [out] bounding box +/// @} +/// @name Heightfield Functions +/// @see rcHeightfield +/// @{ + +/// Calculates the bounding box of an array of vertices. +/// @ingroup recast +/// @param[in] verts An array of vertices. [(x, y, z) * @p nv] +/// @param[in] nv The number of vertices in the @p verts array. +/// @param[out] bmin The minimum bounds of the AABB. [(x, y, z)] [Units: wu] +/// @param[out] bmax The maximum bounds of the AABB. [(x, y, z)] [Units: wu] void rcCalcBounds(const float* verts, int nv, float* bmin, float* bmax); -/// Calculates grid size based on bounding box and grid cell size. -/// @param bmin,bmax [in] bounding box -/// @param cs [in] grid cell size -/// @param w [out] grid width -/// @param h [out] grid height +/// Calculates the grid size based on the bounding box and grid cell size. +/// @ingroup recast +/// @param[in] bmin The minimum bounds of the AABB. [(x, y, z)] [Units: wu] +/// @param[in] bmax The maximum bounds of the AABB. [(x, y, z)] [Units: wu] +/// @param[in] cs The xz-plane cell size. [Limit: > 0] [Units: wu] +/// @param[out] w The width along the x-axis. [Limit: >= 0] [Units: vx] +/// @param[out] h The height along the z-axis. [Limit: >= 0] [Units: vx] void rcCalcGridSize(const float* bmin, const float* bmax, float cs, int* w, int* h); -/// Creates and initializes new heightfield. -/// @param hf [in,out] heightfield to initialize. -/// @param width [in] width of the heightfield. -/// @param height [in] height of the heightfield. -/// @param bmin,bmax [in] bounding box of the heightfield -/// @param cs [in] grid cell size -/// @param ch [in] grid cell height +/// Initializes a new heightfield. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in,out] hf The allocated heightfield to initialize. +/// @param[in] width The width of the field along the x-axis. [Limit: >= 0] [Units: vx] +/// @param[in] height The height of the field along the z-axis. [Limit: >= 0] [Units: vx] +/// @param[in] bmin The minimum bounds of the field's AABB. [(x, y, z)] [Units: wu] +/// @param[in] bmax The maximum bounds of the field's AABB. [(x, y, z)] [Units: wu] +/// @param[in] cs The xz-plane cell size to use for the field. [Limit: > 0] [Units: wu] +/// @param[in] ch The y-axis cell size to use for field. [Limit: > 0] [Units: wu] bool rcCreateHeightfield(rcContext* ctx, rcHeightfield& hf, int width, int height, const float* bmin, const float* bmax, float cs, float ch); -/// Sets the RC_WALKABLE_AREA for every triangle whose slope is below -/// the maximum walkable slope angle. -/// @param walkableSlopeAngle [in] maximum slope angle in degrees. -/// @param verts [in] array of vertices -/// @param nv [in] vertex count -/// @param tris [in] array of triangle vertex indices -/// @param nt [in] triangle count -/// @param areas [out] array of triangle area types +/// Sets the area id of all triangles with a slope below the specified value +/// to #RC_WALKABLE_AREA. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] walkableSlopeAngle The maximum slope that is considered walkable. [Limits: 0 <= value < 90] +/// [Units: Degrees] +/// @param[in] verts The vertices. [(x, y, z) * @p nv] +/// @param[in] nv The number of vertices. +/// @param[in] tris The triangle vertex indices. [(vertA, vertB, vertC) * @p nt] +/// @param[in] nt The number of triangles. +/// @param[out] areas The triangle area ids. [Length: >= @p nt] void rcMarkWalkableTriangles(rcContext* ctx, const float walkableSlopeAngle, const float* verts, int nv, const int* tris, int nt, unsigned char* areas); -/// Sets the RC_NULL_AREA for every triangle whose slope is steeper than -/// the maximum walkable slope angle. -/// @param walkableSlopeAngle [in] maximum slope angle in degrees. -/// @param verts [in] array of vertices -/// @param nv [in] vertex count -/// @param tris [in] array of triangle vertex indices -/// @param nt [in] triangle count -/// @param areas [out] array of triangle are types +/// Sets the area id of all triangles with a slope greater than or equal to the specified value to #RC_NULL_AREA. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] walkableSlopeAngle The maximum slope that is considered walkable. [Limits: 0 <= value < 90] +/// [Units: Degrees] +/// @param[in] verts The vertices. [(x, y, z) * @p nv] +/// @param[in] nv The number of vertices. +/// @param[in] tris The triangle vertex indices. [(vertA, vertB, vertC) * @p nt] +/// @param[in] nt The number of triangles. +/// @param[out] areas The triangle area ids. [Length: >= @p nt] void rcClearUnwalkableTriangles(rcContext* ctx, const float walkableSlopeAngle, const float* verts, int nv, const int* tris, int nt, unsigned char* areas); -/// Adds span to heightfield. -/// The span addition can set to favor flags. If the span is merged to -/// another span and the new smax is within 'flagMergeThr' units away -/// from the existing span the span flags are merged and stored. -/// @param x,y [in] location on the heightfield where the span is added -/// @param smin,smax [in] spans min/max height -/// @param area -/// @param flagMergeThr [in] merge threshold. +/// Adds a span to the specified heightfield. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in,out] hf An initialized heightfield. +/// @param[in] x The width index where the span is to be added. +/// [Limits: 0 <= value < rcHeightfield::width] +/// @param[in] y The height index where the span is to be added. +/// [Limits: 0 <= value < rcHeightfield::height] +/// @param[in] smin The minimum height of the span. [Limit: < @p smax] [Units: vx] +/// @param[in] smax The maximum height of the span. [Limit: <= #RC_SPAN_MAX_HEIGHT] [Units: vx] +/// @param[in] area The area id of the span. [Limit: <= #RC_WALKABLE_AREA) +/// @param[in] flagMergeThr The merge theshold. [Limit: >= 0] [Units: vx] void rcAddSpan(rcContext* ctx, rcHeightfield& hf, const int x, const int y, const unsigned short smin, const unsigned short smax, const unsigned char area, const int flagMergeThr); -/// Rasterizes a triangle into heightfield spans. -/// @param v0,v1,v2 [in] the vertices of the triangle. -/// @param area [in] area type of the triangle. -/// @param solid [in] heightfield where the triangle is rasterized -/// @param flagMergeThr [in] distance in voxel where walkable flag is favored over non-walkable. +/// Rasterizes a triangle into the specified heightfield. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] v0 Triangle vertex 0 [(x, y, z)] +/// @param[in] v1 Triangle vertex 1 [(x, y, z)] +/// @param[in] v2 Triangle vertex 2 [(x, y, z)] +/// @param[in] area The area id of the triangle. [Limit: <= #RC_WALKABLE_AREA] +/// @param[in, out] solid An initialized heightfield. +/// @param[in] flagMergeThr The distance where the walkable flag is favored over the non-walkable flag. +/// [Limit: >= 0] [Units: vx] void rcRasterizeTriangle(rcContext* ctx, const float* v0, const float* v1, const float* v2, const unsigned char area, rcHeightfield& solid, const int flagMergeThr = 1); -/// Rasterizes indexed triangle mesh into heightfield spans. -/// @param verts [in] array of vertices -/// @param nv [in] vertex count -/// @param tris [in] array of triangle vertex indices -/// @param areas [in] array of triangle area types. -/// @param nt [in] triangle count -/// @param solid [in] heightfield where the triangles are rasterized -/// @param flagMergeThr [in] distance in voxel where walkable flag is favored over non-walkable. +/// Rasterizes an indexed triangle mesh into the specified heightfield. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] verts The vertices. [(x, y, z) * @p nv] +/// @param[in] nv The number of vertices. +/// @param[in] tris The triangle indices. [(vertA, vertB, vertC) * @p nt] +/// @param[in] areas The area id's of the triangles. [Limit: <= #RC_WALKABLE_AREA] [Size: @p nt] +/// @param[in] nt The number of triangles. +/// @param[in, out] solid An initialized heightfield. +/// @param[in] flagMergeThr The distance where the walkable flag is favored over the non-walkable flag. +/// [Limit: >= 0] [Units: vx] void rcRasterizeTriangles(rcContext* ctx, const float* verts, const int nv, const int* tris, const unsigned char* areas, const int nt, rcHeightfield& solid, const int flagMergeThr = 1); -/// Rasterizes indexed triangle mesh into heightfield spans. -/// @param verts [in] array of vertices -/// @param nv [in] vertex count -/// @param tris [in] array of triangle vertex indices -/// @param areas [in] array of triangle area types. -/// @param nt [in] triangle count -/// @param solid [in] heightfield where the triangles are rasterized -/// @param flagMergeThr [in] distance in voxel where walkable flag is favored over non-walkable. +/// Rasterizes an indexed triangle mesh into the specified heightfield. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] verts The vertices. [(x, y, z) * @p nv] +/// @param[in] nv The number of vertices. +/// @param[in] tris The triangle indices. [(vertA, vertB, vertC) * @p nt] +/// @param[in] areas The area id's of the triangles. [Limit: <= #RC_WALKABLE_AREA] [Size: @p nt] +/// @param[in] nt The number of triangles. +/// @param[in, out] solid An initialized heightfield. +/// @param[in] flagMergeThr The distance where the walkable flag is favored over the non-walkable flag. +/// [Limit: >= 0] [Units: vx] void rcRasterizeTriangles(rcContext* ctx, const float* verts, const int nv, const unsigned short* tris, const unsigned char* areas, const int nt, rcHeightfield& solid, const int flagMergeThr = 1); -/// Rasterizes the triangles into heightfield spans. -/// @param verts [in] array of vertices -/// @param areas [in] array of triangle area types. -/// @param nt [in] triangle count -/// @param solid [in] heightfield where the triangles are rasterized +/// Rasterizes triangles into the specified heightfield. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] verts The triangle vertices. [(ax, ay, az, bx, by, bz, cx, by, cx) * @p nt] +/// @param[in] areas The area id's of the triangles. [Limit: <= #RC_WALKABLE_AREA] [Size: @p nt] +/// @param[in] nt The number of triangles. +/// @param[in, out] solid An initialized heightfield. +/// @param[in] flagMergeThr The distance where the walkable flag is favored over the non-walkable flag. +/// [Limit: >= 0] [Units: vx] void rcRasterizeTriangles(rcContext* ctx, const float* verts, const unsigned char* areas, const int nt, rcHeightfield& solid, const int flagMergeThr = 1); -/// Marks non-walkable low obstacles as walkable if they are closer than walkableClimb -/// from a walkable surface. Applying this filter allows to step over low hanging -/// low obstacles. -/// @param walkableClimb [in] maximum height between grid cells the agent can climb -/// @param solid [in,out] heightfield describing the solid space -/// @warning TODO: Misses ledge flag, must be called before rcFilterLedgeSpans! +/// Marks non-walkable spans as walkable if their maximum is within @p walkableClimp of a walkable neihbor. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] walkableClimb Maximum ledge height that is considered to still be traversable. +/// [Limit: >=0] [Units: vx] +/// @param[in,out] solid A fully built heightfield. (All spans have been added.) void rcFilterLowHangingWalkableObstacles(rcContext* ctx, const int walkableClimb, rcHeightfield& solid); -/// Removes WALKABLE flag from all spans that are at ledges. This filtering -/// removes possible overestimation of the conservative voxelization so that -/// the resulting mesh will not have regions hanging in air over ledges. -/// @param walkableHeight [in] minimum height where the agent can still walk -/// @param walkableClimb [in] maximum height between grid cells the agent can climb -/// @param solid [in,out] heightfield describing the solid space +/// Marks spans that are ledges as not-walkable. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] walkableHeight Minimum floor to 'ceiling' height that will still allow the floor area to +/// be considered walkable. [Limit: >= 3] [Units: vx] +/// @param[in] walkableClimb Maximum ledge height that is considered to still be traversable. +/// [Limit: >=0] [Units: vx] +/// @param[in,out] solid A fully built heightfield. (All spans have been added.) void rcFilterLedgeSpans(rcContext* ctx, const int walkableHeight, const int walkableClimb, rcHeightfield& solid); -/// Removes WALKABLE flag from all spans which have smaller than -/// 'walkableHeight' clearance above them. -/// @param walkableHeight [in] minimum height where the agent can still walk -/// @param solid [in,out] heightfield describing the solid space +/// Marks walkable spans as not walkable if the clearence above the span is less than the specified height. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] walkableHeight Minimum floor to 'ceiling' height that will still allow the floor area to +/// be considered walkable. [Limit: >= 3] [Units: vx] +/// @param[in,out] solid A fully built heightfield. (All spans have been added.) void rcFilterWalkableLowHeightSpans(rcContext* ctx, int walkableHeight, rcHeightfield& solid); -/// Returns number of spans contained in a heightfield. -/// @param hf [in] heightfield to be compacted -/// @returns number of spans. +/// Returns the number of spans contained in the specified heightfield. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] hf An initialized heightfield. +/// @returns The number of spans in the heightfield. int rcGetHeightFieldSpanCount(rcContext* ctx, rcHeightfield& hf); -/// Builds compact representation of the heightfield. -/// @param walkableHeight [in] minimum height where the agent can still walk -/// @param walkableClimb [in] maximum height between grid cells the agent can climb -/// @param hf [in] heightfield to be compacted -/// @param chf [out] compact heightfield representing the open space. -/// @returns false if operation ran out of memory. +/// @} +/// @name Compact Heightfield Functions +/// @see rcCompactHeightfield +/// @{ + +/// Builds a compact heightfield representing open space, from a heightfield representing solid space. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] walkableHeight Minimum floor to 'ceiling' height that will still allow the floor area +/// to be considered walkable. [Limit: >= 3] [Units: vx] +/// @param[in] walkableClimb Maximum ledge height that is considered to still be traversable. +/// [Limit: >=0] [Units: vx] +/// @param[in] hf The heightfield to be compacted. +/// @param[out] chf The resulting compact heightfield. (Must be pre-allocated.) +/// @returns True if the operation completed successfully. bool rcBuildCompactHeightfield(rcContext* ctx, const int walkableHeight, const int walkableClimb, rcHeightfield& hf, rcCompactHeightfield& chf); -/// Erodes walkable area. -/// @param radius [in] radius of erosion (max 255). -/// @param chf [in,out] compact heightfield to erode. -/// @returns false if operation ran out of memory. +/// Erodes the walkable area within the heightfield by the specified radius. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] radius The radius of erosion. [Limits: 0 < value < 255] [Units: vx] +/// @param[in,out] chf The populated compact heightfield to erode. +/// @returns True if the operation completed successfully. bool rcErodeWalkableArea(rcContext* ctx, int radius, rcCompactHeightfield& chf); -/// Applies median filter to walkable area types, removing noise. -/// @param chf [in,out] compact heightfield to erode. -/// @returns false if operation ran out of memory. +/// Applies a median filter to walkable area types (based on area id), removing noise. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in,out] chf A populated compact heightfield. +/// @returns True if the operation completed successfully. bool rcMedianFilterWalkableArea(rcContext* ctx, rcCompactHeightfield& chf); -/// Marks the area of the convex polygon into the area type of the compact heightfield. -/// @param bmin,bmax [in] bounds of the axis aligned box. -/// @param areaId [in] area ID to mark. -/// @param chf [in,out] compact heightfield to mark. +/// Applies an area id to all spans within the specified bounding box. (AABB) +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] bmin The minimum of the bounding box. [(x, y, z)] +/// @param[in] bmax The maximum of the bounding box. [(x, y, z)] +/// @param[in] areaId The area id to apply. [Limit: <= #RC_WALKABLE_AREA] +/// @param[in,out] chf A populated compact heightfield. void rcMarkBoxArea(rcContext* ctx, const float* bmin, const float* bmax, unsigned char areaId, rcCompactHeightfield& chf); -/// Marks the area of the convex polygon into the area type of the compact heightfield. -/// @param verts [in] vertices of the convex polygon. -/// @param nverts [in] number of vertices in the polygon. -/// @param hmin,hmax [in] min and max height of the polygon. -/// @param areaId [in] area ID to mark. -/// @param chf [in,out] compact heightfield to mark. +/// Applies the area id to the all spans within the specified convex polygon. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] verts The vertices of the polygon [Fomr: (x, y, z) * @p nverts] +/// @param[in] nverts The number of vertices in the polygon. +/// @param[in] hmin The height of the base of the polygon. +/// @param[in] hmax The height of the top of the polygon. +/// @param[in] areaId The area id to apply. [Limit: <= #RC_WALKABLE_AREA] +/// @param[in,out] chf A populated compact heightfield. void rcMarkConvexPolyArea(rcContext* ctx, const float* verts, const int nverts, const float hmin, const float hmax, unsigned char areaId, rcCompactHeightfield& chf); -/// Marks the area of the cylinder into the area type of the compact heightfield. -/// @param pos [in] center bottom location of hte cylinder. -/// @param r [in] radius of the cylinder. -/// @param h [in] height of the cylinder. -/// @param areaId [in] area ID to mark. -/// @param chf [in,out] compact heightfield to mark. +/// Applies the area id to all spans within the specified cylinder. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] pos The center of the base of the cylinder. [Form: (x, y, z)] +/// @param[in] r The radius of the cylinder. +/// @param[in] h The height of the cylinder. +/// @param[in] areaId The area id to apply. [Limit: <= #RC_WALKABLE_AREA] +/// @param[in,out] chf A populated compact heightfield. void rcMarkCylinderArea(rcContext* ctx, const float* pos, const float r, const float h, unsigned char areaId, rcCompactHeightfield& chf); -/// Builds distance field and stores it into the combat heightfield. -/// @param chf [in,out] compact heightfield representing the open space. -/// @returns false if operation ran out of memory. +/// Builds the distance field for the specified compact heightfield. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in,out] chf A populated compact heightfield. +/// @returns True if the operation completed successfully. bool rcBuildDistanceField(rcContext* ctx, rcCompactHeightfield& chf); -/// Divides the walkable heighfied into simple regions using watershed partitioning. -/// Each region has only one contour and no overlaps. -/// The regions are stored in the compact heightfield 'reg' field. -/// The process sometimes creates small regions. If the area of a regions is -/// smaller than 'mergeRegionArea' then the region will be merged with a neighbour -/// region if possible. If multiple regions form an area which is smaller than -/// 'minRegionArea' all the regions belonging to that area will be removed. -/// Here area means the count of spans in an area. -/// @param chf [in,out] compact heightfield representing the open space. -/// @param borderSize [in] Non-navigable Border around the heightfield. -/// @param minRegionArea [in] the smallest allowed region area. -/// @param maxMergeRegionArea [in] the largest allowed region area which can be merged. -/// @returns false if operation ran out of memory. +/// Builds region data for the heightfield using watershed partitioning. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in,out] chf A populated compact heightfield. +/// @param[in] borderSize The size of the non-navigable border around the heightfield. [Limit: >=0] [Units: vx] +/// @param[in] minRegionArea The minimum number of cells allowed to form isolated island areas. [Limit: >=0] +/// [Units: vx]. +/// @param[in] mergeRegionArea Any regions with a span count smaller than this value will, if possible, +/// be merged with larger regions. [Limit: >=0] [Units: vx] +/// @returns True if the operation completed successfully. bool rcBuildRegions(rcContext* ctx, rcCompactHeightfield& chf, const int borderSize, const int minRegionArea, const int mergeRegionArea); -/// Divides the walkable heighfied into simple regions using simple monotone partitioning. -/// Each region has only one contour and no overlaps. -/// The regions are stored in the compact heightfield 'reg' field. -/// The process sometimes creates small regions. If the area of a regions is -/// smaller than 'mergeRegionArea' then the region will be merged with a neighbour -/// region if possible. If multiple regions form an area which is smaller than -/// 'minRegionArea' all the regions belonging to that area will be removed. -/// Here area means the count of spans in an area. -/// @param chf [in,out] compact heightfield representing the open space. -/// @param borderSize [in] Non-navigable Border around the heightfield. -/// @param minRegionArea [in] the smallest allowed regions size. -/// @param maxMergeRegionArea [in] the largest allowed regions size which can be merged. -/// @returns false if operation ran out of memory. +/// Builds region data for the heightfield using simple monotone partitioning. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in,out] chf A populated compact heightfield. +/// @param[in] borderSize The size of the non-navigable border around the heightfield. [Limit: >=0] [Units: vx] +/// @param[in] minRegionArea The minimum number of cells allowed to form isolated island areas. [Limit: >=0] +/// [Units: vx]. +/// @param[in] mergeRegionArea Any regions with a span count smaller than this value will, if possible, +/// be merged with larger regions. [Limit: >=0] [Units: vx] +/// @returns True if the operation completed successfully. bool rcBuildRegionsMonotone(rcContext* ctx, rcCompactHeightfield& chf, const int borderSize, const int minRegionArea, const int mergeRegionArea); -/// Builds 2D layer representation of a heighfield. -/// @param chf [in] compact heightfield representing the open space. -/// @param borderSize [in] Non-navigable Border around the heightfield. -/// @param walkableHeight [in] minimum height where the agent can still walk. -/// @param lset [out] set of 2D heighfield layers. -/// @returns false if operation ran out of memory. + +/// Sets the neighbor connection data for the specified direction. +/// @param[in] s The span to update. +/// @param[in] dir The direction to set. [Limits: 0 <= value < 4] +/// @param[in] i The index of the neighbor span. +inline void rcSetCon(rcCompactSpan& s, int dir, int i) +{ + const unsigned int shift = (unsigned int)dir*6; + unsigned int con = s.con; + s.con = (con & ~(0x3f << shift)) | (((unsigned int)i & 0x3f) << shift); +} + +/// Gets neighbor connection data for the specified direction. +/// @param[in] s The span to check. +/// @param[in] dir The direction to check. [Limits: 0 <= value < 4] +/// @return The neighbor connection data for the specified direction, +/// or #RC_NOT_CONNECTED if there is no connection. +inline int rcGetCon(const rcCompactSpan& s, int dir) +{ + const unsigned int shift = (unsigned int)dir*6; + return (s.con >> shift) & 0x3f; +} + +/// Gets the standard width (x-axis) offset for the specified direction. +/// @param[in] dir The direction. [Limits: 0 <= value < 4] +/// @return The width offset to apply to the current cell position to move +/// in the direction. +inline int rcGetDirOffsetX(int dir) +{ + const int offset[4] = { -1, 0, 1, 0, }; + return offset[dir&0x03]; +} + +/// Gets the standard height (z-axis) offset for the specified direction. +/// @param[in] dir The direction. [Limits: 0 <= value < 4] +/// @return The height offset to apply to the current cell position to move +/// in the direction. +inline int rcGetDirOffsetY(int dir) +{ + const int offset[4] = { 0, 1, 0, -1 }; + return offset[dir&0x03]; +} + +/// @} +/// @name Layer, Contour, Polymesh, and Detail Mesh Functions +/// @see rcHeightfieldLayer, rcContourSet, rcPolyMesh, rcPolyMeshDetail +/// @{ + +/// Builds a layer set from the specified compact heightfield. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] chf A fully built compact heightfield. +/// @param[in] borderSize The size of the non-navigable border around the heightfield. [Limit: >=0] +/// [Units: vx] +/// @param[in] walkableHeight Minimum floor to 'ceiling' height that will still allow the floor area +/// to be considered walkable. [Limit: >= 3] [Units: vx] +/// @param[out] lset The resulting layer set. (Must be pre-allocated.) +/// @returns True if the operation completed successfully. bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf, const int borderSize, const int walkableHeight, rcHeightfieldLayerSet& lset); -/// Builds simplified contours from the regions outlines. -/// @param chf [in] compact heightfield which has regions set. -/// @param maxError [in] maximum allowed distance between simplified contour and cells. -/// @param maxEdgeLen [in] maximum allowed contour edge length in cells. -/// @param cset [out] Resulting contour set. -/// @param flags [in] build flags, see rcBuildContoursFlags. -/// @returns false if operation ran out of memory. +/// Builds a contour set from the region outlines in the provided compact heightfield. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] chf A fully built compact heightfield. +/// @param[in] maxError The maximum distance a simplfied contour's border edges should deviate +/// the original raw contour. [Limit: >=0] [Units: wu] +/// @param[in] maxEdgeLen The maximum allowed length for contour edges along the border of the mesh. +/// [Limit: >=0] [Units: vx] +/// @param[out] cset The resulting contour set. (Must be pre-allocated.) +/// @param[in] buildFlags The build flags. (See: #rcBuildContoursFlags) +/// @returns True if the operation completed successfully. bool rcBuildContours(rcContext* ctx, rcCompactHeightfield& chf, const float maxError, const int maxEdgeLen, rcContourSet& cset, const int flags = RC_CONTOUR_TESS_WALL_EDGES); -/// Builds connected convex polygon mesh from contour polygons. -/// @param cset [in] contour set. -/// @param nvp [in] maximum number of vertices per polygon. -/// @param mesh [out] poly mesh. -/// @returns false if operation ran out of memory. +/// Builds a polygon mesh from the provided contours. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] cset A fully built contour set. +/// @param[in] nvp The maximum number of vertices allowed for polygons generated during the +/// contour to polygon conversion process. [Limit: >= 3] +/// @param[out] mesh The resulting polygon mesh. (Must be re-allocated.) +/// @returns True if the operation completed successfully. bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, const int nvp, rcPolyMesh& mesh); +/// Merges multiple polygon meshes into a single mesh. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] meshes An array of polygon meshes to merge. [Size: @p nmeshes] +/// @param[in] nmeshes The number of polygon meshes in the meshes array. +/// @param[in] mesh The resulting polygon mesh. (Must be pre-allocated.) +/// @returns True if the operation completed successfully. bool rcMergePolyMeshes(rcContext* ctx, rcPolyMesh** meshes, const int nmeshes, rcPolyMesh& mesh); -/// Builds detail triangle mesh for each polygon in the poly mesh. -/// @param mesh [in] poly mesh to detail. -/// @param chf [in] compact height field, used to query height for new vertices. -/// @param sampleDist [in] spacing between height samples used to generate more detail into mesh. -/// @param sampleMaxError [in] maximum allowed distance between simplified detail mesh and height sample. -/// @param dmesh [out] detail mesh. -/// @returns false if operation ran out of memory. +/// Builds a detail mesh from the provided polygon mesh. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] mesh A fully built polygon mesh. +/// @param[in] chf The compact heightfield used to build the polygon mesh. +/// @param[in] sampleDist Sets the distance to use when samping the heightfield. [Limit: >=0] [Units: wu] +/// @param[in] sampleMaxError The maximum distance the detail mesh surface should deviate from +/// heightfield data. [Limit: >=0] [Units: wu] +/// @param[out] dmesh The resulting detail mesh. (Must be pre-allocated.) +/// @returns True if the operation completed successfully. bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompactHeightfield& chf, const float sampleDist, const float sampleMaxError, rcPolyMeshDetail& dmesh); +/// Merges multiple detail meshes into a single detail mesh. +/// @ingroup recast +/// @param[in,out] ctx The build context to use during the operation. +/// @param[in] meshes An array of detail meshes to merge. [Size: @p nmeshes] +/// @param[in] nmeshes The number of detail meshes in the meshes array. +/// @param[out] mesh The resulting detail mesh. (Must be pre-allocated.) +/// @returns True if the operation completed successfully. bool rcMergePolyMeshDetails(rcContext* ctx, rcPolyMeshDetail** meshes, const int nmeshes, rcPolyMeshDetail& mesh); - +/// @} #endif // RECAST_H @@ -906,4 +1123,4 @@ bool rcMergePolyMeshDetails(rcContext* ctx, rcPolyMeshDetail** meshes, const int // Due to the large amount of detail documentation for this file, // the content normally located at the end of the header file has been separated -// out to a file in the /Docs/Extern directory. +// out to a file in /Docs/Extern. diff --git a/Recast/Include/RecastAlloc.h b/Recast/Include/RecastAlloc.h index f9195bb6c..0038c1a5c 100644 --- a/Recast/Include/RecastAlloc.h +++ b/Recast/Include/RecastAlloc.h @@ -39,7 +39,7 @@ typedef void* (rcAllocFunc)(int size, rcAllocHint hint); // @param[in] ptr typedef void (rcFreeFunc)(void* ptr); -/// Sets the custom allocation functions to be used by Recast. +/// Sets the base custom allocation functions to be used by Recast. /// @param[in] allocFunc The memory allocation function to be used by #rcAlloc /// @param[in] freeFunc The memory de-allocation function to be used by #rcFree void rcAllocSetCustom(rcAllocFunc *allocFunc, rcFreeFunc *freeFunc); diff --git a/Recast/Source/Recast.cpp b/Recast/Source/Recast.cpp index 5ff2b11d2..283cf0c12 100644 --- a/Recast/Source/Recast.cpp +++ b/Recast/Source/Recast.cpp @@ -33,14 +33,13 @@ float rcSqrt(float x) } /// @class rcContext -/// @ingroup recast /// @par /// -/// Logging and timer functionality must be provided by a concrete -/// implementation of this class. This class does not provide either on its -/// own. Also, this class does not provide an interface for extracting log -/// messages. (Only adding them.) So the concrete implementations must -/// provide one. +/// This class does not provide logging or timer functionality on its +/// own. Both must be provided by a concrete implementation +/// by overriding the protected member functions. Also, this class does not +/// provide an interface for extracting log messages. (Only adding them.) +/// So concrete implementations must provide one. /// /// If no logging or timers are required, just pass an instance of this /// class through the Recast build process. @@ -185,7 +184,6 @@ void rcFreePolyMeshDetail(rcPolyMeshDetail* dmesh) rcFree(dmesh); } - void rcCalcBounds(const float* verts, int nv, float* bmin, float* bmax) { // Calculate bounding box. @@ -205,6 +203,11 @@ void rcCalcGridSize(const float* bmin, const float* bmax, float cs, int* w, int* *h = (int)((bmax[2] - bmin[2])/cs+0.5f); } +/// @par +/// +/// See the #rcConfig documentation for more information on the configuration parameters. +/// +/// @see rcAllocHeightfield, rcHeightfield bool rcCreateHeightfield(rcContext* /*ctx*/, rcHeightfield& hf, int width, int height, const float* bmin, const float* bmax, float cs, float ch) @@ -234,6 +237,14 @@ static void calcTriNormal(const float* v0, const float* v1, const float* v2, flo rcVnormalize(norm); } +/// @par +/// +/// Only sets the aread id's for the walkable triangles. Does not alter the +/// area id's for unwalkable triangles. +/// +/// See the #rcConfig documentation for more information on the configuration parameters. +/// +/// @see rcHeightfield, rcClearUnwalkableTriangles, rcRasterizeTriangles void rcMarkWalkableTriangles(rcContext* /*ctx*/, const float walkableSlopeAngle, const float* verts, int /*nv*/, const int* tris, int nt, @@ -256,6 +267,14 @@ void rcMarkWalkableTriangles(rcContext* /*ctx*/, const float walkableSlopeAngle, } } +/// @par +/// +/// Only sets the aread id's for the unwalkable triangles. Does not alter the +/// area id's for walkable triangles. +/// +/// See the #rcConfig documentation for more information on the configuration parameters. +/// +/// @see rcHeightfield, rcClearUnwalkableTriangles, rcRasterizeTriangles void rcClearUnwalkableTriangles(rcContext* /*ctx*/, const float walkableSlopeAngle, const float* verts, int /*nv*/, const int* tris, int nt, @@ -300,6 +319,15 @@ int rcGetHeightFieldSpanCount(rcContext* /*ctx*/, rcHeightfield& hf) return spanCount; } +/// @par +/// +/// This is just the beginning of the process of fully building a compact heightfield. +/// Various filters may be applied applied, then the distance field and regions built. +/// E.g: #rcBuildDistanceField and #rcBuildRegions +/// +/// See the #rcConfig documentation for more information on the configuration parameters. +/// +/// @see rcAllocCompactHeightfield, rcHeightfield, rcCompactHeightfield, rcConfig bool rcBuildCompactHeightfield(rcContext* ctx, const int walkableHeight, const int walkableClimb, rcHeightfield& hf, rcCompactHeightfield& chf) { diff --git a/Recast/Source/RecastArea.cpp b/Recast/Source/RecastArea.cpp index e4c93d56e..a59acc53e 100644 --- a/Recast/Source/RecastArea.cpp +++ b/Recast/Source/RecastArea.cpp @@ -26,7 +26,14 @@ #include "RecastAlloc.h" #include "RecastAssert.h" - +/// @par +/// +/// Basically, any spans that are closer to a boundary or obstruction than the specified radius +/// are marked as unwalkable. +/// +/// This method is usually called immediately after the heightfield has been built. +/// +/// @see rcCompactHeightfield, rcBuildCompactHeightfield, rcConfig::walkableRadius bool rcErodeWalkableArea(rcContext* ctx, int radius, rcCompactHeightfield& chf) { rcAssert(ctx); @@ -225,7 +232,12 @@ static void insertSort(unsigned char* a, const int n) } } - +/// @par +/// +/// This filter is usually applied after applying area id's using functions +/// such as #rcMarkBoxArea, #rcMarkConvexPolyArea, and #rcMarkCylinderArea. +/// +/// @see rcCompactHeightfield bool rcMedianFilterWalkableArea(rcContext* ctx, rcCompactHeightfield& chf) { rcAssert(ctx); @@ -300,6 +312,11 @@ bool rcMedianFilterWalkableArea(rcContext* ctx, rcCompactHeightfield& chf) return true; } +/// @par +/// +/// The value of spacial parameters are in world units. +/// +/// @see rcCompactHeightfield, rcMedianFilterWalkableArea void rcMarkBoxArea(rcContext* ctx, const float* bmin, const float* bmax, unsigned char areaId, rcCompactHeightfield& chf) { @@ -360,6 +377,14 @@ static int pointInPoly(int nvert, const float* verts, const float* p) return c; } +/// @par +/// +/// The value of spacial parameters are in world units. +/// +/// The y-values of the polygon vertices are ignored. So the polygon is effectively +/// projected onto the xz-plane at @p hmin, then extruded to @p hmax. +/// +/// @see rcCompactHeightfield, rcMedianFilterWalkableArea void rcMarkConvexPolyArea(rcContext* ctx, const float* verts, const int nverts, const float hmin, const float hmax, unsigned char areaId, rcCompactHeightfield& chf) @@ -427,6 +452,11 @@ void rcMarkConvexPolyArea(rcContext* ctx, const float* verts, const int nverts, ctx->stopTimer(RC_TIMER_MARK_CONVEXPOLY_AREA); } +/// @par +/// +/// The value of spacial parameters are in world units. +/// +/// @see rcCompactHeightfield, rcMedianFilterWalkableArea void rcMarkCylinderArea(rcContext* ctx, const float* pos, const float r, const float h, unsigned char areaId, rcCompactHeightfield& chf) diff --git a/Recast/Source/RecastContour.cpp b/Recast/Source/RecastContour.cpp index 9386a4b12..078c464e5 100644 --- a/Recast/Source/RecastContour.cpp +++ b/Recast/Source/RecastContour.cpp @@ -592,6 +592,19 @@ static bool mergeContours(rcContour& ca, rcContour& cb, int ia, int ib) return true; } +/// @par +/// +/// The raw contours will match the region outlines exactly. The @p maxError and @p maxEdgeLen +/// parameters control how closely the simplified contours will match the raw contours. +/// +/// Simplified contours are generated such that the vertices for portals between areas match up. +/// (They are considered mandatory vertices.) +/// +/// Setting @p maxEdgeLength to zero will disabled the edge length feature. +/// +/// See the #rcConfig documentation for more information on the configuration parameters. +/// +/// @see rcAllocContourSet, rcCompactHeightfield, rcContourSet, rcConfig bool rcBuildContours(rcContext* ctx, rcCompactHeightfield& chf, const float maxError, const int maxEdgeLen, rcContourSet& cset, const int buildFlags) diff --git a/Recast/Source/RecastFilter.cpp b/Recast/Source/RecastFilter.cpp index 66af37a41..bf985c362 100644 --- a/Recast/Source/RecastFilter.cpp +++ b/Recast/Source/RecastFilter.cpp @@ -22,7 +22,17 @@ #include "Recast.h" #include "RecastAssert.h" - +/// @par +/// +/// Allows the formation of walkable regions that will flow over low lying +/// objects such as curbs, and up structures such as stairways. +/// +/// Two neighboring spans are walkable if: rcAbs(currentSpan.smax - neighborSpan.smax) < waklableClimb +/// +/// @warning Will override the effect of #rcFilterLedgeSpans. So if both filters are used, call +/// #rcFilterLedgeSpans after calling this filter. +/// +/// @see rcHeightfield, rcConfig void rcFilterLowHangingWalkableObstacles(rcContext* ctx, const int walkableClimb, rcHeightfield& solid) { rcAssert(ctx); @@ -60,7 +70,17 @@ void rcFilterLowHangingWalkableObstacles(rcContext* ctx, const int walkableClimb ctx->stopTimer(RC_TIMER_FILTER_LOW_OBSTACLES); } - + +/// @par +/// +/// A ledge is a span with one or more neighbors whose maximum is further away than @p walkableClimb +/// from the current span's maximum. +/// This method removes the impact of the overestimation of conservative voxelization +/// so the resulting mesh will not have regions hanging in the air over ledges. +/// +/// A span is a ledge if: rcAbs(currentSpan.smax - neighborSpan.smax) > walkableClimb +/// +/// @see rcHeightfield, rcConfig void rcFilterLedgeSpans(rcContext* ctx, const int walkableHeight, const int walkableClimb, rcHeightfield& solid) { @@ -151,6 +171,12 @@ void rcFilterLedgeSpans(rcContext* ctx, const int walkableHeight, const int walk ctx->stopTimer(RC_TIMER_FILTER_BORDER); } +/// @par +/// +/// For this filter, the clearance above the span is the distance from the span's +/// maximum to the next higher span's minimum. (Same grid column.) +/// +/// @see rcHeightfield, rcConfig void rcFilterWalkableLowHeightSpans(rcContext* ctx, int walkableHeight, rcHeightfield& solid) { rcAssert(ctx); diff --git a/Recast/Source/RecastLayers.cpp b/Recast/Source/RecastLayers.cpp index 4ed0decd9..617cf45fe 100644 --- a/Recast/Source/RecastLayers.cpp +++ b/Recast/Source/RecastLayers.cpp @@ -76,7 +76,11 @@ struct rcLayerSweepSpan unsigned char nei; // neighbour id }; - +/// @par +/// +/// See the #rcConfig documentation for more information on the configuration parameters. +/// +/// @see rcAllocHeightfieldLayerSet, rcCompactHeightfield, rcHeightfieldLayerSet, rcConfig bool rcBuildHeightfieldLayers(rcContext* ctx, rcCompactHeightfield& chf, const int borderSize, const int walkableHeight, rcHeightfieldLayerSet& lset) diff --git a/Recast/Source/RecastMesh.cpp b/Recast/Source/RecastMesh.cpp index c39d210ea..db8c4c22d 100644 --- a/Recast/Source/RecastMesh.cpp +++ b/Recast/Source/RecastMesh.cpp @@ -895,7 +895,12 @@ static bool removeVertex(rcContext* ctx, rcPolyMesh& mesh, const unsigned short return true; } - +/// @par +/// +/// @note If the mesh data is to be used to construct a Detour navigation mesh, then the upper +/// limit must be retricted to <= #DT_VERTS_PER_POLYGON. +/// +/// @see rcAllocPolyMesh, rcContourSet, rcPolyMesh, rcConfig bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, const int nvp, rcPolyMesh& mesh) { rcAssert(ctx); @@ -1212,6 +1217,7 @@ bool rcBuildPolyMesh(rcContext* ctx, rcContourSet& cset, const int nvp, rcPolyMe return true; } +/// @see rcAllocPolyMesh, rcPolyMesh bool rcMergePolyMeshes(rcContext* ctx, rcPolyMesh** meshes, const int nmeshes, rcPolyMesh& mesh) { rcAssert(ctx); diff --git a/Recast/Source/RecastMeshDetail.cpp b/Recast/Source/RecastMeshDetail.cpp index b14c45a5c..e8c23fb1e 100644 --- a/Recast/Source/RecastMeshDetail.cpp +++ b/Recast/Source/RecastMeshDetail.cpp @@ -941,8 +941,11 @@ static unsigned char getTriFlags(const float* va, const float* vb, const float* return flags; } - - +/// @par +/// +/// See the #rcConfig documentation for more information on the configuration parameters. +/// +/// @see rcAllocPolyMeshDetail, rcPolyMesh, rcCompactHeightfield, rcPolyMeshDetail, rcConfig bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompactHeightfield& chf, const float sampleDist, const float sampleMaxError, rcPolyMeshDetail& dmesh) @@ -1161,6 +1164,7 @@ bool rcBuildPolyMeshDetail(rcContext* ctx, const rcPolyMesh& mesh, const rcCompa return true; } +/// @see rcAllocPolyMeshDetail, rcPolyMeshDetail bool rcMergePolyMeshDetails(rcContext* ctx, rcPolyMeshDetail** meshes, const int nmeshes, rcPolyMeshDetail& mesh) { rcAssert(ctx); diff --git a/Recast/Source/RecastRasterization.cpp b/Recast/Source/RecastRasterization.cpp index 71adfb673..d2bb7c98f 100644 --- a/Recast/Source/RecastRasterization.cpp +++ b/Recast/Source/RecastRasterization.cpp @@ -154,6 +154,13 @@ static void addSpan(rcHeightfield& hf, const int x, const int y, } } +/// @par +/// +/// The span addition can be set to favor flags. If the span is merged to +/// another span and the new @p smax is within @p flagMergeThr units +/// from the existing span, the span flags are merged. +/// +/// @see rcHeightfield, rcSpan. void rcAddSpan(rcContext* /*ctx*/, rcHeightfield& hf, const int x, const int y, const unsigned short smin, const unsigned short smax, const unsigned char area, const int flagMergeThr) @@ -276,6 +283,11 @@ static void rasterizeTri(const float* v0, const float* v1, const float* v2, } } +/// @par +/// +/// No spans will be added if the triangle does not overlap the heightfield grid. +/// +/// @see rcHeightfield void rcRasterizeTriangle(rcContext* ctx, const float* v0, const float* v1, const float* v2, const unsigned char area, rcHeightfield& solid, const int flagMergeThr) @@ -291,6 +303,11 @@ void rcRasterizeTriangle(rcContext* ctx, const float* v0, const float* v1, const ctx->stopTimer(RC_TIMER_RASTERIZE_TRIANGLES); } +/// @par +/// +/// Spans will only be added for triangles that overlap the heightfield grid. +/// +/// @see rcHeightfield void rcRasterizeTriangles(rcContext* ctx, const float* verts, const int /*nv*/, const int* tris, const unsigned char* areas, const int nt, rcHeightfield& solid, const int flagMergeThr) @@ -314,6 +331,11 @@ void rcRasterizeTriangles(rcContext* ctx, const float* verts, const int /*nv*/, ctx->stopTimer(RC_TIMER_RASTERIZE_TRIANGLES); } +/// @par +/// +/// Spans will only be added for triangles that overlap the heightfield grid. +/// +/// @see rcHeightfield void rcRasterizeTriangles(rcContext* ctx, const float* verts, const int /*nv*/, const unsigned short* tris, const unsigned char* areas, const int nt, rcHeightfield& solid, const int flagMergeThr) @@ -337,6 +359,11 @@ void rcRasterizeTriangles(rcContext* ctx, const float* verts, const int /*nv*/, ctx->stopTimer(RC_TIMER_RASTERIZE_TRIANGLES); } +/// @par +/// +/// Spans will only be added for triangles that overlap the heightfield grid. +/// +/// @see rcHeightfield void rcRasterizeTriangles(rcContext* ctx, const float* verts, const unsigned char* areas, const int nt, rcHeightfield& solid, const int flagMergeThr) { diff --git a/Recast/Source/RecastRegion.cpp b/Recast/Source/RecastRegion.cpp index b59e67c65..4290972ed 100644 --- a/Recast/Source/RecastRegion.cpp +++ b/Recast/Source/RecastRegion.cpp @@ -936,7 +936,16 @@ static bool filterSmallRegions(rcContext* ctx, int minRegionArea, int mergeRegio return true; } - +/// @par +/// +/// This is usually the second to the last step in creating a fully built +/// compact heightfield. This step is required before regions are built +/// using #rcBuildRegions or #rcBuildRegionsMonotone. +/// +/// After this step, the distance data is available via the rcCompactHeightfield::maxDistance +/// and rcCompactHeightfield::dist fields. +/// +/// @see rcCompactHeightfield, rcBuildRegions, rcBuildRegionsMonotone bool rcBuildDistanceField(rcContext* ctx, rcCompactHeightfield& chf) { rcAssert(ctx); @@ -1019,6 +1028,25 @@ struct rcSweepSpan unsigned short nei; // neighbour id }; +/// @par +/// +/// Non-null regions will consist of connected, non-overlapping walkable spans that form a single contour. +/// Contours will form simple polygons. +/// +/// If multiple regions form an area that is smaller than @p minRegionArea, then all spans will be +/// re-assigned to the zero (null) region. +/// +/// Partitioning can result in smaller than necessary regions. @p mergeRegionArea helps +/// reduce unecessarily small regions. +/// +/// See the #rcConfig documentation for more information on the configuration parameters. +/// +/// The region data will be available via the rcCompactHeightfield::maxRegions +/// and rcCompactSpan::reg fields. +/// +/// @warning The distance field must be created using #rcBuildDistanceField before attempting to build regions. +/// +/// @see rcCompactHeightfield, rcCompactSpan, rcBuildDistanceField, rcBuildRegionsMonotone, rcConfig bool rcBuildRegionsMonotone(rcContext* ctx, rcCompactHeightfield& chf, const int borderSize, const int minRegionArea, const int mergeRegionArea) { @@ -1171,6 +1199,25 @@ bool rcBuildRegionsMonotone(rcContext* ctx, rcCompactHeightfield& chf, return true; } +/// @par +/// +/// Non-null regions will consist of connected, non-overlapping walkable spans that form a single contour. +/// Contours will form simple polygons. +/// +/// If multiple regions form an area that is smaller than @p minRegionArea, then all spans will be +/// re-assigned to the zero (null) region. +/// +/// Watershed partitioning can result in smaller than necessary regions, especially in diagonal corridors. +/// @p mergeRegionArea helps reduce unecessarily small regions. +/// +/// See the #rcConfig documentation for more information on the configuration parameters. +/// +/// The region data will be available via the rcCompactHeightfield::maxRegions +/// and rcCompactSpan::reg fields. +/// +/// @warning The distance field must be created using #rcBuildDistanceField before attempting to build regions. +/// +/// @see rcCompactHeightfield, rcCompactSpan, rcBuildDistanceField, rcBuildRegionsMonotone, rcConfig bool rcBuildRegions(rcContext* ctx, rcCompactHeightfield& chf, const int borderSize, const int minRegionArea, const int mergeRegionArea) {