Exemplo n.º 1
0
void xrMerge()
{
	// clear marks to "false"
	used.assign	(g_nodes.size(),false);
	//	rmark.assign(g_nodes.size(),false);
	
	// iterate on nodes
	u32 group_id		= 0;
	u32 start_time	= timeGetTime();
	for (u32 Size=16; Size>2; Size/=2)
	{
		Msg("Pass size: %d",Size);
		for (u32 i=0; i<g_nodes.size(); i++)
		{
			if (!used[i]) {
				// analyze
				vertex& Start = g_nodes[i];

				int px,pz;
				px = iFloor(Start.Pos.x/g_params.fPatchSize+EPS_L);
				pz = iFloor(Start.Pos.z/g_params.fPatchSize+EPS_L);

				if (px%Size!=0 || pz%Size!=0) continue;

				if (QuadFit(i,Size)) CreatePN(group_id);
			}
			Progress(float(i)/float(g_nodes.size()));
		}
	}
	for (u32 i=0; i<g_nodes.size(); i++)
	{
		if (!used[i]) {
			// analyze
			ProcessOne	(i,8);
			CreatePN	(group_id);
		}
		Progress(float(i)/float(g_nodes.size()));
	}

	Msg("Optimization ratio: %2.1f%%\n",	100.f*float(group_id)/float(g_nodes.size())	);
	Msg("%d / %d\n%d seconds elapsed.",
		group_id,g_nodes.size(),
		(timeGetTime()-start_time)/1000);
}
Exemplo n.º 2
0
	IC void		Perform	(u32 ID)
	{
		if (ID==InvalidNode)		return;
		if (ID>=q_Marks.size())		return;
		if (q_Marks[ID])			return;
		
		q_Marks[ID]			= true;
		q_Clear.push_back	(ID);

		vertex&	N			= g_nodes[ID];
		if (q_Base.distance_to_sqr(N.Pos)>cover_sqr_dist)	return;
		
		// ok
		q_List.push_back	(ID);
		
		Perform	(N.n1);
		Perform	(N.n2);
		Perform	(N.n3);
		Perform	(N.n4);
	}
Exemplo n.º 3
0
	IC void		Begin	(int count)
	{
		q_List.reserve	(8192);
		q_Clear.reserve	(8192);
		q_Marks.assign	(count,false);
	}
Exemplo n.º 4
0
void	xrSmoothNodes()
{
	Nodes	smoothed;	smoothed.reserve(g_nodes.size());
	Marks	mark;		mark.assign(g_nodes.size(),false);

	int inv_count = 0;
	for (u32 i=0; i<g_nodes.size(); i++)
	{
		vertex& N = g_nodes[i];

		Fvector	P1,P2,P3,P4,P,REF;
		int		c;

		// smooth point LF
		{
			bool	bCorner = false;

			c=1;	N.PointLF(REF);	P1.set(REF);
			if (N.nLeft()!=InvalidNode) {
				vertex& L = g_nodes[N.nLeft()];

				L.PointFR(P);	merge(P1);
				if (L.nForward()!=InvalidNode) {
					bCorner = true;
					vertex& C = g_nodes[L.nForward()];

					C.PointRB(P);	merge(P1);
				}
			}
			if (N.nForward()!=InvalidNode) {
				vertex& F = g_nodes[N.nForward()];

				F.PointBL(P);	merge(P1);
				if ((!bCorner) && (F.nLeft()!=InvalidNode)) {
					bCorner = true;

					vertex& C = g_nodes[F.nLeft()];
					C.PointRB(P);	merge(P1);
				}
			}
			R_ASSERT(c<=4);
			P1.div(float(c));
		}

		// smooth point FR
		{
			bool	bCorner = false;

			c=1;	N.PointFR(REF); P2.set(REF);
			if (N.nForward()!=InvalidNode) {
				vertex& F = g_nodes[N.nForward()];

				F.PointRB(P);	merge(P2);
				if (F.nRight()!=InvalidNode) {
					bCorner = true;
					vertex& C = g_nodes[F.nRight()];

					C.PointBL(P);	merge(P2);
				}
			}
			if (N.nRight()!=InvalidNode) {
				vertex& R = g_nodes[N.nRight()];

				R.PointLF(P);	merge(P2);
				if ((!bCorner) && (R.nForward()!=InvalidNode)) {
					bCorner = true;

					vertex& C = g_nodes[R.nForward()];
					C.PointBL(P);	merge(P2);
				}
			}
			R_ASSERT(c<=4);
			P2.div(float(c));
		}

		// smooth point RB
		{
			bool	bCorner = false;

			c=1;	N.PointRB(REF); P3.set(REF);
			if (N.nRight()!=InvalidNode) {
				vertex& R = g_nodes[N.nRight()];

				R.PointBL(P);	merge(P3);
				if (R.nBack()!=InvalidNode) {
					bCorner = true;
					vertex& C = g_nodes[R.nBack()];

					C.PointLF(P);	merge(P3);
				}
			}
			if (N.nBack()!=InvalidNode) {
				vertex& B = g_nodes[N.nBack()];

				B.PointFR(P);	merge(P3);
				if ((!bCorner) && (B.nRight()!=InvalidNode)) {
					bCorner = true;

					vertex& C = g_nodes[B.nRight()];
					C.PointLF(P);	merge(P3);
				}
			}
			R_ASSERT(c<=4);
			P3.div(float(c));
		}

		// smooth point BL
		{
			bool	bCorner = false;

			c=1;	N.PointBL(REF); P4.set(REF);
			if (N.nBack()!=InvalidNode) {
				vertex& B = g_nodes[N.nBack()];

				B.PointLF(P);	merge(P4);
				if (B.nLeft()!=InvalidNode) {
					bCorner = true;
					vertex& C = g_nodes[B.nLeft()];

					C.PointFR(P);	merge(P4);
				}
			}
			if (N.nLeft()!=InvalidNode) {
				vertex& L = g_nodes[N.nLeft()];

				L.PointRB(P);	merge(P4);
				if ((!bCorner) && (L.nBack()!=InvalidNode)) {
					bCorner = true;

					vertex& C = g_nodes[L.nBack()];
					C.PointFR(P);	merge(P4);
				}
			}
			R_ASSERT(c<=4);
			P4.div(float(c));
		}

		// align plane
		Fvector data[4]; data[0]=P1; data[1]=P2; data[2]=P3; data[3]=P4;
		Fvector vOffs,vNorm,D;
		vNorm.set(N.Plane.n);
		vOffs.set(N.Pos);
		Mgc::OrthogonalPlaneFit(
			4,(Mgc::Vector3*)data,
			*((Mgc::Vector3*)&vOffs),
			*((Mgc::Vector3*)&vNorm)
		);
		if (vNorm.y<0) vNorm.invert();

		// create _new node
		vertex NEW = N;
		NEW.Plane.build	(vOffs,vNorm);
		D.set			(0,1,0);
		N.Plane.intersectRayPoint(N.Pos,D,NEW.Pos);	// "project" position
		smoothed.push_back	(NEW);

		// verify placement
		/*
		mark[i]			= !!ValidNode	(NEW);

		if (!mark[i])	inv_count++;.
		*/
	}
	g_nodes = smoothed;

	if (inv_count) Msg("%d invalid nodes detected",inv_count);
}