recast 1 rasterizeTri dividePoly

static bool rasterizeTri(const float* v0, const float* v1, const float* v2,
						 const unsigned char area, rcHeightfield& hf,
						 const float* bmin, const float* bmax,
						 const float cs, const float ics, const float ich,
						 const int flagMergeThr)//格栅化一个三角形
{
	const int w = hf.width;
	const int h = hf.height;
	float tmin[3], tmax[3];
	const float by = bmax[1] - bmin[1];
	
	// Calculate the bounding box of the triangle.
	rcVcopy(tmin, v0);
	rcVcopy(tmax, v0);
	rcVmin(tmin, v1);
	rcVmin(tmin, v2);
	rcVmax(tmax, v1);
	rcVmax(tmax, v2);
	
	// If the triangle does not touch the bbox of the heightfield, skip the triagle.
	if (!overlapBounds(bmin, bmax, tmin, tmax))
		return true;
	//默认y轴朝上,这里的方法是先将整个heightfield做rowfield划分,将三角形化切成片段
//然后又对做过rowfield后的三角形片段做columnfield划分,
	//这样就将原始的三角形切分到矩阵式的y cell(y轴未知,x和z长度为cell size)(等同于xz grid cell)中了,而三角形在每
//个y cell中的片段被用来计算出height范围存放到span中用于做下步计算。所以总结起来这里的目的就是用距离为cellsize的zx线网(xz grid cell)切分 空间中分布的原始的三角
	//形(即格栅化三角形),并取出三角形在y cell中的对应片段的有效高度范围,并记录下来。
	// Calculate the footprint of the triangle on the grid's y-axis
	int y0 = (int)((tmin[2] - bmin[2])*ics);//求取三角形min点相对于整个height field的cell的z轴方向下标
	int y1 = (int)((tmax[2] - bmin[2])*ics);//求取到三角形max点相对于整个height field的cell的z轴方向下标
	y0 = rcClamp(y0, 0, h-1);
	y1 = rcClamp(y1, 0, h-1);
	
	// Clip the triangle into all grid cells it touches.
	float buf[7*3*4];
	float *in = buf, *inrow = buf+7*3, *p1 = inrow+7*3, *p2 = p1+7*3;

	rcVcopy(&in[0], v0);
	rcVcopy(&in[1*3], v1);
	rcVcopy(&in[2*3], v2);
	int nvrow, nvIn = 3;
	
	for (int y = y0; y <= y1; ++y)
	{
		// Clip polygon to row. Store the remaining polygon as well
		const float cz = bmin[2] + y*cs;
		dividePoly(in, nvIn, inrow, &nvrow, p1, &nvIn, cz+cs, 2); //将三角形划分为
//在相应的row中部分和不再row中的部分,p1存放在row中的部分,in存放不再row中的部分,以便for循环的下次运算
		rcSwap(in, p1);
		if (nvrow < 3) continue;
		
		// find the horizontal bounds in the row 基于上面的z周方向裁剪划分的基础上再
//对x轴方向用同样的方法进行裁剪划分
		float minX = inrow[0], maxX = inrow[0];
		for (int i=1; i<nvrow; ++i)
		{
			if (minX > inrow[i*3])	minX = inrow[i*3];
			if (maxX < inrow[i*3])	maxX = inrow[i*3];
		}
		int x0 = (int)((minX - bmin[0])*ics);
		int x1 = (int)((maxX - bmin[0])*ics);
		x0 = rcClamp(x0, 0, w-1);
		x1 = rcClamp(x1, 0, w-1);

		int nv, nv2 = nvrow;

		for (int x = x0; x <= x1; ++x)
		{
			// Clip polygon to column. store the remaining polygon as well
			const float cx = bmin[0] + x*cs;
			dividePoly(inrow, nv2, p1, &nv, p2, &nv2, cx+cs, 0);
			rcSwap(inrow, p2);
			if (nv < 3) continue;
			
			// Calculate min and max of the span.
			float smin = p1[1], smax = p1[1];
			for (int i = 1; i < nv; ++i)
			{
				smin = rcMin(smin, p1[i*3+1]);
				smax = rcMax(smax, p1[i*3+1]);
			}
			smin -= bmin[1];
			smax -= bmin[1];
			// Skip the span if it is outside the heightfield bbox
			if (smax < 0.0f) continue;
			if (smin > by) continue;
			// Clamp the span to the heightfield bbox.
			if (smin < 0.0f) smin = 0;
			if (smax > by) smax = by;
			
			// Snap the span to the heightfield height grid.
			unsigned short ismin = (unsigned short)rcClamp((int)floorf(smin * ich), 0, RC_SPAN_MAX_HEIGHT);
			unsigned short ismax = (unsigned short)rcClamp((int)ceilf(smax * ich), (int)ismin+1, RC_SPAN_MAX_HEIGHT);
			
			if (!addSpan(hf, x, y, ismin, ismax, area, flagMergeThr))//将新的span加入到span链表中。内部有合适的合并操作
				return false;
		}
	}

	return true;
}


