Recast: Detail API documentation for the elements declared in Recast.h. (Partial)

The elements through rcPolyMesh are complete.
This commit is contained in:
Stephen Pratt 2011-08-22 21:49:21 +00:00
parent 2198f85997
commit 5553d19d59
3 changed files with 753 additions and 118 deletions

427
Docs/Extern/Recast_api.txt vendored Normal file
View File

@ -0,0 +1,427 @@
// This file contains the detail API documentation for
// elements defined in the Recast.h.
/**
@struct rcConfig
@ingroup recast
@par
The is a convenience structure that represents an aggregation of parameters
used at different stages in the Recast build process. Some
values are derived during the build process. Not all parameters
are used for all build processes.
Units are usually in voxels (vx) or world units (wu). The units for voxels,
grid size, and cell size are all based on the values of #cs and #ch.
In this documentation, the term 'field' refers to heightfield and
contour data structures that define spacial information using an integer
grid.
The upper and lower limits for the various parameters often depend on
the platform's floating point accuraccy as well as interdependencies between
the values of multiple parameters. See the individual parameter
documentation for details.
@var rcConfig::borderSize
@par
This value represents the the closest the walkable area of the heightfield
should come to the xz-plane AABB of the field. It does not have any
impact on the borders around internal obstructions.
@var rcConfig::tileSize
@par
This field is only used when building multi-tile meshes.
@var rcConfig::cs
@par
@p cs and #ch define voxel/grid/cell size. So their values have significant
side effects on all parameters defined in voxel units.
The minimum value for this parameter depends on the platform's floating point
accuracy, with the practical minimum usually around 0.05.
@var rcConfig::ch
@par
#cs and @p ch define voxel/grid/cell size. So their values have significant
side effects on all parameters defined in voxel units.
The minimum value for this parameter depends on the platform's floating point
accuracy, with the practical minimum usually around 0.05.
@var rcConfig::walkableSlopeAngle
@par
The practical upper limit for this parameter is usually around 85 degrees.
@var rcConfig::walkableHeight
@par
Permits detection of overhangs in the source geometry that make the geometry
below un-walkable. The value is usually set to the maximum agent height.
@var rcConfig::walkableClimb
@par
Allows the mesh to flow over low lying obstructions such as curbs and
up/down stairways. The value is usually set to how far up/down an agent can step.
@var rcConfig::walkableRadius
@par
In general, this is the closest any part of the final mesh should get to an
obstruction in the source geometry. It is usually set to the maximum
agent radius.
While a value of zero is legal, it is not recommended and can result in
odd edge case issues.
@var rcConfig::maxEdgeLen
@par
Extra vertices will be inserted as needed to keep contour edges below this
length. A value of zero effectively disables this feature.
@var rcConfig::maxSimplificationError
@par
The effect of this parameter only applies to the xz-plane.
@var rcConfig::minRegionArea
@par
Any regions that are smaller than this area will be marked as unwalkable.
This is useful in removing useless regions that can sometimes form on
geometry such as table tops, box tops, etc.
@var rcConfig::maxVertsPerPoly
@par
If the mesh data is to be used to construct a Detour navigation mesh, then the upper limit
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
value of #cs. Spans exist within the grid columns with the span
min/max values at increments of #ch from the base of the grid. The smallest
possible span size is <tt>(#cs width) * (#cs depth) * (#ch height)</tt>. (Which is a single voxel.)
The standard process for buidling a heightfield is to allocate it using
#rcAllocHeightfield, initialize it using #rcCreateHeightfield, then
add spans using the various helper functions such as #rcRasterizeTriangle.
Building a heightfield is one of the first steps in creating a polygon mesh
from source geometry. After it is populated, it is used to build a
rcCompactHeightfield.
Example of iterating the spans in a heightfield:
@code
// Where hf is a reference to an heightfield object.
const float* orig = hf.bmin;
const float cs = hf.cs;
const float ch = hf.ch;
const int w = hf.width;
const int h = hf.height;
for (int y = 0; y < h; ++y)
{
for (int x = 0; x < w; ++x)
{
// Deriving the minimum corner of the grid location.
float fx = orig[0] + x*cs;
float fz = orig[2] + y*cs;
// The base span in the column. (May be null.)
const rcSpan* s = hf.spans[x + y*w];
while (s)
{
// Detriving the minium and maximum world position of the span.
float fymin = orig[1]+s->smin*ch;
float fymax = orig[1] + s->smax*ch;
// Do other things with the span before moving up the column.
s = s->next;
}
}
}
@endcode
@see rcAllocHeightfield, rcFreeHeightField, rcCreateHeightfield
@struct rcCompactCell
@par
See the rcCompactHeightfield documentation for an example of how compact cells
are used to iterate the heightfield.
Useful instances of this type can only by obtained from a #rcCompactHeightfield object.
@see rcCompactHeightfield
@struct rcCompactSpan
@par
The span represents open, unobstructed space within a compact heightfield column.
See the rcCompactHeightfield documentation for an example of iterating spans and searching
span connections.
Useful instances of this type can only by obtained from a #rcCompactHeightfield object.
@see rcCompactHeightfield
@struct rcCompactHeightfield
@ingroup recast
@par
For this type of heightfield, the spans represent the open (unobstructed)
space above the solid surfaces of a voxel field. It is usually created from
a #rcHeightfield object. Data is stored in a compact, efficient manner,
but the structure is not condusive to adding and removing spans.
The standard process for buidling a compact heightfield is to allocate it
using #rcAllocCompactHeightfield, build it using #rcBuildCompactHeightfield,
then run it through the various helper functions to generate neighbor
and region data.
Connected neighbor spans form non-overlapping surfaces. When neighbor
information is generated, spans will include data that can be used to
locate axis-neighbors. Axis-neighbors are connected
spans that are offset from the current cell column as follows:
<pre>
Direction 0 = (-1, 0)
Direction 1 = (0, 1)
Direction 2 = (1, 0)
Direction 3 = (0, -1)
</pre>
Example of iterating and inspecting spans, including connected neighbors:
@code
// Where chf is an instance of a rcCompactHeightfield.
const float cs = chf.cs;
const float ch = chf.ch;
for (int y = 0; y < chf.height; ++y)
{
for (int x = 0; x < chf.width; ++x)
{
// Deriving the minimum corner of the grid location.
const float fx = chf.bmin[0] + x*cs;
const float fz = chf.bmin[2] + y*cs;
// Get the cell for the grid location then iterate
// up the column.
const rcCompactCell& c = chf.cells[x+y*chf.width];
for (unsigned i = c.index, ni = c.index+c.count; i < ni; ++i)
{
const rcCompactSpan& s = chf.spans[i];
Deriving the minimum (floor) of the span.
const float fy = chf.bmin[1] + (s.y+1)*ch;
// Testing the area assignment of the span.
if (chf.areas[i] == RC_WALKABLE_AREA)
{
// The span is in the default 'walkable area'.
}
else if (chf.areas[i] == RC_NULL_AREA)
{
// The surface is not considered walkable.
// E.g. It was filtered out during the build processes.
}
else
{
// Do something. (Only applicable for custom build
// build processes.)
}
// Iterating the connected axis-neighbor spans.
for (int dir = 0; dir < 4; ++dir)
{
if (rcGetCon(s, dir) != RC_NOT_CONNECTED)
{
// There is a neighbor in this direction.
const int nx = x + rcGetDirOffsetX(dir);
const int ny = y + rcGetDirOffsetY(dir);
const int ni = (int)chf.cells[nx+ny*w].index + rcGetCon(s, 0);
const rcCompactSpan& ns = chf.spans[ni];
// Do something with the neighbor span.
}
}
}
}
}
@endcode
@see rcAllocCompactHeightfield, rcFreeCompactHeightfield, rcBuildCompactHeightfield
@struct rcContour
@ingroup recast
@par
A contour only exists within the context of a #rcContourSet object.
While the height of the contour's border may vary, the contour will always
form a simple polygon when projected onto the xz-plane.
Example of converting vertices into world space:
@code
// Where cset is the rcContourSet object to which the contour belongs.
float worldX = cset.bmin[0] + vertX * cset.cs;
float worldY = cset.bmin[1] + vertY * cset.ch;
float worldZ = cset.bmin[2] + vertZ * cset.cs;
@endcode
@see rcContourSet
@var rcContour::verts
@par
The simplified contour is a version of the raw contour with all
'unnecessary' vertices removed. Whether a vertex is
considered unnecessary depends on the contour build process.
The data format is as follows: (x, y, z, r) * #nverts
A contour edge is formed by the current and next vertex. The r-value
represents region and connection information for the edge. For example:
@code
int r = verts[i*4+3];
int regionId = r & RC_CONTOUR_REG_MASK;
if (r & RC_BORDER_VERTEX)
{
// The edge represents a solid border.
}
if (r & RC_AREA_BORDER)
{
// The edge represents a transition between different areas.
}
@endcode
@var rcContour::rverts
@par
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.
@see rcAllocContourSet, rcFreeContourSet, rcBuildContours
@struct rcPolyMesh
@ingroup recast
@par
A mesh of potentially overlapping convex polygons of between three
and #nvp vertices. The mesh exists within the context of an axis-aligned
bounding box (AABB) with vertices laid out in an evenly spaced grid, based
on the values of #cs and #ch.
The standard process for building a contour set is to allocate it using
#rcAllocPolyMesh, the initialize it using #rcBuildPolyMesh
Example of iterating the polygons:
@code
// Where mesh is a reference to a rcPolyMesh object.
const int nvp = mesh.nvp;
const float cs = mesh.cs;
const float ch = mesh.ch;
const float* orig = mesh.bmin;
for (int i = 0; i < mesh.npolys; ++i)
{
const unsigned short* p = &mesh.polys[i*nvp*2];
// Iterate the vertices.
unsigned short vi[3]; // The vertex indices.
for (int j = 0; j < nvp; ++j)
{
if (p[j] == RC_MESH_NULL_IDX)
break; // End of vertices.
if (p[j + nvp] == RC_MESH_NULL_IDX)
{
// The edge beginning with this vertex is a solid border.
}
else
{
// The edge beginning with this vertex connects to
// polygon p[j + nvp].
}
// Convert to world space.
const unsigned short* v = &mesh.verts[p[j]*3];
const float x = orig[0] + v[0]*cs;
const float y = orig[1] + v[1]*ch;
const float z = orig[2] + v[2]*cs;
// Do something with the vertices.
}
}
@endcode
@see rcAllocPolyMesh, rcFreePolyMesh, rcBuildPolyMesh
@var rcPolyMesh::verts
@par
The values of #bmin ,#cs, and #ch are used to convert vertex coordinates
to world space as follows:
@code
float worldX = bmin[0] + verts[i*3+0] * cs
float worldY = bmin[1] + verts[i*3+1] * ch
float worldZ = bmin[2] + verts[i*3+2] * cs
@endcode
@var rcPolyMesh::polys
@par
Each entry is <tt>2 * #nvp</tt> in length. The first half of the entry
contains the indices of the polygon. The first instance of #RC_MESH_NULL_IDX
indicates the end of the indices for the entry. The second half contains
indices to neighbor polygons. A value of #RC_MESH_NULL_IDX indicates no
connection for the associated edge. (I.e. The edge is a solid border.)
For example:
<pre>
nvp = 6
For the entry: (1, 3, 4, 8, RC_MESH_NULL_IDX, RC_MESH_NULL_IDX,
18, RC_MESH_NULL_IDX , 21, RC_MESH_NULL_IDX, RC_MESH_NULL_IDX, RC_MESH_NULL_IDX)
(1, 3, 4, 8) defines a polygon with 4 vertices.
Edge 1->3 is shared with polygon 18.
Edge 4->8 is shared with polygon 21.
Edges 3->4 and 4->8 are border edges not shared with any other polygon.
</pre>
@var rcPolyMesh::areas
@par
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.
*/

