筆記 navmesh


筆記 navmesh


1 簡介

RecastNavigation 是一個導航尋路工具集,Unity和UE4就是用的這個庫,開發者叫 Mikko Mononen。
它包括Recast和Detour兩個子集。

1.1 Recast

Recast 是一個網格導航工具集,一般是用在游戲里。
優勢:

  • 自動化的。 用的時候就是把任意層次的幾何體扔進去處理,然后會給你一堆網格信息。
  • 處理比較快。
  • 開源的,可以自己改代碼定制。

處理過程大概分為三個步驟:

  • 體素化模型
    • 用輸入的三角形網格體構建出多層的高度場。
      • 先體素化,用源幾何體構造出實心的高度場,表示障礙空間,包括地面、牆體等;
      • 然后將實心高度場的上表面中連續的區間合並為聯通區域,構造出緊湊高度場,表示可行走的開放空間。
    • 這個時候可以做一些簡單的篩選,去除掉角色不可到達的位置,比如空氣牆外面、空間太小不能容納角色的地方、大石頭里面。
  • 分割聯通區域
    把角色可行走的區域划分成簡單的二維疊加區域,會得到一個不重疊的輪廓線,這大大簡化了最后一步。
  • 將聯通區域簡化成多邊形
    通過先追蹤邊界,再對邊界進行簡化,使導航多邊形從區域中剝離出來。最終得到的多邊形被轉化成了凸多邊形,非常適合用於尋路和層次空間推理。

1.2 Detour

Detour 是一個尋路和空間推理工具包,recast必須要跟Detour結合起來用。 任何導航網格都可以和Detour結合用,但recast生成的是最切合的。
Detour會提供一個適用於許多簡單情況的簡單靜態導航網格,以及允許添加和刪除片段的分塊導航網格。
分塊的網格,可以隨着玩家在關卡中前進,輸入和輸出新的導航數據,或者隨着地圖的變化重新生成tiles。


2 Recast Demo

在源碼的RecastDemo目錄下,a kitchen sink demo,包含了這個庫所有功能。 用來學習這個庫的,而且可以編譯出一個可執行文件,可以用來測試驗證。
官方建議,剛開始學的話,先去看Sample_SoloMesh.cpp這個文件,可以搞清楚編譯導航網格的步驟;看NavMeshTesterTool.cpp這個文件,可以知道Detour是怎么尋路的。

2.1 windows下編譯Recast Demo

  • 下載premake5(需要用它生成vs的編譯項目),解壓到RecastDemo目錄下。
  • 下載SDL2(recast的功能依賴SDL庫),解壓到RecastDemo\Contrib目錄下,改名成SDL。到RecastDemo\Contrib\SDL目錄下,如果沒有lib目錄:
    • 那就到VisualC目錄下,vs打開SDL.sln,選擇Win32、Debug,編譯。
    • 把編出來的RecastDemo\Contrib\SDL\VisualC\Win32\Debug 下的文件復制到RecastDemo\Contrib\SDL\lib\x86
    • 總之RecastDemo\Contrib\SDL\lib\x86這個路徑下要有庫文件。
  • 在RecastDemo目錄下,cmd打開命令行,輸入 premake5 vs2019 (vs版本要對應自己已安裝的版本)
  • vs打開生成的RecastDemo\Build\vs2019\recastnavigation.sln,編譯。
  • 編譯出來的RecastDemo\Bin\RecastDemo.exe 即是可執行文件。

2.2 Recast Demo使用

2.2.1 基本使用

  • 在RecastDemo\Bin\Meshes目錄下有三個樣例文件。
  • 在RecastDemo\Bin\TestCases目錄下可以添加測試文本,編譯出來的RecastDemo\Bin\Tests.exe,可以用來做單元測試。 命令行運行它會指示哪些是失敗的,並統計成功的數量。
  • 運行RecastDemo.exe后,右側有兩個選項 :
    • Sample 三種編譯類型選擇,對應源碼里Sample的三個派生類
      • Solo Mesh 表示純粹的鄰接凸多邊形集合。 就是直接整個網格體按步驟搞。
      • Tile Mesh 表示基於tile划分的N個鄰接凸多邊形集合。 就是先分塊然后再按步驟搞,可以很方便地動態改變地形
      • Temp Obstacles 表示支持動態障礙物。 也是基於tile划分的N個鄰接凸多邊形集合,但它可以動態添加刪除障礙物,游戲里應該都是用這種。
    • Input Mesh 就是輸入進去處理的原始網格體,可以選三個樣例文件試試。
  • 剛開始用,選Solo Mesh和nav_test.obj,然后點Build。
  • WSADQE鍵移動視角,拖動右鍵旋轉。 點右鍵選開始點,點左鍵選結束點,就可以看到路徑了。

