Recast-入门

Recast-Navigation 在做3d游戏的时候,用于做导航的在Unity3D、Unreal Engine都可以使用。当前使用 unreal 4.25

1. Recast工程介绍

RecastNavigation 是一个的导航寻路工具集,它包括了几个子集:

Recast:负责根据提供的模型生成导航网格。
Detour:利用导航网格做寻路操作。这里的导航网格可以是 Recast 生成的,也可以是其他工具生成的。
DetourCrowd:提供了群体寻路行为的功能。
Recast Demo:一个很完善的 Demo,基本上将 Recast 、 Detour 提供的功能都很好地展现了出来。弄懂了这个 Demo 的功能,基本也就了解了 RecastNavigation 究竟可以干什么事。

Recast先从几何体构造素模,然后在其上投射导航网格。此过程包括三个步骤:

  1. 创建素模(voxel mold);

通过将三角形栅格化为多层高度场,从输入三角形网格构建体素模具。然后将一些简单的滤镜应用到模具上,以修剪角色无法移动的位置。

  1. 将素模划分成简单区域(region);

模具描述的可行走区域分为简单的2D覆盖区域。 生成的区域仅具有不重叠的轮廓,这大大简化了过程的最后一步。

  1. 将区域转换成多边形(polygons);

通过首先跟踪边界,然后对其进行简化,可以将导航多边形从区域中剥离。 最终将生成的多边形转换为凸多边形,这使它们非常适合该级的寻路和空间推理。

注:凸多边形的内角均小于或等于180°,边数为n(n属于Z且n大于2)的凸多边形内角和为(n-2)×180°,但任意凸多边形外角和均为360°,并可通过反证法证明凸多边形内角中锐角的个数不能多于3个。

尝试将unreal engine 里面的地图导出成detour能使用的导航网格:

再 UNREAL ENGINE 里面地图是*.umap文件。我们用UE打开之后,在菜单栏里面操作: Windows->导出NavMesh。这个步骤将会生成一个*.obj文件。这种文件其实是一种文本文件,描述了3D对象模型信息。Unity3D也一样能导出这样的文件。此过程将会生成某个尺寸的模型文件。

我们移植了一些Detour的代码,编写了一个程序 RecastCreator。这个程序能将*.obj文件导出成为一个binary文件。后续就直接使用binary文件来做导航操作。

PS D:\work\trunk\refer\recastnavigation\RecastDemo\Bin\Meshes> .\RecastCreator.exe -cfg -out t3.obj t3.region
----- Create Cfg -----
cellsize = 0.30
cellheight = 0.20
agentheight = 2
agentradius = 0.6
agentmaxclimb = 0.9
agentmaxslope = 45
regionminsize = 8
regionmergesize = 20
edgemaxlen = 12
edgemaxerror = 1.3
vertsperpoly = 6
detailsampledist = 6
detailsamplemaxerror = 1
partitiontype = 1
tilesize = 0
----- End -----
PS D:\work\trunk\refer\recastnavigation\RecastDemo\Bin\Meshes> .\RecastCreator.exe -out t3.obj t3.region
----- Create Bin -----
Building navigation:- 1028 x 1135 cells- 525.2K verts, 306.2K tris
Build Times
- Rasterize:    176.99ms        (24.5%)
- Build Compact:        39.54ms (5.5%)
- Filter Border:        29.55ms (4.1%)
- Filter Walkable:      5.15ms  (0.7%)
- Erode Area:   19.18ms (2.7%)
- Median Area:  0.00ms  (0.0%)
- Mark Box Area:        0.00ms  (0.0%)
- Mark Convex Area:     0.00ms  (0.0%)
- Mark Cylinder Area:   0.00ms  (0.0%)
- Build Distance Field: 29.01ms (4.0%)- Distance: 19.88ms (2.7%)- Blur:     8.95ms  (1.2%)
- Build Regions:        105.62ms        (14.6%)- Watershed:        97.48ms (13.5%)- Expand: 35.47ms (4.9%)- Find Basins:    2.93ms  (0.4%)- Filter:   6.76ms  (0.9%)
- Build Layers: 0.00ms  (0.0%)
- Build Contours:       13.14ms (1.8%)- Trace:    8.87ms  (1.2%)- Simplify: 2.00ms  (0.3%)
- Build Polymesh:       6.09ms  (0.8%)
- Build Polymesh Detail:        286.67ms        (39.6%)
- Merge Polymeshes:     0.00ms  (0.0%)
- Merge Polymesh Details:       0.00ms  (0.0%)
=== TOTAL:      723.73ms
>> Polymesh: 2552 vertices  1153 polygons----- End -----

