region.cc
Go to the documentation of this file.
00001 /*
00002   region.cc
00003   data structures supporting multi-resolution ray tracing in world class.
00004   Copyright Richard Vaughan 2008
00005 */
00006 
00007 #include <pthread.h>
00008 #include "region.hh"
00009 using namespace Stg;
00010 
00011 Stg::Region::Region() : 
00012   cells(), 
00013   count(0),
00014   superregion(NULL)
00015 {
00016 }
00017 
00018 Stg::Region::~Region()
00019 {
00020 }
00021 
00022 void Stg::Region::AddBlock()
00023 { 
00024   ++count; 
00025   assert(count>0);
00026   superregion->AddBlock();
00027 }
00028 
00029 void Stg::Region::RemoveBlock()
00030 {
00031   --count; 
00032   assert(count>=0); 
00033   superregion->RemoveBlock();
00034         
00035   // if there's nothing in this region, we can garbage collect the
00036   // cells to keep memory usage under control
00037   if( count == 0 )
00038     cells.clear();
00039 }
00040 
00041 SuperRegion::SuperRegion( World* world, point_int_t origin ) 
00042   : count(0),
00043     origin(origin), 
00044     regions(),
00045     world(world)
00046 {
00047   for( int32_t c=0; c<SUPERREGIONSIZE;++c)
00048     regions[c].superregion = this;
00049 }
00050 
00051 SuperRegion::~SuperRegion()
00052 {
00053 }
00054 
00055 
00056 void SuperRegion::AddBlock()
00057 { 
00058   ++count; 
00059   assert(count>0);
00060 }
00061 
00062 void SuperRegion::RemoveBlock()
00063 {
00064   --count; 
00065   assert(count>=0); 
00066 }               
00067 
00068 
00069 void SuperRegion::DrawOccupancy(void) const
00070 {
00071   //printf( "SR origin (%d,%d) this %p\n", origin.x, origin.y, this );
00072 
00073   glPushMatrix();           
00074   GLfloat scale = 1.0/world->Resolution();
00075   glScalef( scale, scale, 1.0 ); // XX TODO - this seems slightly
00076   glTranslatef( origin.x<<SRBITS, origin.y<<SRBITS,0);
00077   
00078   glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
00079   
00080   // outline superregion
00081   glColor3f( 0,0,1 );   
00082   glRecti( 0,0, 1<<SRBITS, 1<<SRBITS );
00083   
00084   // outline regions
00085   if( regions )
00086     {
00087       const Region* r = &regions[0];
00088       std::vector<GLfloat> rects(1000);
00089                           
00090       for( int y=0; y<SUPERREGIONWIDTH; ++y )
00091         for( int x=0; x<SUPERREGIONWIDTH; ++x )
00092           {
00093             if( r->count ) // region contains some occupied cells
00094               {                                  
00095       
00096                 // outline the region
00097                 glColor3f(0,1,0);
00098                 glRecti( x<<RBITS, y<<RBITS, 
00099                          (x+1)<<RBITS, (y+1)<<RBITS );
00100                 
00101                 // show how many cells are occupied
00102                 //snprintf( buf, 15, "%lu", r->count );
00103                 //Gl::draw_string( x<<RBITS, y<<RBITS, 0, buf );
00104                 
00105                 // draw a rectangle around each occupied cell                                    
00106                 for( int p=0; p<REGIONWIDTH; ++p )
00107                   for( int q=0; q<REGIONWIDTH; ++q )
00108                     {
00109                       const Cell& c = r->cells[p+(q*REGIONWIDTH)];
00110 
00111                       if( c.blocks[0].size() ) // layer 0
00112                         {                                        
00113                           const GLfloat xx = p+(x<<RBITS);
00114                           const GLfloat yy = q+(y<<RBITS);                                      
00115 
00116                           rects.push_back( xx );
00117                           rects.push_back( yy );
00118                           rects.push_back( xx+1 );
00119                           rects.push_back( yy );
00120                           rects.push_back( xx+1 );
00121                           rects.push_back( yy+1 );
00122                           rects.push_back( xx );
00123                           rects.push_back( yy+1 );
00124                         }
00125                       
00126                       if( c.blocks[1].size() ) // layer 1
00127                         {                                        
00128                           const GLfloat xx = p+(x<<RBITS);
00129                           const GLfloat yy = q+(y<<RBITS);                                      
00130                           const double dx = 0.1;
00131 
00132                           rects.push_back( xx+dx );
00133                           rects.push_back( yy+dx );
00134                           rects.push_back( xx+1-dx );
00135                           rects.push_back( yy+dx );
00136                           rects.push_back( xx+1-dx );
00137                           rects.push_back( yy+1-dx );
00138                           rects.push_back( xx+dx );
00139                           rects.push_back( yy+1-dx );
00140                         }
00141                     }
00142 
00143               }  
00144             ++r; // next region quickly
00145           }     
00146       
00147       if( rects.size() )
00148         {
00149           assert( rects.size() % 8 == 0 ); // should be full of squares   
00150           glVertexPointer( 2, GL_FLOAT, 0, &rects[0] );       
00151           glDrawArrays( GL_QUADS, 0, rects.size()/2 );
00152         }
00153     }
00154   else
00155     {  // outline region-collected superregion
00156       glColor3f( 1,1,0 );   
00157       glRecti( 0,0, (1<<SRBITS)-1, (1<<SRBITS)-1 );
00158       glColor3f( 0,0,1 );   
00159     }
00160   
00161   // char buf[32];
00162   // snprintf( buf, 15, "%lu", count );
00163   // Gl::draw_string( 1<<SBITS, 1<<SBITS, 0, buf );
00164   
00165   glPopMatrix();    
00166 }
00167 
00168 static inline const std::vector<GLfloat> DrawBlock( GLfloat x, GLfloat y, GLfloat zmin, GLfloat zmax )
00169 {
00170   std::vector<GLfloat> v(60);
00171 
00172   // TOP
00173   v[0]=x;     v[1]=y;     v[2]=zmax;
00174   v[3]=1+x;   v[4]=y;     v[5]=zmax;
00175   v[6]=1+x;   v[7]=1+y;   v[8]=zmax;
00176   v[9]=x;     v[10]=1+y;  v[11]=zmax;
00177   
00178   // sides
00179   v[12]=x;    v[13]=y;    v[14]=zmax;
00180   v[15]=x;    v[16]=1+y;  v[17]=zmax;
00181   v[18]=x;    v[19]=1+y;  v[20]=zmin;
00182   v[21]=x;    v[22]=y;    v[23]=zmin;
00183   v[24]=1+x;  v[25]=y;    v[26]=zmax;
00184   v[27]=x;    v[28]=y;    v[29]=zmax;
00185   v[30]=x;    v[31]=y;    v[32]=zmin;
00186   v[33]=1+x;  v[34]=y;    v[35]=zmin;
00187   v[36]=1+x;  v[37]=1+y;  v[38]=zmax;
00188   v[39]=1+x;  v[40]=y;    v[41]=zmax;
00189   v[42]=1+x;  v[43]=y;    v[44]=zmin;
00190   v[45]=1+x;  v[46]=1+y;  v[47]=zmin;
00191   v[48]=x;    v[49]=1+y;  v[50]=zmax;
00192   v[51]=1+x;  v[52]=1+y;  v[53]=zmax;
00193   v[54]=1+x;  v[55]=1+y;  v[56]=zmin;
00194   v[57]=x;    v[58]=1+y;  v[59]=zmin;
00195 
00196   return v;
00197 } 
00198 
00199 void SuperRegion::DrawVoxels(unsigned int layer) const
00200 {
00201   glPushMatrix();           
00202   GLfloat scale = 1.0/world->Resolution();
00203   glScalef( scale, scale, 1.0 ); // XX TODO - this seems slightly
00204   glTranslatef( origin.x<<SRBITS, origin.y<<SRBITS,0);
00205 
00206 
00207   glEnable( GL_DEPTH_TEST );
00208   glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
00209   
00210   std::vector<GLfloat> verts(1000);
00211   std::vector<GLfloat> colors(1000);
00212 
00213   const Region* r = &regions[0];
00214   
00215   for( int y=0; y<SUPERREGIONWIDTH; ++y )
00216     for( int x=0; x<SUPERREGIONWIDTH; ++x )
00217       {           
00218         if( r->count ) // not an empty region
00219           for( int p=0; p<REGIONWIDTH; ++p )
00220             for( int q=0; q<REGIONWIDTH; ++q )
00221               {
00222                 const std::vector<Block*>& blocks = 
00223                   r->cells[p+(q*REGIONWIDTH)].blocks[layer];
00224                                          
00225                 if( blocks.size() ) // not an empty cell
00226                   {                                      
00227                     const GLfloat xx(p+(x<<RBITS));
00228                     const GLfloat yy(q+(y<<RBITS));
00229                     
00230                     FOR_EACH( it, blocks )
00231                       {
00232                         Block* block = *it;
00233                         Color c = block->GetColor();
00234                         
00235                         const std::vector<GLfloat> v = DrawBlock(  xx, yy, block->global_z.min, block->global_z.max );
00236                         verts.insert( verts.end(), v.begin(), v.end() );
00237                         
00238                         for( unsigned int i=0; i<20; i++ )
00239                           {
00240                             colors.push_back( c.r );
00241                             colors.push_back( c.g );
00242                             colors.push_back( c.b );
00243                           }
00244                       }
00245                   }
00246               }           
00247         ++r;
00248       }
00249 
00250   if( verts.size() )
00251     {
00252       assert( verts.size() % 60 == 0 ); // should be full of blocks, each with 20 3D vertices
00253 
00254       glEnableClientState( GL_COLOR_ARRAY );
00255 
00256       glVertexPointer( 3, GL_FLOAT, 0, &verts[0] );       
00257       glColorPointer( 3, GL_FLOAT, 0, &colors[0] );
00258 
00259       glDrawArrays( GL_QUADS, 0, verts.size()/3 );
00260 
00261       glDisableClientState( GL_COLOR_ARRAY );
00262     }
00263 
00264   glPopMatrix();    
00265 }
00266 
00267 void Stg::Cell::AddBlock( Block* b, unsigned int layer )
00268 {                       
00269   blocks[layer].push_back( b );   
00270   b->rendered_cells[layer].push_back(this);
00271   region->AddBlock();
00272 }
00273 
00274 void Stg::Cell::RemoveBlock( Block* b, unsigned int layer )
00275 {
00276   std::vector<Block*>& blks( blocks[layer] );
00277   const size_t len( blks.size() );
00278   if( len )
00279     {
00280 #if 0   
00281       // Use conventional STL style             
00282                 
00283       // this special-case test is faster for worlds with simple models,
00284       // which are the ones we want to be really fast. It's a small
00285       // extra cost for worlds with several models in each cell. It
00286       // gives a 5% overall speed increase in fasr.world.
00287                 
00288       if( (blks.size() == 1) &&
00289           (blks[0] == b) ) // special but common case
00290         {
00291           blks.clear(); // cheap
00292         }
00293       else // the general but relatively expensive case
00294         {
00295           EraseAll( b, blks );          
00296         }
00297 #else   
00298       // attempt faster removal loop
00299       // O(n) * low constant array element removal
00300       // this C-style pointer work looks to be very slightly faster than the STL way
00301       Block **start = &blks[0]; // start of array
00302       Block **r     = &blks[0]; // read from here
00303       Block **w     = &blks[0]; // write to here
00304       
00305       while( r < start + len ) // scan down array, skipping 'this' 
00306         {
00307           if( *r != b ) 
00308             *w++ = *r;                          
00309           ++r;
00310         }
00311       blks.resize( w-start );
00312 #endif
00313     }
00314   
00315   region->RemoveBlock();
00316 }


stage
Author(s): Richard Vaughan , Brian Gerkey , Reed Hedges , Andrew Howard , Toby Collett , Pooya Karimian , Jeremy Asher , Alex Couture-Beil , Geoff Biggs , Rich Mattes , Abbas Sadat
autogenerated on Thu Aug 27 2015 15:20:57