2.2.2 Properties屬性參數

rasterization 體素化 :
    Cell Size : 體素在X-Z-plane上的大小。 決定了網格的精度。 越小越精細,但時間和內存消耗相應也越大。 
               核心設置,會影響到其他參數。  
    Cell Height : 體素在Y-plane上的大小。 值較小並不會對內存消耗產生顯著影響;
                 較低的值雖然能夠使網格貼合原始圖形,但是如果是凹凸不平的地形,較低的值可能會造成鄰接的網格之間產生斷裂,
                 導致本來應該連在一起的網格造分離。
Agent 角色 : 
    Height : 角色高度,單位米
    Radius : 角色半徑,單位米
    MaxClimb : 角色最大可跨越不同地形時的高度,比如上樓梯時,單位米
    MaxSlope : 角色最大可通過的斜坡的傾斜度,單位度
Region 區域 : 
    Min Region Size : 區域最小尺寸,單位體素
                      regionMinSize = sqrt(regionMinArea)
    Merged Region Size : 合並區域尺寸,當一個區域小於該尺寸時,如果可以,則會被合並進一些大的區域。單位體素
                         regionMergeSize = sqrt(regionMergeArea)
Partitioning 分割區域的算法 : 
    Watershed : 分水嶺算法,默認是用這個
    Monotone : 單調
    Layers : 按層次
Filtering 篩選,即要剔除的選項 : 
    Low Hanging Obstacles : 低掛障礙物
    Ledge Spans : 壁架
    Walkable Low Height Spans : 高度較低的區間
Polygonization 多邊形 : 
    Max Edge Length : 邊最大長度,單位米
    Max Edge Error : 邊最大誤差,單位體素
    Verts Per Poly : 每個多邊形的最大頂點數
DetailMesh 詳細Mesh數據設置 : 
    Sample Distance : Detail sample 的長度,單位體素
    Max Sample Error : Detail sample 的最大誤差,單位體素高度
Keep Itermediate Results : 是否保持中間結果
Build All Tiles : 編譯所有的tiles
Tiling : 
    Tile Size : tile邊長,單位體素
    Tile Cache : tile緩存
Draw : 顯示方式,很有用。 從原始幾何體到導航網格,可以看到各個階段的結果。

CritterAI 的一些參數
參考CritterAI插件CritterAI與Recast Navigation尋路

minTraversableHeight : 最低可通過高度,設定從底部邊界到頂部邊界之間的最低高度,該高度為模型可通過的高度. 
                       設定值的大小至少得是cellHeight的2倍
maxTraversableStep : 可跨越不同地形時的高度,設定像是從普通平面移動到樓梯這樣的地形是否可通過的高度閥值. 
                     值設定必須大於cellHeight的2倍
maxTraversableSlope : 最大可通過的斜坡的傾斜度
clipLedges : 邊緣突出部分是否可以行走
traversableAreaBorderSize : 可行走區域與阻擋物之前的距離大小. 值設定必須大於cellSize的2倍
smoothingThreshold : 當產生用於表示派生區域的距離場時,會被使用該值
useConservativeExpansion : 是否應用一些算法來避免產生殘缺的區域
minUnconnectedRegionSize : 最小的無法被連接的區域(這里的區域指的是在網格生成之前,某些要與其他區域連接的區域)
maxEdgeLength : 指示網格邊界的多邊形最大的邊
edgeMaxDeviation : 網格邊界與原始集合圖形的偏離量
maxVertsPerPoly : >= 3, 每個多邊形的最大頂點數
contourSampleDistance : 設置采樣距離,類似游戲中的凹凸貼圖類似概念,用於NavMesh過程中的Generate Detailed Mesh,
                        匹配原始集合圖形表面的網格(利用生成更加精細的三角形保證網格來貼合那些凹凸不平的地表).
                        當值在0.9以下時會關閉這個特性.
