Changeset 8546
- Timestamp:
- 07/07/08 22:27:56
- Files:
-
- OpenSceneGraph/trunk/include/osg/KdTree (modified) (4 diffs)
- OpenSceneGraph/trunk/src/osg/KdTree.cpp (modified) (7 diffs)
- OpenSceneGraph/trunk/src/osgUtil/LineSegmentIntersector.cpp (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
OpenSceneGraph/trunk/include/osg/KdTree
r8544 r8546 35 35 struct BuildOptions 36 36 { 37 BuildOptions(): 38 _numVerticesProcessed(0), 39 _targetNumTrianglesPerLeaf(4), 40 _maxNumLevels(24) {} 37 BuildOptions(); 41 38 42 39 int _numVerticesProcessed; … … 164 161 } 165 162 163 const KdLeaf& getLeaf(int leafNum) const 164 { 165 int num = -leafNum-1; 166 if (num<0 || num>static_cast<int>(_kdLeaves.size())-1) 167 { 168 osg::notify(osg::NOTICE)<<"Warning: getLeaf("<<leafNum<<", num = "<<num<<") _kdLeaves.size()="<<_kdLeaves.size()<<std::endl; 169 } 170 171 return _kdLeaves[num]; 172 } 173 166 174 int addNode(const KdNode& node) 167 175 { … … 180 188 return _kdNodes[nodeNum]; 181 189 } 182 183 osg::BoundingBox& getBounindingBox(int nodeNum) 190 191 /// note, nodeNum is positive to distinguish from leftNum 192 const KdNode& getNode(int nodeNum) const 193 { 194 if (nodeNum<0 || nodeNum>static_cast<int>(_kdNodes.size())-1) 195 { 196 osg::notify(osg::NOTICE)<<"Warning: getNode("<<nodeNum<<") _kdNodes.size()="<<_kdNodes.size()<<std::endl; 197 } 198 return _kdNodes[nodeNum]; 199 } 200 201 osg::BoundingBox& getBoundingBox(int nodeNum) 184 202 { 185 203 if (nodeNum<0) … … 200 218 201 219 bool intersect(const KdLeaf& leaf, const osg::Vec3& start, const osg::Vec3& end, LineSegmentIntersections& intersections) const; 220 bool intersect(const KdNode& node, const osg::Vec3& start, const osg::Vec3& end, const osg::Vec3& s, const osg::Vec3& e, LineSegmentIntersections& intersections) const; 221 bool intersectAndClip(osg::Vec3& s, osg::Vec3& e, const osg::BoundingBox& bb) const; 202 222 203 223 typedef std::vector< osg::BoundingBox > BoundingBoxList; OpenSceneGraph/trunk/src/osg/KdTree.cpp
r8544 r8546 20 20 using namespace osg; 21 21 22 // #define VERBOSE_OUTPUT22 // #define VERBOSE_OUTPUT 23 23 24 24 //////////////////////////////////////////////////////////////////////////////// … … 58 58 // KdTree 59 59 60 KdTree::BuildOptions::BuildOptions(): 61 _numVerticesProcessed(0), 62 _targetNumTrianglesPerLeaf(8), 63 _maxNumLevels(24) 64 { 65 } 66 67 //////////////////////////////////////////////////////////////////////////////// 68 // 69 // KdTree 70 60 71 KdTree::KdTree() 61 72 { … … 118 129 int nodeNum = divide(options, bb, leafNum, 0); 119 130 131 #if 0 132 for(KdLeafList::iterator itr = _kdLeaves.begin(); 133 itr != _kdLeaves.end(); 134 ++itr) 135 { 136 KdLeaf& leaf = *itr; 137 leaf.bb.init(); 138 int iend = leaf.first+leaf.second; 139 for(int i=leaf.first; i<iend; ++i) 140 { 141 const Triangle& tri = _triangles[_primitiveIndices[i]]; 142 const osg::Vec3& v1 = (*_vertices)[tri._p1]; 143 const osg::Vec3& v2 = (*_vertices)[tri._p2]; 144 const osg::Vec3& v3 = (*_vertices)[tri._p3]; 145 leaf.bb.expandBy(v1); 146 leaf.bb.expandBy(v2); 147 leaf.bb.expandBy(v3); 148 } 149 // osg::notify(osg::NOTICE)<<"leaf.bb.min("<<leaf.bb._min<<") max("<<leaf.bb._max<<")"<<std::endl; 150 151 } 152 #endif 153 120 154 #ifdef VERBOSE_OUTPUT 121 155 osg::notify(osg::NOTICE)<<"Root nodeNum="<<nodeNum<<std::endl; … … 187 221 { 188 222 189 if (getLeaf(nodeIndex).second<=options._targetNumTrianglesPerLeaf) return nodeIndex; 223 if (getLeaf(nodeIndex).second<=options._targetNumTrianglesPerLeaf) 224 { 225 // leaf is done, now compute bound on it. 226 KdLeaf& leaf = getLeaf(nodeIndex); 227 leaf.bb.init(); 228 int iend = leaf.first+leaf.second; 229 for(int i=leaf.first; i<iend; ++i) 230 { 231 const Triangle& tri = _triangles[_primitiveIndices[i]]; 232 const osg::Vec3& v1 = (*_vertices)[tri._p1]; 233 const osg::Vec3& v2 = (*_vertices)[tri._p2]; 234 const osg::Vec3& v3 = (*_vertices)[tri._p3]; 235 leaf.bb.expandBy(v1); 236 leaf.bb.expandBy(v2); 237 leaf.bb.expandBy(v3); 238 } 239 240 return nodeIndex; 241 } 190 242 191 243 //osg::notify(osg::NOTICE)<<" divide leaf"<<std::endl; … … 293 345 getNode(nodeNum).second = rightChildIndex; 294 346 347 getNode(nodeNum).bb.init(); 348 if (leftChildIndex!=0) getNode(nodeNum).bb.expandBy(getBoundingBox(leftChildIndex)); 349 if (rightChildIndex!=0) getNode(nodeNum).bb.expandBy(getBoundingBox(rightChildIndex)); 350 295 351 return nodeNum; 296 352 } … … 424 480 intersections.insert(intersection); 425 481 426 osg::notify(osg::NOTICE)<<" got intersection ("<<in<<") ratio="<<r<<std::endl;482 // osg::notify(osg::NOTICE)<<" got intersection ("<<in<<") ratio="<<r<<std::endl; 427 483 428 484 intersects = true; … … 432 488 } 433 489 490 bool KdTree::intersect(const KdNode& node, const osg::Vec3& start, const osg::Vec3& end, const osg::Vec3& s, const osg::Vec3& e, LineSegmentIntersections& intersections) const 491 { 492 //osg::notify(osg::NOTICE)<<" Intersect "<<&node<<std::endl; 493 //osg::Vec3 ls(start), le(end); 494 osg::Vec3 ls(s), le(e); 495 int numIntersectionsBefore = intersections.size(); 496 if (intersectAndClip(ls, le, node.bb)) 497 { 498 if (node.first>0) intersect(getNode(node.first), start, end, ls, le, intersections); 499 else if (node.first<0) intersect(getLeaf(node.first), start, end, intersections); 500 501 if (node.second>0) intersect(getNode(node.second), start, end, ls, le, intersections); 502 else if (node.second<0) intersect(getLeaf(node.second), start, end, intersections); 503 } 504 return numIntersectionsBefore != intersections.size(); 505 } 506 507 bool KdTree::intersectAndClip(osg::Vec3& s, osg::Vec3& e, const osg::BoundingBox& bb) const 508 { 509 // compate s and e against the xMin to xMax range of bb. 510 if (s.x()<=e.x()) 511 { 512 513 // trivial reject of segment wholely outside. 514 if (e.x()<bb.xMin()) return false; 515 if (s.x()>bb.xMax()) return false; 516 517 if (s.x()<bb.xMin()) 518 { 519 // clip s to xMin. 520 s = s+(e-s)*(bb.xMin()-s.x())/(e.x()-s.x()); 521 } 522 523 if (e.x()>bb.xMax()) 524 { 525 // clip e to xMax. 526 e = s+(e-s)*(bb.xMax()-s.x())/(e.x()-s.x()); 527 } 528 } 529 else 530 { 531 if (s.x()<bb.xMin()) return false; 532 if (e.x()>bb.xMax()) return false; 533 534 if (e.x()<bb.xMin()) 535 { 536 // clip s to xMin. 537 e = s+(e-s)*(bb.xMin()-s.x())/(e.x()-s.x()); 538 } 539 540 if (s.x()>bb.xMax()) 541 { 542 // clip e to xMax. 543 s = s+(e-s)*(bb.xMax()-s.x())/(e.x()-s.x()); 544 } 545 } 546 547 // compate s and e against the yMin to yMax range of bb. 548 if (s.y()<=e.y()) 549 { 550 551 // trivial reject of segment wholely outside. 552 if (e.y()<bb.yMin()) return false; 553 if (s.y()>bb.yMax()) return false; 554 555 if (s.y()<bb.yMin()) 556 { 557 // clip s to yMin. 558 s = s+(e-s)*(bb.yMin()-s.y())/(e.y()-s.y()); 559 } 560 561 if (e.y()>bb.yMax()) 562 { 563 // clip e to yMax. 564 e = s+(e-s)*(bb.yMax()-s.y())/(e.y()-s.y()); 565 } 566 } 567 else 568 { 569 if (s.y()<bb.yMin()) return false; 570 if (e.y()>bb.yMax()) return false; 571 572 if (e.y()<bb.yMin()) 573 { 574 // clip s to yMin. 575 e = s+(e-s)*(bb.yMin()-s.y())/(e.y()-s.y()); 576 } 577 578 if (s.y()>bb.yMax()) 579 { 580 // clip e to yMax. 581 s = s+(e-s)*(bb.yMax()-s.y())/(e.y()-s.y()); 582 } 583 } 584 585 // compate s and e against the zMin to zMax range of bb. 586 if (s.z()<=e.z()) 587 { 588 589 // trivial reject of segment wholely outside. 590 if (e.z()<bb.zMin()) return false; 591 if (s.z()>bb.zMax()) return false; 592 593 if (s.z()<bb.zMin()) 594 { 595 // clip s to zMin. 596 s = s+(e-s)*(bb.zMin()-s.z())/(e.z()-s.z()); 597 } 598 599 if (e.z()>bb.zMax()) 600 { 601 // clip e to zMax. 602 e = s+(e-s)*(bb.zMax()-s.z())/(e.z()-s.z()); 603 } 604 } 605 else 606 { 607 if (s.z()<bb.zMin()) return false; 608 if (e.z()>bb.zMax()) return false; 609 610 if (e.z()<bb.zMin()) 611 { 612 // clip s to zMin. 613 e = s+(e-s)*(bb.zMin()-s.z())/(e.z()-s.z()); 614 } 615 616 if (s.z()>bb.zMax()) 617 { 618 // clip e to zMax. 619 s = s+(e-s)*(bb.zMax()-s.z())/(e.z()-s.z()); 620 } 621 } 622 623 // osg::notify(osg::NOTICE)<<"clampped segment "<<s<<" "<<e<<std::endl; 624 625 // if (s==e) return false; 626 627 return true; 628 } 629 434 630 bool KdTree::intersect(const osg::Vec3& start, const osg::Vec3& end, LineSegmentIntersections& intersections) const 435 631 { 436 // osg::notify(osg::NOTICE)<<"KdTree::intersect("<<start<<","<<end<<")"<<std::endl; 437 632 //osg::notify(osg::NOTICE)<<"KdTree::intersect("<<start<<","<<end<<")"<<std::endl; 438 633 bool intersects = false; 439 for(KdLeafList::const_iterator itr = _kdLeaves.begin(); 440 itr != _kdLeaves.end(); 441 ++itr) 442 { 443 if (intersect(*itr, start, end, intersections)) intersects = true; 634 635 int option = 2; 636 switch(option) 637 { 638 case(0): 639 { 640 for(KdLeafList::const_iterator itr = _kdLeaves.begin(); 641 itr != _kdLeaves.end(); 642 ++itr) 643 { 644 if (intersect(*itr, start, end, intersections)) intersects = true; 645 } 646 break; 647 } 648 649 case(1): 650 { 651 for(KdLeafList::const_iterator itr = _kdLeaves.begin(); 652 itr != _kdLeaves.end(); 653 ++itr) 654 { 655 osg::Vec3 s(start), e(end); 656 if (intersectAndClip(s,e,itr->bb)) 657 { 658 if (intersect(*itr, start, end, intersections)) intersects = true; 659 } 660 } 661 break; 662 } 663 664 case(2): 665 { 666 //osg::notify(osg::NOTICE)<<"_kdNodes.size()="<<_kdNodes.size()<<std::endl; 667 osg::Vec3 s(start), e(end); 668 if (intersect(getNode(0), start, end, s,e, intersections)) intersects = true; 669 break; 670 } 444 671 } 445 672 OpenSceneGraph/trunk/src/osgUtil/LineSegmentIntersector.cpp
r8545 r8546 20 20 #include <osg/TriangleFunctor> 21 21 #include <osg/KdTree> 22 #include <osg/Timer> 22 23 23 24 using namespace osgUtil; … … 295 296 } 296 297 298 osg::Timer_t before_kdTree = osg::Timer::instance()->tick(); 299 unsigned int numKdTreeHits = 0; 300 unsigned int numConventionalHits = 0; 301 297 302 osg::KdTree* kdTree = dynamic_cast<osg::KdTree*>(drawable->getShape()); 303 osg::Vec3d kdTreeHit; 298 304 if (kdTree) 299 305 { … … 301 307 if (kdTree->intersect(s,e,intersections)) 302 308 { 303 osg::notify(osg::NOTICE)<<"Got KdTree intersections"<<std::endl;309 // osg::notify(osg::NOTICE)<<"Got KdTree intersections"<<std::endl; 304 310 for(osg::KdTree::LineSegmentIntersections::iterator itr = intersections.begin(); 305 311 itr != intersections.end(); … … 323 329 324 330 hit.localIntersectionPoint = _start*(1.0-remap_ratio) + _end*remap_ratio; 331 kdTreeHit = hit.localIntersectionPoint; 325 332 326 osg::notify(osg::NOTICE)<<"KdTree: ratio="<<hit.ratio<<" ("<<hit.localIntersectionPoint<<")"<<std::endl;333 // osg::notify(osg::NOTICE)<<"KdTree: ratio="<<hit.ratio<<" ("<<hit.localIntersectionPoint<<")"<<std::endl; 327 334 328 335 hit.localIntersectionNormal = lsi.intersectionNormal; … … 331 338 hit.ratioList.swap(lsi.ratioList); 332 339 340 ++numKdTreeHits; 333 341 insertIntersection(hit); 334 342 … … 336 344 } 337 345 338 return;346 // return; 339 347 } 340 348 else … … 342 350 // osg::notify(osg::NOTICE)<<"Not KdTree available"<<std::endl; 343 351 } 352 353 osg::Timer_t after_kdTree = osg::Timer::instance()->tick(); 344 354 345 355 osg::TriangleFunctor<LineSegmentIntersectorUtils::TriangleIntersector> ti; … … 347 357 drawable->accept(ti); 348 358 359 osg::Vec3d conventionalHit; 349 360 if (ti._hit) 350 361 { … … 372 383 373 384 hit.localIntersectionPoint = _start*(1.0-remap_ratio) + _end*remap_ratio; 385 conventionalHit = hit.localIntersectionPoint; 374 386 375 387 // osg::notify(osg::NOTICE)<<"Conventional: ratio="<<hit.ratio<<" ("<<hit.localIntersectionPoint<<")"<<std::endl; … … 402 414 403 415 insertIntersection(hit); 404 405 } 406 } 407 416 ++numConventionalHits; 417 418 } 419 } 420 421 osg::Timer_t after_conventional = osg::Timer::instance()->tick(); 422 423 double timeKdTree = osg::Timer::instance()->delta_m(before_kdTree, after_kdTree); 424 double timeConventional = osg::Timer::instance()->delta_m(after_kdTree, after_conventional); 425 426 #if 1 427 if (kdTree) 428 { 429 osg::notify(osg::NOTICE)<<"KdTree ("<<kdTreeHit<<") intersections = "<<numKdTreeHits<< " time = "<<timeKdTree<<std::endl; 430 osg::notify(osg::NOTICE)<<"Conventional ("<<conventionalHit<<") intersections = "<<numConventionalHits<< " time = "<<timeConventional<<std::endl; 431 osg::notify(osg::NOTICE)<<"Ratio = "<<timeConventional/timeKdTree<<std::endl; 432 osg::notify(osg::NOTICE)<<std::endl; 433 } 434 #endif 408 435 } 409 436
