home *** CD-ROM | disk | FTP | other *** search
- #include "Q3bspLoader.h"
-
- //#include "camera.h"
- #include "log.h"
- //#include "light.h"
- #include "Tokenizer.h"
- #include "File.h"
- #include "matrixmath.h"
-
- #include <math.h>
-
- Q3BSP::Q3BSP(const char* filename){
- numVerts = 0;
- numFaces = 0;
- numTextures = 0;
- numLightmaps = 0;
- numMeshVerts =0;
-
- numNodes = 0;
- numLeafs = 0;
- numLeafFaces = 0;
- numPlanes = 0;
-
- pVerts = NULL;
- pMeshVerts =NULL;
- pFaces = NULL;
-
- pNodes = NULL;
- pLeafs = NULL;
- pPlanes = NULL;
- pLeafFaces = NULL;
-
- memset(&clusters, 0, sizeof(Q3BSPVisData_t));
-
- if(!loadBSP(filename)){
- error("(in Q3BSP::Q3BSP()): something went wrong!\n\n");
- }else{
- log("Q3BSP::Q3BSP(): BSP file '%s' loaded: numNodes: %i, numLeafs: %i, numFaces: %i, numVerts: %i.\n"
- ,filename, numNodes, numLeafs, numFaces, numVerts);
- }
- }
-
- Q3BSP::~Q3BSP(){
- clear();
- }
-
-
-
-
- bool Q3BSP::loadBSP(const char* filename){
- FILE *f = NULL;
- int i = 0;
-
- if((f = fopen(filename, "rb")) == NULL){
- error("(in Q3BSP::loadBSP()): Couldn't open BSP file '%s'.\n\n",filename);
- return false;
- }
-
- // read header and lump sizes/offsets
- Q3BSPHeader_t header;
- Q3BSPLump_t lumps[kMaxLumps];
-
- fread(&header, 1, sizeof(Q3BSPHeader_t), f);
-
- if(/*strcmp(header.strID,"IBSP") ||*/ header.version!=0x2e){
- error("(in Q3BSP::loadBSP()): File '%s' seems not to be a valid Q3 Arena BSP file.\n\n",filename);
- fclose(f);
- return false;
- }
-
- fread(&lumps, kMaxLumps, sizeof(Q3BSPLump_t), f);
-
-
- // allocate mem for vertices/faces/...
- numVerts = lumps[kVertices].length / sizeof(Q3BSPVertex_t);
- pVerts = new Q3BSPVertex_s[numVerts];
-
- numMeshVerts = lumps[kMeshVerts].length / sizeof(Q3BSPMeshVertex_t);
- pMeshVerts = new Q3BSPMeshVertex_s[numMeshVerts];
-
- numFaces = lumps[kFaces].length / sizeof(Q3BSPFace_t);
- pFaces = new Q3BSPFace_t[numFaces];
-
- numTextures = lumps[kTextures].length / sizeof(Q3BSPTexture_t);
- Q3BSPTexture_t* pTextures = new Q3BSPTexture_t[numTextures];
-
- numLightmaps = lumps[kLightmaps].length / sizeof(Q3BSPLightmap_t);
- Q3BSPLightmap_t *pLightmaps = new Q3BSPLightmap_t[numLightmaps];
-
- numNodes = lumps[kNodes].length / sizeof(Q3BSPNode_t);
- pNodes = new Q3BSPNode_t [numNodes];
-
- numPlanes = lumps[kPlanes].length / sizeof(Q3BSPPlane_t);
- pPlanes = new Q3BSPPlane_t [numPlanes];
-
- numLeafs = lumps[kLeafs].length / sizeof(Q3BSPLeaf_t);
- pLeafs = new Q3BSPLeaf_t [numLeafs];
-
- numLeafFaces = lumps[kLeafFaces].length / sizeof(int);
- pLeafFaces = new int [numLeafFaces];
-
-
- // read vertices
-
- fseek(f, lumps[kVertices].offset, SEEK_SET);
-
- for(i = 0; i < numVerts; i++){
- fread(&pVerts[i], 1, sizeof(Q3BSPVertex_t), f);
-
- float temp = pVerts[i].position[1];
- pVerts[i].position[1] = pVerts[i].position[2];
- pVerts[i].position[2] = -temp;
-
- temp = pVerts[i].normal[1];
- pVerts[i].normal[1] = pVerts[i].normal[2];
- pVerts[i].normal[2] = -temp;
-
- //pVerts[i].lmCoords[0]*=-1.0f;
- //pVerts[i].lmCoords[1]*=-1.0f;
- pVerts[i].texCoords[1]*=-1.0f;
-
- // vectorScale3d(Q3BSP_SCALE, pVerts[i].position, pVerts[i].position);
- }
-
- // read MeshVerts
- fseek(f, lumps[kMeshVerts].offset, SEEK_SET);
- fread(pMeshVerts, numMeshVerts, sizeof(Q3BSPMeshVertex_t), f);
-
-
- // read faces
- fseek(f, lumps[kFaces].offset, SEEK_SET);
- fread(pFaces, numFaces, sizeof(Q3BSPFace_t), f);
- for(i=0;i<numFaces;i++){
- float temp = pFaces[i].normal[1];
- pFaces[i].normal[1] = pFaces[i].normal[2];
- pFaces[i].normal[2] = -temp;
- //pFaces[i].textureID=0;
- //pFaces[i].lightmapID=0;
- }
-
- // read textures
- if(numTextures>Q3BSP_MAX_TEXTURES){
- numTextures=Q3BSP_MAX_TEXTURES;
- warn("(in Q3BSP::loadBSP()): Q3BSP_MAX_TEXTURES reached! numTextures set to %i.\n\n.", numTextures);
- for(int j=0;j<numFaces;j++){
- if(pFaces[j].textureID>=numTextures)
- pFaces[j].textureID=numTextures-1;
- }
- }
- fseek(f, lumps[kTextures].offset, SEEK_SET);
- fread(pTextures, numTextures, sizeof(Q3BSPTexture_t), f);
-
- char* path=File::extractPath(filename);
- for(i = 0; i < numTextures; i++){
-
- char buff[256];
- Tokenizer t(pTextures[i].strName, "/\\", "");
- strcpy(buff, path);
- strcat(buff, t.tokv[t.tokc-1]);
- textures[i]=new Texture(buff);
- }
- delete[] pTextures;
- delete[] path;
-
- // read lightmaps
- if(numLightmaps>Q3BSP_MAX_TEXTURES){
- numLightmaps=Q3BSP_MAX_TEXTURES;
- warn("(in Q3BSP::loadBSP()): Q3BSP_MAX_TEXTURES reached! numLightmaps set to %i.\n\n.", numLightmaps);
- for(int j=0;j<numFaces;j++){
- if(pFaces[j].lightmapID>=numLightmaps)
- pFaces[j].lightmapID=numLightmaps-1;
- }
- }
-
- fseek(f, lumps[kLightmaps].offset, SEEK_SET);
- for(i = 0; i < numLightmaps; i++){
- fread(&pLightmaps[i], 1, sizeof(Q3BSPLightmap_t), f);
-
- image_t image;
- image.width=128;
- image.height=128;
- image.numChannels=3;
- image.data=(unsigned char*)pLightmaps[i].imageBits;
-
- ImageLoader::gammaShift(&image, Q3BSP_GAMMA_SHIFT);
-
- lightmaps[i]=new Texture(&image);
- //lightmaps[i]=new Texture("gui/hud/laser_button.bmp");
- }
- delete[] pLightmaps;
-
-
- // read nodes
- fseek(f, lumps[kNodes].offset, SEEK_SET);
- fread(pNodes, numNodes, sizeof(Q3BSPNode_t), f);
- for(i=0;i<numNodes;i++){
- int temp = pNodes[i].min.y;
- pNodes[i].min.y = pNodes[i].min.z;
- pNodes[i].min.z = -temp;
-
- temp = pNodes[i].max.y;
- pNodes[i].max.y = pNodes[i].max.z;
- pNodes[i].max.z = -temp;
-
- temp=pNodes[i].max.z;
- pNodes[i].max.z=pNodes[i].min.z;
- pNodes[i].min.z=temp;
- /*
- pNodes[i].max.x=(int)(pNodes[i].max.x*Q3BSP_SCALE);
- pNodes[i].max.y=(int)(pNodes[i].max.y*Q3BSP_SCALE);
- pNodes[i].max.z=(int)(pNodes[i].max.z*Q3BSP_SCALE);
- pNodes[i].min.x=(int)(pNodes[i].min.x*Q3BSP_SCALE);
- pNodes[i].min.y=(int)(pNodes[i].min.y*Q3BSP_SCALE);
- pNodes[i].min.z=(int)(pNodes[i].min.z*Q3BSP_SCALE);
- */
- }
-
- // read planes
- fseek(f, lumps[kPlanes].offset, SEEK_SET);
- fread(pPlanes, numPlanes, sizeof(Q3BSPPlane_t), f);
- for(i = 0; i < numPlanes; i++){
- float temp = pPlanes[i].normal[1];
- pPlanes[i].normal[1] = pPlanes[i].normal[2];
- pPlanes[i].normal[2] = -temp;
-
- // pPlanes[i].d*=Q3BSP_SCALE;
-
- //printf("%f %f %f %f\n", pPlanes[i].normal[0], pPlanes[i].normal[1], pPlanes[i].normal[2], pPlanes[i].d);
- }
-
- // read leafs
- fseek(f, lumps[kLeafs].offset, SEEK_SET);
- fread(pLeafs, numLeafs, sizeof(Q3BSPLeaf_t), f);
-
- for(i = 0; i < numLeafs; i++){
- int temp = pLeafs[i].min.y;
- pLeafs[i].min.y = pLeafs[i].min.z;
- pLeafs[i].min.z = -temp;
-
- temp = pLeafs[i].max.y;
- pLeafs[i].max.y = pLeafs[i].max.z;
- pLeafs[i].max.z = -temp;
-
- temp=pLeafs[i].max.z;
- pLeafs[i].max.z=pLeafs[i].min.z;
- pLeafs[i].min.z=temp;
- /*
- pLeafs[i].max.x=(int)(pLeafs[i].max.x*Q3BSP_SCALE);
- pLeafs[i].max.y=(int)(pLeafs[i].max.y*Q3BSP_SCALE);
- pLeafs[i].max.z=(int)(pLeafs[i].max.z*Q3BSP_SCALE);
- pLeafs[i].min.x=(int)(pLeafs[i].min.x*Q3BSP_SCALE);
- pLeafs[i].min.y=(int)(pLeafs[i].min.y*Q3BSP_SCALE);
- pLeafs[i].min.z=(int)(pLeafs[i].min.z*Q3BSP_SCALE);
- */
- //printf("%i\n", pLeafs[i].numOfLeafFaces);
- }
-
-
- // read leafFaces
- fseek(f, lumps[kLeafFaces].offset, SEEK_SET);
- fread(pLeafFaces, numLeafFaces, sizeof(int), f);
-
- // read visData
- fseek(f, lumps[kVisData].offset, SEEK_SET);
-
- if(lumps[kVisData].length){
- // Read in the number of vectors and each vector's size
- fread(&(clusters.numOfClusters), 1, sizeof(int), f);
- fread(&(clusters.bytesPerCluster), 1, sizeof(int), f);
-
- // Allocate the memory for the cluster bitsets
- int size = clusters.numOfClusters * clusters.bytesPerCluster;
- clusters.pBitsets = new unsigned char [size];
-
- // Read in the all the visibility bitsets for each cluster
- fread(clusters.pBitsets, 1, sizeof(unsigned char) * size, f);
- }else
- clusters.pBitsets = NULL;
-
-
- fclose(f);
-
- // convertMeshes();
- // makeFacesMesh();
- //convertToMesh();
- //facesDrawn.resize(numFaces);
-
- return true;
- }
-
-
- int Q3BSP::getLeafIndex(vec3_t pos){
- int i = 0;
- float distance = 0.0f;
-
- // Continue looping until we find a negative index
- while(i >= 0){
- // Get the current node, then find the slitter plane from that
- // node's plane index. Notice that we use a constant reference
- // to store the plane and node so we get some optimization.
- Q3BSPNode_t* node = &pNodes[i];
- Q3BSPPlane_t* plane = &pPlanes[node->plane];
-
- // Use the Plane Equation (Ax + by + Cz + D = 0) to find if the
- // camera is in front of or behind the current splitter plane.
- distance = plane->normal[0] * pos[0] +
- plane->normal[1] * pos[1] +
- plane->normal[2] * pos[2] - plane->d;
-
- // If the camera is in front of the plane
- if(distance >= 0)
- {
- // Assign the current node to the node in front of itself
- i = node->front;
- }
- // Else if the camera is behind the plane
- else
- {
- // Assign the current node to the node behind itself
- i = node->back;
- }
- }
-
- // Return the leaf index (same thing as saying: return -(i + 1)).
- return ~i; // Binary operation (~(i-1)??)
- }
-
-
-
- inline bool Q3BSP::clusterIsVisible(int current, int test){
-
- // Make sure we have valid memory and that the current cluster is > 0.
- // If we don't have any memory or a negative cluster, return a visibility (1).
- if(!clusters.pBitsets || current < 0) return 1;
-
- // Use binary math to get the 8 bit visibility set for the current cluster
- unsigned char visSet = clusters.pBitsets[(current*clusters.bytesPerCluster) + (test / 8)];
-
- // Now that we have our vector (bitset), do some bit shifting to find if
- // the "test" cluster is visible from the "current" cluster, according to the bitset.
- //int result = visSet & (1 << ((test) & 7));
-
- // Return the result ( either 1 (visible) or 0 (not visible) )
- return ( visSet & (1 << ((test) & 7)) ) != 0;
- }
-
- bool Q3BSP::faceShouldBeConverted(Q3BSPFace_t* face){
-
- //if(face->textureID>=0 && textures[face->textureID]->filename==NULL) // file couldn't be loaded
- // return false;
-
- return (face->type==Q3BSP_FACE_POLYGON /*|| face->type==Q3BSP_FACE_MESH*/);
- }
-
- Mesh* Q3BSP::convertToMesh(){
- // log("Q3BSP::convertToMesh(): converting bsp tree...\n");
- int i,j;
-
- Material** mattab=new Material*[(numTextures+1)*(numLightmaps+1)];
- for(i=0;i<numTextures+1;i++){
- for(j=0;j<numLightmaps+1;j++){
- mattab[(numTextures+1)*j + i]=NULL;
- }
- }
-
-
- Mesh* m=new Mesh();
-
- m->numVertices=numVerts;
- m->numColors=numVerts;
- m->numNormals=numVerts;
- m->numTexCoords=numVerts;
-
- m->vertices=new GLfloat[m->numVertices*3];
- m->colors=new GLfloat[m->numColors*3];
- m->normals=new GLfloat[m->numNormals*3];
- m->texCoords1=new GLfloat[m->numTexCoords*2];
- m->texCoords2=new GLfloat[m->numTexCoords*2];
-
- for(i=0;i<numVerts;i++){
- vectorCopy3d(pVerts[i].position, &m->vertices[i*3]);
- vectorScale3d(Q3BSP_SCALE, &m->vertices[i*3], &m->vertices[i*3]);
- vectorInit3d(pVerts[i].color[0]/255.0f, pVerts[i].color[1]/255.0f, pVerts[i].color[2]/255.0f, &m->colors[i*3]);
- vectorScale3d(3.0f, &m->colors[i*3], &m->colors[i*3]); // FIXME: richtige gamma-correction machen
- vectorCopy3d(pVerts[i].normal, &m->normals[i*3]);
- vectorCopy2d(pVerts[i].texCoords, &m->texCoords1[i*2]);
- vectorCopy2d(pVerts[i].lmCoords, &m->texCoords2[i*2]);
- }
-
- m->numFaces=0;
- for(i=0;i<numFaces;i++){
- if(faceShouldBeConverted(&pFaces[i])){
- m->numFaces += pFaces[i].numMeshVerts/3;
- }
- }
-
- // printf("tja: %i\n", m->numFaces);
- m->faces=new Face*[m->numFaces];
- m->numIndices=m->numFaces*3;
- m->indices=new GLuint[m->numIndices];
-
- // convert them!
- int counter=0;
- for(i=0;i<numFaces;i++){
- if(faceShouldBeConverted(&pFaces[i])){
- //printf("converting: %i; numMeshVerts: %i\n", i, pFaces[i].numMeshVerts);
- Material* mat;
- int texID, lmID;
-
-
- if(pFaces[i].textureID<0)
- texID=numTextures;
- else
- texID=pFaces[i].textureID;
-
- if(pFaces[i].lightmapID<0)
- lmID=numLightmaps;
- else
- lmID=pFaces[i].lightmapID;
-
- if(mattab[lmID*(numTextures+1) + texID]==NULL){
- mat=new Material();
- vectorInit4d(1.0f, 1.0f, 1.0f, 1.0f, mat->color);
- if(pFaces[i].textureID>=0)
- mat->addTexture(textures[pFaces[i].textureID]);
- if(pFaces[i].lightmapID>=0)
- mat->addLightmap(lightmaps[pFaces[i].lightmapID]);
-
- mat->setAttribs();
- //mat->dump();
- mattab[lmID*(numTextures+1) + texID]=mat;
- }else{
- mat=mattab[lmID*(numTextures+1) + texID];
- }
-
- int offset=pFaces[i].startVertIndex;
- pFaces[i].startVertIndex=counter; // new start index!!!
- for(j=0;j<pFaces[i].numMeshVerts;j+=3){
- int index1=pMeshVerts[pFaces[i].meshVertIndex+j+0].offset + offset;
- int index2=pMeshVerts[pFaces[i].meshVertIndex+j+1].offset + offset;
- int index3=pMeshVerts[pFaces[i].meshVertIndex+j+2].offset + offset;
-
- Face* f=new Face();
-
- f->vertices=new float[9];
- f->numVertices=3;
- f->colors=new float[9];
- f->numColors=3;
- f->normals=new float[9];
- f->numNormals=3;
- f->texCoords1=new float[6];
- f->texCoords2=new float[6];
- f->numTexCoords=3;
-
- vectorCopy3d(pVerts[index1].position, &f->vertices[0]);
- vectorCopy3d(pVerts[index2].position, &f->vertices[3]);
- vectorCopy3d(pVerts[index3].position, &f->vertices[6]);
-
- vectorScale3d(Q3BSP_SCALE, &f->vertices[0], &f->vertices[0]);
- vectorScale3d(Q3BSP_SCALE, &f->vertices[3], &f->vertices[3]);
- vectorScale3d(Q3BSP_SCALE, &f->vertices[6], &f->vertices[6]);
-
- vectorInit3d(pVerts[index1].color[0]/255.0f, pVerts[index1].color[1]/255.0f, pVerts[index1].color[2]/255.0f, &f->colors[0]);
- vectorInit3d(pVerts[index2].color[0]/255.0f, pVerts[index2].color[1]/255.0f, pVerts[index2].color[2]/255.0f, &f->colors[3]);
- vectorInit3d(pVerts[index3].color[0]/255.0f, pVerts[index3].color[1]/255.0f, pVerts[index3].color[2]/255.0f, &f->colors[6]);
-
- vectorCopy3d(pVerts[index1].normal, &f->normals[0]);
- vectorCopy3d(pVerts[index2].normal, &f->normals[3]);
- vectorCopy3d(pVerts[index3].normal, &f->normals[6]);
-
- vectorCopy2d(pVerts[index1].texCoords, &f->texCoords1[0]);
- vectorCopy2d(pVerts[index2].texCoords, &f->texCoords1[2]);
- vectorCopy2d(pVerts[index3].texCoords, &f->texCoords1[4]);
-
- vectorCopy2d(pVerts[index1].lmCoords, &f->texCoords2[0]);
- vectorCopy2d(pVerts[index2].lmCoords, &f->texCoords2[2]);
- vectorCopy2d(pVerts[index3].lmCoords, &f->texCoords2[4]);
-
- f->material=mat;
- //f->flags |= FACE_FLAG_TWO_SIDED; // THINKABOUTME
- //f->calcNormal();
- vectorCopy3d(pFaces[i].normal, f->normal);
- //facesMesh->addFace(f);
- m->faces[counter]=f;
- m->indices[counter*3+0]=index1;
- m->indices[counter*3+1]=index2;
- m->indices[counter*3+2]=index3;
- f->indices=new GLuint[3];
- f->indices[0]=index1;
- f->indices[1]=index2;
- f->indices[2]=index3;
- f->numIndices=3;
- counter++;
- }
- }
- }
-
- for(i=0;i<(numTextures+1)*(numLightmaps+1);i++){
- if(mattab[i]!=NULL)
- m->addMaterial(mattab[i]);
-
- }
- //m->sortFacesByMaterial();
- m->setRenderMode();
- m->createVBOs();
- //mesh->dump();
- delete[] mattab;
-
- log("Q3BSP::convertToMesh(): %i faces in mesh.\n", m->numFaces);
- return m;
- }
-
- //PotentialVisibilitySet* Q3BSP::pvs=NULL;
-
- PotentialVisibilitySet* Q3BSP::buildPVS(){
- int i,j;
-
- PotentialVisibilitySet* pvs=new PotentialVisibilitySet(numLeafs);
-
- PVSCluster_t** newClusters=pvs->getClusters();
- for(i=0;i<numLeafs;i++){
- newClusters[i]->min[0]=(float)(pLeafs[i].min.x*Q3BSP_SCALE);
- newClusters[i]->min[1]=(float)(pLeafs[i].min.y*Q3BSP_SCALE);
- newClusters[i]->min[2]=(float)(pLeafs[i].min.z*Q3BSP_SCALE);
- newClusters[i]->max[0]=(float)(pLeafs[i].max.x*Q3BSP_SCALE);
- newClusters[i]->max[1]=(float)(pLeafs[i].max.y*Q3BSP_SCALE);
- newClusters[i]->max[2]=(float)(pLeafs[i].max.z*Q3BSP_SCALE);
- //newClusters[i]->visibleClusters=new BitSet(numLeafs);
- //newClusters[i]->visibleClusters->clearAll();
-
- for(j=0;j<numLeafs;j++){
- if(clusterIsVisible(pLeafs[i].cluster, pLeafs[j].cluster)){
- newClusters[i]->visibleClusters->set(j);
- }
- }
- }
-
- log("Q3BSP::buildPVS(): %i clusters in PVS.\n", pvs->getNumClusters());
- return pvs;
- }
-
- Q3bspExtension* Q3BSP::buildQ3bspExtension(){
- int i;
-
- Q3bspExtension* ret=new Q3bspExtension();
-
- ret->mesh=convertToMesh();
- ret->pvs=buildPVS();
- ret->facesDrawn=new BitSet(ret->mesh->numFaces);
-
- ret->nodes=new Q3bspExtensionNode_t*[numNodes];
- ret->numNodes=numNodes;
- for(i=0;i<numNodes;i++){
- ret->nodes[i]=new Q3bspExtensionNode_t;
- ret->nodes[i]->min[0]=(float)(pNodes[i].min.x*Q3BSP_SCALE);
- ret->nodes[i]->min[1]=(float)(pNodes[i].min.y*Q3BSP_SCALE);
- ret->nodes[i]->min[2]=(float)(pNodes[i].min.z*Q3BSP_SCALE);
- ret->nodes[i]->max[0]=(float)(pNodes[i].max.x*Q3BSP_SCALE);
- ret->nodes[i]->max[1]=(float)(pNodes[i].max.y*Q3BSP_SCALE);
- ret->nodes[i]->max[2]=(float)(pNodes[i].max.z*Q3BSP_SCALE);
- ret->nodes[i]->front=pNodes[i].front;
- ret->nodes[i]->back=pNodes[i].back;
- vectorCopy3d(pPlanes[pNodes[i].plane].normal, ret->nodes[i]->plane);
- ret->nodes[i]->plane[3]=pPlanes[pNodes[i].plane].d*Q3BSP_SCALE;
- }
-
- ret->leafs=new Q3bspExtensionLeaf_t*[numLeafs];
- ret->numLeafs=numLeafs;
- for(i=0;i<numLeafs;i++){
- ret->leafs[i]=new Q3bspExtensionLeaf_t;
- ret->leafs[i]->min[0]=(float)(pLeafs[i].min.x*Q3BSP_SCALE);
- ret->leafs[i]->min[1]=(float)(pLeafs[i].min.y*Q3BSP_SCALE);
- ret->leafs[i]->min[2]=(float)(pLeafs[i].min.z*Q3BSP_SCALE);
- ret->leafs[i]->max[0]=(float)(pLeafs[i].max.x*Q3BSP_SCALE);
- ret->leafs[i]->max[1]=(float)(pLeafs[i].max.y*Q3BSP_SCALE);
- ret->leafs[i]->max[2]=(float)(pLeafs[i].max.z*Q3BSP_SCALE);
-
- ret->leafs[i]->numFaceIndices=0;
- int k, findex;
- for(k=0;k<pLeafs[i].numOfLeafFaces;k++){
- findex=pLeafFaces[pLeafs[i].leafface+k];
- if(faceShouldBeConverted(&pFaces[findex])){
- ret->leafs[i]->numFaceIndices += (pFaces[findex].numMeshVerts/3);
- }
- }
- ret->leafs[i]->faceIndices=new int[ret->leafs[i]->numFaceIndices];
- int c=0;
- for(k=0;k<pLeafs[i].numOfLeafFaces;k++){
- findex=pLeafFaces[pLeafs[i].leafface+k];
- if(faceShouldBeConverted(&pFaces[findex])){
- int si=pFaces[findex].startVertIndex;
- for(int l=0;l<(pFaces[findex].numMeshVerts/3);l++){
- ret->leafs[i]->faceIndices[c]=si+l;
- c++;
- }
- }
- }
- }
-
- ret->numTextures=numTextures;
- ret->textures=new Texture*[numTextures];
- for(i=0;i<numTextures;i++)
- ret->textures[i]=textures[i];
- ret->numLightmaps=numLightmaps;
-
- ret->lightmaps=new Texture*[numLightmaps];
- for(i=0;i<numLightmaps;i++)
- ret->lightmaps[i]=lightmaps[i];
-
- log("Q3BSP::buildQ3bspExtension(): done.\n");
- return ret;
- }
-
-
- void Q3BSP::clear(){
- // int i;
-
- if(pVerts){
- delete[] pVerts;
- pVerts = NULL;
- numVerts=0;
- }
-
- if(pMeshVerts){
- delete[] pMeshVerts;
- pMeshVerts=0;
- numMeshVerts=0;
- }
-
- if(pFaces){
- delete[] pFaces;
- pFaces = NULL;
- numFaces=0;
- }
-
-
- if(pNodes){
- delete[] pNodes;
- pNodes = NULL;
- numNodes=0;
- }
-
- if(pLeafs){
- delete[] pLeafs;
- pLeafs = NULL;
- numLeafs=0;
- }
-
- if(pLeafFaces){
- delete[] pLeafFaces;
- pLeafFaces = NULL;
- numLeafs=0;
- }
-
- if(pPlanes){
- delete[] pPlanes;
- pPlanes = NULL;
- numPlanes=0;
- }
-
- if(clusters.pBitsets){
- delete[] clusters.pBitsets;
- clusters.pBitsets = NULL;
- clusters.numOfClusters=0;
- }
- /*
- for(i=0;i<numTextures;i++){
- if(textures[i]!=NULL){
- delete textures[i];
- textures[i]=NULL;
- }
- }
- numTextures=0;
-
- for(i=0;i<numLightmaps;i++){
- if(lightmaps[i]!=NULL){
- delete lightmaps[i];
- lightmaps[i]=NULL;
- }
- }
- numLightmaps=0;
- */
- }
-
-
-
-
-
-
- Q3bspExtension* Q3bspLoader::q3bspExtension=NULL;
-
- bool Q3bspLoader::loadBSP(const char* filename, Model* model){
- Q3BSP* bsp=new Q3BSP(filename);
-
- q3bspExtension=bsp->buildQ3bspExtension();
- model->addMesh(q3bspExtension->mesh);
-
- delete bsp;
-
- return true;
- }
-