contourMaxDeviation : 最大的采樣偏移距離,最好和contourSampleDistance結合起來看,其效果的精確度受到contourSampleDistance的影響. 
                      為0時,這個特性選項無效,在實際使用時發現在這個值越接近0,其生成的網格就越偏離原始圖形. 

2.2.3 Tools

Test Navmesh : 可以做一些測試,甚至可以自己改源碼添加接口,用來測試一些功能
    Pathfind Follow : 虛線
    Pathfind Straight : 直線
        Vertices at crossings : 選項,顯示路徑上的點
            None 
            Area 
            All 
    Pathfind Sliced : 切片
    Distance to Wall : 顯示起點到最近牆壁的距離
    Raycast : 起點往終點打一條射線,遇到障礙物停下
    Find Polys in Circle : 在以起點為中心,起點到終點為半徑的圓內,找出所有多邊形
    Find Polys in Shape : 在長方形內,找出所有多邊形
    Find Local Neighbourhood : 找出起點周圍的多邊形
    Set Random Start : 隨機設置起點
    Set Random End : 隨機設置終點
    Make Random Points : 隨機選一些點
    Make Random Points Around : 在以起點為圓心的一個圓內,按權重找一些多邊形,然后在這些多邊形上找一些點。
                                注,這些點可能不在圓內 (這個有點坑,游戲里大概率也會用到這個接口,
                                即想在圓內隨機一個點,但有可能隨機出的點不在圓內)
    Include Flags : 地形篩選
    Exclude Flags 
        Walk 
        Swim 
        Door 
        Jump 

Prune Navmesh 

Create Off-Mesh Connections 

Create Convex Volumes 

Create Crowds 

3 recast navigation 源碼分析

參考Steve Pratt的文檔,建議自己去看看,文檔詳細全面。
主要三個模塊:

  • Recast : 創建網格數據,Detour的前置工作
  • Detour : 用Recast生成的數據,創建、操作和查詢導航網格
  • Crowd : 實現了局部轉向和動態避障功能

3.1 Recast

構建導航網格數據有很多種方法,其中一種比較簡單的做法是:
    1. 預處理輸入進去的三角形網格
    2. 構建一個實心高度場rcHeightfield
    3. 構建一個緊湊高度場rcCompactHeightfield
    4. 構建一個輪廓線集合rcContourSet
    5. 構建凸多邊形rcPolyMesh
    6. 構建詳細數據rcPolyMeshDetail
    7. 用rcPolyMesh 和 rcPolyMeshDetail 構建出適用於Detour的導航網格tile
主要類的生命周期處理:
    1. 用Recast allocator分配對象 (如 rcAllocHeightfield)
    2. 初始化或構建對象 (如 rcCreateHeightfield)
    3. 根據需求更新對象 (如 rcRasterizeTriangles)
    4. 使用該對象
    5. 用Recast allocator釋放對象 (如 rcFreeHeightField)

3.2 Detour

3.3 Crowd

3.4 Recast Demo源碼

主要邏輯在recastnavigation\RecastDemo\Source\Sample_TileMesh.cpp Sample_TileMesh::handleBuild()  

4 如何用到自己項目里

源碼的DebugUtils, Detour, DetourCrowd, DetourTileCache, Recast文件夾加到項目里去,可以都打成庫,然后自己封裝一下外層接口。
關卡構建數據要用到DebugUtils, Recast, Detour。 游戲運行時只要用到Detour。


參考

recastnavigations github源碼
Recast Navigation文檔 by Steve Pratt
CritterAI 官方文檔 (基於RecastNavigation的一個尋路插件)
Suppor Navmesh Generation
谷阿莫帶你十分鍾看完 NavMesh 生成算法
關於NavMesh,我所知道的
從零開始學習導航網格#2 編譯RecastNavigation
[Unity3d手游開發筆記]初識RecastNavmesh
navmesh 生成網格信息
服務器3D場景建模(九):RecastNavigation之Detour數據結構
RecastNavigation-理解高度場
NavMesh生成原理


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM