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)
{