00001
00002
00003
00004
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
00036
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
00072
00073 glPushMatrix();
00074 GLfloat scale = 1.0/world->Resolution();
00075 glScalef( scale, scale, 1.0 );
00076 glTranslatef( origin.x<<SRBITS, origin.y<<SRBITS,0);
00077
00078 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
00079
00080
00081 glColor3f( 0,0,1 );
00082 glRecti( 0,0, 1<<SRBITS, 1<<SRBITS );
00083
00084
00085 if( regions )
00086 {
00087 const Region* r = ®ions[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 )
00094 {
00095
00096
00097 glColor3f(0,1,0);
00098 glRecti( x<<RBITS, y<<RBITS,
00099 (x+1)<<RBITS, (y+1)<<RBITS );
00100
00101
00102
00103
00104
00105
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() )
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() )
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;
00145 }
00146
00147 if( rects.size() )
00148 {
00149 assert( rects.size() % 8 == 0 );
00150 glVertexPointer( 2, GL_FLOAT, 0, &rects[0] );
00151 glDrawArrays( GL_QUADS, 0, rects.size()/2 );
00152 }
00153 }
00154 else
00155 {
00156 glColor3f( 1,1,0 );
00157 glRecti( 0,0, (1<<SRBITS)-1, (1<<SRBITS)-1 );
00158 glColor3f( 0,0,1 );
00159 }
00160
00161
00162
00163
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
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
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 );
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 = ®ions[0];
00214
00215 for( int y=0; y<SUPERREGIONWIDTH; ++y )
00216 for( int x=0; x<SUPERREGIONWIDTH; ++x )
00217 {
00218 if( r->count )
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() )
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 );
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
00282
00283
00284
00285
00286
00287
00288 if( (blks.size() == 1) &&
00289 (blks[0] == b) )
00290 {
00291 blks.clear();
00292 }
00293 else
00294 {
00295 EraseAll( b, blks );
00296 }
00297 #else
00298
00299
00300
00301 Block **start = &blks[0];
00302 Block **r = &blks[0];
00303 Block **w = &blks[0];
00304
00305 while( r < start + len )
00306 {
00307 if( *r != b )
00308 *w++ = *r;
00309 ++r;
00310 }
00311 blks.resize( w-start );
00312 #endif
00313 }
00314
00315 region->RemoveBlock();
00316 }