home *** CD-ROM | disk | FTP | other *** search
/ PC World 2006 July & August / PCWorld_2006-07-08_cd.bin / temacd / planearcade / planearcade.exe / Tank3.bmp / q3bsp.cpp < prev    next >
C/C++ Source or Header  |  2004-10-03  |  38KB  |  950 lines

  1.  
  2.  
  3. #include "main.h"
  4.  
  5.  
  6. //------------------------------------------------------------------
  7. // Name: QBSP()
  8. // Desc: konÜtruktor
  9. //------------------------------------------------------------------
  10. QBSP::QBSP()
  11. {
  12.  
  13.     //DirectX
  14.     g_pVB = NULL;
  15.     Texture = NULL;
  16.     LightMap = NULL;
  17.  
  18.     // Here we simply initialize our member variables to 0
  19.     // Nastav jednoduchΘ prom∞nnΘ
  20.     m_iNumOfVerts     = 0;    // PoΦet vrchol∙ scΘny nastav na 0    
  21.     m_iNumOfFaces     = 0;    // PoΦet ploÜek scΘny nastav na 0    
  22.     m_iNumOfTextures  = 0;    // PoΦet textur nastav na 0    
  23.     m_iNumOfLightmaps = 0;    // PoΦet lightmap nastav na 0    
  24.     m_iNumOfNodes      = 0;    // PoΦet uzl∙ nastav na 0    
  25.     m_iNumOfLeafs      = 0;    // PoΦe list∙ nastav na 0    
  26.     m_iNumOfLeafFaces = 0;    // PoΦet ploÜek v listu nastav na 0    
  27.     m_iNumOfPlanes      = 0;    // PoΦet d∞licφch ploch nastav na 0
  28.     m_iVisibleFaces      = 0;    // Kontrolnφ prom∞nnou, kterß uklßdß, kolik ploÜek se renderuje nastav na 0
  29.  
  30.     // Initialize all the dynamic BSP data pointers to NULL
  31.     m_ptBspVertex    = NULL;        // Vrcholy scΘny    
  32.     m_ptBspFace        = NULL;        // PloÜky scΘny    
  33.     m_ptBspNode        = NULL;        // Uzly BSP scΘny
  34.     m_ptBspLeaf        = NULL;        // Listy BSP scΘny
  35.     m_ptBspPlane    = NULL;        // D∞licφ plochy BSP scΘny
  36.     m_piLeafFaces    = NULL;        // PloÜky list∙ BSP scΘny
  37.     m_piLeafBrushes = NULL;        //
  38.     memset(&m_tBspVisData, 0, sizeof(TBspVisData));        // Alokuj pam∞¥ pro data detekce viditelnosti portßl∙
  39.  
  40.  
  41. }
  42.  
  43.  
  44. //------------------------------------------------------------------
  45. // Name: QBSP
  46. // Desc: deÜtruktor
  47. //------------------------------------------------------------------
  48. QBSP::~QBSP()
  49. {
  50.     int i=0;
  51.  
  52.     /////////////
  53.     //DirectX
  54.     /////////////
  55.  
  56.     //zmaz textury
  57.     if (Texture != NULL)
  58.     {
  59.         for ( i=0;i<m_iNumOfTextures;i++)
  60.         {
  61.             if(Texture[i] != NULL)
  62.             {
  63.                 Texture[i]->Release();
  64.             }
  65.         }
  66.         delete[] Texture ;
  67.     }
  68.  
  69.     //zmaz lightmapy
  70.     if (LightMap != NULL)
  71.     {
  72.         for ( i=0;i<m_iNumOfLightmaps;i++)
  73.         {
  74.             if(LightMap[i] != NULL)
  75.             {
  76.                 LightMap[i]->Release();
  77.             }
  78.         }
  79.         delete[] LightMap ;
  80.     }
  81.  
  82.     //vertex buffer
  83.     if (g_pVB != NULL)
  84.         g_pVB->Release();
  85.     g_pVB = NULL;
  86.         
  87. }
  88.  
  89.  
  90. //------------------------------------------------------------------
  91. // Name: LoadBSP()
  92. // Desc: Loadni Quake 3 BSP scenu
  93. //------------------------------------------------------------------
  94. bool QBSP::LoadBSP(const char *pc_filename,float Gamma)
  95. {
  96.     
  97.      FILE *pfile = NULL;          // Soubor nastav na NULL
  98.      int i = 0;                   // Prom∞nnou pro cyklovßnφ nastav na 0
  99.      char cBuf[80]  ;             // Premennß na chybovΘ hlaÜky    
  100.  
  101.      //Informacie pre Log
  102.      LogPrint("Nahravam Quake3 BSP mapu");
  103.      sprintf(cBuf,"  S·bor: %s",pc_filename);
  104.      LogPrint(cBuf);
  105.  
  106.      // Check if the .bsp file could be opened
  107.      // Pokud se napoda°φ otev°φt soubor BSP, tak
  108.      if((pfile = fopen(pc_filename, "rb")) == NULL)
  109.      {
  110.           // Display an error message and quit if the file can't be found.
  111.           // Vyho∩ chybovou hlßÜku
  112.           sprintf("  Nenasiel som s·bor %s",pc_filename);
  113.           LogPrint(cBuf);
  114.           return false;     // Vra¥ funkci false
  115.      }
  116.  
  117.      // Initialize the header and lump structures
  118.      TBspHeader t_bsp_header = {0};                         // Vyma₧ hodnoty BSP hlaviΦky
  119.      TBspLump t_bsp_lump[LUMPS_MAX_LUMPS] = {0};            // Vyma₧ hodnoty BSP identifikaΦnφch polo₧ek
  120.  
  121.      // Read in the header and lump data
  122.      // NaΦti hodnoty hlaviΦky a identifikaΦnφ polo₧ky
  123.      fread(&t_bsp_header, 1, sizeof(TBspHeader), pfile);
  124.      fread(&t_bsp_lump, LUMPS_MAX_LUMPS, sizeof(TBspLump), pfile);
  125.  
  126.      //VypφÜe informßcie pre Log
  127.      LogPrint("  Informacie o QBSP:");
  128.      sprintf(cBuf,"    verzia: %d",t_bsp_header.i_version);
  129.      LogPrint(cBuf);
  130.      sprintf(cBuf,"    pc_id: %s",t_bsp_header.pc_id );
  131.      LogPrint(cBuf);
  132.  
  133.  
  134.      // Now we know all the information about our file.  We can
  135.      // then allocate the needed memory
  136.      //
  137.      // Nynφ znßme vÜechny informace o souboru.
  138.      // Dßle budeme alokovat pot°ebnou pam∞¥ pro vÜechny pot°ebnΘ prom∞nnΘ
  139.  
  140.      // Allocate the vertex memory
  141.      // Alokuj pam∞¥ pro vrcholy
  142.      m_iNumOfVerts = t_bsp_lump[LUMPS_VERTICES].i_length / sizeof(TBspVertex);
  143.      m_ptBspVertex = new TBspVertex [m_iNumOfVerts];
  144.  
  145.      sprintf(cBuf,"    pocet vertexov: %d",m_iNumOfVerts);
  146.      LogPrint(cBuf);
  147.  
  148.      // Allocate the face memory
  149.      // Alokuj pam∞¥ pro ploÜky
  150.      m_iNumOfFaces = t_bsp_lump[LUMPS_FACES].i_length / sizeof(TBspFace);
  151.      m_ptBspFace     = new TBspFace [m_iNumOfFaces];
  152.  
  153.      sprintf(cBuf,"    pocet facov: %d",m_iNumOfFaces);
  154.      LogPrint(cBuf);
  155.  
  156.      // Allocate memory to read in the texture information.
  157.      // Alokuj pam∞¥ pro texturovΘ informace
  158.      m_iNumOfTextures = t_bsp_lump[LUMPS_TEXTURES].i_length / sizeof(TBspTexture);
  159.      TBspTexture *pt_bsp_textures = new TBspTexture [m_iNumOfTextures];
  160.  
  161.      sprintf(cBuf,"    pocet textur: %d",m_iNumOfTextures);
  162.      LogPrint(cBuf);
  163.  
  164.  
  165.      // Allocate memory to read in the lightmap data.
  166.      // Alokuj pam∞¥ pro lightmap data
  167.      m_iNumOfLightmaps = t_bsp_lump[LUMPS_LIGHTMAPS].i_length / sizeof(TBspLightmap);
  168.      TBspLightmap *pt_bsp_lightmaps = new TBspLightmap [m_iNumOfLightmaps ];
  169.  
  170.      sprintf(cBuf,"    pocet lightmap: %d",m_iNumOfLightmaps);
  171.      LogPrint(cBuf);
  172.  
  173.      // Seek to the position in the file that stores the vertex information
  174.      // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
  175.      // ulo₧enΘ hodnoty vrchol∙
  176.      fseek(pfile, t_bsp_lump[LUMPS_VERTICES].i_offset, SEEK_SET);
  177.  
  178.      // Go through all of the vertices that need to be read and swap axises
  179.      // Projdi vÜechny vrcholy
  180.      for(i = 0; i < m_iNumOfVerts; i++)
  181.      {
  182.           // Read in the current vertex
  183.           // ╚ti ze souboru BSP hodnoty vrchol∙
  184.           fread(&m_ptBspVertex[i], 1, sizeof(TBspVertex), pfile);
  185.  
  186.           // Swap the y and z values, and negate the new z so Y is up.
  187.           // Proho∩ hodnoty Y a Z, a nastav opaΦnΘ znamΘnko u novΘ hodnoty Z
  188.           float f_temp = m_ptBspVertex[i].pf_position[1];
  189.           m_ptBspVertex[i].pf_position[1] = m_ptBspVertex[i].pf_position[2];
  190.           m_ptBspVertex[i].pf_position[2] = -f_temp;
  191.  
  192.      }
  193.  
  194.      // Seek to the position in the file that stores the face information
  195.      // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
  196.      // ulo₧enΘ hodnoty ploÜek 
  197.      fseek(pfile, t_bsp_lump[LUMPS_FACES].i_offset, SEEK_SET);
  198.  
  199.      // Read in all the face information
  200.      // ╚ti ze souboru BSP vÜechny hodnoty ploÜek
  201.      fread(m_ptBspFace, m_iNumOfFaces, sizeof(TBspFace), pfile);
  202.  
  203.      // Seek to the position in the file that stores the texture information
  204.      // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
  205.      // ulo₧enΘ hodnoty textur
  206.      fseek(pfile, t_bsp_lump[LUMPS_TEXTURES].i_offset, SEEK_SET);
  207.  
  208.      // Read in all the texture information
  209.      // ╚ti ze souboru BSP vÜechny hodnoty textur
  210.      fread(pt_bsp_textures, m_iNumOfTextures, sizeof(TBspTexture), pfile);
  211.  
  212.      //Alokuj pama¥ pre textury
  213.      Texture = new LPDIRECT3DTEXTURE9[m_iNumOfTextures];
  214.  
  215.      // Go through all of the textures
  216.      // Projdi vÜechny textury
  217.      for(i = 0; i < m_iNumOfTextures; i++)
  218.      {
  219.           // Create a texture from the image
  220.           // NaΦti texturu
  221.          
  222.          char TexFN1[80];
  223.          char TexFN2[80];
  224.          sprintf(TexFN1,"%s.jpg",pt_bsp_textures[i].pc_filename);
  225.          sprintf(TexFN2,"%s.tga",pt_bsp_textures[i].pc_filename);
  226.  
  227.          sprintf(cBuf,"  nahravam texturu: %d %s",i,TexFN1);
  228.          LogPrint(cBuf);
  229.  
  230.          Texture[i] = NULL;
  231.  
  232.          if (FAILED(D3DXCreateTextureFromFileEx(g_pd3dDevice, //Our D3D Device
  233.                                   TexFN1,        //Filename of our texture
  234.                                   D3DX_DEFAULT, //Width:D3DX_DEFAULT = Take from file 
  235.                                   D3DX_DEFAULT, //Height:D3DX_DEFAULT = Take from file
  236.                                   Engine.MipMapLevels,  //MipLevels
  237.                                   0,            //Usage, Is this to be used as a Render Target? 0 == No
  238.                                   Engine.TextureFormat, //32-bit with Alpha, everything should support this
  239.                                   Engine.TextureCreatingFlag,//Pool, let D3D Manage our memory
  240.                                   D3DX_DEFAULT, //Filter:Default filtering
  241.                                   D3DX_DEFAULT, //MipFilter, used for filtering mipmaps
  242.                                   0,            //Disable ColourKey
  243.                                   NULL,         //SourceInfo, returns extra info if we want it (we don't)
  244.                                   NULL,         //Palette:We're not using one
  245.                                   &Texture[i])))  
  246.         {
  247.             sprintf(cBuf,"  nahravam texturu: %d %s",i,TexFN2);
  248.             LogPrint(cBuf);
  249.             if (FAILED(D3DXCreateTextureFromFileEx(g_pd3dDevice, //Our D3D Device
  250.                                   TexFN2,        //Filename of our texture
  251.                                   D3DX_DEFAULT, //Width:D3DX_DEFAULT = Take from file 
  252.                                   D3DX_DEFAULT, //Height:D3DX_DEFAULT = Take from file
  253.                                   Engine.MipMapLevels,  //MipLevels
  254.                                   0,            //Usage, Is this to be used as a Render Target? 0 == No
  255.                                   D3DFMT_UNKNOWN, //32-bit with Alpha, everything should support this
  256.                                   Engine.TextureCreatingFlag,//Pool, let D3D Manage our memory
  257.                                   D3DX_DEFAULT, //Filter:Default filtering
  258.                                   D3DX_DEFAULT, //MipFilter, used for filtering mipmaps
  259.                                   0,            //Disable ColourKey
  260.                                   NULL,         //SourceInfo, returns extra info if we want it (we don't)
  261.                                   NULL,         //Palette:We're not using one
  262.                                   &Texture[i])))  
  263.             {
  264.                 LogPrint("    chyba");
  265.             }
  266.             else
  267.             {
  268.                 LogPrint("    OK");
  269.             }
  270.         }
  271.         else
  272.         {
  273.             LogPrint("    OK");
  274.         }
  275.           
  276.      }
  277.  
  278.      // We can now free all the texture information since we already loaded them
  279.      // Vyma₧ vÜechny texturovΘ hodnoty z pam∞ti
  280.      delete [] pt_bsp_textures;
  281.  
  282.      // Seek to the position in the file that stores the lightmap information
  283.      // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
  284.      // ulo₧enΘ hodnoty lightmap
  285.      fseek(pfile, t_bsp_lump[LUMPS_LIGHTMAPS].i_offset, SEEK_SET);
  286.  
  287.      //inicializuj lightmapy
  288.      LightMap = new LPDIRECT3DTEXTURE9[m_iNumOfLightmaps];
  289.  
  290.     // Go through all of the lightmaps and read them in
  291.     // Projdi vÜechny lightmapy
  292.     for(i = 0; i < m_iNumOfLightmaps; i++)
  293.     {
  294.         // Read in the RGB data for each lightmap
  295.         // NaΦti RGB data vÜech lightmap
  296.         fread(&pt_bsp_lightmaps[i], 1, sizeof(TBspLightmap), pfile);
  297.  
  298.         // Create a texture map for each lightmap that is read in.  The lightmaps
  299.         // are always 128 by 128.
  300.         // Vytvo° lightmap texturu kterß mß velikost v₧dy 128x128 
  301.         
  302.         sprintf(cBuf,"  Vytvaram LightMapu ID: %d",i);
  303.         LogPrint(cBuf);
  304.  
  305.         LightMap[i] = NULL;
  306.  
  307.         if (FAILED(D3DXCreateTexture(g_pd3dDevice,128,128,0,0,D3DFMT_A8R8G8B8,D3DPOOL_MANAGED,&LightMap[i])))
  308.         {
  309.             LogPrint("    chyba");
  310.         }
  311.         else
  312.         {
  313.             LogPrint("    OK");
  314.         }
  315.  
  316.         //skopiruj do lightmapy
  317.         D3DSURFACE_DESC pDesc;
  318.         D3DLOCKED_RECT d3dlr;
  319.         LightMap[i]->GetLevelDesc(0, &pDesc );
  320.  
  321.         LogPrint("    Otvaram lightmapu");
  322.         LightMap[i]->LockRect( 0, &d3dlr, 0, 0 );
  323.         DWORD *pDst = (DWORD *)d3dlr.pBits;
  324.  
  325.         for (int x=0;x<128;x++)
  326.         {
  327.             for (int y=0;y<128;y++)
  328.             {
  329.                 //gamma
  330.                 float f_scale = 1.0f;                // M∞°φtko nastav na 1 
  331.                 float f_temp = 0.0f;                // Odkßdacφ zßsobnφk nastav na 0
  332.                 float f_r = 0, f_g = 0, f_b = 0;    // BarevnΘ kanßly nastav na 0
  333.  
  334.                 f_r = (float) pt_bsp_lightmaps[i].pppby_image_bits[y][x][0];
  335.                 f_g = (float) pt_bsp_lightmaps[i].pppby_image_bits[y][x][1];
  336.                 f_b = (float) pt_bsp_lightmaps[i].pppby_image_bits[y][x][2];
  337.  
  338.                 f_r = f_r * Gamma / 255.0f;
  339.                 f_g = f_g * Gamma / 255.0f;
  340.                 f_b = f_b * Gamma / 255.0f;
  341.  
  342.                 if(f_r > 1.0f && (f_temp = (1.0f / f_r)) < f_scale) f_scale = f_temp;
  343.                 if(f_g > 1.0f && (f_temp = (1.0f / f_g)) < f_scale) f_scale = f_temp;
  344.                 if(f_b > 1.0f && (f_temp = (1.0f / f_b)) < f_scale) f_scale = f_temp;
  345.  
  346.                 f_scale *= 255.0f;        
  347.                 f_r *= f_scale;    
  348.                 f_g *= f_scale;    
  349.                 f_b *= f_scale;
  350.  
  351.                 pt_bsp_lightmaps[i].pppby_image_bits[y][x][0] = (BYTE) f_r;
  352.                 pt_bsp_lightmaps[i].pppby_image_bits[y][x][1] = (BYTE) f_g;
  353.                 pt_bsp_lightmaps[i].pppby_image_bits[y][x][2] = (BYTE) f_b;
  354.  
  355.                 pDst[y*128+x] = (255 << 24 | pt_bsp_lightmaps[i].pppby_image_bits[y][x][0] << 16 | 
  356.                                              pt_bsp_lightmaps[i].pppby_image_bits[y][x][1] << 8  | 
  357.                                              pt_bsp_lightmaps[i].pppby_image_bits[y][x][2]  );
  358.             }
  359.         }
  360.  
  361.         LogPrint("    Zatvaram lightmapu");
  362.         LightMap[i]->UnlockRect (0);
  363.     }
  364.  
  365.     
  366.      // Delete the image bits because we are already done with them
  367.      // Vyma₧ vÜechny lightmap hodnoty z pam∞ti
  368.      delete [] pt_bsp_lightmaps;
  369.  
  370.      // Store the number of nodes and allocate the memory to hold them
  371.      // NaΦti poΦet uzl∙ a alokuj pro n∞ pam∞¥
  372.      m_iNumOfNodes = t_bsp_lump[LUMPS_NODES].i_length / sizeof(TBspNode);
  373.      m_ptBspNode     = new TBspNode [m_iNumOfNodes];
  374.  
  375.      // Seek to the position in the file that hold the nodes and store them in m_ptBspNode
  376.      // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
  377.      // ulo₧enΘ hodnoty uzl∙ a tyto hodnoty naΦti
  378.      fseek(pfile, t_bsp_lump[LUMPS_NODES].i_offset, SEEK_SET);
  379.      fread(m_ptBspNode, m_iNumOfNodes, sizeof(TBspNode), pfile);
  380.  
  381.      // Store the number of leafs and allocate the memory to hold them
  382.      // NaΦti poΦet list∙ a alokuj pro n∞ pam∞¥ 
  383.      m_iNumOfLeafs = t_bsp_lump[LUMPS_LEAFS].i_length / sizeof(TBspLeaf);
  384.      m_ptBspLeaf     = new TBspLeaf [m_iNumOfLeafs];
  385.  
  386.      // Seek to the position in the file that holds the leafs and store them in m_ptBspLeaf
  387.      // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
  388.      // ulo₧enΘ hodnoty list∙ a tyto hodnoty naΦti
  389.      fseek(pfile, t_bsp_lump[LUMPS_LEAFS].i_offset, SEEK_SET);
  390.      fread(m_ptBspLeaf, m_iNumOfLeafs, sizeof(TBspLeaf), pfile);
  391.  
  392.      // Now we need to go through and convert all the leaf bounding boxes
  393.      // to the normal OpenGL Y up axis.
  394.      // Projdi vÜechny listy a proho∩ hodnoty Y na Z vÜech obßlek list∙.
  395.      // OpenGL mß toti₧ Y a Z hodnoty prohozeny oproti
  396.      // ostatnφm grafick²m program∙m (nap°. 3dsMax)
  397.      for(i = 0; i < m_iNumOfLeafs; i++)
  398.      {
  399.           // Swap the min y and z values, then negate the new Z
  400.           // Proho∩  minimßlnφ hodnoty obßlky Y na Z.
  401.           // U Z hodnoty nastav opaΦnΘ znamΘnko
  402.           float f_temp = (float) m_ptBspLeaf[i].pi_min_box[1];
  403.           m_ptBspLeaf[i].pi_min_box[1] = (int) m_ptBspLeaf[i].pi_min_box[2];
  404.           m_ptBspLeaf[i].pi_min_box[2] = (int)-f_temp;
  405.  
  406.           // Swap the max y and z values, then negate the new Z
  407.           // Proho∩  maximßlnφ hodnoty obßlky Y na Z.
  408.           // U Z hodnoty nastav opaΦnΘ znamΘnko
  409.           f_temp = (float) m_ptBspLeaf[i].pi_max_box[1];
  410.           m_ptBspLeaf[i].pi_max_box[1] = (int)m_ptBspLeaf[i].pi_max_box[2];
  411.           m_ptBspLeaf[i].pi_max_box[2] = (int)-f_temp;
  412.       
  413.      }
  414.  
  415.      // Store the number of leaf faces and allocate the memory for them
  416.      // NaΦti poΦet ploÜek list∙ a alokuj pro n∞ pam∞¥
  417.      m_iNumOfLeafFaces = t_bsp_lump[LUMPS_LEAF_FACES].i_length / sizeof(int);
  418.      m_piLeafFaces     = new int [m_iNumOfLeafFaces];
  419.  
  420.      // Seek to the leaf faces lump, then read it's data
  421.      // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
  422.      // ulo₧enΘ hodnoty ploÜky lis∙ a tyto hodnoty naΦti
  423.      fseek(pfile, t_bsp_lump[LUMPS_LEAF_FACES].i_offset, SEEK_SET);
  424.      fread(m_piLeafFaces, m_iNumOfLeafFaces, sizeof(int), pfile);
  425.  
  426.      // Store the number of planes, then allocate memory to hold them
  427.      // NaΦti poΦet d∞licφch ploch a alokuj pro n∞ pam∞¥
  428.      m_iNumOfPlanes = t_bsp_lump[LUMPS_PLANES].i_length / sizeof(TBspPlane);
  429.      m_ptBspPlane   = new TBspPlane [m_iNumOfPlanes];
  430.  
  431.      // Seek to the planes lump in the file, then read them into m_ptBspPlane
  432.      // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
  433.      // ulo₧enΘ hodnoty d∞licφch ploch a tyto hodnoty naΦti
  434.      fseek(pfile, t_bsp_lump[LUMPS_PLANES].i_offset, SEEK_SET);
  435.      fread(m_ptBspPlane, m_iNumOfPlanes, sizeof(TBspPlane), pfile);
  436.  
  437.      // Go through every plane and convert it's normal to the Y-axis being up
  438.      // Projdi vÜechny d∞licφ plochy a proho∩ hodnoty Y na Z vÜech obßlek list∙.
  439.      // U Z hodnoty proho∩ znamΘnko
  440.      for(i = 0; i < m_iNumOfPlanes; i++)
  441.      {
  442.           float f_temp = m_ptBspPlane[i].pf_normal[1];
  443.           m_ptBspPlane[i].pf_normal[1] = m_ptBspPlane[i].pf_normal[2];
  444.           m_ptBspPlane[i].pf_normal[2] = -f_temp;
  445.      }
  446.  
  447.      // Seek to the position in the file that holds the visibility lump
  448.      // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
  449.      // ulo₧enΘ hodnoty bitov²ch informacφ viditelnosti a tyto hodnoty naΦti
  450.      fseek(pfile, t_bsp_lump[LUMPS_VIS_DATA].i_offset, SEEK_SET);
  451.  
  452.      // Check if there is any visibility information first
  453.      // Pokud existuje n∞jakß bitovß informace viditelnosti
  454.      if(t_bsp_lump[LUMPS_VIS_DATA].i_length)
  455.      {
  456.           // Read in the number of vectors and each vector's size
  457.           // NaΦti poΦet klastr∙ a jejich bytovou(1byte = 8bit∙) velikosti
  458.           fread(&(m_tBspVisData.i_num_of_clusters),     1, sizeof(int), pfile);
  459.           fread(&(m_tBspVisData.i_bytes_per_cluster), 1, sizeof(int), pfile);
  460.  
  461.           // Allocate the memory for the cluster bitsets
  462.           // Alokuj pam∞¥ pro bitovΘ hodnoty klastr∙
  463.           int i_size = m_tBspVisData.i_num_of_clusters * m_tBspVisData.i_bytes_per_cluster;
  464.           m_tBspVisData.pby_cluster_bitsets = new byte [i_size];
  465.  
  466.           // Read in the all the visibility bitsets for each cluster
  467.           // NaΦti vÜechny bitovΘ hodnoty klastr∙ pro detekci viditelnosti
  468.           fread(m_tBspVisData.pby_cluster_bitsets, 1, sizeof(byte) * i_size, pfile);
  469.      }
  470.      // Otherwise, we don't have any visibility data (prevents a crash)
  471.      else     // Pokud neexistujφ ₧ßdnΘ bitovΘ informace viditelnosti, tak
  472.           m_tBspVisData.pby_cluster_bitsets = NULL;     // Nastav bitovΘ hodnoty klastr∙ na NULL
  473.  
  474.  
  475.  
  476.      // NaΦti poΦet koliznφch srß₧ek v listu a alokuj pro n∞ pam∞¥ 
  477.     m_iNumOfLeafBrushes = t_bsp_lump[LUMPS_LEAF_BRUSHES].i_length / sizeof(int);
  478.     m_piLeafBrushes = new int[m_iNumOfLeafBrushes];
  479.  
  480.  
  481.     // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
  482.     // ulo₧enΘ hodnoty koliznφch srß₧ek v listu
  483.     fseek(pfile, t_bsp_lump[LUMPS_LEAF_BRUSHES].i_offset, SEEK_SET);
  484.     fread(m_piLeafBrushes, m_iNumOfLeafBrushes, sizeof(int), pfile);
  485.     
  486.  
  487.     // NaΦti poΦet koliznφch srß₧ek a alokuj pro n∞ pam∞¥ 
  488.     m_iNumOfBrushes = t_bsp_lump[LUMPS_BRUSHES].i_length / sizeof(TBspBrush);
  489.     m_ptBspBrush = new TBspBrush[m_iNumOfBrushes];
  490.  
  491.     sprintf(cBuf,"  Kolizne zrazky: %d",m_iNumOfLeafBrushes);
  492.     LogPrint(cBuf);
  493.  
  494.     // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
  495.     // ulo₧enΘ hodnoty koliznφch srß₧ek
  496.     fseek(pfile, t_bsp_lump[LUMPS_BRUSHES].i_offset, SEEK_SET);
  497.     fread(m_ptBspBrush, m_iNumOfBrushes, sizeof(TBspBrush), pfile);
  498.  
  499.     // NaΦti poΦet koliznφch stran srß₧ek a alokuj pro n∞ pam∞¥ 
  500.     m_iNumOfBrushSides = t_bsp_lump[LUMPS_BRUSH_SIDES].i_length / sizeof(TBspBrushSides);
  501.     m_ptBspBrushSides = new TBspBrushSides[m_iNumOfBrushSides];
  502.  
  503.     sprintf(cBuf,"  Kolizne strany: %d",m_iNumOfBrushSides);
  504.     LogPrint(cBuf);
  505.  
  506.     // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
  507.     // ulo₧enΘ hodnoty koliznφch stran srß₧ek
  508.     fseek(pfile, t_bsp_lump[LUMPS_BRUSH_SIDES].i_offset, SEEK_SET);
  509.     fread(m_ptBspBrushSides, m_iNumOfBrushSides, sizeof(TBspBrushSides), pfile);
  510.  
  511.     // NaΦti poΦet efekt∙ a alokuj pro n∞ pam∞¥ 
  512.     m_iNumOfShaders = t_bsp_lump[LUMPS_SHADERS].i_length / sizeof(TBspShader);
  513.     m_ptBspShader = new TBspShader[m_iNumOfShaders];
  514.  
  515.     sprintf(cBuf,"  Pocet efektov: %d",m_iNumOfShaders);
  516.     LogPrint(cBuf);
  517.  
  518.  
  519.     // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
  520.     // ulo₧enΘ hodnoty koliznφch stran srß₧ek
  521.     fseek(pfile, t_bsp_lump[LUMPS_SHADERS].i_offset, SEEK_SET);
  522.     fread(m_ptBspShader, m_iNumOfShaders, sizeof(TBspShader), pfile);
  523.  
  524.     // NaΦti indexy braÜφ efekt∙. 
  525.     // Index nßm bude slou₧it pro zamezenφ kolize  
  526.     // kamery s efektem. Kolize nap°. s mlhou je nesmysl, ₧e.
  527.     m_piShaderBrushIndex = new int[m_iNumOfShaders];    // Alokuj pot°ebnou pam∞¥ pro index
  528.     for(i=0; i<m_iNumOfShaders; i++)
  529.     {
  530.         m_piShaderBrushIndex[i] = m_ptBspShader[i].i_brush_index;    // NaΦti index
  531.     }
  532.  
  533.     // NaΦti poΦet model∙ a alokuj pro n∞ pam∞¥ 
  534.     m_iNumOfModels = t_bsp_lump[LUMPS_MODELS].i_length / sizeof(TBspModel);
  535.     m_ptBspModel = new TBspModel[m_iNumOfModels];
  536.  
  537.     sprintf(cBuf,"  Pocet modelov: %d",m_iNumOfModels);
  538.     LogPrint(cBuf);
  539.  
  540.     // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
  541.     // ulo₧enΘ hodnoty koliznφch stran srß₧ek
  542.     fseek(pfile, t_bsp_lump[LUMPS_MODELS].i_offset, SEEK_SET);
  543.     fread(m_ptBspModel, m_iNumOfModels, sizeof(TBspModel), pfile);
  544.  
  545.     // NaΦti indexy braÜφ efekt∙. 
  546.     // Index nßm bude slou₧it pro zamezenφ kolize  
  547.     // kamery s modelem
  548.     m_piModelBrushIndex = new int[m_iNumOfModels];    // Alokuj pot°ebnou pam∞¥ pro index
  549.     for(i=0; i<m_iNumOfModels; i++)
  550.     {
  551.         m_piModelBrushIndex[i] = m_ptBspModel[i].i_brush_index;    // NaΦti index
  552.     }
  553.  
  554.     // Store the number of mesh vertices and allocate the memory for them
  555.     // NaΦti poΦet vrchol∙ meÜφ a alokuj pro n∞ pam∞¥ 
  556.     m_iNumOfMeshVertices = t_bsp_lump[LUMPS_MESH_VERTS].i_length / sizeof(int);
  557.     m_piMeshVertices = new int [m_iNumOfMeshVertices];
  558.  
  559.     sprintf(cBuf,"  Pocet mesh vertex: %d",m_iNumOfMeshVertices);
  560.     LogPrint(cBuf);
  561.  
  562.     // Seek to the mesh vertices lump, then read it's data
  563.     // Najdi podle poΦtu byt∙ (t_bsp_lump[]) od 0 pozice (SEEK_SET(zaΦßtek souboru)) v BSP souboru
  564.     // ulo₧enΘ hodnoty vrchol∙ meÜφ a tyto hodnoty naΦti 
  565.     fseek(pfile, t_bsp_lump[LUMPS_MESH_VERTS].i_offset, SEEK_SET);
  566.     fread(m_piMeshVertices, m_iNumOfMeshVertices, sizeof(int), pfile);
  567.  
  568.      // Close the file
  569.      // Zav°i soubor
  570.      fclose(pfile);
  571.  
  572.      //Fill Vertex Buffer
  573.      //Napln Vertex Buffer
  574.      FillVertexBuffer();
  575.  
  576.      // Here we allocate enough bits to store all the faces for our bitset
  577.      // Alokuj dostateΦnΘ mno₧stvφ bit∙ pro vÜechny ploÜky, bitovΘ nastavenφ klastr∙
  578.      m_BitsetFacesDrawn.Resize(m_iNumOfFaces);
  579.  
  580.      // Return a success
  581.      // Pokud jsi doÜel a₧ sem, tak vra¥ funkci true
  582.      return true;
  583.  
  584. }
  585.  
  586.  
  587. //------------------------------------------------------------------
  588. // Name: RenderFace()
  589. // Desc: Render jedneho Facu
  590. //------------------------------------------------------------------
  591. void QBSP::RenderFace(int i_face_index)
  592. {
  593.  
  594.          
  595.     TBspFace *p_bsp_face = &m_ptBspFace[i_face_index];
  596.  
  597.     g_pd3dDevice->SetTexture( 0, Texture[p_bsp_face->i_texture_id] );
  598.  
  599.     //ak je pouzita lightmapa
  600.     if(p_bsp_face->i_lightmap_id >= 0)
  601.         g_pd3dDevice->SetTexture( 1, LightMap[p_bsp_face->i_lightmap_id] );
  602.  
  603.  
  604.     //nastav texture stage pre LightMapping
  605.     g_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0);
  606.     g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1);
  607.     g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  608.     g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
  609.  
  610.     g_pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX,1);
  611.     g_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE );
  612.     g_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  613.     g_pd3dDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
  614.  
  615.     //ak je stena 
  616.     if(p_bsp_face->i_type == 1)
  617.     {
  618.  
  619.             g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEXQBSP));
  620.             g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEXQBSP);
  621.             g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, p_bsp_face->i_start_vert_index
  622.                                                           , p_bsp_face->i_num_of_verts-2);
  623.     }
  624.  
  625.     g_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
  626.  
  627.     if(p_bsp_face->i_type == 3)
  628.     {
  629.         //vytvori pole vertexov
  630.         CUSTOMVERTEXQBSP *MeshVertex = NULL;
  631.         MeshVertex = new CUSTOMVERTEXQBSP[p_bsp_face->i_num_mesh_verts];
  632.         
  633.         for(int i=0; i<p_bsp_face->i_num_mesh_verts; i++)        // Proje∩ vÜechny vrcholy meÜφ
  634.         {                
  635.             // Zφskej index aktußlnφho vrcholu
  636.             int i_vert_index = m_piMeshVertices[p_bsp_face->i_mesh_vert_index + i];
  637.             
  638.             // Nastav texturovΘ koordinace
  639.             MeshVertex[i].pos.x = m_ptBspVertex[p_bsp_face->i_start_vert_index + i_vert_index].pf_position[0];
  640.             MeshVertex[i].pos.y = m_ptBspVertex[p_bsp_face->i_start_vert_index + i_vert_index].pf_position[1];
  641.             MeshVertex[i].pos.z = m_ptBspVertex[p_bsp_face->i_start_vert_index + i_vert_index].pf_position[2];
  642.  
  643.             MeshVertex[i].color = 0xffffffff;
  644.  
  645.             MeshVertex[i].tu = m_ptBspVertex[p_bsp_face->i_start_vert_index + i_vert_index].pf_texture_coord[0];
  646.             MeshVertex[i].tv = m_ptBspVertex[p_bsp_face->i_start_vert_index + i_vert_index].pf_texture_coord[1];
  647.         
  648.         }
  649.  
  650.         
  651.         //Vykresli Pole
  652.         g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEXQBSP );
  653.         g_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLELIST,p_bsp_face->i_num_mesh_verts/3,(BYTE**)&MeshVertex[0], sizeof(CUSTOMVERTEXQBSP));
  654.  
  655.         if (MeshVertex != NULL)
  656.             delete MeshVertex;
  657.         
  658.     }
  659.  
  660.  
  661.          
  662. }
  663.  
  664. //------------------------------------------------------------------
  665. // Name: 
  666. // Desc: 
  667. //------------------------------------------------------------------
  668. void QBSP::RenderBSP()
  669. {
  670.  
  671.     //vypni svetla
  672.     g_pd3dDevice->SetRenderState( D3DRS_LIGHTING,false );
  673.  
  674.  
  675.     // Reset our bitset so all the slots are zero.
  676.     // VyΦisti pam∞¥ ve kterΘ jsou ulo₧ena bitovß data vykreslen²ch ploÜek
  677.     m_BitsetFacesDrawn.ClearAll();
  678.  
  679.     // Grab the leaf index that our camera is in
  680.     // Zφskej index listu, ve kterΘm se nachßzφ kamera
  681.      int i_leaf_index = FindLeaf(Camera.Pos);
  682.  
  683.      // Grab the cluster that is assigned to the leaf
  684.      // Zφskej podle indexu klastr listu, ve kterΘm se nachßzφ kamera
  685.      int i_camera_in_cluster = m_ptBspLeaf[i_leaf_index].i_cluster;
  686.  
  687.      // Initialize our counter variables (start at the last leaf and work down)
  688.      int i = m_iNumOfLeafs;        // PoΦet list∙ p°edej hodnot∞ i
  689.      m_iVisibleFaces = 0;          // Vyma₧ vyditelnΘ ploÜky
  690.  
  691.      // Since we are using frustum culling to only draw the visible BSP leafs,
  692.      // we need to calculate the frustum every frame.  This needs to happen
  693.      // right after we position our camera.  Now the frustum planes can be defined.
  694.      // Zφskej hodnoty zornΘho pole kamery z projekΦnφ a modelovΘ matice scΘny.
  695.      // Podle hodnot zornΘho pole pak budeme urΦovat, kterΘ BSP listy jsou viditelnΘ
  696.      // a kterΘ ne. Tento v²poΦet musφme provßd∞t v ka₧dΘm cyklu p°ekreslovßnφ scΘny.
  697.      //m_Frustum.CalculateFrustum();
  698.  
  699.  
  700.      // Go through all the leafs and check their visibility
  701.      // Projdφ vÜechny listy a zjisti jejich viditelnost
  702.      while(i--)
  703.      {
  704.           // Get the current leaf that is to be tested for visibility from our camera's leaf
  705.           // Zφskej aktußlnφ list, kter² budeme pou₧φvat k detekci viditelnosti
  706.           TBspLeaf *p_bsp_leaf = &(m_ptBspLeaf[i]);
  707.  
  708.           //
  709.           //PVS
  710.           //
  711.           // If the current leaf can't be seen from our cluster, go to the next leaf
  712.           // Jestli₧e aktußlnφ klastr listu neni viditeln² z klastru, ve kterΘm je kamera, tak
  713.           if(!IsClusterVisible(i_camera_in_cluster, p_bsp_leaf->i_cluster))
  714.               continue;          // Se vra¥ na zaΦßtek cyklu na dalÜφ list
  715.  
  716.           //
  717.           //FRUSTRUM CULLING
  718.           //
  719.           // If the current leaf is not in the camera's frustum, go to the next leaf
  720.           // Jestli₧e aktußlnφ list nenφ v zornΘm ·hlu kamery, tak
  721.           if(!Camera.FrustrumBox(Get3D((float)p_bsp_leaf->pi_min_box[0], (float)p_bsp_leaf->pi_min_box[1], (float)p_bsp_leaf->pi_min_box[2]),
  722.                                  Get3D((float)p_bsp_leaf->pi_max_box[0], (float)p_bsp_leaf->pi_max_box[1], (float)p_bsp_leaf->pi_max_box[2])))
  723.                continue;          // Se vra¥ na zaΦßtek cyklu na dalÜφ list
  724.  
  725.           // If we get here, the leaf we are testing must be visible in our camera's view.
  726.           // Get the number of faces that this leaf is in charge of.
  727.           // Zφskej poΦet ploÜek v listu
  728.           int i_num_of_leaf_faces = p_bsp_leaf->i_num_of_leaf_faces;
  729.  
  730.           // Loop through and render all of the faces in this leaf
  731.           // Projdi vÜechny ploÜky listu
  732.           while(i_num_of_leaf_faces--)
  733.           {
  734.                // Grab the current face index from our leaf faces array
  735.                // Zφskej index ploÜky
  736.                int i_face_index = m_piLeafFaces[p_bsp_leaf->i_leaf_face + i_num_of_leaf_faces];
  737.  
  738.                            
  739.                // Since many faces are duplicated in other leafs, we need to
  740.                // make sure this face already hasn't been drawn.
  741.                // Jestli₧e ploÜka, kterß mß b²t vykreslena, nebyla ji₧ vykreslena, tak
  742.                if(!m_BitsetFacesDrawn.On(i_face_index))
  743.                {
  744.                     // Increase the rendered face count to display for fun
  745.                     // P°idej 1 k poΦtu viditeln²ch ploÜek
  746.                     m_iVisibleFaces++;
  747.  
  748.                     // Set this face as drawn and render it
  749.                     // Nastav, ploÜku jako vykreslenou
  750.                     m_BitsetFacesDrawn.Set(i_face_index);
  751.  
  752.                     // Vykresli ploÜku podle hodnoty indexu 
  753.                     RenderFace(i_face_index);
  754.                }
  755.           }
  756.      }
  757.  
  758. }
  759.  
  760.  
  761. //------------------------------------------------------------------
  762. // Name: FillVertexBuffer
  763. // Desc: vytvori a nalpni vertex buffer
  764. //------------------------------------------------------------------
  765. void QBSP::FillVertexBuffer()
  766. {
  767.  
  768.     LogPrint("  Vytvaram Vertex Buffer");
  769.  
  770.     //vytvaranie vertex buffera
  771.     if (FAILED(g_pd3dDevice->CreateVertexBuffer(m_iNumOfVerts*sizeof(CUSTOMVERTEXQBSP),
  772.                                    D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEXQBSP,
  773.                                    D3DPOOL_DEFAULT, &g_pVB, NULL )))
  774.       {
  775.         LogPrint("     chyba");
  776.     }
  777.     else
  778.     {
  779.         LogPrint("    OK");
  780.     }
  781.  
  782.  
  783.     //naplnanie VB
  784.  
  785.     //Vertex do ktoreho sa uklada
  786.     CUSTOMVERTEXQBSP *Vertex;
  787.  
  788.     //Otvor VB
  789.     LogPrint("    Otvaram Vertex Buffer");
  790.     g_pVB->Lock(0, 0, (void**)&Vertex, 0 ) ;
  791.  
  792.     //zobrazi model do pola vertexov
  793.     for (int i = 0;i<m_iNumOfVerts;i++)
  794.     {
  795.         
  796.             Vertex[i].pos.x = m_ptBspVertex[i].pf_position[0];
  797.             Vertex[i].pos.y = m_ptBspVertex[i].pf_position[1];
  798.             Vertex[i].pos.z = m_ptBspVertex[i].pf_position[2];
  799.  
  800.             Vertex[i].tu = m_ptBspVertex[i].pf_texture_coord[0];
  801.             Vertex[i].tv = m_ptBspVertex[i].pf_texture_coord[1];
  802.  
  803.             Vertex[i].tu2 = m_ptBspVertex[i].pf_lightmap_coord[0];
  804.             Vertex[i].tv2 = m_ptBspVertex[i].pf_lightmap_coord[1];
  805.         
  806.             Vertex[i].color = D3DXCOLOR(255,255,255,255);
  807.                 
  808.     
  809.     }
  810.  
  811.     //zatvorVB
  812.     LogPrint("    Zatvaram Vertex Buffer");
  813.     g_pVB->Unlock();
  814.  
  815. }
  816.  
  817. //------------------------------------------------------------------
  818. // Name: FindLeaf()
  819. // Desc: Vrßti ID listu v ktorom sa nachßdza kamera
  820. //------------------------------------------------------------------
  821. int QBSP::FindLeaf(VECTOR3D CamPos)
  822. {
  823.     
  824.      int i = 0;                   // Nßvratovß hodnota indexu listu
  825.      float f_distance = 0.0f;     // Vzdßlenost od plochy, kdy dochßzφ k detekci
  826.  
  827.      // Continue looping until we find a negative index
  828.      // Cykluj, dokud nebude nßvratovß hodnota indexu listu zßpornß
  829.      while(i >= 0)
  830.      {
  831.           // Get the current node, then find the slitter plane from that
  832.           // node's plane index.  Notice that we use a constant reference
  833.           // to store the plane and node so we get some optimization.
  834.           // Zφskej aktußlnφ uzek a d∞licφ plochu s indexem tohoto uzlu.
  835.           const TBspNode&  node = m_ptBspNode[i];                  // Zφskej uzel
  836.           const TBspPlane& plane = m_ptBspPlane[node.i_plane];     // Zφskej d∞licφ plochu tohoto uzlu
  837.  
  838.           // Use the Plane Equation (Ax + By + Cz + D = 0) to find if the
  839.           // camera is in front of or behind the current splitter plane.
  840.           // Pou₧ij obecnou rovnici roviny (Ax + By + Cz + D = 0) pro v²poΦet,
  841.           // zda je kamera p°ed, nebo za d∞licφ plochou.
  842.           f_distance = plane.pf_normal[0] * CamPos.X +
  843.                        plane.pf_normal[1] * CamPos.Y +
  844.                        plane.pf_normal[2] * CamPos.Z - plane.f_distance;
  845.  
  846.           // If the camera is in front of the plane
  847.           // Pokud je v²sledek rovnice v∞tÜφ nebo rovno 0, 
  848.           // tak je kamera p°ed d∞licφ rovinou, je tedy v p°ednφm listu 
  849.           if(f_distance >= 0)
  850.           {
  851.                // Assign the current node to the node in front of itself
  852.                // Ulo₧ p°ednφ hodnotu uzlu do indexu listu
  853.                i = node.i_front;
  854.         }
  855.         // Else if the camera is behind the plane
  856.         // Pokud je v²sledek rovnice menÜφ ne₧ 0,
  857.         // tak je kamera za d∞licφ rovinou, je tedy v zadnφm listu
  858.         else
  859.           {
  860.             // Assign the current node to the node behind itself
  861.             // Ulo₧ zadnφ hodnotu uzlu do indexu listu
  862.             i = node.i_back;
  863.         }
  864.      }
  865.  
  866.      
  867.     return ~i;  //vrßti i 
  868.  
  869. }
  870.  
  871. //------------------------------------------------------------------
  872. // Name: IsClusterVisible()
  873. // Desc: Zisti ci je Cluster viditelny z daneho clustra
  874. //------------------------------------------------------------------
  875. int QBSP::IsClusterVisible(int i_camera_in_cluster, int i_test_cluster)
  876. {
  877.     
  878.      // Make sure we have valid memory and that the current cluster is > 0.
  879.      // If we don't have any memory or a negative cluster, return a visibility (1).
  880.      // Ujisti se jestli jsou klastrovß data v pam∞¥i a ₧e klastr ve kterΘm je kamera je > 0
  881.      // Jestli₧e neexistujφ klastrovß data, nebo klastr ve kterΘm je kamera je < 0,
  882.      // tak vra¥ funkci 1. Tφm tento klastr oznaΦφme jako viditeln².
  883.      // Pokud by se oznaΦil jako neviditeln², mohlo by se stßt, ₧e by
  884.      // ve scΘn∞ mohly vzniknout dφry.
  885.      if(!m_tBspVisData.pby_cluster_bitsets || i_camera_in_cluster < 0) return 1;
  886.  
  887.      // Use binary math to get the 8 bit visibility set for the current cluster
  888.      // Pou₧ij binßrnφ operaci pro zφskßnφ 8 bitovΘ informace o viditelnosti klastru ve kterΘm je kamera
  889.      // Bitovß operace (test >> 3) posune bity v "test" o 3 pozice doprava,
  890.      // Φφm₧ provede to samΘ (avÜak rychleji), jako (test / 8)
  891.      byte by_vis_set = m_tBspVisData.pby_cluster_bitsets[(i_camera_in_cluster * m_tBspVisData.i_bytes_per_cluster) + (i_test_cluster >> 3)];
  892.  
  893.      // Now that we have our vector (bitset), do some bit shifting to find if
  894.      // the "test" cluster is visible from the "current" cluster, according to the bitset.
  895.      // Porovnej pomocφ bitovΘho souΦinu "&" bitovΘ hodnoty klastru ve kterΘm je kamera a testovanΘho klastru.
  896.      // Bitov² souΦin "&" nßm vracφ 1, pokud jsou ob∞ hodnoty stejnΘ, a 0 pokud jsou rozdφlnΘ
  897.      // Bitov² posun doleva "1 <<" vynßsobφ jedniΦkou v²slednou hodnotu bitovΘho souΦinu ((test) & 7))
  898.      // Pokud bude hodnota nap°. 1, vynßsobφ se (1 * 2), pokud bude hodnota nap°. 4, vynßsobφ (1 * 16) atd..
  899.      int result = by_vis_set & (1 << ((i_test_cluster) & 7));
  900.  
  901.      // Return the result ( either 1 (visible) or 0 (not visible) )
  902.      // Vra¥ funkci v²sledek bitov²ch operacφ (v²sledek 1 = viditeln² klastr, v²sledek 0 = neviditeln² klastr)
  903.      return ( result );
  904.  
  905.  
  906. }
  907.  
  908. //------------------------------------------------------------------
  909. // Name: CheckBrushCollision()
  910. // Desc: Zisti koliziu s listom
  911. //------------------------------------------------------------------
  912. bool QBSP::CheckBrushCollision(int i_leaf_index)
  913. {
  914.    
  915.  
  916.      TBspLeaf *pt_bsp_leaf = &(m_ptBspLeaf[i_leaf_index]);            // Zφskej hodnoty aktußlnφho listu
  917.      int i_num_leaf_brushes = pt_bsp_leaf->i_num_of_leaf_brushes;     // Zφskej poΦet kolizφ
  918.  
  919.      // Jestli₧e list obsahuje kolize
  920.      if(i_num_leaf_brushes)
  921.      {
  922.           return true;
  923.      }
  924.      else     // Pokud nedochßzφ k detekci kolize
  925.      {
  926.           return false;
  927.      }
  928.  
  929. }
  930.  
  931. //------------------------------------------------------------------
  932. // Name: ColliseBSP()
  933. // Desc: Zisti koliziu
  934. //------------------------------------------------------------------
  935. bool QBSP::ColliseBSP(VECTOR3D Point)
  936. {
  937.  
  938.     int i_ray_leaf_index = FindLeaf(Point);
  939.  
  940.     if(CheckBrushCollision(i_ray_leaf_index))
  941.     {
  942.         return true;
  943.     }
  944.     else
  945.     {
  946.         return false;
  947.     }
  948.         
  949.  
  950. }