void bloomenthal_polygonizer::PolygonizeSurface(const Location& startinglocation)
{
	// Create initial cube
	if(mark_center(startinglocation))
		return;

	Cube c(startinglocation);
	for(TqInt n = 0; n < 8; n++)
		c.corners[n] = get_cached_corner(startinglocation + Location(bit_value(n, 2), bit_value(n, 1), bit_value(n, 0)));

	// Push it on stack
	m_active_cubes.push(c);

	// Process active cubes till none left
	while(!m_active_cubes.empty())
	{
		Cube c = m_active_cubes.top();
		m_active_cubes.pop();

		// Polygonize
		switch(m_Decomposition)
		{
				case MARCHINGCUBES:
				MarchingCube(c);
				break;
				case TETRAHEDRAL:
				// Decompose into tetrahedra and polygonize
				TriangulateTet(c, LBN, LTN, RBN, LBF);
				TriangulateTet(c, RTN, LTN, LBF, RBN);
				TriangulateTet(c, RTN, LTN, LTF, LBF);
				TriangulateTet(c, RTN, RBN, LBF, RBF);
				TriangulateTet(c, RTN, LBF, LTF, RBF);
				TriangulateTet(c, RTN, LTF, RTF, RBF);
				break;
				default:
				Aqsis::log() << warning << "Unknow decomposition " << std::endl;
				MarchingCube(c);
				break;

		}

		// Test six face directions, maybe add to stack
		TestFace(c.l.Left(), c, L, LBN, LBF, LTN, LTF);
		TestFace(c.l.Right(), c, R, RBN, RBF, RTN, RTF);
		TestFace(c.l.Bottom(), c, B, LBN, LBF, RBN, RBF);
		TestFace(c.l.Top(), c, T, LTN, LTF, RTN, RTF);
		TestFace(c.l.Near(), c, N, LBN, LTN, RBN, RTN);
		TestFace(c.l.Far(), c, F, LBF, LTF, RBF, RTF);
	}
}
Ejemplo n.º 2
0
void VoxelTerrain::BuildCubeGrid(float x, float y, float z, float l, float f1, float f2, float f3, float f4, float f5, float f6, float f7, float f8){

	float vcx=x;
	float vcy=y;
	float vcz=-z;
	tmat.TransformVec(vcx, vcy, vcz, 1);

	for (int i = 0 ;i<= 5; i++){
		float d = eyepoint->frustum[i][0] * vcx + eyepoint->frustum[i][1] * vcy - eyepoint->frustum[i][2] * vcz + eyepoint->frustum[i][3];
		if (d <= -l*sqrt(6)) return;//{ds=ds/10; break;}
	}


	float dx,dy,dz;	
	float rc;	

	/* compute distance from node To camera (approximated for speed, don't need to be exact) */
	dx = abs(x - Xcf); dy = abs(y - Ycf); dz = abs(z - Zcf);
	rc = dx+dy+dz;

	if (rc*.1<=3*l){

		float F[27];
		F[0] =tbuffer[(int)(x-l)][(int)(y-l)][(int)(z-l)];
		F[1] =tbuffer[(int)(x)][(int)(y-l)][(int)(z-l)];
		F[2] =tbuffer[(int)(x+l)][(int)(y-l)][(int)(z-l)];
		F[3] =tbuffer[(int)(x-l)][(int)(y)][(int)(z-l)];
		F[4] =tbuffer[(int)(x)][(int)(y)][(int)(z-l)];
		F[5] =tbuffer[(int)(x+l)][(int)(y)][(int)(z-l)];
		F[6] =tbuffer[(int)(x-l)][(int)(y+l)][(int)(z-l)];
		F[7] =tbuffer[(int)(x)][(int)(y+l)][(int)(z-l)];
		F[8] =tbuffer[(int)(x+l)][(int)(y+l)][(int)(z-l)];

		F[9] =tbuffer[(int)(x-l)][(int)(y-l)][(int)(z)];
		F[10]=tbuffer[(int)(x)][(int)(y-l)][(int)(z)];
		F[11]=tbuffer[(int)(x+l)][(int)(y-l)][(int)(z)];
		F[12]=tbuffer[(int)(x-l)][(int)(y)][(int)(z)];
		F[13]=tbuffer[(int)(x)][(int)(y)][(int)(z)];
		F[14]=tbuffer[(int)(x+l)][(int)(y)][(int)(z)];
		F[15]=tbuffer[(int)(x-l)][(int)(y+l)][(int)(z)];
		F[16]=tbuffer[(int)(x)][(int)(y+l)][(int)(z)];
		F[17]=tbuffer[(int)(x+l)][(int)(y+l)][(int)(z)];

		F[18]=tbuffer[(int)(x-l)][(int)(y-l)][(int)(z+l)];
		F[19]=tbuffer[(int)(x)][(int)(y-l)][(int)(z+l)];
		F[20]=tbuffer[(int)(x+l)][(int)(y-l)][(int)(z+l)];
		F[21]=tbuffer[(int)(x-l)][(int)(y)][(int)(z+l)];
		F[22]=tbuffer[(int)(x)][(int)(y)][(int)(z+l)];
		F[23]=tbuffer[(int)(x+l)][(int)(y)][(int)(z+l)];
		F[24]=tbuffer[(int)(x-l)][(int)(y+l)][(int)(z+l)];
		F[25]=tbuffer[(int)(x)][(int)(y+l)][(int)(z+l)];
		F[26]=tbuffer[(int)(x+l)][(int)(y+l)][(int)(z+l)];

		//fix cracks

		dx = abs(x - Xcf); dy = abs(y - Ycf); dz = abs(z - 2 * l - Zcf);	//Back
		rc = dx+dy+dz;
		if (rc*.1>3*l){
			F[1] = (f1+f2)/2;
			F[3] = (f1+f3)/2;
			F[4] = MiddlePoint(f1,f2,f3,f4);
			F[5] = (f2+f4)/2;
			F[7] = (f3+f4)/2;
		}

		dx = abs(x - Xcf); dy = abs(y - Ycf); dz = abs(z + 2 * l - Zcf);	//Front
		rc = dx+dy+dz;
		if (rc*.1>3*l){
			F[19] = (f5+f6)/2;
			F[21] = (f5+f7)/2;
			F[22] = MiddlePoint(f5,f6,f7,f8);
			F[23] = (f6+f8)/2;
			F[25] = (f7+f8)/2;
		}

		dx = abs(x - 2 * l - Xcf); dy = abs(y - Ycf); dz = abs(z - Zcf);	//Left
		rc = dx+dy+dz;
		if (rc*.1>3*l){
			F[3] = (f1+f3)/2;
			F[9] = (f1+f5)/2;
			F[12] = MiddlePoint(f1,f3,f5,f7);
			F[15] = (f3+f7)/2;
			F[21] = (f5+f7)/2;
		}

		dx = abs(x + 2 * l - Xcf); dy = abs(y - Ycf); dz = abs(z - Zcf);	//Right
		rc = dx+dy+dz;
		if (rc*.1>3*l){
			F[5] = (f2+f4)/2;
			F[11] = (f2+f6)/2;
			F[14] = MiddlePoint(f2,f4,f6,f8);
			F[17] = (f4+f8)/2;
			F[23] = (f6+f8)/2;
		}

		dx = abs(x - Xcf); dy = abs(y - 2 * l - Ycf); dz = abs(z - Zcf);	//Up
		rc = dx+dy+dz;
		if (rc*.1>3*l){
			F[1] = (f1+f2)/2;
			F[9] = (f1+f5)/2;
			F[10] = MiddlePoint(f1,f2,f5,f6);
			F[11] = (f2+f6)/2;
			F[19] = (f5+f6)/2;
		}

		dx = abs(x - Xcf); dy = abs(y + 2 * l - Ycf); dz = abs(z - Zcf);	//Down
		rc = dx+dy+dz;
		if (rc*.1>3*l){
			F[7] = (f3+f4)/2;
			F[15] = (f3+f7)/2;
			F[16] = MiddlePoint(f3,f4,f7,f8);
			F[17] = (f4+f8)/2;
			F[25] = (f7+f8)/2;
		}

		//Edges
		dx = abs(x - Xcf); dy = abs(y - 2 * l - Ycf); dz = abs(z - 2 * l - Zcf);
		rc = dx+dy+dz;
		if (rc*.1>3*l){
			F[1] = (f1+f2)/2;
		}

		dx = abs(x - Xcf); dy = abs(y + 2 * l - Ycf); dz = abs(z - 2 * l - Zcf);
		rc = dx+dy+dz;
		if (rc*.1>3*l){
			F[7] = (f3+f4)/2;
		}

		dx = abs(x - Xcf); dy = abs(y - 2 * l - Ycf); dz = abs(z + 2 * l - Zcf);
		rc = dx+dy+dz;
		if (rc*.1>3*l){
			F[19] = (f5+f6)/2;
		}

		dx = abs(x - Xcf); dy = abs(y + 2 * l - Ycf); dz = abs(z + 2 * l - Zcf);
		rc = dx+dy+dz;
		if (rc*.1>3*l){
			F[25] = (f7+f8)/2;
		}


		dx = abs(x - 2 * l - Xcf); dy = abs(y - 2 * l - Ycf); dz = abs(z - Zcf);
		rc = dx+dy+dz;
		if (rc*.1>3*l){
			F[9] = (f1+f5)/2;
		}

		dx = abs(x + 2 * l - Xcf); dy = abs(y - 2 * l - Ycf); dz = abs(z - Zcf);
		rc = dx+dy+dz;
		if (rc*.1>3*l){
			F[11] = (f2+f6)/2;
		}

		dx = abs(x - 2 * l - Xcf); dy = abs(y + 2 * l - Ycf); dz = abs(z - Zcf);
		rc = dx+dy+dz;
		if (rc*.1>3*l){
			F[15] = (f3+f7)/2;
		}

		dx = abs(x + 2 * l - Xcf); dy = abs(y + 2 * l - Ycf); dz = abs(z - Zcf);
		rc = dx+dy+dz;
		if (rc*.1>3*l){
			F[17] = (f4+f8)/2;
		}

		dx = abs(x - 2 * l - Xcf); dy = abs(y - Ycf); dz = abs(z - 2 * l - Zcf);
		rc = dx+dy+dz;
		if (rc*.1>3*l){
			F[3] = (f1+f3)/2;
		}

		dx = abs(x + 2 * l - Xcf); dy = abs(y - Ycf); dz = abs(z - 2 * l - Zcf);
		rc = dx+dy+dz;
		if (rc*.1>3*l){
			F[5] = (f2+f4)/2;
		}

		dx = abs(x - 2 * l - Xcf); dy = abs(y - Ycf); dz = abs(z + 2 * l - Zcf);
		rc = dx+dy+dz;
		if (rc*.1>3*l){
			F[21] = (f5+f7)/2;
		}

		dx = abs(x + 2 * l - Xcf); dy = abs(y - Ycf); dz = abs(z + 2 * l - Zcf);
		rc = dx+dy+dz;
		if (rc*.1>3*l){
			F[23] = (f6+f8)/2;
		}


		l=l/2;
		level+=1;

		BuildCubeGrid (x-l, y-l, z-l,l,  F[0], F[1], F[3], F[4], F[9], F[10], F[12], F[13]);
		BuildCubeGrid (x+l, y-l, z-l,l,  F[1], F[2], F[4], F[5], F[10], F[11], F[13], F[14]);
		BuildCubeGrid (x-l, y+l, z-l,l,  F[3], F[4], F[6], F[7], F[12], F[13], F[15], F[16]);
		BuildCubeGrid (x+l, y+l, z-l,l,  F[4], F[5], F[7], F[8], F[13], F[14], F[16], F[17]);
		BuildCubeGrid (x-l, y-l, z+l,l,  F[9], F[10], F[12], F[13], F[18], F[19], F[21], F[22]);
		BuildCubeGrid (x+l, y-l, z+l,l,  F[10], F[11], F[13], F[14], F[19], F[20], F[22], F[23]);
		BuildCubeGrid (x-l, y+l, z+l,l,  F[12], F[13], F[15], F[16], F[21], F[22], F[24], F[25]);
		BuildCubeGrid (x+l, y+l, z+l,l,  F[13], F[14], F[16], F[17], F[22], F[23], F[25], F[26]);

		level-=1;
	} else {
		float F[8];
		F[0] =f1;
		F[1] =f2;
		F[2] =f3;
		F[3] =f4;
		F[4] =f5;
		F[5] =f6;
		F[6] =f7;
		F[7] =f8;


		MarchingCube (x-l, y-l, z-l,x+l,y+l,z+l, F);
	}

}