home *** CD-ROM | disk | FTP | other *** search
/ Enter 2005 March / ENTER.ISO / files / fwp-0.0.6-win32-installer.exe / Q3bspLoader.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-12-06  |  19.6 KB  |  702 lines

  1. #include "Q3bspLoader.h"
  2.  
  3. //#include "camera.h"
  4. #include "log.h"
  5. //#include "light.h"
  6. #include "Tokenizer.h"
  7. #include "File.h"
  8. #include "matrixmath.h"
  9.  
  10. #include <math.h>
  11.  
  12. Q3BSP::Q3BSP(const char* filename){
  13.     numVerts     = 0;
  14.     numFaces     = 0;
  15.     numTextures  = 0;
  16.     numLightmaps = 0;
  17.     numMeshVerts =0;
  18.  
  19.     numNodes     = 0;
  20.     numLeafs     = 0;
  21.     numLeafFaces = 0;
  22.     numPlanes     = 0;
  23.  
  24.     pVerts         = NULL;
  25.     pMeshVerts    =NULL;
  26.     pFaces         = NULL;
  27.  
  28.     pNodes         = NULL;
  29.     pLeafs         = NULL;
  30.     pPlanes         = NULL;
  31.     pLeafFaces     = NULL;
  32.  
  33.     memset(&clusters, 0, sizeof(Q3BSPVisData_t));
  34.  
  35.     if(!loadBSP(filename)){
  36.         error("(in Q3BSP::Q3BSP()): something went wrong!\n\n");
  37.     }else{
  38.         log("Q3BSP::Q3BSP(): BSP file '%s' loaded: numNodes: %i, numLeafs: %i, numFaces: %i, numVerts: %i.\n"
  39.             ,filename, numNodes, numLeafs, numFaces, numVerts);
  40.     }
  41. }
  42.  
  43. Q3BSP::~Q3BSP(){
  44.     clear();
  45. }
  46.  
  47.  
  48.  
  49.  
  50. bool Q3BSP::loadBSP(const char* filename){
  51.     FILE *f = NULL;
  52.     int i = 0;
  53.  
  54.     if((f = fopen(filename, "rb")) == NULL){
  55.         error("(in Q3BSP::loadBSP()): Couldn't open BSP file '%s'.\n\n",filename);
  56.         return false;
  57.     }
  58.  
  59.     // read header and lump sizes/offsets
  60.     Q3BSPHeader_t header;
  61.     Q3BSPLump_t lumps[kMaxLumps];
  62.  
  63.     fread(&header, 1, sizeof(Q3BSPHeader_t), f);
  64.  
  65.     if(/*strcmp(header.strID,"IBSP") ||*/ header.version!=0x2e){
  66.         error("(in Q3BSP::loadBSP()): File '%s' seems not to be a valid Q3 Arena BSP file.\n\n",filename);
  67.         fclose(f);
  68.         return false;
  69.     }
  70.  
  71.     fread(&lumps, kMaxLumps, sizeof(Q3BSPLump_t), f);
  72.  
  73.  
  74.     // allocate mem for vertices/faces/...
  75.     numVerts = lumps[kVertices].length / sizeof(Q3BSPVertex_t);
  76.     pVerts     = new Q3BSPVertex_s[numVerts];
  77.  
  78.     numMeshVerts = lumps[kMeshVerts].length / sizeof(Q3BSPMeshVertex_t);
  79.     pMeshVerts     = new Q3BSPMeshVertex_s[numMeshVerts];
  80.  
  81.     numFaces = lumps[kFaces].length / sizeof(Q3BSPFace_t);
  82.     pFaces     = new Q3BSPFace_t[numFaces];
  83.  
  84.     numTextures = lumps[kTextures].length / sizeof(Q3BSPTexture_t);
  85.     Q3BSPTexture_t* pTextures = new Q3BSPTexture_t[numTextures];
  86.  
  87.     numLightmaps = lumps[kLightmaps].length / sizeof(Q3BSPLightmap_t);
  88.     Q3BSPLightmap_t *pLightmaps = new Q3BSPLightmap_t[numLightmaps];
  89.  
  90.     numNodes = lumps[kNodes].length / sizeof(Q3BSPNode_t);
  91.     pNodes   = new Q3BSPNode_t [numNodes];
  92.  
  93.     numPlanes = lumps[kPlanes].length / sizeof(Q3BSPPlane_t);
  94.     pPlanes     = new Q3BSPPlane_t [numPlanes];
  95.  
  96.     numLeafs = lumps[kLeafs].length / sizeof(Q3BSPLeaf_t);
  97.     pLeafs     = new Q3BSPLeaf_t [numLeafs];
  98.  
  99.     numLeafFaces = lumps[kLeafFaces].length / sizeof(int);
  100.     pLeafFaces     = new int [numLeafFaces];
  101.  
  102.     
  103.     // read vertices
  104.  
  105.     fseek(f, lumps[kVertices].offset, SEEK_SET);
  106.  
  107.     for(i = 0; i < numVerts; i++){
  108.         fread(&pVerts[i], 1, sizeof(Q3BSPVertex_t), f);
  109.  
  110.         float temp = pVerts[i].position[1];
  111.         pVerts[i].position[1] = pVerts[i].position[2];
  112.         pVerts[i].position[2] = -temp;
  113.  
  114.         temp = pVerts[i].normal[1];
  115.         pVerts[i].normal[1] = pVerts[i].normal[2];
  116.         pVerts[i].normal[2] = -temp;
  117.  
  118.         //pVerts[i].lmCoords[0]*=-1.0f;
  119.         //pVerts[i].lmCoords[1]*=-1.0f;
  120.         pVerts[i].texCoords[1]*=-1.0f;
  121.  
  122. //        vectorScale3d(Q3BSP_SCALE, pVerts[i].position, pVerts[i].position);
  123.     }
  124.  
  125.     // read MeshVerts
  126.     fseek(f, lumps[kMeshVerts].offset, SEEK_SET);
  127.     fread(pMeshVerts, numMeshVerts, sizeof(Q3BSPMeshVertex_t), f);
  128.  
  129.  
  130.     // read faces
  131.     fseek(f, lumps[kFaces].offset, SEEK_SET);
  132.     fread(pFaces, numFaces, sizeof(Q3BSPFace_t), f);
  133.     for(i=0;i<numFaces;i++){
  134.         float temp = pFaces[i].normal[1];
  135.         pFaces[i].normal[1] = pFaces[i].normal[2];
  136.         pFaces[i].normal[2] = -temp;
  137.         //pFaces[i].textureID=0;
  138.         //pFaces[i].lightmapID=0;
  139.     }
  140.  
  141.     // read textures
  142.     if(numTextures>Q3BSP_MAX_TEXTURES){
  143.         numTextures=Q3BSP_MAX_TEXTURES;
  144.         warn("(in Q3BSP::loadBSP()): Q3BSP_MAX_TEXTURES reached! numTextures set to %i.\n\n.", numTextures);
  145.         for(int j=0;j<numFaces;j++){
  146.             if(pFaces[j].textureID>=numTextures)
  147.                 pFaces[j].textureID=numTextures-1;
  148.         }
  149.     }
  150.     fseek(f, lumps[kTextures].offset, SEEK_SET);
  151.     fread(pTextures, numTextures, sizeof(Q3BSPTexture_t), f);
  152.  
  153.     char* path=File::extractPath(filename);
  154.     for(i = 0; i < numTextures; i++){
  155.  
  156.         char buff[256];
  157.         Tokenizer t(pTextures[i].strName, "/\\", "");
  158.         strcpy(buff, path);
  159.         strcat(buff, t.tokv[t.tokc-1]);
  160.         textures[i]=new Texture(buff);
  161.     }
  162.     delete[] pTextures;
  163.     delete[] path;
  164.  
  165.     // read lightmaps
  166.     if(numLightmaps>Q3BSP_MAX_TEXTURES){
  167.         numLightmaps=Q3BSP_MAX_TEXTURES;
  168.         warn("(in Q3BSP::loadBSP()): Q3BSP_MAX_TEXTURES reached! numLightmaps set to %i.\n\n.", numLightmaps);
  169.         for(int j=0;j<numFaces;j++){
  170.             if(pFaces[j].lightmapID>=numLightmaps)
  171.                 pFaces[j].lightmapID=numLightmaps-1;
  172.         }
  173.     }
  174.  
  175.     fseek(f, lumps[kLightmaps].offset, SEEK_SET);
  176.     for(i = 0; i < numLightmaps; i++){
  177.         fread(&pLightmaps[i], 1, sizeof(Q3BSPLightmap_t), f);
  178.  
  179.         image_t image;
  180.         image.width=128;
  181.         image.height=128;
  182.         image.numChannels=3;
  183.         image.data=(unsigned char*)pLightmaps[i].imageBits;
  184.  
  185.         ImageLoader::gammaShift(&image, Q3BSP_GAMMA_SHIFT);
  186.         
  187.         lightmaps[i]=new Texture(&image);
  188.         //lightmaps[i]=new Texture("gui/hud/laser_button.bmp");
  189.     }
  190.     delete[] pLightmaps;
  191.  
  192.  
  193.     // read nodes
  194.     fseek(f, lumps[kNodes].offset, SEEK_SET);
  195.     fread(pNodes, numNodes, sizeof(Q3BSPNode_t), f);
  196.     for(i=0;i<numNodes;i++){
  197.         int temp = pNodes[i].min.y;
  198.         pNodes[i].min.y = pNodes[i].min.z;
  199.         pNodes[i].min.z = -temp;
  200.  
  201.         temp = pNodes[i].max.y;
  202.         pNodes[i].max.y = pNodes[i].max.z;
  203.         pNodes[i].max.z = -temp;
  204.  
  205.         temp=pNodes[i].max.z;
  206.         pNodes[i].max.z=pNodes[i].min.z;
  207.         pNodes[i].min.z=temp;
  208. /*
  209.         pNodes[i].max.x=(int)(pNodes[i].max.x*Q3BSP_SCALE);
  210.         pNodes[i].max.y=(int)(pNodes[i].max.y*Q3BSP_SCALE);
  211.         pNodes[i].max.z=(int)(pNodes[i].max.z*Q3BSP_SCALE);
  212.         pNodes[i].min.x=(int)(pNodes[i].min.x*Q3BSP_SCALE);
  213.         pNodes[i].min.y=(int)(pNodes[i].min.y*Q3BSP_SCALE);
  214.         pNodes[i].min.z=(int)(pNodes[i].min.z*Q3BSP_SCALE);
  215. */
  216.     }
  217.  
  218.     // read planes
  219.     fseek(f, lumps[kPlanes].offset, SEEK_SET);
  220.     fread(pPlanes, numPlanes, sizeof(Q3BSPPlane_t), f);
  221.     for(i = 0; i < numPlanes; i++){
  222.         float temp = pPlanes[i].normal[1];
  223.         pPlanes[i].normal[1] = pPlanes[i].normal[2];
  224.         pPlanes[i].normal[2] = -temp;
  225.  
  226. //        pPlanes[i].d*=Q3BSP_SCALE;
  227.  
  228.         //printf("%f %f %f %f\n", pPlanes[i].normal[0], pPlanes[i].normal[1], pPlanes[i].normal[2], pPlanes[i].d);
  229.     }
  230.  
  231.     // read leafs
  232.     fseek(f, lumps[kLeafs].offset, SEEK_SET);
  233.     fread(pLeafs, numLeafs, sizeof(Q3BSPLeaf_t), f);
  234.  
  235.     for(i = 0; i < numLeafs; i++){
  236.         int temp = pLeafs[i].min.y;
  237.         pLeafs[i].min.y = pLeafs[i].min.z;
  238.         pLeafs[i].min.z = -temp;
  239.  
  240.         temp = pLeafs[i].max.y;
  241.         pLeafs[i].max.y = pLeafs[i].max.z;
  242.         pLeafs[i].max.z = -temp;
  243.  
  244.         temp=pLeafs[i].max.z;
  245.         pLeafs[i].max.z=pLeafs[i].min.z;
  246.         pLeafs[i].min.z=temp;
  247. /*
  248.         pLeafs[i].max.x=(int)(pLeafs[i].max.x*Q3BSP_SCALE);
  249.         pLeafs[i].max.y=(int)(pLeafs[i].max.y*Q3BSP_SCALE);
  250.         pLeafs[i].max.z=(int)(pLeafs[i].max.z*Q3BSP_SCALE);
  251.         pLeafs[i].min.x=(int)(pLeafs[i].min.x*Q3BSP_SCALE);
  252.         pLeafs[i].min.y=(int)(pLeafs[i].min.y*Q3BSP_SCALE);
  253.         pLeafs[i].min.z=(int)(pLeafs[i].min.z*Q3BSP_SCALE);
  254. */
  255.         //printf("%i\n", pLeafs[i].numOfLeafFaces);
  256.     }
  257.  
  258.  
  259.     // read leafFaces
  260.     fseek(f, lumps[kLeafFaces].offset, SEEK_SET);
  261.     fread(pLeafFaces, numLeafFaces, sizeof(int), f);
  262.  
  263.     // read visData
  264.     fseek(f, lumps[kVisData].offset, SEEK_SET);
  265.  
  266.     if(lumps[kVisData].length){
  267.         // Read in the number of vectors and each vector's size
  268.         fread(&(clusters.numOfClusters), 1, sizeof(int), f);
  269.         fread(&(clusters.bytesPerCluster), 1, sizeof(int), f);
  270.  
  271.         // Allocate the memory for the cluster bitsets
  272.         int size = clusters.numOfClusters * clusters.bytesPerCluster;
  273.         clusters.pBitsets = new unsigned char [size];
  274.  
  275.         // Read in the all the visibility bitsets for each cluster
  276.         fread(clusters.pBitsets, 1, sizeof(unsigned char) * size, f);
  277.     }else
  278.         clusters.pBitsets = NULL;
  279.  
  280.  
  281.     fclose(f);
  282.  
  283. //    convertMeshes();
  284. //    makeFacesMesh();
  285.     //convertToMesh();
  286.     //facesDrawn.resize(numFaces);
  287.  
  288.     return true;
  289. }
  290.  
  291.  
  292. int Q3BSP::getLeafIndex(vec3_t pos){
  293.     int i = 0;
  294.     float distance = 0.0f;
  295.  
  296.     // Continue looping until we find a negative index
  297.     while(i >= 0){
  298.         // Get the current node, then find the slitter plane from that
  299.         // node's plane index.  Notice that we use a constant reference
  300.         // to store the plane and node so we get some optimization.
  301.         Q3BSPNode_t*  node = &pNodes[i];
  302.         Q3BSPPlane_t* plane = &pPlanes[node->plane];
  303.  
  304.         // Use the Plane Equation (Ax + by + Cz + D = 0) to find if the
  305.         // camera is in front of or behind the current splitter plane.
  306.         distance =    plane->normal[0] * pos[0] +
  307.                     plane->normal[1] * pos[1] +
  308.                     plane->normal[2] * pos[2] - plane->d;
  309.  
  310.         // If the camera is in front of the plane
  311.         if(distance >= 0)
  312.         {
  313.             // Assign the current node to the node in front of itself
  314.             i = node->front;
  315.         }
  316.         // Else if the camera is behind the plane
  317.         else
  318.         {
  319.             // Assign the current node to the node behind itself
  320.             i = node->back;
  321.         }
  322.     }
  323.  
  324.     // Return the leaf index (same thing as saying:  return -(i + 1)).
  325.     return ~i;  // Binary operation (~(i-1)??)
  326. }
  327.  
  328.  
  329.  
  330. inline bool Q3BSP::clusterIsVisible(int current, int test){
  331.  
  332.     // Make sure we have valid memory and that the current cluster is > 0.
  333.     // If we don't have any memory or a negative cluster, return a visibility (1).
  334.     if(!clusters.pBitsets || current < 0) return 1;
  335.  
  336.     // Use binary math to get the 8 bit visibility set for the current cluster
  337.     unsigned char visSet = clusters.pBitsets[(current*clusters.bytesPerCluster) + (test / 8)];
  338.  
  339.     // Now that we have our vector (bitset), do some bit shifting to find if
  340.     // the "test" cluster is visible from the "current" cluster, according to the bitset.
  341.     //int result = visSet & (1 << ((test) & 7));
  342.  
  343.     // Return the result ( either 1 (visible) or 0 (not visible) )
  344.     return ( visSet & (1 << ((test) & 7)) ) != 0;
  345. }
  346.  
  347. bool Q3BSP::faceShouldBeConverted(Q3BSPFace_t* face){
  348.  
  349.     //if(face->textureID>=0 && textures[face->textureID]->filename==NULL)    // file couldn't be loaded
  350.     //    return false;
  351.  
  352.     return (face->type==Q3BSP_FACE_POLYGON /*|| face->type==Q3BSP_FACE_MESH*/);
  353. }
  354.  
  355. Mesh* Q3BSP::convertToMesh(){
  356. //    log("Q3BSP::convertToMesh(): converting bsp tree...\n");
  357.     int i,j;
  358.         
  359.     Material** mattab=new Material*[(numTextures+1)*(numLightmaps+1)];
  360.     for(i=0;i<numTextures+1;i++){
  361.         for(j=0;j<numLightmaps+1;j++){
  362.             mattab[(numTextures+1)*j + i]=NULL;
  363.         }
  364.     }
  365.  
  366.  
  367.     Mesh* m=new Mesh();
  368.  
  369.     m->numVertices=numVerts;
  370.     m->numColors=numVerts;
  371.     m->numNormals=numVerts;
  372.     m->numTexCoords=numVerts;
  373.  
  374.     m->vertices=new GLfloat[m->numVertices*3];
  375.     m->colors=new GLfloat[m->numColors*3];
  376.     m->normals=new GLfloat[m->numNormals*3];
  377.     m->texCoords1=new GLfloat[m->numTexCoords*2];
  378.     m->texCoords2=new GLfloat[m->numTexCoords*2];
  379.  
  380.     for(i=0;i<numVerts;i++){
  381.         vectorCopy3d(pVerts[i].position, &m->vertices[i*3]);
  382.         vectorScale3d(Q3BSP_SCALE, &m->vertices[i*3], &m->vertices[i*3]);
  383.         vectorInit3d(pVerts[i].color[0]/255.0f, pVerts[i].color[1]/255.0f, pVerts[i].color[2]/255.0f, &m->colors[i*3]);
  384.         vectorScale3d(3.0f, &m->colors[i*3], &m->colors[i*3]);    // FIXME: richtige gamma-correction machen
  385.         vectorCopy3d(pVerts[i].normal, &m->normals[i*3]);
  386.         vectorCopy2d(pVerts[i].texCoords, &m->texCoords1[i*2]);
  387.         vectorCopy2d(pVerts[i].lmCoords, &m->texCoords2[i*2]);
  388.     }
  389.  
  390.     m->numFaces=0;
  391.     for(i=0;i<numFaces;i++){
  392.         if(faceShouldBeConverted(&pFaces[i])){
  393.             m->numFaces += pFaces[i].numMeshVerts/3;
  394.         }
  395.     }
  396.  
  397. //    printf("tja: %i\n", m->numFaces);
  398.     m->faces=new Face*[m->numFaces];
  399.     m->numIndices=m->numFaces*3;
  400.     m->indices=new GLuint[m->numIndices];
  401.  
  402.     // convert them!
  403.     int counter=0;
  404.     for(i=0;i<numFaces;i++){
  405.         if(faceShouldBeConverted(&pFaces[i])){
  406.             //printf("converting: %i; numMeshVerts: %i\n", i, pFaces[i].numMeshVerts);
  407.             Material* mat;
  408.             int texID, lmID;
  409.  
  410.  
  411.             if(pFaces[i].textureID<0)
  412.                 texID=numTextures;
  413.             else
  414.                 texID=pFaces[i].textureID;
  415.  
  416.             if(pFaces[i].lightmapID<0)
  417.                 lmID=numLightmaps;
  418.             else
  419.                 lmID=pFaces[i].lightmapID;
  420.  
  421.             if(mattab[lmID*(numTextures+1) + texID]==NULL){
  422.                 mat=new Material();
  423.                 vectorInit4d(1.0f, 1.0f, 1.0f, 1.0f, mat->color);
  424.                 if(pFaces[i].textureID>=0)
  425.                     mat->addTexture(textures[pFaces[i].textureID]);
  426.                 if(pFaces[i].lightmapID>=0)
  427.                     mat->addLightmap(lightmaps[pFaces[i].lightmapID]);
  428.  
  429.                 mat->setAttribs();
  430.                 //mat->dump();
  431.                 mattab[lmID*(numTextures+1) + texID]=mat;
  432.             }else{
  433.                 mat=mattab[lmID*(numTextures+1) + texID];
  434.             }
  435.  
  436.             int offset=pFaces[i].startVertIndex;
  437.             pFaces[i].startVertIndex=counter;        // new start index!!!
  438.             for(j=0;j<pFaces[i].numMeshVerts;j+=3){
  439.                 int index1=pMeshVerts[pFaces[i].meshVertIndex+j+0].offset + offset;
  440.                 int index2=pMeshVerts[pFaces[i].meshVertIndex+j+1].offset + offset;
  441.                 int index3=pMeshVerts[pFaces[i].meshVertIndex+j+2].offset + offset;
  442.  
  443.                 Face* f=new Face();
  444.  
  445.                 f->vertices=new float[9];
  446.                 f->numVertices=3;
  447.                 f->colors=new float[9];
  448.                 f->numColors=3;
  449.                 f->normals=new float[9];
  450.                 f->numNormals=3;
  451.                 f->texCoords1=new float[6];
  452.                 f->texCoords2=new float[6];
  453.                 f->numTexCoords=3;
  454.  
  455.                 vectorCopy3d(pVerts[index1].position, &f->vertices[0]);
  456.                 vectorCopy3d(pVerts[index2].position, &f->vertices[3]);
  457.                 vectorCopy3d(pVerts[index3].position, &f->vertices[6]);
  458.  
  459.                 vectorScale3d(Q3BSP_SCALE, &f->vertices[0], &f->vertices[0]);
  460.                 vectorScale3d(Q3BSP_SCALE, &f->vertices[3], &f->vertices[3]);
  461.                 vectorScale3d(Q3BSP_SCALE, &f->vertices[6], &f->vertices[6]);
  462.  
  463.                 vectorInit3d(pVerts[index1].color[0]/255.0f, pVerts[index1].color[1]/255.0f, pVerts[index1].color[2]/255.0f, &f->colors[0]);
  464.                 vectorInit3d(pVerts[index2].color[0]/255.0f, pVerts[index2].color[1]/255.0f, pVerts[index2].color[2]/255.0f, &f->colors[3]);
  465.                 vectorInit3d(pVerts[index3].color[0]/255.0f, pVerts[index3].color[1]/255.0f, pVerts[index3].color[2]/255.0f, &f->colors[6]);
  466.  
  467.                 vectorCopy3d(pVerts[index1].normal, &f->normals[0]);
  468.                 vectorCopy3d(pVerts[index2].normal, &f->normals[3]);
  469.                 vectorCopy3d(pVerts[index3].normal, &f->normals[6]);
  470.  
  471.                 vectorCopy2d(pVerts[index1].texCoords, &f->texCoords1[0]);
  472.                 vectorCopy2d(pVerts[index2].texCoords, &f->texCoords1[2]);
  473.                 vectorCopy2d(pVerts[index3].texCoords, &f->texCoords1[4]);
  474.  
  475.                 vectorCopy2d(pVerts[index1].lmCoords, &f->texCoords2[0]);
  476.                 vectorCopy2d(pVerts[index2].lmCoords, &f->texCoords2[2]);
  477.                 vectorCopy2d(pVerts[index3].lmCoords, &f->texCoords2[4]);
  478.  
  479.                 f->material=mat;
  480.                 //f->flags |= FACE_FLAG_TWO_SIDED;    // THINKABOUTME
  481.                 //f->calcNormal();
  482.                 vectorCopy3d(pFaces[i].normal, f->normal);
  483.                 //facesMesh->addFace(f);
  484.                 m->faces[counter]=f;
  485.                 m->indices[counter*3+0]=index1;
  486.                 m->indices[counter*3+1]=index2;
  487.                 m->indices[counter*3+2]=index3;
  488.                 f->indices=new GLuint[3];
  489.                 f->indices[0]=index1;
  490.                 f->indices[1]=index2;
  491.                 f->indices[2]=index3;
  492.                 f->numIndices=3;
  493.                 counter++;
  494.             }
  495.         }
  496.     }
  497.  
  498.     for(i=0;i<(numTextures+1)*(numLightmaps+1);i++){
  499.         if(mattab[i]!=NULL)
  500.             m->addMaterial(mattab[i]);
  501.             
  502.     }
  503.     //m->sortFacesByMaterial();
  504.     m->setRenderMode();
  505.     m->createVBOs();
  506.     //mesh->dump();
  507.     delete[] mattab;
  508.  
  509.     log("Q3BSP::convertToMesh(): %i faces in mesh.\n", m->numFaces);
  510.     return m;
  511. }
  512.  
  513. //PotentialVisibilitySet* Q3BSP::pvs=NULL;
  514.  
  515. PotentialVisibilitySet*  Q3BSP::buildPVS(){
  516.     int i,j;
  517.  
  518.     PotentialVisibilitySet* pvs=new PotentialVisibilitySet(numLeafs);
  519.  
  520.     PVSCluster_t** newClusters=pvs->getClusters();
  521.     for(i=0;i<numLeafs;i++){
  522.         newClusters[i]->min[0]=(float)(pLeafs[i].min.x*Q3BSP_SCALE);
  523.         newClusters[i]->min[1]=(float)(pLeafs[i].min.y*Q3BSP_SCALE);
  524.         newClusters[i]->min[2]=(float)(pLeafs[i].min.z*Q3BSP_SCALE);
  525.         newClusters[i]->max[0]=(float)(pLeafs[i].max.x*Q3BSP_SCALE);
  526.         newClusters[i]->max[1]=(float)(pLeafs[i].max.y*Q3BSP_SCALE);
  527.         newClusters[i]->max[2]=(float)(pLeafs[i].max.z*Q3BSP_SCALE);
  528.         //newClusters[i]->visibleClusters=new BitSet(numLeafs);
  529.         //newClusters[i]->visibleClusters->clearAll();
  530.  
  531.         for(j=0;j<numLeafs;j++){
  532.             if(clusterIsVisible(pLeafs[i].cluster, pLeafs[j].cluster)){
  533.                 newClusters[i]->visibleClusters->set(j);
  534.             }
  535.         }
  536.     }
  537.  
  538.     log("Q3BSP::buildPVS(): %i clusters in PVS.\n", pvs->getNumClusters());
  539.     return pvs;
  540. }
  541.  
  542. Q3bspExtension* Q3BSP::buildQ3bspExtension(){
  543.     int i;
  544.  
  545.     Q3bspExtension* ret=new Q3bspExtension();
  546.  
  547.     ret->mesh=convertToMesh();
  548.     ret->pvs=buildPVS();
  549.     ret->facesDrawn=new BitSet(ret->mesh->numFaces);
  550.  
  551.     ret->nodes=new Q3bspExtensionNode_t*[numNodes];
  552.     ret->numNodes=numNodes;
  553.     for(i=0;i<numNodes;i++){
  554.         ret->nodes[i]=new Q3bspExtensionNode_t;
  555.         ret->nodes[i]->min[0]=(float)(pNodes[i].min.x*Q3BSP_SCALE);
  556.         ret->nodes[i]->min[1]=(float)(pNodes[i].min.y*Q3BSP_SCALE);
  557.         ret->nodes[i]->min[2]=(float)(pNodes[i].min.z*Q3BSP_SCALE);
  558.         ret->nodes[i]->max[0]=(float)(pNodes[i].max.x*Q3BSP_SCALE);
  559.         ret->nodes[i]->max[1]=(float)(pNodes[i].max.y*Q3BSP_SCALE);
  560.         ret->nodes[i]->max[2]=(float)(pNodes[i].max.z*Q3BSP_SCALE);
  561.         ret->nodes[i]->front=pNodes[i].front;
  562.         ret->nodes[i]->back=pNodes[i].back;
  563.         vectorCopy3d(pPlanes[pNodes[i].plane].normal, ret->nodes[i]->plane);
  564.         ret->nodes[i]->plane[3]=pPlanes[pNodes[i].plane].d*Q3BSP_SCALE;
  565.     }
  566.  
  567.     ret->leafs=new Q3bspExtensionLeaf_t*[numLeafs];
  568.     ret->numLeafs=numLeafs;
  569.     for(i=0;i<numLeafs;i++){
  570.         ret->leafs[i]=new Q3bspExtensionLeaf_t;
  571.         ret->leafs[i]->min[0]=(float)(pLeafs[i].min.x*Q3BSP_SCALE);
  572.         ret->leafs[i]->min[1]=(float)(pLeafs[i].min.y*Q3BSP_SCALE);
  573.         ret->leafs[i]->min[2]=(float)(pLeafs[i].min.z*Q3BSP_SCALE);
  574.         ret->leafs[i]->max[0]=(float)(pLeafs[i].max.x*Q3BSP_SCALE);
  575.         ret->leafs[i]->max[1]=(float)(pLeafs[i].max.y*Q3BSP_SCALE);
  576.         ret->leafs[i]->max[2]=(float)(pLeafs[i].max.z*Q3BSP_SCALE);
  577.  
  578.         ret->leafs[i]->numFaceIndices=0;
  579.         int k, findex;
  580.         for(k=0;k<pLeafs[i].numOfLeafFaces;k++){
  581.             findex=pLeafFaces[pLeafs[i].leafface+k];
  582.             if(faceShouldBeConverted(&pFaces[findex])){
  583.                 ret->leafs[i]->numFaceIndices += (pFaces[findex].numMeshVerts/3);
  584.             }
  585.         }
  586.         ret->leafs[i]->faceIndices=new int[ret->leafs[i]->numFaceIndices];
  587.         int c=0;
  588.         for(k=0;k<pLeafs[i].numOfLeafFaces;k++){
  589.             findex=pLeafFaces[pLeafs[i].leafface+k];
  590.             if(faceShouldBeConverted(&pFaces[findex])){
  591.                 int si=pFaces[findex].startVertIndex;
  592.                 for(int l=0;l<(pFaces[findex].numMeshVerts/3);l++){
  593.                     ret->leafs[i]->faceIndices[c]=si+l;
  594.                     c++;
  595.                 }
  596.             }
  597.         }
  598.     }
  599.  
  600.     ret->numTextures=numTextures;
  601.     ret->textures=new Texture*[numTextures];
  602.     for(i=0;i<numTextures;i++)
  603.         ret->textures[i]=textures[i];
  604.     ret->numLightmaps=numLightmaps;
  605.  
  606.     ret->lightmaps=new Texture*[numLightmaps];
  607.     for(i=0;i<numLightmaps;i++)
  608.         ret->lightmaps[i]=lightmaps[i];
  609.  
  610.     log("Q3BSP::buildQ3bspExtension(): done.\n");
  611.     return ret;
  612. }
  613.  
  614.  
  615. void Q3BSP::clear(){
  616. //    int i;
  617.  
  618.     if(pVerts){
  619.         delete[] pVerts;
  620.         pVerts = NULL;
  621.         numVerts=0;
  622.     }
  623.  
  624.     if(pMeshVerts){
  625.         delete[] pMeshVerts;
  626.         pMeshVerts=0;
  627.         numMeshVerts=0;
  628.     }
  629.  
  630.     if(pFaces){
  631.         delete[] pFaces;
  632.         pFaces = NULL;
  633.         numFaces=0;
  634.     }
  635.  
  636.  
  637.     if(pNodes){
  638.         delete[] pNodes;
  639.         pNodes = NULL;
  640.         numNodes=0;
  641.     }
  642.  
  643.     if(pLeafs){
  644.         delete[] pLeafs;
  645.         pLeafs = NULL;
  646.         numLeafs=0;
  647.     }
  648.  
  649.     if(pLeafFaces){
  650.         delete[] pLeafFaces;
  651.         pLeafFaces = NULL;
  652.         numLeafs=0;
  653.     }
  654.  
  655.     if(pPlanes){
  656.         delete[] pPlanes;
  657.         pPlanes = NULL;
  658.         numPlanes=0;
  659.     }
  660.  
  661.     if(clusters.pBitsets){
  662.         delete[] clusters.pBitsets;
  663.         clusters.pBitsets = NULL;
  664.         clusters.numOfClusters=0;
  665.     }
  666. /*
  667.     for(i=0;i<numTextures;i++){
  668.         if(textures[i]!=NULL){
  669.             delete textures[i];
  670.             textures[i]=NULL;
  671.         }
  672.     }
  673.     numTextures=0;
  674.  
  675.     for(i=0;i<numLightmaps;i++){
  676.         if(lightmaps[i]!=NULL){
  677.             delete lightmaps[i];
  678.             lightmaps[i]=NULL;
  679.         }
  680.     }
  681.     numLightmaps=0;
  682. */
  683. }
  684.  
  685.  
  686.  
  687.  
  688.  
  689.  
  690. Q3bspExtension* Q3bspLoader::q3bspExtension=NULL;
  691.  
  692. bool Q3bspLoader::loadBSP(const char* filename, Model* model){
  693.     Q3BSP* bsp=new Q3BSP(filename);
  694.     
  695.     q3bspExtension=bsp->buildQ3bspExtension();
  696.     model->addMesh(q3bspExtension->mesh);
  697.  
  698.     delete bsp;
  699.  
  700.     return true;
  701. }
  702.