Advertisement
mrDIMAS

Blitz 3D BSP Loader

Jun 11th, 2014
511
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 17.72 KB | None | 0 0
  1.  
  2. #include "std.h"
  3. #include "q3bsprep.h"
  4.  
  5. /* Quake3 File format types */
  6.  
  7. #pragma pack(push,1)
  8.  
  9. struct q3_plane{
  10.     Vector normal;
  11.     float distance;
  12. };
  13.  
  14. struct q3_tex{
  15.     char name[64];
  16.     int flags,contents;
  17. };
  18.  
  19. struct q3_vertex{
  20.     Vector coords;
  21.     float tex_coords[4];
  22.     Vector normal;
  23.     unsigned char color[4];
  24. };
  25.  
  26. struct q3_node{
  27.     int plane;
  28.     int children[2];
  29.     int mins[3];
  30.     int maxs[3];
  31. };
  32.  
  33. struct q3_face{
  34.     int texture;
  35.     int effect;
  36.     int type;
  37.     int vertex;
  38.     int n_verts;
  39.     int meshvert;
  40.     int n_meshverts;
  41.     int lm_index;
  42.     int lm_start[2];
  43.     int lm_size[2];
  44.     float lm_origin[3];
  45.     float lm_vecs[2][3];
  46.     float normal[3];
  47.     int patch_size[2];
  48. };
  49.  
  50. struct q3_leaf{
  51.     int cluster;
  52.     int area;
  53.     int mins[3];
  54.     int maxs[3];
  55.     int leafface;
  56.     int n_leaffaces;
  57.     int leafbrush;
  58.     int n_leafbrushes;
  59. };
  60.  
  61. struct q3_brush{
  62.     int brushside;
  63.     int n_brushsides;
  64.     int texture;
  65. };
  66.  
  67. struct q3_brushside{
  68.     int plane;
  69.     int texture;
  70. };
  71.  
  72. struct q3_direntry{
  73.     union{
  74.         int offset;
  75.         void *lump;
  76.     };
  77.     int length;
  78. };
  79.  
  80. struct q3_header{
  81.     unsigned magic;
  82.     int version;
  83.     q3_direntry dir[17];
  84. };
  85.  
  86. #pragma pack(pop)
  87.  
  88. /* Loading reps */
  89. struct Surf{
  90.     Q3BSPSurf *surf;
  91.     int texture,lm_index;
  92.     vector<int> verts,tris;
  93. };
  94.  
  95. struct FaceCmp{
  96.     bool operator()( const q3_face *a,const q3_face *b )const{
  97.         if( a->texture<b->texture ) return true;
  98.         if( b->texture<a->texture ) return false;
  99.         if( a->lm_index<b->lm_index ) return true;
  100.         return false;
  101.     }
  102. };
  103.  
  104. typedef map<q3_face*,Surf*,FaceCmp> FaceMap;
  105.  
  106. /* render reps */
  107.  
  108. struct Q3BSPFace;
  109.  
  110. struct Q3BSPSurf{
  111.     Brush brush;
  112.     gxMesh *mesh;
  113.     vector<Q3BSPFace*> r_faces;
  114.     int texture,lm_index;
  115. };
  116.  
  117. struct Q3BSPFace{
  118.     union{
  119.         Surf *t_surf;
  120.         Q3BSPSurf *surf;
  121.     };
  122.     int vert,n_verts,tri,n_tris;
  123. };
  124.  
  125. struct Q3BSPBrush{
  126.     vector<Plane> planes;
  127. };
  128.  
  129. struct Q3BSPLeaf{
  130.     int cluster;
  131.     Box box;
  132.     vector<Q3BSPFace*> faces;
  133. };
  134.  
  135. struct Q3BSPNode{
  136.     Box box;
  137.     Plane plane;
  138.     Q3BSPNode *nodes[2];
  139.     Q3BSPLeaf *leafs[2];
  140.  
  141.     ~Q3BSPNode(){ delete nodes[0];delete nodes[1];delete leafs[0];delete leafs[1]; }
  142. };
  143.  
  144. static q3_header header;
  145. static FaceMap face_map;
  146. static vector<Surf*> t_surfs;
  147. static vector<q3_vertex> p_verts;   //patch vertices
  148. static vector<Vector> p_coll_verts;
  149. static vector<MeshCollider::Triangle> coll_tris;
  150.  
  151. static float gamma_adj;
  152.  
  153. static Vector r_eye;
  154. static int r_cluster;
  155. static Frustum r_frustum;
  156. static Vector r_frustedges[12];
  157. static map<int,Q3BSPFace*> q3face_map;
  158.  
  159. extern gxScene *gx_scene;
  160. extern gxRuntime *gx_runtime;
  161. extern gxGraphics *gx_graphics;
  162.  
  163. //#define SWAPTRIS
  164. Vector static tf( const Vector &v ){
  165.     return Vector( -v.y,v.z,v.x );
  166. }
  167.  
  168. #ifdef BETA
  169. static void log( const string &t ){
  170.     gx_runtime->debugLog( t.c_str() );
  171. }
  172. #else
  173. static void log( const string &t ){}
  174. #endif
  175.  
  176. static Surf *findSurf( q3_face *f ){
  177.     FaceMap::const_iterator it=face_map.find( f );
  178.     if( it!=face_map.end() ) return it->second;
  179.     Surf *s=d_new Surf;
  180.     s->texture=f->texture;
  181.     s->lm_index=f->lm_index;
  182.     face_map.insert( make_pair( f,s ) );
  183.     t_surfs.push_back( s );
  184.     return s;
  185. }
  186.  
  187. void Q3BSPRep::createTextures(){
  188.     int n_texs=header.dir[1].length/sizeof(q3_tex);
  189.     q3_tex *q3tex=(q3_tex*)header.dir[1].lump;
  190.     for( int k=0;k<n_texs;++k ){
  191.         string t=string(q3tex->name);
  192. //      char fl[32],co[32];
  193. //      ::itoa( q3tex->flags,fl,16 );
  194. //      ::itoa( q3tex->contents,co,16 );
  195. //      log( t+", flags=0x"+fl+", contents=0x"+co );
  196.         Texture tex( t+".tga",1 );
  197.         if( !tex.getCanvas(0) ) tex=Texture( t+".jpg",1 );
  198.         if( !tex.getCanvas(0) ) log( "Failed!" );
  199.         tex.setFlags( 1 );
  200.         textures.push_back( tex );
  201.         ++q3tex;
  202.     }
  203. }
  204.  
  205. void Q3BSPRep::createLightMaps(){
  206.     int n_lmaps=header.dir[14].length/(128*128*3);
  207.     unsigned char *rgb=(unsigned char*)header.dir[14].lump;
  208.     unsigned char adj[256];
  209.     int k;
  210.     for( k=0;k<256;++k ) adj[k]=(unsigned char)(pow( k/255.0f,gamma_adj )*255.0f);
  211.  
  212.     for( k=0;k<n_lmaps;++k ){
  213.         Texture tex( 128,128,1+8+16+32,1 );
  214.         tex.setBlend( gxScene::BLEND_ADD );
  215.         gxCanvas *c=tex.getCanvas(0);
  216.         c->lock();
  217.         for( int y=0;y<128;++y ){
  218.             for( int x=0;x<128;++x ){
  219.                 unsigned argb=0xff000000|(adj[rgb[0]]<<16)|(adj[rgb[1]]<<8)|adj[rgb[2]];
  220.                 c->setPixelFast( x,y,argb );
  221.                 rgb+=3;
  222.             }
  223.         }
  224.         c->unlock();
  225.         light_maps.push_back( tex );
  226.     }
  227. }
  228.  
  229. void Q3BSPRep::createVis(){
  230.     int *vis=(int*)header.dir[16].lump;
  231.     int n_vecs=*vis++;
  232.     vis_sz=*vis++;
  233.     log( "vis: "+itoa(n_vecs)+","+itoa(vis_sz) );
  234.     vis_data=new char[n_vecs*vis_sz];
  235.     memcpy( vis_data,vis,n_vecs*vis_sz );
  236. }
  237.  
  238. void Q3BSPRep::createCollider(){
  239.     vector<MeshCollider::Vertex> coll_verts;
  240.     int n_verts=header.dir[10].length/sizeof(q3_vertex);
  241.     q3_vertex *t=(q3_vertex*)header.dir[10].lump;
  242.     MeshCollider::Vertex cv;
  243.     int k;
  244.     for( k=0;k<n_verts;++k ){
  245.         cv.coords=tf( t->coords );
  246.         coll_verts.push_back( cv );
  247.         ++t;
  248.     }
  249.     for( k=0;k<p_coll_verts.size();++k ){
  250.         cv.coords=p_coll_verts[k];
  251.         coll_verts.push_back( cv );
  252.     }
  253. #ifdef SWAPTRIS
  254.     for( k=0;k<coll_tris.size();++k ){
  255.         std::swap( coll_tris[k].verts[1],coll_tris[k].verts[2] );
  256.     }
  257. #endif
  258.     collider=d_new MeshCollider( coll_verts,coll_tris );
  259.     p_coll_verts.clear();
  260.     coll_verts.clear();
  261.     coll_tris.clear();
  262. }
  263.  
  264. void Q3BSPRep::createSurfs(){
  265.     int k;
  266.     for( k=0;k<t_surfs.size();++k ){
  267.         Surf *s=t_surfs[k];
  268.         gxMesh *mesh=gx_graphics->createMesh( s->verts.size(),s->tris.size()/3,0 );
  269.  
  270.         mesh->lock(gxMesh::LOCK_REUSE);
  271.         int j;
  272.         for( j=0;j<s->verts.size();++j ){
  273.             q3_vertex *t;
  274.             int n=s->verts[j];
  275.             if( n>=0 ){
  276.                 t=(q3_vertex*)header.dir[10].lump+n;
  277.             }else{
  278.                 t=&p_verts[-n-1];
  279.             }
  280.             float tex_coords[2][2]={ {t->tex_coords[2],t->tex_coords[3]},{t->tex_coords[0],t->tex_coords[1]}};
  281.             unsigned argb=0xff000000|(t->color[0]<<16)|(t->color[1]<<8)|t->color[2];
  282.             mesh->setVertex( j,tf(t->coords),tf(t->normal),argb,tex_coords );
  283.         }
  284.         for( j=0;j<s->tris.size();j+=3 ){
  285. #ifdef SWAPTRIS
  286.             mesh->setTriangle( j/3,s->tris[j],s->tris[j+2],s->tris[j+1] );
  287. #else
  288.             mesh->setTriangle( j/3,s->tris[j],s->tris[j+1],s->tris[j+2] );
  289. #endif
  290.         }
  291.         mesh->unlock();
  292.  
  293.         Q3BSPSurf *surf=d_new Q3BSPSurf;
  294.         surf->texture=s->texture;
  295.         surf->lm_index=s->lm_index;
  296.         surf->mesh=mesh;
  297.         surfs.push_back( surf );
  298.         s->surf=surf;
  299.     }
  300.     for( k=0;k<faces.size();++k ){
  301.         Q3BSPFace *f=faces[k];
  302.         f->surf=f->t_surf->surf;
  303.         f->tri/=3;f->n_tris/=3;
  304.     }
  305.     for( k=0;k<t_surfs.size();++k ){
  306.         delete t_surfs[k];
  307.     }
  308.     face_map.clear();
  309.     t_surfs.clear();
  310.     p_verts.clear();
  311. }
  312.  
  313. static void average( const q3_vertex &a,const q3_vertex &b,q3_vertex *c ){
  314.     c->coords=(a.coords+b.coords)*.5f;
  315.     c->normal=(a.normal+b.normal)*.5f;
  316.     for( int k=0;k<4;++k ){
  317.         c->color[k]=(a.color[k]+b.color[k]+1)/2;
  318.         c->tex_coords[k]=(a.tex_coords[k]+b.tex_coords[k])*.5f;
  319.     }
  320. }
  321.  
  322. static void subdivide( vector<q3_vertex> &verts,int level,int index,int step ){
  323.     if( !level ){
  324.         q3_vertex t1,t2;
  325.         average( verts[index],verts[index+step],&t1 );
  326.         average( verts[index+step],verts[index+step*2],&t2 );
  327.         average( t1,t2,&verts[index+step] );
  328.         return;
  329.     }
  330.     average( verts[index],verts[index+step],&verts[index+step/2] );
  331.     average( verts[index+step],verts[index+step*2],&verts[index+step+step/2] );
  332.     average( verts[index+step/2],verts[index+step+step/2],&verts[index+step] );
  333.     subdivide( verts,level-1,index,step/2 );
  334.     subdivide( verts,level-1,index+step,step/2 );
  335. }
  336.  
  337. static void patchFace( Q3BSPFace *face,q3_face *q3face,bool draw,bool solid,int level ){
  338.  
  339.     int k,x,y;
  340.     vector<q3_vertex> verts;
  341.  
  342.     if( draw ){
  343.         int step=1<<level;
  344.         int size_x=(q3face->patch_size[0]-1)*step+1;
  345.         int size_y=(q3face->patch_size[1]-1)*step+1;
  346.         verts.resize( size_x*size_y );
  347.  
  348.         //seed initial verts
  349.         q3_vertex *t=(q3_vertex*)header.dir[10].lump+q3face->vertex;
  350.         for( y=0;y<size_y;y+=step ){
  351.             for( x=0;x<size_x;x+=step ){
  352.                 verts[y*size_x+x]=*t++;
  353.             }
  354.         }
  355.         //subdivide!
  356.         for( y=0;y<size_y;y+=step ){
  357.             for( x=0;x<size_x-1;x+=step*2 ){
  358.                 subdivide( verts,level,y*size_x+x,step );
  359.             }
  360.         }
  361.         for( x=0;x<size_x;++x ){
  362.             for( y=0;y<size_y-1;y+=step*2 ){
  363.                 subdivide( verts,level,y*size_x+x,size_x*step );
  364.             }
  365.         }
  366.  
  367.         Surf *surf=face->t_surf;
  368.         int vert=surf->verts.size()-face->vert;
  369.  
  370.         //generate patch verts
  371.         for( k=0;k<size_x*size_y;++k ){
  372.             p_verts.push_back( verts[k] );
  373.             surf->verts.push_back( -p_verts.size() );
  374.         }
  375.         face->n_verts+=size_x*size_y;
  376.  
  377.         //generate tris...
  378.         for( y=0;y<size_y-1;++y ){
  379.             int n=y*size_x+vert;
  380.             for( x=0;x<size_x-1;++n,++x ){
  381.                 surf->tris.push_back( n );
  382.                 surf->tris.push_back( n+size_x );
  383.                 surf->tris.push_back( n+1 );
  384.                 surf->tris.push_back( n+size_x+1 );
  385.                 surf->tris.push_back( n+1 );
  386.                 surf->tris.push_back( n+size_x );
  387.             }
  388.         }
  389.         face->n_tris+=(size_x-1)*(size_y-1)*6;
  390.     }
  391.  
  392.     if( solid ){
  393.         vector<q3_vertex> verts;
  394.         int step=1;
  395.         int size_x=q3face->patch_size[0];
  396.         int size_y=q3face->patch_size[1];
  397.         verts.resize( size_x*size_y );
  398.  
  399.         //seed initial verts
  400.         q3_vertex *t=(q3_vertex*)header.dir[10].lump+q3face->vertex;
  401.         for( k=0;k<size_x*size_y;++k ) verts[k]=*t++;
  402.         //subdivide!
  403.         for( y=0;y<size_y;y+=step ){
  404.             for( x=0;x<size_x-1;x+=step*2 ){
  405.                 subdivide( verts,0,y*size_x+x,step );
  406.             }
  407.         }
  408.         for( x=0;x<size_x;++x ){
  409.             for( y=0;y<size_y-1;y+=step*2 ){
  410.                 subdivide( verts,0,y*size_x+x,size_x*step );
  411.             }
  412.         }
  413.  
  414.         int vert=header.dir[10].length/sizeof(q3_vertex)+p_coll_verts.size();
  415.  
  416.         //generate patch verts
  417.         for( k=0;k<size_x*size_y;++k ) p_coll_verts.push_back( tf(verts[k].coords) );
  418.  
  419.         MeshCollider::Triangle ct;
  420.         ct.surface=0;ct.index=0;
  421.         //generate tris...
  422.         for( y=0;y<size_y-1;++y ){
  423.             int n=y*size_x+vert;
  424.             for( x=0;x<size_x-1;++n,++x ){
  425.                 ct.verts[0]=n;
  426.                 ct.verts[1]=n+size_x;
  427.                 ct.verts[2]=n+1;
  428.                 coll_tris.push_back( ct );
  429.                 ct.verts[0]=n+size_x+1;
  430.                 ct.verts[1]=n+1;
  431.                 ct.verts[2]=n+size_x;
  432.                 coll_tris.push_back( ct );
  433.             }
  434.         }
  435.     }
  436. }
  437.  
  438. static void meshFace( Q3BSPFace *face,q3_face *q3face,bool draw,bool solid ){
  439.     static map<int,int> vert_map;
  440.     vert_map.clear();
  441.     int *meshverts=(int*)header.dir[11].lump+q3face->meshvert;
  442.     MeshCollider::Triangle ct;
  443.     ct.surface=0;ct.index=0;
  444.     for( int j=0;j<q3face->n_meshverts;j+=3 ){
  445.         for( int q=0;q<3;++q ){
  446.             int n=meshverts[j+q]+q3face->vertex;
  447.             if( draw ){
  448.                 if( !vert_map.count( n ) ){
  449.                     vert_map[n]=face->t_surf->verts.size()-face->vert;
  450.                     face->t_surf->verts.push_back(n);
  451.                     ++face->n_verts;
  452.                 }
  453.                 face->t_surf->tris.push_back( vert_map[n] );
  454.                 ++face->n_tris;
  455.             }
  456.             ct.verts[q]=n;
  457.         }
  458.         if( solid ) coll_tris.push_back( ct );
  459.     }
  460. }
  461.  
  462. static Q3BSPBrush *createBrush( int n ){
  463.     Q3BSPBrush *brush=d_new Q3BSPBrush;
  464.     q3_brush *q3brush=(q3_brush*)header.dir[8].lump+n;
  465.     q3_brushside *q3brushside=(q3_brushside*)header.dir[9].lump+q3brush->brushside;
  466.     Plane p;
  467.     for( int j=0;j<q3brush->n_brushsides;++j ){
  468.         q3_plane *q3plane=(q3_plane*)header.dir[2].lump+q3brushside[j].plane;
  469.         p.n=tf( q3plane->normal );
  470.         p.d=-q3plane->distance;
  471.         brush->planes.push_back( p );
  472.     }
  473.     return brush;
  474. }
  475.  
  476. Q3BSPLeaf *Q3BSPRep::createLeaf( int n ){
  477.     q3_leaf *q3leaf=(q3_leaf*)header.dir[4].lump+n;
  478.  
  479.     Q3BSPLeaf *leaf=d_new Q3BSPLeaf;
  480.  
  481.     leaf->cluster=q3leaf->cluster;
  482.  
  483.     Vector mins( q3leaf->mins[0],q3leaf->mins[1],q3leaf->mins[2] );
  484.     Vector maxs( q3leaf->maxs[0],q3leaf->maxs[1],q3leaf->maxs[2] );
  485.     leaf->box=Box( tf(mins) );
  486.     leaf->box.update( tf(maxs) );
  487.     int *leaffaces=(int*)header.dir[5].lump+q3leaf->leafface;
  488.  
  489.     for( int k=0;k<q3leaf->n_leaffaces;++k ){
  490.  
  491.         int face_n=leaffaces[k];
  492.  
  493.         map<int,Q3BSPFace*>::const_iterator it=q3face_map.find(face_n);
  494.         if( it!=q3face_map.end() ){
  495.             if( it->second ) leaf->faces.push_back( it->second );
  496.             continue;
  497.         }
  498.  
  499.         q3_face *q3face=(q3_face*)header.dir[13].lump+leaffaces[k];
  500.  
  501.         if( q3face->type==1 || q3face->type==3 ){
  502.             if( !q3face->n_meshverts || (q3face->n_meshverts%3) ) continue;
  503.         }else if( q3face->type!=2 ) continue;
  504.  
  505.         bool draw=true,solid=true;
  506.  
  507.         if( q3face->texture>=0 ){
  508.             q3_tex *q3tex=(q3_tex*)header.dir[1].lump+q3face->texture;
  509.             if( !(q3tex->contents & 1) ) continue;
  510.             if( q3tex->flags & 0x84 ) draw=false;
  511.         }
  512.  
  513.         if( !draw && !solid ) continue;
  514.  
  515.         Q3BSPFace *face=0;
  516.         if( draw ){
  517.             Surf *surf=findSurf( q3face );
  518.             face=d_new Q3BSPFace;
  519.             face->t_surf=surf;
  520.             face->vert=surf->verts.size();
  521.             face->tri=surf->tris.size();
  522.             face->n_verts=face->n_tris=0;
  523.             leaf->faces.push_back( face );
  524.             faces.push_back( face );
  525.             q3face_map.insert( make_pair( face_n,face ) );
  526.         }
  527.  
  528.         if( q3face->type==2 ){
  529.             patchFace( face,q3face,draw,solid,1 );
  530.         }else{
  531.             meshFace( face,q3face,draw,solid );
  532.         }
  533.     }
  534.  
  535.     return leaf;
  536. }
  537.  
  538. Q3BSPNode *Q3BSPRep::createNode( int n ){
  539.     q3_node *q3node=(q3_node*)header.dir[3].lump+n;
  540.     q3_plane *q3plane=(q3_plane*)header.dir[2].lump+q3node->plane;
  541.  
  542.     Q3BSPNode *node=new Q3BSPNode;
  543.  
  544.     Vector mins( q3node->mins[0],q3node->mins[1],q3node->mins[2] );
  545.     Vector maxs( q3node->maxs[0],q3node->maxs[1],q3node->maxs[2] );
  546.  
  547.     node->box=Box( tf(mins) );
  548.     node->box.update( tf(maxs) );
  549.     node->plane.n=tf(q3plane->normal);
  550.     node->plane.d=-q3plane->distance;
  551.  
  552.     for( int k=0;k<2;++k ){
  553.         if( q3node->children[k]>=0 ){
  554.             node->nodes[k]=createNode( q3node->children[k] );
  555.             node->leafs[k]=0;
  556.         }else{
  557.             node->leafs[k]=createLeaf( -q3node->children[k]-1 );
  558.             node->nodes[k]=0;
  559.         }
  560.     }
  561.  
  562.     return node;
  563. }
  564.  
  565. Q3BSPRep::Q3BSPRep( const string &f,float gam ):root_node(0),vis_sz(0),vis_data(0),use_lmap(true){
  566.  
  567.     gamma_adj=1-gam;
  568.  
  569.     FILE *buf=fopen( f.c_str(),"rb" );if( !buf ) return;
  570.  
  571.     fread( &header,sizeof(header),1,buf );
  572.     if( header.magic!='PSBI' || header.version!=0x2e ){
  573.         fclose( buf );return;
  574.     }
  575.  
  576.     log( "Header OK" );
  577.  
  578.     int k;
  579.     //load all lumps...
  580.     for( k=0;k<17;++k ){
  581.         if( header.dir[k].offset && header.dir[k].length ){
  582.             fseek( buf,header.dir[k].offset,SEEK_SET );
  583.             header.dir[k].lump=d_new char[header.dir[k].length];
  584.             fread( header.dir[k].lump,header.dir[k].length,1,buf );
  585.         }else{
  586.             header.dir[k].lump=0;
  587.         }
  588.     }
  589.  
  590.     //create root of BSP tree
  591.     root_node=createNode( 0 );
  592.  
  593.     createCollider();
  594.  
  595.     createTextures();
  596.  
  597.     createLightMaps();
  598.  
  599.     createSurfs();
  600.  
  601.     createVis();
  602.  
  603.     //unload all lumps...
  604.     for( k=0;k<17;++k ){
  605.         delete[] header.dir[k].lump;
  606.     }
  607.  
  608.     fclose( buf );
  609.  
  610.     use_lmap=false;
  611.     setLighting( true );
  612.  
  613.     q3face_map.clear();
  614. }
  615.  
  616. Q3BSPRep::~Q3BSPRep(){
  617.     delete root_node;
  618.     delete[] vis_data;
  619.     int k;
  620.     for( k=0;k<surfs.size();++k ){
  621.         gx_graphics->freeMesh( surfs[k]->mesh );
  622.         delete surfs[k];
  623.     }
  624.     for( k=0;k<faces.size();++k ){
  625.         delete faces[k];
  626.     }
  627. }
  628.  
  629. void Q3BSPRep::vis( Q3BSPNode *n ){
  630.     int i=n->plane.distance( r_eye )<0;
  631.     if( n->nodes[i] ) vis( n->nodes[i] );
  632.     else r_cluster=n->leafs[i]->cluster;
  633. }
  634.  
  635. static bool cull( const Box &b,int *clip ){
  636.     for( int n=0;n<6;++n ){
  637.         int mask=1<<n;
  638.         if( !(*clip & mask) ) continue;
  639.         const Plane &p=r_frustum.getPlane( n );
  640.         int q=
  641.             (p.distance(b.corner(0))>=0)+(p.distance(b.corner(1))>=0)+
  642.             (p.distance(b.corner(2))>=0)+(p.distance(b.corner(3))>=0)+
  643.             (p.distance(b.corner(4))>=0)+(p.distance(b.corner(5))>=0)+
  644.             (p.distance(b.corner(6))>=0)+(p.distance(b.corner(7))>=0);
  645.         if( !q ) return false;
  646.         if( q==8 ) *clip&=~mask;
  647.     }
  648.     return true;
  649. }
  650.  
  651. void Q3BSPRep::render( Q3BSPLeaf *l,int clip ){
  652.     int cluster=l->cluster;
  653.     if( cluster<0 ) return;
  654.  
  655.     if( r_cluster>=0 ){
  656.         if( !( vis_data[cluster*vis_sz+r_cluster/8] & (1<<(r_cluster&7))) ) return;
  657.     }
  658.  
  659.     if( clip && !cull( l->box,&clip ) ) return;
  660.  
  661.     for( int k=0;k<l->faces.size();++k ){
  662.         Q3BSPFace *f=l->faces[k];
  663.         if( Q3BSPSurf *s=f->surf ){
  664.             if( !s->r_faces.size() ) r_surfs.push_back( s );
  665.             s->r_faces.push_back( f );
  666.             f->surf=0;
  667.         }
  668.     }
  669. }
  670.  
  671. void Q3BSPRep::render( Q3BSPNode *n,int clip ){
  672.     if( clip && !cull( n->box,&clip ) ) return;
  673.  
  674.     //draw front to back...
  675.     int i=n->plane.distance( r_eye )<0;
  676.     if( n->nodes[i] ) render( n->nodes[i],clip );
  677.     else render( n->leafs[i],clip );
  678.     i^=1;
  679.     if( n->nodes[i] ) render( n->nodes[i],clip );
  680.     else render( n->leafs[i],clip );
  681. }
  682.  
  683. void Q3BSPRep::render( Model *model,const RenderContext &rc ){
  684.     r_eye=-model->getRenderTform() * rc.getCameraTform().v;
  685.     new( &r_frustum ) Frustum( rc.getWorldFrustum(),-model->getRenderTform() );
  686.  
  687.     vis( root_node );
  688.     if( r_cluster==-1 ) log( "No cluster!" );
  689.     render( root_node,0x3f );
  690.  
  691.     if( !r_surfs.size() ) return;
  692.  
  693.     gx_scene->setAmbient2( &ambient.x );
  694.     gx_scene->setWorldMatrix( (gxScene::Matrix*)&model->getRenderTform() );
  695.  
  696.     int k;
  697.     for( k=0;k<r_surfs.size();++k ){
  698.         Q3BSPSurf *s=r_surfs[k];
  699.         gx_scene->setRenderState( s->brush.getRenderState() );
  700.         int j;
  701.         for( j=0;j<s->r_faces.size();++j ){
  702.             Q3BSPFace *f=s->r_faces[j];
  703.             gx_scene->render( s->mesh,f->vert,f->n_verts,f->tri,f->n_tris );
  704.             f->surf=s;
  705.         }
  706.         s->r_faces.clear();
  707.     }
  708.     r_surfs.clear();
  709. }
  710.  
  711. bool Q3BSPRep::collide( const Line &line,float radius,Collision *curr_coll,const Transform &t ){
  712.     return collider->collide( line,radius,curr_coll,t );
  713. }
  714.  
  715. void Q3BSPRep::setAmbient( const Vector &t ){
  716.     ambient=t;
  717. }
  718.  
  719. void Q3BSPRep::setLighting( bool lmap ){
  720.     if( lmap==use_lmap ) return;
  721.     int fx=gxScene::FX_CONDLIGHT;
  722.     if( use_lmap=lmap ){
  723.         int k;
  724.         for( k=0;k<surfs.size();++k ){
  725.             Q3BSPSurf *s=surfs[k];
  726.             if( s->lm_index>=0 ){
  727.                 //has a lightmap...
  728.                 s->brush.setFX( fx );
  729.                 s->brush.setTexture( 0,light_maps[s->lm_index],0 );
  730.                 if( s->texture>=0 ){
  731.                     s->brush.setTexture( 1,textures[s->texture],0 );
  732.                 }
  733.             }else{
  734.                 s->brush.setFX( fx|gxScene::FX_EMISSIVE );
  735.                 if( s->texture>=0 ){
  736.                     s->brush.setTexture( 0,textures[s->texture],0 );
  737.                 }
  738.             }
  739.         }
  740.     }else{
  741.         int k;
  742.         Texture tex;
  743.         for( k=0;k<surfs.size();++k ){
  744.             Q3BSPSurf *s=surfs[k];
  745.             s->brush.setFX( fx|gxScene::FX_EMISSIVE );
  746.             if( s->texture>=0 ){
  747.                 s->brush.setTexture( 0,textures[s->texture],0 );
  748.             }else{
  749.                 s->brush.setTexture( 0,tex,0 );
  750.             }
  751.             s->brush.setTexture( 1,tex,0 );
  752.         }
  753.     }
  754. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement