栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

在服务器端如何用JNI实现 NavMesh寻路

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在服务器端如何用JNI实现 NavMesh寻路

上一节我们已经讲到的在服务器端使用 Easy3dNav来进行 NavMesh 来做寻路 3D寻路系统NavMesh-服务端篇,但性能上能否更快一点呢?众所周知,C++ 版本的性能向来比JAVA版本要出色,所以我们尝试用JAVA调用JNI native 接口来提升寻路的性能。

如何使用JNI技术来实现,JAVA对C++的调用呢?具体可以参考JNI全流程实例使用总结 这篇文章,本篇文章只提供C++端的实现逻辑。

JAVA端

 
    public native int load(int navmeshId, byte[] content, int length);

    
    public native float[] find(int navmeshId, float[] start, float[] end, float[] extents);

    
    public native float[] findNearest(int navmeshId, float[] point, float[] extents);


    
    public native float[] raycast(int navmeshId, float[] start, float[] end, float[] extents);

C++ 端:
这里只展示寻路的API实现:

JNIEXPORT  jfloatArray JNICALL Java_com_gamioo_ooxx_GamiooJNI_find(JNIEnv* env, jobject jobj, jint id,  jfloatArray start, jfloatArray end, jfloatArray extent)
{
	jfloatArray ret=  env->NewFloatArray(0);
	float straightPath[MAX_POLYS * 3];
	jfloat* startPos = (jfloat*)env-> GetFloatArrayElements(start, 0);
	jfloat* endPos = (jfloat*)env->GetFloatArrayElements(end, 0);
	jfloat* extents = (jfloat*)env->GetFloatArrayElements(extent, 0);
	if (startPos == nullptr)
	{
		return ret;
	}
	if (endPos == nullptr)
	{
		return ret;
	}
	if (extents == nullptr)
	{
		return ret;
	}

	dtPolyRef startRef = 0;
	dtPolyRef endRef = 0;
	float startNearestPt[3];
	float endNearestPt[3];

	dtQueryFilter filter;
	filter.setIncludeFlags(0xffff);
	filter.setExcludeFlags(0);
	NavMeshContex* navMeshContex =RecastGet(id);
	//cout << navMeshContex->toString()<navQuery->findNearestPoly(startPos, extents, &filter, &startRef, startNearestPt);
	navMeshContex->navQuery->findNearestPoly(endPos, extents, &filter, &endRef, endNearestPt);
	dtPolyRef polys[MAX_POLYS];
	int npolys;
	unsigned char straightPathFlags[MAX_POLYS];
	dtPolyRef straightPathPolys[MAX_POLYS];
	int nstraightPath = 0;

	navMeshContex->navQuery->findPath(startRef, endRef, startNearestPt, endNearestPt, &filter, polys, &npolys, MAX_POLYS);
	//printf("npolys: %dn", npolys);
	if (npolys)
	{
		float epos1[3];
		dtVcopy(epos1, endNearestPt);

		if (polys[npolys - 1] != endRef)
		{
			navMeshContex->navQuery->closestPointOnPoly(polys[npolys - 1], endNearestPt, epos1, 0);
		}
		navMeshContex->navQuery-> findStraightPath(startNearestPt, endNearestPt, polys, npolys, straightPath, straightPathFlags, straightPathPolys, &nstraightPath, MAX_POLYS, 0);
		ret= Util::ConvertFloatStarToJfloatArray(env, straightPath,nstraightPath * 3);
	}
	return ret;
}

接下去,我们用单测来做下数据对比:

经过数据轨迹对比(C++和JAVA,以及工具的导出轨迹数据),完全一致!说明API实现没问题。

接着,我们做下性能的对比:
系统配置,WIN 11,64G内存,8核数,16线程数
JAVA版本:

C++版本:


从压测数据对比得出结论,寻路性能提高了2倍多,其他的接口也有一定幅度的提升。
总结:
我们可以对寻路的耗时以及稳定性做监控,进行性能的对比。经过对比,通过对C++版本的导航接口调用,我们一定幅度提升了寻路的性能,并且在寻路的稳定性上也得到了提高。

参考文献:
基于NavMesh寻路、漏斗寻路、RVO动态避障自创的服务器大规模寻路+动态避障算法的实现
从零开始学习导航网格#2 编译RecastNavigation
构建recastnavigation并部署服务端到Linux
接入C++版本recastnavigation寻路库到Unity/服务端中

暑期编程PK赛 得CSDN机械键盘等精美礼品!
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1016442.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号