以下为个人学习笔记整理,源项目 github 链接。
# Recast Navigation 源码阅读
# 基础属性
# CellSize
单个「Span」的长宽
# CellHeight
单个「Span」的最小高度
# AgentHeight
行走对象的高度
# AgentRadius
行走对象的步长半径
# AgentMaxClimb
行走对象的最大爬坡高度
# MaxEdgeError
面片和几何物体的距离,可以理解为面片和几何的贴合程度,越小贴合越紧密,面片越多
# VertsPerPoly
多边形的最大顶点数
# Recast 基础数据结构
# Span
体素化的最小单位,用于表示固定长宽(CellSize),可变高的矩形区域。
- smin:矩形区域的最低点的 y 坐标
- smax:矩形区域的最高点的 y 坐标
- area:可行走状态,标识该「Span」上表面能否行走(0:不能,64:可以)
- next:指向同 x-z 坐标的下一个「Span」
/// Represents a span in a heightfield. | |
/// @see rcHeightfield | |
struct rcSpan | |
{ | |
unsigned int smin : RC_SPAN_HEIGHT_BITS; ///< The lower limit of the span. [Limit: < #smax] | |
unsigned int smax : RC_SPAN_HEIGHT_BITS; ///< The upper limit of the span. [Limit: <= #RC_SPAN_MAX_HEIGHT] | |
unsigned int area : 6; ///< The area id assigned to the span. | |
rcSpan* next; ///< The next span higher up in column. | |
}; |
# SpanPool
对于「Span」的内存池。
- RC_SPANS_PER_POOL:默认 2048 个
- next:指向下一个「SpanPool」
/// A memory pool used for quick allocation of spans within a heightfield. | |
/// @see rcHeightfield | |
struct rcSpanPool | |
{ | |
rcSpanPool* next; ///< The next span pool. | |
rcSpan items[RC_SPANS_PER_POOL]; ///< Array of spans in the pool. | |
}; |
# Heightfield
用来表示模型的高度场,管理场景中的三角形面片所产生的「Span」。
- width:max_x / CellSize
- height:max_y / CellHeight
- bmin:(min_x, min_y, min_z),用于表示场景包围盒的左下边界
- bmax:(max_x, max_y,max_z),用于表示场景包围盒的右上边界
- cs:CellSize
- ch:CellHeight
- spans:「Span」的指针数组,记录 x-z 平面上(width * height 个)「Span」的首对象
- pools:「SpanPool」链表的链头,用于申请内存创建「Span」
- freelist:管理「SpanPool」创建出并且空闲未被使用的「Span」
/// A dynamic heightfield representing obstructed space. | |
/// @ingroup recast | |
struct rcHeightfield | |
{ | |
rcHeightfield(); | |
~rcHeightfield(); | |
int width; ///< The width of the heightfield. (Along the x-axis in cell units.) | |
int height; ///< The height of the heightfield. (Along the z-axis in cell units.) | |
float bmin[3]; ///< The minimum bounds in world space. [(x, y, z)] | |
float bmax[3]; ///< The maximum bounds in world space. [(x, y, z)] | |
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.) | |
rcSpan** spans; ///< Heightfield of spans (width*height). | |
rcSpanPool* pools; ///< Linked list of span pools. | |
rcSpan* freelist; ///< The next free span. | |
private: | |
// Explicitly-disabled copy constructor and copy assignment operator. | |
rcHeightfield(const rcHeightfield&); | |
rcHeightfield& operator=(const rcHeightfield&); | |
}; |
# CompactSpan
记录可行走「Span」的上表面高度等信息。
- y:可行走「Span」的
smax
值y = rcClamp(span.smax, 0, 0xffff);
- reg:记录「CompactSpan」所属区域编号
- con:周围(前后左右)四个方向上「CompactSpan」连通数据,每
6
bit 标识一个方向- 每个方向记录的是相邻位置的第几个「CompactSpan」和自己连通,因此可以用相邻位置的
idx + con[dir]
来获取到相邻「CompactSpan」
- 每个方向记录的是相邻位置的第几个「CompactSpan」和自己连通,因此可以用相邻位置的
- h:y 坐标和下一个「Span」的
smmin
的差h = rcClamp(y - span->next->smin, 0, 0xffff);
/// Represents a span of unobstructed space within a compact heightfield. | |
struct rcCompactSpan | |
{ | |
unsigned short y; ///< The lower extent of the span. (Measured from the heightfield's base.) | |
unsigned short reg; ///< The id of the region the span belongs to. (Or zero if not in a region.) | |
unsigned int con : 24; ///< Packed neighbor connection data. | |
unsigned int h : 8; ///< The height of the span. (Measured from #y.) | |
}; |
# CompactCell
通过第一个编号和个数,可以快速遍历所有「CompactSpan」。
- index:该「CompactCell」列从下往上第一个「CompactSpan」的
idx
- 「CompactSpan」编号在 y 轴方向是递增的
- count:每个「CompactCell」包含的「CompactSpan」个数
因此可用首个「CompactSpan」
idx
+ 该列的「CompactSpan」个数count
来遍历整列的「CompactSpan」
/// Provides information on the content of a cell column in a compact heightfield. | |
struct rcCompactCell | |
{ | |
unsigned int index : 24; ///< Index to the first span in the column. | |
unsigned int count : 8; ///< Number of spans in the column. | |
}; |
# CompactHeightfield
用来表示不存在遮挡的空间。
- width:max_x / CellSize
- height:max_y / CellHeight
- spanCount:「CompactSpan」数量。
- walkableHeight:AgentHeight,上下两个「CompactSpan」太近的情况下会影响能否站立
- walkableClimb:AgentMaxClimb,「CompactSpan」内三角形片面倾斜程度会影响能否站立
- borderSize:边界大小。「Region」的外轮廓大小。
- maxDistance:构建「高度场」的「距离场」时,缓存的最大距离,用于分水岭算法的起始漫灌高度
- maxRegions:临时记录「Region」的数量,用于「Region」合并和再编排
- bmin:(min_x, min_y, min_z),用于表示场景包围盒的左下边界
- bmax:(max_x, max_y,max_z),用于表示场景包围盒的右上边界
- cs:CellSize
- ch:CellHeight
- cells:「CompactCell」数组
- spans:「CompactSpan」数组
- dist:临时记录每个「CompactSpan」的「场距」,用于划分「Region」
- areas:记录每个「CompactSpan」的可行走状态
/// A compact, static heightfield representing unobstructed space. | |
/// @ingroup recast | |
struct rcCompactHeightfield | |
{ | |
rcCompactHeightfield(); | |
~rcCompactHeightfield(); | |
int width; ///< The width of the heightfield. (Along the x-axis in cell units.) | |
int height; ///< The height of the heightfield. (Along the z-axis in cell units.) | |
int spanCount; ///< The number of spans in the heightfield. | |
int walkableHeight; ///< The walkable height used during the build of the field. (See: rcConfig::walkableHeight) | |
int walkableClimb; ///< The walkable climb used during the build of the field. (See: rcConfig::walkableClimb) | |
int borderSize; ///< The AABB border size used during the build of the field. (See: rcConfig::borderSize) | |
unsigned short maxDistance; ///< The maximum distance value of any span within the field. | |
unsigned short maxRegions; ///< The maximum region id of any span within the field. | |
float bmin[3]; ///< The minimum bounds in world space. [(x, y, z)] | |
float bmax[3]; ///< The maximum bounds in world space. [(x, y, z)] | |
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.) | |
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] | |
}; |
# Regions 相关数据结构
# Region
多个「CompactSpan」组成的区域。
- spanCount:「CompactSpan」数量
- id:
region_id
- areaType:记录「Region」的可行走状态,继承于
CompactHeightfield.areas
- remap:是否重新编排
- visited:是否已经访问过
- overlap:是否有重叠
- ymin:「Region」内所有「CompactSpan」的最小
y
- ymax:「Region」内所有「CompactSpan」的最大
y
- connectsToBorder:是否和轮廓(BorderSize)相邻
- connections:记录该「Region」能连通的其他「Region」的
region_id
- floors:记录和该「Region」的重叠的「Region」的
region_id
struct rcRegion | |
{ | |
inline rcRegion(unsigned short i) : | |
spanCount(0), | |
id(i), | |
areaType(0), | |
remap(false), | |
visited(false), | |
overlap(false), | |
connectsToBorder(false), | |
ymin(0xffff), | |
ymax(0) | |
{} | |
int spanCount; // Number of spans belonging to this region | |
unsigned short id; // ID of the region | |
unsigned char areaType; // Are type. | |
bool remap; | |
bool visited; | |
bool overlap; | |
bool connectsToBorder; // neighbor is border | |
unsigned short ymin, ymax; | |
rcIntArray connections; | |
rcIntArray floors; | |
} |
# Contour
用于记录单个「Region」轮廓顶点数据。
- nverts:「simplify」后的「Region」轮廓顶点数量
- verts:「simplify」后的「Region」轮廓顶点数据
[x, y, z, neighbor_region_id] * nverts
- nrverts:「simplify」前的「Region」轮廓顶点数量
- rverts:「simplify」前的「Region」轮廓顶点数据
[x, y, z, neighbor_region_id] * nverts
- reg:轮廓顶点所表示的「Region」的
region_id
- area:轮廓顶点所表示的「Region」的
area_type
地形类型
struct rcContour | |
{ | |
int* verts; ///< Simplified contour vertex and connection data. [Size: 4 * #nverts] | |
int nverts; ///< The number of vertices in the simplified contour. | |
int* rverts; ///< Raw contour vertex and connection data. [Size: 4 * #nrverts] | |
int nrverts; ///< The number of vertices in the raw contour. | |
unsigned short reg; ///< The region id of the contour. | |
unsigned char area; ///< The area id of the contour. | |
}; |
# ContourSet
「Contour」集合管理器,存储所有「Region」的轮廓顶点数据。
- conts:「Contour」数组,记录所有「Region」的轮廓顶点数据
- nconts:
len(conts)
- bmin:(min_x, min_y, min_z),用于表示场景包围盒的左下边界
- bmax:(max_x, max_y,max_z),用于表示场景包围盒的右上边界
- cs:CellSize
- ch:CellHeight
- width:max_x / CellSize
- height:max_y / CellHeight
- borderSize:边界大小,「Region」的外轮廓
- maxError:MaxEdgeError
struct rcContourSet | |
{ | |
rcContourSet(); | |
~rcContourSet(); | |
rcContour* conts; ///< An array of the contours in the set. [Size: #nconts] | |
int nconts; ///< The number of contours in the set. | |
float bmin[3]; ///< The minimum bounds in world space. [(x, y, z)] | |
float bmax[3]; ///< The maximum bounds in world space. [(x, y, z)] | |
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 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. | |
float maxError; ///< The MaxEdgeError that this contour set was simplified with. | |
}; |
# ContourHole
- contour:记录对应
region_id
的「Contour」 数据,只记录凹多边形 - minx, minz, leftmost:凹多边形的左下角顶点坐标和顶点编号
struct rcContourHole | |
{ | |
rcContour* contour; | |
int minx, minz, leftmost; | |
}; |
# ContourRegion
- outline:记录对应
region_id
的「Contour」 数据,只记录凸多边形 - nholes:记录对应
region_id
的凹多边形轮廓数量,理论上应该只有一个 - holes:凹多边形数值的起始索引,配合
nholes
可以获取所有的凹多边形
struct rcContourRegion | |
{ | |
rcContour* outline; | |
rcContourHole* holes; | |
int nholes; | |
}; |
# PotentialDiagonal
- vert:顶点在「Contour」的下标
- dist:该凸多边形顶点和某个凹多边形顶点的距离平方
struct rcPotentialDiagonal | |
{ | |
int vert; | |
int dist; | |
}; |
# Mesh 相关数据结构
# Edge
多边形边信息,一条边最多被两个多边形共用
- vert:首尾顶点编号
- poly:该条边所属的多边形编号,由于可能有两个多边形共用,所以 0 记录升序的多边形,1 记录降序的多边形
- polyEdge:多边形内的边编号,由于可能有两个多边形共用,所以 0 记录升序边编号,1 记录降序边编号
struct rcEdge | |
{ | |
unsigned short vert[2]; | |
unsigned short polyEdge[2]; | |
unsigned short poly[2]; | |
}; |
# PolyMesh
记录所有「Poly」数据
- verts:全部「Region」轮廓的所有顶点集合
- polys:2 倍的
npolys
大小,|_0_|_1_| * npolys
- 前半部分记录每个多边形各个顶点的顶点编号
|_0_|
- 后半部分记录每条边相邻的多边形编号
|_1_|
- 前半部分记录每个多边形各个顶点的顶点编号
- regs:记录每个「Poly」的
region_id
- flags:标记地形类型,值取决于
areas
enum SamplePolyFlags | |
{ | |
SAMPLE_POLYFLAGS_WALK = 0x01, // Ability to walk (ground, grass, road) | |
SAMPLE_POLYFLAGS_SWIM = 0x02, // Ability to swim (water). | |
SAMPLE_POLYFLAGS_DOOR = 0x04, // Ability to move through doors. | |
SAMPLE_POLYFLAGS_JUMP = 0x08, // Ability to jump. | |
SAMPLE_POLYFLAGS_DISABLED = 0x10, // Disabled polygon | |
SAMPLE_POLYFLAGS_ALL = 0xffff // All abilities. | |
}; |
- areas:记录每个「Poly」的
area_type
地形类型 - nverts:去重之后的「Contour」顶点数量
- npolys:合并后的多边形数量
- maxpolys:最大「Poly」数量
- nvp:VertsPerPoly
- bmin:(min_x, min_y, min_z),用于表示场景包围盒的左下边界
- bmax:(max_x, max_y,max_z),用于表示场景包围盒的右上边界
- cs:CellSize
- ch:CellHeight
- borderSize:边界大小,「Region」的外轮廓
- maxError:MaxEdgeError
struct rcPolyMesh | |
{ | |
rcPolyMesh(); | |
~rcPolyMesh(); | |
unsigned short* verts; ///< The mesh vertices. [Form: (x, y, z) * #nverts] | |
unsigned short* polys; ///< Polygon and neighbor data. [Length: #maxpolys * 2 * #nvp] | |
unsigned short* regs; ///< The region id assigned to each polygon. [Length: #maxpolys] | |
unsigned short* flags; ///< The user defined flags for each polygon. [Length: #maxpolys] | |
unsigned char* areas; ///< The area id assigned to each polygon. [Length: #maxpolys] | |
int nverts; ///< The number of vertices. | |
int npolys; ///< The number of polygons. | |
int maxpolys; ///< The number of allocated polygons. | |
int nvp; ///< The maximum number of vertices per polygon. | |
float bmin[3]; ///< The minimum bounds in world space. [(x, y, z)] | |
float bmax[3]; ///< The maximum bounds in world space. [(x, y, z)] | |
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. | |
float maxEdgeError; ///< The max error of the polygon edges in the mesh. | |
}; |
# PolyMeshDetail
以每个「Poly」为单位,记录「Poly」经过采样和切分后得到的三角形信息
meshes:四个元素的数组,每四个元素表示一个「Poly」的数据信息,四个元素代表含义如下
- 多边形首个顶点的顶点编号
- 总顶点数量,包括内部新增的
- 多边形首个三角形的编号
- 总三角形数量
verts:记录所有「Poly」经过采样和切分后的顶点
tris:记录所有「Poly」经过采样和切分后的三角形
nmeshes:「Poly」数量,同
PolyMesh.npolys
nverts:「Poly」的总顶点数量
len(verts)
ntris:「Poly」的总三角形数量
len(tris)
/// Contains triangle meshes that represent detailed height data associated | |
/// with the polygons in its associated polygon mesh object. | |
/// @ingroup recast | |
struct rcPolyMeshDetail | |
{ | |
unsigned int* meshes; ///< The sub-mesh data. [Size: 4*#nmeshes] | |
float* verts; ///< The mesh vertices. [Size: 3*#nverts] | |
unsigned char* tris; ///< The mesh triangles. [Size: 4*#ntris] | |
int nmeshes; ///< The number of sub-meshes defined by #meshes. | |
int nverts; ///< The number of vertices in #verts. | |
int ntris; ///< The number of triangles in #tris. | |
}; |
# HeightPatch
记录单个「Poly」的高度相关数据
- data:记录「Poly」AABB 包围盒内每个同
region_id
点所代表的「CompactSpan」的上表面高度 - xmin:「Poly」所有顶点的最小
x
坐标 - ymin:「Poly」所有顶点的最小
z
坐标 - with:「Poly」最大最小顶点的
x
轴跨度 (包围盒长) - height:「Poly」最大最小顶点的
z
轴跨度 (包围盒宽)
struct rcHeightPatch | |
{ | |
inline rcHeightPatch() : data(0), xmin(0), ymin(0), width(0), height(0) {} | |
inline ~rcHeightPatch() { rcFree(data); } | |
unsigned short* data; // all poly xz-plane AABB maxhw,maxhh | |
int xmin, ymin, width, height; | |
}; |
# NavMesh 相关数据结构
# MeshTile
/// Defines a navigation mesh tile. | |
/// @ingroup detour | |
struct dtMeshTile | |
{ | |
unsigned int salt; ///< Counter describing modifications to the tile. | |
unsigned int linksFreeList; ///< Index to the next free link. | |
dtMeshHeader* header; ///< The tile header. | |
dtPoly* polys; ///< The tile polygons. [Size: dtMeshHeader::polyCount] | |
float* verts; ///< The tile vertices. [Size: dtMeshHeader::vertCount] | |
dtLink* links; ///< The tile links. [Size: dtMeshHeader::maxLinkCount] | |
dtPolyDetail* detailMeshes; ///< The tile's detail sub-meshes. [Size: dtMeshHeader::detailMeshCount] | |
/// The detail mesh's unique vertices. [(x, y, z) * dtMeshHeader::detailVertCount] | |
float* detailVerts; | |
/// The detail mesh's triangles. [(vertA, vertB, vertC, triFlags) * dtMeshHeader::detailTriCount]. | |
/// See dtDetailTriEdgeFlags and dtGetDetailTriEdgeFlags. | |
unsigned char* detailTris; | |
/// The tile bounding volume nodes. [Size: dtMeshHeader::bvNodeCount] | |
/// (Will be null if bounding volumes are disabled.) | |
dtBVNode* bvTree; | |
dtOffMeshConnection* offMeshCons; ///< The tile off-mesh connections. [Size: dtMeshHeader::offMeshConCount] | |
unsigned char* data; ///< The tile data. (Not directly accessed under normal situations.) | |
int dataSize; ///< Size of the tile data. | |
int flags; ///< Tile flags. (See: #dtTileFlags) | |
dtMeshTile* next; ///< The next free tile, or the next tile in the spatial grid. | |
}; |
# NavMesh
class dtNavMesh | |
{ | |
public: | |
//... | |
private: | |
dtNavMeshParams m_params; ///< Current initialization params. TODO: do not store this info twice. | |
float m_orig[3]; ///< Origin of the tile (0,0) | |
float m_tileWidth, m_tileHeight; ///< Dimensions of each tile. | |
int m_maxTiles; ///< Max number of tiles. | |
int m_tileLutSize; ///< Tile hash lookup size (must be pot). | |
int m_tileLutMask; ///< Tile hash lookup mask. | |
dtMeshTile** m_posLookup; ///< Tile hash lookup. | |
dtMeshTile* m_nextFree; ///< Freelist of tiles. | |
dtMeshTile* m_tiles; ///< List of tiles. | |
} |
# NavMeshParams
- orig[3]:
bmin
- tileWidth:
max_x - min_x
- tileHeight:
max_z - min_z
- maxPolys:「PolyMesh」的
npolys
/// Configuration parameters used to define multi-tile navigation meshes. | |
/// The values are used to allocate space during the initialization of a navigation mesh. | |
/// @see dtNavMesh::init() | |
/// @ingroup detour | |
struct dtNavMeshParams | |
{ | |
float orig[3]; ///< The world space origin of the navigation mesh's tile space. [(x, y, z)] | |
float tileWidth; ///< The width of each tile. (Along the x-axis.) | |
float tileHeight; ///< The height of each tile. (Along the z-axis.) | |
int maxTiles; ///< The maximum number of tiles the navigation mesh can contain. This and maxPolys are used to calculate how many bits are needed to identify tiles and polygons uniquely. | |
int maxPolys; ///< The maximum number of polygons each tile can contain. This and maxTiles are used to calculate how many bits are needed to identify tiles and polygons uniquely. | |
}; |
# NavMeshCreateParams
# PolyMesh 相关数据
- verts:「PolyMesh」的
verts
- vertCount:「PolyMesh」的
nverts
- polys:「PolyMesh」的
polys
- polyAreas:「PolyMesh」的
areas
- polyFlags:「PolyMesh」的
flags
- polyCount:「PolyMesh」的
npolys
- nvp:「PolyMesh」的
nvp
# PolyMeshDetail 相关数据
- detailMeshes:「PolyMeshDetail」的
meshes
- detailVerts:「PolyMeshDetail」的
verts
- detailVertsCount:「PolyMeshDetail」的
nverts
- detailTris:「PolyMeshDetail」的
tris
- detailTriCount:「PolyMeshDetail」的
ntris
# OffMeshConnection 相关数据
自定义的一些导航链接数据
- offMeshConVerts:
- offMeshConRad:
- offMeshConDir:
- offMeshConAreas:
- offMeshConFlags:
- offMeshConUserID:
- offMeshConCount:
# Tile 相关数据
- userId:
- tileX:
- tileY:
- tileLayer:
# General Configuration 相关数据
- walkableHeight:AgentHeight
- walkableRadius:AgentRadius
- walkableClimb:AgentMaxClimb
- bmin:(min_x, min_y, min_z),用于表示场景包围盒的左下边界
- bmax:(max_x, max_y,max_z),用于表示场景包围盒的右上边界
- cs:CellSize
- ch:CellHeight
- buildBvTree:标记是否需要构建 BVTree
struct dtNavMeshCreateParams | |
{ | |
/// @name Polygon Mesh Attributes | |
/// Used to create the base navigation graph. | |
/// See #rcPolyMesh for details related to these attributes. | |
/// @{ | |
const unsigned short* verts; ///< The polygon mesh vertices. [(x, y, z) * #vertCount] [Unit: vx] | |
int vertCount; ///< The number vertices in the polygon mesh. [Limit: >= 3] | |
const unsigned short* polys; ///< The polygon data. [Size: #polyCount * 2 * #nvp] | |
const unsigned short* polyFlags; ///< The user defined flags assigned to each polygon. [Size: #polyCount] | |
const unsigned char* polyAreas; ///< The user defined area ids assigned to each polygon. [Size: #polyCount] | |
int polyCount; ///< Number of polygons in the mesh. [Limit: >= 1] | |
int nvp; ///< Number maximum number of vertices per polygon. [Limit: >= 3] | |
/// @} | |
/// @name Height Detail Attributes (Optional) | |
/// See #rcPolyMeshDetail for details related to these attributes. | |
/// @{ | |
const unsigned int* detailMeshes; ///< The height detail sub-mesh data. [Size: 4 * #polyCount] | |
const float* detailVerts; ///< The detail mesh vertices. [Size: 3 * #detailVertsCount] [Unit: wu] | |
int detailVertsCount; ///< The number of vertices in the detail mesh. | |
const unsigned char* detailTris; ///< The detail mesh triangles. [Size: 4 * #detailTriCount] | |
int detailTriCount; ///< The number of triangles in the detail mesh. | |
/// @} | |
/// @name Off-Mesh Connections Attributes (Optional) | |
/// Used to define a custom point-to-point edge within the navigation graph, an | |
/// off-mesh connection is a user defined traversable connection made up to two vertices, | |
/// at least one of which resides within a navigation mesh polygon. | |
/// @{ | |
/// Off-mesh connection vertices. [(ax, ay, az, bx, by, bz) * #offMeshConCount] [Unit: wu] | |
const float* offMeshConVerts; | |
/// Off-mesh connection radii. [Size: #offMeshConCount] [Unit: wu] | |
const float* offMeshConRad; | |
/// User defined flags assigned to the off-mesh connections. [Size: #offMeshConCount] | |
const unsigned short* offMeshConFlags; | |
/// User defined area ids assigned to the off-mesh connections. [Size: #offMeshConCount] | |
const unsigned char* offMeshConAreas; | |
/// The permitted travel direction of the off-mesh connections. [Size: #offMeshConCount] | |
/// | |
/// 0 = Travel only from endpoint A to endpoint B.<br/> | |
/// #DT_OFFMESH_CON_BIDIR = Bidirectional travel. | |
const unsigned char* offMeshConDir; | |
/// The user defined ids of the off-mesh connection. [Size: #offMeshConCount] | |
const unsigned int* offMeshConUserID; | |
/// The number of off-mesh connections. [Limit: >= 0] | |
int offMeshConCount; | |
/// @} | |
/// @name Tile Attributes | |
/// @note The tile grid/layer data can be left at zero if the destination is a single tile mesh. | |
/// @{ | |
unsigned int userId; ///< The user defined id of the tile. | |
int tileX; ///< The tile's x-grid location within the multi-tile destination mesh. (Along the x-axis.) | |
int tileY; ///< The tile's y-grid location within the multi-tile desitation mesh. (Along the z-axis.) | |
int tileLayer; ///< The tile's layer within the layered destination mesh. [Limit: >= 0] (Along the y-axis.) | |
float bmin[3]; ///< The minimum bounds of the tile. [(x, y, z)] [Unit: wu] | |
float bmax[3]; ///< The maximum bounds of the tile. [(x, y, z)] [Unit: wu] | |
/// @} | |
/// @name General Configuration Attributes | |
/// @{ | |
float walkableHeight; ///< The agent height. [Unit: wu] | |
float walkableRadius; ///< The agent radius. [Unit: wu] | |
float walkableClimb; ///< The agent maximum traversable ledge. (Up/Down) [Unit: wu] | |
float cs; ///< The xz-plane cell size of the polygon mesh. [Limit: > 0] [Unit: wu] | |
float ch; ///< The y-axis cell height of the polygon mesh. [Limit: > 0] [Unit: wu] | |
/// True if a bounding volume tree should be built for the tile. | |
/// @note The BVTree is not normally needed for layered navigation meshes. | |
bool buildBvTree; | |
/// @} | |
}; |
# MeshHeader
- bvNodeCount:
buildBvTree ? polyCount*2 : 0;
- bvQuantFactor:
1.0f / cs;
/// Provides high level information related to a dtMeshTile object. | |
/// @ingroup detour | |
struct dtMeshHeader | |
{ | |
int magic; ///< Tile magic number. (Used to identify the data format.) | |
int version; ///< Tile data format version number. | |
int x; ///< The x-position of the tile within the dtNavMesh tile grid. (x, y, layer) | |
int y; ///< The y-position of the tile within the dtNavMesh tile grid. (x, y, layer) | |
int layer; ///< The layer of the tile within the dtNavMesh tile grid. (x, y, layer) | |
unsigned int userId; ///< The user defined id of the tile. | |
int polyCount; ///< The number of polygons in the tile. | |
int vertCount; ///< The number of vertices in the tile. | |
int maxLinkCount; ///< The number of allocated links. | |
int detailMeshCount; ///< The number of sub-meshes in the detail mesh. | |
/// The number of unique vertices in the detail mesh. (In addition to the polygon vertices.) | |
int detailVertCount; | |
int detailTriCount; ///< The number of triangles in the detail mesh. | |
int bvNodeCount; ///< The number of bounding volume nodes. (Zero if bounding volumes are disabled.) | |
int offMeshConCount; ///< The number of off-mesh connections. | |
int offMeshBase; ///< The index of the first polygon which is an off-mesh connection. | |
float walkableHeight; ///< The height of the agents using the tile. | |
float walkableRadius; ///< The radius of the agents using the tile. | |
float walkableClimb; ///< The maximum climb height of the agents using the tile. | |
float bmin[3]; ///< The minimum bounds of the tile's AABB. [(x, y, z)] | |
float bmax[3]; ///< The maximum bounds of the tile's AABB. [(x, y, z)] | |
/// The bounding volume quantization factor. | |
float bvQuantFactor; | |
}; |
# Poly
/// Defines a polygon within a dtMeshTile object. | |
/// @ingroup detour | |
struct dtPoly | |
{ | |
/// Index to first link in linked list. (Or #DT_NULL_LINK if there is no link.) | |
unsigned int firstLink; | |
/// The indices of the polygon's vertices. | |
/// The actual vertices are located in dtMeshTile::verts. | |
unsigned short verts[DT_VERTS_PER_POLYGON]; | |
/// Packed data representing neighbor polygons references and flags for each edge. | |
unsigned short neis[DT_VERTS_PER_POLYGON]; | |
/// The user defined polygon flags. | |
unsigned short flags; | |
/// The number of vertices in the polygon. | |
unsigned char vertCount; | |
/// The bit packed area id and polygon type. | |
/// @note Use the structure's set and get methods to acess this value. | |
unsigned char areaAndtype; | |
/// Sets the user defined area id. [Limit: < #DT_MAX_AREAS] | |
inline void setArea(unsigned char a) { areaAndtype = (areaAndtype & 0xc0) | (a & 0x3f); } | |
/// Sets the polygon type. (See: #dtPolyTypes.) | |
inline void setType(unsigned char t) { areaAndtype = (areaAndtype & 0x3f) | (t << 6); } | |
/// Gets the user defined area id. | |
inline unsigned char getArea() const { return areaAndtype & 0x3f; } | |
/// Gets the polygon type. (See: #dtPolyTypes) | |
inline unsigned char getType() const { return areaAndtype >> 6; } | |
}; |
# Link
/// Defines a link between polygons. | |
/// @note This structure is rarely if ever used by the end user. | |
/// @see dtMeshTile | |
struct dtLink | |
{ | |
dtPolyRef ref; ///< Neighbour reference. (The neighbor that is linked to.) | |
unsigned int next; ///< Index of the next link. | |
unsigned char edge; ///< Index of the polygon edge that owns this link. | |
unsigned char side; ///< If a boundary link, defines on which side the link is. | |
unsigned char bmin; ///< If a boundary link, defines the minimum sub-edge area. | |
unsigned char bmax; ///< If a boundary link, defines the maximum sub-edge area. | |
}; |
# PolyDetail
/// Defines the location of detail sub-mesh data within a dtMeshTile. | |
struct dtPolyDetail | |
{ | |
unsigned int vertBase; ///< The offset of the vertices in the dtMeshTile::detailVerts array. | |
unsigned int triBase; ///< The offset of the triangles in the dtMeshTile::detailTris array. | |
unsigned char vertCount; ///< The number of vertices in the sub-mesh. | |
unsigned char triCount; ///< The number of triangles in the sub-mesh. | |
}; |
# BVNode
- i:node 编号,正数表示叶节点在数组的下标;负数表示根节点,数值表示根节点下所有节点数量
/// Bounding volume node. | |
/// @note This structure is rarely if ever used by the end user. | |
/// @see dtMeshTile | |
struct dtBVNode | |
{ | |
unsigned short bmin[3]; ///< Minimum bounds of the node's AABB. [(x, y, z)] | |
unsigned short bmax[3]; ///< Maximum bounds of the node's AABB. [(x, y, z)] | |
int i; ///< The node's index. (Negative for escape sequence.) | |
}; |
# OffMeshConnection 相关数据
# OffMeshConnection
/// Defines an navigation mesh off-mesh connection within a dtMeshTile object. | |
/// An off-mesh connection is a user defined traversable connection made up to two vertices. | |
struct dtOffMeshConnection | |
{ | |
/// The endpoints of the connection. [(ax, ay, az, bx, by, bz)] | |
float pos[6]; | |
/// The radius of the endpoints. [Limit: >= 0] | |
float rad; | |
/// The polygon reference of the connection within the tile. | |
unsigned short poly; | |
/// Link flags. | |
/// @note These are not the connection's user defined flags. Those are assigned via the | |
/// connection's dtPoly definition. These are link flags used for internal purposes. | |
unsigned char flags; | |
/// End point side. | |
unsigned char side; | |
/// The id of the offmesh connection. (User assigned when the navigation mesh is built.) | |
unsigned int userId; | |
}; |
# 细节说明
# neighbor connection data
用于记录相邻的前后左右「Span」连通情况,单个方向只会记录第一个满足相邻条件的「Span」
由 24 bit 构成,6bit 表示一个方位。如果不连通则值为 0x3f
/// 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. | |
/// RC_NOT_CONNECTED == 0X3F | |
inline int rcGetCon(const rcCompactSpan& s, int dir) | |
{ | |
const unsigned int shift = (unsigned int)dir*6; | |
return (s.con >> shift) & 0x3f; | |
} |
dir 方向说明:
///dir: 0~4 左前右后 | |
/// 0:x-1 | |
/// 1:z+1 | |
/// 2:x+1 | |
/// 3:z-1 | |
offset[4] = { -1, 1, 1, -1 }; |
# 参考资料
- 传送门大汇总:https://www.jianshu.com/p/64469a410b5d
- unity Navigation:https://docs.unity3d.com/Manual/Navigation.html
- gen navmash:http://critterai.org/
- 基础篇:https://www.jianshu.com/p/c0d209630c6b