Recast & Detour 尋路引擎的基本流程

轉載自: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庫。

 

SDLSimple DirectMedia Layer)是一套開放源代碼的跨平臺多媒體開發庫,使用C語言寫成。SDL提供了數種控制圖像、聲音、輸出入的函數,讓開發者只要用相同或是相似的代碼就可以開發出跨多個平臺(LinuxWindowsMac OS X等)的應用軟件。目前SDL多用於開發遊戲、模擬器、媒體播放器等多媒體應用領域。

它被廣泛的用於許多著名的遊戲。最著名的遊戲是贏得Linux組遊戲開發大獎的 文明:權利的召喚(Civilization: Call To Power)。

SDL內置了調用OpenGL的函數。

SDL的編譯又需要Direct X


建立NaviMesh的過程(Sample_SoloMesh::handleBuild)

 

一、填寫build的配置結構體rcConfig

二、光柵化輸入的polygon soup(網格?)

a) 創建體素高度域rcHeightfieldrcAllocHeightfieldrcCreateHeightfield

b) 創建存儲三角形的索引緩存:m_triareas = new unsigned char[ntris];

c) 根據斜率搜尋可走的三角形,然後光柵化它們:rcMarkWalkableTrianglesrcRasterizeTriangles

三、過濾可走面

刪除突出的障礙rcFilterLowHangingWalkableObstacles

刪除架狀突出物rcFilterLedgeSpans

刪除玩家不可能站立的區域rcFilterWalkableLowHeightSpans

四、分割可走面爲簡單多邊形

a) 緊縮高度域以加速:rcAllocCompactHeightfieldrcBuildCompactHeightfield

b) 根據可走半徑腐蝕可走區域:rcErodeWalkableArea

c) (可選)標記凸多邊形區域:對於每個getConvexVolumesrcMarkConvexPolyArea

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

rcBuildDistanceFieldrcBuildRegions

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

五、跟蹤並簡化區域輪廓

rcAllocContourSetrcBuildContours

六、通過輪廓創建多邊形網格(Mesh

rcAllocPolyMeshrcBuildPolyMesh

七、創建細節網格(允許訪問每個多邊形的近似高度)

rcAllocPolyMeshDetailrcBuildPolyMeshDetail

 

(至此,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.cpp355行開始)


在建立了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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章