// divides a convex polygons into two convex polygons on both sides of a line
static void dividePoly(const float* in, int nin,
					  float* out1, int* nout1,
					  float* out2, int* nout2,
					  float x, int axis)
{
	float d[12];
	for (int i = 0; i < nin; ++i)
		d[i] = x - in[i*3+axis];//参考的z减去顶点的z

	int m = 0, n = 0;
	for (int i = 0, j = nin-1; i < nin; j=i, ++i)
	{
		bool ina = d[j] >= 0;
		bool inb = d[i] >= 0;
		if (ina != inb)
		{
			float s = d[j] / (d[j] - d[i]);
			out1[m*3+0] = in[j*3+0] + (in[i*3+0] - in[j*3+0])*s;//获取到三角形
//边与row cells交点坐标 ,out1 存放由原始三角形裁剪后剩余部分组成的新的三角形
			out1[m*3+1] = in[j*3+1] + (in[i*3+1] - in[j*3+1])*s;
			out1[m*3+2] = in[j*3+2] + (in[i*3+2] - in[j*3+2])*s;
			rcVcopy(out2 + n*3, out1 + m*3); //将点放到out2中,out2存放原始三角
//形在row cells 中的部分。
			m++;
			n++;
			// add the i'th point to the right polygon. Do NOT add points that are on the dividing line
			// since these were already added above
			if (d[i] > 0)
			{
				rcVcopy(out1 + m*3, in + i*3);
				m++;
			}
			else if (d[i] < 0)
			{
				rcVcopy(out2 + n*3, in + i*3);
				n++;
			}
		}
		else // same side
		{
			// add the i'th point to the right polygon. Addition is done even for points on the dividing line
			if (d[i] >= 0)
			{
				rcVcopy(out1 + m*3, in + i*3);
				m++;
				if (d[i] != 0)
					continue;
			}
			rcVcopy(out2 + n*3, in + i*3);
			n++;
		}
	}

	*nout1 = m;
	*nout2 = n;
}


注意area id(用于描述span的属性,比如walkable ,swiming等)是在rcRasterizeTriangles之前就进行设置的,area id在这一步中会存入到span里面去。
rcHeightfield->spans链表数组中,一个spans列表中元素是从低到高排列的。(对于有相交的区域在addspan的时候就已经合并了)

三角形在span中的片段的具体形状在整个过程(包括后面的所有过程)中并不用管,整个过程都只利用了片段的y的最大值和最小值,以及当前span的最大值余上一个span的最小值所留余的高度,以及span所在的位置。

span中的smin smax都是以cellheight为单位的,记录span的高度上的范围
当前span的top与下一个span的bottom作为可行走的区域

rcFilterLowHangingWalkableObstacles 
rcFilterLedgeSpans// 找到边缘并将边缘的areaid设置成null。
rcFilterWalkableLowHeightSpans //剔除掉可行走区域高度低于walkableHeight的span

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值