2.环境搭建

2.1.编译recastnavigation

工具名称 版本信息
visualstudio2019 16.8.3
CMake 3.19.0-rc1
premake 5.0

2.1.1.下载地址

名称 下载地址
SDL SDL2-devel-2.0.14-VC.zip
premake premake.github

2.1.2.准备好SDL2的dll

将下载的SDL2.dll文件放入到子目录中:

recastnavigation\RecastDemo\Contrib\SDL\lib\x86\SDL2.dll

使用CMake将SDL2编译出来。在windows里面,我这里都是使用32位编译的。

配置下列的环境变量:

变量名 位置
SDL_PATH D:\work\trunk\refer\recastnavigation\RecastDemo\Contrib\SDL
SDL2_INCLUDE_DIR D:\work\trunk\refer\SDL\SDL2-2.0.14\SDL2-2.0.14\include
SDL2_LIBRARY D:\work\trunk\refer\SDL\SDL2-2.0.14\SDL2-2.0.14\build\Debug
SDL2_SDLMAIN_LIBRARY D:\work\trunk\refer\SDL\SDL2-2.0.14\SDL2-2.0.14\build\Debug

2.1.3.使用premake5生成工程文件

这个默认生成的是win32位的

D:\work\trunk\refer\recastnavigation\RecastDemo>"premake5" vs2019
Building configurations...
Running action 'vs2019'...
Generated Build/vs2019/recastnavigation.sln...
Generated Build/vs2019/DebugUtils.vcxproj...
Generated Build/vs2019/DebugUtils.vcxproj.filters...
Generated Build/vs2019/Detour.vcxproj...
Generated Build/vs2019/Detour.vcxproj.filters...
Generated Build/vs2019/DetourCrowd.vcxproj...
Generated Build/vs2019/DetourCrowd.vcxproj.filters...
Generated Build/vs2019/DetourTileCache.vcxproj...
Generated Build/vs2019/DetourTileCache.vcxproj.filters...
Generated Build/vs2019/Recast.vcxproj...
Generated Build/vs2019/Recast.vcxproj.filters...
Generated Build/vs2019/RecastDemo.vcxproj...
Generated Build/vs2019/RecastDemo.vcxproj.user...
Generated Build/vs2019/RecastDemo.vcxproj.filters...
Generated Build/vs2019/Tests.vcxproj...
Generated Build/vs2019/Tests.vcxproj.user...
Generated Build/vs2019/Tests.vcxproj.filters...
Done (225ms).

工程属性->生成事件->命令行;将下面部分去掉

1>找不到文件 - SDL2.dll
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(153,5): error MSB3073: 命令“IF EXIST "..\..\Contrib\SDL\lib\x86\SDL2.dll"\ (xcopy /Q /E /Y /I "..\..\Contrib\SDL\lib\x86\SDL2.dll" "..\..\Bin" > nul) ELSE (xcopy /Q /Y /I "..\..\Contrib\SDL\lib\x86\SDL2.dll" "..\..\Bin" > nul)
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(153,5): error MSB3073: :VCEnd”已退出,代码为 4。
1>已完成生成项目“RecastDemo.vcxproj”的操作 - 失败。IF EXIST "..\..\Contrib\SDL\lib\x86\SDL2.dll"\ (xcopy /Q /E /Y /I "..\..\Contrib\SDL\lib\x86\SDL2.dll" "..\..\Bin" > nul) ELSE (xcopy /Q /Y /I "..\..\Contrib\SDL\lib\x86\SDL2.dll" "..\..\Bin" > nul)

自己手动将编译出来的文件复制过去。

RecastDemo的效果图:

加载一个obj文件:

将obj文件的导航网格生成出来:

生成了之后,地图的颜色将会变化,只需要点击"Build"。有导航网格,才能去测试导航功能。

测试导航功能:

在地图上选择开始结束点;“shift+鼠标左键”

3.Recast 导航网格类型

recastnavigation中提供了3种模式的导航网格:

3.1.SoloMesh

其中SoloMesh模式是静态的导航网格,即对场景build一次之后,将导航网格缓存起来供寻路使用,后续不再允许场景的导航信息发生变化。

文件头:

