Changeset 587 for trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
- Timestamp:
- 02/04/06 12:46:14 (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
r582 r587 10 10 #include "Triangle3.h" 11 11 #include "Tetrahedron3.h" 12 13 #include <stack> 14 12 #include "ViewCellsManager.h" 15 13 #include "Exporter.h" 16 14 #include "Plane3.h" 15 #include <stack> 17 16 18 17 //-- static members … … 214 213 BspTree::BspTree(): 215 214 mRoot(NULL), 216 mUseAreaForPvs( true),215 mUseAreaForPvs(false), 217 216 mGenerateViewCells(true) 218 217 { … … 227 226 environment->GetIntValue("BspTree.Termination.minPolygons", mTermMinPolys); 228 227 environment->GetIntValue("BspTree.Termination.minRays", mTermMinRays); 229 environment->GetFloatValue("BspTree.Termination.min Area", mTermMinArea);228 environment->GetFloatValue("BspTree.Termination.minProbability", mTermMinProbability); 230 229 environment->GetFloatValue("BspTree.Termination.maxRayContribution", mTermMaxRayContribution); 231 230 environment->GetFloatValue("BspTree.Termination.minAccRayLenght", mTermMinAccRayLength); … … 258 257 environment->GetFloatValue("BspTree.AxisAligned.splitBorder", mSplitBorder); 259 258 environment->GetIntValue("BspTree.maxTests", mMaxTests); 259 environment->GetIntValue("BspTree.Termination.maxViewCells", mMaxViewCells); 260 260 261 261 environment->GetFloatValue("BspTree.Construction.epsilon", mEpsilon); … … 263 263 Debug << "BSP max depth: " << mTermMaxDepth << endl; 264 264 Debug << "BSP min PVS: " << mTermMinPvs << endl; 265 Debug << "BSP min area: " << mTermMinArea<< endl;265 Debug << "BSP min probability: " << mTermMinProbability << endl; 266 266 Debug << "BSP max polys: " << mTermMinPolys << endl; 267 267 Debug << "BSP max rays: " << mTermMinRays << endl; … … 413 413 << maxCostNodes * 100 / (double)Leaves() << endl; 414 414 415 app << "#N_PMIN AREALEAVES ( Percentage of leaves with mininum probability )\n"415 app << "#N_PMINPROBABILITYAREALEAVES ( Percentage of leaves with mininum probability )\n" 416 416 << minProbabilityNodes * 100 / (double)Leaves() << endl; 417 417 … … 480 480 new BoundedRayContainer(), 481 481 0, 482 m Box.SurfaceArea(),482 mUseAreaForPvs ? mBox.SurfaceArea() : mBox.GetVolume(), 483 483 new BspNodeGeometry())); 484 484 … … 519 519 tData.mRays, 520 520 tData.mPvs, 521 m Box.SurfaceArea(),521 mUseAreaForPvs ? mBox.SurfaceArea() : mBox.GetVolume(), 522 522 new BspNodeGeometry()); 523 523 … … 528 528 tData.mRays, 529 529 tData.mPvs, 530 mBox.SurfaceArea(),530 mUseAreaForPvs ? mBox.SurfaceArea() : mBox.GetVolume(), 531 531 new BspNodeGeometry()); 532 532 … … 583 583 } 584 584 585 585 586 int BspTree::AddToPolygonSoup(const ViewCellContainer &viewCells, 586 587 PolygonContainer &polys, … … 604 605 } 605 606 606 int BspTree::AddToPolygonSoup(const ObjectContainer &objects, PolygonContainer &polys, int maxObjects) 607 { 608 int limit = (maxObjects > 0) ? Min((int)objects.size(), maxObjects) : (int)objects.size(); 607 608 int BspTree::AddToPolygonSoup(const ObjectContainer &objects, 609 PolygonContainer &polys, 610 int maxObjects, 611 bool addToBbox) 612 { 613 int limit = (maxObjects > 0) ? 614 Min((int)objects.size(), maxObjects) : (int)objects.size(); 609 615 610 616 for (int i = 0; i < limit; ++i) … … 629 635 if (mesh) // copy the mesh data to polygons 630 636 { 631 mBox.Include(object->GetBox()); // add to BSP tree aabb 637 if (addToBbox) 638 { 639 mBox.Include(object->GetBox()); // add to BSP tree aabb 640 } 641 632 642 AddMeshToPolygons(mesh, polys, mRootCell); 633 643 } … … 636 646 return (int)polys.size(); 637 647 } 648 638 649 639 650 void BspTree::Construct(const ViewCellContainer &viewCells) … … 668 679 } 669 680 670 void BspTree::Construct(const RayContainer &sampleRays) 681 682 void BspTree::Construct(const RayContainer &sampleRays, 683 AxisAlignedBox3 *forcedBoundingBox) 671 684 { 672 685 mStat.nodes = 1; 673 686 mBox.Initialize(); // initialise BSP tree bounding box 674 687 688 if (forcedBoundingBox) 689 mBox = *forcedBoundingBox; 690 675 691 PolygonContainer *polys = new PolygonContainer(); 676 692 BoundedRayContainer *rays = new BoundedRayContainer(); … … 724 740 725 741 // compute bounding box 726 Polygon3::IncludeInBox(*polys, mBox); 742 if (!forcedBoundingBox) 743 Polygon3::IncludeInBox(*polys, mBox); 727 744 728 745 //-- store rays … … 746 763 } 747 764 748 void BspTree::Construct(const ObjectContainer &objects, const RayContainer &sampleRays) 765 766 void BspTree::Construct(const ObjectContainer &objects, 767 const RayContainer &sampleRays, 768 AxisAlignedBox3 *forcedBoundingBox) 749 769 { 750 770 mStat.nodes = 1; 751 771 mBox.Initialize(); // initialise BSP tree bounding box 752 772 773 if (forcedBoundingBox) 774 mBox = *forcedBoundingBox; 775 753 776 BoundedRayContainer *rays = new BoundedRayContainer(); 754 777 PolygonContainer *polys = new PolygonContainer(); … … 757 780 758 781 // copy mesh instance polygons into one big polygon soup 759 mStat.polys = AddToPolygonSoup(objects, *polys); 782 mStat.polys = AddToPolygonSoup(objects, *polys, 0, !forcedBoundingBox); 783 760 784 761 785 RayContainer::const_iterator rit, rit_end = sampleRays.end(); … … 776 800 } 777 801 802 778 803 void BspTree::Construct(PolygonContainer *polys, BoundedRayContainer *rays) 779 804 { … … 786 811 ConstructGeometry(mRoot, *geom); 787 812 788 BspTraversalData tData(mRoot, polys, 0, mRootCell, rays, 789 ComputePvsSize(*rays), geom->GetArea(), geom); 813 BspTraversalData tData(mRoot, 814 polys, 815 0, 816 mRootCell, 817 rays, 818 ComputePvsSize(*rays), 819 mUseAreaForPvs ? geom->GetArea() : geom->GetVolume(), 820 geom); 790 821 791 822 tStack.push(tData); … … 804 835 805 836 if (r == mRoot) 806 Debug << "BSP tree construction time spent at root: " << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl; 837 Debug << "BSP tree construction time spent at root: " 838 << TimeDiff(startTime, GetTime())*1e-3 << " secs" << endl; 807 839 } 808 840 … … 818 850 ((int)data.mRays->size() <= mTermMinRays) || 819 851 (data.mPvs <= mTermMinPvs) || 820 (data.m Area <= mTermMinArea) ||852 (data.mProbability <= mTermMinProbability) || 821 853 (data.mDepth >= mTermMaxDepth) || 822 (data.GetAvgRayContribution() < mTermMaxRayContribution)); 854 (mStat.Leaves() >= mMaxViewCells) || 855 (data.GetAvgRayContribution() > mTermMaxRayContribution)); 823 856 } 824 857 … … 842 875 viewCell->mLeaf = leaf; 843 876 877 if (mUseAreaForPvs) 878 viewCell->SetArea(tData.mProbability); 879 else 880 viewCell->SetVolume(tData.mProbability); 881 844 882 //-- add pvs 845 883 if (viewCell != mRootCell) … … 880 918 SubdivideNode(tData, tFrontData, tBackData, coincident); 881 919 882 #ifdef _DEBUG883 // if (frontPolys->empty() && backPolys->empty() && (coincident.size() > 2))884 // { for (PolygonContainer::iterator it = coincident.begin(); it != coincident.end(); ++it)885 // Debug << (*it) << " " << (*it)->GetArea() << " " << (*it)->mParent << endl ;886 // Debug << endl;}887 #endif888 920 889 921 // extract view cells from coincident polygons according to plane normal … … 951 983 BspLeaf *leaf = dynamic_cast<BspLeaf *>(tData.mNode); 952 984 953 Debug << "*********************" << endl; 954 long startTime = GetTime(); 985 long startTime; 986 if (0) 987 { 988 Debug << "*********************" << endl; 989 startTime = GetTime(); 990 } 955 991 956 992 // select subdivision plane 957 993 BspInterior *interior = 958 994 new BspInterior(SelectPlane(leaf, tData)); 959 Debug << "time used for split plane selection: " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl; 995 996 if (0) 997 { 998 Debug << "time used for split plane selection: " 999 << TimeDiff(startTime, GetTime()) * 1e-3 << "s" << endl; 1000 } 960 1001 #ifdef _DEBUG 961 1002 Debug << interior << endl; … … 963 1004 964 1005 965 Debug << "number of rays: " << (int)tData.mRays->size() << endl; 966 Debug << "number of polys: " << (int)tData.mPolygons->size() << endl; 967 968 startTime = GetTime(); 1006 if (0) 1007 { 1008 Debug << "number of rays: " << (int)tData.mRays->size() << endl; 1009 Debug << "number of polys: " << (int)tData.mPolygons->size() << endl; 1010 1011 startTime = GetTime(); 1012 } 969 1013 970 1014 // subdivide rays into front and back rays 971 1015 SplitRays(interior->mPlane, *tData.mRays, *frontData.mRays, *backData.mRays); 972 1016 973 Debug << "time used for rays splitting: " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl; 974 975 startTime = GetTime(); 1017 if (0) 1018 { 1019 Debug << "time used for rays splitting: " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl; 1020 startTime = GetTime(); 1021 } 1022 976 1023 // subdivide polygons with plane 977 1024 mStat.polySplits += SplitPolygons(interior->GetPlane(), … … 981 1028 coincident); 982 1029 983 Debug << "time used for polygon splitting: " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl; 1030 if (0) 1031 { 1032 Debug << "time used for polygon splitting: " << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl; 1033 } 984 1034 985 1035 // compute pvs … … 997 1047 998 1048 999 frontData.m Area = frontData.mGeometry->GetArea();1000 backData.m Area = backData.mGeometry->GetArea();1049 frontData.mProbability = frontData.mGeometry->GetVolume(); 1050 backData.mProbability = backData.mGeometry->GetVolume(); 1001 1051 } 1002 1052 … … 1186 1236 1187 1237 const int axis = box.Size().DrivingAxis(); 1188 const Vector3 position = (box.Min()[axis] + box.Max()[axis]) *0.5f;1238 const Vector3 position = (box.Min()[axis] + box.Max()[axis]) * 0.5f; 1189 1239 1190 1240 Vector3 norm(0,0,0); norm[axis] = 1.0f; … … 1196 1246 ((int)data.mRays->size() > mTermMinRaysForAxisAligned) && 1197 1247 ((mTermMinObjectsForAxisAligned < 0) || 1198 1248 (Polygon3::ParentObjectsSize(*data.mPolygons) > mTermMinObjectsForAxisAligned))) 1199 1249 { 1200 1250 Plane3 plane; … … 1329 1379 // assure that no index is taken twice 1330 1380 const int candidateIdx = (int)RandomValue(0, (Real)(-- maxIdx)); 1331 //Debug << "current Idx: " << maxIdx << " cand idx " << candidateIdx << endl; 1332 1381 1333 1382 Polygon3 *poly = (*data.mPolygons)[candidateIdx]; 1334 1383 1335 1384 // swap candidate to the end to avoid testing same plane 1336 1385 std::swap((*data.mPolygons)[maxIdx], (*data.mPolygons)[candidateIdx]); 1337 1338 1386 //Polygon3 *poly = (*data.mPolygons)[(int)RandomValue(0, (int)polys.size() - 1)]; 1339 1387 … … 1517 1565 const BoundedRayContainer &rays, 1518 1566 const int pvs, 1519 const float area,1567 const float probability, 1520 1568 const BspNodeGeometry &cell) const 1521 1569 { … … 1540 1588 GenerateUniqueIdsForPvs(); 1541 1589 1542 if (mUseAreaForPvs) // use front and back cell areas to approximate volume1543 {1544 // construct child geometry with regard to the candidate split plane1545 BspNodeGeometry frontCell; 1546 BspNodeGeometry backCell;1547 1548 cell.SplitGeometry(frontCell,1549 backCell,1550 candidatePlane,1551 mBox, 1552 mEpsilon);1553 1590 // construct child geometry with regard to the candidate split plane 1591 BspNodeGeometry frontCell; 1592 BspNodeGeometry backCell; 1593 1594 cell.SplitGeometry(frontCell, 1595 backCell, 1596 candidatePlane, 1597 mBox, 1598 mEpsilon); 1599 1600 if (mUseAreaForPvs) 1601 { 1554 1602 pFront = frontCell.GetArea(); 1555 1603 pBack = backCell.GetArea(); 1556 1557 pOverall = area; 1558 } 1604 } 1605 else 1606 { 1607 pFront = frontCell.GetVolume(); 1608 pBack = backCell.GetVolume(); 1609 } 1610 1611 1612 pOverall = probability; 1559 1613 } 1560 1614 … … 1611 1665 // add the source object 1612 1666 AddObjToPvs(ray->sourceObject.mObject, cf, frontPvs, backPvs); 1613 1614 if (mUseAreaForPvs)1615 {1616 float len = 1;1617 1618 if (pvsUseLen)1619 len = SqrDistance(entP, extP);1620 1621 // use length of rays to approximate volume1622 if (Ray::BACK && Ray::COINCIDENT)1623 pBack += len;1624 if (Ray::FRONT && Ray::COINCIDENT)1625 pFront += len;1626 if (Ray::FRONT_BACK || Ray::BACK_FRONT)1627 {1628 if (pvsUseLen)1629 {1630 const Vector3 extp = ray->Extrap(maxT);1631 const float t = candidatePlane.FindT(ray->GetLoc(), extp);1632 1633 const float newT = t * maxT;1634 const float newLen = SqrDistance(ray->Extrap(newT), extp);1635 1636 if (Ray::FRONT_BACK)1637 {1638 pFront += len - newLen;1639 pBack += newLen;1640 }1641 else1642 {1643 pBack += len - newLen;1644 pFront += newLen;1645 }1646 }1647 else1648 {1649 ++ pFront;1650 ++ pBack;1651 }1652 }1653 }1654 1667 } 1655 1668 } … … 1760 1773 { 1761 1774 val += SplitPlaneCost(candidatePlane, *data.mRays, data.mPvs, 1762 data.m Area, *data.mGeometry);1775 data.mProbability, *data.mGeometry); 1763 1776 } 1764 1777 … … 1834 1847 ++ mStat.maxRayContribNodes; 1835 1848 1836 if (data.m Geometry->GetArea() <= mTermMinArea)1849 if (data.mProbability <= mTermMinProbability) 1837 1850 ++ mStat.minProbabilityNodes; 1838 1851 … … 1841 1854 << "Depth: " << data.mDepth << " (max: " << mTermMaxDepth << "), " 1842 1855 << "PVS: " << data.mPvs << " (min: " << mTermMinPvs << "), " 1843 << " Area: " << data.mArea << " (min: " << mTermMinArea<< "), "1856 << "Probability: " << data.mProbability << " (min: " << mTermMinProbability << "), " 1844 1857 << "#polygons: " << (int)data.mPolygons->size() << " (max: " << mTermMinPolys << "), " 1845 1858 << "#rays: " << (int)data.mRays->size() << " (max: " << mTermMinRays << "), " … … 2207 2220 } 2208 2221 2209 void BspTree::ConstructGeometry(BspViewCell *vc, BspNodeGeometry &geom) const 2210 { 2211 // TODO 2212 /* vector<BspLeaf *> leaves = vc->mLeaves; 2213 2214 vector<BspLeaf *>::const_iterator it, it_end = leaves.end(); 2222 2223 2224 void BspTree::ConstructGeometry(ViewCell *vc, 2225 BspNodeGeometry &vcGeom) const 2226 { 2227 ViewCellContainer leaves; 2228 mViewCellsManager->GetViewCellsTree()->CollectLeaves(vc, leaves); 2229 2230 ViewCellContainer::const_iterator it, it_end = leaves.end(); 2215 2231 2216 2232 for (it = leaves.begin(); it != it_end; ++ it) 2217 ConstructGeometry(*it, geom);*/ 2233 { 2234 BspLeaf *l = dynamic_cast<BspViewCell *>(*it)->mLeaf; 2235 ConstructGeometry(l, vcGeom); 2236 } 2237 } 2238 2239 2240 void BspTree::SetViewCellsManager(ViewCellsManager *vcm) 2241 { 2242 mViewCellsManager = vcm; 2218 2243 } 2219 2244 … … 2301 2326 2302 2327 2303 int BspTree::FindNeighbors(BspNode *n, vector<BspLeaf *> &neighbors, 2328 typedef pair<BspNode *, BspNodeGeometry *> bspNodePair; 2329 2330 2331 int BspTree::FindNeighbors(BspNode *n, vector<BspLeaf *> &neighbors, 2304 2332 const bool onlyUnmailed) const 2305 2333 { 2306 BspNodeGeometry geom; 2307 ConstructGeometry(n, geom); 2308 2309 stack<BspNode *> nodeStack; 2310 nodeStack.push(mRoot); 2311 2312 // planes needed to verify that we found neighbor leaf. 2334 stack<bspNodePair> nodeStack; 2335 2336 BspNodeGeometry nodeGeom; 2337 ConstructGeometry(n, nodeGeom); 2338 2339 // split planes from the root to this node 2340 // needed to verify that we found neighbor leaf 2341 // TODO: really needed? 2313 2342 vector<Plane3> halfSpaces; 2314 2343 ExtractHalfSpaces(n, halfSpaces); 2315 2344 2316 while (!nodeStack.empty()) 2317 { 2318 BspNode *node = nodeStack.top(); 2345 2346 BspNodeGeometry *rgeom = new BspNodeGeometry(); 2347 ConstructGeometry(mRoot, *rgeom); 2348 2349 nodeStack.push(bspNodePair(mRoot, rgeom)); 2350 2351 while (!nodeStack.empty()) 2352 { 2353 BspNode *node = nodeStack.top().first; 2354 BspNodeGeometry *geom = nodeStack.top().second; 2355 2319 2356 nodeStack.pop(); 2320 2357 2321 2358 if (node->IsLeaf()) 2322 2359 { 2323 if (node != n && (!onlyUnmailed || !node->Mailed())) 2360 // test if this leaf is in valid view space 2361 if (node->TreeValid() && 2362 (node != n) && 2363 (!onlyUnmailed || !node->Mailed())) 2324 2364 { 2325 // test all planes of current node if neighbour2326 // candidate really is neighbour2327 BspNodeGeometry candidateGeom;2328 ConstructGeometry(node, candidateGeom);2329 2330 2365 bool isAdjacent = true; 2331 for (int i = 0; (i < halfSpaces.size()) && isAdjacent; ++ i) 2366 2367 if (1) 2332 2368 { 2333 const int cf = 2334 Polygon3::ClassifyPlane(candidateGeom.mPolys, 2335 halfSpaces[i], 2336 mEpsilon); 2337 2338 if (cf == Polygon3::BACK_SIDE) 2339 isAdjacent = false; 2369 // test all planes of current node if still adjacent 2370 for (int i = 0; (i < halfSpaces.size()) && isAdjacent; ++ i) 2371 { 2372 const int cf = 2373 Polygon3::ClassifyPlane(geom->mPolys, 2374 halfSpaces[i], 2375 mEpsilon); 2376 2377 if (cf == Polygon3::BACK_SIDE) 2378 { 2379 isAdjacent = false; 2380 } 2381 } 2340 2382 } 2341 2383 else 2384 { 2385 // TODO: why is this wrong?? 2386 // test all planes of current node if still adjacent 2387 for (int i = 0; (i < (int)nodeGeom.mPolys.size()) && isAdjacent; ++ i) 2388 { 2389 Polygon3 *poly = nodeGeom.mPolys[i]; 2390 2391 const int cf = 2392 Polygon3::ClassifyPlane(geom->mPolys, 2393 poly->GetSupportingPlane(), 2394 mEpsilon); 2395 2396 if (cf == Polygon3::BACK_SIDE) 2397 { 2398 isAdjacent = false; 2399 } 2400 } 2401 } 2402 // neighbor was found 2342 2403 if (isAdjacent) 2404 { 2343 2405 neighbors.push_back(dynamic_cast<BspLeaf *>(node)); 2406 } 2344 2407 } 2345 2408 } 2346 else 2409 else 2347 2410 { 2348 2411 BspInterior *interior = dynamic_cast<BspInterior *>(node); 2349 2350 const int cf = Polygon3::ClassifyPlane( geom.mPolys,2351 interior-> mPlane,2412 2413 const int cf = Polygon3::ClassifyPlane(nodeGeom.mPolys, 2414 interior->GetPlane(), 2352 2415 mEpsilon); 2353 2416 2417 BspNode *front = interior->GetFront(); 2418 BspNode *back = interior->GetBack(); 2419 2420 BspNodeGeometry *fGeom = new BspNodeGeometry(); 2421 BspNodeGeometry *bGeom = new BspNodeGeometry(); 2422 2423 geom->SplitGeometry(*fGeom, 2424 *bGeom, 2425 interior->GetPlane(), 2426 mBox, 2427 mEpsilon); 2428 2354 2429 if (cf == Polygon3::FRONT_SIDE) 2355 nodeStack.push(interior->GetFront()); 2430 { 2431 nodeStack.push(bspNodePair(interior->GetFront(), fGeom)); 2432 DEL_PTR(bGeom); 2433 } 2356 2434 else 2435 { 2357 2436 if (cf == Polygon3::BACK_SIDE) 2358 nodeStack.push(interior->GetBack());2359 else2360 2437 { 2361 // random decision 2362 nodeStack.push(interior->GetBack()); 2363 nodeStack.push(interior->GetFront()); 2438 nodeStack.push(bspNodePair(interior->GetBack(), bGeom)); 2439 DEL_PTR(fGeom); 2364 2440 } 2365 } 2366 } 2367 2441 else 2442 { // random decision 2443 nodeStack.push(bspNodePair(front, fGeom)); 2444 nodeStack.push(bspNodePair(back, bGeom)); 2445 } 2446 } 2447 } 2448 2449 DEL_PTR(geom); 2450 } 2451 2368 2452 return (int)neighbors.size(); 2369 2453 } … … 2421 2505 } 2422 2506 2507 2423 2508 BspLeaf *BspTree::GetRandomLeaf(const bool onlyUnmailed) 2424 2509 { … … 2455 2540 return NULL; 2456 2541 } 2542 2457 2543 2458 2544 void BspTree::AddToPvs(BspLeaf *leaf, … … 2495 2581 } 2496 2582 2583 2497 2584 int BspTree::ComputePvsSize(const BoundedRayContainer &rays) const 2498 2585 { … … 2528 2615 } 2529 2616 2617 2530 2618 float BspTree::GetEpsilon() const 2531 2619 { … … 2534 2622 2535 2623 2536 /*************************************************************/ 2537 /* BspNodeGeometry Implementation */ 2538 /*************************************************************/ 2624 int BspTree::CollectMergeCandidates(const vector<BspLeaf *> leaves, 2625 vector<MergeCandidate> &candidates) 2626 { 2627 BspLeaf::NewMail(); 2628 2629 vector<BspLeaf *>::const_iterator it, it_end = leaves.end(); 2630 2631 int numCandidates = 0; 2632 2633 // find merge candidates and push them into queue 2634 for (it = leaves.begin(); it != it_end; ++ it) 2635 { 2636 BspLeaf *leaf = *it; 2637 2638 // the same leaves must not be part of two merge candidates 2639 leaf->Mail(); 2640 vector<BspLeaf *> neighbors; 2641 FindNeighbors(leaf, neighbors, true); 2642 2643 vector<BspLeaf *>::const_iterator nit, nit_end = neighbors.end(); 2644 2645 // TODO: test if at least one ray goes from one leaf to the other 2646 for (nit = neighbors.begin(); nit != nit_end; ++ nit) 2647 { 2648 if ((*nit)->GetViewCell() != leaf->GetViewCell()) 2649 { 2650 MergeCandidate mc(leaf->GetViewCell(), (*nit)->GetViewCell()); 2651 candidates.push_back(mc); 2652 2653 ++ numCandidates; 2654 if ((numCandidates % 1000) == 0) 2655 { 2656 cout << "collected " << numCandidates << " merge candidates" << endl; 2657 } 2658 } 2659 } 2660 } 2661 2662 Debug << "merge queue: " << (int)candidates.size() << endl; 2663 Debug << "leaves in queue: " << numCandidates << endl; 2664 2665 2666 return (int)leaves.size(); 2667 } 2668 2669 2670 int BspTree::CollectMergeCandidates(const VssRayContainer &rays, 2671 vector<MergeCandidate> &candidates) 2672 { 2673 ViewCell::NewMail(); 2674 long startTime = GetTime(); 2675 2676 map<BspLeaf *, vector<BspLeaf*> > neighborMap; 2677 ViewCellContainer::const_iterator iit; 2678 2679 int numLeaves = 0; 2680 2681 BspLeaf::NewMail(); 2682 2683 for (int i = 0; i < (int)rays.size(); ++ i) 2684 { 2685 VssRay *ray = rays[i]; 2686 2687 // traverse leaves stored in the rays and compare and 2688 // merge consecutive leaves (i.e., the neighbors in the tree) 2689 if (ray->mViewCells.size() < 2) 2690 continue; 2691 //TODO viewcellhierarchy 2692 iit = ray->mViewCells.begin(); 2693 BspViewCell *bspVc = dynamic_cast<BspViewCell *>(*(iit ++)); 2694 BspLeaf *leaf = bspVc->mLeaf; 2695 2696 // traverse intersections 2697 // consecutive leaves are neighbors => add them to queue 2698 for (; iit != ray->mViewCells.end(); ++ iit) 2699 { 2700 // next pair 2701 BspLeaf *prevLeaf = leaf; 2702 bspVc = dynamic_cast<BspViewCell *>(*iit); 2703 leaf = bspVc->mLeaf; 2704 2705 // view space not valid or same view cell 2706 if (!leaf->TreeValid() || !prevLeaf->TreeValid() || 2707 (leaf->GetViewCell() == prevLeaf->GetViewCell())) 2708 continue; 2709 2710 vector<BspLeaf *> &neighbors = neighborMap[leaf]; 2711 2712 bool found = false; 2713 2714 // both leaves inserted in queue already => 2715 // look if double pair already exists 2716 if (leaf->Mailed() && prevLeaf->Mailed()) 2717 { 2718 vector<BspLeaf *>::const_iterator it, it_end = neighbors.end(); 2719 2720 for (it = neighbors.begin(); !found && (it != it_end); ++ it) 2721 if (*it == prevLeaf) 2722 found = true; // already in queue 2723 } 2724 2725 if (!found) 2726 { 2727 // this pair is not in map yet 2728 // => insert into the neighbor map and the queue 2729 neighbors.push_back(prevLeaf); 2730 neighborMap[prevLeaf].push_back(leaf); 2731 2732 leaf->Mail(); 2733 prevLeaf->Mail(); 2734 2735 MergeCandidate mc(leaf->GetViewCell(), prevLeaf->GetViewCell()); 2736 2737 candidates.push_back(mc); 2738 2739 if (((int)candidates.size() % 1000) == 0) 2740 { 2741 cout << "collected " << (int)candidates.size() << " merge candidates" << endl; 2742 } 2743 } 2744 } 2745 } 2746 2747 Debug << "neighbormap size: " << (int)neighborMap.size() << endl; 2748 Debug << "merge queue: " << (int)candidates.size() << endl; 2749 Debug << "leaves in queue: " << numLeaves << endl; 2750 2751 2752 //-- collect the leaves which haven't been found by ray casting 2753 #if 0 2754 cout << "finding additional merge candidates using geometry" << endl; 2755 vector<BspLeaf *> leaves; 2756 CollectLeaves(leaves, true); 2757 Debug << "found " << (int)leaves.size() << " new leaves" << endl << endl; 2758 CollectMergeCandidates(leaves, candidates); 2759 #endif 2760 2761 return numLeaves; 2762 } 2763 2764 2765 2766 2767 /***************************************************************/ 2768 /* BspNodeGeometry Implementation */ 2769 /***************************************************************/ 2539 2770 2540 2771 … … 2574 2805 2575 2806 // note: can take arbitrary point, e.g., the origin. However, 2576 // center of massprevents precision errors2807 // we rather take the center of mass to prevents precision errors 2577 2808 const Vector3 center = CenterOfMass(); 2578 2809 … … 2701 2932 front.mPolys.push_back(planePoly->CreateReversePolygon()); 2702 2933 } 2703 2704 //Debug << "returning new geometry " << mPolys.size() << " f: " << front.mPolys.size() << " b: " << back.mPolys.size() << endl;2705 //Debug << "old area " << GetArea() << " f: " << front.GetArea() << " b: " << back.GetArea() << endl;2706 2934 } 2707 2935
Note: See TracChangeset
for help on using the changeset viewer.