导航图和导航网格

概述 

      导航图仍然是一个有用的替代导航网格的方法,而且根据游戏的环境可能会具有一定的优势 。本文讨论了导航图生成的几种方法:从一种基于Delaunay三角网,的自动方法,到衍生于通航区和双三角图形的全自动化方法。

      本文使用了通用的计算几何算法和受到图像处理启发得出的算法(可能作者的意思就是借用一些图形处理的算法)。一个开源计算机视觉库OpenCV([Bradski2008], [OCV]) 中可能可以用于实现这里讨论的基于图像处理技术。

      我们也谈到了分层导航图,带来了很大优化空间的机会

简介:导航网格和导航图

     现在有越来越多中间件处理产品游戏代理的导航我们不打算回顾或者介绍他们,甚至不会提到其中任何一个虽然对于许多典型的场景,他们可以提供坚实解决方案,但是对于很多项目而言,建设一个自定义导航系统任然是唯一选择因此重要的是工程师和设计者要理解(根据需要)应该选择什么技术

      有两种主要方法来为游戏(原文是game levels,感觉翻译为游戏还读得通一点)创造和提供导航信息一种是基于导航网格另一种是采用导航(介绍见的方法来表示[Stout2000导航数据[Snook2000],尤其是导航网格。下图1所示:相同的测试环境下两种方法代表可通过区域的导航数据


图1:导航网格和导航图连接点A到点B时选择的路劲

       游戏中的代理可以用导航网通过一个算法找到从A到达B的路径。我们简单介绍下这个算法:首先,对于出发点A,该算法找到包含A的导航网格三角形Ta,和包含目的地B的导航网格三角形Tb.然后就可以建立一条穿过导航网格(从A到B的)最短的路径,这条路径由从三角形Ta到三角形Tb的一串连接三角形列表L组成。通常这是通过A*算法实现的。

        由于导航三角形组成的任意路径都是有效的,知道列表L就可以让我们用一个分段线性路径连接A到B。因而只要计算出L,就完成了我们的任务,至少粗略完成了。通常需要进一步的修改下路径,因为L看起来太死板了(原文是robotic),这种情况可以从上图中明显看出来。虽然提高路径的美观性是一个迷人的话题,我们不会去深究。

      导航网格经常可以很自然地从碰撞几何图形中生成,可以是通过自动的方式,也可以是手动生成,也可以在运行时再更新,但是这会受到性能限制的挑战,除非我们只同时处理很少部分的网格。

       导航图通过建立二维导航数据来解决这个问题,其中包含技术在很多方面和基于导航网格的技术很相似。导航图基于节点,其中节点并不包含所有的导航面积,只是提供有用的标记作为路标(waypoints);一系列二维图元(圆,四边形等)可以作为导航图中的节点。所有在节点内部的路径都是有效的;而且如果满足限制条件,则从环境中的任意一点到任意节点中的某点的路径(通常是直线)都是有效的,最常见的限制是路径不能与碰撞几何体相交,此外我们需要排除高山,陡坡,和水面(意思就是高山,陡坡,水面不满足条件)。

       经常情况是,沿着这条路径的碰撞检测和其他地形特征限制是非常消耗cpu的。我们可以用阻塞点(blocking primitives)来表示出非导航区域(相当于是用一些点来围起来一块面子,表示这块面积是不能穿过的),然后我们只需要检测是否与这些点围成的图形相交即可。这些阻塞点非常简单,经常是用盒子(面向或轴对齐)或者圆柱体,这样允许对阻塞点进行非常有效率的光线相交测试。注意:导航网格经常不需要额外的阻塞点,因为所有的可导航区域的信息都已经包含在导航网格中。
下图2表示一个列子,其中半透明轴对齐的红色盒子(轮廓是白色,注:定语太多了,都不知道怎么翻译了...)沿着墙,垃圾桶和其他障碍物。导航图有黄绿色的节点,用明亮的黄色边缘连接,相当于图1测试环境的左下角。 (门上锁了,所以没有测试环境的室内连接部分。)

 

图2:阻塞点和导航图

有了导航图和一系列阻塞点,我们可以使用下面的算法构造一个路径:从出发点A开始,我们先知道最近的导航节点Na,所以从A到Na的直线不被阻塞。同样的,我们可以知道离B最近的Nb节点,再利用A*算法我们可以找到一系列连接Na到Nb的节点。下图3是图1中的导航图和阻塞点(淡粉色框)组成。

 

图3:导航图和阻塞点
        导航图相比导航网格,具有一定的优势。首先,导航图中可以很容易地把对象的导航插槽纳入到环境中放置。比如,我们需要一个代理接近门,然后自己以某种方式成功地打开一个门。导航图上的插槽表明门附近想要的位置,可以变成图中的另一个节点,很有可能还有其他一些额外属性(方向,也可能包含一个指示,指示用什么类型的动作来开门)。

 其次,由于导航图不像导航网格一样采用很直接的方式细分几何图形,在层次设计上可以采用非常灵活的方式。节点在层次设计工具中通常作为对象使用,因此,他们比在导航网格中操作三角形(设计师应该关心维护网格的拓扑性质)更容易。通过调整图中的节点位置,设计者可以在环境中引入一些微妙的(和不那么微妙)的理想效果影响路径。

     不用说,手动生成和调整导航图是非常费时间的。另一个缺点是,这些手工制作的图表难以更新,如果在设计过程中地理形状的变化;在游戏运行时想要修改也需要格外小心。综上所述,我们可以得出结论:导航网格比较合适与导航数据需要自动生成的情况;而导航图适合于地形设计者需要且必需手动输入的情况。这提出了简化手动创建和维护导航图复杂度的必要性。
手动生成导航图和确认
可以有很多种技术生成导航图。
导航图的最优密度
一方面导航图要足够密集,才能在环境中提供导航节点访问每个有效的位置。另一方面过于密集后,首先图很难手动建立,也会导致更长的A*算法的计算时间。它也容易导致机器人式的代理:他们往往坚持通过节点而不走明显的捷径。令人惊讶的是一个稀疏图也可能导致运行时计算量得增加或者使算法失效,如果它没有考虑到以下情况见图4。

图4:通过A*算法选到了在墙另一边的最近节点
 图4中,代理放在位置A处,当寻找最近节点时会选择红色标记的点。显然这是错误的开始节点,因此必须要健全的通过射线检测代理点和阻塞点之间,防止代理在走向目的地时穿进墙。如果开始选择的节点被检测剔除,则需要重新找一个近而且可以直接到达的节点,这可能也是非常费时间的,需要视环境复杂度情况而定。

因此,可以使用离线的程序验证的导航图是否存在上述这种问题,而不是依赖于运行时的代码去发现并恢复这种节点过少的情况(按原文实在太难翻译了,从下面开始,我还是按自己的理解翻译吧,奔放点,有错误的地方请大家不吝指正 )。

图5:节点之间的连接:左图的意思是代理可能需要特定的位置才能让路径不与阻塞体相交。

右图的意思是:因为两个导航节点之间的边界留的足够宽,所以,无论如何不会发生阻塞。

因此,它不仅是图形的一些边界需要不与障碍物相交,而且在两个相邻节点间更广泛的区域都必须无障碍物,这个区域是由二维圆柱体和圆柱体间外部切线限定的。当手动创建一个导航图时不是很容易达到这个要求。
一个有用的防止代理太靠近墙的技术是由Minkowski总结出来,且被广泛用于机器人里面。其主要的思想我简要叙述如下:假设代理有一个球体可以包围代理,设其半径为R。显然我们希望代理离墙至少R的距离远,假设原来的阻塞体是严格按照大小绘制的,我们只需要沿着障碍物边界,把边界膨胀R(实在不知怎么叙述了,思想很简单,可以看图)。这个膨胀的过程最好是在开发路线时自动生成(意思就是直接放大障碍物的尺寸),也可以在程序运行时处理。下图说明了这个技术:

 

图6:淡红色的膨胀障碍物覆盖原来的障碍物(暗红)和导航图

总结,最好避免全手动的生成导航图,因为非常容易犯错和耗时。我们应该找一个全自动生成的技术或者有时综合利用手动和自动的方法。从这个角度看,这是制约手动生成导航图的主要制约因素。

未完待续,原文地址:http://www.gamedev.net/page/reference/index.html/_/reference/programming/artificial-intelligence/navigation-graph-generation-r2805

 


你可能感兴趣的:(AI)