Changeset 1259 for GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp
- Timestamp:
- 08/22/06 22:48:02 (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GTP/trunk/Lib/Vis/Preprocessing/src/VspTree.cpp
r1251 r1259 18 18 #include "KdTree.h" 19 19 #include "KdIntersectable.h" 20 #include "HierarchyManager.h" 21 #include "BvHierarchy.h" 20 22 #include "OspTree.h" 23 21 24 22 25 namespace GtpVisibilityPreprocessor { … … 358 361 mStoreRays(false), 359 362 mTimeStamp(1), 360 m OspTree(NULL)363 mHierarchyManager(NULL) 361 364 { 362 365 bool randomize = false; … … 397 400 Environment::GetSingleton()->GetBoolValue("VspTree.simulateOctree", mCirculatingAxis); 398 401 399 Environment::GetSingleton()->GetBoolValue("VspTree.useKdPvsForHeuristics", mUseKdPvsForHeuristics);402 //Environment::GetSingleton()->GetBoolValue("VspTree.useKdPvsForHeuristics", mUseKdPvsForHeuristics); 400 403 401 404 char subdivisionStatsLog[100]; … … 433 436 Debug << "maxband: " << mMaxBand << endl; 434 437 435 if (!mUseKdPvsForHeuristics)436 Debug << "pvs heuristics: per object" << endl;437 else438 Debug << "pvs heuristics: per kd node" << endl;439 440 438 mLocalSubdivisionCandidates = new vector<SortableEntry>; 441 439 … … 911 909 912 910 913 bool VspTree::AddKdLeafToPvs(KdLeaf *leaf,914 ViewCell *vc,915 const float pdf,916 float &contribution)917 {918 bool contri = false;919 920 #if 1 // add kd intersecable to pvs921 KdIntersectable *kdObj = mOspTree->GetOrCreateKdIntersectable(leaf);922 923 if (vc->AddPvsSample(kdObj, pdf, contribution))924 {925 return true;926 }927 928 #else // add all objects of kd node929 930 contribution = 0;931 932 ObjectContainer::const_iterator it, it_end = leaf->mObjects.end();933 934 for (it = leaf->mObjects.begin(); it != it_end; ++ it)935 {936 Intersectable *object = *it;937 938 float newcontri;939 940 if (vc->AddPvsSample(object, pdf, newcontri))941 {942 contri = true;943 }944 945 //pdf += newPdf;946 newContri += contribution;947 }948 #endif949 950 return contri;951 }952 911 953 912 … … 977 936 if (obj) 978 937 { 979 if (!mStoreKdPvs) 980 { 981 // potentially visible objects 982 madeContrib = vc->AddPvsSample(obj, ray->mPdf, contribution); 983 } 984 else 985 { 986 // potentially visible kd cells 987 KdLeaf *leaf = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode); 988 madeContrib = AddKdLeafToPvs(leaf, vc, ray->mPdf, contribution); 989 } 938 madeContrib = 939 mViewCellsManager->AddSampleToPvs( 940 obj, 941 ray->mTermination, 942 vc, 943 ray->mPdf, 944 contribution); 990 945 991 946 sc += contribution; … … 996 951 if (obj) 997 952 { 998 if (!mStoreKdPvs) 999 { 1000 // potentially visible objects 1001 madeContrib = vc->AddPvsSample(obj, ray->mPdf, contribution); 1002 } 1003 else 1004 { 1005 // potentially visible kd cells 1006 KdLeaf *leaf = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode); 1007 madeContrib = AddKdLeafToPvs(leaf, vc, ray->mPdf, contribution); 1008 } 953 madeContrib = 954 mViewCellsManager->AddSampleToPvs( 955 obj, 956 ray->mOrigin, 957 vc, 958 ray->mPdf, 959 contribution); 1009 960 1010 961 sc += contribution; … … 1092 1043 1093 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 else 1070 { 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, NULL); 1084 1085 if (!leaf->Mailed()) 1086 { 1087 leaf->Mail(); 1088 leaf->mCounter = 1; 1089 1090 ++ pvsSize; 1091 } 1092 else 1093 { 1094 ++ leaf->mCounter; 1095 } 1096 break; 1097 } 1098 default: 1099 break; 1100 } 1101 1102 return pvsSize; 1103 } 1104 1105 1094 1106 int VspTree::PrepareHeuristics(KdLeaf *leaf) 1095 1107 { … … 1144 1156 RayInfoContainer::const_iterator ri, ri_end = rays.end(); 1145 1157 1146 //-- set all kd nodes / objects as belonging to the front pvs 1147 1158 // set all kd nodes / objects as belonging to the front pvs 1148 1159 for (ri = rays.begin(); ri != ri_end; ++ ri) 1149 1160 { 1150 1161 VssRay *ray = (*ri).mRay; 1151 Intersectable *oObject = ray->mOriginObject; 1152 1153 if (oObject) 1154 { 1155 if (!mUseKdPvsForHeuristics) 1156 { 1157 if (!oObject->Mailed()) 1158 { 1159 oObject->Mail(); 1160 oObject->mCounter = 1; 1161 1162 ++ pvsSize; 1163 } 1164 else 1165 { 1166 ++ oObject->mCounter; 1167 } 1168 } 1169 else 1170 { 1171 KdLeaf *leaf = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode); 1172 pvsSize += PrepareHeuristics(leaf); 1173 } 1174 } 1175 1176 Intersectable *tObject = (*ri).mRay->mTerminationObject; 1177 1178 if (tObject) 1179 { 1180 if (!mUseKdPvsForHeuristics) 1181 { 1182 if (!tObject->Mailed()) 1183 { 1184 tObject->Mail(); 1185 tObject->mCounter = 1; 1186 ++ pvsSize; 1187 } 1188 else 1189 { 1190 ++ tObject->mCounter; 1191 } 1192 } 1193 else 1194 { 1195 KdLeaf *leaf = mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode); 1196 pvsSize += PrepareHeuristics(leaf); 1197 } 1198 } 1162 1163 pvsSize += PrepareHeuristics(*ray, true); 1164 pvsSize += PrepareHeuristics(*ray, false); 1199 1165 } 1200 1166 … … 1203 1169 1204 1170 1205 void VspTree::RemoveContriFromPvs(KdLeaf *leaf, int &pvs) const 1206 { 1171 int VspTree::EvalMaxEventContribution(KdLeaf *leaf) const 1172 { 1173 int pvs = 0; 1174 1207 1175 // leaf falls out of right pvs 1208 1176 if (-- leaf->mCounter == 0) … … 1211 1179 } 1212 1180 1213 //-- handle objects which are in several kd leaves separately 1181 //-- separately handle objects which are in several kd leaves 1182 1214 1183 ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end(); 1215 1184 … … 1220 1189 if (-- object->mCounter == 0) 1221 1190 { 1222 -- pvs; 1223 } 1224 } 1225 } 1226 1227 1228 void VspTree::AddContriToPvs(KdLeaf *leaf, int &pvs) const 1191 ++ pvs; 1192 } 1193 } 1194 1195 return pvs; 1196 } 1197 1198 1199 int VspTree::EvalMinEventContribution(KdLeaf *leaf) const 1229 1200 { 1230 1201 if (leaf->Mailed()) 1231 return ;1202 return 0; 1232 1203 1233 1204 leaf->Mail(); 1234 1205 1235 1206 // add objects without those which are part of several kd leaves 1236 pvs += ((int)leaf->mObjects.size() - (int)leaf->mMultipleObjects.size());1237 1238 // -- handle objects of several kd leaves separately1207 int pvs = ((int)leaf->mObjects.size() - (int)leaf->mMultipleObjects.size()); 1208 1209 // separately handle objects which are part of several kd leaves 1239 1210 ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end(); 1240 1211 … … 1249 1220 ++ pvs; 1250 1221 } 1251 } 1252 } 1253 1254 1255 void VspTree::EvalPvsIncr(const SortableEntry &ci, 1256 int &pvsLeft, 1257 int &pvsRight) const 1222 } 1223 1224 return pvs; 1225 } 1226 1227 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; 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; 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 1258 1327 { 1259 1328 VssRay *ray = ci.ray; 1260 1329 1261 Intersectable *oObject = ray->mOriginObject; 1262 Intersectable *tObject = ray->mTerminationObject; 1263 1264 if (oObject) 1265 { 1266 if (!mUseKdPvsForHeuristics) 1267 { 1268 if (ci.type == SortableEntry::ERayMin) 1269 { 1270 if (!oObject->Mailed()) 1271 { 1272 oObject->Mail(); 1273 ++ pvsLeft; 1274 } 1275 } 1276 else if (ci.type == SortableEntry::ERayMax) 1277 { 1278 if (-- oObject->mCounter == 0) 1279 -- pvsRight; 1280 } 1281 } 1282 else // per kd node 1283 { 1284 KdLeaf *node = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode); 1285 1286 // add contributions of the kd nodes 1287 if (ci.type == SortableEntry::ERayMin) 1288 { 1289 AddContriToPvs(node, pvsLeft); 1290 } 1291 else if (ci.type == SortableEntry::ERayMax) 1292 { 1293 RemoveContriFromPvs(node, pvsRight); 1294 } 1295 } 1296 } 1297 1298 if (tObject) 1299 { 1300 if (!mUseKdPvsForHeuristics) 1301 { 1302 if (ci.type == SortableEntry::ERayMin) 1303 { 1304 if (!tObject->Mailed()) 1305 { 1306 tObject->Mail(); 1307 ++ pvsLeft; 1308 } 1309 } 1310 else if (ci.type == SortableEntry::ERayMax) 1311 { 1312 if (-- tObject->mCounter == 0) 1313 -- pvsRight; 1314 } 1315 } 1316 else // per kd node 1317 { 1318 KdLeaf *node = mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode); 1319 1320 if (ci.type == SortableEntry::ERayMin) 1321 { 1322 AddContriToPvs(node, pvsLeft); 1323 } 1324 else if (ci.type == SortableEntry::ERayMax) 1325 { 1326 RemoveContriFromPvs(node, pvsRight); 1327 } 1328 } 1330 if (ci.type == SortableEntry::ERayMin) 1331 { 1332 pvsLeft += EvalMinEventContribution(*ray, true); 1333 pvsLeft += EvalMinEventContribution(*ray, false); 1334 } 1335 else 1336 { 1337 pvsRight -= EvalMaxEventContribution(*ray, true); 1338 pvsRight -= EvalMaxEventContribution(*ray, false); 1329 1339 } 1330 1340 } … … 1336 1346 float &position) 1337 1347 { 1348 // get subset of rays 1338 1349 RayInfoContainer usedRays; 1339 1350 … … 1395 1406 for (ci = mLocalSubdivisionCandidates->begin(); ci != ci_end; ++ ci) 1396 1407 { 1397 Eval PvsIncr(*ci, pvsl, pvsr);1408 EvalHeuristicsContribution(*ci, pvsl, pvsr); 1398 1409 1399 1410 // Note: sufficient to compare size of bounding boxes of front and back side? … … 1580 1591 rayInf.ComputeRayIntersection(candidatePlane.mAxis, 1581 1592 candidatePlane.mPosition, t); 1582 1593 /* 1583 1594 if (!mUseKdPvsForHeuristics) 1584 1595 { … … 1591 1602 if (ray->mTerminationObject) 1592 1603 { 1593 KdLeaf *leaf = m OspTree->GetLeaf(ray->mTermination, ray->mTerminationNode);1604 KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode); 1594 1605 UpdateKdLeafPvsContri(leaf, cf, pvsFront, pvsBack, totalPvs); 1595 1606 } … … 1597 1608 if (ray->mOriginObject) 1598 1609 { 1599 KdLeaf *leaf = m OspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);1610 KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode); 1600 1611 UpdateKdLeafPvsContri(leaf, cf, pvsFront, pvsBack, totalPvs); 1601 1612 } 1602 1613 } 1614 */ 1603 1615 } 1604 1616 … … 2243 2255 2244 2256 2245 int VspTree::EvalPvsSize(const RayInfoContainer &rays) const 2246 { 2247 int pvsSize = 0; 2248 Intersectable::NewMail(); 2249 2250 RayInfoContainer::const_iterator rit, rit_end = rays.end(); 2251 2252 if (!mUseKdPvsForHeuristics) 2253 { 2254 for (rit = rays.begin(); rit != rays.end(); ++ rit) 2255 { 2256 VssRay *ray = (*rit).mRay; 2257 2258 if (ray->mOriginObject) 2259 { 2260 if (!ray->mOriginObject->Mailed()) 2257 int VspTree::EvalPvsContribution(const VssRay &ray, const bool isTermination) const 2258 { 2259 Intersectable *obj; 2260 Vector3 pt; 2261 KdNode *node; 2262 2263 ray.GetSampleData(isTermination, pt, &obj, &node); 2264 2265 if (!obj) return 0; 2266 2267 int pvs = 0; 2268 2269 switch(mHierarchyManager->GetObjectSpaceSubdivisonType()) 2270 { 2271 case HierarchyManager::NO_OBJ_SUBDIV: 2272 { 2273 if (!obj->Mailed()) 2274 { 2275 obj->Mail(); 2276 ++ pvs; 2277 } 2278 2279 break; 2280 } 2281 case HierarchyManager::KD_BASED_OBJ_SUBDIV: 2282 { 2283 KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(pt, node); 2284 2285 if (!leaf->Mailed()) 2286 { 2287 leaf->Mail(); 2288 pvs += (int)(leaf->mObjects.size() - leaf->mMultipleObjects.size()); 2289 2290 ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end(); 2291 for (oit = leaf->mMultipleObjects.begin(); oit != oit_end; ++ oit) 2261 2292 { 2262 ray->mOriginObject->Mail(); 2263 ++ pvsSize; 2264 } 2265 } 2266 if (ray->mTerminationObject) 2267 { 2268 if (!ray->mTerminationObject->Mailed()) 2269 { 2270 ray->mTerminationObject->Mail(); 2271 ++ pvsSize; 2272 } 2273 } 2274 } 2275 } 2276 else // compute pvs from kd nodes 2277 { 2278 KdNode::NewMail(); 2279 2280 for (rit = rays.begin(); rit != rays.end(); ++ rit) 2281 { 2282 VssRay *ray = (*rit).mRay; 2283 2284 if (ray->mTerminationObject) 2285 { 2286 KdLeaf *leaf = mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode); 2287 2288 if (!leaf->Mailed()) 2289 { 2290 leaf->Mail(); 2291 pvsSize += (int)(leaf->mObjects.size() - leaf->mMultipleObjects.size()); 2292 2293 ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end(); 2294 for (oit = leaf->mMultipleObjects.begin(); oit != oit_end; ++ oit) 2293 Intersectable *obj = *oit; 2294 2295 if (!obj->Mailed()) 2295 2296 { 2296 Intersectable *obj = *oit; 2297 2298 if (!obj->Mailed()) 2299 { 2300 obj->Mail(); 2301 ++ pvsSize; 2302 } 2297 obj->Mail(); 2298 ++ pvs; 2303 2299 } 2304 2300 } 2305 2301 } 2306 2302 2307 if (ray->mOriginObject) 2308 { 2309 KdLeaf *leaf = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode); 2310 2311 if (!leaf->Mailed()) 2312 { 2313 leaf->Mail(); 2314 pvsSize += (int)(leaf->mObjects.size() - leaf->mMultipleObjects.size()); 2315 2316 ObjectContainer::const_iterator oit, oit_end = leaf->mMultipleObjects.end(); 2317 for (oit = leaf->mMultipleObjects.begin(); oit != oit_end; ++ oit) 2318 { 2319 Intersectable *obj = *oit; 2320 2321 if (!obj->Mailed()) 2322 { 2323 obj->Mail(); 2324 ++ pvsSize; 2325 } 2326 } 2327 } 2328 } 2329 } 2330 } 2331 2303 break; 2304 } 2305 case HierarchyManager::BV_BASED_OBJ_SUBDIV: 2306 { 2307 BvhLeaf *bvhleaf = mHierarchyManager->mBvHierarchy->GetLeaf(obj); 2308 2309 if (!bvhleaf->Mailed()) 2310 { 2311 bvhleaf->Mail(); 2312 pvs += (int)bvhleaf->mObjects.size(); 2313 } 2314 2315 break; 2316 } 2317 default: 2318 break; 2319 } 2320 2321 return pvs; 2322 } 2323 2324 2325 int VspTree::EvalPvsSize(const RayInfoContainer &rays) const 2326 { 2327 int pvsSize = 0; 2328 2329 Intersectable::NewMail(); 2330 KdNode::NewMail(); 2331 BvhNode::NewMail(); 2332 2333 RayInfoContainer::const_iterator rit, rit_end = rays.end(); 2334 2335 for (rit = rays.begin(); rit != rays.end(); ++ rit) 2336 { 2337 VssRay *ray = (*rit).mRay; 2338 pvsSize += EvalPvsContribution(*ray, true); 2339 pvsSize += EvalPvsContribution(*ray, false); 2340 } 2341 2332 2342 return pvsSize; 2333 2343 } … … 2806 2816 2807 2817 2808 void VspTree::CollectDirtyCandidates(VspSubdivisionCandidate *sc,2809 vector<SubdivisionCandidate *> &dirtyList)2810 {2811 VspTraversalData &tData = sc->mParentData;2812 VspLeaf *node = tData.mNode;2813 2814 KdLeaf::NewMail();2815 2816 RayInfoContainer::const_iterator rit, rit_end = tData.mRays->end();2817 2818 // add all kd nodes seen by the rays2819 for (rit = tData.mRays->begin(); rit != rit_end; ++ rit)2820 {2821 VssRay *ray = (*rit).mRay;2822 2823 KdLeaf *leaf = mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode);2824 2825 if (!leaf->Mailed())2826 {2827 leaf->Mail();2828 dirtyList.push_back(leaf->mSubdivisionCandidate);2829 }2830 2831 leaf = mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode);2832 2833 if (!leaf->Mailed())2834 {2835 leaf->Mail();2836 dirtyList.push_back(leaf->mSubdivisionCandidate);2837 }2838 }2839 }2840 2841 2842 2818 void VspTree::PreprocessRays(const VssRayContainer &sampleRays, 2843 2819 RayInfoContainer &rays) … … 2965 2941 2966 2942 2967 2968 } 2943 void VspTree::CollectDirtyCandidates(VspSubdivisionCandidate *sc, 2944 vector<SubdivisionCandidate *> &dirtyList) 2945 { 2946 VspTraversalData &tData = sc->mParentData; 2947 VspLeaf *node = tData.mNode; 2948 2949 KdLeaf::NewMail(); 2950 2951 RayInfoContainer::const_iterator rit, rit_end = tData.mRays->end(); 2952 2953 // add all kd nodes seen by the rays 2954 for (rit = tData.mRays->begin(); rit != rit_end; ++ rit) 2955 { 2956 VssRay *ray = (*rit).mRay; 2957 2958 KdLeaf *leaf = mHierarchyManager->mOspTree->GetLeaf(ray->mOrigin, ray->mOriginNode); 2959 2960 if (!leaf->Mailed()) 2961 { 2962 leaf->Mail(); 2963 dirtyList.push_back(leaf->mSubdivisionCandidate); 2964 } 2965 2966 leaf = mHierarchyManager->mOspTree->GetLeaf(ray->mTermination, ray->mTerminationNode); 2967 2968 if (!leaf->Mailed()) 2969 { 2970 leaf->Mail(); 2971 dirtyList.push_back(leaf->mSubdivisionCandidate); 2972 } 2973 } 2974 } 2975 2976 }
Note: See TracChangeset
for help on using the changeset viewer.