public double fZ;
};
- // These tables are used so that everything can be done in little
- // loops that you can look at all at once rather than in pages and
- // pages of unrolled code.
-
- // a2fVertexOffset lists the positions, relative to vertex0, of
- // each of the 8 vertices of a cube
- static final double a2fVertexOffset[][] = {
- {0.0, 0.0, 0.0},{1.0, 0.0, 0.0},{1.0, 1.0, 0.0},{0.0, 1.0, 0.0},
- {0.0, 0.0, 1.0},{1.0, 0.0, 1.0},{1.0, 1.0, 1.0},{0.0, 1.0, 1.0}
- };
-
- //a2iEdgeConnection lists the index of the endpoint vertices for each of the 12 edges of the cube
- static final int a2iEdgeConnection[][] = {
- {0,1}, {1,2}, {2,3}, {3,0},
- {4,5}, {5,6}, {6,7}, {7,4},
- {0,4}, {1,5}, {2,6}, {3,7}
- };
-
- //a2fEdgeDirection lists the direction vector (vertex1-vertex0) for each edge in the cube
- static final double a2fEdgeDirection[][] = {
- {1.0, 0.0, 0.0},{0.0, 1.0, 0.0},{-1.0, 0.0, 0.0},{0.0, -1.0, 0.0},
- {1.0, 0.0, 0.0},{0.0, 1.0, 0.0},{-1.0, 0.0, 0.0},{0.0, -1.0, 0.0},
- {0.0, 0.0, 1.0},{0.0, 0.0, 1.0},{ 0.0, 0.0, 1.0},{0.0, 0.0, 1.0}
- };
-
- // a2iTetrahedronEdgeConnection lists the index of the endpoint
- // vertices for each of the 6 edges of the tetrahedron
- static final int a2iTetrahedronEdgeConnection[][] = {
- {0,1}, {1,2}, {2,0}, {0,3}, {1,3}, {2,3}
- };
-
- // a2iTetrahedronEdgeConnection lists the index of verticies from a cube
- // that made up each of the six tetrahedrons within the cube
- static final int a2iTetrahedronsInACube[][] = {
- {0,5,1,6},
- {0,1,2,6},
- {0,2,3,6},
- {0,3,7,6},
- {0,7,4,6},
- {0,4,5,6},
- };
-
- static final double afAmbientWhite [] = {0.25, 0.25, 0.25, 1.00};
- static final double afAmbientRed [] = {0.25, 0.00, 0.00, 1.00};
- static final double afAmbientGreen [] = {0.00, 0.25, 0.00, 1.00};
- static final double afAmbientBlue [] = {0.00, 0.00, 0.25, 1.00};
- static final double afDiffuseWhite [] = {0.75, 0.75, 0.75, 1.00};
- static final double afDiffuseRed [] = {0.75, 0.00, 0.00, 1.00};
- static final double afDiffuseGreen [] = {0.00, 0.75, 0.00, 1.00};
- static final double afDiffuseBlue [] = {0.00, 0.00, 0.75, 1.00};
- static final double afSpecularWhite[] = {1.00, 1.00, 1.00, 1.00};
- static final double afSpecularRed [] = {1.00, 0.25, 0.25, 1.00};
- static final double afSpecularGreen[] = {0.25, 1.00, 0.25, 1.00};
- static final double afSpecularBlue [] = {0.25, 0.25, 1.00, 1.00};
-
GLvector sSourcePoint[] = new GLvector[3];
- /*
- GLenum ePolygonMode = GL_FILL;
- int iDataSetSize = 16;
- double fStepSize = 1.0/iDataSetSize;
- double fTargetValue = 48.0;
- double fTime = 0.0;
- boolean bSpin = true;
- boolean bMove = true;
- boolean bLight = true;
-
-
- void vIdle();
- void vDrawScene();
- void vResize(GLsizei, GLsizei);
- void vKeyboard(unsigned char cKey, int iX, int iY);
- void vSpecial(int iKey, int iX, int iY);
-
- GLvoid vPrintHelp();
- GLvoid vSetTime(double fTime);
- double fSample1(double fX, double fY, double fZ);
- double fSample2(double fX, double fY, double fZ);
- double fSample3(double fX, double fY, double fZ);
- double (*fSample)(double fX, double fY, double fZ) = fSample1;
-
- GLvoid vMarchingCubes();
- GLvoid vMarchCube1(double fX, double fY, double fZ, double fScale);
- GLvoid vMarchCube2(double fX, double fY, double fZ, double fScale);
- GLvoid (*vMarchCube)(double fX, double fY, double fZ, double fScale) = vMarchCube1;
-
- void main(int argc, char **argv)
- {
- double afPropertiesAmbient [] = {0.50, 0.50, 0.50, 1.00};
- double afPropertiesDiffuse [] = {0.75, 0.75, 0.75, 1.00};
- double afPropertiesSpecular[] = {1.00, 1.00, 1.00, 1.00};
-
- GLsizei iWidth = 640.0;
- GLsizei iHeight = 480.0;
-
- glutInit(&argc, argv);
- glutInitWindowPosition( 0, 0);
- glutInitWindowSize(iWidth, iHeight);
- glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
- glutCreateWindow( "Marching Cubes" );
- glutDisplayFunc( vDrawScene );
- glutIdleFunc( vIdle );
- glutReshapeFunc( vResize );
- glutKeyboardFunc( vKeyboard );
- glutSpecialFunc( vSpecial );
-
- glClearColor( 0.0, 0.0, 0.0, 1.0 );
- glClearDepth( 1.0 );
-
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_LIGHTING);
- glPolygonMode(GL_FRONT_AND_BACK, ePolygonMode);
-
- glLightfv( GL_LIGHT0, GL_AMBIENT, afPropertiesAmbient);
- glLightfv( GL_LIGHT0, GL_DIFFUSE, afPropertiesDiffuse);
- glLightfv( GL_LIGHT0, GL_SPECULAR, afPropertiesSpecular);
- glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, 1.0);
-
- glEnable( GL_LIGHT0 );
-
- glMaterialfv(GL_BACK, GL_AMBIENT, afAmbientGreen);
- glMaterialfv(GL_BACK, GL_DIFFUSE, afDiffuseGreen);
- glMaterialfv(GL_FRONT, GL_AMBIENT, afAmbientBlue);
- glMaterialfv(GL_FRONT, GL_DIFFUSE, afDiffuseBlue);
- glMaterialfv(GL_FRONT, GL_SPECULAR, afSpecularWhite);
- glMaterialf( GL_FRONT, GL_SHININESS, 25.0);
-
- vResize(iWidth, iHeight);
-
- vPrintHelp();
- glutMainLoop();
- }
-
- GLvoid vPrintHelp()
- {
- printf("Marching Cubes Example by Cory Bloyd (dejaspaminacan@my-deja.com)\n\n");
-
- printf("+/- increase/decrease sample density\n");
- printf("PageUp/PageDown increase/decrease surface value\n");
- printf("s change sample function\n");
- printf("c toggle marching cubes / marching tetrahedrons\n");
- printf("w wireframe on/off\n");
- printf("l toggle lighting / color-by-normal\n");
- printf("Home spin scene on/off\n");
- printf("End source point animation on/off\n");
- }
-
-
- void vResize( GLsizei iWidth, GLsizei iHeight )
- {
- double fAspect, fHalfWorldSize = (1.4142135623730950488016887242097/2);
-
- glViewport( 0, 0, iWidth, iHeight );
- glMatrixMode (GL_PROJECTION);
- glLoadIdentity ();
-
- if(iWidth <= iHeight)
- {
- fAspect = (double)iHeight / (double)iWidth;
- glOrtho(-fHalfWorldSize, fHalfWorldSize, -fHalfWorldSize*fAspect,
- fHalfWorldSize*fAspect, -10*fHalfWorldSize, 10*fHalfWorldSize);
- }
- else
- {
- fAspect = (double)iWidth / (double)iHeight;
- glOrtho(-fHalfWorldSize*fAspect, fHalfWorldSize*fAspect, -fHalfWorldSize,
- fHalfWorldSize, -10*fHalfWorldSize, 10*fHalfWorldSize);
- }
-
- glMatrixMode( GL_MODELVIEW );
- }
-
- void vKeyboard(unsigned char cKey, int iX, int iY)
- {
- switch(cKey)
- {
- case 'w' :
- {
- if(ePolygonMode == GL_LINE)
- {
- ePolygonMode = GL_FILL;
- }
- else
- {
- ePolygonMode = GL_LINE;
- }
- glPolygonMode(GL_FRONT_AND_BACK, ePolygonMode);
- } break;
- case '+' :
- case '=' :
- {
- ++iDataSetSize;
- fStepSize = 1.0/iDataSetSize;
- } break;
- case '-' :
- {
- if(iDataSetSize > 1)
- {
- --iDataSetSize;
- fStepSize = 1.0/iDataSetSize;
- }
- } break;
- case 'c' :
- {
- if(vMarchCube == vMarchCube1)
- {
- vMarchCube = vMarchCube2;//Use Marching Tetrahedrons
- }
- else
- {
- vMarchCube = vMarchCube1;//Use Marching Cubes
- }
- } break;
- case 's' :
- {
- if(fSample == fSample1)
- {
- fSample = fSample2;
- }
- else if(fSample == fSample2)
- {
- fSample = fSample3;
- }
- else
- {
- fSample = fSample1;
- }
- } break;
- case 'l' :
- {
- if(bLight)
- {
- glDisable(GL_LIGHTING);//use vertex colors
- }
- else
- {
- glEnable(GL_LIGHTING);//use lit material color
- }
-
- bLight = !bLight;
- };
- }
- }
-
-
- void vSpecial(int iKey, int iX, int iY)
- {
- switch(iKey)
- {
- case GLUT_KEY_PAGE_UP :
- {
- if(fTargetValue < 1000.0)
- {
- fTargetValue *= 1.1;
- }
- } break;
- case GLUT_KEY_PAGE_DOWN :
- {
- if(fTargetValue > 1.0)
- {
- fTargetValue /= 1.1;
- }
- } break;
- case GLUT_KEY_HOME :
- {
- bSpin = !bSpin;
- } break;
- case GLUT_KEY_END :
- {
- bMove = !bMove;
- } break;
- }
- }
-
- void vIdle()
- {
- glutPostRedisplay();
- }
-
- void vDrawScene()
- {
- static double fPitch = 0.0;
- static double fYaw = 0.0;
- static double fTime = 0.0;
-
- glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
-
- glPushMatrix();
-
- if(bSpin)
- {
- fPitch += 4.0;
- fYaw += 2.5;
- }
- if(bMove)
- {
- fTime += 0.025;
- }
-
- vSetTime(fTime);
-
- glTranslatef(0.0, 0.0, -1.0);
- glRotatef( -fPitch, 1.0, 0.0, 0.0);
- glRotatef( 0.0, 0.0, 1.0, 0.0);
- glRotatef( fYaw, 0.0, 0.0, 1.0);
-
- glPushAttrib(GL_LIGHTING_BIT);
- glDisable(GL_LIGHTING);
- glColor3f(1.0, 1.0, 1.0);
- glutWireCube(1.0);
- glPopAttrib();
-
-
- glPushMatrix();
- glTranslatef(-0.5, -0.5, -0.5);
- glBegin(GL_TRIANGLES);
- vMarchingCubes();
- glEnd();
- glPopMatrix();
-
-
- glPopMatrix();
-
- glutSwapBuffers();
- }
-
-
-
- //vGetColor generates a color from a given position and normal of a point
- GLvoid vGetColor(GLvector &rfColor, GLvector &rfPosition, GLvector &rfNormal)
- {
- double fX = rfNormal.fX;
- double fY = rfNormal.fY;
- double fZ = rfNormal.fZ;
- rfColor.fX = (fX > 0.0 ? fX : 0.0) + (fY < 0.0 ? -0.5*fY : 0.0) + (fZ < 0.0 ? -0.5*fZ : 0.0);
- rfColor.fY = (fY > 0.0 ? fY : 0.0) + (fZ < 0.0 ? -0.5*fZ : 0.0) + (fX < 0.0 ? -0.5*fX : 0.0);
- rfColor.fZ = (fZ > 0.0 ? fZ : 0.0) + (fX < 0.0 ? -0.5*fX : 0.0) + (fY < 0.0 ? -0.5*fY : 0.0);
- }
-
-
-
- //Generate a sample data set. fSample1(), fSample2() and fSample3() define three scalar fields whose
- // values vary by the X,Y and Z coordinates and by the fTime value set by vSetTime()
- GLvoid vSetTime(double fNewTime)
- {
- double fOffset;
- int iSourceNum;
-
- for(iSourceNum = 0; iSourceNum < 3; iSourceNum++)
- {
- sSourcePoint[iSourceNum].fX = 0.5;
- sSourcePoint[iSourceNum].fY = 0.5;
- sSourcePoint[iSourceNum].fZ = 0.5;
- }
-
- fTime = fNewTime;
- fOffset = 1.0 + sinf(fTime);
- sSourcePoint[0].fX *= fOffset;
- sSourcePoint[1].fY *= fOffset;
- sSourcePoint[2].fZ *= fOffset;
- }
-
-
- //fSample1 finds the distance of (fX, fY, fZ) from three moving points
- double fSample1(double fX, double fY, double fZ)
- {
- GLdouble fResult = 0.0;
- GLdouble fDx, fDy, fDz;
- fDx = fX - sSourcePoint[0].fX;
- fDy = fY - sSourcePoint[0].fY;
- fDz = fZ - sSourcePoint[0].fZ;
- fResult += 0.5/(fDx*fDx + fDy*fDy + fDz*fDz);
-
- fDx = fX - sSourcePoint[1].fX;
- fDy = fY - sSourcePoint[1].fY;
- fDz = fZ - sSourcePoint[1].fZ;
- fResult += 1.0/(fDx*fDx + fDy*fDy + fDz*fDz);
-
- fDx = fX - sSourcePoint[2].fX;
- fDy = fY - sSourcePoint[2].fY;
- fDz = fZ - sSourcePoint[2].fZ;
- fResult += 1.5/(fDx*fDx + fDy*fDy + fDz*fDz);
-
- return fResult;
- }
-
- //fSample2 finds the distance of (fX, fY, fZ) from three moving lines
- double fSample2(double fX, double fY, double fZ)
- {
- GLdouble fResult = 0.0;
- GLdouble fDx, fDy, fDz;
- fDx = fX - sSourcePoint[0].fX;
- fDy = fY - sSourcePoint[0].fY;
- fResult += 0.5/(fDx*fDx + fDy*fDy);
-
- fDx = fX - sSourcePoint[1].fX;
- fDz = fZ - sSourcePoint[1].fZ;
- fResult += 0.75/(fDx*fDx + fDz*fDz);
-
- fDy = fY - sSourcePoint[2].fY;
- fDz = fZ - sSourcePoint[2].fZ;
- fResult += 1.0/(fDy*fDy + fDz*fDz);
-
- return fResult;
- }
-
-
- //fSample2 defines a height field by plugging the distance from the center into the sin and cos functions
- double fSample3(double fX, double fY, double fZ)
- {
- double fHeight = 20.0*(fTime + sqrt((0.5-fX)*(0.5-fX) + (0.5-fY)*(0.5-fY)));
- fHeight = 1.5 + 0.1*(sinf(fHeight) + cosf(fHeight));
- GLdouble fResult = (fHeight - fZ)*50.0;
-
- return fResult;
- }
-
-
-
-
-
-
- //vMarchTetrahedron performs the Marching Tetrahedrons algorithm on a single tetrahedron
- GLvoid vMarchTetrahedron(GLvector *pasTetrahedronPosition, double *pafTetrahedronValue)
- {
- extern int aiTetrahedronEdgeFlags[16];
- extern int a2iTetrahedronTriangles[16][7];
-
- int iEdge, iVert0, iVert1, iEdgeFlags, iTriangle, iCorner, iVertex, iFlagIndex = 0;
- double fOffset, fInvOffset, fValue = 0.0;
- GLvector asEdgeVertex[6];
- GLvector asEdgeNorm[6];
- GLvector sColor;
-
- //Find which vertices are inside of the surface and which are outside
- for(iVertex = 0; iVertex < 4; iVertex++)
- {
- if(pafTetrahedronValue[iVertex] <= fTargetValue)
- iFlagIndex |= 1<<iVertex;
- }
-
- //Find which edges are intersected by the surface
- iEdgeFlags = aiTetrahedronEdgeFlags[iFlagIndex];
-
- //If the tetrahedron is entirely inside or outside of the surface, then there will be no intersections
- if(iEdgeFlags == 0)
- {
- return;
- }
- //Find the point of intersection of the surface with each edge
- // Then find the normal to the surface at those points
- for(iEdge = 0; iEdge < 6; iEdge++)
- {
- //if there is an intersection on this edge
- if(iEdgeFlags & (1<<iEdge))
- {
- iVert0 = a2iTetrahedronEdgeConnection[iEdge][0];
- iVert1 = a2iTetrahedronEdgeConnection[iEdge][1];
- fOffset = fGetOffset(pafTetrahedronValue[iVert0], pafTetrahedronValue[iVert1], fTargetValue);
- fInvOffset = 1.0 - fOffset;
-
- asEdgeVertex[iEdge].fX = fInvOffset*pasTetrahedronPosition[iVert0].fX + fOffset*pasTetrahedronPosition[iVert1].fX;
- asEdgeVertex[iEdge].fY = fInvOffset*pasTetrahedronPosition[iVert0].fY + fOffset*pasTetrahedronPosition[iVert1].fY;
- asEdgeVertex[iEdge].fZ = fInvOffset*pasTetrahedronPosition[iVert0].fZ + fOffset*pasTetrahedronPosition[iVert1].fZ;
-
- vGetNormal(asEdgeNorm[iEdge], asEdgeVertex[iEdge].fX, asEdgeVertex[iEdge].fY, asEdgeVertex[iEdge].fZ);
- }
- }
- //Draw the triangles that were found. There can be up to 2 per tetrahedron
- for(iTriangle = 0; iTriangle < 2; iTriangle++)
- {
- if(a2iTetrahedronTriangles[iFlagIndex][3*iTriangle] < 0)
- break;
-
- for(iCorner = 0; iCorner < 3; iCorner++)
- {
- iVertex = a2iTetrahedronTriangles[iFlagIndex][3*iTriangle+iCorner];
-
- vGetColor(sColor, asEdgeVertex[iVertex], asEdgeNorm[iVertex]);
- glColor3f(sColor.fX, sColor.fY, sColor.fZ);
- glNormal3f(asEdgeNorm[iVertex].fX, asEdgeNorm[iVertex].fY, asEdgeNorm[iVertex].fZ);
- glVertex3f(asEdgeVertex[iVertex].fX, asEdgeVertex[iVertex].fY, asEdgeVertex[iVertex].fZ);
- }
- }
- }
-
-
-
- //vMarchCube2 performs the Marching Tetrahedrons algorithm on a single cube by making six calls to vMarchTetrahedron
- GLvoid vMarchCube2(double fX, double fY, double fZ, double fScale)
- {
- int iVertex, iTetrahedron, iVertexInACube;
- GLvector asCubePosition[8];
- double afCubeValue[8];
- GLvector asTetrahedronPosition[4];
- double afTetrahedronValue[4];
-
- //Make a local copy of the cube's corner positions
- for(iVertex = 0; iVertex < 8; iVertex++)
- {
- asCubePosition[iVertex].fX = fX + a2fVertexOffset[iVertex][0]*fScale;
- asCubePosition[iVertex].fY = fY + a2fVertexOffset[iVertex][1]*fScale;
- asCubePosition[iVertex].fZ = fZ + a2fVertexOffset[iVertex][2]*fScale;
- }
-
- //Make a local copy of the cube's corner values
- for(iVertex = 0; iVertex < 8; iVertex++)
- {
- afCubeValue[iVertex] = fSample(asCubePosition[iVertex].fX,
- asCubePosition[iVertex].fY,
- asCubePosition[iVertex].fZ);
- }
-
- for(iTetrahedron = 0; iTetrahedron < 6; iTetrahedron++)
- {
- for(iVertex = 0; iVertex < 4; iVertex++)
- {
- iVertexInACube = a2iTetrahedronsInACube[iTetrahedron][iVertex];
- asTetrahedronPosition[iVertex].fX = asCubePosition[iVertexInACube].fX;
- asTetrahedronPosition[iVertex].fY = asCubePosition[iVertexInACube].fY;
- asTetrahedronPosition[iVertex].fZ = asCubePosition[iVertexInACube].fZ;
- afTetrahedronValue[iVertex] = afCubeValue[iVertexInACube];
- }
- vMarchTetrahedron(asTetrahedronPosition, afTetrahedronValue);
- }
- }
- */
-
-
- // vMarchingCubes iterates over the entire dataset, calling vMarchCube on each cube
- void vMarchingCubes(int iDataSetSize, int fStepSize)
- {
- int iX, iY, iZ;
- for(iX = 0; iX < iDataSetSize; iX++)
- for(iY = 0; iY < iDataSetSize; iY++)
- for(iZ = 0; iZ < iDataSetSize; iZ++)
- {
- vMarchCube(iX*fStepSize, iY*fStepSize, iZ*fStepSize, fStepSize);
- }
- }
-
public abstract double fSample(double x, double y, double z);
- public abstract double fTargetValue();
//vGetNormal() finds the gradient of the scalar field at a point
//This gradient can be used as a very accurate vertx normal for lighting calculations
return (fValueDesired - fValue1)/fDelta;
}
+ // vMarchingCubes iterates over the entire dataset, calling vMarchCube on each cube
+ void vMarchingCubes(Mesh mesh, double targetValue, int iDataSetSize, int fStepSize) {
+ int iX, iY, iZ;
+ for(iX = 0; iX < iDataSetSize; iX++)
+ for(iY = 0; iY < iDataSetSize; iY++)
+ for(iZ = 0; iZ < iDataSetSize; iZ++)
+ vMarchCube(mesh, targetValue, iX*fStepSize, iY*fStepSize, iZ*fStepSize, fStepSize);
+ }
+
//vMarchCube performs the Marching Cubes algorithm on a single cube
- void vMarchCube(double fX, double fY, double fZ, double fScale) {
+ void vMarchCube(Mesh mesh, double targetValue, double fX, double fY, double fZ, double fScale) {
int iCorner, iVertex, iVertexTest, iEdge, iTriangle, iFlagIndex, iEdgeFlags;
double fOffset;
GLvector sColor;
//Find which vertices are inside of the surface and which are outside
iFlagIndex = 0;
for(iVertexTest = 0; iVertexTest < 8; iVertexTest++) {
- if(afCubeValue[iVertexTest] <= fTargetValue())
+ if(afCubeValue[iVertexTest] <= targetValue)
iFlagIndex |= 1<<iVertexTest;
}
//if there is an intersection on this edge
if ((iEdgeFlags & (1<<iEdge))!=0) {
fOffset = fGetOffset(afCubeValue[ a2iEdgeConnection[iEdge][0] ],
- afCubeValue[ a2iEdgeConnection[iEdge][1] ], fTargetValue());
+ afCubeValue[ a2iEdgeConnection[iEdge][1] ], targetValue);
asEdgeVertex[iEdge].fX = fX + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][0] + fOffset * a2fEdgeDirection[iEdge][0]) * fScale;
asEdgeVertex[iEdge].fY = fY + (a2fVertexOffset[ a2iEdgeConnection[iEdge][0] ][1] + fOffset * a2fEdgeDirection[iEdge][1]) * fScale;
}
}
+ ////////////////////////////////////////////////////////////////////////////////////////
+ // Tables //////////////////////////////////////////////////////////////////////////////
+
+ // These tables are used so that everything can be done in little
+ // loops that you can look at all at once rather than in pages and
+ // pages of unrolled code.
+
+ // a2fVertexOffset lists the positions, relative to vertex0, of
+ // each of the 8 vertices of a cube
+ static final double a2fVertexOffset[][] = {
+ {0.0, 0.0, 0.0},{1.0, 0.0, 0.0},{1.0, 1.0, 0.0},{0.0, 1.0, 0.0},
+ {0.0, 0.0, 1.0},{1.0, 0.0, 1.0},{1.0, 1.0, 1.0},{0.0, 1.0, 1.0}
+ };
+
+ //a2iEdgeConnection lists the index of the endpoint vertices for each of the 12 edges of the cube
+ static final int a2iEdgeConnection[][] = {
+ {0,1}, {1,2}, {2,3}, {3,0},
+ {4,5}, {5,6}, {6,7}, {7,4},
+ {0,4}, {1,5}, {2,6}, {3,7}
+ };
+
+ //a2fEdgeDirection lists the direction vector (vertex1-vertex0) for each edge in the cube
+ static final double a2fEdgeDirection[][] = {
+ {1.0, 0.0, 0.0},{0.0, 1.0, 0.0},{-1.0, 0.0, 0.0},{0.0, -1.0, 0.0},
+ {1.0, 0.0, 0.0},{0.0, 1.0, 0.0},{-1.0, 0.0, 0.0},{0.0, -1.0, 0.0},
+ {0.0, 0.0, 1.0},{0.0, 0.0, 1.0},{ 0.0, 0.0, 1.0},{0.0, 0.0, 1.0}
+ };
+
+ // a2iTetrahedronEdgeConnection lists the index of the endpoint
+ // vertices for each of the 6 edges of the tetrahedron
+ static final int a2iTetrahedronEdgeConnection[][] = {
+ {0,1}, {1,2}, {2,0}, {0,3}, {1,3}, {2,3}
+ };
+
+ // a2iTetrahedronEdgeConnection lists the index of verticies from a cube
+ // that made up each of the six tetrahedrons within the cube
+ static final int a2iTetrahedronsInACube[][] = {
+ {0,5,1,6},
+ {0,1,2,6},
+ {0,2,3,6},
+ {0,3,7,6},
+ {0,7,4,6},
+ {0,4,5,6},
+ };
+
// For any edge, if one vertex is inside of the surface and the
// other is outside of the surface then the edge intersects the
// set to 1
static int aiTetrahedronEdgeFlags[] = {
- 0x00, 0x0d, 0x13, 0x1e, 0x26, 0x2b, 0x35, 0x38, 0x38, 0x35, 0x2b, 0x26, 0x1e, 0x13, 0x0d, 0x00,
+ 0x00, 0x0d, 0x13, 0x1e, 0x26, 0x2b, 0x35, 0x38,
+ 0x38, 0x35, 0x2b, 0x26, 0x1e, 0x13, 0x0d, 0x00,
};
// the table, if edge #n is intersected, then bit #n is set to 1
int aiCubeEdgeFlags[] = {
- 0x000, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
- 0x190, 0x099, 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
- 0x230, 0x339, 0x033, 0x13a, 0x636, 0x73f, 0x435, 0x53c, 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
- 0x3a0, 0x2a9, 0x1a3, 0x0aa, 0x7a6, 0x6af, 0x5a5, 0x4ac, 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
- 0x460, 0x569, 0x663, 0x76a, 0x066, 0x16f, 0x265, 0x36c, 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
- 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0x0ff, 0x3f5, 0x2fc, 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
- 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x055, 0x15c, 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
- 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0x0cc, 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
- 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, 0x0cc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
- 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, 0x15c, 0x055, 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
- 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, 0x2fc, 0x3f5, 0x0ff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
- 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, 0x36c, 0x265, 0x16f, 0x066, 0x76a, 0x663, 0x569, 0x460,
- 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, 0x4ac, 0x5a5, 0x6af, 0x7a6, 0x0aa, 0x1a3, 0x2a9, 0x3a0,
- 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x033, 0x339, 0x230,
- 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x099, 0x190,
- 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x000
+ 0x000, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
+ 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
+ 0x190, 0x099, 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
+ 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
+ 0x230, 0x339, 0x033, 0x13a, 0x636, 0x73f, 0x435, 0x53c,
+ 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
+ 0x3a0, 0x2a9, 0x1a3, 0x0aa, 0x7a6, 0x6af, 0x5a5, 0x4ac,
+ 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
+ 0x460, 0x569, 0x663, 0x76a, 0x066, 0x16f, 0x265, 0x36c,
+ 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
+ 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0x0ff, 0x3f5, 0x2fc,
+ 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
+ 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x055, 0x15c,
+ 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
+ 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0x0cc,
+ 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
+ 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
+ 0x0cc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
+ 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
+ 0x15c, 0x055, 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
+ 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
+ 0x2fc, 0x3f5, 0x0ff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
+ 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
+ 0x36c, 0x265, 0x16f, 0x066, 0x76a, 0x663, 0x569, 0x460,
+ 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
+ 0x4ac, 0x5a5, 0x6af, 0x7a6, 0x0aa, 0x1a3, 0x2a9, 0x3a0,
+ 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
+ 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x033, 0x339, 0x230,
+ 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
+ 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x099, 0x190,
+ 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
+ 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x000
};
// For each of the possible vertex states listed in