#include <OSGTileLoadBalancer.h>
Public Types | |
| typedef std::vector < TileGeometryLoad > | TileGeometryLoadLstT |
| typedef std::map< UInt32, TileGeometryLoadLstT::iterator > | TileGeometryLoadMapT |
| typedef std::vector< Region > | ResultT |
| typedef std::vector< RenderNode > | RenderNodeLstT |
Public Member Functions | |
Constructors | |
| TileLoadBalancer (bool useFaceDistribution=false, bool cutBestDirection=true) | |
| TileLoadBalancer (const TileLoadBalancer &source) | |
Assignment | |
| TileLoadBalancer & | operator= (const TileLoadBalancer &source) |
Destructor | |
| virtual | ~TileLoadBalancer (void) |
Load balancing functions | |
| void | update (NodePtr node) |
| void | balance (ViewportPtr vp, bool shrink, ResultT &result) |
| void | addRenderNode (const RenderNode &rn, UInt32 id) |
| void | drawVolumes (WindowPtr win) |
| void | setRegionStatistics (ViewportPtr vp, ResultT &result) |
Protected Types | |
Types | |
| typedef std::vector< RegionLoad > | RegionLoadVecT |
Protected Member Functions | |
Member | |
| double | runFaceBench (GLuint dlist, UInt32 size, Real32 visible) |
| void | updateSubtree (NodePtr &node, TileGeometryLoadMapT &loadMap) |
| void | splitRegion (UInt32 rnFrom, UInt32 rnTo, RegionLoadVecT &visible, Int32 amin[2], Int32 amax[2], UInt32 depth, ResultT &result) |
| Real32 | findBestCut (const RenderNode &renderNodeA, const RenderNode &renderNodeB, RegionLoadVecT &visible, Int32 amin[2], Int32 amax[2], Int32 &bestAxis, Int32 &bestCut) |
| double | calcFaceRenderingCost (TileGeometryLoad *load, Int32 amin[2], Int32 amax[2]) |
Protected Attributes | |
Fields | |
| TileGeometryLoadLstT | _tileGeometryLoad |
| RenderNodeLstT | _renderNode |
| bool | _useFaceDistribution |
| bool | _cutBestDirection |
Friends | |
| class | RegionLoad |
Classes | |
| struct | Region |
| class | RegionLoad |
Definition at line 56 of file OSGTileLoadBalancer.h.
| typedef std::vector<TileGeometryLoad> osg::TileLoadBalancer::TileGeometryLoadLstT |
Definition at line 67 of file OSGTileLoadBalancer.h.
| typedef std::map<UInt32,TileGeometryLoadLstT::iterator> osg::TileLoadBalancer::TileGeometryLoadMapT |
Definition at line 68 of file OSGTileLoadBalancer.h.
| typedef std::vector<Region> osg::TileLoadBalancer::ResultT |
Definition at line 69 of file OSGTileLoadBalancer.h.
| typedef std::vector<RenderNode> osg::TileLoadBalancer::RenderNodeLstT |
Definition at line 70 of file OSGTileLoadBalancer.h.
typedef std::vector<RegionLoad> osg::TileLoadBalancer::RegionLoadVecT [protected] |
Definition at line 158 of file OSGTileLoadBalancer.h.
| TileLoadBalancer::TileLoadBalancer | ( | bool | useFaceDistribution = false, |
|
| bool | cutBestDirection = true | |||
| ) |
Constructor
Definition at line 75 of file OSGTileLoadBalancer.cpp.
00076 : 00077 _useFaceDistribution(useFaceDistribution), 00078 _cutBestDirection(cutBestDirection) 00079 { 00080 }
| TileLoadBalancer::TileLoadBalancer | ( | const TileLoadBalancer & | source | ) |
Copy Constructor
Definition at line 84 of file OSGTileLoadBalancer.cpp.
00084 : 00085 _tileGeometryLoad(source._tileGeometryLoad), 00086 _renderNode(source._renderNode), 00087 _useFaceDistribution(source._useFaceDistribution), 00088 _cutBestDirection(source._cutBestDirection) 00089 { 00090 }
| TileLoadBalancer::~TileLoadBalancer | ( | void | ) | [virtual] |
| TileLoadBalancer & TileLoadBalancer::operator= | ( | const TileLoadBalancer & | source | ) |
assignment
Definition at line 106 of file OSGTileLoadBalancer.cpp.
References _cutBestDirection, _renderNode, _tileGeometryLoad, and _useFaceDistribution.
00107 { 00108 if(this == &source) 00109 return *this; 00110 _tileGeometryLoad = source._tileGeometryLoad; 00111 _renderNode = source._renderNode; 00112 _useFaceDistribution = source._useFaceDistribution; 00113 _cutBestDirection = source._cutBestDirection; 00114 return *this; 00115 }
| void TileLoadBalancer::update | ( | NodePtr | node | ) |
Update the load balancing information
Definition at line 120 of file OSGTileLoadBalancer.cpp.
References _tileGeometryLoad, osg::TileGeometryLoad::isInvalid(), osg::NullFC, and updateSubtree().
Referenced by osg::SortFirstWindow::clientPreSync().
00121 { 00122 TileGeometryLoadMapT loadMap; 00123 00124 // collect old load objects 00125 for(TileGeometryLoadLstT::iterator gI=_tileGeometryLoad.begin();gI!=_tileGeometryLoad.end();++gI) 00126 { 00127 if(gI->getNode() != NullFC) 00128 loadMap[gI->getNode().getFieldContainerId()] = gI; 00129 else 00130 gI->setValid(false); 00131 } 00132 00133 updateSubtree(node,loadMap); 00134 00135 // mark unused load objects as invalid. 00136 for(TileGeometryLoadMapT::iterator mI=loadMap.begin();mI!=loadMap.end();++mI) 00137 mI->second->setValid(false); 00138 00139 // remove all invalid objects. 00140 _tileGeometryLoad.erase(std::remove_if(_tileGeometryLoad.begin(), _tileGeometryLoad.end(), 00141 std::mem_fun_ref(&TileGeometryLoad::isInvalid)), _tileGeometryLoad.end()); 00142 }
| void TileLoadBalancer::balance | ( | ViewportPtr | vp, | |
| bool | shrink, | |||
| ResultT & | result | |||
| ) |
load balance
| vp | current viewport | |
| shrink | shrink to max area of visible objects | |
| result | resulting regions |
Definition at line 151 of file OSGTileLoadBalancer.cpp.
References _renderNode, _tileGeometryLoad, RegionLoad, splitRegion(), osg::TileLoadBalancer::Region::x1, osg::TileLoadBalancer::Region::x2, osg::TileLoadBalancer::Region::y1, and osg::TileLoadBalancer::Region::y2.
Referenced by osg::SortFirstWindow::clientPreSync().
00154 { 00155 Matrix projection,viewing; 00156 RegionLoadVecT visible; 00157 RegionLoadVecT::iterator vi; 00158 Int32 width =vp->getPixelWidth(); 00159 Int32 height=vp->getPixelHeight(); 00160 Int32 wmin[2]={width,height}; 00161 Int32 wmax[2]={0 ,0 }; 00162 Real32 rNear=vp->getCamera()->getNear(); 00163 00164 result.clear(); 00165 vp->getCamera()->getViewing ( viewing ,width,height ); 00166 vp->getCamera()->getProjection( projection,width,height ); 00167 visible.reserve(_tileGeometryLoad.size()); 00168 for(TileGeometryLoadLstT::iterator l=_tileGeometryLoad.begin() ; l!=_tileGeometryLoad.end() ; ++l) 00169 { 00170 // update view dependent values 00171 l->updateView(viewing, 00172 projection, 00173 rNear, 00174 width, 00175 height); 00176 // sort by min values 00177 if(l->isVisible()) 00178 { 00179 // collect visible geometries 00180 visible.push_back(RegionLoad(&(*l))); 00181 if(shrink) 00182 { 00183 if(l->getMin()[0] < wmin[0]) 00184 wmin[0]=l->getMin()[0]; 00185 if(l->getMin()[1] < wmin[1]) 00186 wmin[1]=l->getMin()[1]; 00187 if(l->getMax()[0] > wmax[0]) 00188 wmax[0]=l->getMax()[0]; 00189 if(l->getMax()[1] > wmax[1]) 00190 wmax[1]=l->getMax()[1]; 00191 } 00192 } 00193 } 00194 if(shrink) 00195 { 00196 // handle invisible area 00197 if(wmax[0]<wmin[0] || 00198 wmax[1]<wmin[1] ) 00199 wmin[0]=wmax[0]=wmin[1]=wmax[1]=0; 00200 // clamp to viewable area 00201 if(wmin[0]<0) 00202 wmin[0]=0; 00203 if(wmin[1]<0) 00204 wmin[1]=0; 00205 if(wmax[0]>=width ) 00206 wmax[0]=width -1; 00207 if(wmax[1]>=height) 00208 wmax[1]=height-1; 00209 } 00210 else 00211 { 00212 wmin[0]=wmin[1]=0; 00213 wmax[0]=width-1; 00214 wmax[1]=height-1; 00215 } 00216 // calculate region cost 00217 for(vi=visible.begin();vi!=visible.end();vi++) 00218 { 00219 vi->updateCost(wmin,wmax); 00220 } 00221 if(_renderNode.size()>1) 00222 { 00223 splitRegion(0,_renderNode.size()-1, 00224 visible, 00225 wmin, 00226 wmax, 00227 0, 00228 result); 00229 } 00230 else 00231 { 00232 Region region; 00233 region.x1=wmin[0]; 00234 region.y1=wmin[1]; 00235 region.x2=wmax[0]; 00236 region.y2=wmax[1]; 00237 result.push_back(region); 00238 } 00239 }
| void TileLoadBalancer::addRenderNode | ( | const RenderNode & | rn, | |
| UInt32 | id | |||
| ) |
Add new render node
Definition at line 307 of file OSGTileLoadBalancer.cpp.
References _renderNode.
Referenced by osg::SortFirstWindow::clientInit().
00308 { 00309 while(_renderNode.size()<=id) 00310 _renderNode.push_back(RenderNode()); 00311 _renderNode[id]=rn; 00312 }
| void TileLoadBalancer::drawVolumes | ( | WindowPtr | win | ) |
Draw recangular volume projection
Definition at line 317 of file OSGTileLoadBalancer.cpp.
References _tileGeometryLoad.
00318 { 00319 glPushMatrix(); 00320 glLoadIdentity(); 00321 glMatrixMode(GL_PROJECTION); 00322 glPushMatrix(); 00323 glLoadIdentity(); 00324 glViewport(0,0,win->getWidth(),win->getHeight()); 00325 gluOrtho2D(0,win->getWidth(), 00326 0,win->getHeight()); 00327 glDisable(GL_DEPTH_TEST); 00328 glEnable(GL_COLOR_MATERIAL); 00329 for(TileGeometryLoadLstT::iterator l=_tileGeometryLoad.begin() ; l!=_tileGeometryLoad.end() ; ++l) 00330 { 00331 if(l->isVisible()) 00332 { 00333 glBegin(GL_LINE_LOOP); 00334 glColor3f(0, 1, 0); 00335 glVertex3i(l->getMin()[0],l->getMin()[1],0); 00336 glVertex3i(l->getMax()[0],l->getMin()[1],0); 00337 glVertex3i(l->getMax()[0],l->getMax()[1],0); 00338 glVertex3i(l->getMin()[0],l->getMax()[1],0); 00339 glEnd(); 00340 } 00341 } 00342 glDisable(GL_COLOR_MATERIAL); 00343 glEnable(GL_DEPTH_TEST); 00344 glPopMatrix(); 00345 glMatrixMode(GL_MODELVIEW); 00346 glPopMatrix(); 00347 }
| void TileLoadBalancer::setRegionStatistics | ( | ViewportPtr | vp, | |
| ResultT & | result | |||
| ) |
Update the load balancing information
Definition at line 241 of file OSGTileLoadBalancer.cpp.
References _tileGeometryLoad.
00243 { 00244 Matrix projection,viewing; 00245 Int32 width =vp->getPixelWidth(); 00246 Int32 height=vp->getPixelHeight(); 00247 Real32 rNear=vp->getCamera()->getNear(); 00248 ResultT::iterator resultI; 00249 TileGeometryLoadLstT::iterator l; 00250 00251 vp->getCamera()->getViewing ( viewing ,width,height ); 00252 vp->getCamera()->getProjection( projection,width,height ); 00253 for(resultI=result.begin(); 00254 resultI!=result.end(); 00255 ++resultI) 00256 { 00257 resultI->culledNodes=0; 00258 resultI->faces=0; 00259 resultI->culledFaces=0; 00260 resultI->pixel=0; 00261 } 00262 for(l=_tileGeometryLoad.begin() ; 00263 l!=_tileGeometryLoad.end() ; 00264 ++l) 00265 { 00266 l->updateView(viewing, 00267 projection, 00268 rNear, 00269 width, 00270 height); 00271 for(resultI=result.begin(); 00272 resultI!=result.end(); 00273 ++resultI) 00274 { 00275 if(!l->isVisible()) 00276 resultI->culledNodes++; 00277 else 00278 { 00279 Int32 wmin[2]; 00280 Int32 wmax[2]; 00281 Int32 vismin[2]; 00282 Int32 vismax[2]; 00283 wmin[0]=resultI->x1; 00284 wmin[1]=resultI->y1; 00285 wmax[0]=resultI->x2; 00286 wmax[1]=resultI->y2; 00287 Real32 visible=l->getVisibleFraction(wmin,wmax,vismin,vismax)* 00288 l->getFaces(); 00289 if(visible==0) 00290 resultI->culledNodes++; 00291 else 00292 { 00293 resultI->faces+=visible; 00294 resultI->culledFaces+= l->getFaces()-visible; 00295 resultI->pixel+= 00296 (vismax[0] - vismin[0] + 1)* 00297 (vismax[1] - vismin[1] + 1); 00298 } 00299 } 00300 } 00301 } 00302 }
| double osg::TileLoadBalancer::runFaceBench | ( | GLuint | dlist, | |
| UInt32 | size, | |||
| Real32 | visible | |||
| ) | [protected] |
| void TileLoadBalancer::updateSubtree | ( | NodePtr & | node, | |
| TileGeometryLoadMapT & | loadMap | |||
| ) | [protected] |
Add all geometry nodes in the given tree
Definition at line 351 of file OSGTileLoadBalancer.cpp.
References _tileGeometryLoad, _useFaceDistribution, osg::AttachmentContainerPtr::dcast(), osg::NodePtr::getCore(), osg::FieldContainerPtrBase::getFieldContainerId(), and osg::NullFC.
Referenced by update().
00352 { 00353 // is nodecore a geometry? 00354 if(node->getCore() != NullFC && 00355 GeometryPtr::dcast(node->getCore()) != NullFC) 00356 { 00357 // is this a new node 00358 TileGeometryLoadMapT::iterator mI=loadMap.find(node.getFieldContainerId()); 00359 if(mI==loadMap.end()) 00360 { 00361 _tileGeometryLoad.push_back(TileGeometryLoad(node.getFieldContainerId(),_useFaceDistribution)); 00362 } 00363 else 00364 { 00365 loadMap.erase(mI); 00366 } 00367 } 00368 // handle all childs 00369 for(MFNodePtr::iterator n=node->getMFChildren()->begin(); 00370 n!=node->getMFChildren()->end(); 00371 ++n) 00372 { 00373 updateSubtree(*n,loadMap); 00374 } 00375 }
| void TileLoadBalancer::splitRegion | ( | UInt32 | rnFrom, | |
| UInt32 | rnTo, | |||
| RegionLoadVecT & | visible, | |||
| Int32 | wmin[2], | |||
| Int32 | wmax[2], | |||
| UInt32 | depth, | |||
| ResultT & | result | |||
| ) | [protected] |
Splitupt region
Definition at line 379 of file OSGTileLoadBalancer.cpp.
References _cutBestDirection, _renderNode, findBestCut(), osg::RenderNode::getInvisibleFaceCost(), osg::RenderNode::setGroup(), osg::RenderNode::setInvisibleFaceCost(), osg::TileLoadBalancer::Region::x1, osg::TileLoadBalancer::Region::x2, osg::TileLoadBalancer::Region::y1, and osg::TileLoadBalancer::Region::y2.
Referenced by balance().
00386 { 00387 Int32 axis,cut; 00388 Int32 maxA[2]; 00389 Int32 minB[2]; 00390 RegionLoadVecT visibleA; 00391 RegionLoadVecT visibleB; 00392 RegionLoadVecT::iterator vi; 00393 UInt32 rnToA,rnFromB; 00394 RenderNode groupRegionA,groupRegionB; 00395 RenderNode *renderNodeA,*renderNodeB; 00396 00397 // create group render node if neccessary 00398 rnToA =(rnTo+rnFrom)>>1; 00399 rnFromB=rnToA+1; 00400 if(rnFrom != rnToA) 00401 { 00402 groupRegionA.setGroup(&_renderNode[rnFrom],&_renderNode[rnToA+1]); 00403 renderNodeA=&groupRegionA; 00404 } 00405 else 00406 { 00407 renderNodeA=&_renderNode[rnFrom]; 00408 } 00409 if(rnFromB != rnTo) 00410 { 00411 groupRegionB.setGroup(&_renderNode[rnFromB],&_renderNode[rnTo+1]); 00412 renderNodeB=&groupRegionB; 00413 } 00414 else 00415 { 00416 renderNodeB=&_renderNode[rnFromB]; 00417 } 00418 #if 0 00419 if((rnToA-rnFrom) != (rnTo-rnFromB)) 00420 { 00421 renderNodeB->setInvisibleFaceCost(renderNodeA->getInvisibleFaceCost()); 00422 } 00423 #endif 00424 // do we check both axis? 00425 if(_cutBestDirection) 00426 axis=-1; 00427 else 00428 axis=depth&1; 00429 // search for best cut 00430 findBestCut(*renderNodeA,*renderNodeB, 00431 visible,wmin,wmax,axis,cut); 00432 // create new regions 00433 maxA[axis ]=cut; 00434 maxA[axis^1]=wmax[axis^1]; 00435 minB[axis ]=cut+1; 00436 minB[axis^1]=wmin[axis^1]; 00437 visibleA.reserve(visible.size()); 00438 visibleB.reserve(visible.size()); 00439 00440 // split regions 00441 if(rnFrom != rnToA || rnFromB != rnTo) 00442 { 00443 // split visible regions 00444 for(vi=visible.begin();vi!=visible.end();vi++) 00445 { 00446 if(vi->getLoad()->getMax()[axis] <= cut) 00447 visibleA.push_back(*vi); 00448 else 00449 if(vi->getLoad()->getMin()[axis] > cut) 00450 visibleB.push_back(*vi); 00451 else 00452 { 00453 visibleA.push_back(*vi); 00454 visibleB.push_back(*vi); 00455 visibleA.rbegin()->updateCost(wmin,maxA); 00456 visibleB.rbegin()->updateCost(minB,wmax); 00457 } 00458 } 00459 } 00460 if(rnFrom != rnToA) 00461 splitRegion(rnFrom,rnToA,visibleA,wmin,maxA,depth+1,result); 00462 else 00463 { 00464 Region region; 00465 region.x1=wmin[0]; 00466 region.y1=wmin[1]; 00467 region.x2=maxA[0]; 00468 region.y2=maxA[1]; 00469 result.push_back(region); 00470 } 00471 if(rnFromB != rnTo) 00472 splitRegion(rnFromB,rnTo,visibleB,minB,wmax,depth+1,result); 00473 else 00474 { 00475 Region region; 00476 region.x1=minB[0]; 00477 region.y1=minB[1]; 00478 region.x2=wmax[0]; 00479 region.y2=wmax[1]; 00480 result.push_back(region); 00481 } 00482 }
| Real32 TileLoadBalancer::findBestCut | ( | const RenderNode & | renderNodeA, | |
| const RenderNode & | renderNodeB, | |||
| RegionLoadVecT & | visible, | |||
| Int32 | wmin[2], | |||
| Int32 | wmax[2], | |||
| Int32 & | bestAxis, | |||
| Int32 & | bestCut | |||
| ) | [protected] |
Find best cut through the geometries
Definition at line 486 of file OSGTileLoadBalancer.cpp.
References osg::osgMax().
Referenced by splitRegion().
00493 { 00494 RegionLoadVecT::iterator vi; 00495 Int32 a,f,t,newCut; 00496 Int32 minB[2]; 00497 Int32 maxA[2]; 00498 Real32 costA=0,costB=0; 00499 Real32 newCost; 00500 Real32 bestCost; 00501 Int32 checkAxisFrom,checkAxisTo; 00502 bestCost=1e22; 00503 00504 if(bestAxis>=0) 00505 { 00506 // only check given axis 00507 checkAxisFrom=checkAxisTo=bestAxis; 00508 } 00509 else 00510 { 00511 // check x and y cut 00512 checkAxisFrom=0; 00513 checkAxisTo=1; 00514 } 00515 for(a=checkAxisFrom;a<=checkAxisTo;++a) 00516 { 00517 f=wmin[a]; 00518 t=wmax[a]; 00519 maxA[0]=wmax[0];; 00520 maxA[1]=wmax[1];; 00521 minB[0]=wmin[0];; 00522 minB[1]=wmin[1];; 00523 do 00524 { 00525 newCut=(f+t)/2; 00526 maxA[a]=newCut; 00527 minB[a]=newCut+1; 00528 costA=costB=0; 00529 for(vi=visible.begin();vi!=visible.end();vi++) 00530 { 00531 if(vi->getLoad()->getMax()[a] <= newCut) 00532 { 00533 costA+=vi->getCost(renderNodeA); 00534 } 00535 else 00536 if(vi->getLoad()->getMin()[a] > newCut) 00537 { 00538 costB+=vi->getCost(renderNodeB); 00539 } 00540 else 00541 { 00542 costA+=vi->getCost(renderNodeA,wmin,maxA); 00543 costB+=vi->getCost(renderNodeB,minB,wmax); 00544 } 00545 00546 } 00547 newCost= osgMax( costA, costB ); 00548 if(newCost<bestCost) 00549 { 00550 bestCut=newCut; 00551 bestCost=newCost; 00552 bestAxis=a; 00553 } 00554 // walk into direction of inbalance 00555 if(costA>costB) 00556 t=newCut; 00557 else 00558 f=newCut; 00559 } 00560 while(t-f > 2); 00561 } 00562 return bestCost; 00563 }
| double osg::TileLoadBalancer::calcFaceRenderingCost | ( | TileGeometryLoad * | load, | |
| Int32 | amin[2], | |||
| Int32 | amax[2] | |||
| ) | [protected] |
friend class RegionLoad [friend] |
Definition at line 165 of file OSGTileLoadBalancer.h.
Referenced by balance(), drawVolumes(), operator=(), setRegionStatistics(), update(), and updateSubtree().
RenderNodeLstT osg::TileLoadBalancer::_renderNode [protected] |
Definition at line 166 of file OSGTileLoadBalancer.h.
Referenced by addRenderNode(), balance(), operator=(), and splitRegion().
bool osg::TileLoadBalancer::_useFaceDistribution [protected] |
Definition at line 167 of file OSGTileLoadBalancer.h.
Referenced by operator=(), and updateSubtree().
bool osg::TileLoadBalancer::_cutBestDirection [protected] |
1.5.5