home *** CD-ROM | disk | FTP | other *** search
/ 3D Games - Real-time Rend…ng & Software Technology / 3D Games - Real-time Rendering & Software Technology.iso / flysdk / frontend / flyPVS / pvsengine.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-04-08  |  6.2 KB  |  297 lines

  1. #include "../../lib/Fly3D.h"
  2. #include "pvsengine.h"
  3. #include "opengl.h"
  4.  
  5. extern int cur_side,savelog;
  6. extern HDC hdc;
  7. extern short **face_nodes;
  8. extern char file[256];
  9. extern float VOLUME_FACTOR;
  10. char flypathname[256];
  11.  
  12. void pvsEngine::set_pvs_bit(int node1,int node2)
  13. {
  14.     *(pvs + node1*pvsrowsize + (node2>>3)) |= (1<<(node2&7));
  15. }
  16.  
  17. int pvsEngine::get_pvs_bit(int node1,int node2)
  18. {
  19.     return PVS_TEST(node1,node2);
  20. }
  21.  
  22. static_mesh *pvsEngine::get_object(bsp_node *n)
  23. {
  24.     bsp_object *e=n->elem;
  25.     while(e)
  26.         {
  27.         if (e->type==TYPE_STATIC_MESH)
  28.             break;
  29.         e=e->next_elem;
  30.         }
  31.     return (static_mesh *)e;
  32. }
  33.  
  34. void pvsEngine::draw_bsp(bsp_node *n,vector& p,vector& z)
  35. {
  36.     if (n->leaf!=-1)
  37.         {
  38.         static_mesh *o=get_object(n);
  39.         if (o==0)
  40.             return;
  41.         int i,j;
  42.         for( i=0;i<o->objmesh->nf;i++)
  43.             {
  44.             if (o->objmesh->faces[i]->color.w<1.0f)
  45.                 {
  46.                 glEnd();
  47.                 glEnable(GL_POLYGON_STIPPLE);
  48.                 glBegin(GL_TRIANGLES);
  49.                 }
  50.  
  51.             j=o->objmesh->faces[i]->indx;
  52.     
  53.             //glColor3ub(j&255,(j>>8)&255,(j>>16)&255);
  54.             glColor3ub( ((j&31)<<3)+7, (((j>>5)&31)<<3)+7, (((j>>10)&31)<<3)+7);
  55.  
  56.             glVertex3fv((float *)o->objmesh->faces[i]->vert[0]);
  57.             glVertex3fv((float *)o->objmesh->faces[i]->vert[1]);
  58.             glVertex3fv((float *)o->objmesh->faces[i]->vert[2]);
  59.  
  60.             if (o->objmesh->faces[i]->color.w<1.0f)
  61.                 {
  62.                 glEnd();
  63.                 glDisable(GL_POLYGON_STIPPLE);
  64.                 glBegin(GL_TRIANGLES);
  65.                 }
  66.             }
  67.         return;
  68.         }
  69.  
  70.     float x,y;
  71.     x=vec_dot(n->normal,z);
  72.     y=(vec_dot(n->normal,p)+n->d0)/x;
  73.  
  74.     if (y>0)
  75.         if(fabs(x)>0.7071)
  76.         {
  77.         if (x>0)
  78.             if (n->child[0]) draw_bsp(n->child[0],p,z); else ;
  79.         else 
  80.             if (n->child[1]) draw_bsp(n->child[1],p,z); else ;
  81.         return;
  82.         }
  83.  
  84.     if (n->child[0]) draw_bsp(n->child[0],p,z);
  85.     if (n->child[1]) draw_bsp(n->child[1],p,z);
  86. }
  87.  
  88. void pvsEngine::render_hc_face(vector& p,vector& z,vector& u,char *buf)
  89. {
  90.     glLoadIdentity();
  91.     gluLookAt( 
  92.             p.x,p.y,p.z, 
  93.             p.x+z.x, p.y+z.y, p.z+z.z, 
  94.             u.x,u.y,u.z);
  95.  
  96.     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
  97.  
  98.     glPolygonMode(GL_FRONT,GL_FILL);
  99.     glBegin(GL_TRIANGLES);
  100.     draw_bsp(bsp,p,z);
  101.     glEnd();
  102.  
  103.     glReadPixels(0,0,screen_sx,screen_sy,GL_RGB,GL_UNSIGNED_BYTE,buf);
  104. }
  105.  
  106. void pvsEngine::update_pvs(int node,char *buf)
  107. {
  108.     int i,j,indx1,indx2,indx3,t=screen_sx*(screen_sy-1)-1;
  109.     unsigned char *b=(unsigned char *)buf;
  110.  
  111.     for( i=0;i<t;i++,b+=3 )
  112.     {
  113. //    indx=((unsigned)*b)+((unsigned)*(b+1)<<8)+((unsigned)*(b+2)<<16);
  114.  
  115.     indx1=((unsigned)*b>>3)+((unsigned)*(b+1)>>3<<5)+((unsigned)*(b+2)>>3<<10);
  116.     indx2=((unsigned)*(b+3)>>3)+((unsigned)*(b+4)>>3<<5)+((unsigned)*(b+5)>>3<<10);
  117.     indx3=((unsigned)*(b+screen_sx*3)>>3)+((unsigned)*(b+screen_sx*3+1)>>3<<5)+((unsigned)*(b+screen_sx*3+2)>>3<<10);
  118.  
  119.     if (indx1>=nfaces || indx1!=indx2 || indx1!=indx3)
  120.         continue;
  121.  
  122.     for(j=0;j<face_nodes[indx1][0];j++)
  123.         set_pvs_bit(node, face_nodes[indx1][j+1]);
  124.     }
  125. }
  126.  
  127. void pvsEngine::sample_node(bsp_node *n,vector& v)
  128. {
  129.     vector z,u;
  130.     
  131.     char *buf=new char[3*screen_sx*screen_sy];
  132.  
  133.     z.vec(0,0,1);
  134.     u.vec(1,0,0);
  135.     render_hc_face(v,z,u,buf);
  136.     if (cur_side==0)    SwapBuffers(hdc);
  137.     update_pvs(n->leaf,buf);
  138.  
  139.     z.vec(0,0,-1);
  140.     u.vec(1,0,0);
  141.     render_hc_face(v,z,u,buf);
  142.     if (cur_side==1)    SwapBuffers(hdc);
  143.     update_pvs(n->leaf,buf);
  144.  
  145.     z.vec(0,1,0);
  146.     u.vec(1,0,0);
  147.     render_hc_face(v,z,u,buf);
  148.     if (cur_side==2)    SwapBuffers(hdc);
  149.     update_pvs(n->leaf,buf);
  150.  
  151.     z.vec(0,-1,0);
  152.     u.vec(1,0,0);
  153.     render_hc_face(v,z,u,buf);
  154.     if (cur_side==3)    SwapBuffers(hdc);
  155.     update_pvs(n->leaf,buf);
  156.  
  157.     z.vec(1,0,0);
  158.     u.vec(0,0,1);
  159.     render_hc_face(v,z,u,buf);
  160.     if (cur_side==4)    SwapBuffers(hdc);
  161.     update_pvs(n->leaf,buf);
  162.  
  163.     z.vec(-1,0,0);
  164.     u.vec(0,0,1);
  165.     render_hc_face(v,z,u,buf);
  166.     if (cur_side==5)    SwapBuffers(hdc);
  167.     update_pvs(n->leaf,buf);
  168.     
  169.     delete buf;
  170. }
  171.  
  172. int pvsEngine::get_node_random_point(int leafnum,vector& point)
  173. {
  174.     static_mesh *so=(static_mesh *)leaf[leafnum]->elem;
  175.     boundbox bb=so->objmesh->bbox;
  176.     int i,j=10000;
  177.     for( i=0;i<j;i++ )
  178.     {
  179.         point.x =
  180.             bb.min.x+
  181.             FABSRAND*(bb.max.x-bb.min.x);
  182.         point.y =
  183.             bb.min.y+
  184.             FABSRAND*(bb.max.y-bb.min.y);
  185.         point.z =
  186.             bb.min.z+
  187.             FABSRAND*(bb.max.z-bb.min.z);
  188.         bsp_node *n=find_node(bsp,point,NEAR_PLANE_THRESHOLD);
  189.         if (n==leaf[leafnum])
  190.             break;
  191.     }
  192.     if (i==j)
  193.         return 0;
  194.     return 1;
  195. }
  196.  
  197. void pvsEngine::save_pvslog(char *f)
  198. {
  199.     FILE *fp=fopen(f,"wt");
  200.     if (fp)
  201.     {
  202.         int i,j,k,t=0;
  203.  
  204.         fprintf(fp,"nodenum\tnfaces\tnsamp\tnvis\tbboxx\tbboxy\tbboxz\n");
  205.  
  206.         for( i=0;i<nleaf;i++ )
  207.         {
  208.             k=0;
  209.             for( j=0;j<nleaf;j++ )
  210.                 if (PVS_TEST(i,j))
  211.                     k++;
  212.             t+=k;
  213.  
  214.             static_mesh *so=(static_mesh *)leaf[i]->elem;
  215.             if(so==0)
  216.                 fprintf(fp,"%i\n",i);
  217.             else 
  218.             {
  219.                 vector v=so->objmesh->bbox.max-so->objmesh->bbox.min;
  220.                 float vol=v.x*v.y*v.z;
  221.                 j=(int)(vol/VOLUME_FACTOR)+1;
  222.                 fprintf(fp,"%i\t%i\t%i\t%i\t%.1f\t%.1f\t%.1f\n",
  223.                     i,so->objmesh->nf,j,k,
  224.                 so->objmesh->bbox.max.x-so->objmesh->bbox.min.x,
  225.                 so->objmesh->bbox.max.y-so->objmesh->bbox.min.y,
  226.                 so->objmesh->bbox.max.z-so->objmesh->bbox.min.z);
  227.             }
  228.         }
  229.  
  230.         fprintf(fp,"\nTotal: %i nodes (%i%%)\n",nleaf,t*100/(nleaf*nleaf));
  231.  
  232.         fclose(fp);
  233.     }
  234. }
  235.  
  236. int pvsEngine::opendata(char *f) 
  237. {
  238.     char str[256];
  239.     strcpy(flypathname,f);
  240.     *(strrchr(flypathname,'\\')+1)=0;
  241.     strcpy(file,strrchr(f,'\\')+1);
  242.     *strchr(file,'.')=0;
  243.  
  244.     strcpy(str,flypathname);
  245.     strcat(str,file);
  246.     strcat(str,".bsp");
  247.     if (load_bsp(str)==0)
  248.         return 0;
  249.  
  250.     alloc_pvs(0);
  251.  
  252.     face_nodes=new short *[nfaces];
  253.  
  254.     int i, j, k;
  255.     for( i=0;i<nfaces;i++ )
  256.     {
  257.         face_nodes[i]=new short;
  258.         face_nodes[i][0]=0;
  259.     }
  260.  
  261.     for( i=0;i<nleaf;i++ )
  262.     {
  263.         static_mesh *o=get_object(flyengine->leaf[i]);
  264.         if(o)
  265.             for(j=0;j<o->objmesh->nf;j++)
  266.             {
  267.                 k=o->objmesh->faces[j]->indx;
  268.                 short *temp=new short[face_nodes[k][0]+2];
  269.                 memcpy(temp, face_nodes[k], sizeof(short)*(face_nodes[k][0]+1));
  270.                 delete face_nodes[k];
  271.                 face_nodes[k]=temp;
  272.                 face_nodes[k][face_nodes[k][0]+1]=i;
  273.                 face_nodes[k][0]++;
  274.             }
  275.     }
  276.  
  277.     return 1;
  278. }
  279.  
  280. void pvsEngine::save()
  281. {
  282.     char str[256];
  283.  
  284.     strcpy(str,flypathname);
  285.     strcat(str,file);
  286.     strcat(str,".pvs");
  287.     save_pvs(str);
  288.  
  289.     if (savelog)
  290.     {
  291.     strcpy(str,flypathname);
  292.     strcat(str,file);
  293.     strcat(str,".pvslog.txt");
  294.     save_pvslog(str);
  295.     }
  296. }
  297.