google 的 recastnavigation 笔记 0

截止到2018 /9/12最新版的recastnavigation
racastNavigation实际上是有三部分。
第一部分是recast  建立寻路模型(navmesh),可以参看我的前面1 到5篇博客。这一步其实可以简化成让美术去手动创建模型,不过对模型网格是有一定要求的,需要指定一个美术规范,然后在用recast后面部分的代码创建recastmesh对象。
第二部分是detour,寻路,从一个点到另一个点是否可达,并且寻找出路径。
第三部分detoucrowd,控制多个物体走到目的地。不同于控制一个物体走到目的地,需要考虑控制对象之间的碰撞问题。控制物体到达目的地,有一个专门的名词steer。

https://www.jianshu.com/p/490a9128b248

http://www.critterai.org/projects/nmgen_study/ 
 

1、理解射线与包围盒的交叉碰撞检测 slab 理解法: https://blog.csdn.net/ring0hx/article/details/7677418
另一种理解:二维中线段(A,B) 和 边与轴平行的矩形(min(X1,Y1),max(X2,T2))相交,如下图(只考虑相交的情况),ab投影到x,y 分别为o2,o1,与矩形边的共同投影分别为g2,g1; g2 ,g1 映射回AB,就变成了b2,b1。AB 与变相交为t0,t1 。主要计算(A,t0)区间与AB的比值的范围(只取0~1之间) 和(B,t1)区间与AB的比值的范围有相交,即可证明AB与四边形相交。利用三角形相似原理前面的求区间范围等价于 求取o2的端点到g2起点的比值范围 和 求取o1的端点到 g1起点 的比值范围 的区间有交叉。取两者的min的最大值作为min 和max的最小值作为max,min<max  就说明相交。

//主要原理是将三维降成一维来计算,可以通过上面博客中的slab来理解,也可以通过上面的线段比值关系来理解。 
//包围盒也是需要边界与轴平行,后面的简化计算才有意义。
        float d[3];
	d[0] = sq[0] - sp[0];
	d[1] = sq[1] - sp[1];
	d[2] = sq[2] - sp[2];
	tmin = 0.0;  //将整个sq 到 sp 线段的区域 理解成0~1的区间
	tmax = 1.0f;
	
	for (int i = 0; i < 3; i++)
	{
		if (fabsf(d[i]) < EPS)
		{
			if (sp[i] < amin[i] || sp[i] > amax[i]) //sp[i] 与sq[i]在该轴向垂直的平面上
				return false;
		}
		else
		{
			const float ood = 1.0f / d[i];
			float t1 = (amin[i] - sp[i]) * ood; //求取amin[i]-sp[i] 与sq[i]-sp[i] 的比值。
			float t2 = (amax[i] - sp[i]) * ood; //求取amax[i]-sp[i] 与sq[i]-sp[i] 的比值。
			if (t1 > t2) { float tmp = t1; t1 = t2; t2 = tmp; } //求取到比值范围,大小位置做个调整
			if (t1 > tmin) tmin = t1;  //获取最新的最小值
			if (t2 < tmax) tmax = t2; //获取最新的最大值
			if (tmin > tmax) return false; //无相交的,退出
		}
	}
inline unsigned int dtNextPow2(unsigned int v) //求取大于等于v的2的最低次数幂,只要考虑最高位的1,其他的位数都不考虑就容易理解了。过程就是将最高位的1逐次成倍的往后面复制,达到最高位1后面全是1的结果。然后再加1。前面减1是考虑数本身刚好是2的次数幂。
{
	v--; 
	v |= v >> 1; //如果存在大于等于1位的数,将1{x}(n)最高位1,复制到次高位变成11{x}(n-1)
	v |= v >> 2; //如果存在大于等于2位的数,将[1]1{x}(n-1)高位的至少一个1,复制到第三[第四]位[1]1[1]1{x}(n-1)
	v |= v >> 4; //........将11{x}(n-1)高位的两个1,复制到第三第四位
	v |= v >> 8;
	v |= v >> 16;
	v++;
	return v;
}

对每个 三角形求取aabb范围并保存

solomesh中的第一步通过rcMarkWalkableTriangles设置三角形的area判断依据为三角形的slope,初始只有两个极端的值,表示可行走还是不可行走

solomesh中的rcRasterizeTriangles 函数,如果有图来进行展示会非常好理解,具体思路和操作是
1、将整个模型所在的box进行分条,如果按 俯视图来看, 分成长宽相等的cell(空间中可想象cell为长方体俯视图是边长为cellsize的正方形),整个模型所在的box刚好完全切分成cell。代码中体现在 双重for循环的x,y
2、左上角(或右上角或其他角)开始,从上致下,从左致右的顺序,查看所有三角形与该cell是否相交,如果相交,取出三角形在该cell空间范围内的aabb,并作为一个span(rcSpan类型)保存。总的是一个cell count个头的散列表。x*y作为散列表的关键值,span是一个是散列表中item。并同时将三角形的area传递给span。
3、一个cell中可能同时与多个三角形有相交,也就是有多个span,将新增的span保存到对应的 散列表中,并做好排序,范围小的在表的最上方。
 

solomesh中的rcFilterLowHangingWalkableObstacles,看注释吧

solomesh 中的rcFilterLedgeSpans,看注释和代码吧

solomesh中的rcFilterWalkableLowHeightSpans,看注释和代码

rcBuildCompactHeightfield,作用是将sheildheight转为compactsheildheight,换一种存储方式。方便后面的使用。

rcErodeWalkableArea,腐蚀能走的区域,思路和原因和平面中的 腐蚀作用类型。

rcMarkConvexPolyArea, 更改area的值,该值作为权限使用。

SAMPLE_PARTITION_WATERSHED
       rcBuildDistanceField,计算每个span离边缘的距离。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值