00001 #include <esg/spacesorting/BVH.h>
00002 #include <esg/spacesorting/BVDistRot.h>
00003 #include <esg/iterator/Iterator.h>
00004 #include <esg/iterator/IteratorBVH.h>
00005 #include <esg/InspectorBVH.h>
00006
00007 using namespace esg;
00008
00009 bool BVH::_append(SceneGraphObject* obj,
00010 Geometry* bv,
00011 Node* node,
00012 unsigned depth)
00013 {
00014 if (!node) return false;
00015
00016 if (node->leaf) {
00017 node->list->append(obj);
00018
00019 if (node->list->length() > _leafLimit && depth < _depthLimit) {
00020
00021 Node* newLeftLeaf = new Node;
00022 Node* newRightLeaf = new Node;
00023
00024 newRightLeaf->leaf = true;
00025
00026 newRightLeaf->list = _create_list();
00027
00028 (void) node->list->split(*(newRightLeaf->list), _splitStrategy);
00029
00030
00031 newRightLeaf->leftChild = newLeftLeaf;
00032 newRightLeaf->rightChild = node->rightChild;
00033 newRightLeaf->parent = node;
00034 newRightLeaf->sibling = newLeftLeaf;
00035 newRightLeaf->bv = _create_bv(*(newRightLeaf->list));
00036
00037 newLeftLeaf->leaf = true;
00038 newLeftLeaf->list = node->list;
00039 newLeftLeaf->leftChild = node->leftChild;
00040 newLeftLeaf->rightChild = newRightLeaf;
00041 newLeftLeaf->parent = node;
00042 newLeftLeaf->sibling = newRightLeaf;
00043 newLeftLeaf->bv = _create_bv(*(newLeftLeaf->list));
00044
00045 if (node->rightChild)
00046 node->rightChild->leftChild = newRightLeaf;
00047
00048 if (node->leftChild)
00049 node->leftChild->rightChild = newLeftLeaf;
00050
00051 node->leaf = false;
00052 node->list = NULL;
00053 node->leftChild = newLeftLeaf;
00054 node->rightChild = newRightLeaf;
00055 delete node->bv;
00056 node->bv = _create_bv(*(newLeftLeaf->bv),
00057 *(newRightLeaf->bv));
00058 if (_leftLeaf == node) _leftLeaf = node->leftChild;
00059 return true;
00060 }
00061 else
00062 return _enlarge_bv(&(node->bv), *bv);
00063 }
00064 else {
00065 double dist1 = bv->distance(*(node->leftChild->bv), NULL);
00066 double dist2 = bv->distance(*(node->rightChild->bv), NULL);
00067 bool bvChanged;
00068
00069 if (dist1 <= dist2)
00070 bvChanged = _append(obj, bv, node->leftChild, depth+1);
00071 else
00072 bvChanged = _append(obj, bv, node->rightChild, depth+1);
00073
00074 if (bvChanged) {
00075 Geometry* pNewBV = _create_bv(*(node->leftChild->bv),
00076 *(node->rightChild->bv));
00077 bvChanged = _enlarge_bv(&(node->bv), *pNewBV);
00078 delete pNewBV;
00079 }
00080
00081 return bvChanged;
00082 }
00083 }
00084
00085
00086 void BVH::_remove_leaf(Node* leaf)
00087 {
00088 if (!leaf->parent) {
00089 _leftLeaf = (_root = NULL);
00090 delete leaf->list;
00091 delete leaf->bv;
00092 delete leaf;
00093 return;
00094 }
00095
00096 Node* grandparent = leaf->parent->parent;
00097 Node* sibling;
00098
00099
00100 if (leaf->parent->leftChild == leaf)
00101 sibling = leaf->parent->rightChild;
00102 else
00103 sibling = leaf->parent->leftChild;
00104
00105 if (grandparent) {
00106
00107 if (grandparent->leftChild == leaf->parent)
00108 grandparent->leftChild = sibling;
00109 else
00110 grandparent->rightChild = sibling;
00111 sibling->parent = grandparent;
00112
00113
00114 if (sibling->leftChild == leaf)
00115 sibling->leftChild = leaf->leftChild;
00116 else
00117 sibling->rightChild = leaf->rightChild;
00118 } else {
00119 _root = sibling;
00120 sibling->parent = NULL;
00121 sibling->leftChild = NULL;
00122 sibling->rightChild = NULL;
00123 }
00124
00125
00126 delete leaf->parent->bv;
00127 delete leaf->parent;
00128 delete leaf->bv;
00129 delete leaf->list;
00130 delete leaf;
00131
00132
00133 for (Node* node = sibling->parent; node != NULL; node = node->parent) {
00134 delete node->bv;
00135 node->bv = _create_bv(*(node->leftChild->bv),
00136 *(node->rightChild->bv));
00137 }
00138
00139
00140 if (_leftLeaf == leaf) _leftLeaf = sibling;
00141 }
00142
00143 void BVH::_build_tree(Node* leaf, unsigned depth)
00144 {
00145 if (!leaf || !leaf->leaf || !leaf->list) return;
00146
00147
00148 if (leaf->list->length() <= _leafLimit || depth >= _depthLimit) {
00149 if (leaf->bv) delete leaf->bv;
00150 leaf->bv = _create_bv(*(leaf->list));
00151 return;
00152 }
00153
00154
00155
00156 Node* leftSibling = leaf->leftChild;
00157 Node* rightSibling = leaf->rightChild;
00158
00159 leaf->leftChild = new Node;
00160 leaf->rightChild = new Node;
00161 leaf->leftChild->sibling = leaf->rightChild;
00162 leaf->rightChild->sibling = leaf->leftChild;
00163
00164 leaf->leftChild->leaf = true;
00165 leaf->rightChild->leaf = true;
00166 leaf->leaf = false;
00167
00168 leaf->leftChild->list = _create_list();
00169 (void) leaf->list->split(*(leaf->leftChild->list), _splitStrategy);
00170 leaf->rightChild->list = leaf->list;
00171 leaf->list = NULL;
00172
00173 leaf->leftChild->parent = leaf;
00174 leaf->leftChild->rightChild = leaf->rightChild;
00175 leaf->leftChild->leftChild = leftSibling;
00176 if (leftSibling) leftSibling->rightChild = leaf->leftChild;
00177
00178 leaf->rightChild->parent = leaf;
00179 leaf->rightChild->leftChild = leaf->leftChild;
00180 leaf->rightChild->rightChild = rightSibling;
00181 if (rightSibling) rightSibling->leftChild = leaf->rightChild;
00182
00183
00184 if (_leftLeaf == leaf) _leftLeaf = leaf->leftChild;
00185
00186
00187 _build_tree(leaf->leftChild, depth+1);
00188 _build_tree(leaf->rightChild, depth+1);
00189
00190
00191 if (leaf->bv) delete leaf->bv;
00192 leaf->bv = _create_bv(*(leaf->leftChild->bv), *(leaf->rightChild->bv));
00193 }
00194
00195 void BVH::_destroy_tree(Node* node)
00196 {
00197 if (node->leaf) {
00198
00199
00200
00201
00202
00203
00204
00205
00206 delete node->list;
00207 } else {
00208 _destroy_tree(node->leftChild);
00209 _destroy_tree(node->rightChild);
00210 }
00211
00212 delete node->bv;
00213 delete node;
00214 }
00215
00216 void BVH::_rebuild_tree(Node* pNode)
00217 {
00218 delete pNode->bv;
00219 if (pNode->leaf)
00220 pNode->bv = _create_bv(*(pNode->list));
00221 else {
00222 _rebuild_tree(pNode->leftChild);
00223 _rebuild_tree(pNode->rightChild);
00224 pNode->bv = _create_bv(*(pNode->leftChild->bv),
00225 *(pNode->rightChild->bv));
00226 }
00227 }
00228
00229 Geometry* BVH::_create_bv(BVList& list)
00230 {
00231 List<SceneGraphObject> tmpList;
00232 SceneGraphObject* pObject = list.firstItem();
00233 while (pObject) {
00234 tmpList.append(pObject);
00235 pObject = list.nextItem();
00236 }
00237
00238 return _create_bv(tmpList);
00239 }
00240
00241 void BVH::_collision(Node * pMyNode, Geometry& bv,
00242 List<SceneGraphObject>* pList)
00243 {
00244 if (pMyNode->bv->separation(bv, NULL)) return;
00245
00246 if (pMyNode->leaf) {
00247 for (SceneGraphObject * pObj = pMyNode->list->firstItem();
00248 pObj;
00249 pObj = pMyNode->list->nextItem())
00250 {
00251 pList->append(pObj);
00252 }
00253 } else {
00254 _collision(pMyNode->leftChild, bv, pList);
00255 _collision(pMyNode->rightChild, bv, pList);
00256 }
00257 }
00258
00259 void BVH::_dump(const Node* pNode, const char* intent, const char* tab)
00260 {
00261 char* newIntent = new char [strlen(intent) + strlen(tab) + 2];
00262 newIntent = strcpy(newIntent, intent);
00263 newIntent = strcat(newIntent, " ");
00264 newIntent = strcat(newIntent, tab);
00265
00266 printf("%s bvhNode {\n", intent);
00267 if (pNode->bv) pNode->bv->dump(newIntent, tab);
00268 if (pNode->leaf && pNode->list) {
00269 for (SceneGraphObject * pObj = pNode->list->firstItem();
00270 pObj;
00271 pObj = pNode->list->nextItem())
00272 {
00273
00274 if (pObj->geometry()) pObj->geometry()->dump(newIntent,tab);
00275 }
00276 } else {
00277 _dump(pNode->leftChild, newIntent, tab);
00278 _dump(pNode->rightChild, newIntent, tab);
00279 }
00280 printf("%s }\n", intent);
00281 delete [] newIntent;
00282 }
00283
00284 DistRot* BVH::_create_dist_rot(BVH::Node * pNode)
00285 {
00286 return new BVDistRot(*(pNode->bv), _coordMat, _scaleRatio);
00287 }
00288
00289 void BVH::_dr_init(const Matrix4* pMyTr, const Matrix4* pHisTr, BVH* pPartner)
00290 {
00291 (pMyTr) ? _myTrMat.set(*pMyTr) : _myTrMat.setIdentity();
00292
00293 Matrix4 * m = multiTrans(pHisTr, pMyTr, _scaleRatio);
00294 if (m) {
00295 _coordMat.set(*m);
00296 delete m;
00297 } else {
00298 _coordMat.setIdentity();
00299 }
00300
00301 _pPartner = pPartner;
00302 }
00303
00304 void BVH::_dr_primitives(DRInfo& dr, Node* pNode, Vector3* pDir)
00305 {
00306
00307
00308
00309
00310 for (SceneGraphObject * pA = pNode->list->firstItem();
00311 pA;
00312 pA = pNode->list->nextItem())
00313 {
00314 Geometry * pGA = pA->geometry();
00315 if (!pGA) continue;
00316
00317 for (SceneGraphObject * pB = dr.pLeaf->list->firstItem();
00318 pB;
00319 pB = dr.pLeaf->list->nextItem())
00320 {
00321 Geometry * pGB = pB->geometry();
00322 if (!pGB) continue;
00323
00324 switch (dr.strategy) {
00325 case DRInfo::SEPARATION:
00326 if (! pGA->separation(*pGB, pDir)) {
00327 dr.minD = -MAXDOUBLE;
00328 if (dr.leafInMe) {
00329 dr.pLeafA = dr.pLeaf;
00330 dr.pLeafB = pNode;
00331 } else {
00332 dr.pLeafA = pNode;
00333 dr.pLeafB = dr.pLeaf;
00334 }
00335 return;
00336 }
00337 break;
00338 case DRInfo::DISTANCE:
00339 break;
00340 case DRInfo::POINT_COLLISION:
00341 break;
00342 }
00343 }
00344 }
00345 }
00346
00347 void BVH::_dr_leaf(DRInfo & dr, Node * pNode, unsigned depth)
00348 {
00349 if (pNode->leaf || depth >= dr.maxDepth) {
00350
00351
00352
00353
00354 Vector3* pDir = (dr.pDir) ? new Vector3() : NULL;
00355
00356
00357 double dL = dr.pDistRot->distance(*(pNode->bv), dr.minD, pDir);
00358
00359 if (dL < dr.minD) {
00360
00361 #ifdef ESG_COLLISION_HACK
00362 if (pNode->leaf) _dr_primitives(dr, pNode, pDir);
00363 #endif //ESG_COLLISION_HACK
00364
00365 dr.minD = dL;
00366
00367 if (dr.pDir) {
00368 Matrix3 rMat;
00369 Vector3 tVec, sVec;
00370
00371 dr.pDir->set(*pDir);
00372
00373 if (dr.leafInMe) {
00374 _coordMat.get(rMat, tVec, sVec);
00375 ESG_INVERSE_TR_DIR(rMat, *(dr.pDir), *(dr.pDir));
00376 _myTrMat.transform(*(dr.pDir));
00377 } else {
00378 _pPartner->_coordMat.get(rMat, tVec, sVec);
00379 ESG_INVERSE_TR_DIR(rMat, *(dr.pDir), *(dr.pDir));
00380 _pPartner->_myTrMat.transform(*(dr.pDir));
00381
00382 }
00383 }
00384
00385
00386 if (pNode->leaf) {
00387 if (dr.leafInMe) { dr.pLeafA= dr.pLeaf; dr.pLeafB=pNode; }
00388 else { dr.pLeafA=pNode; dr.pLeafB=dr.pLeaf; }
00389 }
00390 }
00391
00392 if (pDir) delete pDir;
00393
00394 } else {
00395
00396
00397 double dL=dr.pDistRot->distance(*(pNode->leftChild->bv), dr.minD,NULL);
00398 double dR=dr.pDistRot->distance(*(pNode->rightChild->bv),dr.minD,NULL);
00399
00400 if (dL < dR) {
00401 if (dL < dr.minD) {
00402 _dr_leaf(dr, pNode->leftChild, depth+1);
00403 if (dR < dr.minD) _dr_leaf(dr, pNode->rightChild, depth+1);
00404 }
00405 } else {
00406 if (dR < dr.minD) {
00407 _dr_leaf(dr, pNode->rightChild, depth+1);
00408 if (dL < dr.minD) _dr_leaf(dr, pNode->leftChild, depth+1);
00409 }
00410 }
00411 }
00412 }
00413
00414 void BVH::_dr_inner(DRInfo& dr, Node* pMyNode, Node* pHisNode, unsigned depth)
00415 {
00416 if (pHisNode->leaf || depth >= dr.hisMaxDepth) {
00417
00418
00419 dr.leafInMe = false;
00420 dr.pLeaf = pHisNode;
00421 dr.maxDepth = dr.myMaxDepth;
00422 _dr_leaf(dr, pMyNode, depth);
00423 return;
00424 }
00425
00426 if (pMyNode->leaf || depth >= dr.myMaxDepth) {
00427
00428
00429 DistRot * pDistRot = this->_create_dist_rot(pMyNode);
00430 dr.pDistRot = pDistRot;
00431 dr.leafInMe = true;
00432 dr.pLeaf = pMyNode;
00433 dr.maxDepth = dr.hisMaxDepth;
00434 _dr_leaf(dr, pHisNode, depth);
00435 delete pDistRot;
00436 return;
00437 }
00438
00439
00440
00441 double d[4], dd;
00442 int way;
00443 DistRot * pDistRotL = _pPartner->_create_dist_rot(pHisNode->leftChild);
00444 DistRot * pDistRotR = _pPartner->_create_dist_rot(pHisNode->rightChild);
00445
00446
00447 d[0] = pDistRotL->distance(*(pMyNode->leftChild->bv), dr.minD, NULL);
00448 d[1] = pDistRotR->distance(*(pMyNode->leftChild->bv), dr.minD, NULL);
00449 d[2] = pDistRotL->distance(*(pMyNode->rightChild->bv), dr.minD, NULL);
00450 d[3] = pDistRotR->distance(*(pMyNode->rightChild->bv), dr.minD, NULL);
00451
00452
00453
00454 do {
00455 way = -1;
00456 dd = dr.minD;
00457
00458
00459 for (int i = 0; i < 4; i++) if (d[i] < dd) { dd = d[i]; way = i; }
00460
00461
00462 switch (way) {
00463 case 0:
00464 dr.pDistRot = pDistRotL;
00465 _dr_inner(dr, pMyNode->leftChild, pHisNode->leftChild, depth+1);
00466 d[0] = FLT_MAX;
00467 break;
00468 case 1:
00469 dr.pDistRot = pDistRotR;
00470 _dr_inner(dr, pMyNode->leftChild, pHisNode->rightChild, depth+1);
00471 d[1] = FLT_MAX;
00472 break;
00473 case 2:
00474 dr.pDistRot = pDistRotL;
00475 _dr_inner(dr, pMyNode->rightChild, pHisNode->leftChild, depth+1);
00476 d[2] = FLT_MAX;
00477 break;
00478 case 3:
00479 dr.pDistRot = pDistRotR;
00480 _dr_inner(dr, pMyNode->rightChild, pHisNode->rightChild, depth+1);
00481 d[3] = FLT_MAX;
00482 break;
00483 }
00484 } while (way >= 0 && dr.minD > -MAXDOUBLE);
00485
00486 delete pDistRotL;
00487 delete pDistRotR;
00488 }
00489
00490 void BVH::_duplicate_attributes(const SDS& src)
00491 {
00492 SDS::_duplicate_attributes(src);
00493 _leafLimit = ((BVH&)src)._leafLimit;
00494 _depthLimit = ((BVH&)src)._depthLimit;
00495 _pPartner = NULL;
00496 _root = NULL;
00497 _leftLeaf = NULL;
00498 _scaleRatio = ((BVH&)src)._scaleRatio;
00499 _splitStrategy = ((BVH&)src)._splitStrategy;
00500 }
00501
00502
00503
00504
00505 BVH::BVH(unsigned ll, unsigned dl, bool delayBuild, BVList::SplitStrategy ss)
00506 : SDS(delayBuild)
00507 {
00508 _leafLimit = (ll > 0) ? ll : 1;
00509 _depthLimit = dl;
00510 _leftLeaf = NULL;
00511 _root = NULL;
00512 _pPartner = NULL;
00513 _scaleRatio = 1.0;
00514 _splitStrategy = ss;
00515 }
00516
00517 BVH::~BVH()
00518 {
00519 if (_root) _destroy_tree(_root);
00520 }
00521
00522 Iterator* BVH::createIterator()
00523 {
00524 return (Iterator*) new IteratorBVH(this);
00525 }
00526
00527 InspectorSDS* BVH::createInspector(unsigned level)
00528 {
00529 return new InspectorBVH(this, level);
00530 }
00531
00532 int BVH::append(SceneGraphObject* obj)
00533 {
00534 if (!obj) return 0;
00535
00536 if (!obj->tangible()) {
00537 _intangibleChildren.append(obj);
00538 return 1;
00539 }
00540
00541 if (_delayBuild) {
00542 if (!_root) {
00543 _root = new Node;
00544 _root->leaf = true;
00545 _root->list = _create_list();
00546 _leftLeaf = _root;
00547 }
00548 _root->list->append(obj);
00549 } else {
00550 if (_root) {
00551 Geometry* bv = _create_bv(*obj);
00552 (void) _append(obj, bv, _root, 0);
00553 delete bv;
00554 } else {
00555 _root = new Node;
00556 _root->bv = _create_bv(*obj);
00557 _root->leaf = true;
00558 _root->list = _create_list();
00559 _root->list->append(obj);
00560 _leftLeaf = _root;
00561 }
00562 }
00563
00564 return 1;
00565 }
00566
00567 SceneGraphObject* BVH::detach(SceneGraphObject::OID oid)
00568 {
00569 for (Node* node = _leftLeaf; node != NULL; node = node->rightChild) {
00570 SceneGraphObject* obj = node->list->firstItem();
00571 while (obj) {
00572 if (obj->getOID() == oid) {
00573 SceneGraphObject* retObj = node->list->remove(obj);
00574 if (node->list->length() == 0) _remove_leaf(node);
00575 else {
00576 delete node->bv;
00577 node->bv = _create_bv(*(node->list));
00578 }
00579 return retObj;
00580 }
00581 obj = node->list->nextItem();
00582 }
00583 }
00584 return NULL;
00585 }
00586
00587 bool BVH::update()
00588 {
00589 if (_delayBuild) return false;
00590 if (_root) _rebuild_tree(_root);
00591 return true;
00592 }
00593
00594 bool BVH::build()
00595 {
00596 if (!_delayBuild) return false;
00597 if (!_root) return false;
00598 _build_tree(_root, 0);
00599 _delayBuild = false;
00600 return true;
00601 }
00602
00603 double BVH::distance(Matrix4 * pTrMy,
00604 BVH& bvhB,
00605 Matrix4 * pTrB,
00606 Node ** ppMinA,
00607 Node ** ppMinB,
00608 Vector3 * pDir,
00609 unsigned d1,
00610 unsigned d2)
00611 {
00612 if (_delayBuild || bvhB._delayBuild) return -MAXDOUBLE;
00613 if (!_root || !bvhB._root) return -MAXDOUBLE;
00614 if (!_root->bv || !bvhB._root->bv) return -MAXDOUBLE;
00615
00616 DRInfo dr;
00617 dr.strategy = DRInfo::DISTANCE;
00618 dr.pDir = pDir;
00619 dr.pLeafA = NULL;
00620 dr.pLeafB = NULL;
00621 dr.minD = FLT_MAX;
00622 dr.myMaxDepth = d1;
00623 dr.hisMaxDepth = d2;
00624
00625 this->_dr_init(pTrMy, pTrB, &bvhB);
00626 bvhB._dr_init(pTrB, pTrMy, this);
00627
00628
00629 if (ppMinA && ppMinB) {
00630 DistRot * pDRot = bvhB._create_dist_rot(*ppMinB);
00631 dr.minD = pDRot->distance(*((*ppMinA)->bv), FLT_MAX, pDir);
00632 delete pDRot;
00633 }
00634
00635 DistRot * pDistRot = bvhB._create_dist_rot(bvhB._root);
00636 dr.pDistRot = pDistRot;
00637
00638
00639
00640
00642 _dr_inner(dr, _root, bvhB._root, 0);
00643
00644 if (ppMinA && ppMinB) { *ppMinA = dr.pLeafA; *ppMinB = dr.pLeafB; }
00645
00646 delete pDistRot;
00647
00648 return dr.minD;
00649 }
00650
00651 bool BVH::separation(Matrix4* pTrMy,
00652 BVH& bvhB,
00653 Matrix4* pTrB,
00654 Vector3* pDir,
00655 unsigned d1,
00656 unsigned d2)
00657 {
00658 if (_delayBuild || bvhB._delayBuild) return true;
00659 if (!_root || !bvhB._root) return true;
00660 if (!_root->bv || !bvhB._root->bv) return true;
00661
00662 DRInfo dr;
00663 dr.strategy = DRInfo::SEPARATION;
00664 dr.pDir = pDir;
00665
00666 this->_dr_init(pTrMy, pTrB, &bvhB);
00667 bvhB._dr_init(pTrB, pTrMy, this);
00668
00669 dr.minD = 0;
00670 dr.pLeafA = NULL;
00671 dr.pLeafB = NULL;
00672 dr.myMaxDepth = d1;
00673 dr.hisMaxDepth = d2;
00674
00675 DistRot * pDistRot = bvhB._create_dist_rot(bvhB._root);
00676 dr.pDistRot = pDistRot;
00677
00678
00679 if (!dr.pDistRot->separation(*(_root->bv), NULL))
00680 _dr_inner(dr, _root, bvhB._root, 0);
00681
00682 delete pDistRot;
00683
00684 return (dr.minD >= 0.);
00685 }
00686
00687 Geometry** BVH::collision(Matrix4 * pTrMy,
00688 float x,
00689 float y,
00690 float z,
00691 float radius,
00692 int * numLeaves)
00693 {
00694
00695 Geometry * pBV;
00696 List<SceneGraphObject> list;
00697
00698 *numLeaves = 0;
00699
00700 if (_delayBuild) return NULL;
00701 if (!_root) return NULL;
00702 if (!_root->bv) return NULL;
00703
00704 if (pTrMy) {
00705 Vector3 point(x,y,z);
00706 Matrix4 * pTrMat = multiTrans(pTrMy, NULL, _scaleRatio);
00707 pTrMat->transform(point);
00708 Sphere sphere(point.x, point.y, point.z, radius);
00709
00710
00711 pBV = _create_bv(sphere, sphere);
00712 } else {
00713 Sphere sphere(x, y, z, radius);
00714 pBV = _create_bv(sphere, sphere);
00715 }
00716
00717 if (!pBV) return NULL;
00718
00719 _collision(_root, *pBV, &list);
00720
00721 *numLeaves = list.length();
00722 if (*numLeaves == 0) return NULL;
00723
00724 Geometry** array = new Geometry* [*numLeaves];
00725 unsigned i = 0;
00726 for (SceneGraphObject * pObj = list.firstItem();
00727 pObj;
00728 pObj = list.nextItem())
00729 {
00730 array[i] = pObj->geometry();
00731 if (!array[i]) (*numLeaves)--;
00732 else i++;
00733 }
00734
00735 delete pBV;
00736 return array;
00737 }
00738
00739 void BVH::dump(const char* intent, const char* tab)
00740 {
00741 char* newIntent = new char [strlen(intent) + strlen(tab) + 2];
00742 newIntent = strcpy(newIntent, intent);
00743 newIntent = strcat(newIntent, " ");
00744 newIntent = strcat(newIntent, tab);
00745
00746 printf("%s spacialDataStructure BVH {\n", intent);
00747 printf("%s %s leafLimit %d\n", intent, tab, _leafLimit);
00748 printf("%s %s depthLimit %d\n", intent, tab, _depthLimit);
00749 printf("%s %s treeDepth %d\n", intent, tab, _treeDepth);
00750 printf("%s %s splitMode ", intent, tab);
00751 switch (_splitStrategy) {
00752 case BVList::SPLIT_BY_MAX_VARIATION: printf("MAX_VARIATION\n"); break;
00753 case BVList::SPLIT_BY_MAX_EXTENT: printf("MAX_EXTENT\n"); break;
00754 default: printf("UNKNOWN\n"); break;
00755 }
00756 _dump(_root, newIntent, tab);
00757 printf("%s }\n", intent);
00758 delete [] newIntent;
00759 }
00760
00761
00762 void BVH::__debug() {
00763 fprintf(stderr,"BVH Debugging:\n");
00764
00765 if (_root) __debug(_root,0);
00766 else fprintf(stderr,"BVH: No structure\n");
00767 }
00768
00769 void BVH::__debug(Node* n, int d) {
00770 if (!n) return;
00771 for (int i=0;i<d;i++) fprintf(stderr," ");
00772 n->bv->__debug();
00773 if (n->leaf) {
00774 for (int i=0;i<d;i++) fprintf(stderr," ");
00775 n->list->__debug();
00776 } else {
00777 __debug(n->leftChild,d+1);
00778 __debug(n->rightChild,d+1);
00779 }
00780 }
00781
00782 void BVH::__get_edges(Matrix4 * pTrMat,
00783 Node* pNode,
00784 unsigned level,
00785 unsigned maxLevel,
00786 int rot,
00787 float* array,
00788 unsigned& size)
00789 {
00790 if (pNode->leaf || level >= maxLevel) {
00791 Vector3 v;
00792 Geometry * pGeom;
00793
00794 if (rot == 1) pGeom = (Geometry*) pNode->bv->clone(pTrMat);
00795 else if (rot == 2) pGeom = (Geometry*) pNode->bv->clone(&_coordMat);
00796 else pGeom = (Geometry*) pNode->bv->clone();
00797
00798 if (!pGeom) {
00799 fprintf(stderr,"BVH::__get_edges(): Clonning of BV failed\n");
00800 return;
00801 }
00802
00803 Mesh * pMesh = pGeom->mesh(0);
00804 if (!pMesh) { delete pGeom; return; }
00805
00806 pMesh->resetActSolid();
00807 do {
00808 pMesh->resetEdgeWalkInSolid();
00809 do {
00810 v.set(pMesh->getActVert1(false));
00811 array[size++] = v.x;
00812 array[size++] = v.y;
00813 array[size++] = v.z;
00814 v.set(pMesh->getActVert2(false));
00815 array[size++] = v.x;
00816 array[size++] = v.y;
00817 array[size++] = v.z;
00818 } while (pMesh->stepInEdgeWalkInSolid());
00819 } while (pMesh->goToNextSolid());
00820
00821 delete pMesh;
00822 delete pGeom;
00823 return;
00824 }
00825
00826 if (pNode->leaf) return;
00827
00828 __get_edges(pTrMat, pNode->leftChild, level+1, maxLevel, rot, array, size);
00829 __get_edges(pTrMat, pNode->rightChild,level+1, maxLevel, rot, array, size);
00830 }
00831
00832 float* BVH::__getEdges(Matrix4 * pMyTr,
00833 unsigned level,
00834 int rot,
00835 unsigned& size)
00836 {
00837 size = 0;
00838 if (!_root) return NULL;
00839
00840 float * array = new float[100000];
00841
00842 __get_edges(pMyTr, _root, 0, level, rot, array, size);
00843 return array;
00844 }
00845
00846 void BVH::__get_meshes(Matrix4 * pTrMat,
00847 Node* pNode,
00848 unsigned level,
00849 unsigned maxLevel,
00850 int rot,
00851 Mesh** array,
00852 unsigned& size)
00853 {
00854 if (pNode->leaf || level >= maxLevel) {
00855 Vector3 v;
00856 Geometry * pGeom;
00857 if (rot == 1) pGeom = (Geometry*) pNode->bv->clone(pTrMat);
00858 else if (rot == 2) pGeom = (Geometry*) pNode->bv->clone(&_coordMat);
00859 else pGeom = (Geometry*) pNode->bv->clone();
00860 array[size++] = pGeom->mesh(0);
00861 delete pGeom;
00862 return;
00863 }
00864
00865 if (pNode->leaf) return;
00866
00867 __get_meshes(pTrMat, pNode->leftChild, level+1, maxLevel, rot, array,size);
00868 __get_meshes(pTrMat, pNode->rightChild,level+1, maxLevel, rot, array,size);
00869 }
00870
00871 Mesh** BVH::__getMeshes(Matrix4 * pMyTr,
00872 unsigned level,
00873 int rot,
00874 unsigned& size)
00875 {
00876 Mesh ** array = new Mesh* [10000];
00877 size = 0;
00878 __get_meshes(pMyTr, _root, 0, level, rot, array, size);
00879 return array;
00880 }
00881
00882
00883
00884
00885
00886
00887
00888
00889