圖解NavMesh尋路中的漏斗算法

NavMesh是普遍使用的一種尋路技術,將地圖中可走的部分生成連續的多邊形/三角形網格,尋路在網格中進行,主要包含兩步:一、根據網格的鄰接信息構造圖,使用A*之類的尋路算法計算出從起點到重點須要走過的多邊形/三角形集合;二、使用漏斗算法/拉繩子算法,將多邊形列表轉換爲一條最優的路店。本文主要講一下對於三角形列表的漏斗算法原理。算法

諸位讀者若是搜索過網絡,會發現有一年GDC有人講了這個算法,也有幾篇博客翻譯了這個GDC的演講slides,但多半都是僅僅翻譯一遍slides的水平,沒有真的把算法說明白,致使筆者在實現這個算法的時候遇到了很大的困難,好在最後仍是弄懂了。網絡

 

閱讀本文須要必定的前置知識,您須要知道NavMesh及其對應的三角形網格,以及單位在NavMesh中尋路的三角形列表中間結果。ide

 

算法結果

如圖所示,假定左邊的三角形列表是從尋路算法生成的從起點到終點須要通過的三角形,兩個藍色圓點分別是起點和重點;右邊綠色的粗線就是算法的結果,是從起點到終點須要通過的最短路徑。翻譯

image



算法過程

  • 首先計算出三角形列表中的鄰接邊列表,所謂鄰接邊就是兩個三角形公用的邊,而後從起點開始,構造到第一條鄰接邊的漏斗,算法正式開始。

黃色的邊均爲鄰接邊,兩條綠色的邊爲初始的漏斗,姑且約定兩條「漏斗邊」的「起點」爲藍色圓點,方便後文的描述3d

image

  • 將兩條漏斗邊的終點移動到下一條鄰接邊,對於途中的狀況,左邊的邊沒有動(但邏輯上算移動了),右邊的邊向內收緊了。

分別考慮兩條邊的角度變化,當漏斗變窄(或不變化)時,本次移動是有效的,不然須要對那條邊回退操做,對於圖中狀況,移動是有效的blog

可見圖中的漏斗變窄了get

image

  • 繼續將漏斗邊的終點移動到下一條鄰接邊,漏斗繼續收緊,移動有效,以後的兩步操做都和上圖狀況相同

imageimage

  • 下一步操做出現了第一種特殊狀況,漏斗邊終點移動到下一條鄰接邊時,漏斗口的角度變爲了負數(原來右邊漏斗邊轉到了左邊去),這種狀況下,被蓋過去的那條邊的終點就成爲告終果中的第一個點。

同時,將漏斗起點移動到該點,以當前漏斗起點所在三角形的出鄰接邊構造漏斗,繼續算法博客

imageimage

  • 使用以前描述的規則繼續收緊漏斗口

imageimageimage

  • 繼續移動漏斗,這一次會發現左邊的漏斗邊沒有移動,而右邊的漏斗邊會使漏斗口變大,右邊的移動是無效的。此次移動只有左邊發生了移動(雖然起點和終點同樣)

image

  • 下面是算法的結束狀況,算法已經移動到了最後一條鄰接邊,可是從如今的漏斗底直接連一條線到終點確定是不可行的。隨後咱們以終點一個點,看成一條兩條端點相同的邊。用它繼續前進漏斗口。

右邊的漏斗邊若是移動,會使漏斗口變大,所以不移動,左邊的漏斗邊移動,會蓋過右邊的漏斗邊,所以右邊的漏斗邊終點成爲告終果中的另外一個點。it

image

  • 一樣,以該點所在三角形的出鄰接邊從新構造漏斗,繼續算法,很快就會發現漏斗口到終點,收到了最小,算法結束。

imageimage

相關文章
相關標籤/搜索