转载自:http://www.aiuxian.com/article/p-1974951.html
Recast & Detour是一个开源的寻路引擎,其遵循zlib协议,基本上你可以免费且无限制的将它用作个人和商业产品中。
从名字中我们可以看到,这个引擎分成两部分:
第一部分是Recast,主要功能是将场景网格模型生成用于寻路的网格模型(Navigation Mesh)。所生成的寻路网格模型当然要比原模型简单很多,这也提高了实时寻路算法的效率。
第二部分是Detour,主要功能是利用上一步所生成的Navigation Mesh进行寻路,其包含了多种寻路算法,根据不同的路径光滑程度与寻路时间效率的要求可做不同的选择。
关于Navigation Mesh,可参考:
A navigation mesh, or navmesh, is an abstract data structure used in artificial intelligence applications to aid agents in path-finding through large spaces. Meshes that do not map to static obstacles in the environment that they model, offer the additional advantage that agents with access to the mesh will not consider these obstacles in path-finding, reducing computational effort and making collision detection between agents and static obstacles moot. Meshes are typically implemented as graphs, opening their use to a large number of algorithms defined on these structures.
One of the most common uses of a navigation mesh is in video games, to describe the paths that a computer-controlled character can follow. It is usually represented as a volume or brush that is processed and computed during level compilation.
References[edit]
"Navigation Mesh Reference". Retrieved 2012-12-16. ( 这个地址的介绍比较详尽)
Recast & Detour本身是个独立的程序库,其源码所带的Demo用到了SDL库。
SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软件。目前SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。 它被广泛的用于许多著名的游戏。最著名的游戏是赢得Linux组游戏开发大奖的 文明:权利的召唤(Civilization: Call To Power)。 SDL内置了调用OpenGL的函数。 SDL的编译又需要Direct X |
建立NaviMesh的过程(Sample_SoloMesh::handleBuild)
一、填写build的配置结构体rcConfig
二、光栅化输入的polygon soup(网格?)
a) 创建体素高度域rcHeightfield:rcAllocHeightfield,rcCreateHeightfield
b) 创建存储三角形的索引缓存:m_triareas = new unsigned char[ntris];
c) 根据斜率搜寻可走的三角形,然后光栅化它们:rcMarkWalkableTriangles,rcRasterizeTriangles
三、过滤可走面
删除突出的障碍rcFilterLowHangingWalkableObstacles
删除架状突出物rcFilterLedgeSpans
删除玩家不可能站立的区域rcFilterWalkableLowHeightSpans
四、分割可走面为简单多边形
a) 紧缩高度域以加速:rcAllocCompactHeightfield,rcBuildCompactHeightfield
b) 根据可走半径腐蚀可走区域:rcErodeWalkableArea
c) (可选)标记凸多边形区域:对于每个getConvexVolumes:rcMarkConvexPolyArea
d) 分割高度域(heightfield)以可用简单算法来三角化可走区域。有三种分割算法可选:
1) Watershed partitioning
- the classic Recast partitioning
- creates the nicest tessellation
- usually slowest
- partitions the heightfield into nice regions without holes or overlaps
- the are some corner cases where this method creates produces holes and overlaps
- holes may appear when a small obstacles is close to large open area (triangulation can handle this)
- overlaps may occur if you have narrow spiral corridors (i.e stairs), this make triangulation to fail
* generally the best choice if you precompute the nacmesh, use this if you have large open areas
rcBuildDistanceField,rcBuildRegions
2) Monotone partioning
- fastest
- partitions the heightfield into regions without holes and overlaps (guaranteed)
- creates long thin polygons, which sometimes causes paths with detours
* use this if you want fast navmesh generation
rcBuildRegionsMonotone
3) Layer partitoining
- quite fast
- partitions the heighfield into non-overlapping regions
- relies on the triangulation code to cope with holes (thus slower than monotone partitioning)
- produces better triangles than monotone partitioning
- does not have the corner cases of watershed partitioning
- can be slow and create a bit ugly tessellation (still better than monotone)
if you have large open areas with small obstacles (not a problem if you use tiles)
* good choice to use for tiled navmesh with medium and small sized tiles
rcBuildLayerRegions
五、跟踪并简化区域轮廓
rcAllocContourSet,rcBuildContours
六、通过轮廓创建多边形网格(Mesh)
rcAllocPolyMesh,rcBuildPolyMesh
七、创建细节网格(允许访问每个多边形的近似高度)
rcAllocPolyMeshDetail,rcBuildPolyMeshDetail
(至此,Navigation Mesh数据rcPolyMesh已经生成完毕)
八、(可选)从Recast网格创建detour数据
填写dtNavMeshCreateParams结构
创建NavMesh数据:dtCreateNavMeshData
分配Mesh结构:dtAllocNavMesh
初始化Mesh:
status = m_navMesh->init(navData, navDataSize, DT_TILE_FREE_DATA);
(recastnavigation-master\RecastDemo\Source\Sample_SoloMesh.cpp第355行开始)
在建立了NavMesh之后的寻路过程
通过dtNavMeshQuery::findNearestPoly寻找起止点的多边形引用。
此后有多种ToolMode可作为寻路方式:
但每种寻路方式都会先调用寻找多边形路径的算法dtNavMeshQuery::findPath,该方法的输入为起始的多边形引用和起始点的位置(用来计算遍历花费,y坐标影响结果),输出为一条以多边形引用为节点的路径。
注意:如果终点多边形不可达,那么最后一个多边形则为距离终点最近的多边形。如果用来存储结果的数组太小而不足以容纳所有路径多边形,那么这个数组将被填充从起始多边形到终点多边形的最远距离。也就是说,能填多少个就填多少个,但不够存储最后几个多边形了。
enum ToolMode
{
TOOLMODE_PATHFIND_FOLLOW,
TOOLMODE_PATHFIND_STRAIGHT,
TOOLMODE_PATHFIND_SLICED,
TOOLMODE_RAYCAST,
TOOLMODE_DISTANCE_TO_WALL,
TOOLMODE_FIND_POLYS_IN_CIRCLE,
TOOLMODE_FIND_POLYS_IN_SHAPE,
TOOLMODE_FIND_LOCAL_NEIGHBOURHOOD,
};
TOOLMODE_PATHFIND_FOLLOW
迭代的向前,每次前进一小步,直到到达终点或用于存储光滑路径的buffer用完为止。
TOOLMODE_PATHFIND_STRAIGHT
寻找直的路径,也叫“string pulling”就是拉线方法。
TOOLMODE_PATHFIND_SLICED
从代码中没看明白具体是怎样的方法,TODO:在程序中看。
TOOLMODE_RAYCAST
该方法用于快速的短距离检测。
TOOLMODE_DISTANCE_TO_WALL
TOOLMODE_FIND_POLYS_IN_CIRCLE
TOOLMODE_FIND_POLYS_IN_SHAPE
TOOLMODE_FIND_LOCAL_NEIGHBOURHOOD