0 前言

Recastnavigation是一个游戏AI导航库,像Unity,UE引擎中都集成了这个开源项目, HALO中使用的也是这个开源库。导航最重要的就是为NPC寻路,以及其他的寻路需求。

需要注明的是,这个寻路库虽然厉害。但是他的核心是 平面寻路。也就是重力方向一直朝着 -Y 方向。如果是星球地形,既重力方向朝向球心,在任何一点重力方向都是不同的。那么这个开源库就不能使用了。

1 Recastnavigation 下载与编译

主页: https://github.com/recastnavigation/recastnavigation/tree/main?tab=readme-ov-file

编译: https://github.com/recastnavigation/recastnavigation/blob/main/Docs/_2_BuildingAndIntegrating.md

编译细节

这个项目 Recast and Detour 不依赖其他的一些库,但是 RecastDemo 即可视化的示例是需要SDL2库的,SDL2库可以理解为创建窗口应用程序所需要的库。所以我们需要下载SDL。

同时也需要 premake5 编译工具。

1.1 Windows

SDL2-devel-2.28.2-VC.zip 像这样的文件名的release才可以,不要直接下载 source code

// 成功后的文件夹应该是这个样子。
RecastDemo/Contrib
fastlz
readme-sdl.txt
SDL
stb_truetype.h

●Navigate to the RecastDemo folder and run premake5 vs2022

●Open Build/vs2022/recastnavigation.sln in Visual Studio 2022 or Jetbrains Rider.

●Set RecastDemo as the startup project, build, and run.

2. 代码详解

// Figure out how big the raster voxel grid will be based on the input geometry bounds.
rcCalcGridSize // Voxelize the input geometry
rcAllocHeightfield
rcCreateHeightfield
rcMarkWalkableTriangles
rcRasterizeTriangles // Clean up the voxel data and filter out non-walkable areas.
rcFilterLowHangingWalkableObstacles
rcFilterLedgeSpans
rcFilterWalkableLowHeightSpans // Consolidate the voxel data into a more compact representation
rcAllocCompactHeightfield
rcBuildCompactHeightfield // Further refine the voxel representation
rcErodeWalkableArea
rcBuildDistanceField
rcBuildRegions // Triangulate the navmesh polygons from the voxel data
rcAllocContourSet
rcBuildContours
rcAllocPolyMesh
rcBuildPolyMesh // Package the mesh with additional metadata that's useful at runtime.
rcAllocPolyMeshDetail
rcBuildPolyMeshDetail // Cleanup
rcFreeHeightField
rcFreeCompactHeightfield
rcFreeContourSet

代码详解主要为2个部分。

  1. 数据载入
  2. 高度场建立

2.1 数据载入

首先Sample_SoloMesh::handleBuild()会调用InputGeom::getMesh()

那么Mesh数据从哪里来呢?

  1. InputGeom::loadMesh()
  2. InputGeom::load()
  3. rcMeshLoaderObj::addVertex(float x, float y, float z, int& cap) 其中cap是顶点的内存容量,以存8个顶点为开始,内存短缺后以2倍速度扩大。存储皆为1维数组,顶点与顶点之间的 stride==3
  4. void rcMeshLoaderObj::addTriangle(int a, int b, int c, int& cap)

有了Mesh之后,开始计算xz平面的栅格数量,设置为 *sizeX = &m_cfg.width, *sizeZ = &m_cfg.height。平面边缘,只要占到一半以上的cellSize,就认为是一个cell。

void rcCalcGridSize(const float* minBounds, const float* maxBounds, const float cellSize, int* sizeX, int* sizeZ)
{ // (0, 0.5) + 0.5 -> 0
// [0.5, 0.999) + 0.5 -> 1
*sizeX = (int)((maxBounds[0] - minBounds[0]) / cellSize + 0.5f);
*sizeZ = (int)((maxBounds[2] - minBounds[2]) / cellSize + 0.5f);
}

