Changeset 1145 for GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp
- Timestamp:
- 07/24/06 10:12:34 (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp
r1144 r1145 103 103 104 104 105 void OspTreeStatistics::Print(ostream &app) const 106 { 107 app << "=========== OspTree statistics ===============\n"; 108 109 app << setprecision(4); 110 111 app << "#N_CTIME ( Construction time [s] )\n" << Time() << " \n"; 112 113 app << "#N_NODES ( Number of nodes )\n" << nodes << "\n"; 114 115 app << "#N_INTERIORS ( Number of interior nodes )\n" << Interior() << "\n"; 116 117 app << "#N_LEAVES ( Number of leaves )\n" << Leaves() << "\n"; 118 119 app << "#AXIS_ALIGNED_SPLITS (number of axis aligned splits)\n" << splits[0] + splits[1] + splits[2] << endl; 120 121 app << "#N_SPLITS ( Number of splits in axes x y z)\n"; 122 123 for (int i = 0; i < 3; ++ i) 124 app << splits[i] << " "; 125 app << endl; 126 127 app << "#N_PMAXDEPTHLEAVES ( Percentage of leaves at maximum depth )\n" 128 << maxDepthNodes * 100 / (double)Leaves() << endl; 129 130 app << "#N_PMINPVSLEAVES ( Percentage of leaves with mininimal PVS )\n" 131 << minPvsNodes * 100 / (double)Leaves() << endl; 132 133 //app << "#N_PMINRAYSLEAVES ( Percentage of leaves with minimal number of rays)\n" 134 // << minRaysNodes * 100 / (double)Leaves() << endl; 135 136 app << "#N_MAXCOSTNODES ( Percentage of leaves with terminated because of max cost ratio )\n" 137 << maxCostNodes * 100 / (double)Leaves() << endl; 138 139 app << "#N_PMINPROBABILITYLEAVES ( Percentage of leaves with mininum probability )\n" 140 << minProbabilityNodes * 100 / (double)Leaves() << endl; 141 142 // app << "#N_PMAXRAYCONTRIBLEAVES ( Percentage of leaves with maximal ray contribution )\n" 143 // << maxRayContribNodes * 100 / (double)Leaves() << endl; 144 145 app << "#N_PMAXDEPTH ( Maximal reached depth )\n" << maxDepth << endl; 146 147 app << "#N_PMINDEPTH ( Minimal reached depth )\n" << minDepth << endl; 148 149 app << "#AVGDEPTH ( average depth )\n" << AvgDepth() << endl; 150 151 app << "#N_INVALIDLEAVES (number of invalid leaves )\n" << invalidLeaves << endl; 152 153 // app << "#N_RAYS (number of rays / leaf)\n" << AvgRays() << endl; 154 //app << "#N_PVS: " << pvs << endl; 155 156 app << "========== END OF VspTree statistics ==========\n"; 157 } 158 159 105 160 /******************************************************************/ 106 161 /* class VspNode implementation */ … … 471 526 void VspTree::AddSubdivisionStats(const int viewCells, 472 527 const float renderCostDecr, 473 const float splitCandidateCost,474 528 const float totalRenderCost, 475 529 const float avgRenderCost) … … 478 532 << "#ViewCells\n" << viewCells << endl 479 533 << "#RenderCostDecrease\n" << renderCostDecr << endl 480 << "#SplitCandidateCost\n" << splitCandidateCost << endl481 534 << "#TotalRenderCost\n" << totalRenderCost << endl 482 535 << "#AvgRenderCost\n" << avgRenderCost << endl; … … 584 637 585 638 639 void VspTree::EvalSubdivisionStats(const VspTraversalData &tData, 640 const VspTraversalData &tFrontData, 641 const VspTraversalData &tBackData 642 ) 643 { 644 const float cFront = (float)tFrontData.mPvs * tFrontData.mProbability; 645 const float cBack = (float)tBackData.mPvs * tBackData.mProbability; 646 const float cData = (float)tData.mPvs * tData.mProbability; 647 648 const float costDecr = 649 (cFront + cBack - cData) / mBoundingBox.GetVolume(); 650 651 mTotalCost += costDecr; 652 mTotalPvsSize += tFrontData.mPvs + tBackData.mPvs - tData.mPvs; 653 654 AddSubdivisionStats(mVspStats.Leaves(), 655 -costDecr, 656 mTotalCost, 657 (float)mTotalPvsSize / (float)mVspStats.Leaves()); 658 } 659 660 586 661 VspNode *VspTree::Subdivide(SplitQueue &tQueue, 587 VspSplitCandidate &splitCandidate,662 SplitCandidate *splitCandidate, 588 663 const bool globalCriteriaMet) 589 664 { 590 VspTraversalData &tData = splitCandidate.mParentData; 665 // doto remove dynamic cast 666 VspSplitCandidate *sc = dynamic_cast<VspSplitCandidate *>(splitCandidate); 667 VspTraversalData &tData = sc->mParentData; 591 668 592 669 VspNode *newNode = tData.mNode; … … 600 677 601 678 // create new interior node and two leaf node 602 const AxisAlignedPlane splitPlane = s plitCandidate.mSplitPlane;679 const AxisAlignedPlane splitPlane = sc->mSplitPlane; 603 680 newNode = SubdivideNode(splitPlane, tData, tFrontData, tBackData); 604 681 605 const int maxCostMisses = s plitCandidate.mMaxCostMisses;682 const int maxCostMisses = sc->mMaxCostMisses; 606 683 607 684 … … 611 688 612 689 613 if (1) 614 { 615 //-- subdivision statistics 616 617 const float cFront = (float)tFrontData.mPvs * tFrontData.mProbability; 618 const float cBack = (float)tBackData.mPvs * tBackData.mProbability; 619 const float cData = (float)tData.mPvs * tData.mProbability; 620 621 const float costDecr = 622 (cFront + cBack - cData) / mBoundingBox.GetVolume(); 623 624 mTotalCost += costDecr; 625 mTotalPvsSize += tFrontData.mPvs + tBackData.mPvs - tData.mPvs; 626 627 AddSubdivisionStats(mVspStats.Leaves(), 628 -costDecr, 629 splitCandidate.GetPriority(), 630 mTotalCost, 631 (float)mTotalPvsSize / (float)mVspStats.Leaves()); 632 } 633 634 690 if (1) //-- subdivision statistics 691 EvalSubdivisionStats(tData, tFrontData, tBackData); 692 635 693 //-- evaluate new split candidates for global greedy cost heuristics 694 636 695 VspSplitCandidate *frontCandidate = new VspSplitCandidate(tFrontData); 637 696 VspSplitCandidate *backCandidate = new VspSplitCandidate(tBackData); … … 645 704 // delete old view cell 646 705 delete tData.mNode->mViewCell; 706 647 707 // delete old leaf node 648 708 DEL_PTR(tData.mNode); … … 702 762 SelectSplitPlane(splitCandidate.mParentData, splitCandidate.mSplitPlane, frontProb, backProb); 703 763 764 float oldRenderCost; 765 704 766 // compute global decrease in render cost 705 const float priority = EvalRenderCostDecrease(splitCandidate.mSplitPlane, splitCandidate.mParentData); 767 const float renderCostDecr = EvalRenderCostDecrease(splitCandidate.mSplitPlane, 768 splitCandidate.mParentData, 769 oldRenderCost); 770 771 splitCandidate.SetRenderCostDecrease(renderCostDecr); 772 773 #if 0 774 const float priority = (float)-data.mDepth; 775 #else 776 777 // take render cost of node into account 778 // otherwise danger of being stuck in a local minimum!! 779 const float factor = mRenderCostDecreaseWeight; 780 const float priority = factor * renderCostDecr + (1.0f - factor) * oldRenderCost; 781 #endif 782 706 783 splitCandidate.SetPriority(priority); 707 splitCandidate.mMaxCostMisses = success ? splitCandidate.mParentData.mMaxCostMisses : splitCandidate.mParentData.mMaxCostMisses + 1; 784 785 // max cost threshold violated? 786 splitCandidate.mMaxCostMisses = 787 success ? splitCandidate.mParentData.mMaxCostMisses : splitCandidate.mParentData.mMaxCostMisses + 1; 708 788 //Debug << "p: " << tData.mNode << " depth: " << tData.mDepth << endl; 709 789 } … … 1404 1484 1405 1485 //if (axis != 1) 1406 Debug << "axis=" << axis << " costRatio=" << ratio << " pos=" << position << " t=" << (position - minBox) / (maxBox - minBox) 1407 <<"\t pb=(" << pvsBack << ")\t pf=(" << pvsFront << ")" << endl; 1486 //Debug << "axis=" << axis << " costRatio=" << ratio << " pos=" << position << " t=" << (position - minBox) / (maxBox - minBox) 1487 // <<"\t pb=(" << pvsBack << ")\t pf=(" << pvsFront << ")" << endl; 1488 1489 const float volRatio = tData.mBoundingBox.GetVolume() / (sizeBox * mBoundingBox.GetVolume()); 1490 1491 Debug << "\n§§§§ eval local cost §§§§" << endl 1492 << "back pvs: " << penaltyBack << " front pvs: " << penaltyFront << " total pvs: " << penaltyOld << endl 1493 << "back p: " << pBack * volRatio << " front p " << pFront * volRatio << " p: " << pOverall * volRatio << endl 1494 << "old rc: " << oldRenderCost * volRatio << " new rc: " << newRenderCost * volRatio << endl 1495 << "render cost decrease: " << oldRenderCost * volRatio - newRenderCost * volRatio << endl; 1408 1496 1409 1497 return ratio; … … 1497 1585 1498 1586 float VspTree::EvalRenderCostDecrease(const AxisAlignedPlane &candidatePlane, 1499 const VspTraversalData &data) const 1500 { 1501 #if 0 1502 return (float)-data.mDepth; 1503 #endif 1587 const VspTraversalData &data, 1588 float &normalizedOldRenderCost) const 1589 { 1504 1590 float pvsFront = 0; 1505 1591 float pvsBack = 0; … … 1511 1597 float pBack = 0; 1512 1598 1599 const float viewSpaceVol = mBoundingBox.GetVolume(); 1513 1600 1514 1601 // create unique ids for pvs heuristics 1515 Intersectable::NewMail( );1602 Intersectable::NewMail(3); 1516 1603 1517 1604 RayInfoContainer::const_iterator rit, rit_end = data.mRays->end(); … … 1555 1642 const float newRenderCost = penaltyFront * pFront + penaltyBack * pBack; 1556 1643 1644 normalizedOldRenderCost = oldRenderCost / viewSpaceVol; 1645 1557 1646 //Debug << "decrease: " << oldRenderCost - newRenderCost << endl; 1558 const float renderCostDecrease = (oldRenderCost - newRenderCost) / mBoundingBox.GetVolume(); 1559 1560 // take render cost of node into account 1561 // otherwise danger of being stuck in a local minimum!! 1562 const float factor = mRenderCostDecreaseWeight; 1563 1564 const float normalizedOldRenderCost = oldRenderCost / mBoundingBox.GetVolume(); 1565 return factor * renderCostDecrease + (1.0f - factor) * normalizedOldRenderCost; 1647 const float renderCostDecrease = (oldRenderCost - newRenderCost) / viewSpaceVol; 1648 1649 1650 Debug << "\n==== eval render cost decrease ===" << endl 1651 << "back pvs: " << pvsBack << " front pvs " << pvsFront << " total pvs: " << totalPvs << endl 1652 << "back p: " << pBack / viewSpaceVol << " front p " << pFront / viewSpaceVol << " p: " << pOverall / viewSpaceVol << endl 1653 << "old rc: " << normalizedOldRenderCost << " new rc: " << newRenderCost / viewSpaceVol << endl 1654 << "render cost decrease: " << renderCostDecrease << endl; 1655 1656 return renderCostDecrease; 1566 1657 } 1567 1658 … … 1579 1670 1580 1671 // create unique ids for pvs heuristics 1581 Intersectable::NewMail( );1672 Intersectable::NewMail(3); 1582 1673 1583 1674 const int pvsSize = data.mPvs; … … 1601 1692 pOverall = data.mProbability; 1602 1693 1603 // we take simplified computation for spatial mid split1694 // we use spatial mid split => simplified computation 1604 1695 pBack = pFront = pOverall * 0.5f; 1605 1696 … … 1625 1716 return; 1626 1717 1627 //const float renderCost = mViewCellsManager-> EvalRenderCost(obj);1718 //const float renderCost = mViewCellsManager->SimpleRay &raynderCost(obj); 1628 1719 const int renderCost = 1; 1629 1720 … … 1634 1725 } 1635 1726 1636 // TODO: does this really belong to no pvs? 1727 // QUESTION matt: is it safe to assume that 1728 // the object belongs to no pvs in this case? 1637 1729 //if (cf == Ray::COINCIDENT) return; 1638 1730 … … 2162 2254 2163 2255 Intersectable::NewMail(); 2164 ViewCell::NewMail();2256 //ViewCell::NewMail(); 2165 2257 2166 2258 Vector3 entp = origin; … … 2225 2317 ViewCell *vc = leaf->GetViewCell(); 2226 2318 2227 if (!vc->Mailed()) 2228 { 2229 vc->Mail(); 2319 // don't have to mail because each view cell belongs to exactly one leaf 2320 //if (!vc->Mailed()) 2321 //{ 2322 // vc->Mail(); 2230 2323 viewcells.push_back(vc); 2231 2324 ++ hits; 2232 }2325 //} 2233 2326 #if 0 2234 2327 leaf->mRays.push_back(RayInfo(new VssRay(origin, termination, NULL, NULL, 0))); … … 2785 2878 //-- debug output 2786 2879 2787 Debug << "******* OSP options ******** " << endl;2880 Debug << "******* OSP tree options ******** " << endl; 2788 2881 2789 2882 Debug << "max depth: " << mTermMaxDepth << endl; … … 2951 3044 2952 3045 KdNode *OspTree::Subdivide(SplitQueue &tQueue, 2953 OspSplitCandidate &splitCandidate,3046 SplitCandidate *splitCandidate, 2954 3047 const bool globalCriteriaMet) 2955 3048 { 2956 OspTraversalData &tData = splitCandidate.mParentData; 3049 OspSplitCandidate *sc = dynamic_cast<OspSplitCandidate *>(splitCandidate); 3050 OspTraversalData &tData = sc->mParentData; 3051 2957 3052 KdNode *newNode = tData.mNode; 2958 3053 … … 2965 3060 2966 3061 // create new interior node and two leaf node 2967 const AxisAlignedPlane splitPlane = s plitCandidate.mSplitPlane;3062 const AxisAlignedPlane splitPlane = sc->mSplitPlane; 2968 3063 2969 3064 newNode = SubdivideNode(splitPlane, … … 2972 3067 tBackData); 2973 3068 2974 const int maxCostMisses = s plitCandidate.mMaxCostMisses;3069 const int maxCostMisses = sc->mMaxCostMisses; 2975 3070 2976 3071 // how often was max cost ratio missed in this branch? … … 3015 3110 SelectSplitPlane(splitCandidate.mParentData, splitCandidate.mSplitPlane, frontProb, backProb); 3016 3111 3017 const float priority = EvalRenderCostDecrease(splitCandidate.mSplitPlane, splitCandidate.mParentData); 3112 float oldRenderCost; 3113 3114 // compute global decrease in render cost 3115 const float renderCostDecr = EvalRenderCostDecrease(splitCandidate.mSplitPlane, 3116 splitCandidate.mParentData, 3117 oldRenderCost); 3118 3119 splitCandidate.SetRenderCostDecrease(renderCostDecr); 3120 3121 #if 0 3122 const float priority = (float)-data.mDepth; 3123 #else 3124 // take render cost of node into account 3125 // otherwise danger of being stuck in a local minimum!! 3126 const float factor = mRenderCostDecreaseWeight; 3127 const float priority = factor * renderCostDecr + (1.0f - factor) * oldRenderCost; 3128 3129 #endif 3130 3018 3131 // compute global decrease in render cost 3019 3132 splitCandidate.SetPriority(priority); … … 3112 3225 SortSplitCandidates(tData, axis, minBand, maxBand); 3113 3226 3114 float totalVol = PrepareHeuristics(tData); 3227 int numViewCells; 3228 3229 float totalVol = PrepareHeuristics(tData, numViewCells); 3115 3230 float voll = 0; 3116 3231 float volr = totalVol; 3232 3233 int vcl = 0; 3234 int vcr = numViewCells; 3117 3235 3118 3236 const int totalPvs = tData.mNode->mObjects.size(); … … 3121 3239 int pvsr = totalPvs; 3122 3240 3123 // if no good split can be found, take mid split 3241 float sum = (float)totalVol * sizeBox; 3242 3243 ///////////////////////////////// 3244 3245 // note: initialised to take mid split 3246 // if no good split can be found, 3124 3247 position = minBox + 0.5f * sizeBox; 3125 3248 … … 3127 3250 float ratio = 99999999.0f; 3128 3251 bool splitPlaneFound = false; 3129 3130 float minSum = 1e20f;3131 3252 3132 3253 float volBack = voll; 3133 3254 float volFront = volr; 3134 3255 3135 int pvsBack = 0; 3136 int pvsFront = 0; 3137 3138 3139 float sum = (float)totalVol * sizeBox; 3256 int pvsBack = pvsl; 3257 int pvsFront = pvsr; 3258 3259 float minSum = 1e20f; 3260 3261 ///////////////////////////// 3140 3262 3141 3263 Intersectable::NewMail(); … … 3150 3272 Intersectable *object = (*ci).mObject; 3151 3273 3152 EvalHeuristicsContribution(*ci, voll, volr, pvsl, pvsr); 3153 3154 cout << "incr: " << ci->mObject->mViewCellPvs.GetSize() << " obj id " 3155 << ci->mObject->GetId() << endl; 3274 EvalHeuristicsContribution(tData.mNode, 3275 *ci, 3276 voll, volr, 3277 pvsl, pvsr, 3278 vcl, vcr); 3156 3279 3157 3280 // Note: sufficient to compare size of bounding boxes of front and back side? 3281 3158 3282 if (((*ci).mPos >= minBand) && ((*ci).mPos <= maxBand)) 3159 3283 { 3160 //sum = costl * ((*ci).value - minBox) + costr * (maxBox - (*ci).value); 3161 sum = voll * pvsBack + volr * pvsFront; 3162 3163 cout << "pos: " << (*ci).mPos 3164 << "\t (pvsl: " << pvsBack << ", pvsr: " << pvsFront << ")" 3284 sum = voll * pvsl + volr * pvsr; 3285 3286 // note matt: can happen that volr is less than zero: bug or numerical error? 3287 //if (volr < 0) Debug << "warning!! " << totalVol << " " << volRightDecr << " " << volRightDecr - totalVol << endl; 3288 3289 /*Debug << "pos: " << (*ci).mPos 3290 << "\t (pvsl: " << pvsl << ", pvsr: " << pvsr << ")" 3165 3291 << "\t (voll: " << voll << ", volr: " << volr << ")" 3166 << "\t sum: " << sum << endl; 3292 << "\t (vcl: " << vcl << ", vcr: " << vcr << ", nvc: " << numViewCells << ")" 3293 << "\t sum: " << sum << endl;*/ 3167 3294 3168 3295 if (sum < minSum) … … 3193 3320 const float pFront = volFront; 3194 3321 3195 const float penaltyOld = (float)totalPvs; //EvalPvsPenalty(pvsSize, lowerPvsLimit, upperPvsLimit);3196 const float penaltyFront = (float)pvsFront; //EvalPvsPenalty(pvsFront, lowerPvsLimit, upperPvsLimit);3197 const float penaltyBack = (float)pvsBack; //EvalPvsPenalty(pvsBack, lowerPvsLimit, upperPvsLimit);3322 const float penaltyOld = (float)totalPvs; 3323 const float penaltyFront = (float)pvsFront; 3324 const float penaltyBack = (float)pvsBack; 3198 3325 3199 3326 const float oldRenderCost = penaltyOld * pOverall + Limits::Small; … … 3206 3333 } 3207 3334 3208 //if (axis != 1) 3209 Debug << "axis=" << axis << " costRatio=" << ratio << " pos=" 3210 << position << " t=" << (position - minBox) / (maxBox - minBox) 3211 << "\t pb=(" << volBack << ")\t pf=(" << volFront << ")" << endl; 3335 //Debug << "axis=" << axis << " costRatio=" << ratio << " pos=" 3336 // << position << " t=" << (position - minBox) / (maxBox - minBox) 3337 // << "\t pb=(" << volBack << ")\t pf=(" << volFront << ")" << endl; 3338 3339 const float viewSpaceVol = mVspTree->GetBoundingBox().GetVolume(); 3340 3341 Debug << "\n§§§§ eval local cost §§§§" << endl 3342 << "back pvs: " << pvsBack << " front pvs: " << pvsFront << " total pvs: " << totalPvs << endl 3343 << "back p: " << pBack / viewSpaceVol << " front p " << pFront / viewSpaceVol << " p: " << pOverall / viewSpaceVol << endl 3344 << "old rc: " << oldRenderCost / viewSpaceVol << " new rc: " << newRenderCost / viewSpaceVol << endl 3345 << "render cost decrease: " << oldRenderCost / viewSpaceVol - newRenderCost / viewSpaceVol << endl; 3212 3346 3213 3347 return ratio; … … 3255 3389 3256 3390 // if hitpoint with object is inside this node 3257 if ( GetLeaf(ray->mOrigin, ray->mOriginNode) == leaf)3391 if (ray->mOriginObject && (GetLeaf(ray->mOrigin, ray->mOriginNode) == leaf)) 3258 3392 { 3259 3393 pos = ray->mOrigin[axis]; … … 3267 3401 } 3268 3402 3269 if ( GetLeaf(ray->mTermination, ray->mTerminationNode) == leaf)3403 if (ray->mTerminationObject && (GetLeaf(ray->mTermination, ray->mTerminationNode) == leaf)) 3270 3404 { 3271 3405 pos = ray->mTermination[axis]; … … 3274 3408 SortableEntry(SortableEntry::BOX_INTERSECT, 3275 3409 pos, 3276 ray->m OriginObject,3410 ray->mTerminationObject, 3277 3411 ray) 3278 3412 ); … … 3319 3453 3320 3454 3321 float OspTree::PrepareHeuristics(const VssRay &ray )3455 float OspTree::PrepareHeuristics(const VssRay &ray, int &numViewCells) 3322 3456 { 3323 3457 float vol = 0; 3458 numViewCells = 0; 3324 3459 3325 3460 ViewCellContainer viewCells; 3326 3461 3327 3462 mVspTree->GetViewCells(ray, viewCells); 3328 3463 3329 3464 ViewCellContainer::const_iterator vit, vit_end = viewCells.end(); 3330 3465 … … 3335 3470 if (!vc->Mailed()) 3336 3471 { 3472 //Debug << "single vol: "<< vc->GetVolume() << endl; 3337 3473 vc->Mail(); 3338 3474 vc->mCounter = 0; 3339 3475 vol += vc->GetVolume(); 3340 } 3476 ++ numViewCells; 3477 } 3478 3479 // view cell volume already added => just increase counter 3480 ++ vc->mCounter; 3341 3481 } 3342 3482 … … 3345 3485 3346 3486 3347 float OspTree::PrepareHeuristics(const OspTraversalData &tData )3487 float OspTree::PrepareHeuristics(const OspTraversalData &tData, int &numViewCells) 3348 3488 { 3489 float vol = 0; 3490 3349 3491 Intersectable::NewMail(); 3350 3492 ViewCell::NewMail(); 3351 3352 float vol = 0; 3493 numViewCells = 0; 3353 3494 3354 3495 KdLeaf *leaf = tData.mNode; … … 3359 3500 { 3360 3501 VssRay *ray = (*rit).mRay; 3502 3503 int newViewCells; 3361 3504 3362 3505 // if hitpoint with one of the objects is inside this node, we 3363 3506 // evaluate the volume of the view cells seen by this ray 3364 if ((GetLeaf(ray->mOrigin, ray->mOriginNode) == leaf) || 3365 (GetLeaf(ray->mTermination, ray->mTerminationNode) == leaf)) 3366 { 3367 vol += PrepareHeuristics(tData); 3368 } 3369 } 3370 3507 if (ray->mOriginObject && (GetLeaf(ray->mOrigin, ray->mOriginNode) == leaf)) 3508 { 3509 vol += PrepareHeuristics(*ray, newViewCells); 3510 numViewCells += newViewCells; 3511 } 3512 3513 // count double if both hit points are within the kd node 3514 if (ray->mTerminationObject && (GetLeaf(ray->mTermination, ray->mTerminationNode) == leaf)) 3515 { 3516 vol += PrepareHeuristics(*ray, newViewCells); 3517 numViewCells += newViewCells; 3518 } 3519 } 3520 3521 //Debug << "vol: " << vol << endl; 3371 3522 return vol; 3372 3523 } 3373 3524 3374 3525 3375 void OspTree::EvalHeuristicsContribution(const SortableEntry &ci, 3526 void OspTree::EvalHeuristicsContribution(KdLeaf *leaf, 3527 const SortableEntry &ci, 3376 3528 float &volLeft, 3377 3529 float &volRight, 3378 3530 int &pvsLeft, 3379 int &pvsRight) 3531 int &pvsRight, 3532 int &viewCellsLeft, 3533 int &viewCellsRight) 3380 3534 { 3381 3535 Intersectable *obj = ci.mObject; 3382 3536 VssRay *ray = ci.mRay; 3383 3537 3384 3538 switch (ci.mType) 3385 3539 { … … 3395 3549 // compute volume contribution from view cells 3396 3550 case SortableEntry::BOX_INTERSECT: 3397 EvalVolumeContribution(*ray, volRight, volLeft); 3551 if ((ray->mOriginObject && (GetLeaf(ray->mOrigin, ray->mOriginNode) == leaf)) || 3552 (ray->mTerminationObject && (GetLeaf(ray->mTermination, ray->mTerminationNode) == leaf))) 3553 { 3554 EvalVolumeContribution(*ray, volLeft, volRight, viewCellsLeft, viewCellsRight); 3555 } 3398 3556 break; 3399 3557 default: … … 3406 3564 3407 3565 3408 void OspTree::EvalVolumeContribution(const VssRay &ray, float &volLeft, float &volRight) 3566 void OspTree::EvalVolumeContribution(const VssRay &ray, 3567 float &volLeft, 3568 float &volRight, 3569 int &viewCellsLeft, 3570 int &viewCellsRight) 3409 3571 { 3410 3572 ViewCellContainer viewCells; … … 3413 3575 3414 3576 ViewCellContainer::const_iterator vit, vit_end = viewCells.end(); 3415 3577 3416 3578 for (vit = viewCells.begin(); vit != vit_end; ++ vit) 3417 3579 { 3418 // view cells comesto left child node3580 // add view cells volume to left child node 3419 3581 ViewCell *viewCell = *vit; 3420 3582 … … 3422 3584 { 3423 3585 viewCell->Mail(); 3586 3424 3587 volLeft += viewCell->GetVolume(); 3588 3589 ++ viewCellsLeft; 3425 3590 } 3426 3591 3427 3592 // remove from right child node 3428 3429 3593 if (-- viewCell->mCounter == 0) 3430 3594 { 3431 3595 volRight -= viewCell->GetVolume(); 3596 3597 -- viewCellsRight; 3432 3598 } 3433 3599 } … … 3520 3686 pBack = nProbBack[bestAxis]; 3521 3687 3522 //Debug << "val: " << nCostRatio[bestAxis] << " axis: " << bestAxis << endl;3688 Debug << "val: " << nCostRatio[bestAxis] << " axis: " << bestAxis << endl; 3523 3689 return nCostRatio[bestAxis]; 3524 3690 } 3525 3691 3526 3692 3693 bool OspTree::EndPointInsideNode(KdLeaf *leaf, 3694 VssRay &ray, 3695 bool isTermination) const 3696 { 3697 // test if the leaf where the hitpoint is located is the current leaf 3698 if (isTermination) 3699 { 3700 return ray.mTerminationObject && (GetLeaf(ray.mTermination, ray.mOriginNode) == leaf); 3701 } 3702 else 3703 { 3704 return ray.mOriginObject && (GetLeaf(ray.mOrigin, ray.mOriginNode) == leaf); 3705 } 3706 } 3707 3708 3709 #if TODO 3710 void OspTree::EvalSubdivisionStats(const VspTraversalData &tData, 3711 const VspTraversalData &tFrontData, 3712 const VspTraversalData &tBackData 3713 ) 3714 { 3715 const float cFront = (float)tFrontData.mPvs * tFrontData.mProbability; 3716 const float cBack = (float)tBackData.mPvs * tBackData.mProbability; 3717 const float cData = (float)tData.mPvs * tData.mProbability; 3718 3719 const float costDecr = 3720 (cFront + cBack - cData) / mBoundingBox.GetVolume(); 3721 3722 mTotalCost += costDecr; 3723 mTotalPvsSize += tFrontData.mPvs + tBackData.mPvs - tData.mPvs; 3724 3725 AddSubdivisionStats(mVspStats.Leaves(), 3726 -costDecr, 3727 sc->GetPriority(), 3728 mTotalCost, 3729 (float)mTotalPvsSize / (float)mVspStats.Leaves()); 3730 } 3731 #endif 3732 3733 3734 int OspTree::ClassifyRay(VssRay *ray, 3735 KdLeaf *leaf, 3736 const AxisAlignedPlane &plane) const 3737 { 3738 const bool originInside = EndPointInsideNode(leaf, *ray, false); 3739 const bool terminationInside = EndPointInsideNode(leaf, *ray, true); 3740 3741 const bool originGt = 3742 ray->mOrigin[plane.mAxis] > plane.mPosition; 3743 3744 const bool terminationGt = 3745 ray->mTermination[plane.mAxis] > plane.mPosition; 3746 3747 // add view cell volume to front volume 3748 const bool addToFront = ((originInside && originGt) || (terminationInside && terminationGt)); 3749 3750 // add view cell volume to back volume 3751 const bool addToBack = ((originInside && !originGt) || (terminationInside && !terminationGt)); 3752 3753 // classify ray with respect to the child nodes the view cells contribute 3754 if (addToFront && addToBack) 3755 return 0; 3756 else if (addToBack) 3757 return -1; 3758 else if (addToFront) 3759 return 1; 3760 3761 return -2; 3762 } 3763 3764 3527 3765 float OspTree::EvalRenderCostDecrease(const AxisAlignedPlane &candidatePlane, 3528 const OspTraversalData &tData) const 3529 { 3530 #if 0 3531 return (float)-tData.mDepth; 3532 #endif 3533 3766 const OspTraversalData &tData, 3767 float &normalizedOldRenderCost) const 3768 { 3534 3769 float pvsFront = 0; 3535 3770 float pvsBack = 0; … … 3541 3776 float pBack = 0; 3542 3777 3543 Intersectable::NewMail(); 3778 const float viewSpaceVol = mVspTree->GetBoundingBox().GetVolume(); 3779 3780 //Intersectable::NewMail(); 3544 3781 KdLeaf::NewMail(); 3545 3782 ViewCell::NewMail(); … … 3549 3786 3550 3787 // evaluate reverse pvs and view cell volume on left and right cell 3788 // note: should I take all leaf objects or rather the objects hit by rays? 3551 3789 for (oit = leaf->mObjects.begin(); oit != oit_end; ++ oit) 3552 3790 { … … 3556 3794 ++ totalPvs; 3557 3795 3558 cout << "totalpvs " << totalPvs << endl; 3559 3796 //cout << "totalpvs " << totalPvs << endl; 3797 3798 // test if box falls in left / right child node 3560 3799 if (box.Max(candidatePlane.mAxis) > candidatePlane.mPosition) 3561 3800 { … … 3569 3808 3570 3809 3571 ViewCell::NewMail(); 3810 // sum up volume seen from the objects of left and right children 3811 // => the volume is the weight for the render cost equation 3812 ViewCell::NewMail(3); 3572 3813 3573 3814 RayInfoContainer::const_iterator rit, rit_end = tData.mRays->end(); … … 3577 3818 VssRay *ray = (*rit).mRay; 3578 3819 3579 // if hitpoint with one of the objects is inside this node 3580 if (GetLeaf(ray->mOrigin, ray->mOriginNode) == leaf) 3581 { 3820 // test if intersection point with one of the objects is inside this node 3821 const bool originInside = EndPointInsideNode(leaf, *ray, false); 3822 const bool terminationInside = EndPointInsideNode(leaf, *ray, true); 3823 3824 if (originInside || terminationInside) 3825 { 3826 // add volume to volumes of left and / or right children 3827 // if one of the ray end points is inside 3828 const int classification = ClassifyRay(ray, leaf, candidatePlane); 3829 3582 3830 ViewCellContainer viewCells; 3583 3831 mVspTree->GetViewCells(*ray, viewCells); … … 3585 3833 ViewCellContainer::const_iterator vit, vit_end = viewCells.end(); 3586 3834 3587 // add view cells volume to front3835 // evaluate view cells volume contribution 3588 3836 for (vit = viewCells.begin(); vit != vit_end; ++ vit) 3589 3837 { 3590 ViewCell *vc = *vit; 3591 3592 if (!vc->Mailed()) 3593 { 3594 vc->Mail(); 3595 3596 const float vol = vc->GetVolume(); 3597 pOverall += vol; 3598 3599 if (ray->mOrigin[candidatePlane.mAxis] > candidatePlane.mPosition) 3600 pFront += vol; 3601 else 3602 pBack += vol; 3603 } 3838 AddViewCellVolume(*vit, classification, pFront, pBack, pOverall); 3604 3839 } 3605 3840 } … … 3611 3846 const float newRenderCost = pvsFront * pFront + pvsBack * pBack; 3612 3847 3613 Debug << "total pvs: " << totalPvs << " p " << pOverall << endl 3614 << "old: " << oldRenderCost << " new: " << newRenderCost << " decrease: " 3615 << oldRenderCost - newRenderCost << endl; 3616 3617 // todo matt§§: how to normalize volume?? 3618 const float renderCostDecrease = (oldRenderCost - newRenderCost);// / mBoundingBox.GetVolume(); 3619 3620 // take render cost of node into account 3621 // otherwise danger of being stuck in a local minimum!! 3622 const float factor = mRenderCostDecreaseWeight; 3623 3624 const float normalizedOldRenderCost = oldRenderCost;// / mBoundingBox.GetVolume(); 3625 return factor * renderCostDecrease + (1.0f - factor) * normalizedOldRenderCost; 3848 // normalize volume with view space volume 3849 const float renderCostDecrease = (oldRenderCost - newRenderCost) / viewSpaceVol; 3850 3851 Debug << "\n==== eval render cost decrease ===" << endl 3852 << "back pvs: " << pvsBack << " front pvs " << pvsFront << " total pvs: " << totalPvs << endl 3853 << "back p: " << pBack / viewSpaceVol << " front p " << pFront / viewSpaceVol << " p: " << pOverall / viewSpaceVol << endl 3854 << "old rc: " << oldRenderCost / viewSpaceVol << " new rc: " << newRenderCost / viewSpaceVol << endl 3855 << "render cost decrease: " << renderCostDecrease << endl; 3856 3857 normalizedOldRenderCost = oldRenderCost / viewSpaceVol; 3858 3859 return renderCostDecrease; 3626 3860 } 3627 3861 … … 3741 3975 } 3742 3976 } 3743 3744 3977 } 3745 3978 … … 3961 4194 3962 4195 4196 void OspTree::AddViewCellVolume(ViewCell *vc, 4197 const int cf, 4198 float &frontVol, 4199 float &backVol, 4200 float &totalVol) const 4201 { 4202 //const float renderCost = mViewCellsManager->SimpleRay &raynderCost(obj); 4203 const float vol = vc->GetVolume(); 4204 4205 // view cell not found yet => new 4206 if (!vc->Mailed() && !vc->Mailed(1) && !vc->Mailed(2)) 4207 { 4208 totalVol += vol; 4209 } 4210 4211 if (cf >= 0) // front volume 4212 { 4213 if (!vc->Mailed() && !vc->Mailed(2)) 4214 { 4215 frontVol += vol; 4216 4217 // already in back volume => in both volumes 4218 if (vc->Mailed(1)) 4219 vc->Mail(2); 4220 else 4221 vc->Mail(); 4222 } 4223 } 4224 4225 if (cf <= 0) // back volume 4226 { 4227 if (!vc->Mailed(1) && !vc->Mailed(2)) 4228 { 4229 backVol += vol; 4230 4231 // already in front volume => in both volume 4232 if (vc->Mailed()) 4233 vc->Mail(2); 4234 else 4235 vc->Mail(1); 4236 } 4237 } 4238 } 4239 3963 4240 3964 4241 /********************************************************************/ … … 3989 4266 3990 4267 3991 SplitCandidate *HierarchyManager::PrepareVsp(const VssRayContainer &sampleRays,4268 VspTree::VspSplitCandidate *HierarchyManager::PrepareVsp(const VssRayContainer &sampleRays, 3992 4269 AxisAlignedBox3 *forcedViewSpace, 3993 4270 RayInfoContainer &rays) … … 4009 4286 const int pvsSize = mVspTree.ComputePvsSize(rays); 4010 4287 4011 Debug << "pvs size: " << pvsSize << endl;4012 Debug << "rays size: " << rays.size() << endl;4288 Debug << "pvs size: " << (int)pvsSize << endl; 4289 Debug << "rays size: " << (int)rays.size() << endl; 4013 4290 4014 4291 //-- prepare view space partition … … 4052 4329 4053 4330 4054 SplitCandidate * HierarchyManager::PrepareOsp(const VssRayContainer &sampleRays,4331 OspTree::OspSplitCandidate * HierarchyManager::PrepareOsp(const VssRayContainer &sampleRays, 4055 4332 const ObjectContainer &objects, 4056 4333 AxisAlignedBox3 *forcedObjectSpace, … … 4139 4416 const long startTime = GetTime(); 4140 4417 4141 int i = 0; 4418 RunConstruction(true); 4419 4420 cout << "finished in " << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl; 4421 4422 mVspTree.mVspStats.Stop(); 4423 } 4424 4425 4426 bool HierarchyManager::SubdivideSplitCandidate(SplitCandidate *sc) 4427 { 4428 const bool globalTerminationCriteriaMet = 4429 GlobalTerminationCriteriaMet(sc); 4430 4431 const bool vspSplit = (sc->Type() == SplitCandidate::VIEW_SPACE); 4432 4433 if (vspSplit) 4434 { 4435 mVspTree.Subdivide(mTQueue, sc, globalTerminationCriteriaMet); 4436 return true; 4437 } 4438 else 4439 { 4440 mOspTree.Subdivide(mTQueue, sc, globalTerminationCriteriaMet); 4441 return false; 4442 } 4443 } 4444 4445 4446 void HierarchyManager::RunConstruction(const bool repair) 4447 { 4448 int numNodes = 0; 4449 4142 4450 while (!FinishedConstruction()) 4143 4451 { 4144 mCurrentCandidate = NextSplitCandidate(); 4145 4146 const bool globalTerminationCriteriaMet = 4147 GlobalTerminationCriteriaMet(mCurrentCandidate); 4148 4149 cout << "view cells: " << i ++ << endl; 4150 4452 SplitCandidate *splitCandidate = NextSplitCandidate(); 4453 4454 cout << "nodes: " << ++ numNodes << endl; 4455 4456 mTotalCost -= splitCandidate->GetRenderCostDecrease(); 4457 4458 //-- subdivide leaf node 4459 SubdivideSplitCandidate(splitCandidate); 4460 4151 4461 // cost ratio of cost decrease / totalCost 4152 const float costRatio = mCurrentCandidate->GetPriority() / mTotalCost; 4153 //Debug << "cost ratio: " << costRatio << endl; 4462 const float costRatio = splitCandidate->GetRenderCostDecrease() / mTotalCost; 4463 4464 Debug << "\n**********" << endl 4465 << "total cost: " << mTotalCost << " render cost decr: " 4466 << splitCandidate->GetRenderCostDecrease() 4467 << " cost ratio: " << costRatio << endl << endl; 4154 4468 4155 4469 if (costRatio < mTermMinGlobalCostRatio) 4156 4470 ++ mGlobalCostMisses; 4157 4158 //-- subdivide leaf node4159 4160 // we have either a object space or view space split4161 if (mCurrentCandidate->Type() == SplitCandidate::VIEW_SPACE)4162 {4163 VspTree::VspSplitCandidate *sc =4164 dynamic_cast<VspTree::VspSplitCandidate *>(mCurrentCandidate);4165 4166 VspNode *r = mVspTree.Subdivide(mTQueue, *sc, globalTerminationCriteriaMet);4167 }4168 else // object space split4169 {4170 OspTree::OspSplitCandidate *sc =4171 dynamic_cast<OspTree::OspSplitCandidate *>(mCurrentCandidate);4172 4173 KdNode *r = mOspTree.Subdivide(mTQueue, *sc, globalTerminationCriteriaMet);4174 }4175 4471 4176 4472 // reevaluate candidates affected by the split 4177 4473 // for view space splits, this would be object space splits 4178 4474 // and other way round 4179 RepairQueue(); 4180 4181 DEL_PTR(mCurrentCandidate); 4182 } 4183 4184 cout << "finished in " << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl; 4185 4186 mVspTree.mVspStats.Stop(); 4475 if (repair) 4476 RepairQueue(); 4477 4478 DEL_PTR(splitCandidate); 4479 } 4187 4480 } 4188 4481 … … 4195 4488 RayInfoContainer *objectSpaceRays = new RayInfoContainer(); 4196 4489 4490 4197 4491 ///////////////////////////////////////////////////////////// 4198 4492 // view space space partition 4199 4493 ///////////////////////////////////////////////////////////// 4494 4200 4495 4201 4496 // makes no sense otherwise because only one kd cell available … … 4207 4502 mVspTree.mStoreKdPvs = false; 4208 4503 4209 SplitCandidate *sc = PrepareVsp(sampleRays, forcedViewSpace, *viewSpaceRays); 4210 mTQueue.Push(sc); 4504 VspTree::VspSplitCandidate *vsc = 4505 PrepareVsp(sampleRays, forcedViewSpace, *viewSpaceRays); 4506 // add to queue 4507 mTQueue.Push(vsc); 4211 4508 4212 4509 long startTime = GetTime(); … … 4218 4515 int i = 0; 4219 4516 4220 while (!FinishedConstruction()) 4221 { 4222 SplitCandidate *splitCandidate = NextSplitCandidate(); 4223 4224 const bool globalTerminationCriteriaMet = 4225 GlobalTerminationCriteriaMet(splitCandidate); 4226 4227 cout << "vsp nodes: " << i ++ << endl; 4228 4229 // cost ratio of cost decrease / totalCost 4230 const float costRatio = splitCandidate->GetPriority() / mTotalCost; 4231 //cout << "cost ratio: " << costRatio << endl; 4232 4233 if (costRatio < mTermMinGlobalCostRatio) 4234 ++ mGlobalCostMisses; 4235 4236 //-- subdivide leaf node 4237 4238 // we have either a object space or view space split 4239 VspTree::VspSplitCandidate *sc = 4240 dynamic_cast<VspTree::VspSplitCandidate *>(splitCandidate); 4241 4242 4243 VspNode *r = mVspTree.Subdivide(mTQueue, *sc, globalTerminationCriteriaMet); 4244 4245 DEL_PTR(splitCandidate); 4246 } 4517 // all objects can be seen from everywhere 4518 mTotalCost = (float)vsc->mParentData.mPvs; 4519 4520 const bool repairQueue = false; 4521 4522 // process view space candidates 4523 RunConstruction(repairQueue); 4247 4524 4248 4525 cout << "finished in " << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl; 4249 4526 mVspTree.mVspStats.Stop(); 4250 4527 4251 4528 4529 4252 4530 ///////////////////////////////////////////////////////////// 4253 4531 // object space partition 4254 4532 ///////////////////////////////////////////////////////////// 4255 4533 4256 Debug << " **************** osp construction **************" << endl;4534 Debug << "\n$$$$$$$$$ osp tree construction $$$$$$$$$$\n" << endl; 4257 4535 cout << "starting osp contruction ... " << endl; 4258 4536 4537 // compute first candidate 4538 OspTree::OspSplitCandidate *osc = 4539 PrepareOsp(sampleRays, objects, forcedViewSpace, *objectSpaceRays); 4540 4541 mTQueue.Push(osc); 4542 4543 mOspTree.mOspStats.Reset(); 4544 mOspTree.mOspStats.Start(); 4545 4259 4546 startTime = GetTime(); 4260 4547 4261 SplitCandidate *osc = 4262 PrepareOsp(sampleRays, objects, forcedViewSpace, *objectSpaceRays); 4263 4264 mTQueue.Push(osc); 4265 4266 4267 i = 0; 4268 while (!FinishedConstruction()) 4269 { 4270 SplitCandidate *splitCandidate = NextSplitCandidate(); 4271 4272 const bool globalTerminationCriteriaMet = 4273 GlobalTerminationCriteriaMet(splitCandidate); 4274 4275 // cost ratio of cost decrease / totalCost 4276 const float costRatio = splitCandidate->GetPriority() / mTotalCost; 4277 4278 //Debug << "cost ratio: " << costRatio << endl; 4279 //cout << "kd nodes: " << i ++ << endl; 4280 4281 if (costRatio < mTermMinGlobalCostRatio) 4282 ++ mGlobalCostMisses; 4283 4284 //-- subdivide leaf node 4285 4286 // object space split 4287 OspTree::OspSplitCandidate *sc = 4288 dynamic_cast<OspTree::OspSplitCandidate *>(splitCandidate); 4289 4290 KdNode *r = mOspTree.Subdivide(mTQueue, *sc, globalTerminationCriteriaMet); 4291 4292 DEL_PTR(splitCandidate); 4293 } 4294 4295 cout << "finished in " << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl; 4296 4548 // reset cost 4549 // start with one big kd cell - all objects can be seen from everywhere 4550 // note: only true for view space = object space 4551 mTotalCost = (float)osc->mParentData.mNode->mObjects.size();//(float)sc->mParentData.mPvs; 4552 4553 Debug << "reseting cost, new total cost: " << mTotalCost << endl; 4554 4555 // process object space candidates 4556 RunConstruction(repairQueue); 4557 4558 cout << "finished in " << TimeDiff(startTime, GetTime()) * 1e-3 << " secs" << endl; 4559 4560 mOspTree.mOspStats.Stop(); 4561 4562 // reset parameters 4297 4563 mVspTree.mUseKdPvsForHeuristics = savedCountMethod; 4298 4564 mVspTree.mStoreKdPvs = savedStoreMethod; … … 4304 4570 AxisAlignedBox3 *forcedViewSpace) 4305 4571 { 4572 // only view space partition 4573 // object kd tree is taken for osp 4574 4306 4575 mVspTree.mVspStats.Reset(); 4307 4576 mVspTree.mVspStats.Start(); … … 4315 4584 4316 4585 long startTime = GetTime(); 4317 int i = 0; 4318 4319 while (!FinishedConstruction()) 4320 { 4321 SplitCandidate *splitCandidate = NextSplitCandidate(); 4322 4323 const bool globalTerminationCriteriaMet = 4324 GlobalTerminationCriteriaMet(splitCandidate); 4325 4326 cout << "vsp nodes: " << i ++ << endl; 4327 4328 // cost ratio of cost decrease / totalCost 4329 const float costRatio = splitCandidate->GetPriority() / mTotalCost; 4330 //cout << "cost ratio: " << costRatio << endl; 4331 4332 if (costRatio < mTermMinGlobalCostRatio) 4333 ++ mGlobalCostMisses; 4334 4335 //-- subdivide leaf node 4336 4337 // we have either a object space or view space split 4338 VspTree::VspSplitCandidate *sc = 4339 dynamic_cast<VspTree::VspSplitCandidate *>(splitCandidate); 4340 4341 4342 VspNode *r = mVspTree.Subdivide(mTQueue, *sc, globalTerminationCriteriaMet); 4343 4344 DEL_PTR(splitCandidate); 4345 } 4586 4587 RunConstruction(false); 4346 4588 4347 4589 cout << "finished in " << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl; … … 4350 4592 4351 4593 4352 bool HierarchyManager::FinishedConstruction() 4594 bool HierarchyManager::FinishedConstruction() const 4353 4595 { 4354 4596 return mTQueue.Empty();
Note: See TracChangeset
for help on using the changeset viewer.