static const int NAVMESHSET_MAGIC = 'M'<<24 | 'S'<<16 | 'E'<<8 | 'T'; //'MSET';
struct NavMeshSetHeader
{uint32_t magic;uint32_t version;uint32_t numTiles;dtNavMeshParams params;
};// Store header.NavMeshSetHeader header;header.magic = NAVMESHSET_MAGIC;header.version = NAVMESHSET_VERSION;header.numTiles = 0;

3.2.TileMesh

TileMesh也是静态的导航网格,只是与SoloMesh相比它按tile来处理地图,算是介于SoloMesh和TempObstacles之间的一种模式

// 文件名:all_tiles_navmesh.bin
// 文件头: TESM
static const int NAVMESHSET_MAGIC = 'M'<<24 | 'S'<<16 | 'E'<<8 | 'T'; //'MSET';// 加载文件失败:
dtStatus addTileStatus = m_tileCache->addTile(data, tileHeader.dataSize, DT_COMPRESSEDTILE_FREE_DATA, &tile);
inline bool dtStatusFailed(dtStatus status)
static const unsigned int DT_FAILURE = 1u << 31;            // Operation failed.
static const unsigned int DT_WRONG_MAGIC = 1 << 0;        // Input data is not recognized.if (header->magic != DT_TILECACHE_MAGIC)return DT_FAILURE | DT_WRONG_MAGIC;static const int DT_TILECACHE_MAGIC = 'D'<<24 | 'T'<<16 | 'L'<<8 | 'R'; ///< 'DTLR';Sample::saveAll("all_tiles_navmesh.bin", m_navMesh);

3.3.TempObstacles

TempObstacles模式可以支持向场景中动态添加或移除预设形状的阻挡物,导航网格也会随之更新(不过只支持添加阻挡物,而不支持添加新的可行走区域)在处理动态阻挡时,由于单个阻挡对地图的影响区域是有限的,所以会采用将地图切割成多个固定大小的tile,以tile为单位进行网格的生成。这样在添加或移除阻挡时,只需要处理与阻挡相交的tile,而不需要处理整个地图。

static const int TILECACHESET_MAGIC = 'T' << 24 | 'S' << 16 | 'E' << 8 | 'T'; //'TSET';

参考NavMeshDemo源码

3.4.导出Mesh的源码分析

参考官方的代码-RecastDemo部分,在右边的上部,"Sample"中下拉菜单中选择的三类(Solo Mesh、Tile Mesh、Temp Obstacles)导出方式都看明白。

3种导出方式:

Sample* createSolo() { return new Sample_SoloMesh(); }
Sample* createTile() { return new Sample_TileMesh(); }
Sample* createTempObstacle() { return new Sample_TempObstacles(); }

"Build"按钮将会调用

if (imguiButton("Build"))
{ctx.resetLog();if (!sample->handleBuild()){showLog = true;logScroll = 0;}ctx.dumpLog("Build log %s:", meshName.c_str());// Clear test.delete test;test = 0;
}

"Save"按钮将会把生成的网格存储到

类型 文件 大小
Solo solo_navmesh.bin 240kb
Tile all_tiles_navmesh.bin 479kb
TempObstacle all_tiles_tilecache.bin 479kb

导出时候需要设置的参数:

变量 基本信息 备注
cellsize 方块尺寸 0.3
cellheight 方块高度 0.2
agentheight walkableHeight = agentheight/ cellheight 2
agentradius walkableClimb = agentradius/ cellheight 0.6
agentmaxclimb walkableRadius = agentmaxclimb/ cellheight 0.9
agentmaxslope walkableSlopeAngle = agentmaxslope 45
regionminsize minRegionArea = regionminsize*regionminsize 8
regionmergesize mergeRegionArea = regionmergesize*regionmergesize 20
edgemaxlen maxEdgeLen = edgemaxlen/cellheight 12
edgemaxerror maxSimplificationError = edgemaxerror 1.3
vertsperpoly maxVertsPerPoly 6
detailsampledist detailSampleDist = detailsampledist < 0.9f ? 0 : cellsize * detailsampledist; 6
detailsamplemaxerror detailSampleMaxError = cellheight * detailsamplemaxerror 1
partitiontype 1
tilesize 48

RecastNavigation-rcConfig文档

cellsize

方块尺寸(x,z平面上),和平面有关系。较低的值将产生较高质量的导航,但是图形扫描较慢。在文档里面记作 [vx]

cellheight

