Changeset 542 for trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp
- Timestamp:
- 01/16/06 03:23:29 (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/VUT/GtpVisibilityPreprocessor/src/VspBspTree.cpp
r538 r542 278 278 279 279 int numObj = 0; 280 280 281 //-- extract polygons intersected by the rays 281 282 for (rit = sampleRays.begin(); rit != rit_end; ++ rit) … … 313 314 mMaxPvs = (int)(mMaxPvsRatio * (float)numObj); 314 315 315 Debug << "maximal pvs (i.e., view cell considered as valid: " << mMaxPvs << endl;316 Debug << "maximal pvs (i.e., pvs still considered as valid) : " << mMaxPvs << endl; 316 317 //-- store rays 317 318 for (rit = sampleRays.begin(); rit != rit_end; ++ rit) … … 382 383 383 384 mStat.Start(); 384 cout << "Contructing vsp bsp tree ... "; 385 386 long startTime = GetTime(); 387 388 bool mOutOfMemory = false; 385 cout << "Contructing vsp bsp tree ... \n"; 386 387 long startTime = GetTime(); 388 long interTime = GetTime(); 389 mOutOfMemory = false; 390 391 int nleaves = 500; 389 392 390 393 while (!tStack.empty()) … … 404 407 } 405 408 406 // subdivide leaf node409 // subdivide leaf node 407 410 BspNode *r = Subdivide(tStack, tData); 408 411 409 412 if (r == mRoot) 410 413 Debug << "VSP BSP tree construction time spent at root: " 411 << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl << endl; 412 } 413 414 Debug << "Used Memory: " << GetMemUsage() << " MB" << endl; 414 << TimeDiff(startTime, GetTime())*1e-3 << "s" << endl; 415 416 if (mStat.Leaves() >= nleaves) 417 { 418 nleaves += 500; 419 420 cout << "leaves=" << mStat.Leaves() << endl; 421 Debug << "needed " 422 << TimeDiff(interTime, GetTime())*1e-3 << " secs to create 500 leaves" << endl; 423 interTime = GetTime(); 424 } 425 } 426 427 Debug << "Used Memory: " << GetMemUsage() << " MB" << endl << endl; 415 428 cout << "finished\n"; 416 429 … … 436 449 BspNode *newNode = tData.mNode; 437 450 438 if (!mOutOfMemory ||!TerminationCriteriaMet(tData))451 if (!mOutOfMemory && !TerminationCriteriaMet(tData)) 439 452 { 440 453 PolygonContainer coincident; … … 508 521 509 522 523 524 510 525 BspNode *VspBspTree::SubdivideNode(VspBspTraversalData &tData, 511 526 VspBspTraversalData &frontData, … … 517 532 // select subdivision plane 518 533 Plane3 splitPlane; 534 519 535 int maxCostMisses = tData.mMaxCostMisses; 520 bool success = SelectPlane(splitPlane, 521 leaf, 522 tData, 523 frontData, 524 backData); 536 537 const bool success = 538 SelectPlane(splitPlane, leaf, tData, frontData, backData); 539 525 540 if (!success) 526 541 { … … 578 593 if (mPvsUseArea) 579 594 { 580 // if not already computed595 // if geometry was not already computed 581 596 if (!frontData.mGeometry && !backData.mGeometry) 582 597 { … … 820 835 BspNodeGeometry **backGeom, 821 836 float &frontArea, 822 float &backArea) 837 float &backArea, 838 bool useKdSplit) 823 839 { 824 840 const bool useCostHeuristics = false; … … 838 854 AxisAlignedBox3 box; 839 855 box.Initialize(); 840 856 //TODO: for kd split geometry already is box 841 857 if (1 && mPvsUseArea) 842 858 { … … 868 884 Vector3 normal(0,0,0); normal[axis] = 1; 869 885 870 nCostRatio[axis] = SplitPlaneCost(Plane3(normal, nPosition[axis]), 871 tData, *nFrontGeom[axis], *nBackGeom[axis], 872 nFrontArea[axis], nBackArea[axis]); 886 if (useKdSplit) 887 { 888 nCostRatio[axis] = EvalAxisAlignedSplitCost(tData, 889 box, 890 axis, 891 nPosition[axis]); 892 893 Vector3 pos = box.Max(); pos[axis] = nPosition[axis]; 894 AxisAlignedBox3 frontBox(box.Min(), pos); 895 frontBox.ExtractPolys(nFrontGeom[axis]->mPolys); 896 897 pos = box.Min(); pos[axis] = nPosition[axis]; 898 AxisAlignedBox3 backBox(pos, box.Max()); 899 backBox.ExtractPolys(nBackGeom[axis]->mPolys); 900 901 } 902 else 903 { 904 nCostRatio[axis] = SplitPlaneCost(Plane3(normal, nPosition[axis]), 905 tData, *nFrontGeom[axis], *nBackGeom[axis], 906 nFrontArea[axis], nBackArea[axis]); 907 } 873 908 } 874 909 else … … 903 938 *frontGeom = nFrontGeom[bestAxis]; 904 939 *backGeom = nBackGeom[bestAxis]; 940 905 941 // and delete other geometry 906 942 delete nFrontGeom[(bestAxis + 1) % 3]; … … 913 949 return nCostRatio[bestAxis]; 914 950 } 951 952 953 float VspBspTree::EvalAxisAlignedSplitCost(const VspBspTraversalData &data, 954 const AxisAlignedBox3 &box, 955 const int axis, 956 const float &position) const 957 { 958 int pvsFront = 0; 959 int pvsBack = 0; 960 int pvsTotal = 0; 961 962 // create unique ids for pvs heuristics 963 GenerateUniqueIdsForPvs(); 964 965 const int pvsSize = data.mPvs; 966 967 // this is the main ray classification loop! 968 for(RayInfoContainer::iterator ri = data.mRays->begin(); 969 ri != data.mRays->end(); ++ ri) 970 { 971 if (!(*ri).mRay->IsActive()) 972 continue; 973 974 // determine the side of this ray with respect to the plane 975 float t; 976 int side = (*ri).ComputeRayIntersection(axis, position, t); 977 978 AddObjToPvs((*ri).mRay->mTerminationObject, side, pvsFront, pvsBack, pvsTotal); 979 AddObjToPvs((*ri).mRay->mOriginObject, side, pvsFront, pvsBack, pvsTotal); 980 } 981 982 //-- only one of these options should be one 983 //-- pvs + probability heuristics 984 float pBack, pFront, pOverall; 985 986 if (1) 987 { 988 // box length substitute for probability 989 const float minBox = box.Min(axis); 990 const float maxBox = box.Max(axis); 991 992 pBack = position - minBox; 993 pFront = maxBox - position; 994 pOverall = maxBox - minBox; 995 } 996 else //-- area substitute for probability 997 { 998 pOverall = box.SurfaceArea(); 999 1000 const bool useMidSplit = true; 1001 //const bool useMidSplit = false; 1002 1003 //-- simplified computation for mid split 1004 const int axis2 = (axis + 1) % 3; 1005 const int axis3 = (axis + 2) % 3; 1006 1007 const float faceArea = 1008 (box.Max(axis2) - box.Min(axis2)) * 1009 (box.Max(axis3) - box.Min(axis3)); 1010 1011 pBack = pFront = pOverall * 0.5f + faceArea; 1012 } 1013 1014 //Debug << axis << " " << pvsSize << " " << pvsBack << " " << pvsFront << endl; 1015 //Debug << pFront << " " << pBack << " " << pOverall << endl; 1016 1017 // float sum = raysBack*(position - minBox) + raysFront*(maxBox - position); 1018 const float newCost = pvsBack * pBack + pvsFront * pFront; 1019 // float oldCost = leaf->mRays.size(); 1020 const float oldCost = (float)pvsSize * pOverall; 1021 1022 return (mCtDivCi + newCost) / oldCost; 1023 } 1024 915 1025 916 1026 … … 984 1094 candidateCost = SelectAxisAlignedPlane(plane, data, axis, 985 1095 &fGeom, &bGeom, 986 fArea, bArea); 1096 fArea, bArea, 1097 onlyAxisAligned); 987 1098 988 1099 if (candidateCost < lowestCost) … … 991 1102 lowestCost = candidateCost; 992 1103 993 //-- assign already computed values 1104 // assign already computed values 1105 // we can do this because we always save the 1106 // computed values from the axis aligned splits 994 1107 frontData.mGeometry = fGeom; 995 1108 backData.mGeometry = bGeom; … … 1123 1236 int totalPvs = 0; 1124 1237 1238 int limit; 1239 bool useRand; 1240 1241 // choose test rays randomly if too much 1242 if ((int)data.mRays->size() > mMaxTests) 1243 { 1244 useRand = true; 1245 limit = mMaxTests; 1246 } 1247 else 1248 { 1249 useRand = false; 1250 limit = (int)data.mRays->size(); 1251 } 1252 1253 for (int i = 0; i < limit; ++ i) 1254 { 1255 const int testIdx = useRand ? 1256 (int)RandomValue(0, (Real)((int)data.mRays->size() - 1)) : i; 1257 RayInfo rayInf = (*data.mRays)[testIdx]; 1258 1259 float t; 1260 VssRay *ray = rayInf.mRay; 1261 const int cf = rayInf.ComputeRayIntersection(candidatePlane, t); 1262 1263 if (cf >= 0) 1264 ++ raysFront; 1265 if (cf <= 0) 1266 ++ raysBack; 1267 1268 if (mSplitPlaneStrategy & LEAST_RAY_SPLITS) 1269 { 1270 sumBalancedRays += cf; 1271 } 1272 1273 if (mSplitPlaneStrategy & BALANCED_RAYS) 1274 { 1275 if (cf == 0) 1276 ++ sumRaySplits; 1277 } 1278 1279 if (mSplitPlaneStrategy & PVS) 1280 { 1281 // find front and back pvs for origing and termination object 1282 AddObjToPvs(ray->mTerminationObject, cf, pvsFront, pvsBack, totalPvs); 1283 AddObjToPvs(ray->mOriginObject, cf, pvsFront, pvsBack, totalPvs); 1284 } 1285 } 1286 1287 const float raysSize = (float)data.mRays->size() + Limits::Small; 1125 1288 if (mSplitPlaneStrategy & PVS) 1126 1289 { … … 1136 1299 mBox, 1137 1300 mEpsilon); 1138 1301 #if 0 1302 AxisAlignedBox3 fbox; 1303 AxisAlignedBox3 bbox; 1304 AxisAlignedBox3 box; 1305 fbox.Initialize(); 1306 bbox.Initialize(); 1307 box.Initialize(); 1308 1309 geomFront.IncludeInBox(fbox); 1310 geomBack.IncludeInBox(bbox); 1311 data.mGeometry->IncludeInBox(box); 1312 1313 areaFront = fbox.GetVolume(); 1314 areaBack = bbox.GetVolume(); 1315 1316 pOverall = box.GetVolume(); 1317 #else 1139 1318 areaFront = geomFront.GetArea(); 1140 1319 areaBack = geomBack.GetArea(); 1141 1320 1321 pOverall = data.mArea; 1322 #endif 1142 1323 pBack = areaBack; 1143 1324 pFront = areaFront; 1144 pOverall = data.mArea;1145 1325 } 1146 1326 else // use number of rays to approximate volume … … 1152 1332 } 1153 1333 1154 int limit;1155 bool useRand;1156 1157 // choose test rays randomly if too much1158 if ((int)data.mRays->size() > mMaxTests)1159 {1160 useRand = true;1161 limit = mMaxTests;1162 }1163 else1164 {1165 useRand = false;1166 limit = (int)data.mRays->size();1167 }1168 1169 for (int i = 0; i < limit; ++ i)1170 {1171 const int testIdx = useRand ?1172 (int)RandomValue(0, (Real)((int)data.mRays->size() - 1)) : i;1173 RayInfo rayInf = (*data.mRays)[testIdx];1174 1175 float t;1176 VssRay *ray = rayInf.mRay;1177 const int cf = rayInf.ComputeRayIntersection(candidatePlane, t);1178 1179 if (cf >= 0)1180 ++ raysFront;1181 if (cf <= 0)1182 ++ raysBack;1183 1184 if (mSplitPlaneStrategy & LEAST_RAY_SPLITS)1185 {1186 sumBalancedRays += cf;1187 }1188 1189 if (mSplitPlaneStrategy & BALANCED_RAYS)1190 {1191 if (cf == 0)1192 ++ sumRaySplits;1193 }1194 1195 if (mSplitPlaneStrategy & PVS)1196 {1197 // find front and back pvs for origing and termination object1198 AddObjToPvs(ray->mTerminationObject, cf, pvsFront, pvsBack, totalPvs);1199 AddObjToPvs(ray->mOriginObject, cf, pvsFront, pvsBack, totalPvs);1200 }1201 }1202 1203 const float raysSize = (float)data.mRays->size() + Limits::Small;1204 1334 1205 1335 if (mSplitPlaneStrategy & LEAST_RAY_SPLITS) … … 1473 1603 } 1474 1604 1605 1606 1607 void VspBspTree::CheckValidy() 1608 { 1609 stack<BspNode *> nodeStack; 1610 1611 if (!mRoot) 1612 return; 1613 1614 nodeStack.push(mRoot); 1615 1616 while (!nodeStack.empty()) 1617 { 1618 BspNode *node = nodeStack.top(); 1619 nodeStack.pop(); 1620 1621 if (node->IsLeaf()) 1622 { 1623 BspLeaf *leaf = dynamic_cast<BspLeaf *>(node); 1624 1625 if (node->TreeValid()) 1626 { 1627 BspViewCell *viewCell = dynamic_cast<BspLeaf *>(node)->GetViewCell(); 1628 1629 if (viewCell->GetPvs().GetSize() > mMaxPvs) 1630 { 1631 while (!viewCell->mLeaves.empty()) 1632 { 1633 BspLeaf *l = viewCell->mLeaves.back(); 1634 l->SetTreeValid(false); 1635 PropagateUpValidity(l); 1636 1637 l->SetViewCell(GetOrCreateOutOfBoundsCell()); 1638 viewCell->mLeaves.pop_back(); 1639 } 1640 1641 mOutOfBoundsCell->GetPvs().AddPvs(viewCell->GetPvs()); 1642 1643 DEL_PTR(viewCell); 1644 } 1645 } 1646 } 1647 else 1648 { 1649 BspInterior *interior = dynamic_cast<BspInterior *>(node); 1650 1651 nodeStack.push(interior->GetFront()); 1652 nodeStack.push(interior->GetBack()); 1653 } 1654 } 1655 } 1475 1656 1476 1657 void VspBspTree::CollectViewCells(BspNode *root, … … 2438 2619 2439 2620 //-- collect the leaves which haven't been found by ray casting 2440 vector<BspLeaf *> leaves; 2441 CollectLeaves(leaves, true, mMaxPvs); 2442 Debug << "found " << (int)leaves.size() << " new leaves" << endl << endl; 2443 // TODO 2444 CollectMergeCandidates(leaves); 2621 if (0) 2622 { 2623 vector<BspLeaf *> leaves; 2624 CollectLeaves(leaves, true, mMaxPvs); 2625 Debug << "found " << (int)leaves.size() << " new leaves" << endl << endl; 2626 CollectMergeCandidates(leaves); 2627 } 2445 2628 2446 2629 return numLeaves; … … 2519 2702 mMergeMaxCostRatio * BspMergeCandidate::sOverallCost)) 2520 2703 { 2521 / /Debug << "abs mergecost: " << mMergeQueue.top().GetMergeCost() << " rel mergecost: "2522 //<< mMergeQueue.top().GetMergeCost() / BspMergeCandidate::sOverallCost2523 // << " max ratio: " << mMergeMaxCostRatio << endl;2704 /*Debug << "abs mergecost: " << mMergeQueue.top().GetMergeCost() << " rel mergecost: " 2705 << mMergeQueue.top().GetMergeCost() / BspMergeCandidate::sOverallCost 2706 << " max ratio: " << mMergeMaxCostRatio << endl;*/ 2524 2707 BspMergeCandidate mc = mMergeQueue.top(); 2525 2708 mMergeQueue.pop(); … … 2532 2715 { 2533 2716 ViewCell::NewMail(); 2717 2534 2718 MergeViewCells(mc.GetLeaf1(), mc.GetLeaf2()); 2535 2719 -- nViewCells; … … 2709 2893 2710 2894 leaf->SetViewCell(vc2); // finally change view cell 2711 2712 //Debug << "new pvs: " << vc1->GetPvs().GetSize() + vc2->GetPvs().GetSize()2713 // << " (" << vc1->GetPvs().GetSize() << ", " << vc2->GetPvs().GetSize() << ")" << endl;2714 2715 2895 } 2716 2896 … … 2741 2921 if (shuffledCost1 < shuffledCost2) 2742 2922 { 2743 //Debug << "old cost: " << oldCost << ", new cost: " << shuffledCost1 << endl;2744 2923 ShuffleLeaf(leaf1, vc1, vc2); 2745 2924 leaf1->Mail(); … … 2747 2926 else 2748 2927 { 2749 //Debug << "old cost: " << oldCost << ", new cost: " << shuffledCost2 << endl;2750 2928 ShuffleLeaf(leaf2, vc2, vc1); 2751 2929 leaf2->Mail(); … … 2879 3057 2880 3058 //-- compute ratio of old cost 2881 // -- (added size of left and right view cell times pvs size)2882 // -- to new rendering cost (size of merged view cell times pvs size)3059 // (i.e., added size of left and right view cell times pvs size) 3060 // to new rendering cost (i.e, size of merged view cell times pvs size) 2883 3061 const float oldCost = GetLeaf1Cost() + GetLeaf2Cost(); 2884 3062 … … 2886 3064 (float)newPvs * (vc1->GetArea() + vc2->GetArea()); 2887 3065 2888 mMergeCost = newCost - oldCost;2889 3066 if (newPvs > sMaxPvsSize) // strong penalty if pvs size too large 2890 mMergeCost += 1.0; 2891 } 3067 { 3068 mMergeCost = 1e15f; 3069 } 3070 else 3071 { 3072 mMergeCost = newCost - oldCost; 3073 } 3074 } 3075 2892 3076 2893 3077 void BspMergeCandidate::SetLeaf1(BspLeaf *l) … … 2896 3080 } 2897 3081 3082 2898 3083 void BspMergeCandidate::SetLeaf2(BspLeaf *l) 2899 3084 { … … 2901 3086 } 2902 3087 3088 2903 3089 BspLeaf *BspMergeCandidate::GetLeaf1() 2904 3090 { … … 2906 3092 } 2907 3093 3094 2908 3095 BspLeaf *BspMergeCandidate::GetLeaf2() 2909 3096 { 2910 3097 return mLeaf2; 2911 3098 } 3099 2912 3100 2913 3101 bool BspMergeCandidate::Valid() const … … 2918 3106 } 2919 3107 3108 2920 3109 float BspMergeCandidate::GetMergeCost() const 2921 3110 { 2922 3111 return mMergeCost; 2923 3112 } 3113 2924 3114 2925 3115 void BspMergeCandidate::SetValid()
Note: See TracChangeset
for help on using the changeset viewer.