NavMesh生成研究(一):体素化过程

本文详细介绍NavMesh生成过程中关键步骤——体素化。通过创建实心高度域,利用源网格信息生成占据空间的实心体素区间,并进行初步过滤,标记可行走区域。

本文翻译自:http://critterai.org/projects/nmgen_study/voxelization.html

NMGen是一个开源项目,包括Java版的recast静态网格生成代码,以及详细介绍生成过程的文章。因为在阅读过程中觉得对理解recast原理非常有用,所以决定将其翻译在自己blog上。

原blog上完整的目录包括:

其中第一篇第二篇已经由游蓝海做了翻译。这里从第四篇开始,分步骤详细讲述NavMesh的生成过程。翻译时力求忠实于原意,且尽量通俗易懂。译文如下:

概述

构造导航网格的第一步是使用体素化(voxelization)创建实心高度域(solid heightfield)。

构造类: SolidHeightfieldBuilder
数据类: SolidHeightfield

如果你需要回忆体素化的执行过程,请回到总体概述

创建实心高度域

当我们创建了源网格(source mesh)的AABB包围盒和容纳体素信息的实心高度域后,为每个源网格中的多边形执行下列操作:

确定多边形在高度域格子上的投影(footprint)——也就是多边形的AABB包围盒在2D坐标系下的投影。因为求取多边形投影覆盖的格子需要交集测试,这样做的好处是可以降低交集测试的数量。

这里写图片描述

遍历投影覆盖的所有高度域格子列(grid column),并求出源多边形与列相交的比例。如果出现一次相交,那么得到一个新的“裁剪过的”(clipped)多边形。然后确定这个多边形的最低和最高的高度。这就代表着格子列被源多边形占据的比例。

这里写图片描述

我们基于以下信息来为高度域添加区间(span):

  • 与多边形有交集的格子列
  • 裁剪得到的多边形的最低和最高高度范围(格子列被占据的比例)
  • 裁剪多边形的表面是否可行走(traversable)

其中最后一条信息取决于源多边形在y轴的倾斜度(slope)和配置的maxTraversableSlope属性值。如果前者小于后者(例如45度),那么表面可行走。

当新的区间数据添加到高度域时,会做如下事情:

如果新的区间不与任何现存的区间相交,那么创建一个新的区间。否则合并两个区间。

当两个区间合并时,必须验证合并后的区间是否可经过。可行走标志(traversable flag)只应用在区间的上表面。如果设置了该标志,那么就意味着区间的顶端多边形有较低的倾斜度,因此可行走。

如果新区间的顶端高于要合并到的区间顶端,那么将新区间的可行走标志应用到合并后的区间上。

如果新区间的顶端低于要合并到的区间顶端,那么我们不用关心新区间的可行走标志,直接丢弃。

如果新区间的顶端与要合并到的区间高度一致,那么只要两者中任何一个可行走,那么合并后的区间也是可行走的。

这里写图片描述

更多的高度域区间标志

技术上来说,源网格的体素化已经完成,而且高度域已包含占据空间的实心体素区间。区间也有标志代表顶端表面是否可行走。但是这个标志的设置只考虑了与区间相交的多边形的倾斜度。现在是时候做更多的过滤了:从一些区间上移除可行走标志。

两种类型的过滤:

首先,当区间上方有非常近的障碍物时,它的顶端表面也不可行走。想象地板上的一张桌子。虽然桌子下面的地板是平坦的,但仍然不可行走(因为容纳的高度不够)。

这里写图片描述

一个可选择的过滤与凸起(ledge)检测有关。如果从区间的顶端到相邻的区间下降的距离超过了一定阈值,那么这个区间被认为是个凸起,也不可行走。

这里写图片描述

目前的进展

在这一步结尾,我们构造了一个代表源网格占据区域的高度域。执行初步的过滤后,占据区域的顶端表面被标记为是否可行走。