方块高度(y高程),和爬坡有关系。记录计算攀爬仰角,攀爬的高度,计算边缘都需要这个。官方文档里面记作 [vy]

agentheight


minRegionArea

最小孤岛所容纳的cell数目;

任意区域小于指定的数目,将会标记成无法行走。这个东西通常用于去删除无用几何体,比如桌子的顶部,盒子的顶部等等。

值域:[Limit: >=0] 作用域:[Units: vx],vx代表平面;

mergeRegionArea

如果有可能性的话,任意区域如果cell的数目小于它,将会被融合到比它大的区域里面。

值域:[Limit: >=0] 作用域:[Units: vx]

edgemaxlen

沿网格边界的轮廓边缘的最大允许长度。 [Limit: >=0] [Units: vx].

这个将会让边缘更加趋于直线。如果想关闭这个功能将值设置成0。

partitiontype

分区方式

Watershed 分水岭方式

enum SamplePartitionType SAMPLE_PARTITION_WATERSHED = 0

Monotone 单调方式

enum SamplePartitionType SAMPLE_PARTITION_MONOTONE = 1

Layers 分层方式

enum SamplePartitionType SAMPLE_PARTITION_LAYERS = 2

原文释义:

 Partition the heightfield so that we can use simple algorithm later to triangulate the walkable areas.There are 3 martitioning methods, each with some pros and cons:1) Watershed partitioning- the classic Recast partitioning- creates the nicest tessellation- usually slowest- partitions the heightfield into nice regions without holes or overlaps- the are some corner cases where this method creates produces holes and overlaps- holes may appear when a small obstacles is close to large open area (triangulation can handle this)- overlaps may occur if you have narrow spiral corridors (i.e stairs), this make triangulation to fail* generally the best choice if you precompute the nacmesh, use this if you have large open areas2) Monotone partioning- fastest- partitions the heightfield into regions without holes and overlaps (guaranteed)- creates long thin polygons, which sometimes causes paths with detours* use this if you want fast navmesh generation3) Layer partitoining- quite fast- partitions the heighfield into non-overlapping regions- relies on the triangulation code to cope with holes (thus slower than monotone partitioning)- produces better triangles than monotone partitioning- does not have the corner cases of watershed partitioning- can be slow and create a bit ugly tessellation (still better than monotone)if you have large open areas with small obstacles (not a problem if you use tiles)* good choice to use for tiled navmesh with medium and small sized tiles

tilesize

每块tile再xz平面上的size。[Limit: >= 0] [Units: vx].

这个值旨在编译出多tile mesh的时候生效(temp obstacles/tiles)。

4.包围盒分类

4.1.AABB

AABB算法的全称是 - axis aligned bounding box (轴对齐-边界盒)AABB 包围盒是与坐标轴对齐的包围盒, 简单性好, 紧密性较差。

4.2.OBB

OBB 包围盒: OBB(oriented bounding box 方向矩形边界框) 碰撞检測方法紧密性是较好的, 可以大大降低參与相交測试的包围盒的数目, 因此整体性能要优于AABB 和包围球, 而且实时性程度较高。

阅读 Export Recast Navigation Data from UE4

Library: ue-recast-detour这个是从 UE 代码中抽取出的 recast detour 库,在 UE 源码的路径下为 Runtime/Navmesh/Detour,主要目的是保证 UE 客户端与外部服务器的验证方法一致。只将solo方式的导航。

其实在UnrealEngine4的源代码中是有一份NavigationSystemNavmesh。github-UE4-Navmesh。可以直接在ue4的引擎代码里面找到动态阻挡相关的逻辑。

参考

  • [1] recastnavigation
  • [2] premake
  • [3] SDL
  • [4] recastdetour手册
  • [5] 游戏的寻路导航 1:导航网格
  • [6] recastNavigation读书笔记1
  • [7] CritterAI
  • [8] B站讲解RecastDemo如何使用
  • [9] 从零开始学习导航网格
  • [10] AABB&OBB包围盒
  • [11] 生成寻路网格的配置
  • [12] 手动创建navmesh
  • [13] navmesh参数
  • [14] ue-navmesh
  • [15] 循迹研究室-Export Recast Navigation

