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

  1.  
  2. #include "main.h"
  3.  
  4.  
  5.  
  6. //------------------------------------------------------------------
  7. // Name: OCTREE()
  8. // Desc: konstruktor
  9. //------------------------------------------------------------------
  10. OCTREE::OCTREE()
  11. {
  12.     g_pVB = NULL;
  13.     Group = NULL;
  14.     Face = NULL;
  15.     Node = NULL;
  16.     FileScn = NULL;
  17.     FileGeo = NULL;
  18.     FileOct = NULL;
  19. }
  20.  
  21. //------------------------------------------------------------------
  22. // Name: CleanUp()
  23. // Desc: Odstrani
  24. //------------------------------------------------------------------
  25. void OCTREE::CleanUp()
  26. {
  27.     
  28.     //
  29.     //vertex buffer
  30.     //
  31.     if (g_pVB != NULL)
  32.         g_pVB->Release();
  33.     g_pVB = NULL;
  34.  
  35.     //
  36.     //skupina
  37.     //
  38.     if (Group != NULL)
  39.     {
  40.         //znic textury
  41.         for (int i=0;i<NumGroups;i++)
  42.         {
  43.             ClearGroupTextures(i);
  44.         }
  45.  
  46.         delete [] Group;
  47.     }
  48.     Group = NULL;
  49.  
  50.     //
  51.     //face
  52.     //
  53.     if (Face != NULL)
  54.         delete [] Face;
  55.     Face = NULL;
  56.  
  57.     //
  58.     //Octree
  59.     //
  60.     if (Node != NULL)
  61.         delete [] Node;
  62.  
  63.     //
  64.     //kolizia
  65.     //
  66.     IntPos = Get3D(0,0,0);
  67.     IntNormal = Get3D(0,0,0);
  68.     ColliseStatus = false;
  69.  
  70. }
  71.  
  72. //------------------------------------------------------------------
  73. // Name: InitializeGroup()
  74. // Desc: inicializuje textury group
  75. //------------------------------------------------------------------
  76. void OCTREE::InitializeGroupTextures(int Index)
  77. {
  78.  
  79.     int NumTextures = Group[Index].NumTextures;
  80.  
  81.     Group[Index].g_pTexture = new LPDIRECT3DTEXTURE9[NumTextures];
  82.     
  83.     for (int i=0;i<NumTextures;i++)
  84.     {
  85.         Group[Index].g_pTexture[i] = NULL;
  86.     }
  87. }
  88.  
  89.  
  90. //------------------------------------------------------------------
  91. // Name: ClearGroup()
  92. // Desc: Odtrani z pamati textury group
  93. //------------------------------------------------------------------
  94. void OCTREE::ClearGroupTextures(int Index)
  95. {
  96.     
  97.     if(Group[Index].g_pTexture != NULL)
  98.     {
  99.         for (int i=0;i<Group[Index].NumTextures;i++)
  100.         {
  101.             if (Group[Index].g_pTexture[i] != NULL)
  102.                 Group[Index].g_pTexture[i]->Release();
  103.             Group[Index].g_pTexture[i] = NULL;
  104.         }
  105.     }
  106.     
  107.     delete [] Group[Index].g_pTexture;
  108.     Group[Index].g_pTexture = NULL;
  109.  
  110. }
  111.  
  112. //------------------------------------------------------------------
  113. // Name: Load()
  114. // Desc: nahra scenu zo suboru GEO
  115. //------------------------------------------------------------------
  116. void OCTREE::Load(char *FileName)
  117. {
  118.  
  119.     char cBuf[80];
  120.     int i;
  121.  
  122.  
  123.     //Log
  124.     LogPrint("Vytvaram OCTree");
  125.     sprintf(cBuf," Subor: %s",FileName);
  126.     LogPrint(cBuf);
  127.     
  128.  
  129.     ///////////////
  130.     //otvor subor//
  131.     ///////////////
  132.     FileGeo = fopen(FileName,"r");
  133.  
  134.     if (FileGeo == NULL)
  135.         LogPrint(" Subor sa nepodarilo otvrit");
  136.  
  137.  
  138.     ///////////////
  139.     //hlavicka   //
  140.     ///////////////
  141.     fscanf(FileGeo,"%s %d",cBuf,&MinNodeSize);
  142.     fscanf(FileGeo,"%s %d",cBuf,&NumGroups);
  143.     fscanf(FileGeo,"%s %d",cBuf,&NumFaces);
  144.  
  145.     sprintf(cBuf," MinPolygonsInNode: %d",MinNodeSize);
  146.     LogPrint(cBuf);
  147.     sprintf(cBuf," NumGroups: %d",NumGroups);
  148.     LogPrint(cBuf);
  149.     sprintf(cBuf," NumFaces: %d",NumFaces);
  150.     LogPrint(cBuf);
  151.     
  152.  
  153.     ///////////////
  154.     //group      //
  155.     ///////////////
  156.     Group = new OCTGROUP[NumGroups];
  157.     for (i=0;i<NumGroups;i++)
  158.     {
  159.         ReadGroup();
  160.     }
  161.  
  162.     ///////////////
  163.     //faces      //
  164.     ///////////////
  165.     Face = new OCTFACE[NumFaces];
  166.     for (i=0;i<NumFaces;i++)
  167.     {
  168.         ReadFace();
  169.     }
  170.  
  171.     /////////////////
  172.     //Vertex Buffer//
  173.     /////////////////
  174.     CreateVertexBuffer();
  175.  
  176.  
  177.     /////////////////
  178.     //SmoothShading//
  179.     /////////////////
  180.     for (i=0;i<NumGroups;i++)
  181.     {
  182.         if (Group[i].SmoothShading == 1)
  183.         {
  184.             CalcSmoothShading(i);
  185.         }
  186.     }
  187.  
  188.     ///////////
  189.     //OCTree //
  190.     ///////////
  191.     //CreateOctTree();
  192.     //SaveOctTree("scene/terrain.oct");
  193.     //LoadOctTree("scene/terrain.oct");
  194.  
  195.     ////////////////
  196.     //zatvor subor//
  197.     ////////////////
  198.     fclose(FileGeo);
  199.  
  200. }
  201.  
  202.  
  203. //------------------------------------------------------------------
  204. // Name: ReadGroup()
  205. // Desc: Precita a nahraje group
  206. //------------------------------------------------------------------
  207. void OCTREE::ReadGroup()
  208. {
  209.  
  210.     char cBuf[80];
  211.     char TexFileName[80];
  212.     int Index;
  213.     int TexIndex;
  214.  
  215.     fscanf(FileGeo,"%s",cBuf);
  216.     
  217.     fscanf(FileGeo,"%s %d",cBuf,&Index);
  218.     fscanf(FileGeo,"%s %d",cBuf,&Group[Index].NumTextures);
  219.     fscanf(FileGeo,"%s %f",cBuf,&Group[Index].TextureTime);
  220.  
  221.     //log
  222.     sprintf(cBuf," Material %d",Index);
  223.     LogPrint(cBuf);
  224.  
  225.     //default vlastnosti
  226.     Group[Index].ActTexture = 0;
  227.     Group[Index].ActTime = 0.0f;
  228.  
  229.     //inicializacia pola textur
  230.     InitializeGroupTextures(Index);
  231.  
  232.     ///////////////////
  233.     //Nahraje textury//
  234.     ///////////////////
  235.     for (int i=0;i<Group[Index].NumTextures;i++)
  236.     {
  237.         
  238.         fscanf(FileGeo,"%s %d %s",cBuf,&TexIndex,TexFileName);
  239.  
  240.         sprintf(cBuf,"  Textura %s",TexFileName);
  241.         LogPrint(cBuf);
  242.     
  243.         //load hlavnej terrain textury
  244.         if (Index == 0 && (i == 0 || i == 2))
  245.         {
  246.             if (SceneDetail == 0 && i==0) 
  247.                 strcpy(TexFileName,"scene/texturepole512.jpg");
  248.             if (SceneDetail == 0 && i==2) 
  249.                 strcpy(TexFileName,"scene/texturepust512.jpg");
  250.             if (SceneDetail == 1 && i==0) 
  251.                 strcpy(TexFileName,"scene/texturepole1024.jpg");
  252.             if (SceneDetail == 1 && i==2) 
  253.                 strcpy(TexFileName,"scene/texturepust1024.jpg");
  254.                         
  255.             if (FAILED(D3DXCreateTextureFromFileEx(g_pd3dDevice, 
  256.                                       TexFileName,    
  257.                                       0, 
  258.                                       0, 
  259.                                       0,              //MipLevels
  260.                                       0,            
  261.                                       D3DFMT_R5G6B5, 
  262.                                       Engine.TextureCreatingFlag,
  263.                                       D3DX_DEFAULT, //Filter
  264.                                       D3DX_DEFAULT, //MipFilter
  265.                                       0,    //Disable ColorKey
  266.                                       NULL,         
  267.                                       NULL,         
  268.                                       &Group[Index].g_pTexture[i])))  
  269.             {
  270.                 sprintf(cBuf,"  chyba pri vytvarani textury: %s",TexFileName);
  271.                 LogPrint(cBuf);
  272.             }
  273.  
  274.         }
  275.  
  276.         //load ostatnych textur
  277.         else
  278.         {
  279.             if (FAILED(D3DXCreateTextureFromFileEx(g_pd3dDevice, 
  280.                                       TexFileName,    
  281.                                       D3DX_DEFAULT, 
  282.                                       D3DX_DEFAULT, 
  283.                                       Engine.MipMapLevels,   //MipLevels
  284.                                       0,            
  285.                                       Engine.TextureFormat, 
  286.                                       Engine.TextureCreatingFlag,
  287.                                       D3DX_DEFAULT, //Filter
  288.                                       D3DX_DEFAULT, //MipFilter
  289.                                       0xffff00ff,    //ColorKey
  290.                                       NULL,         
  291.                                       NULL,         
  292.                                       &Group[Index].g_pTexture[i])))  
  293.             {
  294.                 sprintf(cBuf,"  chyba pri vytvarani textury: %s",TexFileName);
  295.                 LogPrint(cBuf);
  296.             }
  297.         }
  298.     
  299.  
  300.     }
  301.  
  302.     //nacitaj dalsie vlastnosti
  303.     fscanf(FileGeo,"%s %d",cBuf,&Group[Index].BlendType );
  304.     fscanf(FileGeo,"%s %d",cBuf,&Group[Index].GroupType );
  305.     fscanf(FileGeo,"%s %d",cBuf,&Group[Index].MaterialType  );
  306.     fscanf(FileGeo,"%s %d",cBuf,&Group[Index].CollisionType );
  307.     fscanf(FileGeo,"%s %d",cBuf,&Group[Index].Specular );
  308.     fscanf(FileGeo,"%s %d",cBuf,&Group[Index].SmoothShading );
  309.  
  310. }
  311.  
  312.  
  313.  
  314. //------------------------------------------------------------------
  315. // Name: ReadFace()
  316. // Desc: Precita a nahraje face
  317. //------------------------------------------------------------------
  318. void OCTREE::ReadFace()
  319. {
  320.     char cBuf[80];
  321.     int Index;
  322.     int GroupIndex;
  323.     float X,Y,Z,U,V;
  324.  
  325.     fscanf(FileGeo,"%s",cBuf);
  326.  
  327.     //nacitaj hlavicku
  328.     fscanf(FileGeo,"%s %d",cBuf,&Index);
  329.     fscanf(FileGeo,"%s %d",cBuf,&GroupIndex);
  330.  
  331.     //nacitaj body
  332.     for(int i=2;i>-1;i--)
  333.     {
  334.         fscanf(FileGeo,"%f %f %f %f %f",&X,&Y,&Z,&U,&V);
  335.         
  336.         Face[Index].P[i] = Get3D(X,Y,Z);
  337.         Face[Index].T1[i].X = U;
  338.         Face[Index].T1[i].Y = V;
  339.  
  340.     }
  341.  
  342.     //plane
  343.     Face[Index].Plane = CreatePlaneFace(Face[Index].P[0],
  344.                                         Face[Index].P[1],
  345.                                         Face[Index].P[2]);
  346.  
  347.     //normaly
  348.     Face[Index].N[0] = Face[Index].Plane.Normal ;
  349.     Face[Index].N[1] = Face[Index].Plane.Normal ;
  350.     Face[Index].N[2] = Face[Index].Plane.Normal ;
  351.  
  352.     //texcoord2
  353.     Face[Index].T2[0].X = Face[Index].P[0].X / 500.0f;
  354.     Face[Index].T2[0].Y = Face[Index].P[0].Z / 500.0f;
  355.  
  356.     Face[Index].T2[1].X = Face[Index].P[1].X / 500.0f;
  357.     Face[Index].T2[1].Y = Face[Index].P[1].Z / 500.0f;
  358.  
  359.     Face[Index].T2[2].X = Face[Index].P[2].X / 500.0f;
  360.     Face[Index].T2[2].Y = Face[Index].P[2].Z / 500.0f;
  361.  
  362.     //vlastnosti
  363.     Face[Index].Group = GroupIndex;
  364.     Face[Index].Index = Index;
  365.     
  366.  
  367. }
  368.  
  369. //------------------------------------------------------------------
  370. // Name: CreateVertexBuffer()
  371. // Desc: Vytvori Vertex Buffer
  372. //------------------------------------------------------------------
  373. void OCTREE::CreateVertexBuffer()
  374. {
  375.  
  376.     if (FAILED(g_pd3dDevice->CreateVertexBuffer(NumFaces*3*sizeof(CUSTOMVERTEXOCT),
  377.                                    D3DUSAGE_WRITEONLY|D3DUSAGE_DYNAMIC, D3DFVF_CUSTOMVERTEXOCT,
  378.                                    D3DPOOL_DEFAULT, &g_pVB, NULL )))
  379.       {
  380.         LogPrint(" Chyba pri vytvarani VB");
  381.     }
  382.     else
  383.     {
  384.         LogPrint(" Vertex Buffer vytvoreny");
  385.     }
  386. }
  387.  
  388.  
  389. //------------------------------------------------------------------
  390. // Name: FillVertexBuffer()
  391. // Desc: Naplni VB a ulozi hodnoty do Group
  392. //------------------------------------------------------------------
  393. void OCTREE::FillVertexBuffer()
  394. {
  395.  
  396.     //pomocne premenne
  397.     int ActVertex = 0;
  398.     int NumF = 0;
  399.     int i,u,j;
  400.  
  401.     //reset pocitadla
  402.     NumVisibleFaces = 0;
  403.  
  404.     //Vertex do ktoreho sa uklada
  405.     CUSTOMVERTEXOCT *Vertex;
  406.  
  407.     //Otvor VB
  408.     g_pVB->Lock(0, 0, (void**)&Vertex, D3DLOCK_DISCARD|D3DLOCK_NOOVERWRITE) ;
  409.  
  410.     /////////
  411.     //GROUP//
  412.     /////////
  413.     for (i=0;i<NumGroups;i++)
  414.     {
  415.         //nastavi pociatocnu hodnotu
  416.         Group[i].StartVertex = ActVertex;
  417.         NumF = 0;
  418.         
  419.         for (u=0;u<NumFaces;u++)
  420.         {
  421.             if (Face[u].Visible == true)
  422.             {
  423.                 if (Face[u].Group == i)
  424.                 {
  425.                     //pocitadlo
  426.                     NumVisibleFaces++;
  427.                                 
  428.                     for (j=0;j<3;j++)
  429.                     {
  430.                         //prida vertex do VB
  431.                         Vertex[ActVertex].normal = D3DXVECTOR3(Face[u].N[j].X,
  432.                                                                Face[u].N[j].Y,
  433.                                                                Face[u].N[j].Z);
  434.     
  435.                         Vertex[ActVertex].pos  = D3DXVECTOR3(Face[u].P[j].X,
  436.                                                              Face[u].P[j].Y,
  437.                                                              Face[u].P[j].Z);
  438.  
  439.                         Vertex[ActVertex].tu1 = Face[u].T1[j].X;
  440.                         Vertex[ActVertex].tv1 = Face[u].T1[j].Y;
  441.  
  442.                         Vertex[ActVertex].tu2 = Face[u].T2[j].X;
  443.                         Vertex[ActVertex].tv2 = Face[u].T2[j].Y;
  444.  
  445. //
  446. //                        DebugDrawLine(Face[u].P[j],Get3D(Face[u].P[j].X+(2.0f*Face[u].N[j].X),
  447. //                                                         Face[u].P[j].Y+(2.0f*Face[u].N[j].Y),
  448. //                                                         Face[u].P[j].Z+(2.0f*Face[u].N[j].Z)));
  449.  
  450.                         ActVertex++;
  451.                     }
  452.  
  453.                     NumF++;
  454.                 }
  455.                     
  456.             }
  457.  
  458.         }
  459.  
  460.         Group[i].NumVisibleFaces = NumF;
  461.     
  462.         
  463.     }
  464.  
  465.  
  466.  
  467.     //zatvor VB
  468.     g_pVB->Unlock();
  469.  
  470. }
  471.  
  472. //------------------------------------------------------------------
  473. // Name: Render()
  474. // Desc: Vyrenderuje celu scenu
  475. //------------------------------------------------------------------
  476. void OCTREE::Render()
  477. {
  478.     int i;
  479.  
  480.     ///////////////
  481.     //Optimalize //
  482.     ///////////////
  483.     Optimalize();
  484.  
  485.     //vynuluje world maticu
  486.     D3DXMATRIXA16 NullMatrix;        
  487.     D3DXMatrixIdentity(&NullMatrix);
  488.     g_pd3dDevice->SetTransform( D3DTS_WORLD, &NullMatrix);
  489.  
  490.     //naplni Vertex Buffer
  491.     FillVertexBuffer();
  492.  
  493.     //oznaci Vertex Buffer
  494.     g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEXOCT));
  495.     g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEXOCT);
  496.  
  497.     ///////////////
  498.     //Render     //
  499.     ///////////////
  500.     //priesvitne materialy nakoniec
  501.  
  502.     //0
  503.     for (i = 0;i<NumGroups;i++)
  504.     {
  505.         Engine.SetLighting(false);
  506.     
  507.         if (Group[i].GroupType == 2 && SceneDetail == 2)
  508.             Engine.SetMipMapping(0,false);
  509.  
  510.         if (Group[i].BlendType == 0)
  511.             RenderGroup(i);
  512.  
  513.         Engine.SetMipMapping(0,true);
  514.     }
  515.  
  516.     //1
  517.     for (i = 0;i<NumGroups;i++)
  518.     {
  519.         Engine.SetAlphaTest(true);
  520.         Engine.SetLighting(false);
  521.         Engine.SetFilter(0,D3DTEXF_POINT);
  522.  
  523.         if (Group[i].BlendType == 1)
  524.             RenderGroup(i);
  525.  
  526.         Engine.SetFilter(0,D3DTEXF_LINEAR);
  527.     }
  528.  
  529.     //2
  530.     for (i = 0;i<NumGroups;i++)
  531.     {
  532.         if (Group[i].BlendType == 2)
  533.             RenderGroup(i);
  534.     }
  535.  
  536.     //zresetuj blending
  537.     Engine.SetBlendNone();
  538.  
  539.     //debug
  540.     //RenderDebugNode(Node);
  541.  
  542.     //reset to default
  543.     Engine.ResetToDefault();
  544. }
  545.  
  546. //------------------------------------------------------------------
  547. // Name: RenderGroup()
  548. // Desc: Vyrenderuje skupinu
  549. //------------------------------------------------------------------
  550. void OCTREE::RenderGroup(int Index)
  551. {
  552.  
  553.     //nastavi material
  554.     SetMaterial(Group[Index].MaterialType );
  555.  
  556.     //nastavi blending
  557.     SetBlendMode(Group[Index].BlendType);
  558.  
  559.     //zapni specular ak je povoleny
  560.     if (Group[Index].Specular == 0)
  561.         Engine.SetSpecular(false);
  562.     else
  563.         Engine.SetSpecular(true);
  564.  
  565.     //ak je iba pre krajinu pole nerenderuj
  566.     if (Group[Index].CollisionType == 1 && Mode == 1)
  567.         return;
  568.  
  569.     //
  570.     //NORMAL TEXTURA
  571.     //
  572.     if(Group[Index].GroupType == 0)
  573.     {
  574.         g_pd3dDevice->SetTexture( 0, Group[Index].g_pTexture[0]);
  575.  
  576.     }
  577.  
  578.     //
  579.     //ANIMOVANA TEXTURA
  580.     //
  581.     if(Group[Index].GroupType == 1)
  582.     {
  583.         //vyber textury
  584.         Group[Index].ActTime += PowerTime(1.0f);
  585.         if (Group[Index].ActTime > Group[Index].TextureTime)
  586.         {
  587.             Group[Index].ActTexture++;
  588.             Group[Index].ActTime = 0.0f;    
  589.             if (Group[Index].ActTexture == Group[Index].NumTextures)
  590.                 Group[Index].ActTexture = 0;
  591.         }
  592.         int ActTexture = Group[Index].ActTexture;
  593.         g_pd3dDevice->SetTexture( 0, Group[Index].g_pTexture[ActTexture]);
  594.     }
  595.     //
  596.     //MULTITEXTURING
  597.     //
  598.     if(Group[Index].GroupType == 2)
  599.     {
  600.  
  601.         //vyber indexu textury
  602.         int T1,T2;
  603.         if (Mode == 0) { T1 = 0; T2 = 1; }
  604.         if (Mode == 1) { T1 = 2; T2 = 3; }
  605.  
  606.         //1 stage
  607.         g_pd3dDevice->SetTexture( 0, Group[Index].g_pTexture[T1]);
  608.         g_pd3dDevice->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX,0);
  609.     
  610.         g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
  611.         g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  612.         g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
  613.     
  614.         //2 stage
  615.         g_pd3dDevice->SetTexture( 1, Group[Index].g_pTexture[T2]);
  616.         g_pd3dDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX,1);
  617.         g_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADDSIGNED);
  618.         g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
  619.         g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_CURRENT);
  620.         
  621.     }
  622.     //
  623.     //ENVIROMENT MAPPING
  624.     //
  625.     if(Group[Index].GroupType == 3)
  626.     {
  627.  
  628.         g_pd3dDevice->SetTexture( 0, Group[Index].g_pTexture[0]);
  629.  
  630.         for (int i=0;i<NumFaces;i++)
  631.         {
  632.             if (Face[i].Group != Index)
  633.                 continue;
  634.     
  635.             for (int u=0;u<3;u++)
  636.             {
  637.  
  638.                 Face[i].T1[u] = EnvironmentMapping(Face[i].P[u],
  639.                                                    Face[i].N[u],300.0f,matView);
  640.             }
  641.         }
  642.  
  643.  
  644.     }
  645.  
  646.     //
  647.     //EMBOSS BUMB MAPPING
  648.     //
  649.     if(Group[Index].GroupType == 4)
  650.     {
  651.  
  652.         g_pd3dDevice->SetTexture( 0, Group[Index].g_pTexture[0] );
  653.         g_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );
  654.         g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
  655.         g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  656.         g_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
  657.  
  658.         g_pd3dDevice->SetTexture( 1, Group[Index].g_pTexture[0] );
  659.         g_pd3dDevice->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1 );
  660.         g_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );
  661.         g_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
  662.         g_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLORARG2, D3DTA_CURRENT );
  663.  
  664.         g_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_ADDSIGNED );
  665.         g_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE | D3DTA_COMPLEMENT );
  666.         g_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAARG2, D3DTA_CURRENT );
  667.  
  668.         Engine.SetBlendCustom(D3DBLEND_SRCALPHA,D3DBLEND_ZERO);
  669.  
  670.         for (int i=0;i<NumFaces;i++)
  671.         {
  672.             if (Face[i].Group != Index)
  673.                 continue;
  674.     
  675.             for (int u=0;u<3;u++)
  676.             {
  677.                 Face[i].T2[u] = BumpMapping(Face[i].N[u],Face[i].T1[u],0.030f,matView);
  678.             }
  679.         }
  680.  
  681.  
  682.     }
  683.  
  684.     //render
  685.     if (Group[Index].NumVisibleFaces > 0)
  686.         g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, Group[Index].StartVertex , Group[Index].NumVisibleFaces );
  687.  
  688.     //reset
  689.     Engine.ResetToDefault();
  690. }
  691.  
  692. //------------------------------------------------------------------
  693. // Name: SetMaterial()
  694. // Desc: Nastavi material podla typu
  695. //------------------------------------------------------------------
  696. void OCTREE::SetMaterial(int MaterialType)
  697. {
  698.  
  699.     D3DMATERIAL9 Material;
  700.     ZeroMemory( &Material, sizeof(D3DMATERIAL9) );
  701.  
  702.     switch (MaterialType)
  703.     { 
  704.         case 0: 
  705.             Material = GetMaterial(GetColor(0.2f,0.2f,0.2f,0.2f),
  706.                                    GetColor(1.0f,1.0f,1.0f,1.0f),
  707.                                    GetColor(0.0f,0.0f,0.0f,0.0f),
  708.                                    GetColor(0.0f,0.0f,0.0f,0.0f),0.0f);
  709.  
  710.  
  711.             break;
  712.         case 1: 
  713.             Material = GetMaterial(GetColor(0.3f,0.3f,0.3f,0.3f),
  714.                                    GetColor(1.0f,1.0f,0.0f,0.0f),
  715.                                    GetColor(1.0f,1.0f,1.0f,1.0f),
  716.                                    GetColor(0.2f,0.2f,0.2f,0.2f),5.0f);
  717.  
  718.             break;
  719.         case 2:
  720.  
  721.             break;
  722.     }
  723.         
  724.  
  725.  
  726.     //nastavi material
  727.     g_pd3dDevice->SetMaterial(&Material);
  728.  
  729. }
  730.  
  731. //------------------------------------------------------------------
  732. // Name: SetBlendMode()
  733. // Desc: nastavi priesvitnos¥ podla typu
  734. //------------------------------------------------------------------
  735. void OCTREE::SetBlendMode(int BlendType)
  736. {
  737.     switch (BlendType)
  738.     { 
  739.         case 0: //bez priesvitnosti
  740.             Engine.SetBlendNone();
  741.             break;
  742.         case 1: //transparent
  743.             Engine.SetBlendTrans();
  744.             break;
  745.         case 2: //one
  746.             Engine.SetBlendOne();
  747.             break;
  748.     }
  749. }
  750.  
  751. //------------------------------------------------------------------
  752. // Name: CalcSmoothShading()
  753. // Desc: Vypocita smooth shading pre urcitu skupinu
  754. //------------------------------------------------------------------
  755. void OCTREE::CalcSmoothShading(int Index)
  756. {
  757.     VECTOR3D *Normal = NULL;
  758.     Normal = new VECTOR3D[NumFaces];
  759.     
  760.     for (int i=0;i<NumFaces;i=i+1)
  761.     {
  762.     if (Face[i].Group == Index)
  763.     {
  764.     for (int u=0;u<3;u=u+1)
  765.     {
  766.  
  767.         //bod
  768.         VECTOR3D B = Face[i].P[u];
  769.         
  770.         VECTOR3D NormalVys = Get3D(0.0f,0.0f,0.0f);
  771.         int ActNormal = 0;
  772.  
  773.         //ziskaj normaly
  774.         for (int j=0;j<NumFaces;j=j+1)
  775.         {
  776.         if (Face[i].Group == Index)
  777.         {
  778.         for (int k=0;k<3;k=k+1)
  779.         {
  780.             
  781.  
  782.             if((B.X == Face[j].P[k].X)  &&
  783.                (B.Y == Face[j].P[k].Y)  &&
  784.                (B.Z == Face[j].P[k].Z) )
  785.             {
  786.         
  787.                 Normal[ActNormal] = Face[j].Plane.Normal ;
  788.                 ActNormal++;
  789.                             
  790.             }
  791.  
  792.         }
  793.         }
  794.         }
  795.  
  796.         //vypocitaj normalu
  797.         for (int a=0;a<ActNormal;a++)
  798.         {
  799.             Add(&NormalVys,NormalVys,Normal[a]);
  800.         }
  801.  
  802.         //normalizuj vyslednu normalu
  803.         Normalize(&NormalVys);
  804.  
  805.         //zapis nove normaly
  806.         for (j=0;j<NumFaces;j=j+1)
  807.         {
  808.         if (Face[i].Group == Index)
  809.         {
  810.         for (int k=0;k<3;k=k+1)
  811.         {
  812.  
  813.             if((B.X == Face[j].P[k].X)  &&
  814.                (B.Y == Face[j].P[k].Y)  &&
  815.                (B.Z == Face[j].P[k].Z) )
  816.             {
  817.                 Face[j].N[k] = NormalVys;
  818.             }
  819.  
  820.         }
  821.         }
  822.         }
  823.  
  824.  
  825.     }
  826.     }
  827.     }
  828.  
  829.     if (Normal != NULL)
  830.         delete [] Normal;
  831.     Normal = NULL;
  832. }
  833.  
  834. //------------------------------------------------------------------
  835. // Name: CreateOctTree()
  836. // Desc: vytvori Octree strom
  837. //------------------------------------------------------------------
  838. void OCTREE::CreateOctTree()
  839. {
  840.  
  841.     int i,u;
  842.  
  843.     //log
  844.     LogPrint(" Vytvaram strom");
  845.  
  846.     //vytvori NODE
  847.     Node = new OCTNODE;
  848.  
  849.     ///////////
  850.     //MIN MAX//
  851.     ///////////
  852.     VECTOR3D Min = Get3D(10000.0f,10000.0f,10000.0f);
  853.     VECTOR3D Max = Get3D(-10000.0f,-10000.0f,-10000.0f);
  854.     float a,b,c;
  855.  
  856.     for ( i=0;i<NumFaces;i++)
  857.     {
  858.         for ( u=0;u<3;u++)
  859.         {
  860.             if (Face[i].P[u].X < Min.X)
  861.                 Min.X = Face[i].P[u].X;
  862.             if (Face[i].P[u].Y < Min.Y)
  863.                 Min.Y = Face[i].P[u].Y;
  864.             if (Face[i].P[u].Z < Min.Z)
  865.                 Min.Z = Face[i].P[u].Z;
  866.  
  867.             if (Face[i].P[u].X > Max.X)
  868.                 Max.X = Face[i].P[u].X;
  869.             if (Face[i].P[u].Y > Max.Y)
  870.                 Max.Y = Face[i].P[u].Y;
  871.             if (Face[i].P[u].Z > Max.Z)
  872.                 Max.Z = Face[i].P[u].Z;
  873.         }
  874.     }
  875.  
  876.     
  877.     Node->Centre.X = (Min.X + Max.X) / 2.0f;
  878.     Node->Centre.Y = (Min.Y + Max.Y) / 2.0f;
  879.     Node->Centre.Z = (Min.Z + Max.Z) / 2.0f;
  880.  
  881.     //upravi na kocku
  882.     a = Max.X - Node->Centre.X ;
  883.     b = Max.Y - Node->Centre.Y ;
  884.     c = Max.Z - Node->Centre.Z ;
  885.  
  886.     if (a >= b && a >= c)
  887.     {
  888.         Add(&Node->Max,Node->Centre,Get3D(a,a,a));
  889.         Add(&Node->Min,Node->Centre,Get3D(-a,-a,-a));
  890.     }
  891.     if (b >= a && b >= c)
  892.     {
  893.         Add(&Node->Max,Node->Centre,Get3D(b,b,b));
  894.         Add(&Node->Min,Node->Centre,Get3D(-b,-b,-b));
  895.     }    
  896.     if (c >= b && c >= a)
  897.     {
  898.         Add(&Node->Max,Node->Centre,Get3D(c,c,c));
  899.         Add(&Node->Min,Node->Centre,Get3D(-c,-c,-c));
  900.     }
  901.  
  902.     Node->Polomer = CalcDistance(Node->Centre,Node->Min);
  903.  
  904.     //reset info
  905.     NumEndNodes = 0;
  906.  
  907.     //vytvori octree
  908.     CreateNode(Node);
  909.  
  910.  
  911.  
  912. }
  913.  
  914. //------------------------------------------------------------------
  915. // Name: CreateNode()
  916. // Desc: Funkcia sa vola rekrizivne - vytvara nody
  917. //------------------------------------------------------------------
  918. void OCTREE::CreateNode(OCTNODE *N)
  919. {
  920.  
  921.     int i;
  922.  
  923.     //vypocita stred
  924.     N->Centre.X = (N->Min.X + N->Max.X) / 2.0f;
  925.     N->Centre.Y = (N->Min.Y + N->Max.Y) / 2.0f;
  926.     N->Centre.Z = (N->Min.Z + N->Max.Z) / 2.0f;
  927.  
  928.     //vypocita polomer
  929.     N->Polomer = CalcDistance(N->Centre,N->Min);
  930.  
  931.     //zresetuje vlastnosti
  932.     N->NumFaces = 0;
  933.  
  934.     //zisti face ktore lezia v node
  935.     int *Index = NULL;
  936.     Index = new int[NumFaces];
  937.  
  938.     for (i=0;i<NumFaces;i++)
  939.     {
  940.         if (ColliseNodeFace(N,Face[i]) == true)
  941.         {
  942.             Index[N->NumFaces] = i;
  943.             N->NumFaces++;
  944.         }
  945.     }
  946.  
  947.     //skopiruje a vytvori pole
  948.     N->FaceList = new int [N->NumFaces];
  949.     for (i=0;i<N->NumFaces;i++)
  950.     {
  951.         N->FaceList[i] = Index[i];
  952.     }
  953.  
  954.     //vymaze pomocne pole
  955.     if (Index != NULL)
  956.         delete [] Index;
  957.  
  958.     //zisti ci ma pokracovat vo vytvarani dalsej nody
  959.     if(((N->Centre.X - N->Min.X) < MinNodeSize) || (N->NumFaces == 0  ))
  960.     {
  961.         N->EndNode = true;
  962.  
  963.         if (N->NumFaces>0)
  964.             NumEndNodes++;
  965.  
  966.         return ;
  967.     }
  968.  
  969.     //vymaze pole nody pretoze nieje konecna
  970.     if (N->FaceList != NULL)
  971.         delete [] N->FaceList;
  972.  
  973.     ///////////////////////
  974.     //vytvori dalsie nody//
  975.     ///////////////////////
  976.     N->EndNode = false;
  977.  
  978.     N->Node[0] = new OCTNODE;
  979.     N->Node[1] = new OCTNODE;
  980.     N->Node[2] = new OCTNODE;
  981.     N->Node[3] = new OCTNODE;
  982.     N->Node[4] = new OCTNODE;
  983.     N->Node[5] = new OCTNODE;
  984.     N->Node[6] = new OCTNODE;
  985.     N->Node[7] = new OCTNODE;
  986.  
  987.     ///
  988.     ///Dole
  989.     ///
  990.  
  991.     //0
  992.     N->Node[0]->Min.X = N->Min.X;
  993.     N->Node[0]->Min.Y = N->Min.Y;
  994.     N->Node[0]->Min.Z = N->Centre.Z;
  995.     N->Node[0]->Max.X = N->Centre.X;
  996.     N->Node[0]->Max.Y = N->Centre.Y;
  997.     N->Node[0]->Max.Z = N->Max.Z;
  998.     CreateNode(N->Node[0]);
  999.  
  1000.     //1
  1001.     N->Node[1]->Min.X = N->Centre.X;
  1002.     N->Node[1]->Min.Y = N->Min.Y;
  1003.     N->Node[1]->Min.Z = N->Centre.Z;
  1004.     N->Node[1]->Max.X = N->Max.X;
  1005.     N->Node[1]->Max.Y = N->Centre.Y;
  1006.     N->Node[1]->Max.Z = N->Max.Z;
  1007.     CreateNode(N->Node[1]);
  1008.  
  1009.     //2
  1010.     N->Node[2]->Min.X = N->Min.X;
  1011.     N->Node[2]->Min.Y = N->Min.Y;
  1012.     N->Node[2]->Min.Z = N->Min.Z;
  1013.     N->Node[2]->Max.X = N->Centre.X;
  1014.     N->Node[2]->Max.Y = N->Centre.Y;
  1015.     N->Node[2]->Max.Z = N->Centre.Z;
  1016.     CreateNode(N->Node[2]);
  1017.  
  1018.     //3
  1019.     N->Node[3]->Min.X = N->Centre.X;
  1020.     N->Node[3]->Min.Y = N->Min.Y;
  1021.     N->Node[3]->Min.Z = N->Min.Z;
  1022.     N->Node[3]->Max.X = N->Max.X;
  1023.     N->Node[3]->Max.Y = N->Centre.Y;
  1024.     N->Node[3]->Max.Z = N->Centre.Z;
  1025.     CreateNode(N->Node[3]);
  1026.  
  1027.     ///
  1028.     ///Hore
  1029.     ///
  1030.  
  1031.     //4
  1032.     N->Node[4]->Min.X = N->Min.X;
  1033.     N->Node[4]->Min.Y = N->Centre.Y;
  1034.     N->Node[4]->Min.Z = N->Centre.Z;
  1035.     N->Node[4]->Max.X = N->Centre.X;
  1036.     N->Node[4]->Max.Y = N->Max.Y;
  1037.     N->Node[4]->Max.Z = N->Max.Z;
  1038.     CreateNode(N->Node[4]);
  1039.  
  1040.     //5
  1041.     N->Node[5]->Min.X = N->Centre.X;
  1042.     N->Node[5]->Min.Y = N->Centre.Y;
  1043.     N->Node[5]->Min.Z = N->Centre.Z;
  1044.     N->Node[5]->Max.X = N->Max.X;
  1045.     N->Node[5]->Max.Y = N->Max.Y;
  1046.     N->Node[5]->Max.Z = N->Max.Z;
  1047.     CreateNode(N->Node[5]);
  1048.  
  1049.     //6
  1050.     N->Node[6]->Min.X = N->Min.X;
  1051.     N->Node[6]->Min.Y = N->Centre.Y;
  1052.     N->Node[6]->Min.Z = N->Min.Z;
  1053.     N->Node[6]->Max.X = N->Centre.X;
  1054.     N->Node[6]->Max.Y = N->Max.Y;
  1055.     N->Node[6]->Max.Z = N->Centre.Z;
  1056.     CreateNode(N->Node[6]);
  1057.  
  1058.     //7
  1059.     N->Node[7]->Min.X = N->Centre.X;
  1060.     N->Node[7]->Min.Y = N->Centre.Y;
  1061.     N->Node[7]->Min.Z = N->Min.Z;
  1062.     N->Node[7]->Max.X = N->Max.X;
  1063.     N->Node[7]->Max.Y = N->Max.Y;
  1064.     N->Node[7]->Max.Z = N->Centre.Z;
  1065.     CreateNode(N->Node[7]);
  1066.     
  1067.  
  1068.  
  1069. }
  1070.  
  1071. //------------------------------------------------------------------
  1072. // Name: ColliseNodeLine()
  1073. // Desc: Zisti koliziu usecky a nody
  1074. //------------------------------------------------------------------
  1075. bool OCTREE::ColliseNodeLine(OCTNODE *N,VECTOR3D P1,VECTOR3D P2)
  1076. {
  1077.     if (CollisionBoxEdge(P1,P2,N->Min,N->Max) == true)
  1078.         return true;
  1079.     else
  1080.         return false;
  1081.  
  1082. }
  1083.  
  1084.  
  1085. //------------------------------------------------------------------
  1086. // Name: ColliseNodeFace()
  1087. // Desc: Zisti koliziu medzi Face a node - zisti ci sa face nachazda v node
  1088. //------------------------------------------------------------------
  1089. bool OCTREE::ColliseNodeFace(OCTNODE *N,OCTFACE F)
  1090. {
  1091.     if (ColliseNodeLine(N,F.P[0],F.P[1]) == true)
  1092.         return true;
  1093.     if (ColliseNodeLine(N,F.P[1],F.P[2]) == true)
  1094.         return true;
  1095.     if (ColliseNodeLine(N,F.P[0],F.P[2]) == true)
  1096.         return true;
  1097.  
  1098.  
  1099.     return false;
  1100.  
  1101. }
  1102.  
  1103. //------------------------------------------------------------------
  1104. // Name: RenderDebugNode()
  1105. // Desc: graficky zobrazi octree
  1106. //------------------------------------------------------------------
  1107. void OCTREE::RenderDebugNode(OCTNODE *N)
  1108. {
  1109.     
  1110.     if (N->EndNode == true)
  1111.     {
  1112.         //if (Camera.FrustrumSphere(N->Centre ,N->Polomer ) == false)
  1113.         //    return;
  1114.  
  1115.         if (N->NumFaces > 0)
  1116.         {
  1117.             DebugDrawBox(N->Min,N->Max);
  1118.         }
  1119.     }
  1120.  
  1121.     if (N->EndNode == false)
  1122.     {
  1123.         RenderDebugNode(N->Node[0]);
  1124.         RenderDebugNode(N->Node[1]);
  1125.         RenderDebugNode(N->Node[2]);
  1126.         RenderDebugNode(N->Node[3]);
  1127.         RenderDebugNode(N->Node[4]);
  1128.         RenderDebugNode(N->Node[5]);
  1129.         RenderDebugNode(N->Node[6]);
  1130.         RenderDebugNode(N->Node[7]);
  1131.     }
  1132.  
  1133. }
  1134.  
  1135. //------------------------------------------------------------------
  1136. // Name: Optimalize()
  1137. // Desc: Vyberie tie face ktore su vidie¥
  1138. //------------------------------------------------------------------
  1139. void OCTREE::Optimalize()
  1140. {
  1141.  
  1142.     //oznaci vsetky face ako neviditelne
  1143.     for (int i=0;i<NumFaces;i++)
  1144.     {
  1145.         Face[i].Visible = false;
  1146.     } 
  1147.  
  1148.     //frustrum culling
  1149.     FrustrumNode(Node);
  1150.  
  1151.     //backface culing
  1152.     BackFaceCulling();
  1153.  
  1154. }
  1155.  
  1156. //------------------------------------------------------------------
  1157. // Name: FrustumNode()
  1158. // Desc: Frustrum culling
  1159. //------------------------------------------------------------------
  1160. void OCTREE::FrustrumNode(OCTNODE *N)
  1161. {
  1162.     
  1163.     //ako node neobsahuje ziadny face vyhod
  1164.     if (N->NumFaces == 0)
  1165.         return;
  1166.  
  1167.     //ak nieje v dohlade
  1168.     if (Camera.FrustrumSphere(N->Centre,N->Polomer) == false)
  1169.         return;
  1170.  
  1171.     //
  1172.     if (N->EndNode == true)
  1173.     {
  1174. //        if (Camera.FrustrumSphere(N->Centre,N->Polomer) == false)
  1175. //        return;
  1176.  
  1177.         for (int i=0;i<N->NumFaces;i++)
  1178.         {
  1179.             Face[N->FaceList[i]].Visible = true;
  1180.         }
  1181.     }
  1182.     else
  1183.     {
  1184.         FrustrumNode(N->Node[0]);
  1185.         FrustrumNode(N->Node[1]);
  1186.         FrustrumNode(N->Node[2]);
  1187.         FrustrumNode(N->Node[3]);
  1188.         FrustrumNode(N->Node[4]);
  1189.         FrustrumNode(N->Node[5]);
  1190.         FrustrumNode(N->Node[6]);
  1191.         FrustrumNode(N->Node[7]);
  1192.     }
  1193.  
  1194. }
  1195.  
  1196. //------------------------------------------------------------------
  1197. // Name: ColliseFace()
  1198. // Desc: Zisti koliziu s facom
  1199. //------------------------------------------------------------------
  1200. bool OCTREE::ColliseFace(OCTFACE F, VECTOR3D P1, VECTOR3D P2)
  1201. {
  1202.     VECTOR3D Inter;
  1203.     float U,U1,U2,U3;
  1204.  
  1205.     if (CalcPriesEdge(&Inter,F.Plane,P1,P2) == true)
  1206.     {
  1207.         U1 = CalcAngleCentre(Inter,F.P[0],
  1208.                                    F.P[1]);
  1209.         U2 = CalcAngleCentre(Inter,F.P[1],
  1210.                                    F.P[2]);
  1211.         U3 = CalcAngleCentre(Inter,F.P[2],
  1212.                                    F.P[0]);
  1213.  
  1214.         U = U1+U2+U3;
  1215.  
  1216.         if (U > 6.2f && U < 6.35f)
  1217.         {
  1218.             ColliseStatus = true;
  1219.             IntPos = Inter;
  1220.             IntNormal = F.Plane.Normal;
  1221.             IntMaterialType = Group[F.Group ].MaterialType ;
  1222.             IntBlendType = Group[F.Group ].BlendType ;
  1223.             IntGroupType = Group[F.Group ].GroupType ;
  1224.  
  1225.             return true;
  1226.         }
  1227.         else
  1228.         {
  1229.             return false;
  1230.         }
  1231.     }
  1232.     else
  1233.     {
  1234.         return false;
  1235.     }
  1236. }
  1237.  
  1238. //------------------------------------------------------------------
  1239. // Name: ColliseFaceDistance()
  1240. // Desc: Zisti koliziu s facom vyberie najblizsi priesecnik
  1241. //------------------------------------------------------------------
  1242. bool OCTREE::ColliseFaceDistance(OCTFACE F, VECTOR3D P1, VECTOR3D P2)
  1243. {
  1244.     VECTOR3D Inter;
  1245.     float U,U1,U2,U3;
  1246.  
  1247.     if (CalcPriesEdge(&Inter,F.Plane,P1,P2) == true)
  1248.     {
  1249.         U1 = CalcAngleCentre(Inter,F.P[0],
  1250.                                    F.P[1]);
  1251.         U2 = CalcAngleCentre(Inter,F.P[1],
  1252.                                    F.P[2]);
  1253.         U3 = CalcAngleCentre(Inter,F.P[2],
  1254.                                    F.P[0]);
  1255.  
  1256.         U = U1+U2+U3;
  1257.  
  1258.         if (U > 6.2f && U < 6.35f)
  1259.         {
  1260.             if (ColliseStatus ==false)
  1261.             {
  1262.                 ColliseStatus = true;
  1263.                 IntPos = Inter;
  1264.                 IntNormal = F.Plane.Normal;
  1265.                 IntMaterialType = Group[F.Group ].MaterialType ;
  1266.                 IntBlendType = Group[F.Group ].BlendType ;
  1267.                 IntGroupType = Group[F.Group ].GroupType ;
  1268.             }
  1269.             else
  1270.             {
  1271.                 float Dis1 = CalcDistance(P1,Inter);
  1272.                 float Dis2 = CalcDistance(P1,IntPos);
  1273.  
  1274.                 if(Dis1 < Dis2)
  1275.                 {
  1276.                     IntPos = Inter;
  1277.                     IntNormal = F.Plane.Normal;
  1278.                     IntMaterialType = Group[F.Group ].MaterialType ;
  1279.                     IntBlendType = Group[F.Group ].BlendType ;
  1280.                     IntGroupType = Group[F.Group ].GroupType ;
  1281.         
  1282.                 }
  1283.  
  1284.             }
  1285.  
  1286.             return true;
  1287.         }
  1288.         else
  1289.         {
  1290.             return false;
  1291.         }
  1292.     }
  1293.     else
  1294.     {
  1295.         return false;
  1296.     }
  1297. }
  1298.  
  1299. //------------------------------------------------------------------
  1300. // Name: ColliseNode()
  1301. // Desc: rekruziva na koliziu
  1302. //------------------------------------------------------------------
  1303. void OCTREE::ColliseNode(OCTNODE *N, VECTOR3D P1, VECTOR3D P2)
  1304. {
  1305.     int GroupIndex;
  1306.     int FaceIndex;
  1307.  
  1308.     //
  1309.     //ak uz je kolizia dalej koliziu neprevadzat
  1310.     //
  1311.     if (ColliseStatus == true)
  1312.         return;
  1313.  
  1314.     //
  1315.     //ak luc prechadzat nodov
  1316.     //
  1317.     if (ColliseNodeLine(N,P1,P2) == true)
  1318.     {
  1319.         //ak to je konecna noda
  1320.         if (N->EndNode == true)
  1321.         {
  1322.             for (int i=0;i<N->NumFaces;i++)
  1323.             {
  1324.                 //zisti indexi
  1325.                 FaceIndex = N->FaceList[i];
  1326.                 GroupIndex = Face[FaceIndex].Group ;
  1327.  
  1328.                 //ak je zapnuta kolizia skupiny
  1329.                 if (!(Group[GroupIndex].CollisionType == 1 && Mode == 1))
  1330.                 {
  1331.                     if (ColliseFace(Face[FaceIndex],P1,P2) == true)
  1332.                         break;
  1333.                 }
  1334.             }
  1335.         }
  1336.         //
  1337.         //inak otestuj vsetky podnody
  1338.         //
  1339.         else
  1340.         {
  1341.             ColliseNode(N->Node[0],P1,P2);
  1342.             ColliseNode(N->Node[1],P1,P2);
  1343.             ColliseNode(N->Node[2],P1,P2);
  1344.             ColliseNode(N->Node[3],P1,P2);
  1345.             ColliseNode(N->Node[4],P1,P2);
  1346.             ColliseNode(N->Node[5],P1,P2);
  1347.             ColliseNode(N->Node[6],P1,P2);
  1348.             ColliseNode(N->Node[7],P1,P2);
  1349.         }
  1350.     }
  1351.     
  1352.  
  1353. }
  1354.  
  1355.  
  1356. //------------------------------------------------------------------
  1357. // Name: ColliseNodeDistance()
  1358. // Desc: otestuje vsetky polygony a vybere najblizsi priesecnik k bodu P1
  1359. //------------------------------------------------------------------
  1360. void OCTREE::ColliseNodeDistance(OCTNODE *N, VECTOR3D P1, VECTOR3D P2)
  1361. {
  1362.     int GroupIndex;
  1363.     int FaceIndex;
  1364.  
  1365.     //
  1366.     //ak luc prechadzat nodov
  1367.     //
  1368.     if (ColliseNodeLine(N,P1,P2) == true)
  1369.     {
  1370.         //ak to je konecna noda
  1371.         if (N->EndNode == true)
  1372.         {
  1373.             for (int i=0;i<N->NumFaces;i++)
  1374.             {
  1375.                 //zisti indexi
  1376.                 FaceIndex = N->FaceList[i];
  1377.                 GroupIndex = Face[FaceIndex].Group ;
  1378.  
  1379.                 //ak je zapnuta kolizia skupiny
  1380.                 if (!(Group[GroupIndex].CollisionType == 1 && Mode == 1))
  1381.                 {
  1382.                     ColliseFaceDistance(Face[FaceIndex],P1,P2);
  1383.                 }
  1384.             }
  1385.         }
  1386.         //
  1387.         //inak otestuj vsetky podnody
  1388.         //
  1389.         else
  1390.         {
  1391.             ColliseNodeDistance(N->Node[0],P1,P2);
  1392.             ColliseNodeDistance(N->Node[1],P1,P2);
  1393.             ColliseNodeDistance(N->Node[2],P1,P2);
  1394.             ColliseNodeDistance(N->Node[3],P1,P2);
  1395.             ColliseNodeDistance(N->Node[4],P1,P2);
  1396.             ColliseNodeDistance(N->Node[5],P1,P2);
  1397.             ColliseNodeDistance(N->Node[6],P1,P2);
  1398.             ColliseNodeDistance(N->Node[7],P1,P2);
  1399.         }
  1400.     }
  1401.     
  1402.  
  1403. }
  1404. //------------------------------------------------------------------
  1405. // Name: Collise()
  1406. // Desc: funkcia testuje koliziu s terenom
  1407. //------------------------------------------------------------------
  1408. bool OCTREE::Collise(VECTOR3D P1,VECTOR3D P2)
  1409. {
  1410.     
  1411.     //zresetuje
  1412.     ColliseStatus = false;
  1413.  
  1414.     ColliseNode(Node,P1,P2);
  1415.  
  1416.     return ColliseStatus;
  1417.  
  1418. }
  1419.  
  1420. //------------------------------------------------------------------
  1421. // Name: ColliseDistance()
  1422. // Desc: funkcia testuje koliziu s terenom vyberie najblizsi priesecnik
  1423. //------------------------------------------------------------------
  1424. bool OCTREE::ColliseDistance(VECTOR3D P1,VECTOR3D P2)
  1425. {
  1426.     //zresetuje
  1427.     ColliseStatus = false;
  1428.  
  1429.     ColliseNodeDistance(Node,P1,P2);
  1430.  
  1431.     return ColliseStatus;
  1432.  
  1433. }
  1434. //------------------------------------------------------------------
  1435. // Name: SaveScene()
  1436. // Desc: ulozi optimalizovanu scenu
  1437. //------------------------------------------------------------------
  1438. void OCTREE::SaveScene(char *FileName)
  1439. {
  1440.     
  1441.     //otvori suber pre bynarny zapis
  1442.     FileScn = fopen(FileName,"wb");
  1443.  
  1444.     //zapise pocet facov
  1445.     int NumF = NumFaces;
  1446.     fwrite(&NumF,sizeof(int),1,FileScn);
  1447.  
  1448.     //zapise faces
  1449.     fwrite(Face,sizeof(OCTFACE),NumF,FileScn);
  1450.  
  1451.     //zatvor subor
  1452.     fclose(FileScn);
  1453.  
  1454.  
  1455. }
  1456.  
  1457.  
  1458. //------------------------------------------------------------------
  1459. // Name: LoadScene()
  1460. // Desc: Otvori optimalizovanu scenu
  1461. //------------------------------------------------------------------
  1462. void OCTREE::LoadScene(char *FileNameGeo,char *FileNameScn)
  1463. {
  1464.     
  1465.     char cBuf[80];
  1466.     int i;
  1467.     int NumF;
  1468.  
  1469.     //Log
  1470.     LogPrint("Vytvaram OCTree");
  1471.     sprintf(cBuf," Subor Geo: %s",FileNameGeo);
  1472.     LogPrint(cBuf);
  1473.     sprintf(cBuf," Subor Scn: %s",FileNameScn);
  1474.     LogPrint(cBuf);
  1475.     
  1476.  
  1477.     ///////////////////
  1478.     //otvor subor GEO//
  1479.     ///////////////////
  1480.     FileGeo = fopen(FileNameGeo,"r");
  1481.  
  1482.     if (FileGeo == NULL)
  1483.         LogPrint(" Subor GEO sa nepodarilo otvorit");
  1484.  
  1485.     ///////////////////
  1486.     //otvor subor SCN//
  1487.     ///////////////////
  1488.     FileScn = fopen(FileNameScn,"rb");
  1489.  
  1490.     if (FileScn == NULL)
  1491.         LogPrint(" Subor SCN sa nepodarilo otvorit");
  1492.  
  1493.  
  1494.     ///////////////
  1495.     //hlavicka   //
  1496.     ///////////////
  1497.     fscanf(FileGeo,"%s %d",cBuf,&MinNodeSize);
  1498.     fscanf(FileGeo,"%s %d",cBuf,&NumGroups);
  1499.     fscanf(FileGeo,"%s %d",cBuf,&NumFaces);
  1500.  
  1501.     sprintf(cBuf," MinPolygonsInNode: %d",MinNodeSize);
  1502.     LogPrint(cBuf);
  1503.     sprintf(cBuf," NumGroups: %d",NumGroups);
  1504.     LogPrint(cBuf);
  1505.     sprintf(cBuf," NumFaces: %d",NumFaces);
  1506.     LogPrint(cBuf);
  1507.     
  1508.  
  1509.     ///////////////
  1510.     //group      //
  1511.     ///////////////
  1512.  
  1513.     Group = new OCTGROUP[NumGroups];
  1514.     for (i=0;i<NumGroups;i++)
  1515.     {
  1516.         ReadGroup();
  1517.     }
  1518.  
  1519.     ///////////////
  1520.     //faces      //
  1521.     ///////////////
  1522.     Face = new OCTFACE[NumFaces];
  1523.     fread(&NumF,sizeof(int),1,FileScn);
  1524.     for(i = 0;i<NumF;i++)
  1525.         fread(&Face[i],sizeof(OCTFACE),1,FileScn);
  1526.  
  1527.  
  1528.     /////////////////
  1529.     //Vertex Buffer//
  1530.     /////////////////
  1531.     CreateVertexBuffer();
  1532.  
  1533.     ////////////////
  1534.     //zatvor subor//
  1535.     ////////////////
  1536.     fclose(FileGeo);
  1537.     fclose(FileScn);
  1538.  
  1539.     ///////////
  1540.     //OCTree //
  1541.     ///////////
  1542.     //CreateOctTree();
  1543.  
  1544. }
  1545.  
  1546. //------------------------------------------------------------------
  1547. // Name: BackFaceCulling()
  1548. // Desc: odstrani zadnΘ hrany
  1549. //------------------------------------------------------------------
  1550. void OCTREE::BackFaceCulling()
  1551. {
  1552.  
  1553.     for (int i=0;i<NumFaces;i++)
  1554.     {
  1555.         if (Face[i].Visible == true)
  1556.         {
  1557.             if (PointPlane(Face[i].Plane,Camera.Pos) > 0.0f)
  1558.                 Face[i].Visible = false;
  1559.         }
  1560.     }
  1561.  
  1562. }
  1563.  
  1564. //------------------------------------------------------------------
  1565. // Name: SetTexture()
  1566. // Desc: nastavi externu texturu do skupiny
  1567. //------------------------------------------------------------------
  1568. void OCTREE::SetTexture(int ToGroup,int ToFrame,LPDIRECT3DTEXTURE9 Tex)
  1569. {
  1570.     Group[ToGroup].g_pTexture[ToFrame] = Tex;
  1571. }
  1572.  
  1573.  
  1574. //------------------------------------------------------------------
  1575. // Name: LoadOctTree()
  1576. // Desc: nacita octree storm
  1577. //------------------------------------------------------------------
  1578. void OCTREE::LoadOctTree(char *FileName)
  1579. {
  1580.  
  1581.  
  1582.     //subor
  1583.     FileOct = fopen(FileName,"rb");
  1584.  
  1585.     //zachytavanie chyb
  1586.     if (FileOct == NULL)
  1587.     {
  1588.         char cBuf[80];
  1589.         sprintf(cBuf,"Nemozem najst subor %s",FileName);
  1590.     }
  1591.  
  1592.     //loadne strom
  1593.     Node = new OCTNODE;
  1594.     LoadNode(Node);
  1595.  
  1596.     //zatvor
  1597.     fclose(FileOct);
  1598.     FileOct = NULL;
  1599.  
  1600. }
  1601.  
  1602. //------------------------------------------------------------------
  1603. // Name: SaveOctTree()
  1604. // Desc: ulozi octree stom
  1605. //------------------------------------------------------------------
  1606. void OCTREE::SaveOctTree(char *FileName)
  1607. {
  1608.     //subor
  1609.     FileOct = fopen(FileName,"wb");
  1610.  
  1611.     //ulozi strom
  1612.     SaveNode(Node);
  1613.  
  1614.     //zatvor
  1615.     fclose(FileOct);
  1616.     FileOct = NULL;
  1617.     
  1618.  
  1619. }
  1620.  
  1621. //------------------------------------------------------------------
  1622. // Name: SaveNone()
  1623. // Desc: ulozi nodu octtree
  1624. //------------------------------------------------------------------
  1625. void OCTREE::SaveNode(OCTNODE *N)
  1626. {
  1627.  
  1628.     OCTRNODE RNode;
  1629.  
  1630.     //rnode
  1631.     RNode.Centre = N->Centre;
  1632.     RNode.EndNode = N->EndNode ;
  1633.     RNode.Max = N->Max;
  1634.     RNode.Min = N->Min;
  1635.     RNode.NumFaces = N->NumFaces;
  1636.     RNode.Polomer = N->Polomer;
  1637.  
  1638.     //zapis - node
  1639.     fwrite(&RNode,sizeof(OCTRNODE),1,FileOct);
  1640.  
  1641.     //zapis - facelist ak je konecna
  1642.     if (RNode.EndNode == true)
  1643.         fwrite(N->FaceList,sizeof(int),RNode.NumFaces,FileOct);
  1644.  
  1645.     //ak je konecna node tak vyhod
  1646.     if (RNode.EndNode == true)
  1647.         return;
  1648.  
  1649.     //inak uloz sub nody
  1650.     SaveNode(N->Node[0]);
  1651.     SaveNode(N->Node[1]);
  1652.     SaveNode(N->Node[2]);
  1653.     SaveNode(N->Node[3]);
  1654.     SaveNode(N->Node[4]);
  1655.     SaveNode(N->Node[5]);
  1656.     SaveNode(N->Node[6]);
  1657.     SaveNode(N->Node[7]);
  1658.  
  1659. }
  1660.  
  1661. //------------------------------------------------------------------
  1662. // Name: LoadNone()
  1663. // Desc: nacita nodu octree
  1664. //------------------------------------------------------------------
  1665. void OCTREE::LoadNode(OCTNODE *N)
  1666. {
  1667.  
  1668.     
  1669.     OCTRNODE RNode;
  1670.  
  1671.     //precita - node
  1672.     fread(&RNode,sizeof(OCTRNODE),1,FileOct);
  1673.  
  1674.     //precita - facelist ak je konecna
  1675.     if (RNode.EndNode == true)
  1676.     { 
  1677.         N->FaceList = new int[RNode.NumFaces];
  1678.         fread(N->FaceList,sizeof(int),RNode.NumFaces,FileOct);
  1679.     }
  1680.  
  1681.     //rnode
  1682.     N->Centre = RNode.Centre;
  1683.     N->EndNode = RNode.EndNode ;
  1684.     N->Max = RNode.Max;
  1685.     N->Min = RNode.Min;
  1686.     N->NumFaces = RNode.NumFaces;
  1687.     N->Polomer = RNode.Polomer;
  1688.  
  1689.     //ak je konecna node tak vyhod
  1690.     if (RNode.EndNode == true)
  1691.         return;
  1692.  
  1693.     //vytvor sub nody
  1694.     N->Node[0] = new OCTNODE;
  1695.     N->Node[1] = new OCTNODE;
  1696.     N->Node[2] = new OCTNODE;
  1697.     N->Node[3] = new OCTNODE;
  1698.     N->Node[4] = new OCTNODE;
  1699.     N->Node[5] = new OCTNODE;
  1700.     N->Node[6] = new OCTNODE;
  1701.     N->Node[7] = new OCTNODE;
  1702.  
  1703.     //uloz sub nody
  1704.     LoadNode(N->Node[0]);
  1705.     LoadNode(N->Node[1]);
  1706.     LoadNode(N->Node[2]);
  1707.     LoadNode(N->Node[3]);
  1708.     LoadNode(N->Node[4]);
  1709.     LoadNode(N->Node[5]);
  1710.     LoadNode(N->Node[6]);
  1711.     LoadNode(N->Node[7]);
  1712.  
  1713. }
  1714.