00001 #include <esg/iterator/IteratorBVH.h>
00002 #include <esg/Statistics.h>
00003
00004 using namespace esg;
00005
00006 #ifdef ESG_STATISTICS
00007 #define BVH_INC_TEST { _bvTestsCounter++; }
00008 #define BVH_INC_SUC_TEST { _bvTestsSucCounter++; }
00009 #define BVH_UPDATE_STAT { \
00010 ((Counter*)Statistics::instance()->get(Statistics::OID_BV_TESTS)->receptor())->add(_bvTestsCounter); \
00011 ((Counter*)Statistics::instance()->get(Statistics::OID_BV_TESTS_SUC)->receptor())->add(_bvTestsSucCounter); \
00012 _bvTestsCounter = (_bvTestsSucCounter = 0); \
00013 }
00014 #else
00015 #define BVH_INC_TEST {}
00016 #define BVH_INC_SUC_TEST {}
00017 #define BVH_UPDATE_STAT {}
00018 #endif // ESG_STATISTICS
00019
00020 #define BVH_BACKTRACK { \
00021 do { \
00022 pNode = _stack.back(); _stack.pop_back(); \
00023 BVH_INC_TEST; \
00024 pNode->bv->rayIntersection(&(_riAttr->iEnv), \
00025 ENV_WANT_INTERFERENCE|ENV_USE_CACHE, \
00026 _riAttr->origin, \
00027 _riAttr->direction, \
00028 _riAttr->distLimit); \
00029 if (!_riAttr->iEnv.mask & ENV_HAVE_INTERFERENCE) pNode = NULL; \
00030 else BVH_INC_SUC_TEST; \
00031 } while (!pNode && !_stack.empty()); \
00032 }
00033
00034
00035 SceneGraphObject* IteratorBVH::_first_ray_intersection(BVH::Node* pNode)
00036 {
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 while (pNode) {
00049 if (pNode->leaf) {
00050 _pLastUsedChild = pNode;
00051 return pNode->list->firstItem();
00052 }
00053
00054
00055 BVH_INC_TEST;
00056 pNode->leftChild->bv->rayIntersection(&(_riAttr->iEnv),
00057 ENV_WANT_INTERFERENCE|ENV_USE_CACHE,
00058 _riAttr->origin,
00059 _riAttr->direction,
00060 _riAttr->distLimit);
00061 if (_riAttr->iEnv.mask & ENV_HAVE_INTERFERENCE) {
00062 BVH_INC_SUC_TEST;
00063 _stack.push_back(pNode->rightChild);
00064 pNode = pNode->leftChild;
00065 continue;
00066 }
00067
00068 BVH_INC_TEST;
00069 pNode = pNode->rightChild;
00070 pNode->bv->rayIntersection(&(_riAttr->iEnv),
00071 ENV_WANT_INTERFERENCE|ENV_USE_CACHE,
00072 _riAttr->origin,
00073 _riAttr->direction,
00074 _riAttr->distLimit);
00075 if (_riAttr->iEnv.mask & ENV_HAVE_INTERFERENCE) {
00076 BVH_INC_SUC_TEST;
00077 continue;
00078 }
00079
00080 if (_stack.empty()) return NULL;
00081
00082 BVH_BACKTRACK;
00083 }
00084
00085 return NULL;
00086 }
00087
00088 SceneGraphObject* IteratorBVH::_next_ray_intersection(void)
00089 {
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 BVH::Node * pNode;
00101 do {
00102 if (_stack.empty()) {
00103
00104
00105
00106
00107 if (!_pBottomUpNode) return NULL;
00108
00109 pNode = _pBottomUpNode;
00110
00111
00112
00113
00114 while (true) {
00115 if (!_pBottomUpNode->parent||!_pBottomUpNode->parent->sibling){
00116 _pBottomUpNode = NULL;
00117 break;
00118 }
00119
00120 BVH_INC_TEST;
00121 _pBottomUpNode = _pBottomUpNode->parent->sibling;
00122 _pBottomUpNode->bv->rayIntersection(&(_riAttr->iEnv),
00123 ENV_WANT_INTERFERENCE|
00124 ENV_USE_CACHE,
00125 _riAttr->origin,
00126 _riAttr->direction,
00127 _riAttr->distLimit);
00128 if (_riAttr->iEnv.mask & ENV_HAVE_INTERFERENCE) {
00129 BVH_INC_SUC_TEST;
00130 break;
00131 }
00132 }
00133 } else {
00134
00135
00136
00137 BVH_BACKTRACK;
00138 }
00139
00140
00141
00142
00143
00144
00145 while (pNode) {
00146 if (pNode->leaf) {
00147 _pLastUsedChild = pNode;
00148 return pNode->list->firstItem();
00149 }
00150
00151 BVH_INC_TEST;
00152
00153 pNode->leftChild->bv->rayIntersection(&(_riAttr->iEnv),
00154 ENV_WANT_INTERFERENCE|ENV_USE_CACHE,
00155 _riAttr->origin,
00156 _riAttr->direction,
00157 _riAttr->distLimit);
00158 if (_riAttr->iEnv.mask & ENV_HAVE_INTERFERENCE) {
00159 BVH_INC_SUC_TEST;
00160 _stack.push_back(pNode->rightChild);
00161 pNode = pNode->leftChild;
00162 continue;
00163 }
00164
00165 BVH_INC_TEST;
00166 pNode = pNode->rightChild;
00167 pNode->bv->rayIntersection(&(_riAttr->iEnv),
00168 ENV_WANT_INTERFERENCE|ENV_USE_CACHE,
00169 _riAttr->origin,
00170 _riAttr->direction,
00171 _riAttr->distLimit);
00172 if (_riAttr->iEnv.mask & ENV_HAVE_INTERFERENCE) {
00173 BVH_INC_SUC_TEST;
00174 continue;
00175 }
00176
00177 if (_stack.empty()) { pNode = NULL; continue; }
00178
00179 BVH_BACKTRACK;
00180 }
00181 } while (_pBottomUpNode);
00182
00183 return NULL;
00184 }
00185
00186 #undef BVH_BACKTRACK
00187
00188 SceneGraphObject* IteratorBVH::_halfspace_search(void)
00189 {
00190 SceneGraphObject * pObj;
00191 BVH::Node * pNode;
00192 Interval interval;
00193 float dist;
00194
00195 if (_pLastUsedChild) {
00196 pObj = _pLastUsedChild->list->nextItem();
00197 if (pObj) return pObj;
00198 }
00199
00200 while (!_stack.empty()) {
00201 pNode = _stack.back();
00202 _stack.pop_back();
00203
00204
00205 interval = pNode->bv->extent(_hsAttr->direction);
00206 dist = _hsAttr->origin.dot(_hsAttr->direction);
00207 if (interval.max < dist) continue;
00208
00209 if (pNode->leaf) {
00210 _pLastUsedChild = pNode;
00211 return pNode->list->firstItem();
00212 }
00213
00214 _stack.push_back(pNode->rightChild);
00215 _stack.push_back(pNode->leftChild);
00216 }
00217
00218 return NULL;
00219 }
00220
00221 SceneGraphObject* IteratorBVH::_area_search(void)
00222 {
00223 SceneGraphObject * pObj;
00224 BVH::Node * pNode;
00225
00226 if (_pLastUsedChild) {
00227 pObj = _pLastUsedChild->list->nextItem();
00228 if (pObj) return pObj;
00229 }
00230
00231 while (!_stack.empty()) {
00232 pNode = _stack.back();
00233 _stack.pop_back();
00234
00235
00236 if (pNode->bv->separation(*(_arAttr->area), NULL)) continue;
00237
00238 if (pNode->leaf) {
00239 _pLastUsedChild = pNode;
00240 return pNode->list->firstItem();
00241 }
00242
00243 _stack.push_back(pNode->rightChild);
00244 _stack.push_back(pNode->leftChild);
00245 }
00246
00247 return NULL;
00248 }
00249
00250 SceneGraphObject* IteratorBVH::_children_search(void)
00251 {
00252
00253 if (_pLastUsedChild) {
00254 SceneGraphObject* pObject = _pLastUsedChild->list->nextItem();
00255 if (pObject) return pObject;
00256 _pLastUsedChild = _pLastUsedChild->rightChild;
00257 }
00258 else
00259 _pLastUsedChild = ((BVH*)_pAggregate)->_leftLeaf;
00260
00261 if (_pLastUsedChild) return _pLastUsedChild->list->firstItem();
00262 else return NULL;
00263 }
00264
00265 SceneGraphObject* IteratorBVH::_first_child()
00266 {
00267 while (!_stack.empty()) _stack.pop_back();
00268
00269 #ifdef ESG_STATISTICS
00270 SceneGraphObject * pRet;
00271
00272 if (_traverse == RAY_INTERSECTION && _riAttr) {
00273 if (_riAttr->parentElement) {
00274 _pLastUsedChild = (BVH::Node*) _riAttr->parentElement;
00275 _pBottomUpNode = _pLastUsedChild->sibling;
00276 return _pLastUsedChild->list->firstItem();
00277 } else {
00278 _pLastUsedChild = NULL;
00279 _pBottomUpNode = NULL;
00280 if (!(pRet = _first_ray_intersection(((BVH*)_pAggregate)->_root)))
00281 BVH_UPDATE_STAT;
00282 return pRet;
00283 }
00284 }
00285
00286 _pLastUsedChild = NULL;
00287 _pBottomUpNode = NULL;
00288
00289 if (!((BVH*)_pAggregate)->_root) return NULL;
00290
00291 if (_traverse == HALF_SPACE && _hsAttr) {
00292 _stack.push_back(((BVH*)_pAggregate)->_root);
00293 if (!(pRet = _halfspace_search())) BVH_UPDATE_STAT;
00294 return pRet;
00295 }
00296
00297 if (_traverse == AREA && _arAttr) {
00298 _stack.push_back(((BVH*)_pAggregate)->_root);
00299 if (!(pRet = _area_search())) BVH_UPDATE_STAT;
00300 return pRet;
00301 }
00302
00303 if (_traverse == CHILDREN) {
00304 if (!(pRet = _children_search())) BVH_UPDATE_STAT;
00305 return pRet;
00306 }
00307
00308 #else
00309 if (_traverse == RAY_INTERSECTION && _riAttr) {
00310 if (_riAttr->parentElement) {
00311 _pLastUsedChild = (BVH::Node*) _riAttr->parentElement;
00312 _pBottomUpNode = _pLastUsedChild->sibling;
00313 return _pLastUsedChild->list->firstItem();
00314 } else {
00315 _pLastUsedChild = NULL;
00316 _pBottomUpNode = NULL;
00317 return _first_ray_intersection(((BVH*)_pAggregate)->_root);
00318 }
00319 }
00320
00321 _pLastUsedChild = NULL;
00322 _pBottomUpNode = NULL;
00323
00324 if (!((BVH*)_pAggregate)->_root) return NULL;
00325
00326 if (_traverse == HALF_SPACE && _hsAttr) {
00327 _stack.push_back(((BVH*)_pAggregate)->_root);
00328 return _halfspace_search();
00329 }
00330
00331 if (_traverse == AREA && _arAttr) {
00332 _stack.push_back(((BVH*)_pAggregate)->_root);
00333 return _area_search();
00334 }
00335
00336 if (_traverse == CHILDREN)
00337 return _children_search();
00338 #endif // ESG_STATISTICS
00339
00340 return NULL;
00341 }
00342
00343 SceneGraphObject* IteratorBVH::_next_child()
00344 {
00345 #ifdef ESG_STATISTICS
00346 SceneGraphObject* pRet;
00347
00348 if (!_pLastUsedChild) { BVH_UPDATE_STAT; return NULL; }
00349
00350 if (_traverse == RAY_INTERSECTION && _riAttr) {
00351 SceneGraphObject * pObj = _pLastUsedChild->list->nextItem();
00352 if (pObj) return pObj;
00353 else {
00354 if (!(pRet = _next_ray_intersection())) BVH_UPDATE_STAT;
00355 return pRet;
00356 }
00357 }
00358
00359 if (_traverse == HALF_SPACE && _hsAttr) {
00360 if (!(pRet = _halfspace_search())) BVH_UPDATE_STAT;
00361 return pRet;
00362 }
00363
00364 if (_traverse == AREA && _arAttr) {
00365 if (!(pRet = _area_search())) BVH_UPDATE_STAT;
00366 return pRet;
00367 }
00368
00369 if (_traverse == CHILDREN) {
00370 if (!(pRet = _children_search())) BVH_UPDATE_STAT;
00371 return pRet;
00372 }
00373
00374 #else
00375 if (!_pLastUsedChild) return NULL;
00376 if (_traverse == RAY_INTERSECTION && _riAttr) {
00377 SceneGraphObject * pObj = _pLastUsedChild->list->nextItem();
00378 if (pObj) return pObj; else return _next_ray_intersection();
00379 }
00380 if (_traverse == HALF_SPACE && _hsAttr) return _halfspace_search();
00381 if (_traverse == AREA && _arAttr) return _area_search();
00382 if (_traverse == CHILDREN) return _children_search();
00383 #endif // ESG_STATISTICS
00384
00385 return NULL;
00386 }
00387
00388
00389
00390
00391 IteratorBVH::IteratorBVH(BVH* bvh)
00392 : IteratorSDS((SDS*) bvh)
00393 {
00394 _pLastUsedChild = NULL;
00395 #ifdef ESG_STATISTICS
00396 _bvTestsCounter = 0;
00397 _bvTestsSucCounter = 0;
00398 #endif // ESG_STATISTICS
00399 }
00400
00401 #if 0
00402 Geometry* IteratorBVH::delimitBoundary(void) const
00403 {
00404 if (!((BVH*)_pAggregate)->_root) return NULL;
00405 else return (Geometry*) ((BVH*)_pAggregate)->_root->bv->clone();
00406 }
00407 #endif
00408
00409
00410
00411 #ifdef ESG_STATISTICS
00412 #undef BVH_INC_TEST
00413 #undef BVH_INC_SUC_TEST
00414 #undef BVH_UPDATE_STAT
00415 #endif // ESG_STATISTICS
00416
00417