//Set up variables bool DemoInit() { if(!window.Init("Metaballs", 512, 512, 32, 24, 8, WINDOWED_SCREEN)) return 0; //quit if not created //set up grid if(!cubeGrid.CreateMemory()) return false; if(!cubeGrid.Init(gridSize)) return false; //set up metaballs for(int i=0; i<numMetaballs; i++) metaballs[i].Init(VECTOR3D(0.0f, 0.0f, 0.0f), 5.0f+float(i)); //Set Up Colors diffuseColors[0].Set(0.345f, 0.843f, 0.902f, 1.0f); diffuseColors[1].Set(0.047f, 0.839f, 0.271f, 1.0f); diffuseColors[2].Set(0.976f, 0.213f, 0.847f, 1.0f); //reset timer for start timer.Reset(); return true; }
void drawMetaball(int numMetaballs,const vector< vector<float> >& balls) { const int minGridSize = 10; int gridSize = 30; float threshold = 1.0f; CUBE_GRID cubeGrid; METABALL* metaballs = new METABALL[numMetaballs]; for (int i = 0; i<numMetaballs; i++) metaballs[i].Init(VECTOR3D(balls[i][0], balls[i][1], balls[i][2]), balls[i][3] * balls[i][3]); //init marching cube cubeGrid.CreateMemory(); cubeGrid.Init(gridSize); for (int i = 0; i<cubeGrid.numVertices; i++) { cubeGrid.vertices[i].value = 0.0f; cubeGrid.vertices[i].normal.LoadZero(); } VECTOR3D ballToPoint; float squaredRadius; VECTOR3D ballPosition; float normalScale; for (int i = 0; i<numMetaballs; i++) { squaredRadius = metaballs[i].squaredRadius; ballPosition = metaballs[i].position; //VC++6 standard does not inline functions //by inlining these maually, in this performance-critical area, //almost a 100% increase in speed is found for (int j = 0; j<cubeGrid.numVertices; j++) { //ballToPoint=cubeGrid.vertices[j].position-ballPosition; ballToPoint.x = cubeGrid.vertices[j].position.x - ballPosition.x; ballToPoint.y = cubeGrid.vertices[j].position.y - ballPosition.y; ballToPoint.z = cubeGrid.vertices[j].position.z - ballPosition.z; //get squared distance from ball to point //float squaredDistance=ballToPoint.GetSquaredLength(); float squaredDistance = ballToPoint.x*ballToPoint.x + ballToPoint.y*ballToPoint.y + ballToPoint.z*ballToPoint.z; if (squaredDistance == 0.0f) squaredDistance = 0.0001f; //value = r^2/d^2 cubeGrid.vertices[j].value += squaredRadius / squaredDistance; //normal = (r^2 * v)/d^4 normalScale = squaredRadius / (squaredDistance*squaredDistance); //cubeGrid.vertices[j].normal+=ballToPoint*normalScale; cubeGrid.vertices[j].normal.x += ballToPoint.x*normalScale; cubeGrid.vertices[j].normal.y += ballToPoint.y*normalScale; cubeGrid.vertices[j].normal.z += ballToPoint.z*normalScale; } } //hints glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //need to normalize! glEnable(GL_NORMALIZE); glEnable(GL_CULL_FACE); cubeGrid.DrawSurface(threshold); glDisable(GL_CULL_FACE); cubeGrid.FreeMemory(); delete[] metaballs; }