osg::TileLoadBalancer Class Reference

Manages geometry load.

#include <OSGTileLoadBalancer.h>

List of all members.

Public Types

typedef std::vector
< TileGeometryLoad
TileGeometryLoadLstT
typedef std::map< UInt32,
TileGeometryLoadLstT::iterator > 
TileGeometryLoadMapT
typedef std::vector< RegionResultT
typedef std::vector< RenderNodeRenderNodeLstT

Public Member Functions

Constructors
 TileLoadBalancer (bool useFaceDistribution=false, bool cutBestDirection=true)
 TileLoadBalancer (const TileLoadBalancer &source)
Assignment


TileLoadBalanceroperator= (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< RegionLoadRegionLoadVecT

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


Detailed Description

Definition at line 56 of file OSGTileLoadBalancer.h.


Member Typedef Documentation

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.

Definition at line 70 of file OSGTileLoadBalancer.h.

typedef std::vector<RegionLoad> osg::TileLoadBalancer::RegionLoadVecT [protected]

Definition at line 158 of file OSGTileLoadBalancer.h.


Constructor & Destructor Documentation

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]

Destructor documentation

Definition at line 97 of file OSGTileLoadBalancer.cpp.

00098 {
00099 }


Member Function Documentation

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

Parameters:
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]


Friends And Related Function Documentation

friend class RegionLoad [friend]

Definition at line 198 of file OSGTileLoadBalancer.h.

Referenced by balance().


Member Data Documentation

Definition at line 166 of file OSGTileLoadBalancer.h.

Referenced by addRenderNode(), balance(), operator=(), and splitRegion().

Definition at line 167 of file OSGTileLoadBalancer.h.

Referenced by operator=(), and updateSubtree().

Definition at line 168 of file OSGTileLoadBalancer.h.

Referenced by operator=(), and splitRegion().


The documentation for this class was generated from the following files:

Generated on Mon Mar 17 12:04:39 2008 for OpenSG by  doxygen 1.5.5