03-27
<think>嗯,用户想了解NavMesh的相关概念或实现方法,特别是在游戏开发和路径规划中的应用。首先,我需要根据用户提供的引用资料来整理信息。系统级指令要求使用中文回答,生成相关问题,并正确引用资料。 首先,NavMesh的基本概念。引用1提到NavMesh是用于寻路的重要技术,基本概念包括多边形网格、可行走区域、连接性等。这里需要分点解释每个概念,确保用词准确。 然后是生成过程。引用1和引用4提到了生成步骤,比如场景预处理、体素化、区域划分、生成多边形、连接区域等。要详细说明每个步骤的作用,比如体素化处理障碍物,区域划分如何标记可行走区域。 优势和局限性部分,引用1和2指出NavMesh的高效性、动态更新能力和内存优化,但动态环境更新成本高,复杂地形精度有限。需要对比传统方法,比如栅格法,说明NavMesh的优势。 应用场景方面,引用1、3、4提到了游戏开发中的NPC寻路、动态地图生成,以及机器人路径规划。需要分游戏和机器人两个领域来阐述,并提到生态项目如Unity的NavMesh组件和第三方插件。 实现方法部分,引用4提到CritterAI的空间分区技术和算法优化,需要解释A*算法和局部避障算法的结合,以及动态更新的策略,比如增量式更新或区域重生成生成的问题要围绕用户可能关心的点,比如生成步骤、动态更新、对比其他方法、机器人应用、开源项目等。确保每个问题都能在提供的资料中找到依据,并且问题具有实际意义,帮助用户深入理解。 还要注意引用格式,每个引用末尾自然添加标识,比如[^1]。避免直接复制引用内容,而是用自己的话总结,同时保持准确性。检查LaTeX格式是否正确,但用户问题中没有数学公式,可能不需要使用。最后,回答结构要清晰,分点说明,便于用户理解。</think>### NavMesh 实现与应用详解 #### 、基本概念 NavMesh导航网格)是种通过多边形网格描述可行走区域的寻路技术。其核心思想是将复杂场景简化为连通的平面多边形集合,角色可在这些多边形上移动。关键概念包括: 1. **多边形网格**:将场景划分为凸多边形,避免路径拐角问题。 2. **可行走区域**:标记角色可移动的范围(如地面、平台)。 3. **连接性**:相邻多边形的共享边定义可行走路径。 #### 二、生成过程 1. **场景预处理**:剔除不可行走物体(如装饰物) 2. **体素化(Voxelization)**:将3D场景转为2D网格,处理障碍物高度差 3. **区域划分**:用种子填充算法标记可行走区域 4. **生成多边形**:将相邻网格合并为凸多边形 5. **连接区域**:建立跨区域跳转点(如楼梯连接层) 示例代码(伪代码): ```python def build_navmesh(scene): voxels = voxelize(scene) regions = flood_fill(voxels) polygons = merge_cells(regions) links = create_links(polygons) return NavMesh(polygons, links) ``` #### 三、技术优势 1. **路径质量高**:支持任意形状路径,避免栅格法的锯齿路线 2. **动态更新**:CritterAI等方案支持运行时更新网格[^4] 3. **内存优化**:相比栅格法减少80%存储空间 #### 四、实现要点 1. **空间分区技术**:采用BSP树加速碰撞检测[^4] 2. **路径算法**:A*算法与局部避障算法结合 3. **动态更新策略**: - 增量式更新:局部网格生成[^2] - 连接性修正:更新受影响区域的相邻关系[^4] #### 五、应用场景 | 领域 | 典型应用 | 案例特性 | |---------------|-----------------------------------|------------------------------| | 游戏开发 | NPC自动寻路 | 支持动态地图更新[^2] | | | 战术AI路径规划 | 结合掩体系统实现战术移动 | | 机器人 | 仓库AGV调度 | 处理复杂货架布局 | | | 无人机避障 | 3D多层导航网格 | #### 六、开发工具 1. **Unity NavMesh**:内置组件支持自动烘焙 2. **RecastNavigation**:开源方案支持复杂地形 3. **CritterAI**:适用于动态环境的高性能方案[^4]
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值