rcCreateHeightfield(m_ctx, *m_solid, m_cfg.width, m_cfg.height, m_cfg.bmin, m_cfg.bmax, m_cfg.cs, m_cfg.ch)相当于构造函数,初始化高度场信息HeightField or HeightMap

m_triareas = new unsigned char[ntris];角色代理可以走的三角形。

rcMarkWalkableTriangles(m_ctx, m_cfg.walkableSlopeAngle, verts, nverts, tris, ntris, m_triareas);这个的关键就是三角形的法向量的 y 分量,等于三角形面与 x-z 平面的夹角 cos 值。运用相似三角形。

2.2 高度场建立

主要就是利用x-z平面的网格与映射到平面上的三角形的交点,通过相似三角形获得这个交点 (x-z)-> Y在三维三角形的高度。

这个切割方法是 Sutherland-Hodgman polygon-clipping algorithm 的变种。

Sutherland-Hodgman polygon-clipping algorithm

2.2.1 高度场建立的核心函数。

bool rcRasterizeTriangles(rcContext* context,
const float* verts, const int /*nv*/,
const int* tris, const unsigned char* triAreaIDs, const int numTris,
rcHeightfield& heightfield, const int flagMergeThreshold)
{
rcAssert(context != NULL); rcScopedTimer timer(context, RC_TIMER_RASTERIZE_TRIANGLES); // Rasterize the triangles.
const float inverseCellSize = 1.0f / heightfield.cs;
const float inverseCellHeight = 1.0f / heightfield.ch;
for (int triIndex = 0; triIndex < numTris; ++triIndex)
{
const float* v0 = &verts[tris[triIndex * 3 + 0] * 3];
const float* v1 = &verts[tris[triIndex * 3 + 1] * 3];
const float* v2 = &verts[tris[triIndex * 3 + 2] * 3];
if (!rasterizeTri(v0, v1, v2, triAreaIDs[triIndex], heightfield, heightfield.bmin, heightfield.bmax, heightfield.cs, inverseCellSize, inverseCellHeight, flagMergeThreshold))
{
context->log(RC_LOG_ERROR, "rcRasterizeTriangles: Out of memory.");
return false;
}
} return true;
}

2.2.2 图解

每个 cell 上面是一个 spanList。 他存储着所有在这个cell上面的 所有 三角形在这个cell上的高度信息。

X. Ref

  1. A* : https://theory.stanford.edu/~amitp/GameProgramming/Heuristics.html#heuristics-for-grid-maps
  2. UE DOC: https://www.unrealdoc.com/p/navigation-mesh

Unreal RecastNavigation 开源项目详解的更多相关文章

  1. eclipse里面构建maven项目详解(转载)

    本文来源于:http://my.oschina.net/u/1540325/blog/548530 eclipse里面构建maven项目详解 1       环境安装及分配 Maven是基于项目对象模 ...

  2. JAVA Eclipse使用Maven构建web项目详解(SSM框架)

    tips: 启动项目后,welcome-file的链接即为测试用例 部署maven web项目 Eclipse使用Maven构建web项目详解 pom.xml添加webapp依赖: <depen ...

  3. [转帖](整理)GNU Hurd项目详解

    (整理)GNU Hurd项目详解 http://www.ha97.com/3188.html 发表于: 开源世界 | 作者: 博客教主 标签: GNU,Hurd,详解,项目 Hurd原本是要成为GNU ...

  4. Redis 配置文件 redis.conf 项目详解

    Redis.conf 配置文件详解 # [Redis](http://yijiebuyi.com/category/redis.html) 配置文件 # 当配置中需要配置内存大小时,可以使用 1k, ...

  5. Mac下Intellij IDea发布Web项目详解一

    Mac下Intellij IDea发布Web项目详解一 Mac下Intellij IDea发布Java Web项目(适合第一次配置Tomcat的家伙们)详解二 Mac下Intellij IDea发布J ...

  6. Mac下Intellij IDea发布Java Web项目详解五 开始测试

    测试前准备工作目录 Mac下Intellij IDea发布Web项目详解一 Mac下Intellij IDea发布Java Web项目(适合第一次配置Tomcat的家伙们)详解二 Mac下Intell ...

  7. 利用Intellij+MAVEN搭建Spring+Mybatis+MySql+SpringMVC项目详解

    http://blog.csdn.net/noaman_wgs/article/details/53893948 利用Intellij+MAVEN搭建Spring+Mybatis+MySql+Spri ...

  8. tomcat通过tomcat 安装根目录下的conf-Catalina-localhost目录发布项目详解

    tomcat通过conf-Catalina-localhost目录发布项目详解   Tomcat发布项目的方式大致有三种,但小菜认为通过在tomcat的conf/Catalina/localhost目 ...

  9. python选课系统项目详解

    选课系统项目详解 选课系统简介及分析 选课系统架构设计分析 选课系统目录设计 管理员视图 注册 登录 创建学校 创建课程 创建讲师 学生视图 注册 登录 选择学校 选择课程 查看分数 教师视图 登录 ...

  10. Usage、Usage Minimum和Usage Maximum项目详解

    (1)一个产生多个数据域(Report Count>1)的主项目之前有一个以上的[用途]时,每个[用途]与一个数据域依次对应,如果数据域个数(Report Count)超过[用途]的个数,则剩余 ...