View File

@ -19,264 +19,446 @@
#ifndef RECAST_H #ifndef RECAST_H
#define RECAST_H #define RECAST_H
// Some math headers don't have PI defined. /**
* @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; static const float RC_PI = 3.14159265f;
/// Recast log categories.
/// @ingroup recast
/// @see rcContext
enum rcLogCategory enum rcLogCategory
{ {
RC_LOG_PROGRESS = 1, RC_LOG_PROGRESS = 1, ///< A progress log entry.
RC_LOG_WARNING, RC_LOG_WARNING, ///< A warning log entry.
RC_LOG_ERROR, RC_LOG_ERROR, ///< An error log entry.
}; };
/// Recast performance timer categories.
/// @ingroup recast
/// @see rcContext
enum rcTimerLabel enum rcTimerLabel
{ {
/// The user defined total time of the build.
RC_TIMER_TOTAL, RC_TIMER_TOTAL,
/// A user defined build time.
RC_TIMER_TEMP, RC_TIMER_TEMP,
/// The time to rasterize the triangles. (See: #rcRasterizeTriangle)
RC_TIMER_RASTERIZE_TRIANGLES, RC_TIMER_RASTERIZE_TRIANGLES,
/// The time to build the compact heightfield. (See: #rcBuildCompactHeightfield)
RC_TIMER_BUILD_COMPACTHEIGHTFIELD, RC_TIMER_BUILD_COMPACTHEIGHTFIELD,
/// The total time to build the contours. (See: #rcBuildContours)
RC_TIMER_BUILD_CONTOURS, RC_TIMER_BUILD_CONTOURS,
/// The time to trace the boundaries of the contours. (See: #rcBuildContours)
RC_TIMER_BUILD_CONTOURS_TRACE, RC_TIMER_BUILD_CONTOURS_TRACE,
/// The time to simplify the contours. (See: #rcBuildContours)
RC_TIMER_BUILD_CONTOURS_SIMPLIFY, RC_TIMER_BUILD_CONTOURS_SIMPLIFY,
/// The time to filter ledge spans. (See: #rcFilterLedgeSpans)
RC_TIMER_FILTER_BORDER, RC_TIMER_FILTER_BORDER,
/// The time to filter low height spans. (See: #rcFilterWalkableLowHeightSpans)
RC_TIMER_FILTER_WALKABLE, RC_TIMER_FILTER_WALKABLE,
/// The time to apply the median filter. (See: #rcMedianFilterWalkableArea)
RC_TIMER_MEDIAN_AREA, RC_TIMER_MEDIAN_AREA,
/// The time to filter low obstacles. (See: #rcFilterLowHangingWalkableObstacles)
RC_TIMER_FILTER_LOW_OBSTACLES, RC_TIMER_FILTER_LOW_OBSTACLES,
/// The time to build the polygon mesh. (See: #rcBuildPolyMesh)
RC_TIMER_BUILD_POLYMESH, RC_TIMER_BUILD_POLYMESH,
/// The time to merge polygon meshes. (See: #rcMergePolyMeshes)
RC_TIMER_MERGE_POLYMESH, RC_TIMER_MERGE_POLYMESH,
/// The time to erode the walkable area. (See: #rcErodeWalkableArea)
RC_TIMER_ERODE_AREA, RC_TIMER_ERODE_AREA,
/// The time to mark a box area. (See: #rcMarkBoxArea)
RC_TIMER_MARK_BOX_AREA, RC_TIMER_MARK_BOX_AREA,
/// The time to mark a cylinder area. (See: #rcMarkCylinderArea)
RC_TIMER_MARK_CYLINDER_AREA, RC_TIMER_MARK_CYLINDER_AREA,
/// The time to mark a convex polygon area. (See: #rcMarkConvexPolyArea)
RC_TIMER_MARK_CONVEXPOLY_AREA, RC_TIMER_MARK_CONVEXPOLY_AREA,
/// The total time to build the distance field. (See: #rcBuildDistanceField)
RC_TIMER_BUILD_DISTANCEFIELD, RC_TIMER_BUILD_DISTANCEFIELD,
/// The time to build the distances of the distance field. (See: #rcBuildDistanceField)
RC_TIMER_BUILD_DISTANCEFIELD_DIST, RC_TIMER_BUILD_DISTANCEFIELD_DIST,
/// The time to blur the distance field. (See: #rcBuildDistanceField)
RC_TIMER_BUILD_DISTANCEFIELD_BLUR, RC_TIMER_BUILD_DISTANCEFIELD_BLUR,
/// The total time to build the regions. (See: #rcBuildRegions, #rcBuildRegionsMonotone)
RC_TIMER_BUILD_REGIONS, RC_TIMER_BUILD_REGIONS,
/// The total time to apply the watershed algorithm. (See: #rcBuildRegions)
RC_TIMER_BUILD_REGIONS_WATERSHED, RC_TIMER_BUILD_REGIONS_WATERSHED,
/// The time to expand regions while applying the watershed algorithm. (See: #rcBuildRegions)
RC_TIMER_BUILD_REGIONS_EXPAND, RC_TIMER_BUILD_REGIONS_EXPAND,
/// The time to flood regions while applying the watershed algorithm. (See: #rcBuildRegions)
RC_TIMER_BUILD_REGIONS_FLOOD, RC_TIMER_BUILD_REGIONS_FLOOD,
/// The time to filter out small regions. (See: #rcBuildRegions, #rcBuildRegionsMonotone)
RC_TIMER_BUILD_REGIONS_FILTER, RC_TIMER_BUILD_REGIONS_FILTER,
/// The time to build heightfield layers. (See: #rcBuildHeightfieldLayers)
RC_TIMER_BUILD_LAYERS, RC_TIMER_BUILD_LAYERS,
/// The time to build the polygon mesh detail. (See: #rcBuildPolyMeshDetail)
RC_TIMER_BUILD_POLYMESHDETAIL, RC_TIMER_BUILD_POLYMESHDETAIL,
/// The time to merge polygon mesh details. (See: #rcMergePolyMeshDetails)
RC_TIMER_MERGE_POLYMESHDETAIL, RC_TIMER_MERGE_POLYMESHDETAIL,
/// The maximum number of timers. (Used for iterating timers.)
RC_MAX_TIMERS RC_MAX_TIMERS
}; };
/// Build context provides several optional utilities needed for the build process, /// Provides an interface for optional logging and performance tracking of the Recast
/// such as timing, logging, and build time collecting. /// build process.
class rcContext class rcContext
{ {
public: public:
/// Contructor.
/// @param[in] state TRUE if the logging and performance timers should be enabled. [Default: true]
inline rcContext(bool state = true) : m_logEnabled(state), m_timerEnabled(state) {} inline rcContext(bool state = true) : m_logEnabled(state), m_timerEnabled(state) {}
virtual ~rcContext() {} virtual ~rcContext() {}
/// Enables or disables logging. /// Enables or disables logging.
/// @param[in] state TRUE if logging should be enabled.
inline void enableLog(bool state) { m_logEnabled = state; } inline void enableLog(bool state) { m_logEnabled = state; }
/// Resets log.
/// Clears all log entries.
inline void resetLog() { if (m_logEnabled) doResetLog(); } inline void resetLog() { if (m_logEnabled) doResetLog(); }
/// Logs a message. /// Logs a message.
/// @param[in] category The category of the message.
/// @param[in] format The message.
void log(const rcLogCategory category, const char* format, ...); void log(const rcLogCategory category, const char* format, ...);
/// Enables or disables timer. /// Enables or disables the performance timers.
/// @param[in] state TRUE if timers should be enabled.
inline void enableTimer(bool state) { m_timerEnabled = state; } inline void enableTimer(bool state) { m_timerEnabled = state; }
/// Resets all timers.
/// Clears all peformance timers. (Resets all to unused.)
inline void resetTimers() { if (m_timerEnabled) doResetTimers(); } inline void resetTimers() { if (m_timerEnabled) doResetTimers(); }
/// Starts timer, used for performance timing.
/// Starts the specified performance timer.
/// @param label The category of timer.
inline void startTimer(const rcTimerLabel label) { if (m_timerEnabled) doStartTimer(label); } inline void startTimer(const rcTimerLabel label) { if (m_timerEnabled) doStartTimer(label); }
/// Stops timer, used for performance timing.
/// Stops the specified performance timer.
/// @param label The category of the timer.
inline void stopTimer(const rcTimerLabel label) { if (m_timerEnabled) doStopTimer(label); } inline void stopTimer(const rcTimerLabel label) { if (m_timerEnabled) doStopTimer(label); }
/// Returns time accumulated between timer start/stop.
/// Returns the total accumulated time of the specified performance timer.
/// @param 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.
inline int getAccumulatedTime(const rcTimerLabel label) const { return m_timerEnabled ? doGetAccumulatedTime(label) : -1; } inline int getAccumulatedTime(const rcTimerLabel label) const { return m_timerEnabled ? doGetAccumulatedTime(label) : -1; }
protected: protected:
/// @name Virtual functions to override for custom implementations. /// @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() {} virtual void doResetLog() {}
/// Logs a message.
/// @param[in] category The category of the message.
/// @param[in] msg The formatted message.
/// @param[in] len The length of the formatted message.
virtual void doLog(const rcLogCategory /*category*/, const char* /*msg*/, const int /*len*/) {} virtual void doLog(const rcLogCategory /*category*/, const char* /*msg*/, const int /*len*/) {}
/// Clears all timers. (Resets all to unused.)
virtual void doResetTimers() {} virtual void doResetTimers() {}
/// Starts the specified performance timer.
/// @param[in] label The category of timer.
virtual void doStartTimer(const rcTimerLabel /*label*/) {} virtual void doStartTimer(const rcTimerLabel /*label*/) {}
/// Stops the specified performance timer.
/// @param[in] label The category of the timer.
virtual void doStopTimer(const rcTimerLabel /*label*/) {} virtual void doStopTimer(const rcTimerLabel /*label*/) {}
/// Returns the total accumulated time of the specified performance timer.
/// @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; } virtual int doGetAccumulatedTime(const rcTimerLabel /*label*/) const { return -1; }
///@} ///@}
/// True if logging is enabled.
bool m_logEnabled; bool m_logEnabled;
/// True if the performance timers are enabled.
bool m_timerEnabled; bool m_timerEnabled;
}; };
/// Specifies a configuration to use when performing Recast builds.
/// The units of the parameters are specified in parenthesis as follows:
/// (vx) voxels, (wu) world units
struct rcConfig struct rcConfig
{ {
int width, height; ///< Dimensions of the rasterized heightfield (vx) /// The width of the field along the x-axis. [Limit: >= 0] [Units: vx]
int tileSize; ///< Width and Height of a tile (vx) int width;
int borderSize; ///< Non-navigable Border around the heightfield (vx)
float cs, ch; ///< Grid cell size and height (wu) /// The height of the field along the z-axis. [Limit: >= 0] [Units: vx]
float bmin[3], bmax[3]; ///< Grid bounds (wu) int height;
float walkableSlopeAngle; ///< Maximum walkable slope angle in degrees.
int walkableHeight; ///< Minimum height where the agent can still walk (vx) /// The width/height size of tile's on the xz-plane. [Limit: >= 0] [Units: vx]
int walkableClimb; ///< Maximum height between grid cells the agent can climb (vx) int tileSize;
int walkableRadius; ///< Radius of the agent in cells (vx)
int maxEdgeLen; ///< Maximum contour edge length (vx) /// The size of the non-navigable border around the heightfield. [Limit: >=0] [Units: vx]
float maxSimplificationError; ///< Maximum distance error from contour to cells (vx) int borderSize;
int minRegionArea; ///< Regions whose area is smaller than this threshold will be removed. (vx)
int mergeRegionArea; ///< Regions whose area is smaller than this threshold will be merged (vx) /// The xz-plane cell size to use for fields. [Limit: > 0] [Units: wu]
int maxVertsPerPoly; ///< Max number of vertices per polygon float cs;
float detailSampleDist; ///< Detail mesh sample spacing.
float detailSampleMaxError; ///< Detail mesh simplification max sample error. /// The y-axis cell size to use for fields. [Limit: > 0] [Units: wu]
float ch;
/// The minimum bounds of the field's AABB. [(x, y, z)] [Units: wu]
float bmin[3];
/// The maximum bounds of the field's AABB. [(x, y, z)] [Units: wu]
float bmax[3];
/// The maximum slope that is considered walkable. [Limits: 0 <= value < 90] [Units: Degrees]
float walkableSlopeAngle;
/// Minimum floor to 'ceiling' height that will still allow the floor area to
/// be considered walkable. [Limit: >= 3] [Units: vx]
int walkableHeight;
/// Maximum ledge height that is considered to still be traversable. [Limit: >=0] [Units: vx]
int walkableClimb;
/// The distance to erode/shrink the walkable area of the heightfield away from
/// obstructions. [Limit: >=0] [Units: vx]
int walkableRadius;
/// The maximum allowed length for contour edges along the border of the mesh. [Limit: >=0] [Units: vx]
int maxEdgeLen;
/// The maximum distance a simplfied contour's border edges should deviate
/// 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]
int minRegionArea;
/// Any regions with a cell count smaller than this value will, if possible,
/// be merged with larger regions. [Limit: >=0] [Units: vx]
int mergeRegionArea;
/// The maximum number of vertices allowed for polygons generated during the
/// contour to polygon conversion process. [Limit: >= 3]
int maxVertsPerPoly;
/// Sets the sampling distance to use when generating the detail mesh.
/// (For height detail only.) [Limits: 0 or >= 0.9] [Units: wu]
float detailSampleDist;
/// The maximum distance the detail mesh surface should deviate from heightfield
/// data. (For height detail only.) [Limit: >=0] [Units: wu]
float detailSampleMaxError;
}; };
/// Define number of bits in the above structure for smin/smax. /// Defines number of bits in rcSpan::smin and rcSpan::smax.
static const int RC_SPAN_HEIGHT_BITS = 13; static const int RC_SPAN_HEIGHT_BITS = 13;
/// The max height is used for clamping rasterized values. /// Defines the maximum value for rcSpan::smin and rcSpan::smax.
static const int RC_SPAN_MAX_HEIGHT = (1<<RC_SPAN_HEIGHT_BITS)-1; static const int RC_SPAN_MAX_HEIGHT = (1<<RC_SPAN_HEIGHT_BITS)-1;
/// Heightfield span. /// Represents a span in a heightfield.
/// @see rcHeightfield
struct rcSpan struct rcSpan
{ {
unsigned int smin : 13; ///< Span min height. unsigned int smin : 13; ///< The mimum height of the span.
unsigned int smax : 13; ///< Span max height. unsigned int smax : 13; ///< The maximum height of the span.
unsigned int area : 6; ///< Span area type. unsigned int area : 6; ///< The area id assigned to the span.
rcSpan* next; ///< Next span in column. rcSpan* next; ///< The next span higher up in column.
}; };
/// Number of spans allocated per pool. /// The number of spans allocated per span spool.
/// @see rcSpanPool
static const int RC_SPANS_PER_POOL = 2048; static const int RC_SPANS_PER_POOL = 2048;
/// Memory pool used for quick span allocation. /// A memory pool used for quick allocation of spans within a heightfield.
/// @see rcHeightfield
struct rcSpanPool struct rcSpanPool
{ {
rcSpanPool* next; ///< Pointer to next pool. rcSpanPool* next; ///< The next span pool.
rcSpan items[RC_SPANS_PER_POOL]; ///< Array of spans. rcSpan items[RC_SPANS_PER_POOL]; ///< Array of spans in the pool.
}; };
/// Dynamic span-heightfield. /// A dynamic heightfield representing obstructed space.
struct rcHeightfield struct rcHeightfield
{ {
int width, height; ///< Dimension of the heightfield. int width; ///< The width of the heightfield. (Along the x-axis in cell units.)
float bmin[3], bmax[3]; ///< Bounding box of the heightfield int height; ///< The height of the heightfield. (Along the z-axis in cell units.)
float cs, ch; ///< Cell size and height. float bmin[3]; ///< The minimum bounds in world space. [(x, y, z)]
rcSpan** spans; ///< Heightfield of spans (width*height). float bmax[3]; ///< The maximum bounds in world space. [(x, y, z)]
rcSpanPool* pools; ///< Linked list of span pools. float cs; ///< The size of each cell. (On the xz-plane.)
rcSpan* freelist; ///< Pointer to next free span. float ch; ///< The height of each cell. (The minimum increment along the y-axis.)
rcSpan** spans; ///< Heightfield of spans (width*height).
rcSpanPool* pools; ///< Linked list of span pools.
rcSpan* freelist; ///< The next free span.
}; };
/// Allocates a heightfield object using the Recast allocator.
/// @return A heightfield that is ready for initialization, or null on failure.
/// @ingroup recast
rcHeightfield* rcAllocHeightfield(); rcHeightfield* rcAllocHeightfield();
/// Frees the specified heightfield object using the Recast allocator.
/// @param[in] hf A heightfield allocated using #rcAllocHeightfield
/// @ingroup recast
void rcFreeHeightField(rcHeightfield* hf); void rcFreeHeightField(rcHeightfield* hf);
/// Provides information on the content of a cell column in a compact heightfield.
struct rcCompactCell struct rcCompactCell
{ {
unsigned int index : 24; ///< Index to first span in column. unsigned int index : 24; ///< Index to the first span in the column.
unsigned int count : 8; ///< Number of spans in this column. unsigned int count : 8; ///< Number of spans in the column.
}; };
/// Represents a span of unobstructed space within a compact heightfield.
struct rcCompactSpan struct rcCompactSpan
{ {
unsigned short y; ///< Bottom coordinate of the span. unsigned short y; ///< The lower extent of the span. (Measured from the heightfield's base.)
unsigned short reg; unsigned short reg; ///< The id of the region the span belongs to. (Or zero if not in a region.)
unsigned int con : 24; ///< Connections to neighbour cells. unsigned int con : 24; ///< Packed neighbor connection data.
unsigned int h : 8; ///< Height of the span. unsigned int h : 8; ///< The height of the span. (Measured from #y.)
}; };
/// Compact static heightfield. /// A compact, static heightfield representing unobstructed space.
struct rcCompactHeightfield struct rcCompactHeightfield
{ {
int width, height; ///< Width and height of the heightfield. int width; ///< The width of the heightfield. (Along the x-axis in cell units.)
int spanCount; ///< Number of spans in the heightfield. int height; ///< The height of the heightfield. (Along the z-axis in cell units.)
int walkableHeight, walkableClimb; ///< Agent properties. int spanCount; ///< The number of spans in the heightfield.
int borderSize; ///< Border size of the heighfield. int walkableHeight; ///< The walkable height used during the build of the field. (See: rcConfig::walkableHeight)
unsigned short maxDistance; ///< Maximum distance value stored in heightfield. int walkableClimb; ///< The walkable climb used during the build of the field. (See: rcConfig::walkableClimb)
unsigned short maxRegions; ///< Maximum Region Id stored in heightfield. int borderSize; ///< The AABB border size used during the build of the field. (See: rcConfig::borderSize)
float bmin[3], bmax[3]; ///< Bounding box of the heightfield. unsigned short maxDistance; ///< The maximum distance value of any span within the field.
float cs, ch; ///< Cell size and height. unsigned short maxRegions; ///< The maximum region id of any span within the field.
rcCompactCell* cells; ///< Pointer to width*height cells. float bmin[3]; ///< The minimum bounds in world space. [(x, y, z)]
rcCompactSpan* spans; ///< Pointer to spans. float bmax[3]; ///< The maximum bounds in world space. [(x, y, z)]
unsigned short* dist; ///< Pointer to per span distance to border. float cs; ///< The size of each cell. (On the xz-plane.)
unsigned char* areas; ///< Pointer to per span area ID. float ch; ///< The height of each cell. (The minimum increment along the y-axis.)
rcCompactCell* cells; ///< Array of cells. [Size: #width*#height]
rcCompactSpan* spans; ///< Array of spans. [Size: #spanCount]
unsigned short* dist; ///< Array containing border distance data. [Size: #spanCount]
unsigned char* areas; ///< Array containing area id data. [Size: #spanCount]
}; };
/// Allocates a compact heightfield object using the Recast allocator.
/// @return A compact heightfield that is ready for initialization, or null on failure.
/// @ingroup recast
rcCompactHeightfield* rcAllocCompactHeightfield(); rcCompactHeightfield* rcAllocCompactHeightfield();
/// Frees the specified compact heightfield object using the Recast allocator.
/// @param[in] chf A compact heightfield allocated using #rcAllocCompactHeightfield
/// @ingroup recast
void rcFreeCompactHeightfield(rcCompactHeightfield* chf); void rcFreeCompactHeightfield(rcCompactHeightfield* chf);
/// Represents a heightfield layer within a layer set.
/// @ingroup recast
/// @see rcHeightfieldLayerSet
struct rcHeightfieldLayer struct rcHeightfieldLayer
{ {
float bmin[3], bmax[3]; ///< Bounding box of the heightfield. float bmin[3]; ///< The minimum bounds in world space. [(x, y, z)]
float cs, ch; ///< Cell size and height. float bmax[3]; ///< The maximum bounds in world space. [(x, y, z)]
int width, height; ///< Width and height of the layer. float cs; ///< The size of each cell. (On the xz-plane.)
int minx,maxx,miny,maxy; ///< Bounding box of usable data. float ch; ///< The height of each cell. (The minimum increment along the y-axis.)
int hmin, hmax; ///< Height min/max int width; ///< The width of the heightfield. (Along the x-axis in cell units.)
unsigned char* heights; ///< Heighfield. int height; ///< The height of the heightfield. (Along the z-axis in cell units.)
unsigned char* areas; ///< Area types. int minx; ///< The minimum x-bounds of usable data.
unsigned char* cons; ///< Connections. int maxx; ///< The maximum x-bounds of usable data.
int miny; ///< The minimum y-bounds of usable data. (Along the z-axis.)
int maxy; ///< The maximum y-bounds of usable data. (Along the z-axis.)
int hmin; ///< The minimum height bounds of usable data. (Along the y-axis.)
int hmax; ///< The maximum height bounds of usable data. (Along the y-axis.)
unsigned char* heights; ///< The heightfield. [Size: (width - borderSize*2) * (h - borderSize*2)]
unsigned char* areas; ///< Area ids. [Size: Same as #heights]
unsigned char* cons; ///< Packed neighbor connection information. [Size: Same as #heights]
}; };
/// Represents a set of heightfield layers.
/// @ingroup recast
/// @see rcAllocHeightfieldLayerSet, rcFreeHeightfieldLayerSet
struct rcHeightfieldLayerSet struct rcHeightfieldLayerSet
{ {
rcHeightfieldLayer* layers; ///< Pointer to layers. rcHeightfieldLayer* layers; ///< The layers in the set. [Size: #nlayers]
int nlayers; ///< Number of layers. int nlayers; ///< The number of layers in the set.
}; };
/// Allocates a heightfield layer set using the Recast allocator.
/// @return A heightfield layer set that is ready for initialization, or null on failure.
/// @ingroup recast
rcHeightfieldLayerSet* rcAllocHeightfieldLayerSet(); rcHeightfieldLayerSet* rcAllocHeightfieldLayerSet();
/// Frees the specified heightfield layer set using the Recast allocator.
/// @param[in] lset A heightfield layer set allocated using #rcAllocHeightfieldLayerSet
/// @ingroup recast
void rcFreeHeightfieldLayerSet(rcHeightfieldLayerSet* lset); void rcFreeHeightfieldLayerSet(rcHeightfieldLayerSet* lset);
/// Represents a simple, non-overlapping contour in field space.
struct rcContour struct rcContour
{ {
int* verts; ///< Vertex coordinates, each vertex contains 4 components. int* verts; ///< Simplified contour vertex and connection data. [Size: 4 * #nverts]
int nverts; ///< Number of vertices. int nverts; ///< The number of vertices in the simplified contour.
int* rverts; ///< Raw vertex coordinates, each vertex contains 4 components. int* rverts; ///< Raw contour vertex and connection data. [Size: 4 * #nrverts]
int nrverts; ///< Number of raw vertices. int nrverts; ///< The number of vertices in the raw contour.
unsigned short reg; ///< Region ID of the contour. unsigned short reg; ///< The region id of the contour.
unsigned char area; ///< Area ID of the contour. unsigned char area; ///< The area id of the contour.
}; };
/// Represents a group of related contours.
struct rcContourSet struct rcContourSet
{ {
rcContour* conts; ///< Pointer to all contours. rcContour* conts; ///< An array of the contours in the set. [Size: #nconts]
int nconts; ///< Number of contours. int nconts; ///< The number of contours in the set.
float bmin[3], bmax[3]; ///< Bounding box of the heightfield. float bmin[3]; ///< The minimum bounds in world space. [(x, y, z)]
float cs, ch; ///< Cell size and height. float bmax[3]; ///< The maximum bounds in world space. [(x, y, z)]
int width, height; ///< Region where the contours were build. float cs; ///< The size of each cell. (On the xz-plane.)
int borderSize; ///< Border size of the heighfield where the contours were build from. float ch; ///< The height of each cell. (The minimum increment along the y-axis.)
int width; ///< The width of the set. (Along the x-axis in cell units.)
int height; ///< The height of the set. (Along the z-axis in cell units.)
int borderSize; ///< The AABB border size used to generate the source data from which the contours were derived.
}; };
/// Allocates a contour set object using the Recast allocator.
/// @return A contour set that is ready for initialization, or null on failure.
/// @ingroup recast
rcContourSet* rcAllocContourSet(); rcContourSet* rcAllocContourSet();
/// Frees the specified contour set using the Recast allocator.
/// @param[in] cset A contour set allocated using #rcAllocContourSet
/// @ingroup recast
void rcFreeContourSet(rcContourSet* cset); void rcFreeContourSet(rcContourSet* cset);
/// Polymesh store a connected mesh of polygons. /// Represents a polygon mesh suitable for use in building a navigation mesh.
/// The polygons are store in an array where each polygons takes
/// 'nvp*2' elements. The first 'nvp' elements are indices to vertices
/// and the second 'nvp' elements are indices to neighbour polygons.
/// If a polygon has less than 'bvp' vertices, the remaining indices
/// are set to RC_MESH_NULL_IDX. If an polygon edge does not have a neighbour
/// the neighbour index is set to RC_MESH_NULL_IDX.
/// Vertices can be transformed into world space as follows:
/// x = bmin[0] + verts[i*3+0]*cs;
/// y = bmin[1] + verts[i*3+1]*ch;
/// z = bmin[2] + verts[i*3+2]*cs;
struct rcPolyMesh struct rcPolyMesh
{ {
unsigned short* verts; ///< Vertices of the mesh, 3 elements per vertex. unsigned short* verts; ///< The mesh vertices. [Form: (x, y, z) * #nverts]
unsigned short* polys; ///< Polygons of the mesh, nvp*2 elements per polygon. unsigned short* polys; ///< Polygon and neighbor data. [Length: #maxpolys * 2 * #nvp]
unsigned short* regs; ///< Region ID of the polygons. unsigned short* regs; ///< The region id assigned to each polygon. [Length: #maxpolys]
unsigned short* flags; ///< Per polygon flags. unsigned short* flags; ///< The user defined flags for each polygon. [Length: #maxpolys]
unsigned char* areas; ///< Area ID of polygons. unsigned char* areas; ///< The area id assigned to each polygon. [Length: #maxpolys]
int nverts; ///< Number of vertices. int nverts; ///< The number of vertices.
int npolys; ///< Number of polygons. int npolys; ///< The number of polygons.
int maxpolys; ///< Number of allocated polygons. int maxpolys; ///< The number of allocated polygons.
int nvp; ///< Max number of vertices per polygon. int nvp; ///< The maximum number of vertices per polygon.
float bmin[3], bmax[3]; ///< Bounding box of the mesh. float bmin[3]; ///< The minimum bounds in world space. [(x, y, z)]
float cs, ch; ///< Cell size and height. float bmax[3]; ///< The maximum bounds in world space. [(x, y, z)]
int borderSize; ///< Border size of the heighfield where the mesh was build from. float cs; ///< The size of each cell. (On the xz-plane.)
float ch; ///< The height of each cell. (The minimum increment along the y-axis.)
int borderSize; ///< The AABB border size used to generate the source data from which the mesh was derived.
}; };
/// Allocates a polygon mesh object using the Recast allocator.
/// @return A polygon mesh that is ready for initialization, or null on failure.
/// @ingroup recast
rcPolyMesh* rcAllocPolyMesh(); rcPolyMesh* rcAllocPolyMesh();
/// Frees the specified polygon mesh using the Recast allocator.
/// @param[in] pmesh A polygon mesh allocated using #rcAllocPolyMesh
/// @ingroup recast
void rcFreePolyMesh(rcPolyMesh* pmesh); void rcFreePolyMesh(rcPolyMesh* pmesh);
@ -719,3 +901,9 @@ bool rcMergePolyMeshDetails(rcContext* ctx, rcPolyMeshDetail** meshes, const int
#endif // RECAST_H #endif // RECAST_H
///////////////////////////////////////////////////////////////////////////
// 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.

View File

@ -32,7 +32,27 @@ float rcSqrt(float x)
return sqrtf(x); return sqrtf(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.
///
/// If no logging or timers are required, just pass an instance of this
/// class through the Recast build process.
///
/// @par
///
/// Example:
/// @code
/// // Where ctx is an instance of rcContext and filepath is a char array.
/// ctx->log(RC_LOG_ERROR, "buildTiledNavigation: Could not load '%s'", filepath);
/// @endcode
void rcContext::log(const rcLogCategory category, const char* format, ...) void rcContext::log(const rcLogCategory category, const char* format, ...)
{ {
if (!m_logEnabled) if (!m_logEnabled)