图解NavMesh寻路中的漏斗算法

NavMesh是普遍使用的一种寻路技术,将地图中可走的部分生成连续的多边形/三角形网格,寻路在网格中进行,主要包含两步:一、根据网格的邻接信息构造图,使用A*之类的寻路算法计算出从起点到重点须要走过的多边形/三角形集合;二、使用漏斗算法/拉绳子算法,将多边形列表转换为一条最优的路店。本文主要讲一下对于三角形列表的漏斗算法原理。算法

诸位读者若是搜索过网络,会发现有一年GDC有人讲了这个算法,也有几篇博客翻译了这个GDC的演讲slides,但多半都是仅仅翻译一遍slides的水平,没有真的把算法说明白,致使笔者在实现这个算法的时候遇到了很大的困难,好在最后仍是弄懂了。网络

 

阅读本文须要必定的前置知识,您须要知道NavMesh及其对应的三角形网格,以及单位在NavMesh中寻路的三角形列表中间结果。ide

 

算法结果

如图所示,假定左边的三角形列表是从寻路算法生成的从起点到终点须要通过的三角形,两个蓝色圆点分别是起点和重点;右边绿色的粗线就是算法的结果,是从起点到终点须要通过的最短路径。翻译

image



算法过程

  • 首先计算出三角形列表中的邻接边列表,所谓邻接边就是两个三角形公用的边,而后从起点开始,构造到第一条邻接边的漏斗,算法正式开始。

黄色的边均为邻接边,两条绿色的边为初始的漏斗,姑且约定两条“漏斗边”的“起点”为蓝色圆点,方便后文的描述3d

image

  • 将两条漏斗边的终点移动到下一条邻接边,对于途中的状况,左边的边没有动(但逻辑上算移动了),右边的边向内收紧了。

分别考虑两条边的角度变化,当漏斗变窄(或不变化)时,本次移动是有效的,不然须要对那条边回退操做,对于图中状况,移动是有效的blog

可见图中的漏斗变窄了get

image

  • 继续将漏斗边的终点移动到下一条邻接边,漏斗继续收紧,移动有效,以后的两步操做都和上图状况相同

imageimage

  • 下一步操做出现了第一种特殊状况,漏斗边终点移动到下一条邻接边时,漏斗口的角度变为了负数(原来右边漏斗边转到了左边去),这种状况下,被盖过去的那条边的终点就成为告终果中的第一个点。

同时,将漏斗起点移动到该点,以当前漏斗起点所在三角形的出邻接边构造漏斗,继续算法博客

imageimage

  • 使用以前描述的规则继续收紧漏斗口

imageimageimage

  • 继续移动漏斗,这一次会发现左边的漏斗边没有移动,而右边的漏斗边会使漏斗口变大,右边的移动是无效的。此次移动只有左边发生了移动(虽然起点和终点同样)

image

  • 下面是算法的结束状况,算法已经移动到了最后一条邻接边,可是从如今的漏斗底直接连一条线到终点确定是不可行的。随后咱们以终点一个点,看成一条两条端点相同的边。用它继续前进漏斗口。

右边的漏斗边若是移动,会使漏斗口变大,所以不移动,左边的漏斗边移动,会盖过右边的漏斗边,所以右边的漏斗边终点成为告终果中的另外一个点。it

image

  • 一样,以该点所在三角形的出邻接边从新构造漏斗,继续算法,很快就会发现漏斗口到终点,收到了最小,算法结束。

imageimage

相关文章
相关标签/搜索