随机推荐

  1. PyTorch视觉模型库torchvision.models介绍

    安装pytorch时我们一般都是会一并选择安装自带的视觉模型库 torchvision ,  该库不仅有经典的视觉模型结构同时还提供了对应参数的下载功能,可以说torchvision库是十分方便于研究 ...

  2. Hessian Free Optimization——外国网友分享的“共轭梯度”的推导

    外国网友分享的"共轭梯度"的推导: https://andrew.gibiansky.com/blog/machine-learning/hessian-free-optimiza ...

  3. 使用SiliconCloud尝试GraphRag——以《三国演义》为例(手把手教程,适合小白)

    使用OpenAI模型体验GraphRag--以<边城>为例 在使用SiliconCloud之前,先使用OpenAI的模型看看GraphRag的效果. GraphRAG是一种基于AI的内容理 ...

  4. springboot解析自定义yml

    springboot解析自定义yml 在实际项目开发中我们经常需要用到一些自定义配置,并且希望单独配置,方便维护,现在介绍下方式: 方式一手动加载 对于一些不变动的配置,写死在项目中维护,如下 然后在 ...

  5. Win32_SDK 屏蔽Edit控件的右键系统菜单方法

    找了好久的方法,网上都是基于mfc的方法,现在找到解决方法了,分享给大家, 就是要重新设置Edit控件的回调函数 //Win32 SDK 下Edit控件屏蔽右键系统菜单方法 第一步: //声明保存旧的 ...

  6. centos7.5离线安装zabbix4.0

    一.配置环境 1.1 Linux环境说明 zabbix 安装要求 https://www.zabbix.com/documentation/4.0/zh/manual/installation/req ...

  7. Playwright 浏览器窗口最大化

    实现方式 浏览器启动时,加参数 args=['--start-maximized']: 创建上下文时,加参数 no_viewport=True. from playwright.sync_api im ...

  8. 为 OpenWrt 路由器编译 minieap-sysu 项目

    学校的校园网要使用锐捷认证,于是想把认证客户端装到刷了 OpenWrt 的路由器上面.然而认证客户端 Linux 版只支持 x86 架构,我的路由器处理器却是 AArch64 架构,装不了,所以只能想 ...

  9. 「Docker学习系列教程」基础篇小总结及高级篇预告

    通过前面十来篇的学习,我们已经把docker基础篇学习完了.这篇文章,咱们就来小总结下基础篇学习的东西以及介绍接下来高级篇中,将会学习到哪些知识点. 基础篇总结: 第一篇,      凯哥就介绍了怎么 ...

  10. C# WebSocket高并发通信阻塞问题

    项目上遇到使用WebSocket超时问题,具体情况是这样的,OTA升级过程中,解压zip文件会有解压进度事件,将解压进度通过进程通信传给另一进程,通信提示超时异常 小伙伴堂园发现大文件使用Zip解压, ...