Exemple #1
0
// extract surface mesh
void TriSurfMesh( vector< MCCube*>& input, vector< MCTri*>& output){
	vector< MCCube* >::const_iterator itr_cube; MCCube*	pCube;
	for ( itr_cube = input.begin(); itr_cube != input.end(); ++itr_cube ){
		pCube = *itr_cube;
		Polygonise( pCube, output );
	}
}
void generate_terrain(density_func_t function, std::vector<VtxPosNormTex>& vertices, std::vector<uint32_t>& indices) {
    static const float size = 10.0f;
    static const float granularity = 0.125f;
    static const float gran_div_2 = granularity * 0.5f;
    uint32_t vtx_index = 0;
    float x, y, z;
    for(x=-size;x<=size;x += granularity) {
        for(y=-size;y<=size;y += granularity) {
            for(z=-size;z<=size;z += granularity) {
                gridcell_t cell;
                int ii = 0;
                float xx = x-gran_div_2;
                float xadder = granularity;
                for(float yy=y-gran_div_2; yy <= y+gran_div_2; yy += granularity) {
                    for(float zz=z-gran_div_2; zz <= z+gran_div_2; zz += granularity) {
                        cell.p[ii].x = xx;
                        cell.p[ii].y = yy;
                        cell.p[ii].z = zz;
                        ++ii;
                        xx += xadder;
                        cell.p[ii].x = xx;
                        cell.p[ii].y = yy;
                        cell.p[ii].z = zz;
                        ++ii;
                        xadder *= -1.0f;
                    }
                }
                for(ii=0;ii<8;++ii) {
                    cell.val[ii] = function(cell.p[ii]);
                }
                triangle_t triangles[5];
                int num_triangles = Polygonise(cell, 0.0f, triangles);
                for(ii=0;ii<num_triangles;++ii) {
                    triangle_t tri = triangles[ii];
                    float3 norm;
                    float3 edge0 = float3subtract(&tri.p[1], &tri.p[0]);
                    float3 edge1 = float3subtract(&tri.p[2], &tri.p[0]);
                    norm = float3cross(&edge1, &edge0);
                    norm = float3normalize(&norm);

                    for(int jj=2; jj>=0; --jj) {
                        float2 tex = {tri.p[jj].x, tri.p[jj].z};
                        VtxPosNormTex v = {
                            tri.p[jj],
                            norm,
                            tex
                        };
                        vertices.push_back(v);
                        indices.push_back(vtx_index++);
                    }
                }
            }
        }
    }
}
int Sculpture::createMesh() {
    vector<Triangle> triangles;
    for (int i = 0 ; i < SCULPTURE_SIZE - 1 ; i++) {
        for (int j = 0 ; j < SCULPTURE_SIZE - 1 ; j++) {
            for (int k = 0 ; k < SCULPTURE_SIZE - 1 ; k++) {
                GRIDCELL grid;
                this->initGrid(grid, i, j, k);
                Polygonise(grid, 0.5, triangles);
            }
        }
    }
    updateColors(triangles);
    mesh.clear();
    trianglesToMesh(triangles);
    return mesh.getNumberOfTriangles();
}
void runInterpTest()
{
	GRIDCELL cell = { { { 0,0,1 },{ 1,0,1 },{ 1,0,0 } ,{ 0,0,0 } ,{ 0,1,1 } ,{ 1,1,1 } ,{ 1,1,0 } ,{ 0,1,0 } },{ 0,1,0,0,0,0,0,0 } };
	const int times = 10000000;

	TRIANGLE* triangles = new TRIANGLE[times];



	double start = clock();

	std::cout << "Starting test ";
	std::cout << start << std::endl;

	for (int i = 0; i < times; i++)
	{
		triangles += Polygonise(cell, 0.5, triangles);
	}

	double end = clock();

	std::cout << "Completed test ";
	std::cout << end << std::endl;


	auto msPerKernel = (end - start) / times;

	std::cout << "Time per kernel in ms: " << msPerKernel << std::endl;

	auto kernelsPerFrame_60 = 1.0 / msPerKernel * 1000 / 60;
	std::cout << "Kernels per frame at 60 FPS: " << kernelsPerFrame_60 << std::endl;
	auto cubeSize60FPS = pow(kernelsPerFrame_60, 1.0 / 3);
	std::cout << "Kernel Cube per frame at 60 FPS: " << cubeSize60FPS << std::endl;



}
//Software marching cubes
//VERY far to be optimal !
void MarchingCubesRenderer::RenderMarchCube(float *data, ivec3 size, ivec3 gridsize, float isolevel){
  vec3 gridStep = vec3(2.0, 2.0, 2.0) / vec3(gridsize.x, gridsize.y, gridsize.z);

  ivec3 dataGridStep = size / gridsize;

  vec3 *triangles = new vec3[16];
  
  std::vector<Vector3>& positions = _mesh->getPositionVector();
  positions.clear();

  for (int k = 0; k < gridsize.z - 1; k++)
  for (int j = 0; j < gridsize.y - 1; j++)
  for (int i = 0; i < gridsize.x - 1; i++){
    GridCell cell;
    vec3 vcurf(i, j, k);
    ivec3 vcuri(i, j, k);

    cell.pos[0] = vcurf*gridStep - 1.0f;
    ivec3 valPos0 = vcuri*dataGridStep;
    cell.val[0] = data[valPos0.x + valPos0.y*size.x + valPos0.z*size.x*size.y];

    ivec3 valPos;

    cell.pos[1] = cell.pos[0] + vec3(gridStep.x, 0, 0);
    if (i == gridsize.x - 1)
      valPos = valPos0;
    else
      valPos = valPos0 + ivec3(dataGridStep.x, 0, 0);
    cell.val[1] = data[valPos.x + valPos.y*size.x + valPos.z*size.x*size.y];

    cell.pos[2] = cell.pos[0] + vec3(gridStep.x, gridStep.y, 0);
    valPos = valPos0 + ivec3(i == gridsize.x - 1 ? 0 : dataGridStep.x, j == gridsize.y - 1 ? 0 : dataGridStep.y, 0);
    cell.val[2] = data[valPos.x + valPos.y*size.x + valPos.z*size.x*size.y];

    cell.pos[3] = cell.pos[0] + vec3(0, gridStep.y, 0);
    valPos = valPos0 + ivec3(0, j == gridsize.y - 1 ? 0 : dataGridStep.y, 0);
    cell.val[3] = data[valPos.x + valPos.y*size.x + valPos.z*size.x*size.y];


    cell.pos[4] = cell.pos[0] + vec3(0, 0, gridStep.z);
    valPos = valPos0 + ivec3(0, 0, k == gridsize.z - 1 ? 0 : dataGridStep.z);
    cell.val[4] = data[valPos.x + valPos.y*size.x + valPos.z*size.x*size.y];


    cell.pos[5] = cell.pos[0] + vec3(gridStep.x, 0, gridStep.z);
    valPos = valPos0 + ivec3(i == gridsize.x - 1 ? 0 : dataGridStep.x, 0, k == gridsize.z - 1 ? 0 : dataGridStep.z);
    cell.val[5] = data[valPos.x + valPos.y*size.x + valPos.z*size.x*size.y];

    cell.pos[6] = cell.pos[0] + vec3(gridStep.x, gridStep.y, gridStep.z);
    valPos = valPos0 + ivec3(i == gridsize.x - 1 ? 0 : dataGridStep.x, j == gridsize.y - 1 ? 0 : dataGridStep.y, k == gridsize.z - 1 ? 0 : dataGridStep.z);
    cell.val[6] = data[valPos.x + valPos.y*size.x + valPos.z*size.x*size.y];

    cell.pos[7] = cell.pos[0] + vec3(0, gridStep.y, gridStep.z);
    valPos = valPos0 + ivec3(0, j == gridsize.y - 1 ? 0 : dataGridStep.y, k == gridsize.z - 1 ? 0 : dataGridStep.z);
    cell.val[7] = data[valPos.x + valPos.y*size.x + valPos.z*size.x*size.y];


    int numvert = Polygonise(cell, isolevel, triangles);

    //Put the triangles into the mesh
    for (int n = 0; n < numvert; n++){
      positions.push_back(Vector3(triangles[n].x, triangles[n].y, triangles[n].z));
    }


  }
  if (positions.empty() == false)
  {
    GetGLError();
    _mesh->constructBuffer();
    GetGLError();
    _mesh->drawBuffers();
    GetGLError();
  }
}
Exemple #6
0
void Engine::render()
{
	float i,j,k;
	int	num_cubes = 16;
	int	grid_width = 16;
	float	step_size = (float)grid_width / num_cubes;
	float	half_step = step_size / 2.0;
	TRIANGLE	triangle[5];
	GRIDCELL	cube;
	int		num_triangle = 0;

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glColor3f(1.0, 0.0, 0.0);
	glTranslatef(0.0f, 0.0f, -40.0f);
//	glRotatef(time, 0.0f, 1.0f, 0.0f);


	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );

	for(i = 0; i <= grid_width; i += step_size )
	{
		for(j = 0; j <= grid_width; j += step_size )
		{
			for(k = 0; k <= grid_width; k += step_size )
			{
				set_zero(cube);

				set_metaball(cube, grid_width, half_step, 2.0, i, j, k,
				5.5 * cos(time / 50.0),
				5 * sin(time / 50.0),
				0);

				set_metaball(cube, grid_width, half_step, 2.0, i, j, k,
				5.5 * sin(time / 50.0),
				5 * sin(time / 50.0),
				0);

				num_triangle = Polygonise(cube, 0.25, triangle);

//				glColor3f((int)(i + j + k) % 2, 0, 0);
				if (num_triangle)
				{
					for(int t = 0; t < num_triangle; t++)
					{
						glBegin(GL_TRIANGLES);
						glVertex3f(triangle[t].p[0].x, triangle[t].p[0].y, triangle[t].p[0].z);
						glVertex3f(triangle[t].p[1].x, triangle[t].p[1].y, triangle[t].p[1].z);
						glVertex3f(triangle[t].p[2].x, triangle[t].p[2].y, triangle[t].p[2].z);
						glEnd();
					}
				}
			}
		}
	}

