寻路库recastnavigation改造

Posted 流子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了寻路库recastnavigation改造相关的知识,希望对你有一定的参考价值。

本文是介绍对寻路库recastnavigation 改造,使得使用更加友好。
Git仓库:
https://github.com/jiangguilong2000/recastnavigation

首先,我们要做一些前置操作
SDL: 开放源代码的跨平台多媒体开发库
Premake:量跨平台构建系统

环境:
VS 2019以及完整的C++编译环境

Rider For Unreal Engine 2022.2.1(下面简称Rider)

Unity 2019.4.8 lts

.Net Core 2.2

1.首先把git库拉到本地,先将下载的SDL库放到ecastnavigation\\RecastDemo\\Contrib,需要改名为SDL,应该得到如下目录recastnavigation-master\\RecastDemo\\Contrib\\SDL\\lib\\x64
2/然后将下载premake5.exe放入
recastnavigation\\RecastDemo
3.然后通过命令行控制premake编译recastnavigation为sln工程

PS E:\\recastnavigation\\RecastDemo> .\\premake5.exe 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 (160ms).

然后目录中会生成一个Build文件夹,里面是我们编译出来的sln工程

recastnavigation\\RecastDemo\\Build\\vs2019\\recastnavigation.sln

用rider打开,直接运行,我们就能看到编辑器画面了

接下去我们要对源码进行一些改造:
原始的recast是没有开始点和结束点的坐标的,那如何能显示出来呢?

void NavMeshTesterTool::handleRenderOverlay(double* proj, double* model, int* view)

	GLdouble x, y, z;
	char buf[64];

	// Draw start and end point labels
	if (m_sposSet && gluProject((GLdouble)m_spos[0], (GLdouble)m_spos[1], (GLdouble)m_spos[2],
		model, proj, view, &x, &y, &z))
	
		if (m_showCoord)
		
			snprintf(buf, sizeof(buf), "Start (%.1f, %.1f, %.1f)", m_spos[0], m_spos[1], m_spos[2]);
			imguiDrawText((int)x, (int)(y - 25), IMGUI_ALIGN_CENTER, buf, imguiRGBA(0, 0, 0, 220));
		
		else
			imguiDrawText((int)x, (int)(y - 25), IMGUI_ALIGN_CENTER, "Start", imguiRGBA(0, 0, 0, 220));
	


	if (m_toolMode == TOOLMODE_RAYCAST && m_hitResult && m_showCoord &&
		gluProject((GLdouble)m_hitPos[0], (GLdouble)m_hitPos[1], (GLdouble)m_hitPos[2],
			model, proj, view, &x, &y, &z))
	
		snprintf(buf, sizeof(buf), "HitPos (%.1f, %.1f, %.1f)", m_hitPos[0], m_hitPos[1], m_hitPos[2]);
		imguiDrawText((int)x, (int)(y - 25), IMGUI_ALIGN_CENTER, buf, imguiRGBA(0, 0, 0, 220));
	
	if (m_eposSet && gluProject((GLdouble)m_epos[0], (GLdouble)m_epos[1], (GLdouble)m_epos[2],
		model, proj, view, &x, &y, &z))
	
		if (m_showCoord)
		
			float totalCost = 0.0f;
			for (int i = 0; i + 1 < m_nstraightPath; i++)
				totalCost += dtVdist(&m_straightPath[i * 3], &m_straightPath[(i + 1) * 3]);
			snprintf(buf, sizeof(buf), "End (%.1f, %.1f, %.1f), Cost %.1f", m_epos[0], m_epos[1], m_epos[2], totalCost);
			imguiDrawText((int)x, (int)(y - 25), IMGUI_ALIGN_CENTER, buf, imguiRGBA(0, 0, 0, 220));
		
		else
			imguiDrawText((int)x, (int)(y - 25), IMGUI_ALIGN_CENTER, "End", imguiRGBA(0, 0, 0, 220));
	

那么,如何能显示出关键点point list?,首先,路径搜索的模式要改成TOOLMODE_PATHFIND_STRAIGHT模式,代码需要增加如下的打印,
在NavMeshTesterTool.cpp中增加,

void NavMeshTesterTool::recalc()
....
....
	if (m_toolMode == TOOLMODE_PATHFIND_STRAIGHT&& m_nstraightPath>0) 
    	
    		stringstream os;
    		os << "total point size=" << m_nstraightPath<< ",";
    		//m_sample->getContext()->log(RC_LOG_PROGRESS, "total point size=%d", m_nstraightPath);
    		for (int i = 0; i < m_nstraightPath; ++i)
    		
    			if (i > 0&&i%10==0) 
    				m_sample->getContext()->log(RC_LOG_PROGRESS, "%s", os.str().c_str());
    				os.str("");
    			
    			os << "[" << m_straightPath[i * 3] << "," << m_straightPath[i * 3 + 1] << "," << m_straightPath[i * 3 + 2] << "] ";
    		
    		m_sample->getContext()->log(RC_LOG_PROGRESS, "%s", os.str().c_str());
    	

在Sample.h中增加

public:
	Sample();
	virtual ~Sample();
	
	void setContext(BuildContext* ctx)  m_ctx = ctx; 
	BuildContext* getContext() 
		return m_ctx;
	


最后一个问题,如何把显示日志的地方的文本能鼠标选中?目前还没搞定

以上是关于寻路库recastnavigation改造的主要内容,如果未能解决你的问题,请参考以下文章

Recastnavigation 创建 off-mesh link 的潜规则

lua 要求如何工作

游戏AI之A*寻路

游戏的寻路算法

如何使用Unity做游戏中的寻路导航

3D寻路系统NavMesh-客户端篇