Changeset 349 for trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
- Timestamp:
- 10/26/05 19:18:30 (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/VUT/GtpVisibilityPreprocessor/src/ViewCellBsp.cpp
r342 r349 43 43 contribution for a minimum number splits in the tree. 44 44 */ 45 float BspTree::sLeast SplitsTable[] = {0, 0, 1, 0};45 float BspTree::sLeastPolySplitsTable[] = {0, 0, 1, 0}; 46 46 /** Evaluates split plane classification with respect to the plane's 47 47 contribution for a balanced tree. 48 48 */ 49 float BspTree::sBalancedTreeTable[] = {-1, 1, 0, 0}; 49 float BspTree::sBalancedPolysTable[] = {1, -1, 0, 0}; 50 51 /** Evaluates split plane classification with respect to the plane's 52 contribution for a minimum number of ray splits. 53 */ 54 float BspTree::sLeastRaySplitsTable[] = {0, 0, 1, 1, 0}; 55 /** Evaluates split plane classification with respect to the plane's 56 contribution for balanced rays. 57 */ 58 float BspTree::sBalancedRaysTable[] = {1, -1, 0, 0, 0}; 50 59 51 60 /****************************************************************/ … … 158 167 } 159 168 160 void BspInterior::SplitRays(RayContainer &rays, 161 RayContainer &frontRays, 162 RayContainer &backRays) 163 { 169 int BspInterior::SplitRays(RayContainer &rays, 170 RayContainer &frontRays, 171 RayContainer &backRays, 172 const AxisAlignedBox3 &box) 173 { 174 int splits = 0; 175 164 176 while (!rays.empty()) 165 177 { … … 172 184 173 185 // test with tree bounding box 174 /* if (!mBox.GetMinMaxT(*ray, &minT, &maxT))186 if (!box.GetMinMaxT(*ray, &minT, &maxT)) 175 187 continue; 188 176 189 if (minT < 0) // start ray from origin 177 190 minT = 0; 178 */ 191 179 192 // bound ray 180 193 if ((ray->GetType() == Ray::LOCAL_RAY) && … … 185 198 } 186 199 187 int classification = ray->ClassifyPlane(mPlane, minT, maxT); 188 200 const int classification = ray->ClassifyPlane(mPlane, minT, maxT); 201 202 ray->SetId(classification); 203 189 204 switch (classification) 190 205 { 191 case Plane3::COINCIDENT:206 case Ray::COINCIDENT: 192 207 break; 193 case Plane3::BACK_SIDE: 194 ray->SetId(BACK_RAY); 208 case Ray::BACK: 195 209 backRays.push_back(ray); 196 210 break; 197 case Plane3::FRONT_SIDE: 198 ray->SetId(FRONT_RAY); 211 case Ray::FRONT: 199 212 frontRays.push_back(ray); 200 213 break; 201 case Plane3::SPLIT: 202 ray->SetId(SPLIT_RAY); 214 case Ray::FRONT_BACK: 215 ray->SetId(Ray::FRONT_BACK); 216 backRays.push_back(ray); 217 ++ splits; 218 break; 219 case Ray::BACK_FRONT: 203 220 frontRays.push_back(ray); 204 backRays.push_back(ray); 205 //extp = splitPlane->FindIntersection(ray.GetLoc(), extp, &maxt); 221 ++ splits; 206 222 break; 207 223 default: 224 Debug << "Should not come here" << endl; 208 225 break; 209 226 } 210 227 } 228 229 return splits; 211 230 } 212 231 … … 215 234 PolygonContainer &backPolys, 216 235 PolygonContainer &coincident, 217 bool storePolys)236 const bool storePolys) 218 237 { 219 238 Polygon3 *splitPoly = NULL; … … 232 251 233 252 // classify polygon 234 int classification = poly->ClassifyPlane(mPlane);253 const int classification = poly->ClassifyPlane(mPlane); 235 254 236 255 Polygon3 *front_piece = NULL; … … 241 260 switch (classification) 242 261 { 243 case P lane3::COINCIDENT:262 case Polygon3::COINCIDENT: 244 263 coincident.push_back(poly); 245 264 break; 246 case P lane3::FRONT_SIDE:265 case Polygon3::FRONT_SIDE: 247 266 frontPolys.push_back(poly); 248 267 break; 249 case P lane3::BACK_SIDE:268 case Polygon3::BACK_SIDE: 250 269 backPolys.push_back(poly); 251 270 break; 252 case P lane3::SPLIT:271 case Polygon3::SPLIT: 253 272 front_piece = new Polygon3(poly->mParent); 254 273 back_piece = new Polygon3(poly->mParent); … … 262 281 ++ splits; // increase number of splits 263 282 264 //-- inherit rays 265 if (poly->mPiercingRays)266 InheritRays(*poly, *front_piece, *back_piece);267 283 //-- inherit rays from parent polygon 284 poly->InheritRays(*front_piece, *back_piece); 285 Debug << "p: " << poly->mPiercingRays.size() << " f: " << front_piece->mPiercingRays.size() << " b: " << back_piece->mPiercingRays.size() << endl; 286 268 287 // check if polygons still valid 269 288 if (front_piece->Valid()) … … 280 299 Debug << "split " << *poly << endl << *front_piece << endl << *back_piece << endl; 281 300 #endif 282 ProcessPolygon(&poly, storePolys); 283 301 ProcessPolygon(&poly, storePolys); 284 302 break; 285 303 default: … … 290 308 291 309 return splits; 292 }293 294 void BspInterior::InheritRays(const Polygon3 &poly,295 Polygon3 &front_piece,296 Polygon3 &back_piece)297 {298 RayContainer *rays = poly.mPiercingRays;299 300 RayContainer::const_iterator it, it_end = rays->end();301 302 for (it = rays->begin(); it != it_end; ++ it)303 {304 switch((*it)->GetId())305 {306 case BACK_RAY:307 back_piece.GetPiercingRays()->push_back(*it);308 break;309 case FRONT_RAY:310 front_piece.GetPiercingRays()->push_back(*it);311 break;312 }313 }314 310 } 315 311 … … 664 660 if (it != facePolyMap.end()) 665 661 { 666 (*it).second-> AddPiercingRay(ray);662 (*it).second->mPiercingRays.push_back(ray); 667 663 } 668 664 else … … 670 666 Polygon3 *poly = new Polygon3(face, obj->GetMesh()); 671 667 polys->push_back(poly); 672 poly-> AddPiercingRay(ray);668 poly->mPiercingRays.push_back(ray); 673 669 674 670 facePolyMap[face] = poly; … … 842 838 PolygonContainer &coincident, 843 839 RayContainer &rays, 844 RayContainer & backRays,845 RayContainer & frontRays)840 RayContainer &frontRays, 841 RayContainer &backRays) 846 842 { 847 843 mStat.nodes += 2; … … 855 851 #endif 856 852 857 // partitionrays858 interior->SplitRays(rays, frontRays, backRays );853 // subdivide rays into front and back rays 854 interior->SplitRays(rays, frontRays, backRays, mBox); 859 855 860 856 // split polygons with split plane … … 987 983 } 988 984 985 bool BspTree::SelectAxisAlignedPlane(Plane3 &plane, 986 const PolygonContainer &polys) const 987 { 988 AxisAlignedBox3 box; 989 box.Initialize(); 990 991 // create bounding box of region 992 Polygon3::IncludeInBox(polys, box); 993 994 int objectsBack = 0, objectsFront = 0; 995 int axis = 0; 996 float costRatio = MAX_FLOAT; 997 Vector3 position; 998 999 //-- area subdivision 1000 for (int i = 0; i < 3; ++ i) 1001 { 1002 float p = 0; 1003 float r = BestCostRatio(polys, box, i, p, objectsBack, objectsFront); 1004 1005 if (r < costRatio) 1006 { 1007 costRatio = r; 1008 axis = i; 1009 position = p; 1010 } 1011 } 1012 1013 if (costRatio >= sMaxCostRatio) 1014 return false; 1015 1016 Vector3 norm(0,0,0); norm[axis] = 1.0f; 1017 plane = Plane3(norm, position); 1018 1019 return true; 1020 } 1021 989 1022 Plane3 BspTree::SelectPlane(BspLeaf *leaf, 990 1023 PolygonContainer &polys, 991 1024 const RayContainer &rays) 992 1025 { 993 if (polys.size() == 0) 994 { 995 Debug << "Warning: No split candidate available\n"; 996 return Plane3(); 1026 if (polys.empty()) 1027 { 1028 Debug << "Warning: No autopartition polygon candidate available\n"; 1029 1030 // return axis aligned split 1031 AxisAlignedBox3 box; 1032 box.Initialize(); 1033 1034 // create bounding box of region 1035 Polygon3::IncludeInBox(polys, box); 1036 1037 const int axis = box.Size().DrivingAxis(); 1038 const Vector3 position = (box.Min()[axis] + box.Max()[axis])*0.5f; 1039 1040 Vector3 norm(0,0,0); norm[axis] = 1.0f; 1041 return Plane3(norm, position); 997 1042 } 998 1043 … … 1000 1045 ((int)polys.size() > sTermMaxPolysForAxisAligned)) 1001 1046 { 1002 AxisAlignedBox3 box; 1003 box.Initialize(); 1004 1005 // todo: area subdivision 1006 Polygon3::IncludeInBox(polys, box); 1007 1008 int objectsBack = 0, objectsFront = 0; 1009 int axis = 0; 1010 float costRatio = MAX_FLOAT; 1011 Vector3 position; 1012 1013 for (int i = 0; i < 3; ++ i) 1014 { 1015 float p = 0; 1016 float r = BestCostRatio(polys, box, i, p, objectsBack, objectsFront); 1017 1018 if (r < costRatio) 1019 { 1020 costRatio = r; 1021 axis = i; 1022 position = p; 1023 } 1024 } 1025 1026 if (costRatio < sMaxCostRatio) 1027 { 1028 Vector3 norm(0,0,0); norm[axis] = 1.0f; 1029 return Plane3(norm, position); 1030 } 1047 Plane3 plane; 1048 if (SelectAxisAlignedPlane(plane, polys)) 1049 return plane; 1031 1050 } 1032 1051 … … 1074 1093 int BspTree::GetNextCandidateIdx(int currentIdx, PolygonContainer &polys) 1075 1094 { 1076 int candidateIdx = Random(currentIdx --);1095 const int candidateIdx = Random(currentIdx --); 1077 1096 1078 1097 // swap candidates to avoid testing same plane 2 times … … 1101 1120 // needed for balanced view cells criterium 1102 1121 ViewCell::NewMail(); 1103 int backId = ViewCell::sMailId;1122 const int backId = ViewCell::sMailId; 1104 1123 ViewCell::NewMail(); 1105 int frontId = ViewCell::sMailId;1124 const int frontId = ViewCell::sMailId; 1106 1125 ViewCell::NewMail(); 1107 int frontAndBackId = ViewCell::sMailId;1126 const int frontAndBackId = ViewCell::sMailId; 1108 1127 1109 1128 PolygonContainer::const_iterator it, it_end = polys.end(); … … 1111 1130 for (it = polys.begin(); it != it_end; ++ it) 1112 1131 { 1113 int classification = (*it)->ClassifyPlane(candidatePlane);1132 const int classification = (*it)->ClassifyPlane(candidatePlane); 1114 1133 1115 1134 if (sSplitPlaneStrategy & BALANCED_POLYS) 1116 sumBalancedPolys += sBalanced TreeTable[classification];1135 sumBalancedPolys += sBalancedPolysTable[classification]; 1117 1136 1118 1137 if (sSplitPlaneStrategy & LEAST_SPLITS) 1119 sumSplits += sLeast SplitsTable[classification];1138 sumSplits += sLeastPolySplitsTable[classification]; 1120 1139 1121 1140 if (sSplitPlaneStrategy & LARGEST_POLY_AREA) 1122 1141 { 1123 if (classification == P lane3::COINCIDENT)1142 if (classification == Polygon3::COINCIDENT) 1124 1143 sumPolyArea += (*it)->GetArea(); 1125 1144 //totalArea += area; … … 1128 1147 if (sSplitPlaneStrategy & BLOCKED_RAYS) 1129 1148 { 1130 float blockedRays = (float)(*it)->GetPiercingRays()->size();1131 1132 if (classification == P lane3::COINCIDENT)1149 const float blockedRays = (float)(*it)->mPiercingRays.size(); 1150 1151 if (classification == Polygon3::COINCIDENT) 1133 1152 sumBlockedRays += blockedRays; 1134 1153 … … 1143 1162 // assure that we only count a view cell 1144 1163 // once for the front and once for the back side of the plane 1145 if (classification == P lane3::FRONT_SIDE)1164 if (classification == Polygon3::FRONT_SIDE) 1146 1165 { 1147 1166 if ((viewCell->mMailbox != frontId) && … … 1158 1177 } 1159 1178 } 1160 else if (classification == P lane3::BACK_SIDE)1179 else if (classification == Polygon3::BACK_SIDE) 1161 1180 { 1162 1181 if ((viewCell->mMailbox != backId) && … … 1190 1209 if (sSplitPlaneStrategy & BLOCKED_RAYS) 1191 1210 if (totalBlockedRays != 0) 1192 val += sBlockedRaysFactor * sumBlockedRays/ totalBlockedRays;1211 val += sBlockedRaysFactor * (totalBlockedRays - sumBlockedRays) / totalBlockedRays; 1193 1212 1194 1213 if (sSplitPlaneStrategy & BALANCED_VIEW_CELLS) … … 1218 1237 1219 1238 // test with tree bounding box 1220 /*if (!mBox.GetMinMaxT(*ray, &minT, &maxT))1239 if (!mBox.GetMinMaxT(*ray, &minT, &maxT)) 1221 1240 continue; 1222 1241 if (minT < 0) // start ray from origin 1223 minT = 0; */1242 minT = 0; 1224 1243 1225 1244 // bound ray … … 1231 1250 } 1232 1251 1233 int classification = ray->ClassifyPlane(candidatePlane, minT, maxT); 1252 const int classification = 1253 ray->ClassifyPlane(candidatePlane, minT, maxT); 1234 1254 1235 1255 if (sSplitPlaneStrategy & LEAST_RAY_SPLITS) 1236 1256 { 1237 sumBalancedRays += sBalanced TreeTable[classification];1257 sumBalancedRays += sBalancedRaysTable[classification]; 1238 1258 } 1239 1259 1240 1260 if (sSplitPlaneStrategy & BALANCED_RAYS) 1241 1261 { 1242 sumRaySplits += sLeast SplitsTable[classification];1262 sumRaySplits += sLeastRaySplitsTable[classification]; 1243 1263 } 1244 1264 } … … 1332 1352 environment->GetBoolValue("BspTree.storeSplitPolys", sStoreSplitPolys); 1333 1353 1334 environment->GetFloatValue("BspTree.Construction.sideTolerance", Polygon3::sSideTolerance);1335 Polygon3::sSideToleranceSqrt = Polygon3::sSideTolerance * Polygon3::sSideTolerance;1354 environment->GetFloatValue("BspTree.Construction.sideTolerance", Vector3::sDistTolerance); 1355 Vector3::sDistToleranceSqrt = Vector3::sDistTolerance * Vector3::sDistTolerance; 1336 1356 1337 1357 Debug << "BSP max depth: " << sTermMaxDepth << endl; … … 1379 1399 { 1380 1400 BspInterior *interior = dynamic_cast<BspInterior *>(node); 1401 1381 1402 nodeStack.push(interior->GetBack()); 1382 1403 nodeStack.push(interior->GetFront()); … … 1417 1438 } 1418 1439 1419 #ifdef _DEBUG1440 //#ifdef _DEBUG 1420 1441 Debug << "BSP stats: " 1421 1442 << "Depth: " << data.mDepth << " (max: " << sTermMaxDepth << "), " 1422 1443 << "#polygons: " << (int)data.mPolygons->size() << " (max: " << sTermMaxPolygons << "), " 1423 1444 << "#rays: " << (int)data.mRays->size() << " (max: " << sTermMaxRays << ")" << endl; 1424 #endif1445 //#endif 1425 1446 } 1426 1447 … … 1520 1541 entp = extp; 1521 1542 mint = maxt; // NOTE: need this? 1543 1544 if (ray.GetType() == Ray::LINE_SEGMENT && mint > 1.0f) 1545 break; 1546 1522 1547 BspRayTraversalData &s = tStack.top(); 1523 1548
Note: See TracChangeset
for help on using the changeset viewer.