/*
	glColor3f(1.0, 1.0, 1.0);
	glTranslatef(-8.0, -8.0, -8.0);
	for(i = 0; i <= num_cubes; i += 1.0f)
	{
		for(j = 0; j <= num_cubes; j += 1.0f)
		{
			for(k = 0; k <= num_cubes; k += 1.0f)
			{
				draw_box();
				glTranslatef(0.0, 0.0, 1.0);
			}
			glTranslatef(0.0, 1.0, 0.0);
			if (k == num_cubes + 1)
				glTranslatef(0.0, 0.0, -num_cubes - 1);
		}
		if (j == num_cubes + 1)
			glTranslatef(0.0, -num_cubes - 1, 0.0);
		glTranslatef(1.0, 0.0, 0.0);
	}
*/

	SwapBuffers(hdc);
}
void runKernelTest()
{
	/*auto s = new MarchingCubesService();

	auto gridP = MarchingCubesService.Vertices.Select(f = > f.ToVector3()).ToArray();
	auto gridVals = new double[8];
	gridVals[0] = 1;

	auto triangles = new List<Vector3>();


	auto watch = new Stopwatch();
	watch.Start();
	*/

	GRIDCELL cell = { { { 0,0,1 },{ 1,0,1 },{ 1,0,0 } ,{ 0,0,0 } ,{ 0,1,1 } ,{ 1,1,1 } ,{ 1,1,0 } ,{ 0,1,0 } },{ 0,1,0,0,0,0,0,0 } };
	const int times = 10000000;

	TRIANGLE* triangles = new TRIANGLE[times];



	double start = clock();

	std::cout << "Starting test ";
	std::cout << start << std::endl;

	for (int i = 0; i < times; i++)
	{
		triangles += Polygonise(cell, 0.5, triangles);
	}

	double end = clock();

	std::cout << "Completed test ";
	std::cout << end << std::endl;


	auto msPerKernel = (end - start) / times;

	std::cout << "Time per kernel in ms: " << msPerKernel << std::endl;

	auto kernelsPerFrame_60 = 1.0 / msPerKernel * 1000 / 60;
	std::cout << "Kernels per frame at 60 FPS: " << kernelsPerFrame_60 << std::endl;
	auto cubeSize60FPS = pow(kernelsPerFrame_60, 1.0 / 3);
	std::cout << "Kernel Cube per frame at 60 FPS: " << cubeSize60FPS << std::endl;







	start = clock();

	std::cout << "Starting test ";
	std::cout << start << std::endl;

	for (int i = 0; i < times; i++)
	{
		//VertexInterp(cell, 10, triangles);
	}

	end = clock();

	std::cout << "Completed test ";
	std::cout << end << std::endl;


	msPerKernel = (end - start) / times;

	std::cout << "Time per kernel in ms: " << msPerKernel << std::endl;

	kernelsPerFrame_60 = 1.0 / msPerKernel * 1000 / 60;
	std::cout << "Kernels per frame at 60 FPS: " << kernelsPerFrame_60 << std::endl;
	cubeSize60FPS = pow(kernelsPerFrame_60, 1.0 / 3);
	std::cout << "Kernel Cube per frame at 60 FPS: " << cubeSize60FPS << std::endl;







	getchar();
}
static void AEMarchingCubes(uint8_t* voxels, uint32_t stepX, uint32_t stepY, uint32_t stepZ, double isovalue, uint32_t w, uint32_t h, uint32_t d, AEMCTriangleArray* triangleArray) {
    // Run the processCube function on every cube in the grid
	for(uint32_t x = stepX; x < w-2*stepX; x += stepX) {
		for(uint32_t y = stepY; y < h-2*stepY; y += stepY) {
			for(uint32_t z = stepZ; z < d-2*stepZ; z += stepZ) {
				/*GRIDCELL c = {{
					{x,y,z, 
                        (double)(voxels[Index(x+stepX,y,z,w,h,d)]-voxels[Index(x-stepX,y,z,w,h,d)]) / -stepX,
                        (double)(voxels[Index(x,y+stepY,z,w,h,d)]-voxels[Index(x,y-stepY,z,w,h,d)]) / -stepY,
                        (double)(voxels[Index(x,y,z+stepZ,w,h,d)]-voxels[Index(x,y,z-stepZ,w,h,d)]) / -stepZ
                    },
					{x+stepX,y,z, 
                        (double)(voxels[Index(x+2*stepX,y,z,w,h,d)]-voxels[Index(x,y,z,w,h,d)]) / -stepX,
                        (double)(voxels[Index(x+stepX,y+stepY,z,w,h,d)]-voxels[Index(x+stepX,y-stepY,z,w,h,d)]) / -stepY,
                        (double)(voxels[Index(x+stepX,y,z+stepZ,w,h,d)]-voxels[Index(x+stepX,y,z-stepZ,w,h,d)]) / -stepZ
                    },
					{x+stepX,y,z+stepZ, 
                        (double)(voxels[Index(x+2*stepX,y,z+stepZ,w,h,d)]-voxels[Index(x,y,z+stepZ,w,h,d)]) / -stepX,
                        (double)(voxels[Index(x+stepX,y+stepY,z+stepZ,w,h,d)]-voxels[Index(x+stepX,y-stepY,z+stepZ,w,h,d)]) / -stepY,
                        (double)(voxels[Index(x+stepX,y,z+2*stepZ,w,h,d)]-voxels[Index(x+stepX,y,z,w,h,d)]) / -stepZ
                    },
					{x,y,z+stepZ, 
                        (double)(voxels[Index(x+stepX,y,z+stepZ,w,h,d)]-voxels[Index(x-stepX,y,z+stepZ,w,h,d)]) / -stepX,
                        (double)(voxels[Index(x,y+stepY,z+stepZ,w,h,d)]-voxels[Index(x,y-stepY,z+stepZ,w,h,d)]) / -stepY,
                        (double)(voxels[Index(x,y,z+2*stepZ,w,h,d)]-voxels[Index(x,y,z,w,h,d)]) / -stepZ
                    },
					{x,y+stepY,z, 
                        (double)(voxels[Index(x+stepX,y+stepY,z,w,h,d)]-voxels[Index(x-stepX,y+stepY,z,w,h,d)]) / -stepX,
                        (double)(voxels[Index(x,y+2*stepY,z,w,h,d)]-voxels[Index(x,y,z,w,h,d)]) / -stepY,
                        (double)(voxels[Index(x,y+stepY,z+stepZ,w,h,d)]-voxels[Index(x,y+stepY,z-stepZ,w,h,d)]) / -stepZ
                    },
					{x+stepX,y+stepY,z, 
                        (double)(voxels[Index(x+2*stepX,y+stepY,z,w,h,d)]-voxels[Index(x+stepX,y+stepY,z,w,h,d)]) / -stepX,
                        (double)(voxels[Index(x+stepX,y+2*stepY,z,w,h,d)]-voxels[Index(x+stepX,y,z,w,h,d)]) / -stepY,
                        (double)(voxels[Index(x+stepX,y+stepY,z+stepZ,w,h,d)]-voxels[Index(x+stepX,y+stepY,z-stepZ,w,h,d)]) / -stepZ
                    },
					{x+stepX,y+stepY,z+stepZ, 
                        (double)(voxels[Index(x+2*stepX,y+stepY,z+stepZ,w,h,d)]-voxels[Index(x,y+stepY,z+stepZ,w,h,d)]) / -stepX,
                        (double)(voxels[Index(x+stepX,y+2*stepY,z+stepZ,w,h,d)]-voxels[Index(x+stepX,y,z+stepZ,w,h,d)]) / -stepY,
                        (double)(voxels[Index(x+stepX,y+stepY,z+2*stepZ,w,h,d)]-voxels[Index(x+stepX,y+stepY,z,w,h,d)]) / -stepZ
                    },
					{x,y+stepY,z+stepZ, 
                        (double)(voxels[Index(x+stepX,y+stepY,z+stepZ,w,h,d)]-voxels[Index(x-stepX,y+stepY,z+stepZ,w,h,d)]) / -stepX,
                        (double)(voxels[Index(x,y+2*stepY,z+stepZ,w,h,d)]-voxels[Index(x,y,z+stepZ,w,h,d)]) / -stepY,
                        (double)(voxels[Index(x,y+stepY,z+2*stepZ,w,h,d)]-voxels[Index(x,y+stepY,z,w,h,d)]) / -stepZ
                    }
				},{
					voxels[Index(x,y,z,w,h,d)],
					voxels[Index(x+stepX,y,z,w,h,d)],
					voxels[Index(x+stepX,y,z+stepZ,w,h,d)],
					voxels[Index(x,y,z+stepZ,w,h,d)],
					voxels[Index(x,y+stepY,z,w,h,d)],
					voxels[Index(x+stepX,y+stepY,z,w,h,d)],
					voxels[Index(x+stepX,y+stepY,z+stepZ,w,h,d)],
					voxels[Index(x,y+stepY,z+stepZ,w,h,d)]
				}};*/
				GRIDCELL c={{
					{x,y,z,0,0,0},
					{x+stepX,y,z,0,0,0},
					{x+stepX,y,z+stepZ,0,0,0},
					{x,y,z+stepZ,0,0,0},
					{x,y+stepY,z,0,0,0},
					{x+stepX,y+stepY,z,0,0,0},
					{x+stepX,y+stepY,z+stepZ,0,0,0},
					{x,y+stepY,z+stepZ,0,0,0}
				},{
					voxels[Index(x,y,z,w,h,d)],
					voxels[Index(x+stepX,y,z,w,h,d)],
					voxels[Index(x+stepX,y,z+stepZ,w,h,d)],
					voxels[Index(x,y,z+stepZ,w,h,d)],
					voxels[Index(x,y+stepY,z,w,h,d)],
					voxels[Index(x+stepX,y+stepY,z,w,h,d)],
					voxels[Index(x+stepX,y+stepY,z+stepZ,w,h,d)],
					voxels[Index(x,y+stepY,z+stepZ,w,h,d)]
				}};
				///Polygonise(c, isovalue);
				TRIANGLE triangles[5];
				size_t count=Polygonise(c, isovalue, triangles);
				for (size_t i=0; i<count; i++) {
					AEArrayAddBytes(triangleArray, triangles+i);
				}
			}
		}
	}
}
Exemple #9
0
void CMarchCube::MultiMaterial(CMesh* pMeshOut, void* pArrays, bool SumMat, CColor* pColors, float Thresh, float Scale)
{
	std::vector<CArray3Df>* pDA = (std::vector<CArray3Df>*) pArrays;
	int NumMat = (*pDA).size();

	int Resolution=1;
	Scale=Scale/Resolution;

	//of course, assumes cubic structure!!!
	GRIDCELL GridCell;
	pMeshOut->Clear();

	//innefficient!
	CArray3Df Padded;
	CArray3Df aR;
	CArray3Df aG;
	CArray3Df aB;
	
	Padded.IniSpace(((*pDA)[0].GetXSize()*Resolution)+2, ((*pDA)[0].GetYSize()*Resolution)+2, ((*pDA)[0].GetZSize()*Resolution)+2, 0);
	aR.IniSpace(Padded.GetXSize()*Resolution, Padded.GetYSize()*Resolution, Padded.GetZSize()*Resolution, 0.0);
	aG.IniSpace(Padded.GetXSize()*Resolution, Padded.GetYSize()*Resolution, Padded.GetZSize()*Resolution, 0.0);
	aB.IniSpace(Padded.GetXSize()*Resolution, Padded.GetYSize()*Resolution, Padded.GetZSize()*Resolution, 0.0);

	for (int i=0; i<(*pDA)[0].GetXSize()*Resolution; i++)
		for (int j=0; j<(*pDA)[0].GetYSize()*Resolution; j++)
			for (int k=0; k<(*pDA)[0].GetZSize()*Resolution; k++){

				//find the max, for color (or for thresh, as well if !SumMat)
				float max = -9e9f;
//				float max = 0.0f;

				for (int  m=0; m<NumMat; m++){
					if ((*pDA)[m](i, j, k) > max){
						max = (*pDA)[m](i, j, k);
						if (pColors != NULL){ //grab the colors!
							aR(i+1, j+1, k+1) = pColors[m].r;
							aG(i+1, j+1, k+1) = pColors[m].g;
							aB(i+1, j+1, k+1) = pColors[m].b;
							//fill in outside of padded here if we wish...
							}
						}
					}

				if (SumMat){ //if we're summing the materials to create the mesh...
					for (int  m=0; m<NumMat; m++){
						float ToAdd = ((*pDA)[m])(i, j, k);
						if (m==0) Padded(i+1, j+1, k+1) = ToAdd;
						else Padded(i+1, j+1, k+1) += ToAdd;
					}
				}
				else { //if we're not summing the materials...
					Padded(i+1, j+1, k+1) = max;
				}
				//TRACE("%f\n", Padded(i+1, j+1, k+1));
				}


	//form cubes
	float ai, aj, ak; //jmc: for speed, declare them only once
	
	for (int i=0; i<Padded.GetXSize()*Resolution-1; i++){
		for (int j=0; j<Padded.GetYSize()*Resolution-1; j++){
			for (int k=0; k<Padded.GetZSize()*Resolution-1; k++){
				ai = i-0.5f;
				aj = j-0.5f;
				ak = k-0.5f;
				GridCell.p[0] = CVertex(Vec3D<>(Scale*ai, Scale*aj, Scale*ak), CColor(aR(i, j, k), aG(i, j, k), aB(i, j, k))); 
				GridCell.val[0] = Padded(i, j, k);
				GridCell.p[1] = CVertex(Vec3D<>(Scale*(ai+1), Scale*aj, Scale*ak), CColor(aR(i+1, j, k), aG(i+1, j, k), aB(i+1, j, k)));
				GridCell.val[1] = Padded(i+1, j, k);
				GridCell.p[2] = CVertex(Vec3D<>(Scale*(ai+1), Scale*(aj+1), Scale*ak), CColor(aR(i+1, j+1, k), aG(i+1, j+1, k), aB(i+1, j+1, k)));
				GridCell.val[2] = Padded(i+1, j+1, k);
				GridCell.p[3] = CVertex(Vec3D<>(Scale*ai, Scale*(aj+1), Scale*ak), CColor(aR(i, j+1, k), aG(i, j+1, k), aB(i, j+1, k)));
				GridCell.val[3] = Padded(i, j+1, k);
				GridCell.p[4] = CVertex(Vec3D<>(Scale*ai, Scale*aj, Scale*(ak+1)), CColor(aR(i, j, k+1), aG(i, j, k+1), aB(i, j, k+1)));
				GridCell.val[4] = Padded(i, j, k+1);
				GridCell.p[5] = CVertex(Vec3D<>(Scale*(ai+1), Scale*aj, Scale*(ak+1)), CColor(aR(i+1, j, k+1), aG(i+1, j, k+1), aB(i+1, j, k+1)));
				GridCell.val[5] = Padded(i+1, j, k+1);
				GridCell.p[6] = CVertex(Vec3D<>(Scale*(ai+1), Scale*(aj+1), Scale*(ak+1)), CColor(aR(i+1, j+1, k+1), aG(i+1, j+1, k+1), aB(i+1, j+1, k+1)));
				GridCell.val[6] = Padded(i+1, j+1, k+1);
				GridCell.p[7] = CVertex(Vec3D<>(Scale*ai, Scale*(aj+1), Scale*(ak+1)), CColor(aR(i, j+1, k+1), aG(i, j+1, k+1), aB(i, j+1, k+1)));
				GridCell.val[7] = Padded(i, j+1, k+1);

				Polygonise(GridCell, Thresh, pMeshOut); //crunch this cube and add the vertices...
			}
		}
	}

	pMeshOut->WeldClose(Scale/2);
	pMeshOut->CalcFaceNormals();
	pMeshOut->CalcVertNormals();
	//pMeshOut->WeldClose(Scale);
}
Exemple #10
0
void CMarchCube::SingleMaterialMultiColor(CMesh* pMeshOut, CArray3Df* pArray, CArray3Df* rColorArray, CArray3Df* gColorArray, CArray3Df* bColorArray, float Thresh, float Scale)
{	

	std::vector<CArray3Df> tmpVec; //put in an stl vector to call MultiMaterial()
	tmpVec.push_back(*pArray);

	
	//of course, assumes cubic structure!!!
	GRIDCELL GridCell;
	pMeshOut->Clear();
	
	//innefficient!
	CArray3Df Padded;
	CArray3Df aR;
	CArray3Df aG;
	CArray3Df aB;
	
	Padded.IniSpace(pArray->GetXSize()+2, pArray->GetYSize()+2, pArray->GetZSize()+2, -1e6);
	aR.IniSpace(Padded.GetXSize(), Padded.GetYSize(), Padded.GetZSize(), 0.0);
	aG.IniSpace(Padded.GetXSize(), Padded.GetYSize(), Padded.GetZSize(), 0.0);
	aB.IniSpace(Padded.GetXSize(), Padded.GetYSize(), Padded.GetZSize(), 0.0);
	
	for (int i=0; i<pArray->GetXSize(); i++)
		for (int j=0; j<pArray->GetYSize(); j++)
			for (int k=0; k<pArray->GetZSize(); k++){

				//existince array	
				Padded(i+1, j+1, k+1) = (*pArray)(i,j,k);

				//color arrays
				aR(i+1, j+1, k+1) = (*rColorArray)(i,j,k);
				aG(i+1, j+1, k+1) = (*gColorArray)(i,j,k);
				aB(i+1, j+1, k+1) = (*bColorArray)(i,j,k);
			}
	
	
	//form cubes
	float ai, aj, ak; //jmc: for speed, declare them only once
	
	for (int i=0; i<Padded.GetXSize()-1; i++){
		for (int j=0; j<Padded.GetYSize()-1; j++){
			for (int k=0; k<Padded.GetZSize()-1; k++){
				ai = i-0.5f;
				aj = j-0.5f;
				ak = k-0.5f;
				GridCell.p[0] = CVertex(Vec3D<>(Scale*ai, Scale*aj, Scale*ak), CColor(aR(i, j, k), aG(i, j, k), aB(i, j, k))); //put in ccppn-generated rgb here. 
				GridCell.val[0] = Padded(i, j, k);
				GridCell.p[1] = CVertex(Vec3D<>(Scale*(ai+1), Scale*aj, Scale*ak), CColor(aR(i+1, j, k), aG(i+1, j, k), aB(i+1, j, k)));
				GridCell.val[1] = Padded(i+1, j, k);
				GridCell.p[2] = CVertex(Vec3D<>(Scale*(ai+1), Scale*(aj+1), Scale*ak), CColor(aR(i+1, j+1, k), aG(i+1, j+1, k), aB(i+1, j+1, k)));
				GridCell.val[2] = Padded(i+1, j+1, k);
				GridCell.p[3] = CVertex(Vec3D<>(Scale*ai, Scale*(aj+1), Scale*ak), CColor(aR(i, j+1, k), aG(i, j+1, k), aB(i, j+1, k)));
				GridCell.val[3] = Padded(i, j+1, k);
				GridCell.p[4] = CVertex(Vec3D<>(Scale*ai, Scale*aj, Scale*(ak+1)), CColor(aR(i, j, k+1), aG(i, j, k+1), aB(i, j, k+1)));
				GridCell.val[4] = Padded(i, j, k+1);
				GridCell.p[5] = CVertex(Vec3D<>(Scale*(ai+1), Scale*aj, Scale*(ak+1)), CColor(aR(i+1, j, k+1), aG(i+1, j, k+1), aB(i+1, j, k+1)));
				GridCell.val[5] = Padded(i+1, j, k+1);
				GridCell.p[6] = CVertex(Vec3D<>(Scale*(ai+1), Scale*(aj+1), Scale*(ak+1)), CColor(aR(i+1, j+1, k+1), aG(i+1, j+1, k+1), aB(i+1, j+1, k+1)));
				GridCell.val[6] = Padded(i+1, j+1, k+1);
				GridCell.p[7] = CVertex(Vec3D<>(Scale*ai, Scale*(aj+1), Scale*(ak+1)), CColor(aR(i, j+1, k+1), aG(i, j+1, k+1), aB(i, j+1, k+1)));
				GridCell.val[7] = Padded(i, j+1, k+1);
				
				Polygonise(GridCell, Thresh, pMeshOut); //crunch this cube and add the vertices...
			}
		}
	}
	
	pMeshOut->WeldClose(Scale/2);
}
Exemple #11
0
void MyWidget::MarchingCubes() {

    Vector **triangles = new Vector*[5];
    for (int i = 0; i < 5; i++) {
        triangles[i] = new Vector[3];
    }

    Matrix T(4, 4);
    T.Diag(1);
    T(0, 3) = Tx + 200;
    T(1, 3) = Ty + 150;
    T(2, 3) = Tz;

    Matrix Sc(4, 4);
    Sc(0, 0) = ScX;
    Sc(1, 1) = ScY;
    Sc(2, 2) = ScZ;
    Sc(3, 3) = 1;

    Matrix RX(4, 4);
    RX.Diag(1);
    RX(1, 1) = cos(AlfaX);
    RX(1, 2) = sin(AlfaX);
    RX(2, 1) = -sin(AlfaX);
    RX(2, 2) = cos(AlfaX);

    Matrix RY(4, 4);
    RY.Diag(1);
    RY(0, 0) = cos(AlfaY);
    RY(0, 2) = -sin(AlfaY);
    RY(2, 0) = sin(AlfaY);
    RY(2, 2) = cos(AlfaY);

    Matrix RZ(4, 4);
    RZ.Diag(1);
    RZ(0, 0) = cos(AlfaZ);
    RZ(0, 1) = sin(AlfaZ);
    RZ(1, 0) = -sin(AlfaZ);
    RZ(1, 1) = cos(AlfaZ);

    Matrix m = T.multi(Sc.multi(RX.multi(RY.multi(RZ))));

    T.free();
    Sc.free();
    RX.free();
    RY.free();
    RZ.free();

    Matrix p;

    for (int x = _S; x < fR2; x += _S) {
        for (int y = _S; y < fR2; y += _S) {
            for (int z = _S; z < fR2; z += _S) {
                int n = Polygonise(x, y, z, 1, triangles);
                for (int i = 0; i < n; i++) {
                    Vector tab[3];
                    for (int j = 0; j < 3; j++) {
                        p = m.multi(triangles[i][j]);
                        tab[j] = Vector(p(X, 0), p(Y, 0), p(Z, 0));
                    }
                    Triangle(_bitsDest, tab[0], tab[1], tab[2]);

                    tab[0].free();
                    tab[1].free();
                    tab[2].free();
                }
            }
        }
    }

    m.free();
    p.free();

    for (int i = 0; i < 5; i++) {
        for (int j = 0; j < 3; j++) {
            triangles[i][j].free();
        }
    }
}
Exemple #12
0
void update(void) {
	// if no spheres nothing todo.
	static float frame = 0.0;
	if (!nbSpeheres) 
	{
		return;
	} else {
		frame += 0.05;
		spheres[0].x = 0.2f * (float)sin(frame * 1.0f) + 0.5f;
		spheres[0].y = 0.2f * (float)cos(frame * 1.0f) + 0.5f;
		spheres[1].y = 0.2f * (float)sin(frame * 0.7f) + 0.5f;
		spheres[1].z = 0.2f * (float)cos(frame * 0.7f) + 0.5f;
		spheres[2].z = 0.2f * (float)sin(frame * 1.3f) + 0.5f;
		spheres[2].x = 0.2f * (float)cos(frame * 1.3f) + 0.5f;
	}

	DWORD dwNbVertex = 0;
	// (from dake calodox)
	// modified to fill my needs
	double diffx, diffy, diffz;
	double dist;
	// calculate the metasphere
	for (int gz=0;gz<GRID_Z;gz++)                
	{
		for (int gy=0;gy<GRID_Y;gy++)
		{
			for (int gx=0;gx<GRID_X;gx++)       
			{
				//efface la grille 
				metagrille[gx][gy][gz]=0.0;
				//				double s = gy*gy;
				//				metagrille[gx][gy][gz] = s != 0 ? 1/s : 0;
				for (int n = 0; n < nbSpeheres; ++n)
				{
					diffx= gx - ((spheres[n].x + 1.0) * (GRID_X / 2.0)); 
					diffy= gy - ((spheres[n].y + 1.0) * (GRID_Y / 2.0));
					diffz= gz - ((spheres[n].z + 1.0) * (GRID_Z / 2.0));
					dist = 1.0/
						((diffx * diffx) + (diffy * diffy) + (diffz * diffz));
					metagrille[gx][gy][gz] += dist;
				}
			}
		}
	}

	// TODO add an algo to go faster HERE!!!
	for (int jz = 0; jz < (GRID_Z - 1); ++ jz)
	{
		for (int jy = 0; jy < (GRID_Y - 1); ++ jy)
		{
			for (int jx = 0; jx < (GRID_X - 1); ++ jx)
			{
				gride[jx][jy][jz].val[0] = metagrille[jx][jy][jz];
				gride[jx][jy][jz].val[1] = metagrille[jx + 1][jy][jz];
				gride[jx][jy][jz].val[2] = metagrille[jx + 1][jy + 1][jz];
				gride[jx][jy][jz].val[3] = metagrille[jx][jy + 1][jz];
				gride[jx][jy][jz].val[4] = metagrille[jx][jy][jz + 1];
				gride[jx][jy][jz].val[5] = metagrille[jx + 1][jy][jz + 1];
				gride[jx][jy][jz].val[6] = metagrille[jx + 1][jy + 1][jz + 1];
				gride[jx][jy][jz].val[7] = metagrille[jx][jy + 1][jz + 1];
				DWORD newVert = Polygonise(
					gride[jx][jy][jz], 
					ISO_LEVEL, 
					(TRIANGLE*)&cvVertices[dwNbVertex]) * 3;

				// make the Normals calculation
				for (DWORD pu = 0; pu < newVert; ++pu)
				{
					float vect[3] = {0.0f, 0.0f, 0.0f};
					for (int no = 0; no < nbSpeheres; ++no)
					{
						float dx, dy, dz;
						dx = cvVertices[dwNbVertex + pu].x - spheres[no].x;
						dy = cvVertices[dwNbVertex + pu].y - spheres[no].y;
						dz = cvVertices[dwNbVertex + pu].z - spheres[no].z;
						double mdist = 1.0 / sqrt((dx * dx) + (dy * dy) + (dz * dz));
						vect[0] += (float)(dx * mdist);
						vect[1] += (float)(dy * mdist);
						vect[2] += (float)(dz * mdist);
					}
					// Normalize
					float d = sqrt(
						(vect[0] * vect[0]) +
						(vect[1] * vect[1]) +
						(vect[2] * vect[2]));
					cvVertices[dwNbVertex + pu].nx = vect[0] / d;
					cvVertices[dwNbVertex + pu].ny = vect[1] / d;
					cvVertices[dwNbVertex + pu].nz = vect[2] / d;
				}
				dwNbVertex += newVert;
			}
		}
	}
	dwNbVertices = dwNbVertex;
}
void generate_terrain_points(density_func_t function, float3 min, float3 max, float granularity, std::vector<float3>& vertices) {
    const float inv_gran = 1.0f/granularity;
    // Calculate the grid size
    int32_t x_size = (int32_t)((max.x - min.x) * inv_gran) + 1;
    int32_t y_size = (int32_t)((max.y - min.y) * inv_gran) + 1;
    int32_t z_size = (int32_t)((max.z - min.z) * inv_gran) + 1;
    uint32_t grid_size = x_size * y_size * z_size;

    #define ARRAY_INDEX(_x,_y,_z) ((_z)*x_size*y_size + (_y)*x_size + (_x))
    float4* grid = (float4*)calloc(grid_size, sizeof(float4));

    float xf, yf, zf;
    int xi, yi, zi;
    for(zf = min.z, zi = 0; zi < z_size; ++zi, zf += granularity) {
        for(yf = min.y, yi = 0; yi < y_size; ++yi, yf += granularity) {
            for(xf = min.x, xi = 0; xi < x_size; ++xi, xf += granularity) {
                float4 pt = { xf, yf, zf, 0.0f };
                pt.w = function(*(float3*)&pt);
                grid[ARRAY_INDEX(xi,yi,zi)] = pt;
            }
        }
    }

    for(zi = 0; zi < z_size-1; ++zi) {
        for(yi = 0; yi < y_size-1; ++yi) {
            for(xi = 0; xi < x_size-1; ++xi) {
                gridcell_t cell;
                float4 val;
                int ii=0;
                // Get the cell corners
                val = grid[ARRAY_INDEX(xi, yi, zi)];
                cell.p[ii] = *(float3*)&val;
                cell.val[ii++] = val.w;
                val = grid[ARRAY_INDEX(xi+1, yi, zi)];
                cell.p[ii] = *(float3*)&val;
                cell.val[ii++] = val.w;
                val = grid[ARRAY_INDEX(xi+1, yi, zi+1)];
                cell.p[ii] = *(float3*)&val;
                cell.val[ii++] = val.w;
                val = grid[ARRAY_INDEX(xi, yi, zi+1)];
                cell.p[ii] = *(float3*)&val;
                cell.val[ii++] = val.w;
                
                val = grid[ARRAY_INDEX(xi, yi+1, zi)];
                cell.p[ii] = *(float3*)&val;
                cell.val[ii++] = val.w;
                val = grid[ARRAY_INDEX(xi+1, yi+1, zi)];
                cell.p[ii] = *(float3*)&val;
                cell.val[ii++] = val.w;
                val = grid[ARRAY_INDEX(xi+1, yi+1, zi+1)];
                cell.p[ii] = *(float3*)&val;
                cell.val[ii++] = val.w;
                val = grid[ARRAY_INDEX(xi, yi+1, zi+1)];
                cell.p[ii] = *(float3*)&val;
                cell.val[ii++] = val.w;

                // Polygonize the cell
                triangle_t triangles[5];
                int num_triangles = Polygonise(cell, 0.0f, triangles);
                for(ii=0;ii<num_triangles;++ii) {
                    triangle_t tri = triangles[ii];
                    if(degenerate(tri))
                        continue;
                    for(int jj=2; jj>=0; --jj) {
                        vertices.push_back(tri.p[jj]);
                    }
                }
            }
        }
    }
    free(grid);
}