Changeset 1020 for GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp
- Timestamp:
- 06/18/06 03:47:06 (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GTP/trunk/Lib/Vis/Preprocessing/src/VspOspTree.cpp
r1016 r1020 16 16 #include "ViewCellsManager.h" 17 17 #include "Beam.h" 18 #include "KdTree.h" 19 18 20 19 21 namespace GtpVisibilityPreprocessor { … … 381 383 382 384 383 void VspTree:: Construct(const VssRayContainer &sampleRays,384 AxisAlignedBox3 *forcedBoundingBox)385 void VspTree::PrepareConstruction(const VssRayContainer &sampleRays, 386 AxisAlignedBox3 *forcedBoundingBox) 385 387 { 386 388 mVspStats.nodes = 1; 387 mBo x.Initialize(); // initialise BSPtree bounding box389 mBoundingBox.Initialize(); // initialise vsp tree bounding box 388 390 389 391 if (forcedBoundingBox) 390 mBox = *forcedBoundingBox; 391 392 PolygonContainer polys; 393 RayInfoContainer *rays = new RayInfoContainer(); 394 392 mBoundingBox = *forcedBoundingBox; 393 395 394 VssRayContainer::const_iterator rit, rit_end = sampleRays.end(); 396 395 397 long startTime = GetTime();398 399 cout << "Extracting polygons from rays ... ";400 401 396 Intersectable::NewMail(); 402 397 403 int numObj = 0; 404 405 //-- store rays 398 //-- compute bounding box 406 399 for (rit = sampleRays.begin(); rit != rit_end; ++ rit) 407 400 { 408 401 VssRay *ray = *rit; 409 402 410 float minT, maxT; 411 412 static Ray hray; 413 hray.Init(*ray); 414 415 // TODO: not very efficient to implictly cast between rays types 416 if (mBox.GetRaySegment(hray, minT, maxT)) 417 { 418 float len = ray->Length(); 419 420 if (!len) 421 len = Limits::Small; 422 423 rays->push_back(RayInfo(ray, minT / len, maxT / len)); 424 } 425 } 426 427 mTermMinProbability *= mBox.GetVolume(); 428 403 // compute bounding box of view space 404 if (!forcedBoundingBox) 405 { 406 mBoundingBox.Include(ray->GetTermination()); 407 mBoundingBox.Include(ray->GetOrigin()); 408 } 409 } 410 411 mTermMinProbability *= mBoundingBox.GetVolume(); 429 412 mGlobalCostMisses = 0; 430 431 cout << "finished" << endl; 432 433 // use split cost priority queue 434 Construct(rays); 413 } 414 415 416 void VspTree::AddSubdivisionStats(const int viewCells, 417 const float renderCostDecr, 418 const float splitCandidateCost, 419 const float totalRenderCost, 420 const float avgRenderCost) 421 { 422 mSubdivisionStats 423 << "#ViewCells\n" << viewCells << endl 424 << "#RenderCostDecrease\n" << renderCostDecr << endl 425 << "#SplitCandidateCost\n" << splitCandidateCost << endl 426 << "#TotalRenderCost\n" << totalRenderCost << endl 427 << "#AvgRenderCost\n" << avgRenderCost << endl; 435 428 } 436 429 … … 449 442 450 443 451 void VspTree::Construct(RayInfoContainer *rays)452 {453 #if TODO454 VspSplitQueue tQueue;455 /// create new vsp tree456 mRoot = new VspLeaf();457 /// we use the overall probability as normalizer458 const float prop = mBox.GetVolume();459 460 VspTraversalData tData(mRoot,461 0,462 rays,463 ComputePvsSize(*rays),464 prop,465 mBox);466 467 468 // compute first split candidate469 VspSplitCandidate splitCandidate;470 EvalSplitCandidate(tData, splitCandidate);471 472 tQueue.push(splitCandidate);473 474 mTotalCost = tData.mPvs * tData.mProbability / mBox.GetVolume();475 mTotalPvsSize = tData.mPvs;476 477 mSubdivisionStats478 << "#ViewCells\n1\n" << endl479 << "#RenderCostDecrease\n0\n" << endl480 << "#SplitCandidateCost\n0\n" << endl481 << "#TotalRenderCost\n" << mTotalCost << endl482 << "#AvgRenderCost\n" << mTotalPvsSize << endl;483 484 Debug << "total cost: " << mTotalCost << endl;485 486 487 mVspStats.Start();488 cout << "Constructing vsp bsp tree ... \n";489 490 long startTime = GetTime();491 int nLeaves = 500;492 int nViewCells = 500;493 494 // used for intermediate time measurements and progress495 long interTime = GetTime();496 497 mOutOfMemory = false;498 499 mCreatedViewCells = 0;500 501 while (!tQueue.empty())502 {503 splitCandidate = tQueue.top();504 tQueue.pop();505 506 // cost ratio of cost decrease / totalCost507 float costRatio = splitCandidate.GetCost() / mTotalCost;508 509 //Debug << "cost ratio: " << costRatio << endl;510 511 if (costRatio < mTermMinGlobalCostRatio)512 ++ mGlobalCostMisses;513 514 if (0 && !mOutOfMemory)515 {516 float mem = GetMemUsage();517 518 if (mem > mMaxMemory)519 {520 mOutOfMemory = true;521 Debug << "memory limit reached: " << mem << endl;522 }523 }524 525 // subdivide leaf node526 VspNode *r = Subdivide(tQueue, splitCandidate);527 528 if (r == mRoot)529 Debug << "VSP BSP tree construction time spent at root: "530 << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl;531 532 if (mVspStats.Leaves() >= nLeaves)533 {534 nLeaves += 500;535 536 cout << "leaves=" << mVspStats.Leaves() << endl;537 Debug << "needed "538 << TimeDiff(interTime, GetTime())*1e-3539 << " secs to create 500 view cells" << endl;540 interTime = GetTime();541 }542 543 if (mCreatedViewCells == nViewCells)544 {545 nViewCells += 500;546 547 cout << "generated " << mCreatedViewCells << " viewcells" << endl;548 }549 }550 551 Debug << "Used Memory: " << GetMemUsage() << " MB" << endl << endl;552 cout << "finished\n";553 554 mVspStats.Stop();555 #endif556 }557 558 559 444 bool VspTree::LocalTerminationCriteriaMet(const VspTraversalData &data) const 560 445 { … … 577 462 578 463 579 // subdivide using a split plane queue580 464 VspNode *VspTree::Subdivide(SplitQueue &tQueue, 581 VspSplitCandidate &splitCandidate) 465 VspSplitCandidate &splitCandidate, 466 const bool globalCriteriaMet) 582 467 { 583 468 VspTraversalData &tData = splitCandidate.mParentData; … … 585 470 VspNode *newNode = tData.mNode; 586 471 587 if (!LocalTerminationCriteriaMet(tData) && ! GlobalTerminationCriteriaMet(tData))472 if (!LocalTerminationCriteriaMet(tData) && !globalCriteriaMet) 588 473 { 589 474 VspTraversalData tFrontData; … … 594 479 // create new interior node and two leaf node 595 480 const AxisAlignedPlane splitPlane = splitCandidate.mSplitPlane; 596 597 481 newNode = SubdivideNode(splitPlane, tData, tFrontData, tBackData); 598 482 … … 604 488 tBackData.mMaxCostMisses = maxCostMisses; 605 489 606 490 //-- statistics 607 491 if (1) 608 492 { 609 float cFront = (float)tFrontData.mPvs * tFrontData.mProbability; 610 float cBack = (float)tBackData.mPvs * tBackData.mProbability; 611 float cData = (float)tData.mPvs * tData.mProbability; 612 613 614 float costDecr = 615 (cFront + cBack - cData) / mBox.GetVolume(); 493 const float cFront = (float)tFrontData.mPvs * tFrontData.mProbability; 494 const float cBack = (float)tBackData.mPvs * tBackData.mProbability; 495 const float cData = (float)tData.mPvs * tData.mProbability; 496 497 const float costDecr = 498 (cFront + cBack - cData) / mBoundingBox.GetVolume(); 616 499 617 500 mTotalCost += costDecr; 618 501 mTotalPvsSize += tFrontData.mPvs + tBackData.mPvs - tData.mPvs; 619 502 620 mSubdivisionStats 621 << "#ViewCells\n" << mVspStats.Leaves() << endl 622 << "#RenderCostDecrease\n" << -costDecr << endl 623 << "#SplitCandidateCost\n" << splitCandidate.GetPriority() << endl 624 << "#TotalRenderCost\n" << mTotalCost << endl 625 << "#AvgRenderCost\n" << (float)mTotalPvsSize / (float)mVspStats.Leaves() << endl; 626 } 627 628 629 //-- push the new split candidates on the stack 630 VspSplitCandidate frontCandidate; 631 VspSplitCandidate backCandidate; 632 633 EvalSplitCandidate(tFrontData, frontCandidate); 634 EvalSplitCandidate(tBackData, backCandidate); 635 #if TODO 503 AddSubdivisionStats(mVspStats.Leaves(), 504 -costDecr, 505 splitCandidate.GetPriority(), 506 mTotalCost, 507 (float)mTotalPvsSize / (float)mVspStats.Leaves()); 508 } 509 510 511 //-- push the new split candidates on the queue 512 VspSplitCandidate *frontCandidate = new VspSplitCandidate(); 513 VspSplitCandidate *backCandidate = new VspSplitCandidate(); 514 515 EvalSplitCandidate(tFrontData, *frontCandidate); 516 EvalSplitCandidate(tBackData, *backCandidate); 517 636 518 tQueue.push(frontCandidate); 637 519 tQueue.push(backCandidate); 638 #endif 520 639 521 // delete old leaf node 640 522 DEL_PTR(tData.mNode); … … 646 528 { 647 529 VspLeaf *leaf = dynamic_cast<VspLeaf *>(newNode); 530 648 531 VspViewCell *viewCell = new VspViewCell(); 649 650 532 leaf->SetViewCell(viewCell); 651 533 … … 671 553 } 672 554 } 673 674 // should I check here? 555 675 556 viewCell->mLeaf = leaf; 676 557 … … 678 559 leaf->mProbability = tData.mProbability; 679 560 680 EvaluateLeafStats(tData); 561 // finally evaluate stats until this leaf 562 EvaluateLeafStats(tData); 681 563 } 682 564 683 565 //-- cleanup 684 566 tData.Clear(); 685 567 686 568 return newNode; 687 569 } … … 691 573 VspSplitCandidate &splitData) 692 574 { 693 VspTraversalData frontData;694 VspTraversalData backData;695 575 float frontProb; 576 float backtProb; 577 696 578 VspLeaf *leaf = dynamic_cast<VspLeaf *>(tData.mNode); 697 579 698 580 // compute locally best split plane 699 581 const bool success = 700 582 SelectPlane(tData, splitData.mSplitPlane, 701 front Data.mProbability, backData.mProbability);583 frontProb, backtProb); 702 584 703 585 //TODO … … 789 671 return interior; 790 672 } 791 792 /*793 KdNode *VspOpsTree::SubdivideSpatialNode(KdLeaf *leaf,794 const AxisAlignedPlane &splitPlane,795 const AxisAlignedBox3 &box,796 AxisAlignedBox3 &backBBox,797 AxisAlignedBox3 &frontBBox)798 {799 float position;800 801 #if TODO802 mSpatialStat.nodes += 2;803 mSpatialStat.splits[axis];804 #endif805 806 // add the new nodes to the tree807 KdInterior *node = new KdInterior(leaf->mParent);808 809 node->mAxis = splitPlane.mAxis;810 node->mPosition = splitPlane.mPosition;811 node->mBox = box;812 813 backBBox = box;814 frontBBox = box;815 816 // first count ray sides817 int objectsBack = 0;818 int objectsFront = 0;819 820 backBBox.SetMax(axis, position);821 frontBBox.SetMin(axis, position);822 823 SplitObjects(leaf->m824 ObjectContainer::const_iterator mi, mi_end = leaf->mObjects.end();825 826 for ( mi = leaf->mObjects.begin(); mi != mi_end; ++ mi)827 {828 // determine the side of this ray with respect to the plane829 AxisAlignedBox3 box = (*mi)->GetBox();830 831 if (box.Max(axis) > position )832 ++ objectsFront;833 834 if (box.Min(axis) < position )835 objectsBack++;836 }837 838 839 KdLeaf *back = new KdLeaf(node, objectsBack);840 KdLeaf *front = new KdLeaf(node, objectsFront);841 842 // replace a link from node's parent843 if ( leaf->mParent )844 leaf->mParent->ReplaceChildLink(leaf, node);845 846 // and setup child links847 node->SetupChildLinks(back, front);848 849 for (mi = leaf->mObjects.begin();850 mi != leaf->mObjects.end();851 mi++) {852 // determine the side of this ray with respect to the plane853 AxisAlignedBox3 box = (*mi)->GetBox();854 855 if (box.Max(axis) >= position )856 front->mObjects.push_back(*mi);857 858 if (box.Min(axis) < position )859 back->mObjects.push_back(*mi);860 861 mStat.objectRefs -= (int)leaf->mObjects.size();862 mStat.objectRefs += objectsBack + objectsFront;863 }864 865 delete leaf;866 return node;867 }868 */869 870 673 871 674 … … 1267 1070 1268 1071 1269 // 1072 //-- pvs rendering heuristics 1270 1073 const int lowerPvsLimit = mViewCellsManager->GetMinPvsSize(); 1271 1074 const int upperPvsLimit = mViewCellsManager->GetMaxPvsSize(); 1272 1075 1273 // only render cost heuristics or combined with standard deviation1274 const float penaltyOld = EvalPvsPenalty( totalPvs, lowerPvsLimit, upperPvsLimit);1275 const float penaltyFront = EvalPvsPenalty( pvsFront, lowerPvsLimit, upperPvsLimit);1276 const float penaltyBack = EvalPvsPenalty( pvsBack, lowerPvsLimit, upperPvsLimit);1076 //-- only render cost heuristics or combined with standard deviation 1077 const float penaltyOld = EvalPvsPenalty((int)totalPvs, lowerPvsLimit, upperPvsLimit); 1078 const float penaltyFront = EvalPvsPenalty((int)pvsFront, lowerPvsLimit, upperPvsLimit); 1079 const float penaltyBack = EvalPvsPenalty((int)pvsBack, lowerPvsLimit, upperPvsLimit); 1277 1080 1278 1081 const float oldRenderCost = pOverall * penaltyOld; … … 1280 1083 1281 1084 //Debug << "decrease: " << oldRenderCost - newRenderCost << endl; 1282 const float renderCostDecrease = (oldRenderCost - newRenderCost) / mBo x.GetVolume();1085 const float renderCostDecrease = (oldRenderCost - newRenderCost) / mBoundingBox.GetVolume(); 1283 1086 1284 1087 1285 1088 #if 1 1286 // take render cost of node into account to avoid being stuck in a local minimum 1287 const float normalizedOldRenderCost = oldRenderCost / mBox.GetVolume(); 1089 // take render cost of node into account 1090 // otherwise danger of being stuck in a local minimum!! 1091 const float normalizedOldRenderCost = oldRenderCost / mBoundingBox.GetVolume(); 1288 1092 return 0.99f * renderCostDecrease + 0.01f * normalizedOldRenderCost; 1289 1093 #else … … 1434 1238 AxisAlignedBox3 VspTree::GetBoundingBox() const 1435 1239 { 1436 return mBo x;1240 return mBoundingBox; 1437 1241 } 1438 1242 … … 1581 1385 void VspTree::ValidateTree() 1582 1386 { 1387 mVspStats.invalidLeaves = 0; 1388 1583 1389 stack<VspNode *> nodeStack; 1584 1390 … … 1587 1393 1588 1394 nodeStack.push(mRoot); 1589 1590 mVspStats.invalidLeaves = 0; 1395 1591 1396 while (!nodeStack.empty()) 1592 1397 { … … 1662 1467 } 1663 1468 } 1664 1665 1469 } 1666 1470 1667 1471 1668 1472 int VspTree::FindNeighbors(VspLeaf *n, 1669 1670 1473 vector<VspLeaf *> &neighbors, 1474 const bool onlyUnmailed) const 1671 1475 { 1672 1476 stack<VspNode *> nodeStack; 1673 1674 1477 nodeStack.push(mRoot); 1675 1478 … … 1946 1749 float maxt, mint; 1947 1750 1948 if (!mBo x.GetRaySegment(ray, mint, maxt))1751 if (!mBoundingBox.GetRaySegment(ray, mint, maxt)) 1949 1752 return 0; 1950 1753 … … 1978 1781 // cases N1,N2,N3,P5,Z2,Z3 1979 1782 continue; 1980 } else 1783 } 1784 else 1981 1785 { 1982 1786 // case N4 … … 2020 1824 ++ hits; 2021 1825 } 2022 2023 1826 #if 0 2024 1827 leaf->mRays.push_back(RayInfo(new VssRay(origin, termination, NULL, NULL, 0))); 2025 1828 #endif 2026 1829 // get the next node from the stack … … 2088 1891 { 2089 1892 int collapsed = 0; 2090 //TODO 2091 #if HAS_TO_BE_REDONE 1893 2092 1894 (void)CollapseTree(mRoot, collapsed); 2093 2094 1895 // revalidate leaves 2095 1896 RepairViewCellsLeafLists(); 2096 #endif 1897 2097 1898 return collapsed; 2098 1899 } … … 2286 2087 2287 2088 int VspTree::SplitRays(const AxisAlignedPlane &plane, 2288 2289 2290 2089 RayInfoContainer &rays, 2090 RayInfoContainer &frontRays, 2091 RayInfoContainer &backRays) const 2291 2092 { 2292 2093 int splits = 0; … … 2338 2139 { 2339 2140 if (!node->GetParent()) 2340 return mBo x;2141 return mBoundingBox; 2341 2142 2342 2143 if (!node->IsLeaf()) … … 2358 2159 2359 2160 2161 2162 /*****************************************************************/ 2163 /* class OpsTree implementation */ 2164 /*****************************************************************/ 2165 2166 2167 void OspTree::SplitObjects(const AxisAlignedPlane & splitPlane, 2168 const ObjectContainer &objects, 2169 ObjectContainer &back, 2170 ObjectContainer &front) 2171 { 2172 ObjectContainer::const_iterator oit, oit_end = objects.end(); 2173 2174 for (oit = objects.begin(); oit != oit_end; ++ oit) 2175 { 2176 // determine the side of this ray with respect to the plane 2177 const AxisAlignedBox3 box = (*oit)->GetBox(); 2178 2179 if (box.Max(splitPlane.mAxis) >= splitPlane.mPosition) 2180 front.push_back(*oit); 2181 2182 if (box.Min(splitPlane.mAxis) < splitPlane.mPosition) 2183 back.push_back(*oit); 2184 #if TODO 2185 mStat.objectRefs -= (int)objects.size(); 2186 mStat.objectRefs += objectsBack + objectsFront; 2187 #endif 2188 } 2189 } 2190 2191 2192 KdInterior *OspTree::SubdivideNode(KdLeaf *leaf, 2193 const AxisAlignedPlane &splitPlane, 2194 const AxisAlignedBox3 &box, 2195 AxisAlignedBox3 &backBBox, 2196 AxisAlignedBox3 &frontBBox) 2197 { 2198 #if TODO 2199 mSpatialStat.nodes += 2; 2200 mSpatialStat.splits[axis]; 2201 #endif 2202 2203 // add the new nodes to the tree 2204 KdInterior *node = new KdInterior(leaf->mParent); 2205 2206 const int axis = splitPlane.mAxis; 2207 const float position = splitPlane.mPosition; 2208 2209 node->mAxis = axis; 2210 node->mPosition = position; 2211 node->mBox = box; 2212 2213 backBBox = box; 2214 frontBBox = box; 2215 2216 // first count ray sides 2217 int objectsBack = 0; 2218 int objectsFront = 0; 2219 2220 backBBox.SetMax(axis, position); 2221 frontBBox.SetMin(axis, position); 2222 2223 ObjectContainer::const_iterator mi, mi_end = leaf->mObjects.end(); 2224 2225 for ( mi = leaf->mObjects.begin(); mi != mi_end; ++ mi) 2226 { 2227 // determine the side of this ray with respect to the plane 2228 const AxisAlignedBox3 box = (*mi)->GetBox(); 2229 2230 if (box.Max(axis) > position) 2231 ++ objectsFront; 2232 2233 if (box.Min(axis) < position) 2234 ++ objectsBack; 2235 } 2236 2237 KdLeaf *back = new KdLeaf(node, objectsBack); 2238 KdLeaf *front = new KdLeaf(node, objectsFront); 2239 2240 // replace a link from node's parent 2241 if (leaf->mParent) 2242 leaf->mParent->ReplaceChildLink(leaf, node); 2243 2244 // and setup child links 2245 node->SetupChildLinks(back, front); 2246 2247 SplitObjects(splitPlane, leaf->mObjects, back->mObjects, front->mObjects); 2248 2249 //delete leaf; 2250 return node; 2251 } 2252 2253 2254 KdNode *OspTree::Subdivide(SplitQueue &tQueue, 2255 OspSplitCandidate &splitCandidate, 2256 const bool globalCriteriaMet) 2257 { 2258 OspTraversalData &tData = splitCandidate.mParentData; 2259 2260 KdNode *newNode = tData.mNode; 2261 2262 if (!LocalTerminationCriteriaMet(tData) && !globalCriteriaMet) 2263 { 2264 OspTraversalData tFrontData; 2265 OspTraversalData tBackData; 2266 2267 //-- continue subdivision 2268 2269 // create new interior node and two leaf node 2270 const AxisAlignedPlane splitPlane = splitCandidate.mSplitPlane; 2271 newNode = SubdivideNode(dynamic_cast<KdLeaf *>(newNode), 2272 splitPlane, 2273 tData.mBoundingBox, 2274 tFrontData.mBoundingBox, 2275 tBackData.mBoundingBox); 2276 2277 const int maxCostMisses = splitCandidate.mMaxCostMisses; 2278 2279 // how often was max cost ratio missed in this branch? 2280 tFrontData.mMaxCostMisses = maxCostMisses; 2281 tBackData.mMaxCostMisses = maxCostMisses; 2282 2283 //-- push the new split candidates on the queue 2284 OspSplitCandidate *frontCandidate = new OspSplitCandidate(); 2285 OspSplitCandidate *backCandidate = new OspSplitCandidate(); 2286 2287 EvalSplitCandidate(tFrontData, *frontCandidate); 2288 EvalSplitCandidate(tBackData, *backCandidate); 2289 2290 tQueue.push(frontCandidate); 2291 tQueue.push(backCandidate); 2292 2293 // delete old leaf node 2294 DEL_PTR(tData.mNode); 2295 } 2296 2297 2298 //-- terminate traversal 2299 if (newNode->IsLeaf()) 2300 { 2301 //KdLeaf *leaf = dynamic_cast<KdLeaf *>(newNode); 2302 EvaluateLeafStats(tData); 2303 } 2304 2305 //-- cleanup 2306 tData.Clear(); 2307 2308 return newNode; 2309 } 2310 2311 2312 void OspTree::EvalSplitCandidate(OspTraversalData &tData, 2313 OspSplitCandidate &splitData) 2314 { 2315 float frontProb; 2316 float backtProb; 2317 2318 KdLeaf *leaf = dynamic_cast<KdLeaf *>(tData.mNode); 2319 2320 // compute locally best split plane 2321 const bool success = false; 2322 #if TODO 2323 SelectPlane(tData, splitData.mSplitPlane, 2324 frontData.mProbability, backData.mProbability); 2325 2326 //TODO 2327 // compute global decrease in render cost 2328 splitData.mPriority = EvalRenderCostDecrease(splitData.mSplitPlane, tData); 2329 splitData.mParentData = tData; 2330 splitData.mMaxCostMisses = success ? tData.mMaxCostMisses : tData.mMaxCostMisses + 1; 2331 #endif 2332 } 2333 2334 2360 2335 /*****************************************************************/ 2361 2336 /* class HierarchyManager implementation */ … … 2376 2351 2377 2352 2378 void HierarchyManager::PrepareTraversal() 2379 { 2380 2381 #if TODO 2382 /// create new vsp tree 2383 mRoot = new VspLeaf(); 2384 /// we use the overall probability as normalizer 2385 const float prop = mBoundingBox.GetVolume(); 2386 2387 VspTraversalData tData(mRoot, 2388 0, 2389 rays, 2390 ComputePvsSize(*rays), 2391 prop, 2392 mBoundingBox); 2393 2394 2395 // compute first split candidates 2396 VspTree::VspSplitCandidate vspSplitCandidate = new VspTree::VspSplitCandidate(); 2397 EvalSplitCandidate(tData, *vspSplitCandidate); 2398 mTQueue.push(splitCandidate); 2399 2400 OspSplitCandidate ospSplitCandidate = new OspSplitCandidate(); 2401 EvalSplitCandidate(tData, *ospSplitCandidate); 2402 mTQueue.push(ospSplitCandidate); 2403 2404 mTotalCost = tData.mPvs * tData.mProbability / mBox.GetVolume(); 2405 mTotalPvsSize = tData.mPvs; 2406 2407 mSubdivisionStats 2408 << "#ViewCells\n1\n" << endl 2409 << "#RenderCostDecrease\n0\n" << endl 2410 << "#SplitCandidateCost\n0\n" << endl 2411 << "#TotalRenderCost\n" << mTotalCost << endl 2412 << "#AvgRenderCost\n" << mTotalPvsSize << endl; 2413 2414 Debug << "total cost: " << mTotalCost << endl; 2415 2416 #endif 2353 void HierarchyManager::PrepareConstruction(const VssRayContainer &sampleRays, 2354 AxisAlignedBox3 *forcedViewSpace, 2355 RayInfoContainer &rays) 2356 { 2357 VssRayContainer::const_iterator rit, rit_end = sampleRays.end(); 2358 2359 long startTime = GetTime(); 2360 2361 cout << "storing rays ... "; 2362 2363 Intersectable::NewMail(); 2364 2365 mVspTree->PrepareConstruction(sampleRays, forcedViewSpace); 2366 2367 //-- store rays 2368 for (rit = sampleRays.begin(); rit != rit_end; ++ rit) 2369 { 2370 VssRay *ray = *rit; 2371 2372 float minT, maxT; 2373 2374 static Ray hray; 2375 hray.Init(*ray); 2376 2377 // TODO: not very efficient to implictly cast between rays types 2378 if (mBoundingBox.GetRaySegment(hray, minT, maxT)) 2379 { 2380 float len = ray->Length(); 2381 2382 if (!len) 2383 len = Limits::Small; 2384 2385 rays.push_back(RayInfo(ray, minT / len, maxT / len)); 2386 } 2387 } 2388 2389 cout << "finished" << endl; 2390 2391 //mOspTree->PrepareConstruction(sampleRays, forcedViewSpace, rays); 2392 } 2393 2394 2395 bool HierarchyManager::GlobalTerminationCriteriaMet(SplitCandidate *candidate) const 2396 { 2397 if (candidate->Type() == SplitCandidate::VIEW_SPACE) 2398 { 2399 VspTree::VspSplitCandidate *sc = 2400 dynamic_cast<VspTree::VspSplitCandidate *>(candidate); 2401 2402 return mVspTree->GlobalTerminationCriteriaMet(sc->mParentData); 2403 } 2404 2405 return true; 2417 2406 } 2418 2407 … … 2420 2409 void HierarchyManager::Construct(const VssRayContainer &sampleRays, 2421 2410 const ObjectContainer &objects, 2422 AxisAlignedBox3 *forcedBoundingBox) 2423 { 2424 #if TODO 2425 //-- store rays 2426 for (rit = sampleRays.begin(); rit != rit_end; ++ rit) 2427 { 2428 VssRay *ray = *rit; 2429 2430 float minT, maxT; 2431 2432 static Ray hray; 2433 hray.Init(*ray); 2434 2435 // TODO: not very efficient to implictly cast between rays types 2436 if (mBoundingBox.GetRaySegment(hray, minT, maxT)) 2437 { 2438 float len = ray->Length(); 2439 2440 if (!len) 2441 len = Limits::Small; 2442 2443 rays->push_back(RayInfo(ray, minT / len, maxT / len)); 2444 } 2445 } 2446 #endif 2447 } 2448 2449 2450 bool HierarchyManager::FinishedConstruction() 2451 { 2452 return mTQueue.empty(); 2453 } 2454 2455 2456 void HierarchyManager::Construct(RayInfoContainer *rays) 2457 { 2458 PrepareTraversal(); 2411 AxisAlignedBox3 *forcedViewSpace) 2412 { 2413 RayInfoContainer *rays = new RayInfoContainer(); 2414 2415 // prepare vsp and osp trees for traversal 2416 PrepareConstruction(sampleRays, forcedViewSpace, *rays); 2459 2417 2460 2418 mVspTree->mVspStats.Start(); 2461 cout << "Constructing vsp bsp tree ... \n"; 2462 2419 2420 cout << "Constructing view space / object space tree ... \n"; 2463 2421 const long startTime = GetTime(); 2464 2422 … … 2467 2425 SplitCandidate *splitCandidate = NextSplitCandidate(); 2468 2426 2427 const bool globalTerminationCriteriaMet = 2428 GlobalTerminationCriteriaMet(splitCandidate); 2429 2469 2430 // cost ratio of cost decrease / totalCost 2470 2431 const float costRatio = splitCandidate->GetPriority() / mTotalCost; 2471 2472 2432 //Debug << "cost ratio: " << costRatio << endl; 2473 2433 … … 2475 2435 ++ mGlobalCostMisses; 2476 2436 2477 // subdivide leaf node2478 // either object space or view space2437 //-- subdivide leaf node 2438 //-- either a object space or view space split 2479 2439 if (splitCandidate->Type() == SplitCandidate::VIEW_SPACE) 2480 2440 { … … 2482 2442 dynamic_cast<VspTree::VspSplitCandidate *>(splitCandidate); 2483 2443 2484 VspNode *r = mVspTree->Subdivide(mTQueue, *sc );2485 } 2486 else // object space 2444 VspNode *r = mVspTree->Subdivide(mTQueue, *sc, globalTerminationCriteriaMet); 2445 } 2446 else // object space split 2487 2447 { 2488 2448 #if TODO … … 2490 2450 #endif 2491 2451 } 2492 } 2493 2494 cout << "finished\n"; 2452 2453 DEL_PTR(splitCandidate); 2454 } 2455 2456 cout << "finished in " << TimeDiff(startTime, GetTime())*1e-3 << "secs" << endl; 2495 2457 2496 2458 mVspTree->mVspStats.Stop(); 2497 2459 } 2498 2460 2499 } 2461 2462 bool HierarchyManager::FinishedConstruction() 2463 { 2464 return mTQueue.empty(); 2465 } 2466 2467 2468 }
Note: See TracChangeset
for help on using the changeset viewer.