- Timestamp:
- 08/10/05 17:09:29 (19 years ago)
- Location:
- trunk/VUT/GtpVisibilityPreprocessor/src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
r225 r233 67 67 } 68 68 69 /****************************************************************/ 70 /* class BspLeaf implementation */ 71 /****************************************************************/ 72 73 BspLeaf::BspLeaf(ViewCell *viewCell): mViewCell(viewCell) 74 { 75 } 76 77 ViewCell *BspLeaf::GetViewCell() 78 { 79 return mViewCell; 80 } 81 82 bool BspLeaf::IsLeaf() const 83 { 84 return true; 85 } 86 87 /****************************************************************/ 88 /* class Polygon implementation */ 89 /****************************************************************/ 90 91 Polygon::Polygon() 92 {} 93 94 Polygon::Polygon(const VertexContainer &vertices): mVertices(vertices) 95 {} 96 97 Polygon::Polygon(Face *face, Mesh *parent) 98 { 99 VertexIndexContainer::const_iterator it; 100 101 for (it = face->mVertexIndices.begin(); it != face->mVertexIndices.end(); ++ it) 102 { 103 mVertices.push_back(parent->mVertices[*it]); 104 } 105 } 106 107 Plane3 Polygon::GetSupportingPlane() 108 { 109 return Plane3(mVertices[0], mVertices[1], mVertices[2]); 110 } 111 112 void Polygon::DeletePolygons(PolygonQueue *polys) 113 { 114 // don't need to store polygon information = delete polygons 115 while(!polys->empty()) 69 void BspInterior::SplitPolygons(PolygonQueue *polys, PolygonQueue *frontPolys, PolygonQueue *backPolys) 70 { 71 while (!polys->empty()) 116 72 { 117 73 Polygon *poly = polys->front(); 74 118 75 polys->pop(); 119 DEL_PTR(poly); 120 } 121 122 } 123 124 void Polygon::Split(Plane3 *partition, Polygon *front, Polygon *back) 125 { 126 Vector3 ptA = mVertices[mVertices.size() - 1];; 127 128 int sideA = partition->Side(ptA); 129 130 VertexContainer::const_iterator it; 131 132 // find line - plane intersections 133 for (it = mVertices.begin(); it != mVertices.end(); ++ it) 134 { 135 Vector3 ptB = (*it); 136 int sideB = partition->Side(ptB); 137 138 // vertices on different sides => split 139 if ((sideA != 0) && (sideB != 0) && (sideA != sideB)) 140 { 141 Vector3 v = ptB - ptA; // line from A to B 142 float dv = DotProd(partition->mNormal, v); 143 float t = 0; 144 145 if (dv) 146 { 147 t = - partition->Distance(ptA) / dv; 148 } 149 } 150 if (sideB >= 0) 151 { 152 back->mVertices.push_back(ptB); 153 } 154 else if (sideB <= 0) 155 { 156 front->mVertices.push_back(ptB); 157 } 158 159 ptA = ptB; 160 sideA = sideB; 161 } 162 } 163 164 int Polygon::Side(Plane3 *plane) 165 { 166 VertexContainer::const_iterator it; 167 168 bool onFrontSide = false; 169 bool onBackSide = false; 170 171 // find line - plane intersections 172 for (it = mVertices.begin(); it != mVertices.end(); ++ it) 173 { 174 int side = plane->Side(*it); 175 176 if (side > 0) 177 { 178 onFrontSide = true; 179 } 180 else if (side < 0) 181 { 182 onBackSide = true; 183 } 184 185 if (onFrontSide && onBackSide) // splits 186 return SPLIT; 187 } 188 189 if (onBackSide) 190 { 191 return BACK_SIDE; 192 } 193 else if (onFrontSide) 194 { 195 return FRONT_SIDE; 196 } 197 198 return COINCIDENT; 199 } 200 201 /****************************************************************/ 202 /* class BspTree implementation */ 203 /****************************************************************/ 204 205 BspTree::BspTree(const ViewCellContainer &viewCells): 206 mMaxPolys(0), mMaxDepth(0), mRoot(NULL) 207 { 208 //mRootCell = cell; 209 Subdivide(viewCells); 210 } 211 212 BspTree::BspTree(const ObjectContainer &objects, int maxPolys, int maxDepth): 213 mMaxPolys(maxPolys), mMaxDepth(maxDepth) 214 { 215 mRoot = new BspLeaf(); 216 217 Subdivide(objects); 218 } 219 220 BspTree::~BspTree() 221 { 222 std::stack<BspNode *> tStack; 223 224 tStack.push(mRoot); 225 226 while (!tStack.empty()) 227 { 228 BspNode *node = tStack.top(); 229 230 tStack.pop(); 231 232 if (!node->IsLeaf()) 233 { 234 BspInterior *interior = dynamic_cast<BspInterior *>(node); 235 236 // push the children on the stack (there are always two children) 237 interior->GetBack()->mParent = NULL; 238 interior->GetFront()->mParent = NULL; 239 240 tStack.push(interior->GetBack()); 241 tStack.push(interior->GetFront()); 242 } 243 244 DEL_PTR(node); 245 } 246 } 247 248 249 void BspTree::InsertViewCell(ViewCell *viewCell) 250 { 251 std::stack<BspTraversalData> tStack; 252 253 PolygonQueue polys; 254 // copy polygon information to guide the split process 255 CopyMesh2Polygon(viewCell->GetMesh(), polys); 256 257 tStack.push(BspTraversalData(mRoot, NULL, &polys, 0)); 258 259 while (!tStack.empty()) 260 { 261 /*BspNode *node = tStack.top(); 262 263 tStack.pop(); 264 265 if (!node->IsLeaf()) 266 { 267 BspInterior *interior = dynamic_cast<BspInterior *>(node); 268 269 // push the children on the stack (there are always two children) 270 interior->GetBack()->mParent = NULL; 271 interior->GetFront()->mParent = NULL; 272 273 tStack.push(interior->GetBack()); 274 tStack.push(interior->GetFront()); 275 } 276 277 DEL_PTR(node);*/ 278 } 279 /* BspNode *currentNode = mRoot; 280 281 std::stack<BspTraversalData> tStack; 282 // stack<STraversalData> tStack; 283 284 //tStack.push(tdata); 285 286 while (!tStack.empty()) 287 { 288 BspTraversalData data = tStack.top(); 289 290 tStack.pop(); 291 292 Mesh backPolys; 293 Mesh frontPolys; 294 295 if (data.mNode->IsLeaf()) // if we have a leaf => subdivide 296 { 297 BspNode *node = SubdivideNode(dynamic_cast<BspLeaf *>(data.mNode), 298 data.mParent, 299 data.mPolys, 300 data.mDepth, 301 backPolys, 302 frontPolys); 303 304 if (!node->IsLeaf()) // node was subdivided 305 { 306 BspInterior *interior = dynamic_cast<BspInterior *>(node); 307 308 // push the children on the stack (there are always two children) 309 //tStack.push(BspTraversalData(interior->GetBack(), interior, backPolys, data.mDepth + 1)); 310 //tStack.push(BspTraversalData(interior->GetFront(), interior, frontPolys, data.mDepth + 1)); 311 } 312 } 313 }*/ 314 } 315 316 void BspTree::Subdivide(const ViewCellContainer &viewCells) 317 { 318 } 319 320 void BspTree::CopyMesh2Polygon(Mesh *mesh, PolygonQueue &polys) 321 { 322 FaceContainer::const_iterator fi; 323 // copy the face data to polygons 324 for (fi = mesh->mFaces.begin(); fi != mesh->mFaces.end(); ++ fi) 325 { 326 Polygon *poly = new Polygon((*fi), mesh); 327 polys.push(poly); 328 } 329 } 330 331 void BspTree::Copy2PolygonSoup(const ObjectContainer &objects, PolygonQueue &polys) 332 { 333 ObjectContainer::const_iterator it, it_end = objects.end(); 334 335 for (it = objects.begin(); it != it_end; ++ it) 336 { 337 Intersectable *object = *it; 338 339 // extract the mesh instances 340 if (object->Type() == Intersectable::MESH_INSTANCE) 341 { 342 MeshInstance *inst = dynamic_cast<MeshInstance *>(object); 343 344 Mesh *mesh = inst->GetMesh(); 345 346 // copy the mesh data to polygons 347 CopyMesh2Polygon(mesh, polys); 348 } 349 } 350 } 351 352 void BspTree::Subdivide(const ObjectContainer &objects) 353 { 354 std::stack<BspTraversalData> tStack; 355 PolygonQueue polys; 356 357 // copy mesh instance polygons into one big polygon soup 358 Copy2PolygonSoup(objects, polys); 359 360 BspTraversalData tdata(mRoot, mRoot->GetParent(), &polys, 0); 361 tStack.push(tdata); 362 363 while (!tStack.empty()) 364 { 365 BspTraversalData data = tStack.top(); 366 367 tStack.pop(); 368 369 PolygonQueue *backPolys = new PolygonQueue(); 370 PolygonQueue *frontPolys = new PolygonQueue(); 371 372 BspNode *node = SubdivideNode(dynamic_cast<BspLeaf *>(data.mNode), 373 data.mParent, 374 data.mPolys, 375 data.mDepth, 376 backPolys, 377 frontPolys); 378 379 if (!node->IsLeaf()) // node was subdivided 380 { 381 BspInterior *interior = dynamic_cast<BspInterior *>(node); 382 383 // push the children on the stack (there are always two children) 384 tStack.push(BspTraversalData(interior->GetBack(), interior, backPolys, data.mDepth + 1)); 385 tStack.push(BspTraversalData(interior->GetFront(), interior, frontPolys, data.mDepth + 1)); 386 } 387 } 388 } 389 390 Plane3 BspTree::SelectPlane(PolygonQueue *polyQueue) 391 { 392 // TODO: more sophisticated criteria 393 return polyQueue->front()->GetSupportingPlane(); 394 } 395 396 BspNode *BspTree::SubdivideNode(BspLeaf *leaf, BspInterior *parent, 397 PolygonQueue *polys, const int depth, 398 PolygonQueue *frontPolys, PolygonQueue *backPolys) 399 { 400 // terminate traversal if no more faces in mesh 401 if ((polys->size() <= mMaxPolys) || (depth >= mMaxDepth)) 402 { 403 // don't need to store polygon information = delete polygons 404 Polygon::DeletePolygons(polys); 405 406 return leaf; 407 } 408 409 // add the new nodes to the tree + select subdivision plane 410 BspInterior *node = new BspInterior(SelectPlane(polys)); 411 412 while (!polys->empty()) 413 { 414 Polygon *poly = polys->front(); 415 416 polys->pop(); 417 418 int result = 0;// = node->GetPlane()->Side(node->GetPlane()); 76 77 int result = poly->Side(&mPlane); 419 78 420 79 Polygon *front_piece = NULL; … … 424 83 { 425 84 case Polygon::COINCIDENT: 85 break; 426 86 case Polygon::FRONT_SIDE: 427 87 frontPolys->push(poly); … … 435 95 436 96 //-- split polygon 437 poly->Split(node->GetPlane(), front_piece, back_piece); 438 97 poly->Split(&mPlane, front_piece, back_piece); 439 98 440 99 backPolys->push(back_piece); … … 445 104 break; 446 105 default: 447 frontPolys->push(poly);448 106 break; 449 107 } 450 108 } 451 452 // backside of convex view cell polygon => outside 109 // delete old polygons 110 Polygon::DeletePolygons(polys); 111 } 112 113 /****************************************************************/ 114 /* class BspLeaf implementation */ 115 /****************************************************************/ 116 117 BspLeaf::BspLeaf(ViewCell *viewCell): mViewCell(viewCell) 118 { 119 } 120 121 ViewCell *BspLeaf::GetViewCell() 122 { 123 return mViewCell; 124 } 125 126 bool BspLeaf::IsLeaf() const 127 { 128 return true; 129 } 130 131 /****************************************************************/ 132 /* class Polygon implementation */ 133 /****************************************************************/ 134 135 Polygon::Polygon() 136 {} 137 138 Polygon::Polygon(const VertexContainer &vertices): mVertices(vertices) 139 {} 140 141 Polygon::Polygon(Face *face, Mesh *parent) 142 { 143 VertexIndexContainer::const_iterator it; 144 145 for (it = face->mVertexIndices.begin(); it != face->mVertexIndices.end(); ++ it) 146 { 147 mVertices.push_back(parent->mVertices[*it]); 148 } 149 } 150 151 Plane3 Polygon::GetSupportingPlane() 152 { 153 return Plane3(mVertices[0], mVertices[1], mVertices[2]); 154 } 155 156 void Polygon::DeletePolygons(PolygonQueue *polys) 157 { 158 // don't need to store polygon information = delete polygons 159 while(!polys->empty()) 160 { 161 Polygon *poly = polys->front(); 162 polys->pop(); 163 DEL_PTR(poly); 164 } 165 } 166 167 void Polygon::Split(Plane3 *partition, Polygon *front, Polygon *back) 168 { 169 Vector3 ptA = mVertices[mVertices.size() - 1];; 170 171 int sideA = partition->Side(ptA); 172 173 VertexContainer::const_iterator it; 174 175 // find line - plane intersections 176 for (it = mVertices.begin(); it != mVertices.end(); ++ it) 177 { 178 Vector3 ptB = (*it); 179 int sideB = partition->Side(ptB); 180 181 // vertices on different sides => split 182 if ((sideA != 0) && (sideB != 0) && (sideA != sideB)) 183 { 184 Vector3 v = ptB - ptA; // line from A to B 185 float dv = DotProd(partition->mNormal, v); 186 float t = 0; 187 188 if (dv) 189 { 190 t = - partition->Distance(ptA) / dv; 191 } 192 } 193 if (sideB >= 0) 194 { 195 back->mVertices.push_back(ptB); 196 } 197 else if (sideB <= 0) 198 { 199 front->mVertices.push_back(ptB); 200 } 201 202 ptA = ptB; 203 sideA = sideB; 204 } 205 } 206 207 int Polygon::Side(Plane3 *plane) 208 { 209 VertexContainer::const_iterator it; 210 211 bool onFrontSide = false; 212 bool onBackSide = false; 213 214 // find line - plane intersections 215 for (it = mVertices.begin(); it != mVertices.end(); ++ it) 216 { 217 int side = plane->Side(*it); 218 219 if (side > 0) 220 { 221 onFrontSide = true; 222 } 223 else if (side < 0) 224 { 225 onBackSide = true; 226 } 227 228 if (onFrontSide && onBackSide) // splits 229 return SPLIT; 230 } 231 232 if (onBackSide) 233 { 234 return BACK_SIDE; 235 } 236 else if (onFrontSide) 237 { 238 return FRONT_SIDE; 239 } 240 241 return COINCIDENT; 242 } 243 244 /****************************************************************/ 245 /* class BspTree implementation */ 246 /****************************************************************/ 247 248 BspTree::BspTree(const ViewCellContainer &viewCells): 249 mMaxPolys(0), mMaxDepth(0), mRoot(NULL) 250 { 251 //mRootCell = cell; 252 Subdivide(viewCells); 253 } 254 255 BspTree::BspTree(const ObjectContainer &objects, int maxPolys, int maxDepth): 256 mMaxPolys(maxPolys), mMaxDepth(maxDepth) 257 { 258 mRoot = new BspLeaf(); 259 260 Subdivide(objects); 261 } 262 263 BspTree::~BspTree() 264 { 265 std::stack<BspNode *> tStack; 266 267 tStack.push(mRoot); 268 269 while (!tStack.empty()) 270 { 271 BspNode *node = tStack.top(); 272 273 tStack.pop(); 274 275 if (!node->IsLeaf()) 276 { 277 BspInterior *interior = dynamic_cast<BspInterior *>(node); 278 279 // push the children on the stack (there are always two children) 280 interior->GetBack()->mParent = NULL; 281 interior->GetFront()->mParent = NULL; 282 283 tStack.push(interior->GetBack()); 284 tStack.push(interior->GetFront()); 285 } 286 287 DEL_PTR(node); 288 } 289 } 290 291 292 void BspTree::InsertViewCell(ViewCell *viewCell) 293 { 294 std::stack<BspTraversalData> tStack; 295 296 PolygonQueue polys; 297 // copy polygon information to guide the split process 298 CopyMesh2Polygon(viewCell->GetMesh(), polys); 299 300 tStack.push(BspTraversalData(mRoot, NULL, &polys, 0, viewCell)); 301 302 while (!tStack.empty()) 303 { 304 // filter polygons donw the tree 305 BspTraversalData tData = tStack.top(); 306 307 tStack.pop(); 308 309 if (!tData.mNode->IsLeaf()) 310 { 311 BspInterior *interior = dynamic_cast<BspInterior *>(tData.mNode); 312 313 // filter polygons down the tree. 314 PolygonQueue *frontPolys = new PolygonQueue(); 315 PolygonQueue *backPolys = new PolygonQueue(); 316 317 interior->SplitPolygons(tData.mPolys, frontPolys, backPolys); 318 319 // push the children on the stack 320 if (frontPolys->size() > 0) 321 tStack.push(BspTraversalData(interior->GetFront(), interior->GetParent(), frontPolys, tData.mDepth + 1)); 322 else 323 delete frontPolys; 324 325 if (backPolys > 0) 326 tStack.push(BspTraversalData(interior->GetBack(), interior->GetParent(), backPolys, tData.mDepth + 1)); // TODO: really need to keep viewcell?? 327 else 328 delete backPolys; 329 } 330 else // reached leaf and must split 331 { 332 BuildTree(tStack, tData); 333 } 334 } 335 /* BspNode *currentNode = mRoot; 336 337 std::stack<BspTraversalData> tStack; 338 // stack<STraversalData> tStack; 339 340 //tStack.push(tdata); 341 342 while (!tStack.empty()) 343 { 344 BspTraversalData data = tStack.top(); 345 346 tStack.pop(); 347 348 Mesh backPolys; 349 Mesh frontPolys; 350 351 if (data.mNode->IsLeaf()) // if we have a leaf => subdivide 352 { 353 BspNode *node = SubdivideNode(dynamic_cast<BspLeaf *>(data.mNode), 354 data.mParent, 355 data.mPolys, 356 data.mDepth, 357 data.viewCell, 358 backPolys, 359 frontPolys); 360 361 if (!node->IsLeaf()) // node was subdivided 362 { 363 BspInterior *interior = dynamic_cast<BspInterior *>(node); 364 365 // push the children on the stack (there are always two children) 366 //tStack.push(BspTraversalData(interior->GetBack(), interior, backPolys, data.mDepth + 1)); 367 //tStack.push(BspTraversalData(interior->GetFront(), interior, frontPolys, data.mDepth + 1)); 368 } 369 } 370 }*/ 371 } 372 373 void BspTree::Subdivide(const ViewCellContainer &viewCells) 374 { 375 } 376 377 void BspTree::CopyMesh2Polygon(Mesh *mesh, PolygonQueue &polys) 378 { 379 FaceContainer::const_iterator fi; 380 // copy the face data to polygons 381 for (fi = mesh->mFaces.begin(); fi != mesh->mFaces.end(); ++ fi) 382 { 383 Polygon *poly = new Polygon((*fi), mesh); 384 polys.push(poly); 385 } 386 } 387 388 void BspTree::Copy2PolygonSoup(const ObjectContainer &objects, PolygonQueue &polys) 389 { 390 ObjectContainer::const_iterator it, it_end = objects.end(); 391 392 for (it = objects.begin(); it != it_end; ++ it) 393 { 394 Intersectable *object = *it; 395 396 // extract the mesh instances 397 if (object->Type() == Intersectable::MESH_INSTANCE) 398 { 399 MeshInstance *inst = dynamic_cast<MeshInstance *>(object); 400 401 Mesh *mesh = inst->GetMesh(); 402 403 // copy the mesh data to polygons 404 CopyMesh2Polygon(mesh, polys); 405 } 406 } 407 } 408 409 void BspTree::Subdivide(const ObjectContainer &objects) 410 { 411 std::stack<BspTraversalData> tStack; 412 PolygonQueue *polys = new PolygonQueue(); 413 414 // copy mesh instance polygons into one big polygon soup 415 Copy2PolygonSoup(objects, *polys); 416 417 BspTraversalData tData(mRoot, mRoot->GetParent(), polys, 0, NULL); 418 tStack.push(tData); 419 420 while (!tStack.empty()) 421 { 422 tData = tStack.top(); 423 424 tStack.pop(); 425 426 BuildTree(tStack, tData); 427 } 428 } 429 430 void BspTree::BuildTree(BspTraversalStack &tStack, BspTraversalData ¤tData) 431 { 432 PolygonQueue *backPolys = new PolygonQueue(); 433 PolygonQueue *frontPolys = new PolygonQueue(); 434 435 BspNode *node = SubdivideNode(dynamic_cast<BspLeaf *>(currentData.mNode), 436 currentData.mParent, 437 currentData.mPolys, 438 currentData.mDepth, 439 currentData.mViewCell, 440 backPolys, 441 frontPolys); 442 443 if (!node->IsLeaf()) // node was subdivided 444 { 445 BspInterior *interior = dynamic_cast<BspInterior *>(node); 446 447 // push the children on the stack (there are always two children) 448 tStack.push(BspTraversalData(interior->GetBack(), interior, backPolys, currentData.mDepth + 1, NULL)); 449 tStack.push(BspTraversalData(interior->GetFront(), interior, frontPolys, currentData.mDepth + 1, currentData.mViewCell)); 450 } 451 } 452 453 Plane3 BspTree::SelectPlane(PolygonQueue *polyQueue) 454 { 455 // TODO: more sophisticated criteria 456 return polyQueue->front()->GetSupportingPlane(); 457 } 458 459 BspNode *BspTree::SubdivideNode(BspLeaf *leaf, 460 BspInterior *parent, 461 PolygonQueue *polys, 462 const int depth, 463 ViewCell *viewCell, 464 PolygonQueue *frontPolys, 465 PolygonQueue *backPolys) 466 { 467 // terminate traversal if no more faces in mesh 468 if ((polys->size() <= mMaxPolys) || (depth >= mMaxDepth)) 469 { 470 // don't need to store polygon information = delete polygons 471 Polygon::DeletePolygons(polys); 472 473 return leaf; 474 } 475 476 // add the new nodes to the tree + select subdivision plane 477 BspInterior *node = new BspInterior(SelectPlane(polys)); 478 479 // split polygon according to current plane 480 node->SplitPolygons(polys, frontPolys, backPolys); 481 482 // two new leaves 453 483 BspLeaf *back = new BspLeaf(); 454 BspLeaf *front = new BspLeaf( );484 BspLeaf *front = new BspLeaf(viewCell); 455 485 456 486 // replace a link from node's parent … … 467 497 return node; 468 498 } 469 470 499 //} // GtpVisibilityPreprocessor -
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.h
r225 r233 5 5 #include "Containers.h" 6 6 #include <queue> 7 #include <stack> 7 8 8 9 class ViewCell; … … 15 16 class Polygon; 16 17 17 /** 18 BspNode abstract class serving for interior and leaf node implementation 19 */ 20 class BspNode 21 { 22 friend BspTree; 23 24 public: 25 /** Determines whether this node is a leaf or not 26 @return true if leaf 27 */ 28 virtual bool IsLeaf() const = 0; 29 30 /** Determines whether this node is a root 31 @return true if root 32 */ 33 virtual bool IsRoot() const; 34 35 /** Returns parent node. 36 */ 37 BspInterior *GetParent(); 38 39 protected: 40 41 /// parent of this node 42 BspInterior *mParent; 43 }; 44 45 /** BSP interior node implementation 46 */ 47 class BspInterior : public BspNode 48 { 49 public: 50 /** Standard contructor taking split plane as argument. 51 */ 52 BspInterior(Plane3 plane); 53 /** @return false since it is an interior node 54 */ 55 bool IsLeaf() const; 56 57 BspNode *GetBack(); 58 BspNode *GetFront(); 59 60 Plane3 *GetPlane(); 61 62 void ReplaceChildLink(BspNode *oldChild, BspNode *newChild); 63 void SetupChildLinks(BspNode *b, BspNode *f); 64 65 protected: 18 typedef std::queue<Polygon *> PolygonQueue; 19 20 /** 21 BspNode abstract class serving for interior and leaf node implementation 22 */ 23 class BspNode 24 { 25 friend BspTree; 26 27 public: 28 /** Determines whether this node is a leaf or not 29 @return true if leaf 30 */ 31 virtual bool IsLeaf() const = 0; 32 33 /** Determines whether this node is a root 34 @return true if root 35 */ 36 virtual bool IsRoot() const; 37 38 /** Returns parent node. 39 */ 40 BspInterior *GetParent(); 41 42 protected: 43 44 /// parent of this node 45 BspInterior *mParent; 46 }; 47 48 /** BSP interior node implementation 49 */ 50 class BspInterior : public BspNode 51 { 52 public: 53 /** Standard contructor taking split plane as argument. 54 */ 55 BspInterior(Plane3 plane); 56 /** @return false since it is an interior node 57 */ 58 bool IsLeaf() const; 59 60 BspNode *GetBack(); 61 BspNode *GetFront(); 62 63 Plane3 *GetPlane(); 64 65 void ReplaceChildLink(BspNode *oldChild, BspNode *newChild); 66 void SetupChildLinks(BspNode *b, BspNode *f); 67 68 /** Splits polygons. 69 @param polys the polygons to be split 70 @param frontPolys returns the polygons in the front of the split plane 71 @param backPolys returns the polygons in the back of the split plane 72 */ 73 void SplitPolygons(PolygonQueue *polys, PolygonQueue *frontPolys, PolygonQueue *backPolys); 74 75 protected: 76 77 /// Splitting plane corresponding to this node 78 Plane3 mPlane; 79 /// back node 80 BspNode *mBack; 81 /// front node 82 BspNode *mFront; 83 }; 84 85 86 /** BSP leaf node implementation */ 87 class BspLeaf : public BspNode 88 { 89 public: 90 BspLeaf(ViewCell *viewCell = NULL); 91 92 /** @return true since it is an interior node */ 93 bool IsLeaf() const; 94 ViewCell *GetViewCell(); 95 96 protected: 97 98 /// polygonal representation of this viewcell 99 /// if NULL this note does not correspond to feasible viewcell 100 ViewCell *mViewCell; 101 }; 102 103 104 /** Class representing a polygon. 105 */ 106 class Polygon 107 { 108 public: 109 Polygon(); 110 Polygon(const VertexContainer &vertices); 111 112 /** Copies all the vertices of the face. 113 */ 114 Polygon(Face *face, Mesh *parent); 115 116 /** Returns supporting plane of this polygon. 117 */ 118 Plane3 GetSupportingPlane(); 119 120 /** Splits polygon. 121 @param partition the split plane 122 @param front the front polygon 123 @param back the back polygon 124 */ 125 void Split(Plane3 *partition, Polygon *front, Polygon *back); 126 127 enum {BACK_SIDE, FRONT_SIDE, SPLIT, COINCIDENT}; 128 129 /** Side of the plane where the polygon is located. 130 @returns one of BACK_SIDE, FRONT_SIDE, SPLIT, COINCIDENT 131 */ 132 int Side(Plane3 *plane); 133 134 static void DeletePolygons(PolygonQueue *polys); 135 136 /// vertices are connected in counterclockwise order. 137 VertexContainer mVertices; 138 }; 139 140 /** Implementation of the ViewCell BSP tree. */ 141 class BspTree 142 { 143 public: 144 145 /** Additional data which is passed down the BSP tree during traversal. 146 */ 147 struct BspTraversalData 148 { 149 /// the current node 150 BspNode *mNode; 151 /// parent of current node 152 BspInterior *mParent; 153 /// polygonal data for splitting 154 PolygonQueue *mPolys; 155 /// current depth 156 int mDepth; 66 157 67 /// Splitting plane corresponding to this node 68 Plane3 mPlane; 69 /// back node 70 BspNode *mBack; 71 /// front node 72 BspNode *mFront; 73 }; 74 75 76 /** BSP leaf node implementation */ 77 class BspLeaf : public BspNode 78 { 79 public: 80 BspLeaf(ViewCell *viewCell = NULL); 81 82 /** @return true since it is an interior node */ 83 bool IsLeaf() const; 84 ViewCell *GetViewCell(); 85 86 protected: 87 88 /// polygonal representation of this viewcell 89 /// if NULL this note does not correspond to feasible viewcell 90 ViewCell *mViewCell; 91 }; 92 93 typedef std::queue<Polygon *> PolygonQueue; 94 95 /** Class representing a polygon. 96 */ 97 class Polygon 98 { 99 public: 100 Polygon(); 101 Polygon(const VertexContainer &vertices); 102 103 /** Copies all the vertices of the face. 104 */ 105 Polygon(Face *face, Mesh *parent); 106 107 /** Returns supporting plane of this polygon. 108 */ 109 Plane3 GetSupportingPlane(); 110 111 /** Splits polygon. 112 @param partition the split plane 113 @param front the front polygon 114 @param back the back polygon 115 */ 116 void Split(Plane3 *partition, Polygon *front, Polygon *back); 117 118 enum {BACK_SIDE, FRONT_SIDE, SPLIT, COINCIDENT}; 119 120 /** Side of the plane where the polygon is located. 121 @returns one of BACK_SIDE, FRONT_SIDE, SPLIT, COINCIDENT 122 */ 123 int Side(Plane3 *plane); 124 125 static void DeletePolygons(PolygonQueue *polys); 126 127 /// vertices are connected in counterclockwise order. 128 VertexContainer mVertices; 129 }; 130 131 /** Implementation of the ViewCell BSP tree. */ 132 class BspTree 133 { 134 public: 135 136 /** Additional data which is passed down the BSP tree during traversal. 137 */ 138 struct BspTraversalData 139 { 140 /// the current node 141 BspNode *mNode; 142 /// parent of current node 143 BspInterior *mParent; 144 /// polygonal data for splitting 145 PolygonQueue *mPolys; 146 /// current depth 147 int mDepth; 148 149 BspTraversalData() {} 150 151 BspTraversalData(BspNode *node, BspInterior *parent, PolygonQueue *polys, const int depth): 152 mNode(node), mParent(parent), mPolys(polys), mDepth(depth) {} 153 }; 154 155 156 /** Constructs BSP tree from list of view cells. 157 */ 158 BspTree(const ViewCellContainer &viewCells); 159 /** Constructs BSP tree from list of objects. 160 @param object list of intersectables 161 @param maxPolys maximal allowed number of polygons 162 @param maxDepth maximal allowed BSP tree depth 163 */ 164 BspTree(const ObjectContainer &objects, int maxPolys, int maxDepth); 165 166 ~BspTree(); 167 168 protected: 169 /** Selects a splitting plane from the given polygons. 170 */ 171 Plane3 SelectPlane(PolygonQueue *polyQueue); 172 173 /** Filters next viewcell down the tree and inserts it into the appropriate leaves 174 (i.e., possibly more than one leaf). 175 */ 176 void InsertViewCell(ViewCell *viewCell); 177 178 /** Subdivides tree according to the given list of viewcells. 179 */ 180 void Subdivide(const ViewCellContainer &viewCells); 181 /** Subdivides tree according to the given list of objects. 182 */ 183 void Subdivide(const ObjectContainer &objects); 184 185 /** Subdivides leaf. 186 @param leaf the leaf to be subdivided 187 @param parent the parent node of this leaf 188 @param polys the input polygons 189 @param depth the current tree depth 190 @param frontPolys the polygons of the front child node as a result from splitting 191 @param backPolys the polygons of the back child node as a result from splitting 192 */ 193 BspNode *SubdivideNode(BspLeaf *leaf, BspInterior *parent, 194 PolygonQueue *polys, const int depth, 195 PolygonQueue *frontPolys, PolygonQueue *backPolys); 196 197 /** Extracts the mesh instances of the objects and copies them into the mesh. 198 */ 199 static void Copy2PolygonSoup(const ObjectContainer &objects, PolygonQueue &polys); 200 201 static void CopyMesh2Polygon(Mesh *mesh, PolygonQueue &polys); 202 203 /// Pointer to the root of the tree 204 BspNode *mRoot; 205 /// Pointer to the root cell of the viewspace 206 // ViewCell *mRootCell; 207 /// maximal number of polygons allowed in leaf 208 int mMaxPolys; 209 /// maximal depth 210 int mMaxDepth; 211 }; 212 158 BspTraversalData() {} 159 160 BspTraversalData(BspNode *node, BspInterior *parent, PolygonQueue *polys, const int depth): 161 mNode(node), mParent(parent), mPolys(polys), mDepth(depth) {} 162 }; 163 164 typedef std::stack<BspTraversalData> BspTraversalStack; 165 166 /** Constructs BSP tree from list of view cells. 167 */ 168 BspTree(const ViewCellContainer &viewCells); 169 /** Constructs BSP tree from list of objects. 170 @param object list of intersectables 171 @param maxPolys maximal allowed number of polygons 172 @param maxDepth maximal allowed BSP tree depth 173 */ 174 BspTree(const ObjectContainer &objects, int maxPolys, int maxDepth); 175 176 ~BspTree(); 177 178 protected: 179 /** Builds a new extension of the tree. 180 */ 181 void BuildTree(BspTraversalStack &tStack, BspTraversalData ¤tData); 182 183 /** Selects a splitting plane from the given polygons. 184 */ 185 Plane3 SelectPlane(PolygonQueue *polyQueue); 186 187 /** Filters next viewcell down the tree and inserts it into the appropriate leaves 188 (i.e., possibly more than one leaf). 189 */ 190 void InsertViewCell(ViewCell *viewCell); 191 192 /** Subdivides tree according to the given list of viewcells. 193 */ 194 void Subdivide(const ViewCellContainer &viewCells); 195 /** Subdivides tree according to the given list of objects. 196 */ 197 void Subdivide(const ObjectContainer &objects); 198 199 /** Subdivides leaf. 200 @param leaf the leaf to be subdivided 201 @param parent the parent node of this leaf 202 @param polys the input polygons 203 @param depth the current tree depth 204 @param frontPolys the polygons of the front child node as a result from splitting 205 @param backPolys the polygons of the back child node as a result from splitting 206 */ 207 BspNode *SubdivideNode(BspLeaf *leaf, BspInterior *parent, 208 PolygonQueue *polys, const int depth, 209 ViewCell *viewCell, 210 PolygonQueue *frontPolys, PolygonQueue *backPolys); 211 212 /** Filters polygons down the tree. 213 @param node the current BSP node 214 @param polys the polygons to be filtered 215 @param frontPolys returns the polygons in front of the split plane 216 @param backPolys returns the polygons in the back of the split plane 217 */ 218 void FilterPolygons(BspInterior *node, PolygonQueue *polys, PolygonQueue *frontPolys, PolygonQueue *backPolys); 219 220 /** Extracts the mesh instances of the objects and copies them into the mesh. 221 */ 222 static void Copy2PolygonSoup(const ObjectContainer &objects, PolygonQueue &polys); 223 224 static void CopyMesh2Polygon(Mesh *mesh, PolygonQueue &polys); 225 226 /// Pointer to the root of the tree 227 BspNode *mRoot; 228 /// Pointer to the root cell of the viewspace 229 // ViewCell *mRootCell; 230 /// maximal number of polygons allowed in leaf 231 int mMaxPolys; 232 /// maximal depth 233 int mMaxDepth; 234 }; 235 213 236 //}; // GtpVisibilityPreprocessor 214 237
Note: See TracChangeset
for help on using the changeset viewer.