Changeset 1291 for GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp
- Timestamp:
- 08/28/06 18:42:33 (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp
r1290 r1291 730 730 731 731 // compute locally best split plane 732 const float ratio = SelectSplitPlane( 733 splitCandidate.mParentData, 734 splitCandidate.mSplitPlane, 735 frontProb, 736 backProb); 732 const float ratio = SelectSplitPlane(splitCandidate.mParentData, 733 splitCandidate.mSplitPlane, 734 frontProb, 735 backProb); 737 736 738 737 const bool success = ratio < mTermMaxCostRatio; 739 738 739 // max cost threshold violated? 740 splitCandidate.mMaxCostMisses = 741 success ? splitCandidate.mParentData.mMaxCostMisses : splitCandidate.mParentData.mMaxCostMisses + 1; 742 740 743 float oldRenderCost; 741 744 … … 758 761 759 762 splitCandidate.SetPriority(priority); 760 761 // max cost threshold violated?762 splitCandidate.mMaxCostMisses =763 success ? splitCandidate.mParentData.mMaxCostMisses : splitCandidate.mParentData.mMaxCostMisses + 1;764 //Debug << "p: " << tData.mNode << " depth: " << tData.mDepth << endl;765 763 } 766 764 … … 907 905 } 908 906 } 909 910 911 907 912 908 … … 992 988 mLocalSubdivisionCandidates->reserve(requestedSize); 993 989 994 995 990 float pos; 996 997 991 RayInfoContainer::const_iterator rit, rit_end = rays.end(); 998 992 … … 1017 1011 1018 1012 1019 int VspTree::GetPvsContribution(Intersectable *object) const1020 {1021 int pvsContri = 0;1022 1023 KdPvsMap::const_iterator kit, kit_end = object->mKdPvs.mEntries.end();1024 1025 Intersectable::NewMail();1026 1027 // Search kd leaves this object is attached to1028 for (kit = object->mKdPvs.mEntries.begin(); kit != kit_end; ++ kit)1029 {1030 KdNode *l = (*kit).first;1031 1032 // new object found during sweep1033 // => increase pvs contribution of this kd node1034 if (!l->Mailed())1035 {1036 l->Mail();1037 ++ pvsContri;1038 }1039 }1040 1041 return pvsContri;1042 }1043 1044 1045 int VspTree::PrepareHeuristics(const VssRay &ray, const bool isTermination)1046 {1047 int pvsSize = 0;1048 1049 Intersectable *obj;1050 Vector3 pt;1051 KdNode *node;1052 1053 ray.GetSampleData(isTermination, pt, &obj, &node);1054 1055 if (!obj)1056 return 0;1057 1058 switch (mHierarchyManager->GetObjectSpaceSubdivisonType())1059 {1060 case HierarchyManager::NO_OBJ_SUBDIV:1061 {1062 if (!obj->Mailed())1063 {1064 obj->Mail();1065 obj->mCounter = 1;1066 1067 ++ pvsSize;1068 }1069 else1070 {1071 ++ obj->mCounter;1072 }1073 break;1074 }1075 case HierarchyManager::KD_BASED_OBJ_SUBDIV:1076 {1077 KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(pt, node);1078 pvsSize += PrepareHeuristics(leaf);1079 break;1080 }1081 case HierarchyManager::BV_BASED_OBJ_SUBDIV:1082 {1083 BvhLeaf *leaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj);1084 1085 if (!leaf->Mailed())1086 {1087 leaf->Mail();1088 leaf->mCounter = 1;1089 1090 pvsSize += (int)leaf->mObjects.size();1091 }1092 else1093 {1094 ++ leaf->mCounter;1095 }1096 break;1097 }1098 default:1099 break;1100 }1101 1102 return pvsSize;1103 }1104 1105 1106 1013 int VspTree::PrepareHeuristics(KdLeaf *leaf) 1107 1014 { … … 1112 1019 leaf->Mail(); 1113 1020 leaf->mCounter = 1; 1114 1115 1021 // add objects without the objects which are in several kd leaves 1116 1022 pvsSize += (int)(leaf->mObjects.size() - leaf->mMultipleObjects.size()); 1117 //Debug << "adding " << (int)leaf->mObjects.size() << " " << leaf->mMultipleObjects.size() << endl;1118 1023 } 1119 1024 else … … 1123 1028 1124 1029 //-- the objects belonging to several leaves must be handled seperately 1125 1126 1030 ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end(); 1127 1031 … … 1151 1055 Intersectable::NewMail(); 1152 1056 KdNode::NewMail(); 1057 BvhNode::NewMail(); 1153 1058 1154 1059 int pvsSize = 0; … … 1226 1131 1227 1132 1228 int VspTree::EvalMinEventContribution(const VssRay &ray, 1229 const bool isTermination) const 1230 { 1231 Intersectable *obj; 1232 Vector3 pt; 1233 KdNode *node; 1234 1235 ray.GetSampleData(isTermination, pt, &obj, &node); 1236 1237 if (!obj) return 0; 1238 1239 int pvs = 0; 1240 1241 switch (mHierarchyManager->GetObjectSpaceSubdivisonType()) 1242 { 1243 case HierarchyManager::NO_OBJ_SUBDIV: 1244 { 1245 if (!obj->Mailed()) 1246 { 1247 obj->Mail(); 1248 ++ pvs; 1249 } 1250 1251 break; 1252 } 1253 case HierarchyManager::KD_BASED_OBJ_SUBDIV: 1254 { 1255 KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(pt, node); 1256 // add contributions of the kd nodes 1257 pvs += EvalMinEventContribution(leaf); 1258 1259 break; 1260 } 1261 case HierarchyManager::BV_BASED_OBJ_SUBDIV: 1262 { 1263 BvhLeaf *leaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj); 1264 1265 if (!leaf->Mailed()) 1266 { 1267 leaf->Mail(); 1268 pvs += (int)leaf->mObjects.size(); 1269 } 1270 break; 1271 } 1272 default: 1273 break; 1274 } 1275 return pvs; 1276 } 1277 1278 1279 int VspTree::EvalMaxEventContribution(const VssRay &ray, 1280 const bool isTermination) const 1281 { 1282 Intersectable *obj; 1283 Vector3 pt; 1284 KdNode *node; 1285 1286 ray.GetSampleData(isTermination, pt, &obj, &node); 1287 1288 if (!obj) return 0; 1289 1290 int pvs = 0; 1291 1292 switch (mHierarchyManager->GetObjectSpaceSubdivisonType()) 1293 { 1294 case HierarchyManager::NO_OBJ_SUBDIV: 1295 { 1296 if (-- obj->mCounter == 0) 1297 ++ pvs; 1298 break; 1299 } 1300 case HierarchyManager::KD_BASED_OBJ_SUBDIV: 1301 { 1302 KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(pt, node); 1303 1304 // add contributions of the kd nodes 1305 pvs += EvalMaxEventContribution(leaf); 1306 break; 1307 } 1308 case HierarchyManager::BV_BASED_OBJ_SUBDIV: 1309 { 1310 BvhLeaf *leaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj); 1311 1312 if (-- leaf->mCounter == 0) 1313 pvs += (int)leaf->mObjects.size(); 1314 break; 1315 } 1316 default: 1317 break; 1318 } 1319 1320 return pvs; 1321 } 1322 1323 1324 void VspTree::EvalHeuristicsContribution(const SortableEntry &ci, 1325 int &pvsLeft, 1326 int &pvsRight) const 1133 void VspTree::EvalHeuristics(const SortableEntry &ci, 1134 int &pvsLeft, 1135 int &pvsRight) const 1327 1136 { 1328 1137 VssRay *ray = ci.ray; 1329 1138 1139 // eval changes in pvs causes by min event 1330 1140 if (ci.type == SortableEntry::ERayMin) 1331 1141 { … … 1333 1143 pvsLeft += EvalMinEventContribution(*ray, false); 1334 1144 } 1335 else 1145 else // eval changes in pvs causes by max event 1336 1146 { 1337 1147 pvsRight -= EvalMaxEventContribution(*ray, true); … … 1358 1168 } 1359 1169 1360 int pvsSize = tData.mPvs;1361 1362 1170 const float minBox = box.Min(axis); 1363 1171 const float maxBox = box.Max(axis); … … 1371 1179 1372 1180 // prepare the sweep 1373 // (note: returns pvs size, so there would be no need 1374 // to give pvs size as argument) 1375 pvsSize = PrepareHeuristics(usedRays); 1181 // note: returns pvs size => no need t give pvs size as function parameter 1182 const int pvsSize = PrepareHeuristics(usedRays); 1376 1183 1377 1184 // go through the lists, count the number of objects left and right … … 1398 1205 Intersectable::NewMail(); 1399 1206 KdLeaf::NewMail(); 1400 1207 BvhLeaf::NewMail(); 1401 1208 1402 1209 //-- traverse through visibility events … … 1406 1213 for (ci = mLocalSubdivisionCandidates->begin(); ci != ci_end; ++ ci) 1407 1214 { 1408 EvalHeuristicsContribution(*ci, pvsl, pvsr); 1215 // compute changes to front and back pvs 1216 EvalHeuristics(*ci, pvsl, pvsr); 1409 1217 1410 1218 // Note: sufficient to compare size of bounding boxes of front and back side? 1411 1219 if (((*ci).value >= minBand) && ((*ci).value <= maxBand)) 1412 1220 { 1413 1414 1221 float currentPos; 1415 1222 … … 1421 1228 1422 1229 sum = pvsl * ((*ci).value - minBox) + pvsr * (maxBox - (*ci).value); 1423 //Debug << "pos=" << (*ci).value << "\t newpos=" << currentPos << "\t pvs=(" << pvsl << "," << pvsr << ")" << "\t cost= " << sum << endl;1230 1424 1231 1425 1232 if (sum < minSum) … … 1460 1267 const float volRatio = tData.mBoundingBox.GetVolume() / (sizeBox * mBoundingBox.GetVolume()); 1461 1268 1462 /* 1463 //if (axis != 1) 1464 //Debug << "axis=" << axis << " costRatio=" << ratio << " pos=" << position << " t=" << (position - minBox) / (maxBox - minBox) 1465 // <<"\t pb=(" << pvsBack << ")\t pf=(" << pvsFront << ")" << endl; 1466 1467 Debug << "\n§§§§ eval local cost §§§§" << endl 1269 Debug << "\n§§§§ eval local cost §§§§" << endl 1468 1270 << "back pvs: " << penaltyBack << " front pvs: " << penaltyFront << " total pvs: " << penaltyOld << endl 1469 1271 << "back p: " << pBack * volRatio << " front p " << pFront * volRatio << " p: " << pOverall * volRatio << endl 1470 1272 << "old rc: " << oldRenderCost * volRatio << " new rc: " << newRenderCost * volRatio << endl 1471 1273 << "render cost decrease: " << oldRenderCost * volRatio - newRenderCost * volRatio << endl; 1472 */ 1274 1473 1275 return ratio; 1474 1276 } … … 1494 1296 const bool useSpecialAxis = 1495 1297 mOnlyDrivingAxis || mCirculatingAxis; 1496 //Debug << "data: " << tData.mBoundingBox << " pvs " << tData.mPvs << endl;1298 1497 1299 if (mCirculatingAxis) 1498 1300 { … … 1546 1348 } 1547 1349 1548 1549 1350 //-- assign values of best split 1550 1551 1351 plane.mAxis = bestAxis; 1552 1352 plane.mPosition = nPosition[bestAxis]; // split plane position … … 1555 1355 pBack = nProbBack[bestAxis]; 1556 1356 1557 //Debug << "val: " << nCostRatio[bestAxis] << " axis: " << bestAxis << endl;1558 1357 return nCostRatio[bestAxis]; 1559 1358 } … … 1578 1377 Intersectable::NewMail(3); 1579 1378 KdLeaf::NewMail(3); 1379 BvhLeaf::NewMail(3); 1580 1380 1581 1381 RayInfoContainer::const_iterator rit, rit_end = data.mRays->end(); … … 1588 1388 VssRay *ray = rayInf.mRay; 1589 1389 1390 // classify ray 1590 1391 const int cf = 1591 1392 rayInf.ComputeRayIntersection(candidatePlane.mAxis, 1592 1393 candidatePlane.mPosition, t); 1593 1394 1594 switch (mHierarchyManager->GetObjectSpaceSubdivisonType()) 1595 { 1596 case HierarchyManager::NO_OBJ_SUBDIV: 1597 { 1598 // find front and back pvs for origing and termination object 1599 UpdateObjPvsContri(ray->mTerminationObject, cf, pvsFront, pvsBack, totalPvs); 1600 UpdateObjPvsContri(ray->mOriginObject, cf, pvsFront, pvsBack, totalPvs); 1601 1602 break; 1603 } 1604 case HierarchyManager::KD_BASED_OBJ_SUBDIV: 1605 { 1606 break; 1607 } 1608 case HierarchyManager::BV_BASED_OBJ_SUBDIV: 1609 { 1610 BvhLeaf *tLeaf = mHierarchyManager->mBvHierarchy->GetLeaf(ray->mTerminationObject); 1611 BvhLeaf *oLeaf = mHierarchyManager->mBvHierarchy->GetLeaf(ray->mOriginObject); 1612 1613 UpdateBvhLeafPvsContri(tLeaf, cf, pvsFront, pvsBack, totalPvs); 1614 UpdateBvhLeafPvsContri(oLeaf, cf, pvsFront, pvsBack, totalPvs); 1615 1616 break; 1617 } 1618 default: 1619 break; 1620 } 1621 1622 /* 1623 if (!mUseKdPvsForHeuristics) 1624 { 1625 1626 } 1627 else 1628 { 1629 if (ray->mTerminationObject) 1630 { 1631 KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode); 1632 UpdateKdLeafPvsContri(leaf, cf, pvsFront, pvsBack, totalPvs); 1633 } 1634 1635 if (ray->mOriginObject) 1636 { 1637 KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode); 1638 UpdateKdLeafPvsContri(leaf, cf, pvsFront, pvsBack, totalPvs); 1639 } 1640 } 1641 */ 1395 // evaluate contribution of ray endpoint to front and back pvs 1396 // with respect to the classification 1397 UpdateContributionsToPvs(*ray, true, cf, pvsFront, pvsBack, totalPvs); 1398 UpdateContributionsToPvs(*ray, false, cf, pvsFront, pvsBack, totalPvs); 1642 1399 } 1643 1400 … … 1649 1406 1650 1407 pFront = frontBox.GetVolume(); 1651 pBack = pOverall - pFront; 1652 1408 pBack = pOverall - pFront; 1653 1409 1654 1410 //-- pvs rendering heuristics 1411 1655 1412 const int lowerPvsLimit = mViewCellsManager->GetMinPvsSize(); 1656 1413 const int upperPvsLimit = mViewCellsManager->GetMaxPvsSize(); 1657 1414 1658 1415 //-- only render cost heuristics or combined with standard deviation 1416 1659 1417 const float penaltyOld = EvalPvsPenalty((int)totalPvs, lowerPvsLimit, upperPvsLimit); 1660 1418 const float penaltyFront = EvalPvsPenalty((int)pvsFront, lowerPvsLimit, upperPvsLimit); … … 1667 1425 1668 1426 const float renderCostDecrease = (oldRenderCost - newRenderCost) / viewSpaceVol; 1669 /*1427 1670 1428 Debug << "\n==== eval render cost decrease ===" << endl 1671 1429 << "back pvs: " << pvsBack << " front pvs " << pvsFront << " total pvs: " << totalPvs << endl … … 1673 1431 << "old rc: " << normalizedOldRenderCost << " new rc: " << newRenderCost / viewSpaceVol << endl 1674 1432 << "render cost decrease: " << renderCostDecrease << endl; 1675 */ 1433 1676 1434 return renderCostDecrease; 1677 1435 } 1436 1678 1437 1679 1438 … … 1699 1458 for(rit = data.mRays->begin(); rit != rit_end; ++ rit) 1700 1459 { 1460 VssRay *ray = (*rit).mRay; 1461 1701 1462 // determine the side of this ray with respect to the plane 1702 1463 float t; 1703 1464 const int side = (*rit).ComputeRayIntersection(axis, position, t); 1704 1465 1705 UpdateObjPvsContri((*rit).mRay->mTerminationObject, side, pvsFront, pvsBack, pvsTotal); 1706 UpdateObjPvsContri((*rit).mRay->mOriginObject, side, pvsFront, pvsBack, pvsTotal); 1707 } 1466 UpdateContributionsToPvs(*ray, true, side, pvsFront, pvsBack, pvsTotal); 1467 UpdateContributionsToPvs(*ray, false, side, pvsFront, pvsBack, pvsTotal); 1468 } 1469 1708 1470 1709 1471 //-- evaluate cost heuristics 1710 1472 1711 float pOverall; 1712 1713 pOverall = data.mProbability; 1473 float pOverall = data.mProbability; 1714 1474 1715 1475 // we use spatial mid split => simplified computation … … 1728 1488 1729 1489 1730 void VspTree::Update ObjPvsContri(Intersectable *obj,1731 const int cf,1732 float &frontPvs,1733 float &backPvs,1734 float &totalPvs) const1490 void VspTree::UpdateContributionsToPvs(Intersectable *obj, 1491 const int cf, 1492 float &frontPvs, 1493 float &backPvs, 1494 float &totalPvs) const 1735 1495 { 1736 1496 if (!obj) return; … … 1779 1539 1780 1540 1781 void VspTree::Update BvhLeafPvsContri(BvhLeaf *leaf,1782 const int cf,1783 float &frontPvs,1784 float &backPvs,1785 float &totalPvs) const1541 void VspTree::UpdateContributionsToPvs(BvhLeaf *leaf, 1542 const int cf, 1543 float &frontPvs, 1544 float &backPvs, 1545 float &totalPvs) const 1786 1546 { 1787 1547 if (!leaf) return; 1788 /* 1548 1789 1549 const int renderCost = (int)leaf->mObjects.size(); 1790 1550 … … 1825 1585 leaf->Mail(1); 1826 1586 } 1827 } */1828 } 1829 1830 1831 1832 void VspTree::Update KdLeafPvsContri(KdLeaf *leaf,1833 const int cf,1834 float &frontPvs,1835 float &backPvs,1836 float &totalPvs) const1587 } 1588 } 1589 1590 1591 1592 void VspTree::UpdateContributionsToPvs(KdLeaf *leaf, 1593 const int cf, 1594 float &frontPvs, 1595 float &backPvs, 1596 float &totalPvs) const 1837 1597 { 1838 1598 if (!leaf) return; … … 1847 1607 } 1848 1608 1849 // compute contributionof yet unclassified objects1609 // recursivly update contributions of yet unclassified objects 1850 1610 ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end(); 1851 1611 1852 1612 for (oit = leaf->mMultipleObjects.begin(); oit != oit_end; ++ oit) 1853 1613 { 1854 Update ObjPvsContri(*oit, cf, frontPvs, backPvs, totalPvs);1614 UpdateContributionsToPvs(*oit, cf, frontPvs, backPvs, totalPvs); 1855 1615 } 1856 1616 … … 2296 2056 2297 2057 2298 void VspTree::CollectPvs(const RayInfoContainer &rays,2299 ObjectContainer &objects) const2300 {2301 RayInfoContainer::const_iterator rit, rit_end = rays.end();2302 2303 Intersectable::NewMail();2304 2305 for (rit = rays.begin(); rit != rays.end(); ++ rit)2306 {2307 VssRay *ray = (*rit).mRay;2308 2309 Intersectable *object;2310 object = ray->mOriginObject;2311 2312 if (object)2313 {2314 if (!object->Mailed())2315 {2316 object->Mail();2317 objects.push_back(object);2318 }2319 }2320 2321 object = ray->mTerminationObject;2322 2323 if (object)2324 {2325 if (!object->Mailed())2326 {2327 object->Mail();2328 objects.push_back(object);2329 }2330 }2331 }2332 }2333 2334 2335 int VspTree::EvalPvsContribution(const VssRay &ray, const bool isTermination) const2336 {2337 Intersectable *obj;2338 Vector3 pt;2339 KdNode *node;2340 2341 ray.GetSampleData(isTermination, pt, &obj, &node);2342 2343 if (!obj) return 0;2344 2345 int pvs = 0;2346 2347 switch(mHierarchyManager->GetObjectSpaceSubdivisonType())2348 {2349 case HierarchyManager::NO_OBJ_SUBDIV:2350 {2351 if (!obj->Mailed())2352 {2353 obj->Mail();2354 ++ pvs;2355 }2356 2357 break;2358 }2359 case HierarchyManager::KD_BASED_OBJ_SUBDIV:2360 {2361 KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(pt, node);2362 2363 if (!leaf->Mailed())2364 {2365 leaf->Mail();2366 pvs += (int)(leaf->mObjects.size() - leaf->mMultipleObjects.size());2367 2368 ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end();2369 for (oit = leaf->mMultipleObjects.begin(); oit != oit_end; ++ oit)2370 {2371 Intersectable *obj = *oit;2372 2373 if (!obj->Mailed())2374 {2375 obj->Mail();2376 ++ pvs;2377 }2378 }2379 }2380 2381 break;2382 }2383 case HierarchyManager::BV_BASED_OBJ_SUBDIV:2384 {2385 BvhLeaf *bvhleaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj);2386 2387 if (!bvhleaf->Mailed())2388 {2389 bvhleaf->Mail();2390 pvs += (int)bvhleaf->mObjects.size();2391 }2392 2393 break;2394 }2395 default:2396 break;2397 }2398 2399 return pvs;2400 }2401 2402 2403 2058 int VspTree::EvalPvsSize(const RayInfoContainer &rays) const 2404 2059 { … … 2414 2069 { 2415 2070 VssRay *ray = (*rit).mRay; 2416 pvsSize += EvalPvsContribution(*ray, true); 2417 pvsSize += EvalPvsContribution(*ray, false); 2071 2072 pvsSize += EvalContributionToPvs(*ray, true); 2073 pvsSize += EvalContributionToPvs(*ray, false); 2418 2074 } 2419 2075 … … 2430 2086 int VspTree::CastLineSegment(const Vector3 &origin, 2431 2087 const Vector3 &termination, 2432 ViewCellContainer &viewcells) 2088 ViewCellContainer &viewcells, 2089 const bool useMailboxing) 2433 2090 { 2434 2091 int hits = 0; … … 2438 2095 2439 2096 stack<LineTraversalData> tStack; 2440 2441 //Intersectable::NewMail();2442 //ViewCell::NewMail();2443 2097 2444 2098 Vector3 entp = origin; … … 2503 2157 ViewCell *vc = leaf->GetViewCell(); 2504 2158 2505 // don't have to mail because each view cell belongs to exactly one leaf 2506 //if (!vc->Mailed()) 2507 //{ 2508 // vc->Mail(); 2159 // don't have to mail if each view cell belongs to exactly one leaf 2160 if (!useMailboxing || !vc->Mailed()) 2161 { 2162 if (useMailboxing) 2163 vc->Mail(); 2164 2509 2165 viewcells.push_back(vc); 2510 2166 ++ hits; 2511 //}2167 } 2512 2168 #if 0 2513 2169 leaf->mRays.push_back(RayInfo(new VssRay(origin, termination, NULL, NULL, 0))); … … 2932 2588 void VspTree::GetViewCells(const VssRay &ray, ViewCellContainer &viewCells) 2933 2589 { 2934 #if 12935 // use view cells manager to compute view cells2936 VssRay vcRay(ray);2937 2938 mViewCellsManager->ComputeSampleContribution(vcRay, false, true);2939 viewCells = vcRay.mViewCells;2940 #else2941 2590 static Ray hray; 2942 2591 hray.Init(ray); … … 2950 2599 const Vector3 termination = hray.Extrap(tmax); 2951 2600 2952 // if no precomputation of view cells2953 CastLineSegment(origin, termination, viewCells);2954 #endif 2601 // view cells were not precomputed 2602 // don't mail because we need mailboxing for something else 2603 CastLineSegment(origin, termination, viewCells, false); 2955 2604 } 2956 2605 … … 3052 2701 } 3053 2702 3054 } 2703 2704 int VspTree::EvalMaxEventContribution(const VssRay &ray, 2705 const bool isTermination) const 2706 { 2707 Intersectable *obj; 2708 Vector3 pt; 2709 KdNode *node; 2710 2711 ray.GetSampleData(isTermination, pt, &obj, &node); 2712 2713 if (!obj) 2714 return 0; 2715 2716 int pvs = 0; 2717 2718 switch ( mHierarchyManager->GetObjectSpaceSubdivisonType()) 2719 { 2720 case HierarchyManager::NO_OBJ_SUBDIV: 2721 { 2722 if (-- obj->mCounter == 0) 2723 ++ pvs; 2724 break; 2725 } 2726 case HierarchyManager::KD_BASED_OBJ_SUBDIV: 2727 { 2728 KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(pt, node); 2729 2730 // add contributions of the kd nodes 2731 pvs += EvalMaxEventContribution(leaf); 2732 break; 2733 } 2734 case HierarchyManager::BV_BASED_OBJ_SUBDIV: 2735 { 2736 BvhLeaf *leaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj); 2737 2738 if (-- leaf->mCounter == 0) 2739 pvs += (int)leaf->mObjects.size(); 2740 break; 2741 } 2742 default: 2743 break; 2744 } 2745 2746 return pvs; 2747 } 2748 2749 2750 int VspTree::PrepareHeuristics(const VssRay &ray, const bool isTermination) 2751 { 2752 int pvsSize = 0; 2753 2754 Intersectable *obj; 2755 Vector3 pt; 2756 KdNode *node; 2757 2758 ray.GetSampleData(isTermination, pt, &obj, &node); 2759 2760 if (!obj) 2761 return 0; 2762 2763 switch (mHierarchyManager->GetObjectSpaceSubdivisonType()) 2764 { 2765 case HierarchyManager::NO_OBJ_SUBDIV: 2766 { 2767 if (!obj->Mailed()) 2768 { 2769 obj->Mail(); 2770 obj->mCounter = 0; 2771 2772 ++ pvsSize; 2773 } 2774 2775 ++ obj->mCounter; 2776 break; 2777 } 2778 case HierarchyManager::KD_BASED_OBJ_SUBDIV: 2779 { 2780 KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(pt, node); 2781 pvsSize += PrepareHeuristics(leaf); 2782 break; 2783 } 2784 case HierarchyManager::BV_BASED_OBJ_SUBDIV: 2785 { 2786 BvhLeaf *leaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj); 2787 2788 if (!leaf->Mailed()) 2789 { 2790 leaf->Mail(); 2791 leaf->mCounter = 0; 2792 2793 pvsSize += (int)leaf->mObjects.size(); 2794 } 2795 2796 ++ leaf->mCounter; 2797 break; 2798 } 2799 default: 2800 break; 2801 } 2802 2803 return pvsSize; 2804 } 2805 2806 2807 int VspTree::EvalMinEventContribution(const VssRay &ray, 2808 const bool isTermination) const 2809 { 2810 Intersectable *obj; 2811 Vector3 pt; 2812 KdNode *node; 2813 2814 ray.GetSampleData(isTermination, pt, &obj, &node); 2815 2816 if (!obj) return 0; 2817 2818 int pvs = 0; 2819 2820 switch (mHierarchyManager->GetObjectSpaceSubdivisonType()) 2821 { 2822 case HierarchyManager::NO_OBJ_SUBDIV: 2823 { 2824 if (!obj->Mailed()) 2825 { 2826 obj->Mail(); 2827 ++ pvs; 2828 } 2829 break; 2830 } 2831 case HierarchyManager::KD_BASED_OBJ_SUBDIV: 2832 { 2833 KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(pt, node); 2834 // add contributions of the kd nodes 2835 pvs += EvalMinEventContribution(leaf); 2836 break; 2837 } 2838 case HierarchyManager::BV_BASED_OBJ_SUBDIV: 2839 { 2840 BvhLeaf *leaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj); 2841 2842 if (!leaf->Mailed()) 2843 { 2844 leaf->Mail(); 2845 pvs += (int)leaf->mObjects.size(); 2846 } 2847 break; 2848 } 2849 default: 2850 break; 2851 } 2852 2853 return pvs; 2854 } 2855 2856 2857 void VspTree::UpdateContributionsToPvs(const VssRay &ray, 2858 const bool isTermination, 2859 const int cf, 2860 float &frontPvs, 2861 float &backPvs, 2862 float &totalPvs) const 2863 { 2864 Intersectable *obj; 2865 Vector3 pt; 2866 KdNode *node; 2867 2868 ray.GetSampleData(isTermination, pt, &obj, &node); 2869 2870 if (!obj) return; 2871 2872 switch (mHierarchyManager->GetObjectSpaceSubdivisonType()) 2873 { 2874 case HierarchyManager::NO_OBJ_SUBDIV: 2875 { 2876 // find front and back pvs for origing and termination object 2877 UpdateContributionsToPvs(obj, cf, frontPvs, backPvs, totalPvs); 2878 break; 2879 } 2880 case HierarchyManager::KD_BASED_OBJ_SUBDIV: 2881 { 2882 KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(pt, node); 2883 UpdateContributionsToPvs(leaf, cf, frontPvs, backPvs, totalPvs); 2884 break; 2885 } 2886 case HierarchyManager::BV_BASED_OBJ_SUBDIV: 2887 { 2888 BvhLeaf *leaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj); 2889 UpdateContributionsToPvs(leaf, cf, frontPvs, backPvs, totalPvs); 2890 break; 2891 } 2892 } 2893 } 2894 2895 2896 int VspTree::EvalContributionToPvs(const VssRay &ray, 2897 const bool isTermination) const 2898 { 2899 Intersectable *obj; 2900 Vector3 pt; 2901 KdNode *node; 2902 2903 ray.GetSampleData(isTermination, pt, &obj, &node); 2904 2905 if (!obj) 2906 return 0; 2907 2908 int pvs = 0; 2909 2910 switch(mHierarchyManager->GetObjectSpaceSubdivisonType()) 2911 { 2912 case HierarchyManager::NO_OBJ_SUBDIV: 2913 { 2914 if (!obj->Mailed()) 2915 { 2916 obj->Mail(); 2917 ++ pvs; 2918 } 2919 break; 2920 } 2921 case HierarchyManager::KD_BASED_OBJ_SUBDIV: 2922 { 2923 KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(pt, node); 2924 2925 pvs += EvalContributionToPvs(leaf); 2926 break; 2927 } 2928 case HierarchyManager::BV_BASED_OBJ_SUBDIV: 2929 { 2930 BvhLeaf *bvhleaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj); 2931 2932 if (!bvhleaf->Mailed()) 2933 { 2934 bvhleaf->Mail(); 2935 pvs += (int)bvhleaf->mObjects.size(); 2936 } 2937 break; 2938 } 2939 default: 2940 break; 2941 } 2942 2943 return pvs; 2944 } 2945 2946 2947 int VspTree::EvalContributionToPvs(KdLeaf *leaf) const 2948 { 2949 if (leaf->Mailed()) // leaf already mailed 2950 return 0; 2951 2952 leaf->Mail(); 2953 2954 int pvs = 0; 2955 pvs += (int)(leaf->mObjects.size() - leaf->mMultipleObjects.size()); 2956 2957 ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end(); 2958 2959 for (oit = leaf->mMultipleObjects.begin(); oit != oit_end; ++ oit) 2960 { 2961 Intersectable *obj = *oit; 2962 2963 if (!obj->Mailed()) 2964 { 2965 obj->Mail(); 2966 ++ pvs; 2967 } 2968 } 2969 2970 return pvs; 2971 } 2972 2973 }
Note: See TracChangeset
for help on using the changeset viewer.