00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "ExCOctree.h"
00025
00026 ExCOctree::ExCOctree(void)
00027 {
00028 Guard(ExCOctree::ExCOctree(void))
00029 m_ShowOctreeSubdivision=true;
00030 m_SubDivisionLevel=1;
00031 A=NULL;
00032 B=NULL;
00033 C=NULL;
00034 D=NULL;
00035 E=NULL;
00036 F=NULL;
00037 G=NULL;
00038 H=NULL;
00039 UnGuard
00040 }
00041
00042 ExCOctree::ExCOctree(std::vector<ExCMesh> VecMesh)
00043 {
00044 Guard(ExCOctree::ExCOctree(std::vector<ExCMesh> VecMesh))
00045 ExCOctree();
00046 Build(VecMesh);
00047 UnGuard
00048 }
00049
00050 ExCOctree::~ExCOctree(void)
00051 {
00052 Guard(ExCOctree::~ExCOctree(void))
00053
00054 UnGuard
00055 }
00056
00057 void ExCOctree::BuildFirstBox(void)
00058 {
00059 Guard(void ExCOctree::BuildFirstBox(void))
00060
00061 double MaxX,MaxY,MaxZ,MinX,MinY,MinZ;
00062 m_ItVecMesh=m_VecMesh.begin();
00063 MaxX=m_ItVecMesh->A.GetX();
00064 MinX=m_ItVecMesh->A.GetX();
00065 MaxY=m_ItVecMesh->A.GetY();
00066 MinY=m_ItVecMesh->A.GetY();
00067 MaxZ=m_ItVecMesh->A.GetZ();
00068 MinZ=m_ItVecMesh->A.GetZ();
00069 for(m_ItVecMesh=m_VecMesh.begin();m_ItVecMesh!=m_VecMesh.end();++m_ItVecMesh)
00070 {
00071 if(m_ItVecMesh->A.GetX()<MinX){MinX=m_ItVecMesh->A.GetX();}
00072 if(m_ItVecMesh->A.GetX()>MaxX){MaxX=m_ItVecMesh->A.GetX();}
00073 if(m_ItVecMesh->B.GetX()<MinX){MinX=m_ItVecMesh->B.GetX();}
00074 if(m_ItVecMesh->B.GetX()>MaxX){MaxX=m_ItVecMesh->B.GetX();}
00075 if(m_ItVecMesh->C.GetX()<MinX){MinX=m_ItVecMesh->C.GetX();}
00076 if(m_ItVecMesh->C.GetX()>MaxX){MaxX=m_ItVecMesh->C.GetX();}
00077
00078 if(m_ItVecMesh->A.GetY()<MinY){MinY=m_ItVecMesh->A.GetY();}
00079 if(m_ItVecMesh->A.GetY()>MaxY){MaxY=m_ItVecMesh->A.GetY();}
00080 if(m_ItVecMesh->B.GetY()<MinY){MinY=m_ItVecMesh->B.GetY();}
00081 if(m_ItVecMesh->B.GetY()>MaxY){MaxY=m_ItVecMesh->B.GetY();}
00082 if(m_ItVecMesh->C.GetY()<MinY){MinY=m_ItVecMesh->C.GetY();}
00083 if(m_ItVecMesh->C.GetY()>MaxY){MaxY=m_ItVecMesh->C.GetY();}
00084
00085 if(m_ItVecMesh->A.GetZ()<MinZ){MinZ=m_ItVecMesh->A.GetZ();}
00086 if(m_ItVecMesh->A.GetZ()>MaxZ){MaxZ=m_ItVecMesh->A.GetZ();}
00087 if(m_ItVecMesh->B.GetZ()<MinZ){MinZ=m_ItVecMesh->B.GetZ();}
00088 if(m_ItVecMesh->B.GetZ()>MaxZ){MaxZ=m_ItVecMesh->B.GetZ();}
00089 if(m_ItVecMesh->C.GetZ()<MinZ){MinZ=m_ItVecMesh->C.GetZ();}
00090 if(m_ItVecMesh->C.GetZ()>MaxZ){MaxZ=m_ItVecMesh->C.GetZ();}
00091 }
00092
00093
00094
00095
00096 if((MaxX-MinX)>=(MaxY-MinY)&&(MaxX-MinX)>=(MaxZ-MinZ))
00097 {
00098 maxsegment=MaxX-MinX;
00099 }
00100 if((MaxY-MinY)>=(MaxX-MinX)&&(MaxY-MinY)>=(MaxZ-MinZ))
00101 {
00102 maxsegment=MaxY-MinY;
00103 }
00104 if((MaxZ-MinZ)>=(MaxY-MinY)&&(MaxZ-MinZ)>=(MaxX-MinX))
00105 {
00106 maxsegment=MaxZ-MinZ;
00107 }
00108
00109 m_GLobalBox.m_Center.SetX(((MaxX-MinX)/2)-maxsegment/2);
00110 m_GLobalBox.m_Center.SetY(((MaxY-MinY)/2)-maxsegment/2);
00111 m_GLobalBox.m_Center.SetZ(((MaxZ-MinZ)/2));
00112
00113 BuildBox(m_GLobalBox.m_Center,maxsegment);
00114
00115 UnGuard
00116 }
00117
00118 void ExCOctree::BuildBox(ExCVertex center,double size)
00119 {
00120 Guard(void ExCOctree::BuildBox(ExCVertex center,double size))
00121 maxsegment=size;
00122 m_GLobalBox.m_Center=center;
00123
00124 m_GLobalBox.m_Vertex[0].SetX(center.GetX()+(size/2));
00125 m_GLobalBox.m_Vertex[0].SetY(center.GetY()+(size/2));
00126 m_GLobalBox.m_Vertex[0].SetZ(center.GetZ()-(size/2));
00127 m_GLobalBox.m_Vertex[1].SetX(center.GetX()+(size/2));
00128 m_GLobalBox.m_Vertex[1].SetY(center.GetY()+(size/2));
00129 m_GLobalBox.m_Vertex[1].SetZ(center.GetZ()+(size/2));
00130 m_GLobalBox.m_Vertex[2].SetX(center.GetX()-(size/2));
00131 m_GLobalBox.m_Vertex[2].SetY(center.GetY()+(size/2));
00132 m_GLobalBox.m_Vertex[2].SetZ(center.GetZ()+(size/2));
00133 m_GLobalBox.m_Vertex[3].SetX(center.GetX()-(size/2));
00134 m_GLobalBox.m_Vertex[3].SetY(center.GetY()+(size/2));
00135 m_GLobalBox.m_Vertex[3].SetZ(center.GetZ()-(size/2));
00136 m_GLobalBox.m_Vertex[4].SetX(center.GetX()+(size/2));
00137 m_GLobalBox.m_Vertex[4].SetY(center.GetY()-(size/2));
00138 m_GLobalBox.m_Vertex[4].SetZ(center.GetZ()-(size/2));
00139 m_GLobalBox.m_Vertex[5].SetX(center.GetX()+(size/2));
00140 m_GLobalBox.m_Vertex[5].SetY(center.GetY()-(size/2));
00141 m_GLobalBox.m_Vertex[5].SetZ(center.GetZ()+(size/2));
00142 m_GLobalBox.m_Vertex[6].SetX(center.GetX()-(size/2));
00143 m_GLobalBox.m_Vertex[6].SetY(center.GetY()-(size/2));
00144 m_GLobalBox.m_Vertex[6].SetZ(center.GetZ()+(size/2));
00145 m_GLobalBox.m_Vertex[7].SetX(center.GetX()-(size/2));
00146 m_GLobalBox.m_Vertex[7].SetY(center.GetY()-(size/2));
00147 m_GLobalBox.m_Vertex[7].SetZ(center.GetZ()-(size/2));
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 UnGuard
00158 }
00159
00160 void ExCOctree::SubDivise(void)
00161 {
00162 Guard(void ExCOctree::SubDivise(void))
00163 ExCVertex VertexTmp;
00164 A=new ExCOctree();
00165 A->SetSubDivisionLevel(m_SubDivisionLevel+1);
00166 A->SetManagerTexture(ManagerTexture);
00167 VertexTmp.SetX(m_GLobalBox.m_Center.GetY()+maxsegment/4);
00168 VertexTmp.SetY(m_GLobalBox.m_Center.GetY()+maxsegment/4);
00169 VertexTmp.SetZ(m_GLobalBox.m_Center.GetZ()+maxsegment/4);
00170 A->BuildBox(VertexTmp,maxsegment/2);
00171
00172 B=new ExCOctree();
00173 B->SetSubDivisionLevel(m_SubDivisionLevel+1);
00174 B->SetManagerTexture(ManagerTexture);
00175 VertexTmp.SetX(m_GLobalBox.m_Center.GetX()+maxsegment/4);
00176 VertexTmp.SetY(m_GLobalBox.m_Center.GetY()+maxsegment/4);
00177 VertexTmp.SetZ(m_GLobalBox.m_Center.GetZ()-maxsegment/4);
00178 B->BuildBox(VertexTmp,maxsegment/2);
00179
00180 C=new ExCOctree();
00181 C->SetSubDivisionLevel(m_SubDivisionLevel+1);
00182 C->SetManagerTexture(ManagerTexture);
00183 VertexTmp.SetX(m_GLobalBox.m_Center.GetX()-maxsegment/4);
00184 VertexTmp.SetY(m_GLobalBox.m_Center.GetY()+maxsegment/4);
00185 VertexTmp.SetZ(m_GLobalBox.m_Center.GetZ()-maxsegment/4);
00186 C->BuildBox(VertexTmp,maxsegment/2);
00187
00188 D=new ExCOctree();
00189 D->SetSubDivisionLevel(m_SubDivisionLevel+1);
00190 D->SetManagerTexture(ManagerTexture);
00191 VertexTmp.SetX(m_GLobalBox.m_Center.GetX()-maxsegment/4);
00192 VertexTmp.SetY(m_GLobalBox.m_Center.GetY()+maxsegment/4);
00193 VertexTmp.SetZ(m_GLobalBox.m_Center.GetZ()+maxsegment/4);
00194 D->BuildBox(VertexTmp,maxsegment/2);
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 int i=0;
00229 for(m_ItVecMesh=m_VecMesh.begin(),i=0;m_ItVecMesh!=m_VecMesh.end();m_ItVecMesh++,i++)
00230 {
00231
00232 if(MeshInOctree(*m_ItVecMesh,A))
00233 {
00234 A->m_VecMesh.push_back(*m_ItVecMesh);
00235
00236 continue;
00237 }
00238 if(MeshInOctree(*m_ItVecMesh,B))
00239 {
00240 B->m_VecMesh.push_back(*m_ItVecMesh);
00241
00242 continue;
00243 }
00244 if(MeshInOctree(*m_ItVecMesh,C))
00245 {
00246 C->m_VecMesh.push_back(*m_ItVecMesh);
00247
00248 continue;
00249 }
00250 if(MeshInOctree(*m_ItVecMesh,D))
00251 {
00252 D->m_VecMesh.push_back(*m_ItVecMesh);
00253
00254 continue;
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 }
00282
00283 std::cout<<"Level :"<<m_SubDivisionLevel<<"Stay :"<<m_VecMesh.size()<<std::endl;
00284 if(m_VecMesh.size()>0)
00285 {
00286 BuilList();
00287 }
00288
00289 if(A->m_VecMesh.size()==0)
00290 {
00291
00292 A=NULL;
00293 }
00294 if(B->m_VecMesh.size()==0)
00295 {
00296
00297 B=NULL;
00298 }
00299 if(C->m_VecMesh.size()==0)
00300 {
00301
00302 C=NULL;
00303 }
00304 if(D->m_VecMesh.size()==0)
00305 {
00306
00307 D=NULL;
00308 }
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 if(m_VecMesh.size()>MAX_MESH_IN_CUBE&&m_SubDivisionLevel<MAX_SUBDIVISION)
00331 {
00332 if(A!=NULL)A->SubDivise();
00333 if(B!=NULL)B->SubDivise();
00334 if(C!=NULL)C->SubDivise();
00335 if(D!=NULL)D->SubDivise();
00336 if(E!=NULL)E->SubDivise();
00337 if(F!=NULL)F->SubDivise();
00338 if(G!=NULL)G->SubDivise();
00339 if(H!=NULL)H->SubDivise();
00340
00341 }
00342 else
00343 {
00344 BuilList();
00345 }
00346 UnGuard
00347 }
00348
00349 bool ExCOctree::MeshInOctree(ExCMesh Mesh,ExCOctree *octree)
00350 {
00351 Guard(bool ExCOctree::MeshInOctree(ExCMesh Mesh,ExCOctree *octree))
00352 double MaxX,MaxY,MaxZ,MinX,MinY,MinZ;
00353 int cmptin=0;
00354 MaxX=octree->m_GLobalBox.m_Center.GetX()+(maxsegment/2);
00355 MinX=octree->m_GLobalBox.m_Center.GetX()-(maxsegment/2);
00356 MaxY=octree->m_GLobalBox.m_Center.GetY()+(maxsegment/2);
00357 MinY=octree->m_GLobalBox.m_Center.GetY()-(maxsegment/2);
00358 MaxZ=octree->m_GLobalBox.m_Center.GetZ()+(maxsegment/2);
00359 MinZ=octree->m_GLobalBox.m_Center.GetZ()-(maxsegment/2);
00360
00361 if(Mesh.A.GetX()<=MaxX && Mesh.A.GetX()>=MinX)
00362 {
00363 if(Mesh.A.GetY()<=MaxY && Mesh.A.GetY()>=MinY)
00364 {
00365 if(Mesh.A.GetZ()<=MaxZ && Mesh.A.GetZ()>=MinZ)
00366 {
00367 cmptin++;
00368 }
00369 }
00370 }
00371
00372 if(Mesh.B.GetX()<=MaxX && Mesh.B.GetX()>=MinX)
00373 {
00374 if(Mesh.B.GetY()<=MaxY && Mesh.B.GetY()>=MinY)
00375 {
00376 if(Mesh.B.GetZ()<=MaxZ && Mesh.B.GetZ()>=MinZ)
00377 {
00378 cmptin++;
00379 }
00380 }
00381 }
00382
00383 if(Mesh.C.GetX()<=MaxX && Mesh.C.GetX()>=MinX)
00384 {
00385 if(Mesh.C.GetY()<=MaxY && Mesh.C.GetY()>=MinY)
00386 {
00387 if(Mesh.C.GetZ()<=MaxZ && Mesh.C.GetZ()>=MinZ)
00388 {
00389 cmptin++;
00390 }
00391 }
00392 }
00393
00394 if(cmptin>1)
00395 {
00396 return true;
00397 }
00398 else return false;
00399 UnGuard
00400 }
00401
00402 void ExCOctree::Build(std::vector<ExCMesh> VecMesh)
00403 {
00404 Guard(void ExCOctree::Build(std::vector<ExCMesh> VecMesh))
00405 m_VecMesh=VecMesh;
00406 BuildBox(ExCVertex(),1000);
00407 if(m_VecMesh.size()>MAX_MESH_IN_CUBE&&m_SubDivisionLevel<MAX_SUBDIVISION)
00408 {
00409 SubDivise();
00410 }else
00411 {
00412 BuilList();
00413 }
00414
00415 UnGuard
00416 }
00417
00418 void ExCOctree::Draw(void)
00419 {
00420 Guard(void ExCOctree::Draw(void))
00421 Frustrum.CalculateFrustum();
00422
00423 if(Frustrum.CubeInFrustum(m_GLobalBox.m_Center.GetX(),m_GLobalBox.m_Center.GetY(),m_GLobalBox.m_Center.GetZ(),maxsegment))
00424 {
00425 if(m_ShowOctreeSubdivision)
00426 {
00427 if(m_SubDivisionLevel%1==0){glColor3f((float)m_SubDivisionLevel/10,1.0f-((float)m_SubDivisionLevel/10),1.0f);}
00428 if(m_SubDivisionLevel%2==0){glColor3f(1.0f,1.0f-((float)m_SubDivisionLevel/10),(float)m_SubDivisionLevel/10);}
00429 if(m_SubDivisionLevel%3==0){glColor3f(1.0f-((float)m_SubDivisionLevel/10),1.0f,(float)m_SubDivisionLevel/10);}
00430 m_GLobalBox.Draw();
00431 }
00432 glCallList(m_GlListId);
00433
00434 if(A!=NULL)A->Draw();
00435 if(B!=NULL)B->Draw();
00436 if(C!=NULL)C->Draw();
00437 if(D!=NULL)D->Draw();
00438 if(E!=NULL)E->Draw();
00439 if(F!=NULL)F->Draw();
00440 if(G!=NULL)G->Draw();
00441 if(H!=NULL)H->Draw();
00442 }
00443
00444 UnGuard
00445 }
00446
00447 void ExCOctree::BuilList(void)
00448 {
00449 Guard(void ExMap::BuilList(void))
00450 m_GlListId=glGenLists(1);
00451 glNewList(m_GlListId,GL_COMPILE);
00452 glColor3f(1.0f, 1.0f, 1.0f);
00453 glDisable(GL_LIGHTING);
00454 glEnable(GL_TEXTURE_2D);
00455 int i=0;
00456
00457 for(m_ItVecMesh=m_VecMesh.begin();m_ItVecMesh!=m_VecMesh.end();++m_ItVecMesh)
00458 {
00459 ManagerTexture->SetActiveTexture(m_ItVecMesh->GetMaterial());
00460 glBegin(GL_TRIANGLES);
00461
00462
00463
00464
00465
00466
00467
00468 glTexCoord2f(m_ItVecMesh->A.GetU(), m_ItVecMesh->A.GetV());
00469 glVertex3f(m_ItVecMesh->A.GetX(),m_ItVecMesh->A.GetY(),m_ItVecMesh->A.GetZ());
00470
00471
00472
00473
00474
00475
00476
00477 glTexCoord2f(m_ItVecMesh->B.GetU(), m_ItVecMesh->B.GetV());
00478 glVertex3f(m_ItVecMesh->B.GetX(),m_ItVecMesh->B.GetY(),m_ItVecMesh->B.GetZ());
00479
00480
00481
00482
00483
00484
00485
00486 glTexCoord2f(m_ItVecMesh->C.GetU(), m_ItVecMesh->C.GetV());
00487 glVertex3f(m_ItVecMesh->C.GetX(),m_ItVecMesh->C.GetY(),m_ItVecMesh->C.GetZ());
00488 glEnd();
00489 i++;
00490 }
00491 glEnable(GL_LIGHTING);
00492 glDisable(GL_TEXTURE_2D);
00493 glEndList();
00494 UnGuard
00495 }