VoxelCube.cpp

Go to the documentation of this file.
00001 
00015 #include "../common/standard.h"
00016 #include "VoxelCube.h"
00017 #include "GLBitmapBuffer.h"
00018 #include "MarchingCubesTables.h"
00019 #include "GLutils.h"
00020 
00021 #include <GL/glu.h>
00022 
00023 #include <map>
00024 
00025 
00030 std::vector< Vertex > VoxelCube::calculateVoxelCorners (int xpos, int ypos, int zpos) const
00031 {
00032     double halfVoxelSize = voxelSize / 2.;
00033     double halfCubeSize = voxelsPerSide * halfVoxelSize;
00034 
00035     Vertex origin = Vertex (-halfCubeSize + center[0], -halfCubeSize + center[1], -halfCubeSize + center[2]);
00036 
00037     origin[0] += voxelSize * xpos;
00038     origin[1] += voxelSize * ypos;
00039     origin[2] += voxelSize * zpos;
00040 
00041     std::vector< Vertex > rtn;
00042     for (int z = 0; z < 2; z++)
00043     {
00044         for (int y = 0; y < 2; y++)
00045         {
00046             for (int x = 0; x < 2; x++)
00047             {
00048                 Vertex pt = origin;
00049                 pt[0] += voxelSize*x;
00050                 pt[1] += voxelSize*y;
00051                 pt[2] += voxelSize*z;
00052 
00053                 rtn.push_back (pt);
00054             }
00055         }
00056     }
00057 
00058     return rtn;
00059 }
00060 
00061 
00067 void VoxelCube::setTransparent(SurfaceVoxelList::iterator i)
00068 {
00069     VoxelPos &p = *i;
00070     int index = PosToIndex (p[0], p[1], p[2]);
00071     solids[index] = false;
00072 }
00073 
00074 
00080 void VoxelCube::exposeSurroundingVoxels (SurfaceVoxelList::iterator i)
00081 {
00082     VoxelPos &p = *i;
00083 
00084     unsigned int x = p[0];
00085     unsigned int y = p[1];
00086     unsigned int z = p[2];
00087 
00088 /*
00089  * Enumerate the possible surrounding voxels
00090  */
00091     VoxelPos x1(x-1, y,   z);
00092     VoxelPos y1(x,   y-1, z);
00093     VoxelPos z1(x,   y,   z-1);
00094     VoxelPos x2(x+1, y,   z);
00095     VoxelPos y2(x,   y+1, z);
00096     VoxelPos z2(x,   y,   z+1);
00097 
00098 /* 
00099  * Add surrounding voxels to the SVL. 
00100  */
00101     unsigned int maxVoxel = voxelsPerSide - 1;
00102 
00103     if (x > 0 && !isTransparent(x1)) svl.push_back (x1);
00104     if (y > 0 && !isTransparent(y1)) svl.push_back (y1);
00105     if (z > 0 && !isTransparent(z1)) svl.push_back (z1);
00106 
00107     if (x < maxVoxel && !isTransparent(x2)) svl.push_back (x2);
00108     if (y < maxVoxel && !isTransparent(y2)) svl.push_back (y2);
00109     if (z < maxVoxel && !isTransparent(z2)) svl.push_back (z2);
00110 }
00111 
00112 
00113 
00122 void VoxelCube::setFinalColor (SurfaceVoxelList::iterator i, RgbByte &color)
00123 {
00124     VoxelPos &pos = *i;
00125 
00126     ColoredVoxelPos cvp(pos, color);
00127 
00128     svlColored.push_back (cvp);
00129 }
00130 
00131 
00132 
00136 void VoxelCube::fillItemBufferArray (Viewpoint &image)
00137 {
00138     GLBitmapBuffer bitbuff;
00139     int width = image.getWidth();
00140     int height = image.getHeight();
00141 
00142 /*
00143  * Make our bitmap buffer, and set up the image's perspective
00144  */
00145     bitbuff.create(width, height);
00146     bitbuff.select();
00147 
00148     // set the projection matrix
00149     glMatrixMode(GL_PROJECTION);
00150     glLoadMatrixd(image.getProjectionMatrix());
00151 
00152     // set the modelview matrix
00153     glMatrixMode(GL_MODELVIEW);
00154     glLoadMatrixd(image.getModelviewMatrix());
00155 
00156     // set the viewport
00157     glViewport (0, 0, width, height);
00158     glEnable (GL_DEPTH_TEST);        
00159     glEnable (GL_CULL_FACE);
00160 /*
00161  * Draw to the bitmap buffer
00162  */
00163     glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00164 
00165     double halfVoxelSize = voxelSize / 2.;
00166     double halfCubeSize = voxelsPerSide * halfVoxelSize;
00167 
00168     glMatrixMode (GL_MODELVIEW);
00169     glPushMatrix();
00170         glTranslated(center[0], center[1], center[2]);
00171         glTranslated (-halfCubeSize, -halfCubeSize, -halfCubeSize);
00172         glTranslated (halfVoxelSize, halfVoxelSize, halfVoxelSize);
00173         
00174             SurfaceVoxelList::iterator i;
00175             unsigned int id;
00176             for (i = svl.begin(); i != svl.end(); i++)
00177             {
00178                 VoxelPos &pos = *i;
00179                 glPushMatrix();
00180                     glTranslated (pos[0]*voxelSize, pos[1]*voxelSize, pos[2]*voxelSize);
00181 
00182                     id = PosToIdentifier(pos[0], pos[1], pos[2]);
00183                     glColor3ubv ((GLubyte*)&id);
00184                     
00185                     drawCube (voxelSize, GL_QUADS);
00186                 glPopMatrix();
00187             }
00188 
00189     glPopMatrix();
00190 
00191     glFinish();
00192 
00193     // copy the bitmap buffer to the image's item buffer
00194     glReadPixels (
00195         0, 0, 
00196         width, height,
00197         GL_RGBA, GL_UNSIGNED_BYTE,
00198         &image.imageBuffer[0]);
00199 
00200     bitbuff.unselect();
00201 }
00202 
00203 
00204 
00211 ColorVertex Interpolate(Vertex &v1, Vertex &v2, double tVal1, double tVal2, float isoLevel)
00212 {
00213         ColorVertex interpolation;
00214         float mu;
00215 
00216         mu = float((isoLevel - tVal1))/(tVal2 - tVal1);
00217         interpolation.pos[0] = v1[0] + mu*(v2[0] - v1[0]);
00218         interpolation.pos[1] = v1[1] + mu*(v2[1] - v1[1]);
00219         interpolation.pos[2] = v1[2] + mu*(v2[2] - v1[2]);
00220 
00221         return interpolation;
00222 }
00223 
00224 
00225 
00232 ColorVertex VoxelCube::calculateIntersection(ColVector< 3, unsigned int> &curOrigin, unsigned int nEdgeNo, float isoLevel, ColorMap &colorMap)
00233 {
00234         float x1, y1, z1, x2, y2, z2;
00235         unsigned int v1x = curOrigin[0], v1y = curOrigin[1], v1z = curOrigin[2];
00236         unsigned int v2x = curOrigin[0], v2y = curOrigin[1], v2z = curOrigin[2];
00237         
00238         switch (nEdgeNo)
00239         {
00240         case 0:
00241                 v2y += 1;
00242                 break;
00243         case 1:
00244                 v1y += 1;
00245                 v2x += 1;
00246                 v2y += 1;
00247                 break;
00248         case 2:
00249                 v1x += 1;
00250                 v1y += 1;
00251                 v2x += 1;
00252                 break;
00253         case 3:
00254                 v1x += 1;
00255                 break;
00256         case 4:
00257                 v1z += 1;
00258                 v2y += 1;
00259                 v2z += 1;
00260                 break;
00261         case 5:
00262                 v1y += 1;
00263                 v1z += 1;
00264                 v2x += 1;
00265                 v2y += 1;
00266                 v2z += 1;
00267                 break;
00268         case 6:
00269                 v1x += 1;
00270                 v1y += 1;
00271                 v1z += 1;
00272                 v2x += 1;
00273                 v2z += 1;
00274                 break;
00275         case 7:
00276                 v1x += 1;
00277                 v1z += 1;
00278                 v2z += 1;
00279                 break;
00280         case 8:
00281                 v2z += 1;
00282                 break;
00283         case 9:
00284                 v1y += 1;
00285                 v2y += 1;
00286                 v2z += 1;
00287                 break;
00288         case 10:
00289                 v1x += 1;
00290                 v1y += 1;
00291                 v2x += 1;
00292                 v2y += 1;
00293                 v2z += 1;
00294                 break;
00295         case 11:
00296                 v1x += 1;
00297                 v2x += 1;
00298                 v2z += 1;
00299                 break;
00300         }
00301 
00302         x1 = v1x*voxelSize;
00303         y1 = v1y*voxelSize;
00304         z1 = v1z*voxelSize;
00305         x2 = v2x*voxelSize;
00306         y2 = v2y*voxelSize;
00307         z2 = v2z*voxelSize;
00308 
00309         unsigned int nPointsInXDirection = (voxelsPerSide);
00310         unsigned int nPointsInSlice = nPointsInXDirection*(voxelsPerSide);
00311         int val1 = !isTransparent(v1x, v1y, v1z);
00312     int val2 = !isTransparent(v2x, v2y, v2z);
00313 
00314     ColorVertex intersection = Interpolate(
00315         Vertex(x1, y1, z1),
00316         Vertex(x2, y2, z2),
00317         val1, val2, isoLevel);
00318 
00319     VoxelPos va(v1x, v1y, v1z);
00320     VoxelPos vb(v2x, v2y, v2z);
00321 
00322     RgbByte color1 (0,0,0);
00323     RgbByte color2 (0,0,0);
00324 
00325     ColorMap::iterator i;
00326 #if 0
00327     i = colorMap.find(va);
00328     if (i != colorMap.end()) color1 = (*i).second;
00329 
00330     i = colorMap.find(vb);
00331     if (i != colorMap.end()) color2 = (*i).second;
00332 
00333     intersection.color = LERP(0.5,
00334         color1,
00335         color2);
00336 #else
00337     ColorMap::iterator i_first = colorMap.find(va);
00338     ColorMap::iterator i_second = colorMap.find(vb);
00339 
00340     if (i_first != colorMap.end())
00341     {
00342         if (i_second != colorMap.end())
00343             intersection.color = LERP(0.5, (*i_first).second, (*i_second).second);
00344         else
00345             intersection.color = (*i_first).second;
00346     }
00347     else
00348     {
00349         if (i_second != colorMap.end())
00350             intersection.color = (*i_second).second;
00351         else
00352             intersection.color = RgbByte(1,0,0);
00353     }
00354 #endif
00355 
00356 
00357     
00358         return intersection;
00359 }
00360 
00361 
00362 
00363 
00364 
00371 unsigned int VoxelCube::GetEdgeID(unsigned int nX, unsigned int nY, unsigned int nZ, unsigned int nEdgeNo)
00372 {
00373         switch (nEdgeNo) {
00374         case 0:
00375                 return PosToIndex(nX, nY, nZ) + 1;
00376         case 1:
00377                 return PosToIndex(nX, nY + 1, nZ);
00378         case 2:
00379                 return PosToIndex(nX + 1, nY, nZ) + 1;
00380         case 3:
00381                 return PosToIndex(nX, nY, nZ);
00382         case 4:
00383                 return PosToIndex(nX, nY, nZ + 1) + 1;
00384         case 5:
00385                 return PosToIndex(nX, nY + 1, nZ + 1);
00386         case 6:
00387                 return PosToIndex(nX + 1, nY, nZ + 1) + 1;
00388         case 7:
00389                 return PosToIndex(nX, nY, nZ + 1);
00390         case 8:
00391                 return PosToIndex(nX, nY, nZ) + 2;
00392         case 9:
00393                 return PosToIndex(nX, nY + 1, nZ) + 2;
00394         case 10:
00395                 return PosToIndex(nX + 1, nY + 1, nZ) + 2;
00396         case 11:
00397                 return PosToIndex(nX + 1, nY, nZ) + 2;
00398         default:
00399                 // Invalid edge no.
00400                 throw ArgError("GetEdgeID(): invalid edge number");
00401         }
00402 }
00403 
00404 struct TRIANGLE {
00405         unsigned int pointID[3];
00406 };
00407 
00408 typedef std::map< unsigned int, ColorVertex > IdToVertexMap;
00409 typedef std::vector< TRIANGLE > TriangleArray;
00410 
00411 
00412 
00413 void VoxelCube::constructColorMap (ColorMap &colorMap)
00414 {
00415     if (!svlColored.size())
00416         return;
00417 
00418     ColoredSurfaceVoxelList::iterator i;
00419     for (i = svlColored.begin(); i != svlColored.end(); i++)
00420     {
00421         ColoredVoxelPos pos = (*i);
00422         
00423         VoxelPos p;
00424         p[0] = pos[0]; p[1] = pos[1]; p[2] = pos[2];
00425         colorMap[p] = pos.color;
00426     }
00427 }
00428 
00429 
00430 
00437 void VoxelCube::makeMesh(float isoLevel, QEM::ProgMesh &mesh)
00438 {
00439     ColorMap colorMap;
00440     constructColorMap (colorMap);
00441     
00442     unsigned int nCells = voxelsPerSide - 1;
00443 
00444     IdToVertexMap idVertexMap;
00445     TriangleArray tris;
00446 
00447     for (int z = 0; z < nCells; z++)
00448     {
00449         for (int y = 0; y < nCells; y++)
00450         {
00451             for (int x = 0; x < nCells; x++)
00452             {
00453                 unsigned int tableIndex = 0;
00454                 ColVector<3, unsigned int> curOrigin (x,y,z);
00455                 
00456                 if (isTransparent (x,   y ,  z))   tableIndex |= 1;   // 1 << 0
00457                 if (isTransparent (x,   y+1, z))   tableIndex |= 2;   // 1 << 1
00458                 if (isTransparent (x+1, y+1, z))   tableIndex |= 4;   // 1 << 2
00459                 if (isTransparent (x+1, y,   z))   tableIndex |= 8;   // 1 << 3
00460                 if (isTransparent (x,   y,   z+1)) tableIndex |= 16;  // 1 << 4
00461                 if (isTransparent (x,   y+1, z+1)) tableIndex |= 32;  // 1 << 5
00462                 if (isTransparent (x+1, y+1, z+1)) tableIndex |= 64;  // 1 << 6
00463                 if (isTransparent (x+1, y,   z+1)) tableIndex |= 128; // 1 << 7
00464                 
00465                 if (edgeTable[tableIndex] == 0)
00466                     continue;
00467                 
00468 #define EDGETABLE_HAS(n) edgeTable[tableIndex] & (1 << n)
00469                 
00470                 // Now create a triangulation of the isosurface in this
00471                 // cell.
00472                 if (EDGETABLE_HAS (3)) {
00473                     ColorVertex pt = calculateIntersection (curOrigin, 3, isoLevel, colorMap);
00474                     unsigned int id = GetEdgeID(x, y, z, 3);
00475                     idVertexMap[id] = pt;
00476                 }
00477                 if (EDGETABLE_HAS(0)) {
00478                     ColorVertex pt = calculateIntersection (curOrigin, 0, isoLevel, colorMap);
00479                     unsigned int id = GetEdgeID(x, y, z, 0);
00480                     idVertexMap[id] = pt;
00481                 }
00482                 if (EDGETABLE_HAS(8)) {
00483                     ColorVertex pt = calculateIntersection (curOrigin, 8, isoLevel, colorMap);
00484                     unsigned int id = GetEdgeID(x, y, z, 8);
00485                     idVertexMap[id] = pt;
00486                 }
00487                 
00488                 if (x == nCells - 1) {
00489                     if (EDGETABLE_HAS(2)) {
00490                         ColorVertex pt = calculateIntersection (curOrigin, 2, isoLevel, colorMap);
00491                         unsigned int id = GetEdgeID(x, y, z, 2);
00492                         idVertexMap[id] = pt;
00493                     }
00494                     if (EDGETABLE_HAS(11)) {
00495                         ColorVertex pt = calculateIntersection (curOrigin, 11, isoLevel, colorMap);
00496                         unsigned int id = GetEdgeID(x, y, z, 11);
00497                         idVertexMap[id] = pt;
00498                     }
00499                 }
00500                 if (y == nCells - 1) {
00501                     if (EDGETABLE_HAS(1)) {
00502                         ColorVertex pt = calculateIntersection (curOrigin, 1, isoLevel, colorMap);
00503                         unsigned int id = GetEdgeID(x, y, z, 1);
00504                         idVertexMap[id] = pt;
00505                     }
00506                     if (EDGETABLE_HAS(9)) {
00507                         ColorVertex pt = calculateIntersection (curOrigin, 9, isoLevel, colorMap);
00508                         unsigned int id = GetEdgeID(x, y, z, 9);
00509                         idVertexMap[id] = pt;
00510                     }
00511                 }
00512                 if (z == nCells - 1) {
00513                     if (EDGETABLE_HAS(4)) {
00514                         ColorVertex pt = calculateIntersection (curOrigin, 4, isoLevel, colorMap);
00515                         unsigned int id = GetEdgeID(x, y, z, 4);
00516                         idVertexMap[id] = pt;
00517                     }
00518                     if (EDGETABLE_HAS(7)) {
00519                         ColorVertex pt = calculateIntersection (curOrigin, 7, isoLevel, colorMap);
00520                         unsigned int id = GetEdgeID(x, y, z, 7);
00521                         idVertexMap[id] = pt;
00522                     }
00523                 }
00524                 if ((x==nCells - 1) && (y==nCells - 1))
00525                 {
00526                     if (EDGETABLE_HAS(10)) 
00527                     {
00528                         ColorVertex pt = calculateIntersection (curOrigin, 10, isoLevel, colorMap);
00529                         unsigned int id = GetEdgeID(x, y, z, 10);
00530                         idVertexMap[id] = pt;
00531                     }
00532                 }
00533                 if ((x==nCells - 1) && (z==nCells - 1))
00534                 {
00535                     if (EDGETABLE_HAS(6)) 
00536                     {
00537                         ColorVertex pt = calculateIntersection (curOrigin, 6, isoLevel, colorMap);
00538                         unsigned int id = GetEdgeID(x, y, z, 6);
00539                         idVertexMap[id] = pt;
00540                     }
00541                 }
00542                 if ((y==nCells - 1) && (z==nCells - 1))
00543                 {
00544                     if (EDGETABLE_HAS(5)) {
00545                         ColorVertex pt = calculateIntersection (curOrigin, 5, isoLevel, colorMap);
00546                         unsigned int id = GetEdgeID(x, y, z, 5);
00547                         idVertexMap[id] = pt;
00548                     }
00549                 }
00550                 
00551                 for (unsigned int i = 0; triTable[tableIndex][i] != -1; i += 3) {
00552 
00553                     TRIANGLE triangle;
00554                     unsigned int pointID0, pointID1, pointID2;
00555                     pointID0 = GetEdgeID(x, y, z, triTable[tableIndex][i]);
00556                     pointID1 = GetEdgeID(x, y, z, triTable[tableIndex][i+1]);
00557                     pointID2 = GetEdgeID(x, y, z, triTable[tableIndex][i+2]);
00558                     
00559                     triangle.pointID[0] = pointID0;
00560                     triangle.pointID[1] = pointID1;
00561                     triangle.pointID[2] = pointID2;
00562                                         
00563                     tris.push_back(triangle);
00564                 }                
00565 
00566             }
00567             
00568         }
00569         
00570     }
00571 
00572     IdToVertexMap::iterator vertex_iter;
00573 
00574     std::map< unsigned int, unsigned int> oursToTheirs;
00575 
00576     float halfWidth = (float)(voxelsPerSide * voxelSize) / 2;
00577 
00578     for (vertex_iter = idVertexMap.begin(); vertex_iter != idVertexMap.end(); vertex_iter++)
00579     {
00580         ColorVertex &v = (*vertex_iter).second;
00581         
00582         unsigned int id = mesh.addVertexWithColor (v.pos[0], v.pos[1], v.pos[2], v.color);
00583         oursToTheirs[(*vertex_iter).first] = id;
00584         MTRACE ("added vertex %.3d: %.2lf %.2lf %.2lf\n",
00585             id, v.pos[0], v.pos[1], v.pos[2]);
00586     }
00587 
00588     for (int i = 0; i < tris.size(); i++)
00589     {
00590         unsigned int a = tris[i].pointID[0];
00591         unsigned int b = tris[i].pointID[1];
00592         unsigned int c = tris[i].pointID[2];
00593 
00594         MTRACE("Trying to add face ids (%.3d -> %3d) (%.3d -> %3d) (%.3d -> %3d)\n",
00595             a, oursToTheirs[a],
00596             b, oursToTheirs[b],
00597             c, oursToTheirs[c]);
00598 
00599         if (a != b && b != c && a != c)
00600         {
00601             try {
00602                 mesh.addFace(
00603                     oursToTheirs[a],
00604                     oursToTheirs[b],
00605                     oursToTheirs[c]);
00606             }
00607             catch (...)
00608             {
00609                 MTRACE("caught\n");
00610             }
00611         }
00612     }
00613 
00614 }
00615 
00616 
00622 void VoxelCube::draw(bool bTranslateToCenter)
00623 {
00624     double halfVoxelSize = voxelSize / 2.;
00625     double halfCubeSize = voxelsPerSide * halfVoxelSize;
00626     
00627     glPushAttrib (GL_ENABLE_BIT);
00628 
00629         glDisable (GL_TEXTURE_2D);
00630 
00631         glMatrixMode (GL_MODELVIEW);
00632         glPushMatrix();
00633             if (bTranslateToCenter)
00634                 glTranslated(center[0], center[1], center[2]);
00635 
00636             glTranslated(-halfCubeSize, -halfCubeSize, -halfCubeSize);
00637             glTranslated(halfVoxelSize, halfVoxelSize, halfVoxelSize);
00638 
00639             // if there are colored voxel in our colored surface voxel list,
00640             // then let's draw that
00641             if (svlColored.size())
00642             {
00643                 ColoredSurfaceVoxelList::iterator i;
00644                 for (i = svlColored.begin(); i != svlColored.end(); i++)
00645                 {
00646                     ColoredVoxelPos pos = (*i);
00647                     
00648                     glPushMatrix();
00649                     
00650                         glTranslated (
00651                             pos[0] * voxelSize,
00652                             pos[1] * voxelSize,
00653                             pos[2] * voxelSize);
00654                     
00655                         glColor3ub (pos.color[0], pos.color[1], pos.color[2]);
00656                         drawCube (voxelSize, GL_QUADS);
00657 
00658                     glPopMatrix();
00659                 }
00660             }
00661             else // no colors are assigned yet, so we'll draw the svl with random colors
00662             {
00663                 SurfaceVoxelList::iterator i;
00664                 for (i = svl.begin(); i != svl.end(); i++)
00665                 {
00666                     VoxelPos pos = (*i);
00667                     
00668                     glPushMatrix();
00669                     
00670                         glTranslated (
00671                             pos[0] * voxelSize,
00672                             pos[1] * voxelSize,
00673                             pos[2] * voxelSize);
00674                     
00675                         srand (pos[0]+pos[1]*voxelsPerSide+pos[2]*voxelsPerSide*voxelsPerSide);
00676 
00677                         glColor3f (
00678                             (rand()%100)/100.,
00679                             (rand()%100)/100.,
00680                             (rand()%100)/100.);
00681                         drawCube (voxelSize, GL_QUADS);
00682 
00683                     glPopMatrix();
00684                 }
00685             }
00686         glPopMatrix();
00687 
00688     glPopAttrib (); // GL_ENABLE_BIT
00689 }
00690 
00691 
00692 
00693 
00694 double VoxelCube::getMinimumFarPlane (Vertex COP, Vertex lookatPoint) const
00695 {
00696     ColVector3 viewDirection = lookatPoint - COP;
00697     viewDirection.normalize();
00698 
00699     double rtn = 0.0;
00700 
00701     for (int x = -1; x <= 1; x+= 2)
00702     {
00703         for (int y = -1; y <= 1; y+= 2)
00704         {
00705             for (int z = -1; z <= 1; z += 2)
00706             {
00707                 Vertex corner = center;
00708                 corner[0] += (x * voxelSize * voxelsPerSide) / 2.;
00709                 corner[1] += (y * voxelSize * voxelsPerSide) / 2.;
00710                 corner[2] += (z * voxelSize * voxelsPerSide) / 2.;
00711 
00712                 ColVector3 diff = corner - COP;
00713 
00714                 ColVector3 diffDirection = diff;
00715                 diffDirection.normalize();
00716 
00717                 double cos = diffDirection.dotProduct(viewDirection);
00718 
00719                 if (cos > 0)
00720                 {
00721                     double dist = cos * diff.getLength();
00722                     rtn = MAX (rtn, dist);
00723                 }
00724             }
00725         }
00726     }
00727 
00728     return rtn;
00729 }
00730 
00731 
00735 bool VoxelCube::isTransparent (const VoxelPos &p) const
00736 {
00737     return isTransparent (p[0], p[1], p[2]);
00738 }
00739 
00744 bool VoxelCube::isTransparent (int x, int y, int z) const
00745 {
00746     return !solids[PosToIndex (x,y,z)];
00747 }
00748 
00749 
00750 
00757 void VoxelCube::setVoxelsPerSide (int vps)
00758 {
00759     if (vps < 1 || vps > 255) throw ArgError("VoxelCube::setVoxelsPerSide(): voxels per side must be between 1 and 255");
00760 
00761     voxelsPerSide = vps;
00762 
00763     svl.clear();
00764     svlColored.clear();
00765 
00766    
00767     // add the 8 faces of the voxel cube to the SVL
00768     int max = voxelsPerSide - 1;
00769     for (int row = 0; row < voxelsPerSide; row++)
00770         for (int col = 0; col < voxelsPerSide; col++)
00771         {
00772             svl.push_back (VoxelPos(0,row,col));
00773             svl.push_back (VoxelPos(row,0,col));
00774             svl.push_back (VoxelPos(row,col,0));
00775 
00776             svl.push_back (VoxelPos(max,row,col));
00777             svl.push_back (VoxelPos(row,max,col));
00778             svl.push_back (VoxelPos(row,col,max));
00779         }
00780 
00781 
00782     // initialize our list of solid (vs. transparent) bools
00783     solids.resize(vps*vps*vps);
00784 
00785     // all of our voxels are initially solid;
00786     // initialize our "solids" array to all "true"
00787     std::fill(solids.begin(), solids.end(), true);
00788 }
00789 
00790 unsigned int VoxelCube::PosToIdentifier (int x, int y, int z) const
00791 {
00792     unsigned int rtn = PosToIndex(x,y,z) + 1;
00793     return rtn;
00794 }
00795 
00796 
00797 unsigned int VoxelCube::PosToIndex (int x, int y, int z) const
00798 { 
00799     if (x >= voxelsPerSide ||
00800         y >= voxelsPerSide ||
00801         z >= voxelsPerSide)
00802     {
00803         throw ArgError ("VoxelCube::getIndex(): you've asked for voxel (%d,%d,%d), but there are only %d voxels per side!",
00804             x,y,z,voxelsPerSide);
00805     }
00806 
00807     return x + y*voxelsPerSide + z*voxelsPerSide*voxelsPerSide; 
00808 }
00809 
00810 
00811 
00812 
00821 Rect< double > VoxelCube::getBoundingRect (std::vector< Vertex > &vertices, const GLdouble modelMatrix[16], const GLdouble projMatrix[16], const GLint viewport[4]) const
00822 {    
00823     Rect< double > bounds;
00824     
00825     double garbage;
00826     GLenum rtn = gluProject (
00827         vertices[0][0], vertices[0][1], vertices[0][2],
00828         modelMatrix,
00829         projMatrix,
00830         viewport,
00831         &bounds.left, &bounds.bottom,
00832         &garbage);
00833 
00834     if (rtn != GL_TRUE)
00835         throw Error("VoxelCube::getBoundingRect(): gluProject failure.");
00836     
00837     bounds.right = bounds.left;
00838     bounds.top = bounds.bottom;
00839     
00840    /*
00841     * Let's make a bounding rectangle for the projected voxel corners
00842     */
00843 
00844     for (int corner = 1; corner < 8; corner++)
00845     {
00846         double curx, cury;
00847 
00848         rtn = gluProject (
00849             vertices[corner][0], vertices[corner][1], vertices[corner][2],
00850             modelMatrix,
00851             projMatrix,
00852             viewport,
00853             &curx, &cury,
00854             &garbage);
00855         if (rtn != GL_TRUE)
00856             throw Error("VoxelCube::getBoundingRect(): gluProject failure.");
00857         
00858         bounds.expandToEnclosePoint (curx, cury);
00859     }
00860 
00861     // let's be conservative, and enlarge the bounding box by a pixel
00862     bounds.bottom -= 1;
00863     bounds.left   -= 1;
00864     bounds.right  +=1;
00865     bounds.top    +=1;
00866     
00867     Rect< double > screen(
00868         viewport[0], 
00869         viewport[2]-1,
00870         viewport[3]-1,
00871         viewport[1]);
00872     
00873     bounds = bounds.intersectRect (screen);
00874     return bounds;
00875 
00876 }

Generated on Tue May 21 03:34:52 2002 for Archimedes by doxygen1.2.15