Changeset 2093
- Timestamp:
- 02/05/07 16:17:40 (17 years ago)
- Location:
- GTP/trunk/Lib/Vis/Preprocessing/src
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.cpp
r2065 r2093 1845 1845 1846 1846 1847 void BvHierarchy::CollectNodes(BvhNode *root, vector<BvhNode *> &nodes) const 1848 { 1849 stack<BvhNode *> nodeStack; 1850 nodeStack.push(root); 1851 1852 while (!nodeStack.empty()) 1853 { 1854 BvhNode *node = nodeStack.top(); 1855 nodeStack.pop(); 1856 1857 nodes.push_back(node); 1858 1859 if (!node->IsLeaf()) 1860 { 1861 BvhInterior *interior = (BvhInterior *)node; 1862 1863 nodeStack.push(interior->GetBack()); 1864 nodeStack.push(interior->GetFront()); 1865 } 1866 } 1867 } 1868 1869 1847 1870 AxisAlignedBox3 BvHierarchy::GetBoundingBox(BvhNode *node) const 1848 1871 { … … 2785 2808 2786 2809 2787 } 2810 void BvHierarchy::SetUniqueNodeIds() 2811 { 2812 // export bounding boxes 2813 vector<BvhNode *> nodes; 2814 2815 // hack: should also expect interior nodes 2816 CollectNodes(mRoot, nodes); 2817 2818 vector<BvhNode *>::const_iterator oit, oit_end = nodes.end(); 2819 2820 int id = 0; 2821 2822 for (oit = nodes.begin(); oit != oit_end; ++ oit, ++ id) 2823 { 2824 (*oit)->SetId(id); 2825 } 2826 } 2827 2828 2829 } -
GTP/trunk/Lib/Vis/Preprocessing/src/BvHierarchy.h
r2003 r2093 562 562 void CollectLeaves(BvhNode *root, vector<BvhLeaf *> &leaves) const; 563 563 564 /** Returns vector of leaves. 565 */ 566 void CollectNodes(BvhNode *root, vector<BvhNode *> &nodes) const; 567 564 568 /** Returns bounding box of the whole tree (= bbox of root node) 565 569 */ … … 924 928 bool InitialTerminationCriteriaMet(const BvhTraversalData &tData) const; 925 929 930 /** Sets the bvh node ids. 931 */ 932 void SetUniqueNodeIds(); 926 933 927 934 protected: -
GTP/trunk/Lib/Vis/Preprocessing/src/HierarchyManager.cpp
r2073 r2093 391 391 cout << "finished" << endl; 392 392 } 393 394 if (mObjectSpaceSubdivisionType == BV_BASED_OBJ_SUBDIV) 395 { 396 mBvHierarchy->SetUniqueNodeIds(); 397 } 393 398 } 394 399 … … 1662 1667 } 1663 1668 } 1669 else if (mObjectSpaceSubdivisionType == BV_BASED_OBJ_SUBDIV) 1670 { 1671 // export bounding boxes 1672 vector<BvhNode *> nodes; 1673 1674 // hack: should also expect interior nodes 1675 mBvHierarchy->CollectNodes(mBvHierarchy->GetRoot(), nodes); 1676 1677 vector<BvhNode *>::const_iterator oit, oit_end = nodes.end(); 1678 1679 for (oit = nodes.begin(); oit != oit_end; ++ oit) 1680 { 1681 const AxisAlignedBox3 box = (*oit)->GetBox(); 1682 const int id = (*oit)->GetId(); 1683 1684 stream << "<BoundingBox" << " id=\"" << (*oit)->GetId() << "\"" 1685 << " min=\"" << box.Min().x << " " << box.Min().y << " " << box.Min().z << "\"" 1686 << " max=\"" << box.Max().x << " " << box.Max().y << " " << box.Max().z << "\" />" << endl; 1687 } 1688 } 1664 1689 else 1665 1690 { -
GTP/trunk/Lib/Vis/Preprocessing/src/TraversalTree.cpp
r2073 r2093 24 24 25 25 26 TraversalNode::TraversalNode(TraversalInterior *parent):mParent(parent), mMailbox(0), mIntersectable(NULL) 27 28 { 29 if (parent) 30 mDepth = parent->mDepth+1; 31 else 32 mDepth = 0; 26 TraversalNode::TraversalNode(TraversalInterior *parent): 27 mParent(parent), mMailbox(0) 28 { 29 } 30 31 32 TraversalInterior::TraversalInterior(TraversalInterior *parent): 33 TraversalNode(parent), mBack(NULL), mFront(NULL) 34 { 33 35 } 34 36 … … 42 44 43 45 46 bool TraversalInterior::IsLeaf() const 47 { 48 return false; 49 } 50 51 52 void TraversalInterior::SetupChildLinks(TraversalNode *b, TraversalNode *f) 53 { 54 mBack = b; 55 mFront = f; 56 57 b->mParent = f->mParent = this; 58 } 59 60 61 void TraversalInterior::ReplaceChildLink(TraversalNode *oldChild, TraversalNode *newChild) 62 { 63 if (mBack == oldChild) 64 mBack = newChild; 65 else 66 mFront = newChild; 67 } 68 69 70 TraversalLeaf::TraversalLeaf(TraversalInterior *parent, const int objects): 71 TraversalNode(parent) 72 { 73 mObjects.reserve(objects); 74 } 75 76 77 bool TraversalLeaf::IsLeaf() const 78 { 79 return true; 80 } 81 82 44 83 TraversalLeaf::~TraversalLeaf() 45 84 { 46 DEL_PTR(mViewCell);47 85 } 48 86 49 87 50 88 TraversalTree::TraversalTree() 51 { 52 53 54 mRoot = new TraversalLeaf(NULL, 0); 55 Environment::GetSingleton()->GetIntValue("TraversalTree.Termination.maxNodes", mTermMaxNodes); 56 Environment::GetSingleton()->GetIntValue("TraversalTree.Termination.maxDepth", mTermMaxDepth); 57 Environment::GetSingleton()->GetIntValue("TraversalTree.Termination.minCost", mTermMinCost); 58 Environment::GetSingleton()->GetFloatValue("TraversalTree.Termination.maxCostRatio", mMaxCostRatio); 59 Environment::GetSingleton()->GetFloatValue("TraversalTree.Termination.ct_div_ci", mCt_div_ci); 60 Environment::GetSingleton()->GetFloatValue("TraversalTree.splitBorder", mSplitBorder); 61 62 Environment::GetSingleton()->GetBoolValue("TraversalTree.sahUseFaces", mSahUseFaces); 63 64 char splitType[64]; 65 Environment::GetSingleton()->GetStringValue("TraversalTree.splitMethod", splitType); 66 67 mSplitMethod = SPLIT_SPATIAL_MEDIAN; 68 if (strcmp(splitType, "spatialMedian") == 0) 69 mSplitMethod = SPLIT_SPATIAL_MEDIAN; 70 else 71 if (strcmp(splitType, "objectMedian") == 0) 72 mSplitMethod = SPLIT_OBJECT_MEDIAN; 73 else 74 if (strcmp(splitType, "SAH") == 0) 75 mSplitMethod = SPLIT_SAH; 76 else { 77 cerr<<"Wrong kd split type "<<splitType<<endl; 78 exit(1); 79 } 80 splitCandidates = NULL; 89 { 90 mRoot = new TraversalLeaf(NULL, 0); 91 92 Environment::GetSingleton()->GetIntValue("TraversalTree.Termination.maxNodes", mTermMaxNodes); 93 Environment::GetSingleton()->GetIntValue("TraversalTree.Termination.maxDepth", mTermMaxDepth); 94 Environment::GetSingleton()->GetIntValue("TraversalTree.Termination.minCost", mTermMinCost); 95 Environment::GetSingleton()->GetFloatValue("TraversalTree.Termination.maxCostRatio", mMaxCostRatio); 96 Environment::GetSingleton()->GetFloatValue("TraversalTree.Termination.ct_div_ci", mCt_div_ci); 97 Environment::GetSingleton()->GetFloatValue("TraversalTree.splitBorder", mSplitBorder); 98 99 Environment::GetSingleton()->GetBoolValue("TraversalTree.sahUseFaces", mSahUseFaces); 100 101 char splitType[64]; 102 Environment::GetSingleton()->GetStringValue("TraversalTree.splitMethod", splitType); 103 104 mSplitMethod = SPLIT_SPATIAL_MEDIAN; 105 if (strcmp(splitType, "spatialMedian") == 0) 106 { 107 mSplitMethod = SPLIT_SPATIAL_MEDIAN; 108 } 109 else 110 { 111 if (strcmp(splitType, "objectMedian") == 0) 112 { 113 mSplitMethod = SPLIT_OBJECT_MEDIAN; 114 } 115 else 116 { 117 if (strcmp(splitType, "SAH") == 0) 118 { 119 mSplitMethod = SPLIT_SAH; 120 } 121 else 122 { 123 cerr<<"Wrong kd split type "<<splitType<<endl; 124 exit(1); 125 } 126 127 splitCandidates = NULL; 128 } 129 } 81 130 } 82 131 … … 85 134 { 86 135 DEL_PTR(mRoot); 87 88 CLEAR_CONTAINER(mKdIntersectables);89 136 } 90 137 … … 94 141 { 95 142 96 if (!splitCandidates) 97 splitCandidates = new vector<SortableEntry *>; 98 99 // first construct a leaf that will get subdivide 100 TraversalLeaf *leaf = (TraversalLeaf *) mRoot; 101 102 mStat.nodes = 1; 103 104 mBox.Initialize(); 105 ObjectContainer::const_iterator mi; 106 for ( mi = leaf->mObjects.begin(); 107 mi != leaf->mObjects.end(); 108 mi++) { 109 // cout<<(*mi)->GetBox()<<endl; 110 mBox.Include((*mi)->GetBox()); 111 } 112 113 cout <<"TraversalTree Root Box:"<<mBox<<endl; 114 mRoot = Subdivide(TraversalData(leaf, mBox, 0)); 115 116 // remove the allocated array 117 CLEAR_CONTAINER(*splitCandidates); 118 delete splitCandidates; 119 120 float area = GetBox().SurfaceArea()*KD_PVS_AREA; 121 122 SetPvsTerminationNodes(area); 123 124 return true; 125 } 126 127 TraversalNode * 128 TraversalTree::Subdivide(const TraversalData &tdata) 129 { 130 131 TraversalNode *result = NULL; 132 133 priority_queue<TraversalData> tStack; 134 // stack<STraversalData> tStack; 135 136 tStack.push(tdata); 137 AxisAlignedBox3 backBox, frontBox; 138 139 while (!tStack.empty()) { 140 // cout<<mStat.Nodes()<<" "<<mTermMaxNodes<<endl; 141 if (mStat.Nodes() > mTermMaxNodes) { 142 // if ( GetMemUsage() > maxMemory ) { 143 // count statistics on unprocessed leafs 144 while (!tStack.empty()) { 145 EvaluateLeafStats(tStack.top()); 143 if (!splitCandidates) 144 { 145 splitCandidates = new vector<SortableEntry *>; 146 } 147 148 // first construct a leaf that will get subdivide 149 TraversalLeaf *leaf = static_cast<TraversalLeaf *>(mRoot); 150 151 mStat.nodes = 1; 152 153 mBox.Initialize(); 154 ObjectContainer::const_iterator mi; 155 for ( mi = leaf->mObjects.begin(); mi != leaf->mObjects.end(); ++ mi) 156 { 157 // cout<<(*mi)->GetBox()<<endl; 158 mBox.Include((*mi)->GetBox()); 159 } 160 161 cout << "TraversalTree Root Box:" << mBox << endl; 162 mRoot = Subdivide(TraversalData(leaf, mBox, 0)); 163 164 // remove the allocated array 165 CLEAR_CONTAINER(*splitCandidates); 166 delete splitCandidates; 167 168 return true; 169 } 170 171 172 TraversalNode *TraversalTree::Subdivide(const TraversalData &tdata) 173 { 174 TraversalNode *result = NULL; 175 176 //priority_queue<TraversalData> tStack; 177 stack<TraversalData> tStack; 178 179 tStack.push(tdata); 180 AxisAlignedBox3 backBox, frontBox; 181 182 while (!tStack.empty()) 183 { 184 // cout<<mStat.Nodes() << " " << mTermMaxNodes << endl; 185 if (mStat.Nodes() > mTermMaxNodes) 186 { 187 while (!tStack.empty()) 188 { 189 EvaluateLeafStats(tStack.top()); 190 tStack.pop(); 191 } 192 break; 193 } 194 195 TraversalData data = tStack.top(); 146 196 tStack.pop(); 147 } 148 break; 149 } 150 151 152 TraversalData data = tStack.top(); 153 tStack.pop(); 154 155 TraversalNode *node = SubdivideNode((TraversalLeaf *) data.mNode, 156 data.mBox, 157 backBox, 158 frontBox 159 ); 160 161 if (result == NULL) 162 result = node; 163 164 if (!node->IsLeaf()) { 165 166 TraversalInterior *interior = (TraversalInterior *) node; 167 // push the children on the stack 168 tStack.push(TraversalData(interior->mBack, backBox, data.mDepth+1)); 169 tStack.push(TraversalData(interior->mFront, frontBox, data.mDepth+1)); 170 171 } else { 172 EvaluateLeafStats(data); 173 } 174 } 175 176 return result; 177 178 } 179 180 181 bool 182 TraversalTree::TerminationCriteriaMet(const TraversalLeaf *leaf) 197 198 TraversalLeaf *tLeaf = static_cast<TraversalLeaf *> (data.mNode); 199 TraversalNode *node = SubdivideNode(tLeaf, 200 data.mBox, 201 backBox, 202 frontBox); 203 204 if (result == NULL) 205 result = node; 206 207 if (!node->IsLeaf()) 208 { 209 TraversalInterior *interior = static_cast<TraversalInterior *>(node); 210 211 // push the children on the stack 212 tStack.push(TraversalData(interior->mBack, backBox, data.mDepth + 1)); 213 tStack.push(TraversalData(interior->mFront, frontBox, data.mDepth + 1)); 214 215 } 216 else 217 { 218 EvaluateLeafStats(data); 219 } 220 } 221 222 return result; 223 } 224 225 226 bool TraversalTree::TerminationCriteriaMet(const TraversalLeaf *leaf) 183 227 { 184 228 const bool criteriaMet = 185 229 ((int)leaf->mObjects.size() <= mTermMinCost) || 186 187 230 (leaf->mDepth >= mTermMaxDepth); 231 188 232 if (criteriaMet) 189 cerr<< "\n OBJECTS="<<leaf->mObjects.size()<<endl;233 cerr<< "\n OBJECTS=" << (int)leaf->mObjects.size() << endl; 190 234 191 235 return criteriaMet; … … 193 237 194 238 195 int 196 TraversalTree::SelectPlane(TraversalLeaf *leaf, 197 const AxisAlignedBox3 &box, 198 float &position 199 ) 200 { 201 int axis = -1; 202 203 switch (mSplitMethod) 204 { 205 case SPLIT_SPATIAL_MEDIAN: { 206 axis = box.Size().DrivingAxis(); 207 position = (box.Min()[axis] + box.Max()[axis])*0.5f; 208 break; 209 } 210 case SPLIT_SAH: { 211 int objectsBack, objectsFront; 212 float costRatio; 213 bool mOnlyDrivingAxis = true; 214 215 if (mOnlyDrivingAxis) { 216 axis = box.Size().DrivingAxis(); 217 costRatio = BestCostRatio(leaf, 218 box, 219 axis, 220 position, 221 objectsBack, 222 objectsFront); 223 } else { 224 costRatio = MAX_FLOAT; 225 for (int i=0; i < 3; i++) { 226 float p; 227 float r = BestCostRatio(leaf, 228 box, 229 i, 230 p, 231 objectsBack, 232 objectsFront); 233 if (r < costRatio) { 234 costRatio = r; 235 axis = i; 236 position = p; 237 } 238 } 239 } 240 241 if (costRatio > mMaxCostRatio) { 242 //cout<<"Too big cost ratio "<<costRatio<<endl; 243 axis = -1; 244 } 245 break; 246 } 247 248 } 249 return axis; 250 } 239 int TraversalTree::SelectPlane(TraversalLeaf *leaf, 240 const AxisAlignedBox3 &box, 241 float &position) 242 { 243 int axis = -1; 244 245 switch (mSplitMethod) 246 { 247 case SPLIT_SPATIAL_MEDIAN: 248 { 249 axis = box.Size().DrivingAxis(); 250 position = (box.Min()[axis] + box.Max()[axis])*0.5f; 251 break; 252 } 253 case SPLIT_SAH: 254 { 255 int objectsBack, objectsFront; 256 float costRatio; 257 bool mOnlyDrivingAxis = true; 258 259 if (mOnlyDrivingAxis) 260 { 261 axis = box.Size().DrivingAxis(); 262 costRatio = BestCostRatio(leaf, 263 box, 264 axis, 265 position, 266 objectsBack, 267 objectsFront); 268 } 269 else 270 { 271 costRatio = MAX_FLOAT; 272 273 for (int i=0; i < 3; i++) 274 { 275 float p; 276 float r = BestCostRatio(leaf, 277 box, 278 i, 279 p, 280 objectsBack, 281 objectsFront); 282 283 if (r < costRatio) 284 { 285 costRatio = r; 286 axis = i; 287 position = p; 288 } 289 } 290 } 291 292 if (costRatio > mMaxCostRatio) 293 { 294 //cout<<"Too big cost ratio "<<costRatio<<endl; 295 axis = -1; 296 } 297 break; 298 } 299 } 300 301 return axis; 302 } 303 251 304 252 305 TraversalNode *TraversalTree::SubdivideNode(TraversalLeaf *leaf, 253 306 const AxisAlignedBox3 &box, 254 307 AxisAlignedBox3 &backBBox, 255 AxisAlignedBox3 &frontBBox 256 ) 308 AxisAlignedBox3 &frontBBox) 257 309 { 258 310 … … 301 353 302 354 if (box.Min(axis) < position ) 303 objectsBack++;355 ++ objectsBack; 304 356 } 305 357 … … 310 362 311 363 // replace a link from node's parent 312 if ( leaf->mParent ) 364 if (leaf->mParent) 365 { 313 366 leaf->mParent->ReplaceChildLink(leaf, node); 367 } 314 368 315 369 // and setup child links … … 321 375 AxisAlignedBox3 box = (*mi)->GetBox(); 322 376 323 // matt: no more ref324 // for handling multiple objects: keep track of references325 //if (leaf->IsRoot())326 // (*mi)->mReferences = 1; // initialise references at root327 328 // matt: no more ref329 //-- (*mi)->mReferences; // remove parent ref330 331 332 377 if (box.Max(axis) >= position ) 333 378 { 334 379 front->mObjects.push_back(*mi); 335 //++ (*mi)->mReferences;336 380 } 337 381 … … 339 383 { 340 384 back->mObjects.push_back(*mi); 341 // matt: no more ref342 // ++ (*mi)->mReferences;343 385 } 344 386 … … 347 389 } 348 390 349 // store objects referenced in more than one leaf350 // for easy access351 ProcessMultipleRefs(back);352 ProcessMultipleRefs(front);353 354 391 delete leaf; 392 355 393 return node; 356 394 } 357 395 358 396 359 void 360 TraversalTreeStatistics::Print(ostream &app) const 361 { 362 app << "===== TraversalTree statistics ===============\n"; 363 364 app << "#N_NODES ( Number of nodes )\n" << nodes << "\n"; 365 366 app << "#N_LEAVES ( Number of leaves )\n" << Leaves() << "\n"; 367 368 app << "#N_SPLITS ( Number of splits in axes x y z dx dy dz)\n"; 369 for (int i=0; i<7; i++) 370 app << splits[i] <<" "; 371 app <<endl; 372 373 app << "#N_RAYREFS ( Number of rayRefs )\n" << 374 rayRefs << "\n"; 375 376 app << "#N_RAYRAYREFS ( Number of rayRefs / ray )\n" << 377 rayRefs/(double)rays << "\n"; 378 379 app << "#N_LEAFRAYREFS ( Number of rayRefs / leaf )\n" << 380 rayRefs/(double)Leaves() << "\n"; 381 382 app << "#N_MAXOBJECTREFS ( Max number of object refs / leaf )\n" << 383 maxObjectRefs << "\n"; 384 385 app << "#N_NONEMPTYRAYREFS ( Number of rayRefs in nonEmpty leaves / non empty leaf )\n" << 386 rayRefsNonZeroQuery/(double)(Leaves() - zeroQueryNodes) << "\n"; 387 388 app << "#N_LEAFDOMAINREFS ( Number of query domain Refs / leaf )\n" << 389 objectRefs/(double)Leaves() << "\n"; 390 391 // app << setprecision(4); 392 393 app << "#N_PEMPTYLEAVES ( Percentage of leaves with zero query domains )\n"<< 394 zeroQueryNodes*100/(double)Leaves()<<endl; 395 396 app << "#N_PMAXDEPTHLEAVES ( Percentage of leaves at maxdepth )\n"<< 397 maxDepthNodes*100/(double)Leaves()<<endl; 398 399 app << "#N_PMINCOSTLEAVES ( Percentage of leaves with minCost )\n"<< 400 minCostNodes*100/(double)Leaves()<<endl; 401 402 app << "#N_ADDED_RAYREFS (Number of dynamically added ray references )\n"<< 403 addedRayRefs<<endl; 404 405 app << "#N_REMOVED_RAYREFS (Number of dynamically removed ray references )\n"<< 406 removedRayRefs<<endl; 407 408 // app << setprecision(4); 409 410 // app << "#N_CTIME ( Construction time [s] )\n" 411 // << Time() << " \n"; 412 413 app << "===== END OF TraversalTree statistics ==========\n"; 414 415 } 416 417 418 419 void 420 TraversalTree::EvaluateLeafStats(const TraversalData &data) 397 void TraversalTreeStatistics::Print(ostream &app) const 398 { 399 app << "===== TraversalTree statistics ===============\n"; 400 401 app << "#N_NODES ( Number of nodes )\n" << nodes << "\n"; 402 403 app << "#N_LEAVES ( Number of leaves )\n" << Leaves() << "\n"; 404 405 app << "#N_SPLITS ( Number of splits in axes x y z dx dy dz)\n"; 406 for (int i=0; i<7; i++) 407 app << splits[i] <<" "; 408 app <<endl; 409 410 app << "#N_RAYREFS ( Number of rayRefs )\n" << 411 rayRefs << "\n"; 412 413 app << "#N_RAYRAYREFS ( Number of rayRefs / ray )\n" << 414 rayRefs/(double)rays << "\n"; 415 416 app << "#N_LEAFRAYREFS ( Number of rayRefs / leaf )\n" << 417 rayRefs/(double)Leaves() << "\n"; 418 419 app << "#N_MAXOBJECTREFS ( Max number of object refs / leaf )\n" << 420 maxObjectRefs << "\n"; 421 422 app << "#N_NONEMPTYRAYREFS ( Number of rayRefs in nonEmpty leaves / non empty leaf )\n" << 423 rayRefsNonZeroQuery/(double)(Leaves() - zeroQueryNodes) << "\n"; 424 425 app << "#N_LEAFDOMAINREFS ( Number of query domain Refs / leaf )\n" << 426 objectRefs/(double)Leaves() << "\n"; 427 428 // app << setprecision(4); 429 430 app << "#N_PEMPTYLEAVES ( Percentage of leaves with zero query domains )\n"<< 431 zeroQueryNodes*100/(double)Leaves()<<endl; 432 433 app << "#N_PMAXDEPTHLEAVES ( Percentage of leaves at maxdepth )\n"<< 434 maxDepthNodes*100/(double)Leaves()<<endl; 435 436 app << "#N_PMINCOSTLEAVES ( Percentage of leaves with minCost )\n"<< 437 minCostNodes*100/(double)Leaves()<<endl; 438 439 app << "#N_ADDED_RAYREFS (Number of dynamically added ray references )\n"<< 440 addedRayRefs<<endl; 441 442 app << "#N_REMOVED_RAYREFS (Number of dynamically removed ray references )\n"<< 443 removedRayRefs<<endl; 444 445 // app << setprecision(4); 446 447 // app << "#N_CTIME ( Construction time [s] )\n" 448 // << Time() << " \n"; 449 450 app << "===== END OF TraversalTree statistics ==========\n"; 451 452 } 453 454 455 void TraversalTree::EvaluateLeafStats(const TraversalData &data) 421 456 { 422 457 … … 439 474 440 475 void 441 TraversalTree::SortSubdivisionCandidates( 442 TraversalLeaf *node, 443 const int axis 444 ) 476 TraversalTree::SortSubdivisionCandidates(TraversalLeaf *node, 477 const int axis) 445 478 { 446 479 CLEAR_CONTAINER(*splitCandidates); … … 451 484 // creates a sorted split candidates array 452 485 if (splitCandidates->capacity() > 500000 && 453 requestedSize < (int)(splitCandidates->capacity()/10) ) { 454 delete splitCandidates; 455 splitCandidates = new vector<SortableEntry *>; 456 } 486 requestedSize < (int)(splitCandidates->capacity()/10) ) 487 { 488 delete splitCandidates; 489 splitCandidates = new vector<SortableEntry *>; 490 } 457 491 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 492 splitCandidates->reserve(requestedSize); 493 494 // insert all queries 495 for(ObjectContainer::const_iterator mi = node->mObjects.begin(); 496 mi != node->mObjects.end(); 497 mi++) 498 { 499 AxisAlignedBox3 box = (*mi)->GetBox(); 500 501 splitCandidates->push_back(new SortableEntry(SortableEntry::BOX_MIN, 502 box.Min(axis), 503 *mi) 504 ); 505 506 splitCandidates->push_back(new SortableEntry(SortableEntry::BOX_MAX, 507 box.Max(axis), 508 *mi) 509 ); 510 } 511 512 stable_sort(splitCandidates->begin(), splitCandidates->end(), iltS); 479 513 } 480 514 481 515 482 516 float 483 TraversalTree::BestCostRatio( 484 TraversalLeaf *node, 485 const AxisAlignedBox3 &box, 486 const int axis, 487 float &position, 488 int &objectsBack, 489 int &objectsFront 490 ) 517 TraversalTree::BestCostRatio(TraversalLeaf *node, 518 const AxisAlignedBox3 &box, 519 const int axis, 520 float &position, 521 int &objectsBack, 522 int &objectsFront 523 ) 491 524 { 492 525 … … 494 527 495 528 #if DEBUG_COST 496 497 498 499 500 501 nodeId++;502 503 504 505 506 507 508 509 costStream.open(filename);529 static int nodeId = -1; 530 char filename[256]; 531 532 static int lastAxis = 100; 533 if (axis <= lastAxis) 534 nodeId++; 535 536 lastAxis = axis; 537 538 sprintf(filename, "sah-cost%d-%d.log", nodeId, axis); 539 ofstream costStream; 540 541 if (nodeId < 100) 542 costStream.open(filename); 510 543 511 544 #endif 512 513 SortSubdivisionCandidates(node, axis); 514 515 // go through the lists, count the number of objects left and right 516 // and evaluate the following cost funcion: 517 // C = ct_div_ci + (ol + or)/queries 518 519 float totalIntersections = 0.0f; 520 vector<SortableEntry *>::const_iterator ci; 521 522 for(ci = splitCandidates->begin(); 523 ci < splitCandidates->end(); 524 ci++) 525 if ((*ci)->type == SortableEntry::BOX_MIN) { 526 totalIntersections += (*ci)->intersectable->IntersectionComplexity(); 527 } 528 529 float intersectionsLeft = 0; 530 float intersectionsRight = totalIntersections; 531 532 int objectsLeft = 0, objectsRight = (int)node->mObjects.size(); 533 534 float minBox = box.Min(axis); 535 float maxBox = box.Max(axis); 536 float boxArea = box.SurfaceArea(); 537 538 float minBand = minBox + mSplitBorder*(maxBox - minBox); 539 float maxBand = minBox + (1.0f - mSplitBorder)*(maxBox - minBox); 540 541 float minSum = 1e20f; 542 543 for(ci = splitCandidates->begin(); 544 ci < splitCandidates->end(); 545 ci++) { 546 switch ((*ci)->type) { 547 case SortableEntry::BOX_MIN: 548 objectsLeft++; 549 intersectionsLeft += (*ci)->intersectable->IntersectionComplexity(); 550 break; 551 case SortableEntry::BOX_MAX: 552 objectsRight--; 553 intersectionsRight -= (*ci)->intersectable->IntersectionComplexity(); 554 break; 555 } 556 557 if ((*ci)->value > minBand && (*ci)->value < maxBand) { 558 AxisAlignedBox3 lbox = box; 559 AxisAlignedBox3 rbox = box; 560 lbox.SetMax(axis, (*ci)->value); 561 rbox.SetMin(axis, (*ci)->value); 562 563 float sum; 564 if (mSahUseFaces) 565 sum = intersectionsLeft*lbox.SurfaceArea() + intersectionsRight*rbox.SurfaceArea(); 566 else 567 sum = objectsLeft*lbox.SurfaceArea() + objectsRight*rbox.SurfaceArea(); 568 569 // cout<<"pos="<<(*ci).value<<"\t q=("<<ql<<","<<qr<<")\t r=("<<rl<<","<<rr<<")"<<endl; 570 // cout<<"cost= "<<sum<<endl; 545 546 SortSubdivisionCandidates(node, axis); 547 548 // go through the lists, count the number of objects left and right 549 // and evaluate the following cost funcion: 550 // C = ct_div_ci + (ol + or)/queries 551 552 float totalIntersections = 0.0f; 553 vector<SortableEntry *>::const_iterator ci; 554 555 for(ci = splitCandidates->begin(); ci < splitCandidates->end(); ++ ci) 556 if ((*ci)->type == SortableEntry::BOX_MIN) 557 { 558 totalIntersections += (*ci)->intersectable->IntersectionComplexity(); 559 } 560 561 float intersectionsLeft = 0; 562 float intersectionsRight = totalIntersections; 563 564 int objectsLeft = 0, objectsRight = (int)node->mObjects.size(); 565 566 float minBox = box.Min(axis); 567 float maxBox = box.Max(axis); 568 float boxArea = box.SurfaceArea(); 569 570 float minBand = minBox + mSplitBorder*(maxBox - minBox); 571 float maxBand = minBox + (1.0f - mSplitBorder)*(maxBox - minBox); 572 573 float minSum = 1e20f; 574 575 for(ci = splitCandidates->begin(); ci < splitCandidates->end(); ++ ci) 576 { 577 switch ((*ci)->type) 578 { 579 case SortableEntry::BOX_MIN: 580 objectsLeft++; 581 intersectionsLeft += (*ci)->intersectable->IntersectionComplexity(); 582 break; 583 case SortableEntry::BOX_MAX: 584 objectsRight--; 585 intersectionsRight -= (*ci)->intersectable->IntersectionComplexity(); 586 break; 587 } 588 589 if ((*ci)->value > minBand && (*ci)->value < maxBand) 590 { 591 AxisAlignedBox3 lbox = box; 592 AxisAlignedBox3 rbox = box; 593 lbox.SetMax(axis, (*ci)->value); 594 rbox.SetMin(axis, (*ci)->value); 595 596 float sum; 597 598 if (mSahUseFaces) 599 sum = intersectionsLeft*lbox.SurfaceArea() + intersectionsRight*rbox.SurfaceArea(); 600 else 601 sum = objectsLeft*lbox.SurfaceArea() + objectsRight*rbox.SurfaceArea(); 602 603 // cout<<"pos="<<(*ci).value<<"\t q=("<<ql<<","<<qr<<")\t r=("<<rl<<","<<rr<<")"<<endl; 604 // cout<<"cost= "<<sum<<endl; 571 605 572 606 #if DEBUG_COST 573 if (nodeId < 100) { 574 float oldCost = mSahUseFaces ? totalIntersections : node->mObjects.size(); 575 float newCost = mCt_div_ci + sum/boxArea; 576 float ratio = newCost/oldCost; 577 costStream<<(*ci)->value<<" "<<ratio<<endl; 578 } 607 if (nodeId < 100) 608 { 609 float oldCost = mSahUseFaces ? totalIntersections : node->mObjects.size(); 610 float newCost = mCt_div_ci + sum/boxArea; 611 float ratio = newCost/oldCost; 612 costStream<<(*ci)->value<<" "<<ratio<<endl; 613 } 579 614 #endif 580 581 if (sum < minSum) { 582 minSum = sum; 583 position = (*ci)->value; 584 585 objectsBack = objectsLeft; 586 objectsFront = objectsRight; 587 } 588 } 589 } 590 591 float oldCost = mSahUseFaces ? totalIntersections : node->mObjects.size(); 592 float newCost = mCt_div_ci + minSum/boxArea; 593 float ratio = newCost/oldCost; 594 615 616 if (sum < minSum) 617 { 618 minSum = sum; 619 position = (*ci)->value; 620 621 objectsBack = objectsLeft; 622 objectsFront = objectsRight; 623 } 624 } 625 } 626 627 const float oldCost = mSahUseFaces ? totalIntersections : node->mObjects.size(); 628 const float newCost = mCt_div_ci + minSum/boxArea; 629 const float ratio = newCost/oldCost; 630 595 631 #if 0 596 597 598 632 cout<<"===================="<<endl; 633 cout<<"costRatio="<<ratio<<" pos="<<position<<" t="<<(position - minBox)/(maxBox - minBox) 634 <<"\t o=("<<objectsBack<<","<<objectsFront<<")"<<endl; 599 635 #endif 600 636 return ratio; 601 637 } 602 638 603 639 604 640 int TraversalTree::CastLineSegment(const Vector3 &origin, 605 const Vector3 &termination, 606 ViewCellContainer &viewcells) 641 const Vector3 &termination, 642 ViewCellContainer &viewcells, 643 const bool useMailboxing) 607 644 { 608 645 int hits = 0; … … 611 648 const Vector3 dir = termination - origin; 612 649 613 stack<RayTraversalData> tStack; 614 615 Intersectable::NewMail(); 616 617 //maxt += Limits::Threshold; 650 stack<LineTraversalData> tStack; 618 651 619 652 Vector3 entp = origin; … … 641 674 // cases N1,N2,N3,P5,Z2,Z3 642 675 continue; 643 } 644 else 676 } else 645 677 { 646 678 // case N4 … … 667 699 // $$ modification 3.5.2004 - hints from Kamil Ghais 668 700 // case N4 or P4 669 float tdist = (position - origin[axis]) / dir[axis]; 670 //tStack.push(RayTraversalData(farChild, extp, maxt)); //TODO 701 const float tdist = (position - origin[axis]) / dir[axis]; 702 tStack.push(LineTraversalData(farChild, extp, maxt)); //TODO 703 671 704 extp = origin + dir * tdist; 672 705 maxt = tdist; … … 676 709 // compute intersection with all objects in this leaf 677 710 TraversalLeaf *leaf = static_cast<TraversalLeaf *>(node); 678 679 // add view cell to intersections 680 ViewCell *vc = leaf->mViewCell; 681 682 if (!vc->Mailed()) 683 { 684 vc->Mail(); 685 viewcells.push_back(vc); 711 ViewCell *viewCell = NULL; 712 713 #if TODO 714 if (0) 715 viewCell = mViewCellsTree->GetActiveViewCell(leaf->GetViewCell()); 716 else 717 viewCell = leaf->mViewCell; 718 #endif 719 // don't have to mail if each view cell belongs to exactly one leaf 720 if (!useMailboxing || !viewCell->Mailed()) 721 { 722 if (useMailboxing) 723 viewCell->Mail(); 724 725 viewcells.push_back(viewCell); 686 726 ++ hits; 687 727 } … … 694 734 mint = maxt; 695 735 696 RayTraversalData &s = tStack.top();736 LineTraversalData &s = tStack.top(); 697 737 node = s.mNode; 698 738 extp = s.mExitPoint; 699 739 maxt = s.mMaxT; 740 700 741 tStack.pop(); 701 742 } … … 706 747 707 748 708 void 709 TraversalTree::CollectLeaves(vector<TraversalLeaf *> &leaves) 710 { 711 stack<TraversalNode *> nodeStack; 712 nodeStack.push(mRoot); 713 714 while (!nodeStack.empty()) { 715 TraversalNode *node = nodeStack.top(); 716 nodeStack.pop(); 717 if (node->IsLeaf()) { 718 TraversalLeaf *leaf = (TraversalLeaf *)node; 719 leaves.push_back(leaf); 720 } else { 721 TraversalInterior *interior = (TraversalInterior *)node; 722 nodeStack.push(interior->mBack); 723 nodeStack.push(interior->mFront); 724 } 725 } 726 } 727 728 729 } 749 void TraversalTree::CollectLeaves(vector<TraversalLeaf *> &leaves) 750 { 751 stack<TraversalNode *> nodeStack; 752 nodeStack.push(mRoot); 753 754 while (!nodeStack.empty()) 755 { 756 TraversalNode *node = nodeStack.top(); 757 nodeStack.pop(); 758 759 if (node->IsLeaf()) 760 { 761 TraversalLeaf *leaf = (TraversalLeaf *)node; 762 leaves.push_back(leaf); 763 } 764 else 765 { 766 TraversalInterior *interior = (TraversalInterior *)node; 767 nodeStack.push(interior->mBack); 768 nodeStack.push(interior->mFront); 769 } 770 } 771 } 772 773 774 AxisAlignedBox3 TraversalTree::GetBox(const TraversalNode *node) const 775 { 776 TraversalInterior *parent = node->mParent; 777 778 if (parent == NULL) 779 return mBox; 780 781 if (!node->IsLeaf()) 782 return ((TraversalInterior *)node)->mBox; 783 784 AxisAlignedBox3 box(parent->mBox); 785 786 if (parent->mFront == node) 787 box.SetMin(parent->mAxis, parent->mPosition); 788 else 789 box.SetMax(parent->mAxis, parent->mPosition); 790 return box; 791 } 792 793 } -
GTP/trunk/Lib/Vis/Preprocessing/src/TraversalTree.h
r2073 r2093 61 61 62 62 // Constructor 63 TraversalTreeStatistics() { 64 Reset(); 63 TraversalTreeStatistics() 64 { 65 Reset(); 65 66 } 66 67 … … 69 70 int Leaves() const { return (nodes / 2) + 1; } 70 71 71 void Reset() { 72 nodes = 0; 73 for (int i=0; i<7; i++) 74 splits[i] = 0; 75 rays = queryDomains = 0; 76 rayRefs = rayRefsNonZeroQuery = objectRefs = 0; 77 zeroQueryNodes = 0; 78 maxDepthNodes = 0; 79 minCostNodes = 0; 80 maxObjectRefs = 0; 81 addedRayRefs = removedRayRefs = 0; 72 void Reset() 73 { 74 nodes = 0; 75 76 for (int i=0; i<7; i++) 77 splits[i] = 0; 78 79 rays = queryDomains = 0; 80 rayRefs = rayRefsNonZeroQuery = objectRefs = 0; 81 zeroQueryNodes = 0; 82 maxDepthNodes = 0; 83 minCostNodes = 0; 84 maxObjectRefs = 0; 85 addedRayRefs = removedRayRefs = 0; 82 86 } 83 87 84 void 85 Print(ostream &app) const; 86 87 friend ostream &operator<<(ostream &s, const TraversalTreeStatistics &stat){88 89 88 void Print(ostream &app) const; 89 90 friend ostream &operator<<(ostream &s, const TraversalTreeStatistics &stat) 91 { 92 stat.Print(s); 93 return s; 90 94 } 91 95 … … 94 98 95 99 class TraversalInterior; 96 /** Abstract class for kd-tree node */ 97 class TraversalNode { 100 101 /** Abstract class for kd-tree node 102 */ 103 class TraversalNode 104 { 98 105 public: 99 100 static int sMailId; 101 static int sReservedMailboxes; 102 int mMailbox; 103 104 KdIntersectable *mIntersectable; 105 106 void Mail() { mMailbox = sMailId; } 107 //static void NewMail() { sMailId ++; } 108 bool Mailed() const { return mMailbox == sMailId; } 109 110 static void NewMail(const int reserve = 1) { 106 107 virtual ~TraversalNode(){}; 108 109 TraversalNode(TraversalInterior *parent); 110 /** Determines whether this node is a leaf or interior node 111 @return true if leaf 112 */ 113 virtual bool IsLeaf() const = 0; 114 115 /** Determines whether this node is the root of the tree 116 @return true if root 117 */ 118 virtual bool IsRoot() const 119 { 120 return mParent == NULL; 121 } 122 123 /** Parent of the node - the parent is a little overhead for maintanance of the tree, 124 but allows various optimizations of tree traversal algorithms 125 */ 126 TraversalInterior *mParent; 127 128 129 /////////////////// 130 // mailing stuff 131 132 public: 133 134 void Mail() 135 { 136 mMailbox = sMailId; 137 } 138 139 bool Mailed() const 140 { 141 return mMailbox == sMailId; 142 } 143 144 static void NewMail(const int reserve = 1) 145 { 111 146 sMailId += sReservedMailboxes; 112 147 sReservedMailboxes = reserve; 113 148 } 114 void Mail(const int mailbox) { mMailbox = sMailId + mailbox; } 115 bool Mailed(const int mailbox) const { return mMailbox == sMailId + mailbox; } 116 117 virtual ~TraversalNode(){}; 118 TraversalNode(TraversalInterior *parent); 119 120 /** Determines whether this node is a leaf or interior node 121 @return true if leaf 122 */ 123 virtual bool IsLeaf() const = 0; 124 125 /** Determines whether this node is the root of the tree 126 @return true if root 127 */ 128 virtual bool IsRoot() const { 129 return mParent == NULL; 130 } 131 132 /** Parent of the node - the parent is a little overhead for maintanance of the tree, 133 but allows various optimizations of tree traversal algorithms */ 134 TraversalInterior *mParent; 135 short mDepth; 136 short mPvsTermination; 149 150 void Mail(const int mailbox) 151 { 152 mMailbox = sMailId + mailbox; 153 } 154 155 156 bool Mailed(const int mailbox) const 157 { 158 return mMailbox == sMailId + mailbox; 159 } 160 161 int mMailbox; 162 163 static int sMailId; 164 static int sReservedMailboxes; 137 165 }; 138 166 139 /** Implementation of the kd-tree interior node */ 140 class TraversalInterior : public TraversalNode { 141 167 168 /** Implementation of the kd-tree interior node 169 */ 170 class TraversalInterior : public TraversalNode 171 { 142 172 public: 143 144 TraversalInterior(TraversalInterior *parent):TraversalNode(parent), mBack(NULL), mFront(NULL) {} 145 146 ~TraversalInterior(); 147 148 /** \sa TraversalNode::IsLeaf() */ 149 virtual bool IsLeaf() const { return false; } 150 151 /** splitting axis */ 152 int mAxis; 153 /** splitting position, absolute position within the bounding box of this node */ 154 float mPosition; 155 /** bounding box of interior node */ 156 AxisAlignedBox3 mBox; 157 158 /** back node */ 159 TraversalNode *mBack; 160 /** front node */ 161 TraversalNode *mFront; 162 163 void SetupChildLinks(TraversalNode *b, TraversalNode *f) { 164 mBack = b; 165 mFront = f; 166 b->mParent = f->mParent = this; 167 } 168 169 void ReplaceChildLink(TraversalNode *oldChild, TraversalNode *newChild) { 170 if (mBack == oldChild) 171 mBack = newChild; 172 else 173 mFront = newChild; 174 } 175 176 173 174 TraversalInterior(TraversalInterior *parent); 175 ~TraversalInterior(); 176 177 /** \sa TraversalNode::IsLeaf() 178 */ 179 bool IsLeaf() const; 180 181 void SetupChildLinks(TraversalNode *b, TraversalNode *f); 182 183 void ReplaceChildLink(TraversalNode *oldChild, TraversalNode *newChild); 184 185 186 ////////////////////////// 187 188 /// splitting axis 189 int mAxis; 190 /// splitting position, absolute position within the bounding box of this node. 191 float mPosition; 192 /// bounding box of interior node 193 AxisAlignedBox3 mBox; 194 195 /// back node 196 TraversalNode *mBack; 197 /// front node 198 TraversalNode *mFront; 177 199 }; 178 179 class SubdivisionCandidate; 180 181 /** Implementation of the kd-tree leaf node */ 182 class TraversalLeaf : public TraversalNode { 200 201 202 /** Implementation of the kd-tree leaf node 203 */ 204 class TraversalLeaf : public TraversalNode 205 { 183 206 public: 184 TraversalLeaf(TraversalInterior *parent, const int objects): 185 TraversalNode(parent), mViewCell(NULL) { 186 mObjects.reserve(objects); 187 } 188 189 void AddPassingRay(const Ray &ray, const int contributions) { 190 mPassingRays.AddRay(ray, contributions); 191 // Debug << "adding passing ray" << endl; 192 } 193 194 ~TraversalLeaf(); 195 196 void AddPassingRay2(const Ray &ray, 197 const int objects, 198 const int viewcells 199 ) { 200 mPassingRays.AddRay2(ray, objects, viewcells); 201 // Debug << "adding passing ray" << endl; 202 } 203 204 /** \sa TraversalNode::IsLeaf() */ 205 virtual bool IsLeaf() const { return true; } 206 207 208 /** pointers to occluders contained in this node */ 209 ObjectContainer mObjects; 210 211 /** Ray set description of the rays passing through this node */ 212 PassingRaySet mPassingRays; 213 214 /** PVS consisting of visible TraversalTree nodes */ 215 KdPvs mKdPvs; 216 217 /// pvs of view cells seeing this node. 218 SubdivisionCandidate *mSubdivisionCandidate; 219 220 /// pointer to view cell. 221 KdViewCell *mViewCell; 222 223 VssRayContainer mVssRays; 224 225 /// Objects that are referenced in more than one leaf. 226 ObjectContainer mMultipleObjects; 227 228 /// universal counter 229 int mCounter; 207 208 TraversalLeaf(TraversalInterior *parent, const int objects); 209 210 ~TraversalLeaf(); 211 212 /** \sa TraversalNode::IsLeaf() 213 */ 214 virtual bool IsLeaf() const; 215 216 ///////////////////////////////// 217 218 // pointers to view cells contained in this node 219 ObjectContainer mObjects; 220 221 short mDepth; 230 222 }; 231 223 232 224 233 /** TraversalTree for indexing scene entities - occluders/occludees/viewcells */ 234 class TraversalTree { 235 225 /** TraversalTree for indexing scene entities - occluders/occludees/viewcells 226 */ 227 class TraversalTree 228 { 229 236 230 protected: 237 struct TraversalData 238 { 239 TraversalNode *mNode; 240 AxisAlignedBox3 mBox;241 int mDepth;242 float mPriority;243 244 TraversalData() {} 245 246 TraversalData(TraversalNode *n, const float p): 247 mNode(n), mPriority(p) 248 {} 249 250 TraversalData(TraversalNode *n, 251 const AxisAlignedBox3 &b,252 const int d):253 mNode(n), mBox(b), mDepth(d) {} 254 255 256 bool operator<( 257 const TraversalData &b) const {258 TraversalLeaf *leafa = (TraversalLeaf *) mNode; 259 TraversalLeaf *leafb = (TraversalLeaf *) b.mNode;260 return 261 leafa->mObjects.size()*mBox.SurfaceArea()262 <263 leafb->mObjects.size()*b.mBox.SurfaceArea();264 } 265 266 267 // comparator for the 268 struct less_priority : public 269 binary_function<const TraversalData, const TraversalData, bool> { 270 271 bool operator()(const TraversalData a, const TraversalData b) { 272 return a.mPriority < b.mPriority;273 }274 275 };276 277 };278 279 231 232 struct TraversalData 233 { 234 TraversalNode *mNode; 235 AxisAlignedBox3 mBox; 236 int mDepth; 237 float mPriority; 238 239 TraversalData() {} 240 241 TraversalData(TraversalNode *n, const float p): 242 mNode(n), mPriority(p) 243 {} 244 245 TraversalData(TraversalNode *n, 246 const AxisAlignedBox3 &b, 247 const int d): 248 mNode(n), mBox(b), mDepth(d) {} 249 250 251 bool operator<(const TraversalData &b) const 252 { 253 TraversalLeaf *leafa = (TraversalLeaf *) mNode; 254 TraversalLeaf *leafb = (TraversalLeaf *) b.mNode; 255 256 return 257 leafa->mObjects.size() * mBox.SurfaceArea() 258 < 259 leafb->mObjects.size() * b.mBox.SurfaceArea(); 260 } 261 262 263 // comparator for the 264 struct less_priority: public 265 binary_function<const TraversalData, const TraversalData, bool> 266 { 267 bool operator()(const TraversalData a, const TraversalData b) 268 { 269 return a.mPriority < b.mPriority; 270 } 271 }; 272 }; 273 280 274 281 275 public: 282 276 283 enum {SPLIT_OBJECT_MEDIAN, 284 SPLIT_SPATIAL_MEDIAN, 285 SPLIT_SAH}; 286 287 TraversalTree(); 288 289 ~TraversalTree(); 290 291 /** Insert view cell into the tree */ 292 virtual void InsertViewCell(ViewCell *viewCell) { 293 // mRoot->mViewcells.push_back(viewCell); 294 } 295 296 virtual bool Construct(); 297 298 /** Check whether subdivision criteria are met for the given subtree. 299 If not subdivide the leafs of the subtree. The criteria are specified in 300 the environment as well as the subdivision method. By default surface area 301 heuristics is used. 302 303 @param subtree root of the subtree 304 305 @return true if subdivision was performed, false if subdivision criteria 306 were already met 307 */ 308 virtual TraversalNode *Subdivide(const TraversalData &tdata); 309 310 /** Get the root of the tree */ 311 TraversalNode *GetRoot() const { 312 return mRoot; 313 } 314 315 316 AxisAlignedBox3 GetBox() const { return mBox; } 317 318 int 319 CastRay( 320 Ray &ray 321 ); 322 323 324 int 325 CastBeam( 326 Beam &beam 327 ); 328 329 330 /** Casts line segment into tree. 331 @returns intersected view cells. 332 */ 333 int CastLineSegment(const Vector3 &origin, 334 const Vector3 &termination, 335 vector<ViewCell *> &viewcells); 336 337 338 const TraversalTreeStatistics &GetStatistics() const { 339 return mStat; 340 } 341 342 /** Returns or creates a new intersectable for use in a kd based pvs. 343 The OspTree is responsible for destruction of the intersectable. 344 */ 345 KdIntersectable *GetOrCreateKdIntersectable(TraversalNode *node); 346 347 348 void 349 SetPvsTerminationNodes( 350 const float maxArea); 351 352 TraversalNode * 353 GetPvsNode(const Vector3 &point) const; 354 355 356 void 357 CollectKdObjects(const AxisAlignedBox3 &box, 358 ObjectContainer &objects 359 ); 360 361 void 362 CollectObjects(TraversalNode *n, ObjectContainer &objects); 363 364 void 365 CollectObjects(const AxisAlignedBox3 &box, 366 ObjectContainer &objects); 367 368 void 369 CollectLeaves(vector<TraversalLeaf *> &leaves); 370 371 /** If the kd tree is used as view cell container, this 372 methods creates the view cells. 373 @returns the newly created view cells in a view cell container 374 */ 375 void 376 CreateAndCollectViewCells(ViewCellContainer &viewCells) const; 377 378 AxisAlignedBox3 GetBox(const TraversalNode *node) const { 379 TraversalInterior *parent = node->mParent; 380 if (parent == NULL) 381 return mBox; 382 383 if (!node->IsLeaf()) 384 return ((TraversalInterior *)node)->mBox; 385 386 AxisAlignedBox3 box(parent->mBox); 387 if (parent->mFront == node) 388 box.SetMin(parent->mAxis, parent->mPosition); 389 else 390 box.SetMax(parent->mAxis, parent->mPosition); 391 return box; 392 } 393 394 float GetSurfaceArea(const TraversalNode *node) const { 395 return GetBox(node).SurfaceArea(); 396 } 397 398 399 TraversalNode * 400 FindRandomNeighbor(TraversalNode *n, 401 bool onlyUnmailed 402 ); 403 404 TraversalNode * 405 TraversalTree::GetRandomLeaf(const Plane3 &halfspace); 406 407 TraversalNode * 408 GetRandomLeaf(const bool onlyUnmailed = false); 409 410 411 TraversalNode * 412 GetNode(const Vector3 &point, const float maxArea) const; 413 414 void GetBoxIntersections(const AxisAlignedBox3 &box, 415 vector<TraversalLeaf *> &leaves); 416 417 int 418 FindNeighbors(TraversalNode *n, 419 vector<TraversalNode *> &neighbors, 420 bool onlyUnmailed 421 ); 422 423 int 424 CollectLeafPvs(); 425 426 bool ExportBinTree(const string &filename); 427 bool LoadBinTree(const string &filename, ObjectContainer &object); 277 enum {SPLIT_OBJECT_MEDIAN, 278 SPLIT_SPATIAL_MEDIAN, 279 SPLIT_SAH}; 280 281 TraversalTree(); 282 283 ~TraversalTree(); 284 285 286 /** Casts line segment into tree. 287 @returns intersected view cells. 288 */ 289 int CastLineSegment(const Vector3 &origin, 290 const Vector3 &termination, 291 ViewCellContainer &viewcells, 292 const bool useMailboxing); 293 294 virtual bool Construct(); 295 296 /** Check whether subdivision criteria are met for the given subtree. 297 If not subdivide the leafs of the subtree. The criteria are specified in 298 the environment as well as the subdivision method. By default surface area 299 heuristics is used. 300 301 @param subtree root of the subtree 302 303 @return true if subdivision was performed, false if subdivision criteria 304 were already met 305 */ 306 virtual TraversalNode *Subdivide(const TraversalData &tdata); 307 308 /** Get the root of the tree 309 */ 310 TraversalNode *GetRoot() const 311 { 312 return mRoot; 313 } 314 315 AxisAlignedBox3 GetBox() const 316 { 317 return mBox; 318 } 319 320 const TraversalTreeStatistics &GetStatistics() const 321 { 322 return mStat; 323 } 324 325 void CollectObjects(TraversalNode *n, ObjectContainer &objects); 326 327 void CollectObjects(const AxisAlignedBox3 &box, ObjectContainer &objects); 328 329 void CollectLeaves(vector<TraversalLeaf *> &leaves); 330 331 float GetSurfaceArea(const TraversalNode *node) const 332 { 333 return GetBox(node).SurfaceArea(); 334 } 335 336 AxisAlignedBox3 GetBox(const TraversalNode *node) const; 337 428 338 429 339 protected: 430 340 431 struct RayData { 432 // pointer to the actual ray 433 Ray *ray; 434 435 // endpoints - do we need them? 436 #if USE_FIXEDPOINT_T 437 short tmin, tmax; 438 #else 439 float tmin, tmax; 341 /** Struct for traversing line segment. 342 */ 343 struct LineTraversalData 344 { 345 LineTraversalData () {} 346 LineTraversalData (TraversalNode *n, const Vector3 &p, const float maxt): 347 mNode(n), mExitPoint(p), mMaxT(maxt) {} 348 349 TraversalNode *mNode; 350 Vector3 mExitPoint; 351 float mMaxT; 352 }; 353 354 // -------------------------------------------------------------- 355 // For sorting objects 356 // -------------------------------------------------------------- 357 struct SortableEntry 358 { 359 enum 360 { 361 BOX_MIN, 362 BOX_MAX 363 }; 364 365 int type; 366 float value; 367 Intersectable *intersectable; 368 369 SortableEntry() {} 370 SortableEntry(const int t, const float v, Intersectable *i): 371 type(t), value(v), intersectable(i) 372 {} 373 374 bool operator<(const SortableEntry &b) const 375 { 376 return value < b.value; 377 } 378 }; 379 380 inline static bool iltS(SortableEntry *a, SortableEntry *b) 381 { 382 return a->value < b->value; 383 } 384 385 // reusable array of split candidates 386 vector<SortableEntry *> *splitCandidates; 387 388 float BestCostRatio(TraversalLeaf *node, 389 const AxisAlignedBox3 &box, 390 const int axis, 391 float &position, 392 int &objectsBack, 393 int &objectsFront); 394 395 void SortSubdivisionCandidates(TraversalLeaf *node, const int axis); 396 397 void EvaluateLeafStats(const TraversalData &data); 398 399 TraversalNode *SubdivideNode(TraversalLeaf *leaf, 400 const AxisAlignedBox3 &box, 401 AxisAlignedBox3 &backBBox, 402 AxisAlignedBox3 &frontBBox 403 ); 404 405 bool TerminationCriteriaMet(const TraversalLeaf *leaf); 406 407 int SelectPlane(TraversalLeaf *leaf, 408 const AxisAlignedBox3 &box, 409 float &position); 410 411 412 //////////////////////// 413 414 int mTermMaxNodes; 415 float mSplitBorder; 416 int mTermMaxDepth; 417 int mTermMinCost; 418 float mMaxCostRatio; 419 float mCt_div_ci; 420 int mSplitMethod; 421 bool mSahUseFaces; 422 423 /// root of the tree 424 TraversalNode *mRoot; 425 /// bounding box of the tree root 426 AxisAlignedBox3 mBox; 427 TraversalTreeStatistics mStat; 428 429 }; 430 431 432 } 433 440 434 #endif 441 442 RayData():ray(NULL) {}443 RayData(Ray *r):ray(r), tmin(0),444 445 #if USE_FIXEDPOINT_T446 #define FIXEDPOINT_ONE 0x7FFE447 // tmax(0xFFFF)448 tmax(FIXEDPOINT_ONE)449 #else450 tmax(1.0f)451 #endif452 {}453 454 RayData(Ray *r,455 const float _min,456 const float _max457 ):ray(r) {458 SetTMin(_min);459 SetTMax(_max);460 }461 462 RayData(Ray *r,463 const short _min,464 const float _max465 ):ray(r), tmin(_min) {466 SetTMax(_max);467 }468 469 RayData(Ray *r,470 const float _min,471 const short _max472 ):ray(r), tmax(_max) {473 SetTMin(_min);474 }475 476 friend bool operator<(const RayData &a, const RayData &b) {477 return a.ray < b.ray;478 }479 480 481 float ExtrapOrigin(const int axis) const {482 return ray->GetLoc(axis) + GetTMin()*ray->GetDir(axis);483 }484 485 float ExtrapTermination(const int axis) const {486 return ray->GetLoc(axis) + GetTMax()*ray->GetDir(axis);487 }488 489 #if USE_FIXEDPOINT_T490 float GetTMin () const { return tmin/(float)(FIXEDPOINT_ONE); }491 float GetTMax () const { return tmax/(float)(FIXEDPOINT_ONE); }492 493 void SetTMin (const float t) {494 tmin = (short) (t*(float)(FIXEDPOINT_ONE));495 }496 497 void SetTMax (const float t) {498 tmax = (short) (t*(float)(FIXEDPOINT_ONE));499 tmax++;500 // if (tmax!=0xFFFF)501 // tmax++;502 }503 #else504 float GetTMin () const { return tmin; }505 float GetTMax () const { return tmax; }506 507 void SetTMin (const float t) { tmin = t; }508 void SetTMax (const float t) { tmax = t; }509 #endif510 };511 512 struct RayTraversalData {513 TraversalNode *mNode;514 Vector3 mExitPoint;515 float mMaxT;516 517 RayTraversalData() {}518 RayTraversalData(TraversalNode *n,519 const Vector3 &p,520 const float maxt):521 mNode(n), mExitPoint(p), mMaxT(maxt) {}522 };523 524 // --------------------------------------------------------------525 // For sorting objects526 // --------------------------------------------------------------527 struct SortableEntry528 {529 enum {530 BOX_MIN,531 BOX_MAX532 };533 534 int type;535 float value;536 Intersectable *intersectable;537 538 SortableEntry() {}539 SortableEntry(const int t, const float v, Intersectable *i):type(t),540 value(v),541 intersectable(i) {}542 543 bool operator<(const SortableEntry &b) const {544 return value < b.value;545 }546 547 };548 549 inline static bool iltS(SortableEntry *a, SortableEntry *b)550 {551 return a->value < b->value;552 }553 554 // reusable array of split candidates555 vector<SortableEntry *> *splitCandidates;556 557 float558 BestCostRatio(559 TraversalLeaf *node,560 const AxisAlignedBox3 &box,561 const int axis,562 float &position,563 int &objectsBack,564 int &objectsFront565 );566 567 void568 SortSubdivisionCandidates(569 TraversalLeaf *node,570 const int axis571 );572 573 void574 EvaluateLeafStats(const TraversalData &data);575 576 TraversalNode *577 SubdivideNode(578 TraversalLeaf *leaf,579 const AxisAlignedBox3 &box,580 AxisAlignedBox3 &backBBox,581 AxisAlignedBox3 &frontBBox582 );583 584 bool585 TerminationCriteriaMet(const TraversalLeaf *leaf);586 587 int588 SelectPlane(TraversalLeaf *leaf,589 const AxisAlignedBox3 &box,590 float &position591 );592 593 /** does some post processing on the objects in the new child leaves.594 */595 void ProcessMultipleRefs(TraversalLeaf *leaf) const;596 597 void ExportBinLeaf(OUT_STREAM &stream, TraversalLeaf *leaf);598 void ExportBinInterior(OUT_STREAM &stream, TraversalInterior *interior);599 TraversalLeaf *ImportBinLeaf(IN_STREAM &stream, TraversalInterior *parent, const ObjectContainer &objects);600 TraversalInterior *ImportBinInterior(IN_STREAM &stream, TraversalInterior *parent);601 TraversalNode *LoadNextNode(IN_STREAM &stream, TraversalInterior *parent, const ObjectContainer &objects);602 603 /** Adds this objects to the kd leaf objects.604 @warning: Can corrupt the tree605 */606 void InsertObjects(TraversalNode *node, const ObjectContainer &objects);607 608 int mTermMaxNodes;609 float mSplitBorder;610 int mTermMaxDepth;611 int mTermMinCost;612 float mMaxCostRatio;613 float mCt_div_ci;614 int mSplitMethod;615 bool mSahUseFaces;616 /// root of the tree617 TraversalNode *mRoot;618 /// bounding box of the tree root619 AxisAlignedBox3 mBox;620 TraversalTreeStatistics mStat;621 public:622 /// stores the kd node intersectables used for pvs623 vector<KdIntersectable *> mKdIntersectables;624 625 };626 627 628 }629 630 #endif -
GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsManager.cpp
r2091 r2093 6604 6604 const AxisAlignedBox3 box = obj->GetBox(); 6605 6605 6606 // set kd id6606 // set kd node id 6607 6607 obj->SetId(id); 6608 6608 … … 6617 6617 } 6618 6618 } 6619 6619 6620 6620 6621 ////////////////////////// -
GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParser.cpp
r2071 r2093 64 64 static SAXParser::ValSchemes valScheme = SAXParser::Val_Auto; 65 65 66 // hack for loading bvh nodes 66 67 #define PVS_HACK 0 67 68 … … 582 583 // to sumof pdfs, i.e. its relative visibility 583 584 // temporarily set to 1.0f 584 //cout << "r";585 586 585 pvs.AddSample(*oit, 1.0f); 587 586 } … … 833 832 834 833 835 ViewCell *ViewCellsParseHandlers::GetOrCreateViewCell(const int id, const bool isLeaf)836 {/*837 ViewCellsMap::iterator vit = mViewCells.find(id);838 839 if (vit != mViewCells.end())840 {841 return (*vit).second;842 }843 else844 {845 ViewCell *vc;846 if (isLeaf)847 {848 vc = new ViewCellLeaf();849 }850 else851 {852 vc = new ViewCellInterior();853 }854 855 vc->SetId(id);856 mViewCells[id] = vc;857 return vc;858 }*/859 return NULL;860 }861 862 863 834 void ViewCellsParseHandlers::StartViewCell(AttributeList& attributes, const bool isLeaf) 864 835 { … … 867 838 const int len = attributes.getLength(); 868 839 float mergeCost; 869 //ObjectPvs pvs; 870 871 //viewCell = GetOrCreateViewCell(id, isLeaf); 872 840 873 841 if (isLeaf) 874 842 { … … 892 860 893 861 // create new view cell, otherwise use reference. 894 //viewCell = GetOrCreateViewCell(id, isLeaf);895 862 viewCell->SetId(id); 896 863 … … 1322 1289 if (PVS_HACK) 1323 1290 { 1324 if (1) // Temp matt: should HAVE right id 1325 { 1291 if (0) // Temp matt: should already have right id 1326 1292 leaf->SetId((int)mBvhLeaves.size()); 1327 }1293 1328 1294 mBvhLeaves.push_back(leaf); 1329 1330 //cout << "i";1331 1295 } 1332 1296 } -
GTP/trunk/Lib/Vis/Preprocessing/src/ViewCellsParserXerces.h
r2048 r2093 131 131 132 132 // Handlers for X3D 133 ViewCell *GetOrCreateViewCell(const int id, const bool isLeaf); 134 133 135 134 void StartBspLeaf(AttributeList& attributes); 136 135 void StartBspInterior(AttributeList& attributes);
Note: See TracChangeset
for help on using the changeset viewer.