- Timestamp:
- 11/14/05 21:29:57 (19 years ago)
- Location:
- trunk/VUT/GtpVisibilityPreprocessor
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/VUT/GtpVisibilityPreprocessor/scripts/Preprocessor.vcproj
r408 r410 261 261 </File> 262 262 <File 263 RelativePath="..\src\Statistics.h"> 264 </File> 265 <File 263 266 RelativePath="..\src\Triangle3.cpp"> 264 267 </File> -
trunk/VUT/GtpVisibilityPreprocessor/scripts/default.env
r409 r410 23 23 } 24 24 25 Preprocessor { 26 # type sampling 27 type vss 28 } 29 25 30 Unigraphics { 26 31 meshGrouping 1 … … 88 93 # input fromViewCells 89 94 # input fromSceneGeometry 90 samples 10000095 samples 200000 91 96 sideTolerance 0.005 92 97 } … … 126 131 #splitPlaneStrategy 130 127 132 128 splitPlaneStrategy 1 133 splitPlaneStrategy 1024 129 134 130 135 maxPolyCandidates 50 … … 138 143 minPvs 35 139 144 minArea 0.01 140 maxRayContribution 0.0 5145 maxRayContribution 0.005 141 146 #maxAccRayLength 100 142 147 … … 166 171 Simulation { 167 172 objRenderCost 1.0 168 vcOverhead 0.05 173 vcOverhead 1.0 174 moveSpeed 1.0 169 175 } 170 176 -
trunk/VUT/GtpVisibilityPreprocessor/src/Preprocessor.cpp
r409 r410 87 87 environment->GetFloatValue("Simulation.moveSpeed", moveSpeed); 88 88 89 Debug << "render simulator using render cost=" << objRenderCost << ", vc overhead=" << vcOverhead << ", move speed=" << moveSpeed << endl; 89 90 if (ViewCell::sHierarchy = ViewCell::BSP) 90 91 mRenderSimulator = new BspViewCellRenderSimulator(objRenderCost, vcOverhead, moveSpeed, mBspTree); -
trunk/VUT/GtpVisibilityPreprocessor/src/RenderSimulator.cpp
r409 r410 48 48 for (it = viewCells.begin(); it != it_end; ++ it) 49 49 { 50 // compute view cell area 50 51 mBspTree->ConstructGeometry(dynamic_cast<BspViewCell *>(*it), geom); 52 const float area = Polygon3::GetArea(geom); 51 53 CLEAR_CONTAINER(geom); 52 54 53 const float area = Polygon3::GetArea(geom);54 55 // area substitute for view point probability 55 56 float pInVc = area; -
trunk/VUT/GtpVisibilityPreprocessor/src/SamplingPreprocessor.cpp
r409 r410 479 479 passContributingSamples, 480 480 passSampleContributions); 481 482 //mVspKdTree->Construct(mSampleRays, mBoundingBox); 481 483 } 484 /*else if (ViewCell::sHierarchy == ViewCell::VSPKD) 485 { 486 ProcessVspKdViewCells(ray, 487 reverseSample ? NULL : object, 488 faceIndex, 489 passContributingSamples, 490 passSampleContributions); 491 }*/ 482 492 } 483 493 } else { -
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
r409 r410 1144 1144 } 1145 1145 1146 Debug << "lowest: " << lowestCost << endl; 1147 1148 //limit = maxRaysCandidates > 0 ? Min((int)rays.size(), maxRayCandidates) : (int)rays.size(); 1146 //Debug << "lowest: " << lowestCost << endl; 1147 1148 //-- choose candidate planes extracted from rays 1149 // we currently use two methods 1150 // 1) take 3 ray endpoints, where two are minimum and one a maximum 1151 // point or the other way round 1152 // 2) take plane normal as plane normal and the midpoint of the ray. 1153 // PROBLEM: does not resemble any point where visibility is likely to change 1149 1154 const BoundedRayContainer *rays = data.mRays; 1150 1155 … … 1175 1180 } 1176 1181 1177 Debug << "lowest: " << lowestCost << endl;1182 //Debug << "lowest: " << lowestCost << endl; 1178 1183 1179 1184 for (int i = 0; i < sMaxRayCandidates / 2; ++ i) … … 1208 1213 if (candidateCost < lowestCost) 1209 1214 { 1210 Debug << "choose ray plane 2: " << candidateCost << endl;1215 //Debug << "choose ray plane 2: " << candidateCost << endl; 1211 1216 bestPlane = plane; 1212 1217 … … 1215 1220 } 1216 1221 1222 #ifdef _DEBUG 1217 1223 Debug << "plane lowest cost: " << lowestCost << endl; 1224 #endif 1218 1225 return bestPlane; 1219 1226 } … … 1763 1770 mStat.accumDepth += data.mDepth; 1764 1771 1765 //#ifdef _DEBUG1772 #ifdef _DEBUG 1766 1773 Debug << "BSP stats: " 1767 1774 << "Depth: " << data.mDepth << " (max: " << sTermMaxDepth << "), " … … 1772 1779 << "#pvs: " << leaf->GetViewCell()->GetPvs().GetSize() << "=, " 1773 1780 << "#avg ray contrib (pvs): " << (float)data.mPvs / (float)data.mRays->size() << endl; 1774 //#endif1781 #endif 1775 1782 } 1776 1783 -
trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.cpp
r409 r410 141 141 app << "#N_RAYS ( Number of rays )\n" 142 142 << rays <<endl; 143 144 143 144 app << "#N_INITPVS ( Initial PVS size )\n" 145 145 << initialPvsSize <<endl; 146 146 … … 370 370 int &pvsFront) 371 371 { 372 373 int minDirDepth = 6; 374 int axis; 372 int minDirDepth = 6; 373 int axis; 375 374 float costRatio; 376 375 377 376 if (splitType == ESplitRegular) { 378 377 costRatio = BestCostRatioRegular(leaf, 379 380 381 382 383 384 pvsFront385 ); 386 387 } else {388 if (splitType == ESplitHeuristic) 389 costRatio = BestCostRatioHeuristic(leaf, 390 axis,391 position,392 raysBack,393 raysFront,394 pvsBack,395 pvsFront396 378 axis, 379 position, 380 raysBack, 381 raysFront, 382 pvsBack, 383 pvsFront); 384 385 } 386 else 387 { 388 if (splitType == ESplitHeuristic) 389 costRatio = BestCostRatioHeuristic(leaf, 390 axis, 391 position, 392 raysBack, 393 raysFront, 394 pvsBack, 395 pvsFront); 397 396 else { 398 cerr <<"VspKdTree: Unknown split heuristics\n";397 cerr << "VspKdTree: Unknown split heuristics\n"; 399 398 exit(1); 400 399 } 401 400 } 402 401 403 if (costRatio > termMaxCostRatio) { 402 if (costRatio > termMaxCostRatio) 403 { 404 404 // cout<<"Too big cost ratio "<<costRatio<<endl; 405 405 return -1; … … 421 421 422 422 float 423 VspKdTree::EvalCostRatio( 424 VspKdTreeLeaf *leaf, 425 const int axis, 426 const float position, 427 int &raysBack, 428 int &raysFront, 429 int &pvsBack, 430 int &pvsFront 431 ) 423 VspKdTree::EvalCostRatio(VspKdTreeLeaf *leaf, 424 const int axis, 425 const float position, 426 int &raysBack, 427 int &raysFront, 428 int &pvsBack, 429 int &pvsFront) 432 430 { 433 431 raysBack = 0; … … 448 446 // this is the main ray classification loop! 449 447 for(VspKdTreeNode::RayInfoContainer::iterator ri = leaf->rays.begin(); 450 ri != leaf->rays.end(); 451 ri++) 452 if ((*ri).mRay->IsActive()) { 448 ri != leaf->rays.end(); ri++) 449 if ((*ri).mRay->IsActive()) 450 { 451 // determine the side of this ray with respect to the plane 452 int side = (*ri).ComputeRayIntersection(axis, position, (*ri).mRay->mT); 453 // (*ri).mRay->mSide = side; 454 455 if (side <= 0) 456 raysBack ++; 453 457 454 // determine the side of this ray with respect to the plane 455 int side = (*ri).ComputeRayIntersection(axis, position, (*ri).mRay->mT); 456 // (*ri).mRay->mSide = side; 458 if (side >= 0) 459 raysFront++; 457 460 458 if (side <= 0) 459 raysBack++; 460 461 if (side >= 0) 462 raysFront++; 463 464 AddObject2Pvs((*ri).mRay->mTerminationObject, side, pvsBack, pvsFront); 465 } 461 AddObject2Pvs((*ri).mRay->mTerminationObject, side, pvsBack, pvsFront); 462 } 466 463 467 464 AxisAlignedBox3 box = GetBBox(leaf); … … 475 472 476 473 newCost = ct_div_ci + sum/sizeBox; 477 478 } else { 479 474 } 475 else 476 { 480 477 // directional split 481 for(VspKdTreeNode::RayInfoContainer::iterator ri = leaf->rays.begin(); 482 ri != leaf->rays.end(); 483 ri++) 484 if ((*ri).mRay->IsActive()) { 485 478 for(VspKdTreeNode::RayInfoContainer::iterator ri = leaf->rays.begin(); 479 ri != leaf->rays.end(); ++ ri) 480 if ((*ri).mRay->IsActive()) 481 { 486 482 // determine the side of this ray with respect to the plane 487 483 int side; … … 499 495 // (*ri).mRay->mSide = side; 500 496 AddObject2Pvs((*ri).mRay->mTerminationObject, side, pvsBack, pvsFront); 501 502 } 503 504 AxisAlignedBox3 box = GetDirBBox(leaf); 505 506 float minBox = box.Min(axis-3); 507 float maxBox = box.Max(axis-3); 508 float sizeBox = maxBox - minBox; 509 510 // float sum = raysBack*(position - minBox) + raysFront*(maxBox - position); 511 float sum = 512 pvsBack*(position - minBox) + 513 pvsFront*(maxBox - position); 497 } 498 499 AxisAlignedBox3 box = GetDirBBox(leaf); 500 501 float minBox = box.Min(axis - 3); 502 float maxBox = box.Max(axis - 3); 503 float sizeBox = maxBox - minBox; 504 505 // float sum = raysBack*(position - minBox) + raysFront*(maxBox - position); 506 float sum = pvsBack*(position - minBox) + pvsFront*(maxBox - position); 514 507 // float sum = pvsBack + pvsFront; 515 508 newCost = ct_div_ci + sum/sizeBox; 516 509 } 517 510 518 511 // cout<<axis<<" "<<pvsSize<<" "<<pvsBack<<" "<<pvsFront<<endl; 519 512 // float oldCost = leaf->rays.size(); 520 513 float oldCost = pvsSize; 521 float ratio = newCost/oldCost; 514 515 float ratio = newCost / oldCost; 522 516 // cout<<"ratio="<<ratio<<endl; 523 517 return ratio; … … 525 519 526 520 float 527 VspKdTree::BestCostRatioRegular( 528 VspKdTreeLeaf *leaf, 529 int &axis, 530 float &position, 531 int &raysBack, 532 int &raysFront, 533 int &pvsBack, 534 int &pvsFront 535 ) 521 VspKdTree::BestCostRatioRegular(VspKdTreeLeaf *leaf, 522 int &axis, 523 float &position, 524 int &raysBack, 525 int &raysFront, 526 int &pvsBack, 527 int &pvsFront) 536 528 { 537 529 int nRaysBack[6], nRaysFront[6]; … … 543 535 AxisAlignedBox3 sBox = GetBBox(leaf); 544 536 AxisAlignedBox3 dBox = GetDirBBox(leaf); 537 545 538 // int sAxis = box.Size().DrivingAxis(); 546 539 int sAxis = sBox.Size().DrivingAxis(); … … 549 542 bool onlyDrivingAxis = true; 550 543 551 for (axis = 0; axis < 6; axis++) { 552 if (!onlyDrivingAxis || axis == sAxis || axis == dAxis) { 544 for (axis = 0; axis < 6; ++ axis) 545 { 546 if (!onlyDrivingAxis || axis == sAxis || axis == dAxis) 547 { 553 548 if (axis < 3) 554 549 nPosition[axis] = (sBox.Min()[axis] + sBox.Max()[axis])*0.5f; … … 557 552 558 553 nCostRatio[axis] = EvalCostRatio(leaf, 559 axis, 560 nPosition[axis], 561 nRaysBack[axis], 562 nRaysFront[axis], 563 nPvsBack[axis], 564 nPvsFront[axis] 565 ); 554 axis, 555 nPosition[axis], 556 nRaysBack[axis], 557 nRaysFront[axis], 558 nPvsBack[axis], 559 nPvsFront[axis]); 566 560 567 if ( 561 if (bestAxis == -1) 568 562 bestAxis = axis; 569 563 else 570 if ( nCostRatio[axis] < nCostRatio[bestAxis])564 if (nCostRatio[axis] < nCostRatio[bestAxis]) 571 565 bestAxis = axis; 572 566 } … … 585 579 } 586 580 587 float 588 VspKdTree::BestCostRatioHeuristic( 589 VspKdTreeLeaf *leaf, 590 int &axis, 591 float &position, 592 int &raysBack, 593 int &raysFront, 594 int &pvsBack, 595 int &pvsFront 596 ) 581 float VspKdTree::BestCostRatioHeuristic(VspKdTreeLeaf *leaf, 582 int &axis, 583 float &position, 584 int &raysBack, 585 int &raysFront, 586 int &pvsBack, 587 int &pvsFront) 597 588 { 598 589 AxisAlignedBox3 box = GetBBox(leaf); … … 622 613 // set all object as belonging to the fron pvs 623 614 for(VspKdTreeNode::RayInfoContainer::iterator ri = leaf->rays.begin(); 624 ri != leaf->rays.end(); 625 ri++) 626 if ((*ri).mRay->IsActive()) { 615 ri != leaf->rays.end(); ++ ri) 616 { 617 if ((*ri).mRay->IsActive()) 618 { 627 619 Intersectable *object = (*ri).mRay->mTerminationObject; 620 628 621 if (object) 629 if (!object->Mailed()) { 622 if (!object->Mailed()) 623 { 630 624 object->Mail(); 631 625 object->mCounter = 1; 632 } else 633 object->mCounter++; 634 } 626 } 627 else 628 ++ object->mCounter; 629 } 630 } 635 631 636 632 Intersectable::NewMail(); 637 633 638 for (vector<SortableEntry>::const_iterator ci = splitCandidates->begin();639 ci < splitCandidates->end();640 ci++){634 for (vector<SortableEntry>::const_iterator ci = splitCandidates->begin(); 635 ci < splitCandidates->end(); ++ ci) 636 { 641 637 VssRay *ray; 642 switch ((*ci).type) {643 case SortableEntry::ERayMin: {644 rl++;645 ray = (VssRay *) (*ci).data;646 Intersectable *object = ray->mTerminationObject;647 if (object && !object->Mailed()) {648 object->Mail();649 pl++;650 }651 break;652 }653 case SortableEntry::ERayMax: {654 rr--;655 ray = (VssRay *) (*ci).data;656 Intersectable *object = ray->mTerminationObject;657 if (object) {658 if (--object->mCounter == 0)659 pr--;660 }661 break;662 }663 }664 if ((*ci).value > minBand && (*ci).value < maxBand) {665 638 639 switch ((*ci).type) 640 { 641 case SortableEntry::ERayMin: 642 { 643 ++ rl; 644 ray = (VssRay *) (*ci).data; 645 Intersectable *object = ray->mTerminationObject; 646 if (object && !object->Mailed()) 647 { 648 object->Mail(); 649 ++ pl; 650 } 651 break; 652 } 653 case SortableEntry::ERayMax: 654 { 655 -- rr; 656 657 ray = (VssRay *) (*ci).data; 658 Intersectable *object = ray->mTerminationObject; 659 660 if (object) 661 { 662 if (-- object->mCounter == 0) 663 -- pr; 664 } 665 666 break; 667 } 668 } 669 670 if ((*ci).value > minBand && (*ci).value < maxBand) 671 { 666 672 sum = pl*((*ci).value - minBox) + pr*(maxBox - (*ci).value); 673 674 // cout<<"pos="<<(*ci).value<<"\t q=("<<ql<<","<<qr<<")\t r=("<<rl<<","<<rr<<")"<<endl; 675 // cout<<"cost= "<<sum<<endl; 667 676 668 // cout<<"pos="<<(*ci).value<<"\t q=("<<ql<<","<<qr<<")\t r=("<<rl<<","<<rr<<")"<<endl; 669 // cout<<"cost= "<<sum<<endl; 670 671 if (sum < minSum) { 677 if (sum < minSum) 678 { 672 679 minSum = sum; 673 680 position = (*ci).value; 674 681 675 682 raysBack = rl; 676 683 raysFront = rr; 677 684 678 685 pvsBack = pl; 679 686 pvsFront = pr; 680 687 681 } 682 } 683 } 684 685 float oldCost = leaf->GetPvsSize(); 686 float newCost = ct_div_ci + minSum/sizeBox; 687 float ratio = newCost/oldCost; 688 689 // cout<<"===================="<<endl; 690 // cout<<"costRatio="<<ratio<<" pos="<<position<<" t="<<(position - minBox)/(maxBox - minBox) 691 // <<"\t q=("<<queriesBack<<","<<queriesFront<<")\t r=("<<raysBack<<","<<raysFront<<")"<<endl; 688 } 689 } 690 } 691 692 float oldCost = leaf->GetPvsSize(); 693 float newCost = ct_div_ci + minSum / sizeBox; 694 float ratio = newCost / oldCost; 695 696 // cout<<"===================="<<endl; 697 // cout<<"costRatio="<<ratio<<" pos="<<position<<" t="<<(position - minBox)/(maxBox - minBox) 698 // <<"\t q=("<<queriesBack<<","<<queriesFront<<")\t r=("<<raysBack<<","<<raysFront<<")"<<endl; 699 692 700 return ratio; 693 701 } 694 702 695 void 696 VspKdTree::SortSplitCandidates( 697 VspKdTreeLeaf *node, 698 const int axis 699 ) 700 { 701 702 splitCandidates->clear(); 703 704 int requestedSize = 2*(node->rays.size()); 705 // creates a sorted split candidates array 706 if (splitCandidates->capacity() > 500000 && 707 requestedSize < (int)(splitCandidates->capacity()/10) ) { 708 709 delete splitCandidates; 710 splitCandidates = new vector<SortableEntry>; 711 } 712 713 splitCandidates->reserve(requestedSize); 714 715 // insert all queries 716 for(VspKdTreeNode::RayInfoContainer::const_iterator ri = node->rays.begin(); 717 ri < node->rays.end(); 718 ri++) { 719 bool positive = (*ri).mRay->HasPosDir(axis); 720 splitCandidates->push_back(SortableEntry(positive ? SortableEntry::ERayMin : 721 SortableEntry::ERayMax, 722 (*ri).ExtrapOrigin(axis), 723 (void *)&*ri) 724 ); 725 726 splitCandidates->push_back(SortableEntry(positive ? SortableEntry::ERayMax : 727 SortableEntry::ERayMin, 728 (*ri).ExtrapTermination(axis), 729 (void *)&*ri) 730 ); 731 } 732 733 stable_sort(splitCandidates->begin(), splitCandidates->end()); 734 } 735 736 737 void 738 VspKdTree::EvaluateLeafStats(const TraversalData &data) 739 { 740 741 // the node became a leaf -> evaluate stats for leafs 742 VspKdTreeLeaf *leaf = (VspKdTreeLeaf *)data.node; 743 744 if (data.depth >= termMaxDepth) 745 stat.maxDepthNodes++; 703 void VspKdTree::SortSplitCandidates(VspKdTreeLeaf *node, 704 const int axis) 705 { 706 splitCandidates->clear(); 707 708 int requestedSize = 2*(node->rays.size()); 709 // creates a sorted split candidates array 710 if (splitCandidates->capacity() > 500000 && 711 requestedSize < (int)(splitCandidates->capacity()/10) ) 712 { 713 delete splitCandidates; 714 splitCandidates = new vector<SortableEntry>; 715 } 716 717 splitCandidates->reserve(requestedSize); 718 719 // insert all queries 720 for(VspKdTreeNode::RayInfoContainer::const_iterator ri = node->rays.begin(); 721 ri < node->rays.end(); ++ ri) 722 { 723 bool positive = (*ri).mRay->HasPosDir(axis); 724 splitCandidates->push_back(SortableEntry(positive ? SortableEntry::ERayMin : SortableEntry::ERayMax, 725 (*ri).ExtrapOrigin(axis), (void *)&*ri)); 726 727 splitCandidates->push_back(SortableEntry(positive ? SortableEntry::ERayMax : SortableEntry::ERayMin, 728 (*ri).ExtrapTermination(axis), (void *)&*ri)); 729 } 730 731 stable_sort(splitCandidates->begin(), splitCandidates->end()); 732 } 733 734 735 void VspKdTree::EvaluateLeafStats(const TraversalData &data) 736 { 737 // the node became a leaf -> evaluate stats for leafs 738 VspKdTreeLeaf *leaf = (VspKdTreeLeaf *)data.node; 739 740 if (data.depth >= termMaxDepth) 741 ++ stat.maxDepthNodes; 746 742 747 743 // if ( (int)(leaf->rays.size()) < termMinCost) 748 744 // stat.minCostNodes++; 749 if ( leaf->GetPvsSize() < termMinPvs) 750 stat.minPvsNodes++; 751 752 if ( leaf->GetPvsSize() < termMinRays) 753 stat.minRaysNodes++; 754 755 if (0 && leaf->GetAvgRayContribution() > termMaxRayContribution ) 756 stat.maxRayContribNodes++; 757 758 if (SqrMagnitude(data.bbox.Size()) <= termMinSize) { 759 stat.minSizeNodes++; 760 } 761 762 if ( (int)(leaf->rays.size()) > stat.maxRayRefs) 763 stat.maxRayRefs = leaf->rays.size(); 764 765 } 766 767 768 769 VspKdTreeNode * 770 VspKdTree::SubdivideNode( 771 VspKdTreeLeaf *leaf, 772 const AxisAlignedBox3 &box, 773 AxisAlignedBox3 &backBBox, 774 AxisAlignedBox3 &frontBBox 775 ) 776 { 777 778 if ( (leaf->GetPvsSize() < termMinPvs) || (leaf->rays.size() < termMinRays) || 745 if (leaf->GetPvsSize() < termMinPvs) 746 ++ stat.minPvsNodes; 747 748 if (leaf->GetPvsSize() < termMinRays) 749 ++ stat.minRaysNodes; 750 751 if (0 && leaf->GetAvgRayContribution() > termMaxRayContribution) 752 ++ stat.maxRayContribNodes; 753 754 if (SqrMagnitude(data.bbox.Size()) <= termMinSize) 755 ++ stat.minSizeNodes; 756 757 if ((int)(leaf->rays.size()) > stat.maxRayRefs) 758 stat.maxRayRefs = leaf->rays.size(); 759 } 760 761 762 763 VspKdTreeNode *VspKdTree::SubdivideNode(VspKdTreeLeaf *leaf, 764 const AxisAlignedBox3 &box, 765 AxisAlignedBox3 &backBBox, 766 AxisAlignedBox3 &frontBBox) 767 { 768 if ( (leaf->GetPvsSize() < termMinPvs) || (leaf->rays.size() < termMinRays) || 779 769 // (leaf->GetAvgRayContribution() > termMaxRayContribution ) || 780 770 (leaf->depth >= termMaxDepth) || SqrMagnitude(box.Size()) <= termMinSize ) 781 771 { 782 772 783 773 #if 0 … … 792 782 793 783 float position; 794 795 784 // first count ray sides 796 797 785 int raysBack; 786 int raysFront; 798 787 int pvsBack; 799 788 int pvsFront; 800 789 801 802 790 // select subdivision axis 791 int axis = SelectPlane( leaf, box, position, raysBack, raysFront, pvsBack, pvsFront); 803 792 804 793 // cout<<"rays back="<<raysBack<<" rays front="<<raysFront<<" pvs back="<<pvsBack<<" pvs front="<< 805 794 // pvsFront<<endl; 806 795 807 if (axis == -1) { 808 return leaf; 809 } 810 811 stat.nodes+=2; 812 stat.splits[axis]++; 813 814 // add the new nodes to the tree 815 VspKdTreeInterior *node = new VspKdTreeInterior(leaf->parent); 816 817 node->axis = axis; 818 node->position = position; 819 node->bbox = box; 820 node->dirBBox = GetDirBBox(leaf); 821 822 backBBox = box; 823 frontBBox = box; 824 825 VspKdTreeLeaf *back = new VspKdTreeLeaf(node, raysBack); 796 if (axis == -1) 797 { 798 return leaf; 799 } 800 801 stat.nodes += 2; 802 ++ stat.splits[axis]; 803 804 // add the new nodes to the tree 805 VspKdTreeInterior *node = new VspKdTreeInterior(leaf->parent); 806 807 node->axis = axis; 808 node->position = position; 809 node->bbox = box; 810 node->dirBBox = GetDirBBox(leaf); 811 812 backBBox = box; 813 frontBBox = box; 814 815 VspKdTreeLeaf *back = new VspKdTreeLeaf(node, raysBack); 826 816 back->SetPvsSize(pvsBack); 827 817 VspKdTreeLeaf *front = new VspKdTreeLeaf(node, raysFront); 828 818 front->SetPvsSize(pvsFront); 829 819 830 // replace a link from node's parent 831 if ( leaf->parent ) 832 leaf->parent->ReplaceChildLink(leaf, node); 833 // and setup child links 834 node->SetupChildLinks(back, front); 835 836 if (axis <= VspKdTreeNode::SPLIT_Z) { 820 // replace a link from node's parent 821 if (leaf->parent) 822 leaf->parent->ReplaceChildLink(leaf, node); 823 // and setup child links 824 node->SetupChildLinks(back, front); 825 826 if (axis <= VspKdTreeNode::SPLIT_Z) 827 { 837 828 backBBox.SetMax(axis, position); 838 829 frontBBox.SetMin(axis, position); 839 830 840 831 for(VspKdTreeNode::RayInfoContainer::iterator ri = leaf->rays.begin(); 841 ri != leaf->rays.end(); 842 ri++){843 if ((*ri).mRay->IsActive()) { 844 832 ri != leaf->rays.end(); ri++) 833 { 834 if ((*ri).mRay->IsActive()) 835 { 845 836 // first unref ray from the former leaf 846 837 (*ri).mRay->Unref(); … … 849 840 int side = node->ComputeRayIntersection(*ri, (*ri).mRay->mT); 850 841 851 if (side == 0) { 852 if ((*ri).mRay->HasPosDir(axis)) { 842 if (side == 0) 843 { 844 if ((*ri).mRay->HasPosDir(axis)) 845 { 853 846 back->AddRay(VspKdTreeNode::RayInfo((*ri).mRay, 854 (*ri).mMinT, 855 (*ri).mRay->mT) 856 ); 847 (*ri).mMinT, 848 (*ri).mRay->mT)); 857 849 front->AddRay(VspKdTreeNode::RayInfo((*ri).mRay, 858 (*ri).mRay->mT, 859 (*ri).mMaxT)); 860 } else { 850 (*ri).mRay->mT, 851 (*ri).mMaxT)); 852 } 853 else 854 { 861 855 back->AddRay(VspKdTreeNode::RayInfo((*ri).mRay, 862 863 856 (*ri).mRay->mT, 857 (*ri).mMaxT)); 864 858 front->AddRay(VspKdTreeNode::RayInfo((*ri).mRay, 865 866 859 (*ri).mMinT, 860 (*ri).mRay->mT)); 867 861 } 868 } else 862 } 863 else 869 864 if (side == 1) 870 865 front->AddRay(*ri); 871 866 else 872 867 back->AddRay(*ri); 873 868 } else 874 869 (*ri).mRay->Unref(); 875 } 876 } else { 877 // rays front/back 870 } 871 } 872 else 873 { 874 // rays front/back 878 875 879 880 for(VspKdTreeNode::RayInfoContainer::iterator ri = leaf->rays.begin(); 881 ri != leaf->rays.end();882 ri++) {883 if ((*ri).mRay->IsActive()){876 for(VspKdTreeNode::RayInfoContainer::iterator ri = leaf->rays.begin(); 877 ri != leaf->rays.end(); ++ ri) 878 { 879 if ((*ri).mRay->IsActive()) 880 { 884 881 // first unref ray from the former leaf 885 882 (*ri).mRay->Unref(); … … 894 891 front->AddRay(*ri); 895 892 else 896 back->AddRay(*ri); 897 898 }else893 back->AddRay(*ri); 894 } 895 else 899 896 (*ri).mRay->Unref(); 900 } 901 } 902 903 // update stats 904 stat.rayRefs -= leaf->rays.size(); 905 stat.rayRefs += raysBack + raysFront; 906 907 908 delete leaf; 909 return node; 910 } 911 912 913 914 915 916 917 int 918 VspKdTree::ReleaseMemory(const int time) 919 { 920 stack<VspKdTreeNode *> tstack; 921 922 // find a node in the tree which subtree will be collapsed 923 int maxAccessTime = time - accessTimeThreshold; 924 int released; 925 926 tstack.push(root); 927 928 while (!tstack.empty()) { 929 VspKdTreeNode *node = tstack.top(); 930 tstack.pop(); 897 } 898 } 899 900 // update stats 901 stat.rayRefs -= leaf->rays.size(); 902 stat.rayRefs += raysBack + raysFront; 903 904 delete leaf; 905 return node; 906 } 907 908 int VspKdTree::ReleaseMemory(const int time) 909 { 910 stack<VspKdTreeNode *> tstack; 911 912 // find a node in the tree which subtree will be collapsed 913 int maxAccessTime = time - accessTimeThreshold; 914 int released; 915 916 tstack.push(root); 917 918 while (!tstack.empty()) 919 { 920 VspKdTreeNode *node = tstack.top(); 921 tstack.pop(); 931 922 932 933 if (!node->IsLeaf()) { 934 VspKdTreeInterior *in = (VspKdTreeInterior *)node; 935 // cout<<"depth="<<(int)in->depth<<" time="<<in->lastAccessTime<<endl; 936 if (in->depth >= minCollapseDepth && 937 in->lastAccessTime <= maxAccessTime) { 938 released = CollapseSubtree(node, time); 939 break; 940 } 941 942 if (in->back->GetAccessTime() < 943 in->front->GetAccessTime()) { 944 tstack.push(in->front); 945 tstack.push(in->back); 946 } else { 947 tstack.push(in->back); 948 tstack.push(in->front); 949 } 950 } 951 } 952 953 while (tstack.empty()) { 954 // could find node to collaps... 955 // cout<<"Could not find a node to release "<<endl; 956 break; 957 } 958 959 return released; 960 } 961 962 963 964 965 VspKdTreeNode * 966 VspKdTree::SubdivideLeaf( 967 VspKdTreeLeaf *leaf, 968 const float sizeThreshold 969 ) 970 { 971 VspKdTreeNode *node = leaf; 972 973 AxisAlignedBox3 leafBBox = GetBBox(leaf); 923 if (!node->IsLeaf()) 924 { 925 VspKdTreeInterior *in = (VspKdTreeInterior *)node; 926 // cout<<"depth="<<(int)in->depth<<" time="<<in->lastAccessTime<<endl; 927 if (in->depth >= minCollapseDepth && in->lastAccessTime <= maxAccessTime) 928 { 929 released = CollapseSubtree(node, time); 930 break; 931 } 932 if (in->back->GetAccessTime() < in->front->GetAccessTime()) 933 { 934 tstack.push(in->front); 935 tstack.push(in->back); 936 } 937 else 938 { 939 tstack.push(in->back); 940 tstack.push(in->front); 941 } 942 } 943 } 944 945 while (tstack.empty()) 946 { 947 // could find node to collaps... 948 // cout<<"Could not find a node to release "<<endl; 949 break; 950 } 951 952 return released; 953 } 954 955 956 957 958 VspKdTreeNode *VspKdTree::SubdivideLeaf(VspKdTreeLeaf *leaf, 959 const float sizeThreshold) 960 { 961 VspKdTreeNode *node = leaf; 962 963 AxisAlignedBox3 leafBBox = GetBBox(leaf); 974 964 975 965 static int pass = 0; 976 pass ++; 977 978 // check if we should perform a dynamic subdivision of the leaf 979 if ( 980 // leaf->rays.size() > (unsigned)termMinCost && 981 (leaf->GetPvsSize() >= termMinPvs) && 982 SqrMagnitude(leafBBox.Size()) > sizeThreshold) { 983 984 // memory check and realese... 985 if (GetMemUsage() > maxTotalMemory) { 986 ReleaseMemory( pass ); 987 } 988 989 AxisAlignedBox3 backBBox, frontBBox; 990 991 // subdivide the node 992 node = 993 SubdivideNode(leaf, 994 leafBBox, 995 backBBox, 996 frontBBox 997 ); 998 } 999 return node; 966 ++ pass; 967 968 // check if we should perform a dynamic subdivision of the leaf 969 if (// leaf->rays.size() > (unsigned)termMinCost && 970 (leaf->GetPvsSize() >= termMinPvs) && 971 (SqrMagnitude(leafBBox.Size()) > sizeThreshold) ) 972 { 973 // memory check and realese... 974 if (GetMemUsage() > maxTotalMemory) 975 ReleaseMemory(pass); 976 977 AxisAlignedBox3 backBBox, frontBBox; 978 979 // subdivide the node 980 node = SubdivideNode(leaf, leafBBox, backBBox, frontBBox); 981 } 982 return node; 1000 983 } 1001 984 … … 1004 987 void 1005 988 VspKdTree::UpdateRays(VssRayContainer &remove, 1006 VssRayContainer &add 1007 ) 1008 { 1009 VspKdTreeLeaf::NewMail(); 1010 1011 // schedule rays for removal 1012 for(VssRayContainer::const_iterator ri = remove.begin(); 1013 ri != remove.end(); 1014 ri++) { 1015 (*ri)->ScheduleForRemoval(); 1016 } 1017 1018 int inactive=0; 1019 1020 for(VssRayContainer::const_iterator ri = remove.begin(); 1021 ri != remove.end(); 1022 ri++) { 1023 if ((*ri)->ScheduledForRemoval()) 1024 // RemoveRay(*ri, NULL, false); 1025 // !!! BUG - with true it does not work correctly - aggreated delete 1026 RemoveRay(*ri, NULL, true); 1027 else 1028 inactive++; 1029 } 1030 1031 1032 // cout<<"all/inactive"<<remove.size()<<"/"<<inactive<<endl; 1033 1034 for(VssRayContainer::const_iterator ri = add.begin(); 1035 ri != add.end(); 1036 ri++) { 1037 AddRay(*ri); 1038 } 1039 1040 1041 } 1042 1043 1044 void 1045 VspKdTree::RemoveRay(VssRay *ray, 1046 vector<VspKdTreeLeaf *> *affectedLeaves, 1047 const bool removeAllScheduledRays 1048 ) 1049 { 1050 1051 stack<RayTraversalData> tstack; 1052 1053 tstack.push(RayTraversalData(root, VspKdTreeNode::RayInfo(ray))); 1054 1055 RayTraversalData data; 1056 1057 // cout<<"Number of ray refs = "<<ray->RefCount()<<endl; 1058 1059 while (!tstack.empty()) { 1060 data = tstack.top(); 1061 tstack.pop(); 1062 1063 if (!data.node->IsLeaf()) { 1064 // split the set of rays in two groups intersecting the 1065 // two subtrees 1066 1067 TraverseInternalNode(data, tstack); 989 VssRayContainer &add) 990 { 991 VspKdTreeLeaf::NewMail(); 992 993 // schedule rays for removal 994 for(VssRayContainer::const_iterator ri = remove.begin(); 995 ri != remove.end(); ++ ri) 996 { 997 (*ri)->ScheduleForRemoval(); 998 } 999 1000 int inactive = 0; 1001 1002 for (VssRayContainer::const_iterator ri = remove.begin(); ri != remove.end(); ++ ri) 1003 { 1004 if ((*ri)->ScheduledForRemoval()) 1005 // RemoveRay(*ri, NULL, false); 1006 // !!! BUG - with true it does not work correctly - aggreated delete 1007 RemoveRay(*ri, NULL, true); 1008 else 1009 ++ inactive; 1010 } 1011 1012 // cout<<"all/inactive"<<remove.size()<<"/"<<inactive<<endl; 1013 1014 for(VssRayContainer::const_iterator ri = add.begin(); ri != add.end(); ++ ri) 1015 { 1016 AddRay(*ri); 1017 } 1018 } 1019 1020 1021 void VspKdTree::RemoveRay(VssRay *ray, 1022 vector<VspKdTreeLeaf *> *affectedLeaves, 1023 const bool removeAllScheduledRays) 1024 { 1025 stack<RayTraversalData> tstack; 1026 1027 tstack.push(RayTraversalData(root, VspKdTreeNode::RayInfo(ray))); 1028 1029 RayTraversalData data; 1030 1031 // cout<<"Number of ray refs = "<<ray->RefCount()<<endl; 1032 while (!tstack.empty()) 1033 { 1034 data = tstack.top(); 1035 tstack.pop(); 1036 1037 if (!data.node->IsLeaf()) 1038 { 1039 // split the set of rays in two groups intersecting the 1040 // two subtrees 1041 1042 TraverseInternalNode(data, tstack); 1043 } 1044 else 1045 { 1046 // remove the ray from the leaf 1047 // find the ray in the leaf and swap it with the last ray... 1048 VspKdTreeLeaf *leaf = (VspKdTreeLeaf *)data.node; 1068 1049 1069 } else { 1070 // remove the ray from the leaf 1071 // find the ray in the leaf and swap it with the last ray... 1072 VspKdTreeLeaf *leaf = (VspKdTreeLeaf *)data.node; 1050 if (!leaf->Mailed()) 1051 { 1052 leaf->Mail(); 1053 1054 if (affectedLeaves) 1055 affectedLeaves->push_back(leaf); 1056 1057 if (removeAllScheduledRays) 1058 { 1059 int tail = leaf->rays.size() - 1; 1060 1061 for (int i=0; i < (int)(leaf->rays.size()); ++ i) 1062 { 1063 if (leaf->rays[i].mRay->ScheduledForRemoval()) 1064 { 1065 // find a ray to replace it with 1066 while (tail >= i && leaf->rays[tail].mRay->ScheduledForRemoval()) 1067 { 1068 ++ stat.removedRayRefs; 1069 leaf->rays[tail].mRay->Unref(); 1070 leaf->rays.pop_back(); 1071 1072 -- tail; 1073 } 1074 1075 if (tail < i) 1076 break; 1077 1078 ++ stat.removedRayRefs; 1079 1080 leaf->rays[i].mRay->Unref(); 1081 leaf->rays[i] = leaf->rays[tail]; 1082 leaf->rays.pop_back(); 1083 -- tail; 1084 } 1085 } 1086 } 1087 } 1073 1088 1074 if (!leaf->Mailed()) { 1075 leaf->Mail(); 1076 if (affectedLeaves) 1077 affectedLeaves->push_back(leaf); 1078 1079 if (removeAllScheduledRays) { 1080 int tail = leaf->rays.size()-1; 1081 1082 for (int i=0; i < (int)(leaf->rays.size()); i++) { 1083 if (leaf->rays[i].mRay->ScheduledForRemoval()) { 1084 // find a ray to replace it with 1085 while (tail >= i && leaf->rays[tail].mRay->ScheduledForRemoval()) { 1086 stat.removedRayRefs++; 1087 leaf->rays[tail].mRay->Unref(); 1088 leaf->rays.pop_back(); 1089 tail--; 1090 } 1091 1092 if (tail < i) 1093 break; 1094 1095 stat.removedRayRefs++; 1096 leaf->rays[i].mRay->Unref(); 1097 leaf->rays[i] = leaf->rays[tail]; 1098 leaf->rays.pop_back(); 1099 tail--; 1100 } 1101 } 1102 } 1103 } 1104 1105 if (!removeAllScheduledRays) 1106 for (int i=0; i < (int)leaf->rays.size(); i++) { 1107 if (leaf->rays[i].mRay == ray) { 1108 stat.removedRayRefs++; 1109 ray->Unref(); 1110 leaf->rays[i] = leaf->rays[leaf->rays.size()-1]; 1111 leaf->rays.pop_back(); 1112 // check this ray again 1113 break; 1114 } 1115 } 1116 1117 } 1118 } 1119 1120 if (ray->RefCount() != 0) { 1121 cerr<<"Error: Number of remaining refs = "<<ray->RefCount()<<endl; 1122 exit(1); 1123 } 1124 1125 } 1126 1127 1128 void 1129 VspKdTree::AddRay(VssRay *ray) 1130 { 1131 1132 stack<RayTraversalData> tstack; 1133 1134 tstack.push(RayTraversalData(root, VspKdTreeNode::RayInfo(ray))); 1135 1136 RayTraversalData data; 1137 1138 while (!tstack.empty()) { 1139 data = tstack.top(); 1140 tstack.pop(); 1141 1142 if (!data.node->IsLeaf()) { 1143 TraverseInternalNode(data, tstack); 1144 } else { 1145 // remove the ray from the leaf 1146 // find the ray in the leaf and swap it with the last ray... 1147 VspKdTreeLeaf *leaf = (VspKdTreeLeaf *)data.node; 1148 leaf->AddRay(data.rayData); 1149 stat.addedRayRefs++; 1150 } 1151 } 1152 } 1153 1154 void 1155 VspKdTree::TraverseInternalNode( 1156 RayTraversalData &data, 1157 stack<RayTraversalData> &tstack) 1158 { 1159 VspKdTreeInterior *in = (VspKdTreeInterior *) data.node; 1160 1161 if (in->axis <= VspKdTreeNode::SPLIT_Z) { 1162 1163 // determine the side of this ray with respect to the plane 1164 int side = in->ComputeRayIntersection(data.rayData, 1165 data.rayData.mRay->mT); 1089 if (!removeAllScheduledRays) 1090 for (int i=0; i < (int)leaf->rays.size(); i++) 1091 { 1092 if (leaf->rays[i].mRay == ray) 1093 { 1094 ++ stat.removedRayRefs; 1095 ray->Unref(); 1096 leaf->rays[i] = leaf->rays[leaf->rays.size() - 1]; 1097 leaf->rays.pop_back(); 1098 // check this ray again 1099 break; 1100 } 1101 } 1102 } 1103 } 1104 1105 if (ray->RefCount() != 0) 1106 { 1107 cerr << "Error: Number of remaining refs = " << ray->RefCount() << endl; 1108 exit(1); 1109 } 1110 1111 } 1112 1113 void VspKdTree::AddRay(VssRay *ray) 1114 { 1115 stack<RayTraversalData> tstack; 1116 1117 tstack.push(RayTraversalData(root, VspKdTreeNode::RayInfo(ray))); 1118 1119 RayTraversalData data; 1120 1121 while (!tstack.empty()) 1122 { 1123 data = tstack.top(); 1124 tstack.pop(); 1125 1126 if (!data.node->IsLeaf()) 1127 { 1128 TraverseInternalNode(data, tstack); 1129 } 1130 else 1131 { 1132 // remove the ray from the leaf 1133 // find the ray in the leaf and swap it with the last ray... 1134 VspKdTreeLeaf *leaf = (VspKdTreeLeaf *)data.node; 1135 leaf->AddRay(data.rayData); 1136 ++ stat.addedRayRefs; 1137 } 1138 } 1139 } 1140 1141 void VspKdTree::TraverseInternalNode(RayTraversalData &data, 1142 stack<RayTraversalData> &tstack) 1143 { 1144 VspKdTreeInterior *in = (VspKdTreeInterior *) data.node; 1145 1146 if (in->axis <= VspKdTreeNode::SPLIT_Z) 1147 { 1148 // determine the side of this ray with respect to the plane 1149 int side = in->ComputeRayIntersection(data.rayData, data.rayData.mRay->mT); 1166 1150 1167 1168 if (side == 0) { 1169 if (data.rayData.mRay->HasPosDir(in->axis)) { 1170 tstack.push(RayTraversalData(in->back, 1171 VspKdTreeNode::RayInfo(data.rayData.mRay, 1172 data.rayData.mMinT, 1173 data.rayData.mRay->mT)) 1174 ); 1151 if (side == 0) 1152 { 1153 if (data.rayData.mRay->HasPosDir(in->axis)) 1154 { 1155 tstack.push(RayTraversalData(in->back, 1156 VspKdTreeNode::RayInfo(data.rayData.mRay, data.rayData.mMinT, 1157 data.rayData.mRay->mT))); 1175 1158 1176 tstack.push(RayTraversalData(in->front, 1177 VspKdTreeNode::RayInfo(data.rayData.mRay, 1178 data.rayData.mRay->mT, 1179 data.rayData.mMaxT 1180 )) 1181 ); 1182 1183 } else { 1184 tstack.push(RayTraversalData(in->back, 1185 VspKdTreeNode::RayInfo(data.rayData.mRay, 1186 data.rayData.mRay->mT, 1187 data.rayData.mMaxT 1188 )) 1189 ); 1190 1191 tstack.push(RayTraversalData(in->front, 1192 VspKdTreeNode::RayInfo(data.rayData.mRay, 1193 data.rayData.mMinT, 1194 data.rayData.mRay->mT)) 1195 ); 1196 1197 1198 } 1199 } else 1200 if (side == 1) 1201 tstack.push(RayTraversalData(in->front, data.rayData)); 1202 else 1203 tstack.push(RayTraversalData(in->back, data.rayData)); 1204 } 1205 else { 1206 // directional split 1159 tstack.push(RayTraversalData(in->front, 1160 VspKdTreeNode::RayInfo(data.rayData.mRay, data.rayData.mRay->mT, 1161 data.rayData.mMaxT))); 1162 1163 } 1164 else 1165 { 1166 tstack.push(RayTraversalData(in->back, 1167 VspKdTreeNode::RayInfo(data.rayData.mRay, 1168 data.rayData.mRay->mT, 1169 data.rayData.mMaxT))); 1170 tstack.push(RayTraversalData(in->front, 1171 VspKdTreeNode::RayInfo(data.rayData.mRay, 1172 data.rayData.mMinT, 1173 data.rayData.mRay->mT))); 1174 } 1175 } 1176 else 1177 if (side == 1) 1178 tstack.push(RayTraversalData(in->front, data.rayData)); 1179 else 1180 tstack.push(RayTraversalData(in->back, data.rayData)); 1181 } 1182 else 1183 { 1184 // directional split 1207 1185 if (data.rayData.mRay->GetDirParametrization(in->axis - 3) > in->position) 1208 1186 tstack.push(RayTraversalData(in->front, data.rayData)); 1209 1187 else 1210 1188 tstack.push(RayTraversalData(in->back, data.rayData)); 1211 1212 } 1213 1214 1215 int 1216 VspKdTree::CollapseSubtree(VspKdTreeNode *sroot, const int time) 1217 { 1218 // first count all rays in the subtree1219 // use mail 1 for this purpose 1220 stack<VspKdTreeNode *> tstack; 1221 1222 1223 1189 } 1190 } 1191 1192 1193 int VspKdTree::CollapseSubtree(VspKdTreeNode *sroot, const int time) 1194 { 1195 // first count all rays in the subtree 1196 // use mail 1 for this purpose 1197 stack<VspKdTreeNode *> tstack; 1198 1199 int rayCount = 0; 1200 int totalRayCount = 0; 1201 int collapsedNodes = 0; 1224 1202 1225 1203 #if DEBUG_COLLAPSE 1226 1227 1228 1204 cout<<"Collapsing subtree"<<endl; 1205 cout<<"acessTime="<<sroot->GetAccessTime()<<endl; 1206 cout<<"depth="<<(int)sroot->depth<<endl; 1229 1207 #endif 1230 1208 1231 // tstat.collapsedSubtrees++; 1232 // tstat.collapseDepths += (int)sroot->depth; 1233 // tstat.collapseAccessTimes += time - sroot->GetAccessTime(); 1234 1235 tstack.push(sroot); 1236 VssRay::NewMail(); 1237 1238 while (!tstack.empty()) { 1239 collapsedNodes++; 1240 VspKdTreeNode *node = tstack.top(); 1241 tstack.pop(); 1242 1243 if (node->IsLeaf()) { 1244 VspKdTreeLeaf *leaf = (VspKdTreeLeaf *) node; 1245 for(VspKdTreeNode::RayInfoContainer::iterator ri = leaf->rays.begin(); 1246 ri != leaf->rays.end(); 1247 ri++) { 1209 // tstat.collapsedSubtrees++; 1210 // tstat.collapseDepths += (int)sroot->depth; 1211 // tstat.collapseAccessTimes += time - sroot->GetAccessTime(); 1212 tstack.push(sroot); 1213 VssRay::NewMail(); 1214 1215 while (!tstack.empty()) 1216 { 1217 ++ collapsedNodes; 1218 1219 VspKdTreeNode *node = tstack.top(); 1220 tstack.pop(); 1221 if (node->IsLeaf()) 1222 { 1223 VspKdTreeLeaf *leaf = (VspKdTreeLeaf *) node; 1224 1225 for(VspKdTreeNode::RayInfoContainer::iterator ri = leaf->rays.begin(); 1226 ri != leaf->rays.end(); ++ ri) 1227 { 1228 ++ totalRayCount; 1248 1229 1249 totalRayCount++;1250 if ((*ri).mRay->IsActive() && !(*ri).mRay->Mailed()){1230 if ((*ri).mRay->IsActive() && !(*ri).mRay->Mailed()) 1231 { 1251 1232 (*ri).mRay->Mail(); 1252 rayCount++;1233 ++ rayCount; 1253 1234 } 1254 } 1255 } else { 1256 tstack.push(((VspKdTreeInterior *)node)->back); 1257 tstack.push(((VspKdTreeInterior *)node)->front); 1258 } 1259 } 1260 1261 VssRay::NewMail(); 1262 1263 // create a new node that will hold the rays 1264 VspKdTreeLeaf *newLeaf = new VspKdTreeLeaf( sroot->parent, rayCount ); 1265 if ( newLeaf->parent ) 1266 newLeaf->parent->ReplaceChildLink(sroot, newLeaf); 1267 1268 1269 tstack.push( sroot ); 1270 1271 while (!tstack.empty()) { 1272 1273 VspKdTreeNode *node = tstack.top(); 1274 tstack.pop(); 1275 1276 if (node->IsLeaf()) { 1277 VspKdTreeLeaf *leaf = (VspKdTreeLeaf *) node; 1278 1279 for(VspKdTreeNode::RayInfoContainer::iterator ri = leaf->rays.begin(); 1280 ri != leaf->rays.end(); 1281 ri++) { 1282 1283 // unref this ray from the old node 1284 1285 if ((*ri).mRay->IsActive()) { 1235 } 1236 } 1237 else 1238 { 1239 tstack.push(((VspKdTreeInterior *)node)->back); 1240 tstack.push(((VspKdTreeInterior *)node)->front); 1241 } 1242 } 1243 1244 VssRay::NewMail(); 1245 1246 // create a new node that will hold the rays 1247 VspKdTreeLeaf *newLeaf = new VspKdTreeLeaf(sroot->parent, rayCount); 1248 1249 if (newLeaf->parent) 1250 newLeaf->parent->ReplaceChildLink(sroot, newLeaf); 1251 1252 tstack.push(sroot); 1253 1254 while (!tstack.empty()) 1255 { 1256 VspKdTreeNode *node = tstack.top(); 1257 tstack.pop(); 1258 1259 if (node->IsLeaf()) 1260 { 1261 VspKdTreeLeaf *leaf = (VspKdTreeLeaf *) node; 1262 1263 for(VspKdTreeNode::RayInfoContainer::iterator ri = leaf->rays.begin(); 1264 ri != leaf->rays.end(); ++ ri) 1265 { 1266 // unref this ray from the old node 1267 if ((*ri).mRay->IsActive()) 1268 { 1286 1269 (*ri).mRay->Unref(); 1287 if (!(*ri).mRay->Mailed()) { 1270 if (!(*ri).mRay->Mailed()) 1271 { 1288 1272 (*ri).mRay->Mail(); 1289 1273 newLeaf->AddRay(*ri); 1290 1274 } 1291 } else 1275 } 1276 else 1292 1277 (*ri).mRay->Unref(); 1293 1294 } 1295 } else { 1296 tstack.push(((VspKdTreeInterior *)node)->back); 1297 tstack.push(((VspKdTreeInterior *)node)->front); 1298 } 1299 } 1300 1301 // delete the node and all its children 1302 delete sroot; 1303 1304 // for(VspKdTreeNode::SRayContainer::iterator ri = newLeaf->rays.begin(); 1305 // ri != newLeaf->rays.end(); 1306 // ri++) 1307 // (*ri).ray->UnMail(2); 1308 1278 } 1279 } 1280 else 1281 { 1282 tstack.push(((VspKdTreeInterior *)node)->back); 1283 tstack.push(((VspKdTreeInterior *)node)->front); 1284 } 1285 } 1286 1287 // delete the node and all its children 1288 delete sroot; 1289 1290 // for(VspKdTreeNode::SRayContainer::iterator ri = newLeaf->rays.begin(); 1291 // ri != newLeaf->rays.end(); ++ ri) 1292 // (*ri).ray->UnMail(2); 1309 1293 1310 1294 #if DEBUG_COLLAPSE 1311 1295 cout<<"Total memory before="<<GetMemUsage()<<endl; 1312 1296 #endif 1313 1297 1314 1315 1298 stat.nodes -= collapsedNodes - 1; 1299 stat.rayRefs -= totalRayCount - rayCount; 1316 1300 1317 1301 #if DEBUG_COLLAPSE 1318 cout<<"collapsed nodes"<<collapsedNodes<<endl;1319 cout<<"collapsed rays"<<totalRayCount - rayCount<<endl;1320 cout<<"Total memory after="<<GetMemUsage()<<endl;1321 cout<<"================================"<<endl;1302 cout << "collapsed nodes" << collapsedNodes << endl; 1303 cout << "collapsed rays" << totalRayCount - rayCount << endl; 1304 cout << "Total memory after=" << GetMemUsage() << endl; 1305 cout << "================================" << endl; 1322 1306 #endif 1323 1307 1324 1308 // tstat.collapsedNodes += collapsedNodes; 1325 1309 // tstat.collapsedRays += totalRayCount - rayCount; 1326 1327 return totalRayCount - rayCount; 1328 } 1329 1330 1331 int 1332 VspKdTree::GetPvsSize(VspKdTreeNode *node, const AxisAlignedBox3 &box) const 1310 return totalRayCount - rayCount; 1311 } 1312 1313 1314 int VspKdTree::GetPvsSize(VspKdTreeNode *node, const AxisAlignedBox3 &box) const 1333 1315 { 1334 1316 stack<VspKdTreeNode *> tstack; 1335 1317 tstack.push(root); 1336 1318 1337 1319 Intersectable::NewMail(); 1338 1320 int pvsSize = 0; 1339 1321 1340 while (!tstack.empty()) { 1341 VspKdTreeNode *node = tstack.top(); 1342 tstack.pop(); 1322 while (!tstack.empty()) 1323 { 1324 VspKdTreeNode *node = tstack.top(); 1325 tstack.pop(); 1343 1326 1344 1345 if (node->IsLeaf()){1327 if (node->IsLeaf()) 1328 { 1346 1329 VspKdTreeLeaf *leaf = (VspKdTreeLeaf *)node; 1347 for(VspKdTreeNode::RayInfoContainer::iterator ri = leaf->rays.begin(); 1348 ri != leaf->rays.end(); 1349 ri++) 1350 if ((*ri).mRay->IsActive()) { 1330 for (VspKdTreeNode::RayInfoContainer::iterator ri = leaf->rays.begin(); 1331 ri != leaf->rays.end(); ++ ri) 1332 { 1333 if ((*ri).mRay->IsActive()) 1334 { 1351 1335 Intersectable *object; 1352 1336 #if BIDIRECTIONAL_RAY 1353 1337 object = (*ri).mRay->mOriginObject; 1354 if (object && !object->Mailed()) { 1355 pvsSize++; 1338 1339 if (object && !object->Mailed()) 1340 { 1341 ++ pvsSize; 1356 1342 object->Mail(); 1357 1343 } 1358 1344 #endif 1359 1345 object = (*ri).mRay->mTerminationObject; 1360 if (object && !object->Mailed()) { 1361 pvsSize++; 1346 if (object && !object->Mailed()) 1347 { 1348 ++ pvsSize; 1362 1349 object->Mail(); 1363 1350 } 1364 1351 } 1365 } else { 1352 } 1353 } 1354 else 1355 { 1366 1356 VspKdTreeInterior *in = (VspKdTreeInterior *)node; 1367 if (in->axis < 3) { 1368 if (box.Max(in->axis) >= in->position ) 1357 1358 if (in->axis < 3) 1359 { 1360 if (box.Max(in->axis) >= in->position) 1369 1361 tstack.push(in->front); 1370 1362 1371 if (box.Min(in->axis) <= in->position 1363 if (box.Min(in->axis) <= in->position) 1372 1364 tstack.push(in->back); 1373 } else { 1365 } 1366 else 1367 { 1374 1368 // both nodes for directional splits 1375 1369 tstack.push(in->front); … … 1378 1372 } 1379 1373 } 1374 1380 1375 return pvsSize; 1381 1376 } 1382 1377 1383 void 1384 VspKdTree::GetRayContributionStatistics( 1385 float &minRayContribution, 1386 float &maxRayContribution, 1387 float &avgRayContribution 1388 ) 1378 void VspKdTree::GetRayContributionStatistics(float &minRayContribution, 1379 float &maxRayContribution, 1380 float &avgRayContribution) 1389 1381 { 1390 1382 stack<VspKdTreeNode *> tstack; 1391 1383 tstack.push(root); 1392 1384 1393 1385 minRayContribution = 1.0f; 1394 1386 maxRayContribution = 0.0f; 1387 1395 1388 float sumRayContribution = 0.0f; 1396 1389 int leaves = 0; 1397 1390 1398 while (!tstack.empty()) { 1399 VspKdTreeNode *node = tstack.top(); 1400 tstack.pop(); 1401 1402 if (node->IsLeaf()) { 1391 while (!tstack.empty()) 1392 { 1393 VspKdTreeNode *node = tstack.top(); 1394 tstack.pop(); 1395 if (node->IsLeaf()) 1396 { 1403 1397 leaves++; 1404 1398 VspKdTreeLeaf *leaf = (VspKdTreeLeaf *)node; 1405 1399 float c = leaf->GetAvgRayContribution(); 1400 1406 1401 if (c > maxRayContribution) 1407 1402 maxRayContribution = c; … … 1410 1405 sumRayContribution += c; 1411 1406 1412 } else { 1407 } 1408 else { 1413 1409 VspKdTreeInterior *in = (VspKdTreeInterior *)node; 1414 1410 // both nodes for directional splits … … 1424 1420 1425 1421 1426 int 1427 VspKdTree::GenerateRays(const float ratioPerLeaf, 1428 SimpleRayContainer &rays) 1422 int VspKdTree::GenerateRays(const float ratioPerLeaf, 1423 SimpleRayContainer &rays) 1429 1424 { 1430 1425 stack<VspKdTreeNode *> tstack; 1431 tstack.push(root); 1432 1433 while (!tstack.empty()) { 1434 VspKdTreeNode *node = tstack.top(); 1435 tstack.pop(); 1436 1437 if (node->IsLeaf()) { 1426 tstack.push(root); 1427 1428 while (!tstack.empty()) 1429 { 1430 VspKdTreeNode *node = tstack.top(); 1431 tstack.pop(); 1432 1433 if (node->IsLeaf()) 1434 { 1438 1435 VspKdTreeLeaf *leaf = (VspKdTreeLeaf *)node; 1439 1436 float c = leaf->GetAvgRayContribution(); … … 1441 1438 // cout<<num<<" "; 1442 1439 1443 for (int i=0; i < num; i++) { 1440 for (int i=0; i < num; i++) 1441 { 1444 1442 Vector3 origin = GetBBox(leaf).GetRandomPoint(); 1445 1443 Vector3 dirVector = GetDirBBox(leaf).GetRandomPoint(); … … 1449 1447 } 1450 1448 1451 } else { 1449 } 1450 else 1451 { 1452 1452 VspKdTreeInterior *in = (VspKdTreeInterior *)node; 1453 1453 // both nodes for directional splits … … 1461 1461 1462 1462 1463 float 1464 VspKdTree::GetAvgPvsSize() 1463 float VspKdTree::GetAvgPvsSize() 1465 1464 { 1466 1465 stack<VspKdTreeNode *> tstack; 1467 1466 tstack.push(root); 1468 1467 1469 1468 int sumPvs = 0; 1470 1469 int leaves = 0; 1471 while (!tstack.empty()) { 1472 VspKdTreeNode *node = tstack.top(); 1473 tstack.pop(); 1474 1475 if (node->IsLeaf()) { 1470 1471 while (!tstack.empty()) 1472 { 1473 VspKdTreeNode *node = tstack.top(); 1474 tstack.pop(); 1475 1476 if (node->IsLeaf()) 1477 { 1476 1478 VspKdTreeLeaf *leaf = (VspKdTreeLeaf *)node; 1477 1479 // update pvs size … … 1479 1481 sumPvs += leaf->GetPvsSize(); 1480 1482 leaves++; 1481 } else { 1483 } 1484 else 1485 { 1482 1486 VspKdTreeInterior *in = (VspKdTreeInterior *)node; 1483 1487 // both nodes for directional splits … … 1487 1491 } 1488 1492 1489 1490 return sumPvs/(float)leaves; 1491 } 1493 return sumPvs / (float)leaves; 1494 } -
trunk/VUT/GtpVisibilityPreprocessor/src/VspKdTree.h
r408 r410 374 374 // KD-tree node - leaf node 375 375 // -------------------------------------------------------------- 376 class VspKdTreeLeaf : 377 public VspKdTreeNode 376 class VspKdTreeLeaf : public VspKdTreeNode 378 377 { 379 378 private: 380 379 int mPvsSize; 381 380 public: 382 383 384 385 381 static int mailID; 382 int mailbox; 383 384 RayInfoContainer rays; 386 385 bool mValidPvs; 387 386 388 VspKdTreeLeaf(VspKdTreeInterior *p, 389 const int nRays 390 ):VspKdTreeNode(p), rays(), mPvsSize(0), mValidPvs(false) { 391 rays.reserve(nRays); 392 } 393 394 virtual ~VspKdTreeLeaf() { } 395 396 virtual int Type() const { return ELeaf; } 397 398 virtual void Print(ostream &s) const { 399 s<<endl<<"L: r="<<rays.size()<<endl; 400 }; 401 402 void AddRay(const RayInfo &data) { 387 VspKdTreeLeaf(VspKdTreeInterior *p, const int nRays): 388 VspKdTreeNode(p), rays(), mPvsSize(0), mValidPvs(false) 389 { 390 rays.reserve(nRays); 391 } 392 393 virtual ~VspKdTreeLeaf() { } 394 395 virtual int Type() const 396 { 397 return ELeaf; 398 } 399 400 virtual void Print(ostream &s) const 401 { 402 s << endl << "L: r = " << rays.size() << endl; 403 }; 404 405 void AddRay(const RayInfo &data) 406 { 403 407 mValidPvs = false; 404 rays.push_back(data); 405 data.mRay->Ref(); 406 } 407 408 int GetPvsSize() const { 408 rays.push_back(data); 409 data.mRay->Ref(); 410 } 411 412 int GetPvsSize() const 413 { 409 414 return mPvsSize; 410 415 } 411 void SetPvsSize(const int s) { 416 void SetPvsSize(const int s) 417 { 412 418 mPvsSize = s; 413 419 } 414 420 415 void 416 UpdatePvsSize(); 417 418 void Mail() { mailbox = mailID; } 419 static void NewMail() { mailID++; } 420 bool Mailed() const { return mailbox == mailID; } 421 422 bool Mailed(const int mail) { 423 return mailbox >= mailID + mail; 424 } 425 426 float GetAvgRayContribution() const { 421 void UpdatePvsSize(); 422 423 void Mail() 424 { 425 mailbox = mailID; 426 } 427 428 static void NewMail() 429 { 430 ++ mailID; 431 } 432 433 bool Mailed() const 434 { 435 return mailbox == mailID; 436 } 437 438 bool Mailed(const int mail) 439 { 440 return mailbox >= mailID + mail; 441 } 442 443 float GetAvgRayContribution() const 444 { 427 445 return GetPvsSize()/((float)rays.size() + Limits::Small); 428 446 } 429 447 430 float GetSqrRayContribution() const { 448 float GetSqrRayContribution() const 449 { 431 450 return sqr(GetPvsSize()/((float)rays.size() + Limits::Small)); 432 451 } … … 435 454 436 455 // Inline functions 437 inline 438 VspKdTreeNode::VspKdTreeNode(VspKdTreeInterior *p): 439 parent(p), axis(-1), depth(p ? p->depth + 1 : 0){}456 inline VspKdTreeNode::VspKdTreeNode(VspKdTreeInterior *p): 457 parent(p), axis(-1), depth(p ? p->depth + 1 : 0) 458 {} 440 459 441 460 … … 446 465 class VspKdTree 447 466 { 448 struct TraversalData 449 { 450 VspKdTreeNode *node; 451 AxisAlignedBox3 bbox; 452 int depth; 453 float priority; 467 struct TraversalData 468 { 469 VspKdTreeNode *node; 470 AxisAlignedBox3 bbox; 471 int depth; 472 float priority; 473 474 TraversalData() {} 475 476 TraversalData(VspKdTreeNode *n, const float p): 477 node(n), priority(p) 478 {} 479 480 TraversalData(VspKdTreeNode *n, const AxisAlignedBox3 &b, const int d): 481 node(n), bbox(b), depth(d) {} 454 482 455 TraversalData() {} 456 457 TraversalData(VspKdTreeNode *n, const float p): 458 node(n), priority(p) 459 {} 460 461 TraversalData(VspKdTreeNode *n, 462 const AxisAlignedBox3 &b, 463 const int d): 464 node(n), bbox(b), depth(d) {} 483 // comparator for the 484 struct less_priority : public binary_function<const TraversalData, const TraversalData, bool> 485 { 486 bool operator()(const TraversalData a, const TraversalData b) 487 { 488 return a.priority < b.priority; 489 } 490 }; 491 492 // ~TraversalData() {} 493 // TraversalData(const TraversalData &s):node(s.node), bbox(s.bbox), depth(s.depth) {} 465 494 466 467 // comparator for the 468 struct less_priority : public 469 binary_function<const TraversalData, const TraversalData, bool> { 470 471 bool operator()(const TraversalData a, const TraversalData b) { 472 return a.priority < b.priority; 473 } 474 475 }; 476 477 // ~TraversalData() {} 478 // TraversalData(const TraversalData &s):node(s.node), bbox(s.bbox), depth(s.depth) {} 479 480 friend bool operator<(const TraversalData &a, 481 const TraversalData &b) { 482 // return a.node->queries.size() < b.node->queries.size(); 483 VspKdTreeLeaf *leafa = (VspKdTreeLeaf *) a.node; 484 VspKdTreeLeaf *leafb = (VspKdTreeLeaf *) b.node; 495 friend bool operator<(const TraversalData &a, const TraversalData &b) 496 { 497 // return a.node->queries.size() < b.node->queries.size(); 498 VspKdTreeLeaf *leafa = (VspKdTreeLeaf *) a.node; 499 VspKdTreeLeaf *leafb = (VspKdTreeLeaf *) b.node; 485 500 #if 0 486 501 return … … 503 518 #if 0 504 519 return 505 leafa->GetPvsSize() /(leafa->rays.size()+1)520 leafa->GetPvsSize() / (float)(leafa->rays.size() + 1) 506 521 > 507 leafb->GetPvsSize() /(leafb->rays.size()+1);522 leafb->GetPvsSize() / (float)(leafb->rays.size() + 1); 508 523 #endif 509 524 #if 0 510 525 return 511 leafa->GetPvsSize() *leafa->rays.size()526 leafa->GetPvsSize() * (float)leafa->rays.size() 512 527 < 513 leafb->GetPvsSize() *leafb->rays.size();528 leafb->GetPvsSize() * (float)leafb->rays.size(); 514 529 #endif 515 530 } … … 518 533 // simplified data for ray traversal only... 519 534 520 struct RayTraversalData {521 522 523 524 525 526 RayTraversalData(VspKdTreeNode *n, 527 528 535 struct RayTraversalData 536 { 537 VspKdTreeNode::RayInfo rayData; 538 VspKdTreeNode *node; 539 540 RayTraversalData() {} 541 542 RayTraversalData(VspKdTreeNode *n, const VspKdTreeNode::RayInfo &data): 543 rayData(data), node(n) {} 529 544 }; 530 545 531 546 public: 532 ///////////////////////////// 533 // The core pointer 534 VspKdTreeNode *root; 535 536 ///////////////////////////// 537 // Basic properties 538 539 // total number of nodes of the tree 540 int nodes; 541 // axis aligned bounding box of the scene 542 AxisAlignedBox3 bbox; 543 544 // axis aligned bounding box of directions 545 AxisAlignedBox3 dirBBox; 546 547 ///////////////////////////// 548 // Construction parameters 549 550 // epsilon used for the construction 551 float epsilon; 552 553 // ratio between traversal and intersection costs 554 float ct_div_ci; 555 // max depth of the tree 556 int termMaxDepth; 557 // minimal ratio of the volume of the cell and the query volume 558 float termMinSize; 547 548 ///////////////////////////// 549 // The core pointer 550 VspKdTreeNode *root; 551 552 ///////////////////////////// 553 // Basic properties 554 555 // total number of nodes of the tree 556 int nodes; 557 558 // axis aligned bounding box of the scene 559 AxisAlignedBox3 bbox; 560 561 // axis aligned bounding box of directions 562 AxisAlignedBox3 dirBBox; 563 564 ///////////////////////////// 565 // Construction parameters 566 567 // epsilon used for the construction 568 float epsilon; 569 570 // ratio between traversal and intersection costs 571 float ct_div_ci; 572 573 // max depth of the tree 574 int termMaxDepth; 575 // minimal ratio of the volume of the cell and the query volume 576 float termMinSize; 559 577 560 578 // minimal pvs per node to still get subdivided 561 579 int termMinPvs; 562 580 563 581 // minimal ray number per node to still get subdivided 564 565 566 567 582 int termMinRays; 583 584 // maximal cost ration to subdivide a node 585 float termMaxCostRatio; 568 586 569 587 // maximal contribution per ray to subdivide the node 570 588 float termMaxRayContribution; 571 589 572 573 // randomized construction 574 bool randomize; 575 576 // type of the splitting to use fo rthe tree construction 577 enum {ESplitRegular, ESplitHeuristic }; 578 int splitType; 579 580 // maximal size of the box on which the refdir splitting can be performed 581 // (relative to the scene bbox 582 float refDirBoxMaxSize; 583 584 // maximum alovable memory in MB 585 float maxTotalMemory; 586 587 // maximum alovable memory for static kd tree in MB 588 float maxStaticMemory; 589 590 // this is used during the construction depending 591 // on the type of the tree and queries... 592 float maxMemory; 593 594 595 // minimal acess time for collapse 596 int accessTimeThreshold; 590 // randomized construction 591 bool randomize; 592 593 // type of the splitting to use for the tree construction 594 enum {ESplitRegular, ESplitHeuristic }; 595 int splitType; 596 597 // maximal size of the box on which the refdir splitting can be performed 598 // (relative to the scene bbox 599 float refDirBoxMaxSize; 600 601 // maximum alovable memory in MB 602 float maxTotalMemory; 603 604 // maximum alovable memory for static kd tree in MB 605 float maxStaticMemory; 606 607 // this is used during the construction depending 608 // on the type of the tree and queries... 609 float maxMemory; 610 611 // minimal acess time for collapse 612 int accessTimeThreshold; 597 613 598 614 // minimal depth at which to perform collapse 599 int minCollapseDepth; 600 601 602 // reusable array of split candidates 603 vector<SortableEntry> *splitCandidates; 604 ///////////////////////////// 605 606 VspKdStatistics stat; 607 608 609 VspKdTree(); 610 virtual ~VspKdTree(); 611 612 virtual void 613 Construct( 614 VssRayContainer &rays, 615 AxisAlignedBox3 *forcedBoundingBox = NULL 616 ); 617 618 // incemental construction 619 virtual void UpdateRays(VssRayContainer &remove, 620 VssRayContainer &add 621 ); 622 623 virtual void AddRays( 624 VssRayContainer &add 625 ) 615 int minCollapseDepth; 616 617 // reusable array of split candidates 618 vector<SortableEntry> *splitCandidates; 619 620 ///////////////////////////// 621 VspKdStatistics stat; 622 623 VspKdTree(); 624 virtual ~VspKdTree(); 625 626 virtual void Construct(VssRayContainer &rays, 627 AxisAlignedBox3 *forcedBoundingBox = NULL); 628 629 // incemental construction 630 virtual void UpdateRays(VssRayContainer &remove, VssRayContainer &add); 631 632 virtual void AddRays(VssRayContainer &add) 626 633 { 627 634 VssRayContainer remove; … … 629 636 } 630 637 631 632 633 VspKdTreeNode * 634 Locate(const Vector3 &v); 635 636 VspKdTreeNode * 637 SubdivideNode(VspKdTreeLeaf *leaf, 638 const AxisAlignedBox3 &box, 639 AxisAlignedBox3 &backBox, 640 AxisAlignedBox3 &frontBox 641 ); 642 643 VspKdTreeNode * 644 Subdivide(const TraversalData &tdata); 645 646 int 647 SelectPlane(VspKdTreeLeaf *leaf, 648 const AxisAlignedBox3 &box, 649 float &position, 650 int &raysBack, 651 int &raysFront, 652 int &pvsBack, 653 int &pvsFront 654 ); 655 656 void 657 SortSplitCandidates( 658 VspKdTreeLeaf *node, 659 const int axis 660 ); 661 662 663 // return memory usage in MB 664 float GetMemUsage() const { 665 return 666 (sizeof(VspKdTree) + 667 stat.Leaves()*sizeof(VspKdTreeLeaf) + 668 stat.Interior()*sizeof(VspKdTreeInterior) + 669 stat.rayRefs*sizeof(VspKdTreeNode::RayInfo))/(1024.0f*1024.0f); 670 } 671 672 float GetRayMemUsage() const { 673 return 674 stat.rays*(sizeof(VssRay))/(1024.0f*1024.0f); 675 } 676 677 float 678 BestCostRatioHeuristic( 679 VspKdTreeLeaf *node, 680 int &axis, 681 float &position, 682 int &raysBack, 683 int &raysFront, 684 int &pvsBack, 685 int &pvsFront 686 ); 687 688 float 689 BestCostRatioRegular( 690 VspKdTreeLeaf *node, 691 int &axis, 692 float &position, 693 int &raysBack, 694 int &raysFront, 695 int &pvsBack, 696 int &pvsFront 697 698 ); 699 700 float 701 EvalCostRatio( 702 VspKdTreeLeaf *node, 703 const int axis, 704 const float position, 705 int &raysBack, 706 int &raysFront, 707 int &pvsBack, 708 int &pvsFront 709 ); 710 711 AxisAlignedBox3 GetBBox(const VspKdTreeNode *node) { 712 if (node->parent == NULL) 713 return bbox; 714 715 if (!node->IsLeaf()) 716 return ((VspKdTreeInterior *)node)->bbox; 717 718 if (node->parent->axis >= 3) 719 return node->parent->bbox; 638 VspKdTreeNode *Locate(const Vector3 &v); 639 640 VspKdTreeNode *SubdivideNode(VspKdTreeLeaf *leaf, 641 const AxisAlignedBox3 &box, 642 AxisAlignedBox3 &backBox, 643 AxisAlignedBox3 &frontBox); 644 645 VspKdTreeNode *Subdivide(const TraversalData &tdata); 646 647 int SelectPlane(VspKdTreeLeaf *leaf, 648 const AxisAlignedBox3 &box, 649 float &position, 650 int &raysBack, 651 int &raysFront, 652 int &pvsBack, 653 int &pvsFront); 654 655 void SortSplitCandidates(VspKdTreeLeaf *node, 656 const int axis); 657 658 659 // return memory usage in MB 660 float GetMemUsage() const 661 { 662 return 663 (sizeof(VspKdTree) + 664 stat.Leaves() * sizeof(VspKdTreeLeaf) + 665 stat.Interior() * sizeof(VspKdTreeInterior) + 666 stat.rayRefs * sizeof(VspKdTreeNode::RayInfo)) / (1024.0f*1024.0f); 667 } 668 669 float GetRayMemUsage() const 670 { 671 return stat.rays * (sizeof(VssRay))/(1024.0f * 1024.0f); 672 } 673 674 float BestCostRatioHeuristic(VspKdTreeLeaf *node, 675 int &axis, 676 float &position, 677 int &raysBack, 678 int &raysFront, 679 int &pvsBack, 680 int &pvsFront); 681 682 float BestCostRatioRegular(VspKdTreeLeaf *node, 683 int &axis, 684 float &position, 685 int &raysBack, 686 int &raysFront, 687 int &pvsBack, 688 int &pvsFront); 689 690 float EvalCostRatio(VspKdTreeLeaf *node, 691 const int axis, 692 const float position, 693 int &raysBack, 694 int &raysFront, 695 int &pvsBack, 696 int &pvsFront); 697 698 AxisAlignedBox3 GetBBox(const VspKdTreeNode *node) 699 { 700 if (node->parent == NULL) 701 return bbox; 702 703 if (!node->IsLeaf()) 704 return ((VspKdTreeInterior *)node)->bbox; 705 706 if (node->parent->axis >= 3) 707 return node->parent->bbox; 720 708 721 AxisAlignedBox3 box(node->parent->bbox); 722 if (node->parent->front == node) 723 box.SetMin(node->parent->axis, node->parent->position); 724 else 725 box.SetMax(node->parent->axis, node->parent->position); 726 return box; 727 } 728 729 AxisAlignedBox3 GetDirBBox(const VspKdTreeNode *node) { 730 731 if (node->parent == NULL) 732 return dirBBox; 709 AxisAlignedBox3 box(node->parent->bbox); 710 if (node->parent->front == node) 711 box.SetMin(node->parent->axis, node->parent->position); 712 else 713 box.SetMax(node->parent->axis, node->parent->position); 714 return box; 715 } 716 717 AxisAlignedBox3 GetDirBBox(const VspKdTreeNode *node) 718 { 719 if (node->parent == NULL) 720 return dirBBox; 721 if (!node->IsLeaf()) 722 return ((VspKdTreeInterior *)node)->dirBBox; 723 if (node->parent->axis < 3) 724 return node->parent->dirBBox; 733 725 734 if (!node->IsLeaf() ) 735 return ((VspKdTreeInterior *)node)->dirBBox; 736 737 if (node->parent->axis < 3) 738 return node->parent->dirBBox; 739 740 AxisAlignedBox3 dBBox(node->parent->dirBBox); 741 742 if (node->parent->front == node) 743 dBBox.SetMin(node->parent->axis - 3, node->parent->position); 744 else 745 dBBox.SetMax(node->parent->axis - 3, node->parent->position); 746 return dBBox; 747 } 748 749 int 750 ReleaseMemory(const int time); 751 752 int 753 CollapseSubtree(VspKdTreeNode *node, const int time); 754 755 void 756 CountAccess(VspKdTreeInterior *node, const long time) { 757 node->accesses++; 758 node->lastAccessTime = time; 759 } 760 761 VspKdTreeNode * 762 SubdivideLeaf( 763 VspKdTreeLeaf *leaf, 764 const float SAThreshold 765 ); 766 767 void 768 RemoveRay(VssRay *ray, 769 vector<VspKdTreeLeaf *> *affectedLeaves, 770 const bool removeAllScheduledRays 771 ); 772 773 void 774 AddRay(VssRay *ray); 775 776 void 777 TraverseInternalNode( 778 RayTraversalData &data, 779 stack<RayTraversalData> &tstack); 780 781 void 782 EvaluateLeafStats(const TraversalData &data); 783 784 785 int 786 GetRootPvsSize() const { 726 AxisAlignedBox3 dBBox(node->parent->dirBBox); 727 728 if (node->parent->front == node) 729 dBBox.SetMin(node->parent->axis - 3, node->parent->position); 730 else 731 dBBox.SetMax(node->parent->axis - 3, node->parent->position); 732 return dBBox; 733 } 734 735 int ReleaseMemory(const int time); 736 737 int CollapseSubtree(VspKdTreeNode *node, const int time); 738 739 void CountAccess(VspKdTreeInterior *node, const long time) 740 { 741 ++ node->accesses; 742 node->lastAccessTime = time; 743 } 744 745 VspKdTreeNode * SubdivideLeaf(VspKdTreeLeaf *leaf, 746 const float SAThreshold); 747 748 void RemoveRay(VssRay *ray, 749 vector<VspKdTreeLeaf *> *affectedLeaves, 750 const bool removeAllScheduledRays); 751 752 void AddRay(VssRay *ray); 753 754 void TraverseInternalNode(RayTraversalData &data, 755 stack<RayTraversalData> &tstack); 756 757 void EvaluateLeafStats(const TraversalData &data); 758 759 760 int GetRootPvsSize() const 761 { 787 762 return GetPvsSize(root, bbox); 788 763 } 789 764 790 int 791 GetPvsSize(VspKdTreeNode *node, const AxisAlignedBox3 &box) const; 792 793 void 794 GetRayContributionStatistics( 795 float &minRayContribution, 796 float &maxRayContribution, 797 float &avgRayContribution 798 ); 799 800 int 801 GenerateRays(const float ratioPerLeaf, 802 SimpleRayContainer &rays); 803 804 float 805 GetAvgPvsSize(); 806 765 int GetPvsSize(VspKdTreeNode *node, const AxisAlignedBox3 &box) const; 766 767 void GetRayContributionStatistics(float &minRayContribution, 768 float &maxRayContribution, 769 float &avgRayContribution); 770 771 int GenerateRays(const float ratioPerLeaf, 772 SimpleRayContainer &rays); 773 774 float GetAvgPvsSize(); 807 775 }; 808 776 -
trunk/VUT/GtpVisibilityPreprocessor/src/VssRay.h
r386 r410 5 5 using namespace std; 6 6 #include "Vector3.h" 7 #include "Ray.h" 7 8 8 9 class AxisAlignedBox3; … … 60 61 } 61 62 63 VccRay(const Ray &ray): 64 VccRay(ray.GetLoc(), ray.Extrap(ray.intersections[0].mT), ray.intersections[0].mObject, ray.sourceObject.mObject) 65 {} 62 66 void Precompute() { 63 67 mFlags = 0; -
trunk/VUT/GtpVisibilityPreprocessor/src/default.env
r403 r410 119 119 # input fromViewCells 120 120 # input fromSceneGeometry 121 samples 10000 121 samples 100000 122 122 sideTolerance 0.005 123 123 }
Note: See TracChangeset
for help on using the changeset viewer.