recastnavigation相关推荐

  1. unity三维地图的经纬度如何在二维地图上表示_接入C++版本recastnavigation寻路库到Unity/服务端中...

    前言 因为Unity版本的更新迭代,老版本的A*插件在新版本Unity已经无法正常使用,包括一些运行时代码也已经过时,重新接入要花费很多时间,干脆接入一个新的寻路方案吧. 这里选择的是久负盛名的htt ...

  2. 服务器3D场景建模(六):RecastNavigation介绍

    RecastNavigation RecastNavigation是一款非常强大的寻路系统,被广泛的应用于各大游戏引擎中.如Unreal, Unity等. github网址:https://githu ...

  3. 服务器3D场景建模(九):RecastNavigation之Detour数据结构

    dtNavMesh dtNavMesh是Detour中表达3D场景的数据结构. 作者给的注释为: /// A navigation mesh based on tiles of convex poly ...

  4. RecastNavigation源码阅读之Recast工程

    Recast工程 相关概念 AABB(Axis-aligned bounding box) 高度场(Heightfield) 区间(Span) 紧缩高度场(CompactHeightfield) 紧缩 ...

  5. 从 NavMesh 网格寻路回归到 Grid 网格寻路。

    上一个项目的寻路方案是客户端和服务器都采用了 NavMesh 作为解决方案,当时的那几篇文章(一,二,三)是很多网友留言和后台发消息询问最多的,看来这个方案有着广泛的需求.但因为是商业项目,我无法贴出 ...

  6. 后台寻路系统的大体思路与流程

    总的思路就是: 1, 通过前台unity的navigation的的接口:  获得顶点和三角形集合数据 2, 将前台的mesh数据转换成标准的obj格式数据 3. 强obj mesh数据经过一系列转换和 ...

  7. 将Unity场景以Wavefront Obj格式导出

    原文链接 使用方法请参考原文链接.导出的Obj文件可以作为RecastNavigation的RecastDemo.exe程序的输入文件. 脚本修改如下,支持Unity 5.3.5f1.仅修改了原文链接 ...

  8. 将Unity地形以Wavefront Obj格式导出

    原文链接 使用方法请参考原文链接.导出的Obj文件可以作为RecastNavigation的RecastDemo.exe程序的输入文件. 对于已经创建好的Unity Scene,使用原文链接给出的Ed ...

  9. C++机器学习库整理

    来自谷歌AI的TensorFlow 由 Google 开发的热门深度学习库,它拥有自己的工具.库和社区资源生态系统,使研究人员和开发人员能够轻松构建和部署 ML 支持的应用程序. 官方文档:https ...

最新文章

  1. Hbase写入量大导致region过大无法split问题
  2. SQL游标原理和使用方法
  3. DL:LinearNN(numpy自定义的) solve XOR problem
  4. python进行矩阵计算公式_纯python进行矩阵的相乘运算的方法示例
  5. nginx绑定freenom.com域名
  6. 小程序 WXS响应事件(滚动菜单栏tab吸顶)
  7. 程序员常挂在嘴边的10句话:刚刚还是好的啊!
  8. Python自动化二--jmeter分布式测试,抓包,python语法基本介绍
  9. 和公婆住在一起是什么体验?
  10. 【SpringBoot_ANNOTATIONS】自动装配 02 @Resource @Inject
  11. 灵格斯怎么屏幕取词_灵格斯词霸(Lingoes)基础使用教程
  12. 机房运维——技术文档
  13. SQL查询语句精华大全
  14. Android、Python实现微信运动
  15. Win10客户端 ssh 远程连接 win server 2008 R2服务器
  16. LeetCode 求和问题总结(2sum,3sum,ksum)
  17. 亚马逊美国站UL2849电动自行车标准测试报告
  18. python画猫hellokitty_如何用铅笔画HelloKitty? 原来是这样的
  19. 如何查找重复文件并快速删除,电脑查重复文件的方法
  20. 如何与陌生人交谈的技巧

热门文章

  1. CMD替换WINPE壁纸并实时更新
  2. SVM分类器算法总结应用
  3. MAC使用终端cd定位到指定目录
  4. 如何用xshell上次超过4GB的文件到虚拟机
  5. Part I 空气曲棍球 Chapter4 Adding Color and Shade)
  6. ubuntu控制台访问u盘_解决ubuntu无法挂在u盘的问题
  7. 河南洛阳计算机操作题,洛阳市中招计算机考试Word操作题:比尔盖茨的故事
  8. A103_数据库优化_多机优化
  9. 国产“天价手机”凉凉,还记得8868吗?
  10. 【计算机视觉】基于Python—OpenCV的手势识别详解(一)