Changeset 8415 for OpenSceneGraph/trunk/examples/osgkdtree/osgkdtree.cpp
- Timestamp:
- 06/06/08 15:21:27 (5 years ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
OpenSceneGraph/trunk/examples/osgkdtree/osgkdtree.cpp
r8414 r8415 45 45 { 46 46 47 typedef int value_type; 48 typedef std::vector< value_type > Indices; 49 50 //#define LEAF_OBJECT 51 //#define VERBOSE_OUTPUT 52 53 #ifdef LEAF_OBJECT 47 54 class KDNode 48 55 { … … 50 57 51 58 KDNode(): 52 _leftChild(0),53 _rightChild(0) {}59 first(0), 60 second(0) {} 54 61 55 62 KDNode(const KDNode& rhs): 56 _leftChild(rhs._leftChild),57 _rightChild(rhs._rightChild) {}63 first(rhs.first), 64 second(rhs.second) {} 58 65 59 66 KDNode& operator = (const KDNode& rhs) 60 67 { 61 _leftChild = rhs._leftChild;62 _rightChild = rhs._rightChild;68 first = rhs.first; 69 second = rhs.second; 63 70 return *this; 64 71 } 65 72 66 typedef short value_type; 67 68 value_type _leftChild; 69 value_type _rightChild; 73 value_type first; 74 value_type second; 70 75 }; 71 76 … … 75 80 76 81 KDLeaf() {} 77 78 typedef unsigned int index_type;79 typedef std::vector< index_type > Indices;80 82 81 83 Indices _vertexIndices; … … 86 88 }; 87 89 90 #else 91 typedef std::pair< value_type, value_type> KDNode; 92 typedef std::pair< value_type, value_type> KDLeaf; 93 #endif 94 95 88 96 class KDTree : public osg::Shape 89 97 { … … 97 105 98 106 META_Shape(osg, KDTree) 107 99 108 100 109 typedef std::vector< unsigned int > AxisStack; 101 typedef std::vector< KDNode > KDNodeList; 110 typedef std::vector< KDNode > KDNodeList; 111 112 #ifdef LEAF_OBJECT 102 113 typedef std::vector< osg::ref_ptr<KDLeaf> > KDLeafList; 103 104 114 105 115 /// note, leafNum is negative to distinguish from nodeNum 106 116 int addLeaf(KDLeaf* leaf) { int num = _kdLeaves.size(); _kdLeaves.push_back(leaf); return -(num+1); } … … 131 141 return _kdLeaves[num].get(); 132 142 } 143 144 #else 145 typedef std::vector< KDLeaf > KDLeafList; 146 147 /// note, leafNum is negative to distinguish from nodeNum 148 int addLeaf(const KDLeaf& leaf) { int num = _kdLeaves.size(); _kdLeaves.push_back(leaf); return -(num+1); } 149 150 int replaceLeaf(int leafNum, const KDLeaf& leaf) 151 { 152 int num = -leafNum-1; 153 154 if (num>_kdLeaves.size()-1) 155 { 156 osg::notify(osg::NOTICE)<<"Warning: replaceChild("<<leafNum<<", leaf), num = "<<num<<" _kdLeaves.size()="<<_kdLeaves.size()<<std::endl; 157 return leafNum; 158 } 159 160 _kdLeaves[num] = leaf; return leafNum; 161 } 162 163 /// note, leafNum is negative to distinguish from nodeNum 164 KDLeaf& getLeaf(int leafNum) 165 { 166 int num = -leafNum-1; 167 if (num<0 || num>_kdLeaves.size()-1) 168 { 169 osg::notify(osg::NOTICE)<<"Warning: getLeaf("<<leafNum<<", num = "<<num<<") _kdLeaves.size()="<<_kdLeaves.size()<<std::endl; 170 } 171 172 return _kdLeaves[num]; 173 } 174 #endif 175 133 176 134 177 int addNode(const KDNode& node) … … 156 199 AxisStack _axisStack; 157 200 KDNodeList _kdNodes; 158 KDLeafList _kdLeaves; 201 KDLeafList _kdLeaves; 202 Indices _vertexIndices; 159 203 }; 160 204 … … 174 218 175 219 176 void traverse(KD Leaf& leaf, unsigned int level)220 void traverse(KDTree& tree, KDLeaf& leaf, unsigned int level) 177 221 { 178 222 output(level)<<"leaf("<<level<<") { "; 179 223 224 #ifdef LEAF_OBJECT 180 225 for(unsigned int i=0; i<leaf._vertexIndices.size(); ++i) 181 226 { … … 183 228 else osg::notify(osg::NOTICE)<<", "<<leaf._vertexIndices[i]; 184 229 } 185 230 #else 231 unsigned int end = leaf.first+leaf.second; 232 for(unsigned int i=leaf.first; i<end; ++i) 233 { 234 if (i==leaf.first) osg::notify(osg::NOTICE)<<tree._vertexIndices[i]; 235 else osg::notify(osg::NOTICE)<<", "<<tree._vertexIndices[i]; 236 } 237 #endif 186 238 osg::notify(osg::NOTICE)<<"}"<<std::endl;; 187 239 188 240 } 189 241 190 void traverse(KDTree& tree, KDNode::value_type nodeIndex, unsigned int level)242 void traverse(KDTree& tree, value_type nodeIndex, unsigned int level) 191 243 { 192 244 output(level)<<"traverse("<<nodeIndex<<", "<< level<<") { "<<std::endl; … … 195 247 { 196 248 KDNode& node = tree._kdNodes[nodeIndex]; 197 if (node. _leftChild) traverse(tree,node._leftChild,level+1);249 if (node.first) traverse(tree,node.first,level+1); 198 250 else output(level+1)<<"empty left child()"<<std::endl; 199 251 200 if (node. _rightChild) traverse(tree,node._rightChild,level+1);252 if (node.second) traverse(tree,node.second,level+1); 201 253 else output(level+1)<<"empty right child()"<<std::endl; 202 254 } 203 255 else 204 256 { 205 KDNode::value_type leafIndex = -nodeIndex-1; 257 value_type leafIndex = -nodeIndex-1; 258 #ifdef LEAF_OBJECT 206 259 KDLeaf& leaf = *(tree._kdLeaves[leafIndex]); 207 traverse(leaf, level); 260 #else 261 KDLeaf& leaf = tree._kdLeaves[leafIndex]; 262 #endif 263 traverse(tree, leaf, level); 208 264 } 209 265 … … 221 277 else if (!tree._kdLeaves.empty()) 222 278 { 223 traverse(*tree._kdLeaves.front(), 0); 279 #ifdef LEAF_OBJECT 280 traverse(tree, *tree._kdLeaves.front(), 0); 281 #else 282 traverse(tree, tree._kdLeaves.front(), 0); 283 #endif 224 284 } 225 285 } … … 269 329 KDTree* KDTreeBuilder::createKDTree(osg::Geometry* geometry) 270 330 { 271 #if VERBOSE_OUTPUT331 #ifdef VERBOSE_OUTPUT 272 332 osg::notify(osg::NOTICE)<<"osg::KDTreeBuilder::createKDTree()"<<std::endl; 273 333 #endif … … 283 343 unsigned int estimatedSize = (unsigned int)(float(vertices->size())/float(_targetNumVerticesPerLeaf)*1.5); 284 344 285 #if VERBOSE_OUTPUT345 #ifdef VERBOSE_OUTPUT 286 346 osg::notify(osg::NOTICE)<<"kdTree->_kdNodes.reserve()="<<estimatedSize<<std::endl<<std::endl; 287 347 #endif … … 295 355 _numVerticesProcessed += vertices->size(); 296 356 357 #ifdef LEAF_OBJECT 297 358 // create initial leaf list 298 359 KDLeaf* leaf = new KDLeaf; … … 302 363 leaf->_vertexIndices.push_back(i); 303 364 } 304 365 #else 366 367 kdTree->_vertexIndices.reserve(vertices->size()); 368 for(unsigned int i=0; i<vertices->size(); ++i) 369 { 370 kdTree->_vertexIndices.push_back(i); 371 } 372 KDLeaf leaf(0, kdTree->_vertexIndices.size()); 373 374 #endif 375 376 int leafNum = kdTree->addLeaf(leaf); 305 377 osg::BoundingBox bb = kdTree->_bb; 306 307 int leafNum = kdTree->addLeaf(leaf);308 378 int nodeNum = divide(*kdTree, bb, leafNum, 0); 309 310 #if VERBOSE_OUTPUT 379 380 381 382 383 #ifdef VERBOSE_OUTPUT 311 384 osg::notify(osg::NOTICE)<<"Root nodeNum="<<nodeNum<<std::endl; 312 385 #endif 313 386 314 #if VERBOSE_OUTPUT387 #ifdef VERBOSE_OUTPUT 315 388 316 389 KDTreeTraverser traverser; … … 334 407 kdTree._bb.zMax()-kdTree._bb.zMin()); 335 408 336 #if VERBOSE_OUTPUT409 #ifdef VERBOSE_OUTPUT 337 410 osg::notify(osg::NOTICE)<<"computeDivisions("<<_maxNumLevels<<") "<<dimensions<< " { "<<std::endl; 338 411 #endif … … 355 428 dimensions[axis] /= 2.0f; 356 429 357 #if VERBOSE_OUTPUT430 #ifdef VERBOSE_OUTPUT 358 431 osg::notify(osg::NOTICE)<<" "<<level<<", "<<dimensions<<", "<<axis<<std::endl; 359 432 #endif 360 433 } 361 434 362 #if VERBOSE_OUTPUT435 #ifdef VERBOSE_OUTPUT 363 436 osg::notify(osg::NOTICE)<<"}"<<std::endl; 364 437 #endif … … 372 445 int axis = kdTree._axisStack[level]; 373 446 374 #if VERBOSE_OUTPUT447 #ifdef VERBOSE_OUTPUT 375 448 //osg::notify(osg::NOTICE)<<"divide("<<nodeIndex<<", "<<level<< "), axis="<<axis<<std::endl; 376 449 #endif … … 378 451 if (nodeIndex>=0) 379 452 { 380 #if VERBOSE_OUTPUT453 #ifdef VERBOSE_OUTPUT 381 454 osg::notify(osg::NOTICE)<<" divide node"<<std::endl; 382 455 #endif … … 386 459 else 387 460 { 461 462 #ifdef LEAF_OBJECT 388 463 if (kdTree.getLeaf(nodeIndex)->_vertexIndices.size()<=_targetNumVerticesPerLeaf) return nodeIndex; 389 464 #else 465 if (kdTree.getLeaf(nodeIndex).second<=_targetNumVerticesPerLeaf) return nodeIndex; 466 #endif 390 467 //osg::notify(osg::NOTICE)<<" divide leaf"<<std::endl; 391 468 … … 397 474 float mid = (original_min+original_max)*0.5f; 398 475 476 #ifdef LEAF_OBJECT 399 477 { 400 478 osg::ref_ptr<KDLeaf> leaf = kdTree.getLeaf(nodeIndex); … … 424 502 { 425 503 //osg::notify(osg::NOTICE)<<"LeftLeaf empty"<<std::endl; 426 kdTree.getNode(nodeNum). _leftChild= 0;427 kdTree.getNode(nodeNum). _rightChild = kdTree.replaceLeaf(nodeIndex, rightLeaf.get());504 kdTree.getNode(nodeNum).first = 0; 505 kdTree.getNode(nodeNum).second = kdTree.replaceLeaf(nodeIndex, rightLeaf.get()); 428 506 } 429 507 else if (rightLeaf->_vertexIndices.empty()) 430 508 { 431 509 //osg::notify(osg::NOTICE)<<"RightLeaf empty"<<std::endl; 432 kdTree.getNode(nodeNum). _leftChild= kdTree.replaceLeaf(nodeIndex, leftLeaf.get());433 kdTree.getNode(nodeNum). _rightChild = 0;510 kdTree.getNode(nodeNum).first = kdTree.replaceLeaf(nodeIndex, leftLeaf.get()); 511 kdTree.getNode(nodeNum).second = 0; 434 512 } 435 513 else 436 514 { 437 kdTree.getNode(nodeNum)._leftChild = kdTree.replaceLeaf(nodeIndex, leftLeaf.get()); 438 kdTree.getNode(nodeNum)._rightChild = kdTree.addLeaf(rightLeaf.get()); 439 } 440 441 442 } 443 444 int originalLeftChildIndex = kdTree.getNode(nodeNum)._leftChild; 445 int originalRightChildIndex = kdTree.getNode(nodeNum)._rightChild; 515 kdTree.getNode(nodeNum).first = kdTree.replaceLeaf(nodeIndex, leftLeaf.get()); 516 kdTree.getNode(nodeNum).second = kdTree.addLeaf(rightLeaf.get()); 517 } 518 } 519 #else 520 { 521 KDLeaf& leaf = kdTree.getLeaf(nodeIndex); 522 523 osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(kdTree._geometry->getVertexArray()); 524 525 //osg::notify(osg::NOTICE)<<" divide leaf->_vertexIndices.size()="<<leaf->_vertexIndices.size()<<std::endl; 526 527 unsigned int estimatedSize = leaf.second; 528 529 int end = leaf.first+leaf.second-1; 530 int left = leaf.first; 531 int right = leaf.first+leaf.second-1; 532 533 while(left<right) 534 { 535 while(left<right && ((*vertices)[kdTree._vertexIndices[left]])[axis]<=mid) { ++left; } 536 537 while(left<right && ((*vertices)[kdTree._vertexIndices[right]])[axis]>mid) { --right; } 538 539 if (left<right) 540 { 541 std::swap(kdTree._vertexIndices[left], kdTree._vertexIndices[right]); 542 ++left; 543 --right; 544 } 545 } 546 547 if (left==right) 548 { 549 if (((*vertices)[kdTree._vertexIndices[left]])[axis]<=mid) ++left; 550 else --right; 551 } 552 553 KDLeaf leftLeaf(leaf.first, (right-leaf.first)+1); 554 KDLeaf rightLeaf(left, (end-left)+1); 555 556 #if 0 557 osg::notify(osg::NOTICE)<<"In leaf.first ="<<leaf.first <<" leaf.second ="<<leaf.second<<std::endl; 558 osg::notify(osg::NOTICE)<<" leftLeaf.first ="<<leftLeaf.first <<" leftLeaf.second ="<<leftLeaf.second<<std::endl; 559 osg::notify(osg::NOTICE)<<" rightLeaf.first="<<rightLeaf.first<<" rightLeaf.second="<<rightLeaf.second<<std::endl; 560 osg::notify(osg::NOTICE)<<" left="<<left<<" right="<<right<<std::endl; 561 562 if (leaf.second != (leftLeaf.second +rightLeaf.second)) 563 { 564 osg::notify(osg::NOTICE)<<"*** Error in size, leaf.second="<<leaf.second 565 <<", leftLeaf.second="<<leftLeaf.second 566 <<", rightLeaf.second="<<rightLeaf.second<<std::endl; 567 } 568 else 569 { 570 osg::notify(osg::NOTICE)<<"Size OK, leaf.second="<<leaf.second 571 <<", leftLeaf.second="<<leftLeaf.second 572 <<", rightLeaf.second="<<rightLeaf.second<<std::endl; 573 } 574 #endif 575 if (leftLeaf.second<=0) 576 { 577 //osg::notify(osg::NOTICE)<<"LeftLeaf empty"<<std::endl; 578 kdTree.getNode(nodeNum).first = 0; 579 kdTree.getNode(nodeNum).second = kdTree.replaceLeaf(nodeIndex, rightLeaf); 580 } 581 else if (rightLeaf.second<=0) 582 { 583 //osg::notify(osg::NOTICE)<<"RightLeaf empty"<<std::endl; 584 kdTree.getNode(nodeNum).first = kdTree.replaceLeaf(nodeIndex, leftLeaf); 585 kdTree.getNode(nodeNum).second = 0; 586 } 587 else 588 { 589 kdTree.getNode(nodeNum).first = kdTree.replaceLeaf(nodeIndex, leftLeaf); 590 kdTree.getNode(nodeNum).second = kdTree.addLeaf(rightLeaf); 591 } 592 } 593 #endif 594 595 int originalLeftChildIndex = kdTree.getNode(nodeNum).first; 596 int originalRightChildIndex = kdTree.getNode(nodeNum).second; 446 597 447 598 … … 449 600 bb._max[axis] = mid; 450 601 451 //osg::notify(osg::NOTICE)<<" divide leftLeaf "<<kdTree.getNode(nodeNum). _leftChild<<std::endl;602 //osg::notify(osg::NOTICE)<<" divide leftLeaf "<<kdTree.getNode(nodeNum).first<<std::endl; 452 603 int leftChildIndex = divide(kdTree, bb, originalLeftChildIndex, level+1); 453 604 … … 457 608 bb._min[axis] = mid; 458 609 459 //osg::notify(osg::NOTICE)<<" divide rightLeaf "<<kdTree.getNode(nodeNum). _rightChild<<std::endl;610 //osg::notify(osg::NOTICE)<<" divide rightLeaf "<<kdTree.getNode(nodeNum).second<<std::endl; 460 611 int rightChildIndex = divide(kdTree, bb, originalRightChildIndex, level+1); 461 612 462 613 bb._min[axis] = restore; 463 614 464 kdTree.getNode(nodeNum). _leftChild= leftChildIndex;465 kdTree.getNode(nodeNum). _rightChild = rightChildIndex;615 kdTree.getNode(nodeNum).first = leftChildIndex; 616 kdTree.getNode(nodeNum).second = rightChildIndex; 466 617 467 618 return nodeNum; … … 488 639 489 640 osgUtil::UpdateVisitor updateVisitor; 641 updateVisitor.setFrameStamp(new osg::FrameStamp); 490 642 scene->accept(updateVisitor); 643 scene->getBound(); 491 644 492 645
