region.cc
Go to the documentation of this file.
1 /*
2  region.cc
3  data structures supporting multi-resolution ray tracing in world class.
4  Copyright Richard Vaughan 2008
5 */
6 
7 #include <pthread.h>
8 #include "region.hh"
9 using namespace Stg;
10 
12  cells(),
13  count(0),
14  superregion(NULL)
15 {
16 }
17 
19 {
20 }
21 
23 {
24  ++count;
25  assert(count>0);
27 }
28 
30 {
31  --count;
32  assert(count>=0);
34 
35  // if there's nothing in this region, we can garbage collect the
36  // cells to keep memory usage under control
37  if( count == 0 )
38  cells.clear();
39 }
40 
42  : count(0),
43  origin(origin),
44  regions(),
45  world(world)
46 {
47  for( int32_t c=0; c<SUPERREGIONSIZE;++c)
48  regions[c].superregion = this;
49 }
50 
52 {
53 }
54 
55 
57 {
58  ++count;
59  assert(count>0);
60 }
61 
63 {
64  --count;
65  assert(count>=0);
66 }
67 
68 
70 {
71  //printf( "SR origin (%d,%d) this %p\n", origin.x, origin.y, this );
72 
73  glPushMatrix();
74  GLfloat scale = 1.0/world->Resolution();
75  glScalef( scale, scale, 1.0 ); // XX TODO - this seems slightly
76  glTranslatef( origin.x<<SRBITS, origin.y<<SRBITS,0);
77 
78  glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
79 
80  // outline superregion
81  glColor3f( 0,0,1 );
82  glRecti( 0,0, 1<<SRBITS, 1<<SRBITS );
83 
84  // outline regions
85  if( regions )
86  {
87  const Region* r = &regions[0];
88  std::vector<GLfloat> rects(1000);
89 
90  for( int y=0; y<SUPERREGIONWIDTH; ++y )
91  for( int x=0; x<SUPERREGIONWIDTH; ++x )
92  {
93  if( r->count ) // region contains some occupied cells
94  {
95 
96  // outline the region
97  glColor3f(0,1,0);
98  glRecti( x<<RBITS, y<<RBITS,
99  (x+1)<<RBITS, (y+1)<<RBITS );
100 
101  // show how many cells are occupied
102  //snprintf( buf, 15, "%lu", r->count );
103  //Gl::draw_string( x<<RBITS, y<<RBITS, 0, buf );
104 
105  // draw a rectangle around each occupied cell
106  for( int p=0; p<REGIONWIDTH; ++p )
107  for( int q=0; q<REGIONWIDTH; ++q )
108  {
109  const Cell& c = r->cells[p+(q*REGIONWIDTH)];
110 
111  if( c.blocks[0].size() ) // layer 0
112  {
113  const GLfloat xx = p+(x<<RBITS);
114  const GLfloat yy = q+(y<<RBITS);
115 
116  rects.push_back( xx );
117  rects.push_back( yy );
118  rects.push_back( xx+1 );
119  rects.push_back( yy );
120  rects.push_back( xx+1 );
121  rects.push_back( yy+1 );
122  rects.push_back( xx );
123  rects.push_back( yy+1 );
124  }
125 
126  if( c.blocks[1].size() ) // layer 1
127  {
128  const GLfloat xx = p+(x<<RBITS);
129  const GLfloat yy = q+(y<<RBITS);
130  const double dx = 0.1;
131 
132  rects.push_back( xx+dx );
133  rects.push_back( yy+dx );
134  rects.push_back( xx+1-dx );
135  rects.push_back( yy+dx );
136  rects.push_back( xx+1-dx );
137  rects.push_back( yy+1-dx );
138  rects.push_back( xx+dx );
139  rects.push_back( yy+1-dx );
140  }
141  }
142 
143  }
144  ++r; // next region quickly
145  }
146 
147  if( rects.size() )
148  {
149  assert( rects.size() % 8 == 0 ); // should be full of squares
150  glVertexPointer( 2, GL_FLOAT, 0, &rects[0] );
151  glDrawArrays( GL_QUADS, 0, rects.size()/2 );
152  }
153  }
154  else
155  { // outline region-collected superregion
156  glColor3f( 1,1,0 );
157  glRecti( 0,0, (1<<SRBITS)-1, (1<<SRBITS)-1 );
158  glColor3f( 0,0,1 );
159  }
160 
161  // char buf[32];
162  // snprintf( buf, 15, "%lu", count );
163  // Gl::draw_string( 1<<SBITS, 1<<SBITS, 0, buf );
164 
165  glPopMatrix();
166 }
167 
168 static inline const std::vector<GLfloat> DrawBlock( GLfloat x, GLfloat y, GLfloat zmin, GLfloat zmax )
169 {
170  std::vector<GLfloat> v(60);
171 
172  // TOP
173  v[0]=x; v[1]=y; v[2]=zmax;
174  v[3]=1+x; v[4]=y; v[5]=zmax;
175  v[6]=1+x; v[7]=1+y; v[8]=zmax;
176  v[9]=x; v[10]=1+y; v[11]=zmax;
177 
178  // sides
179  v[12]=x; v[13]=y; v[14]=zmax;
180  v[15]=x; v[16]=1+y; v[17]=zmax;
181  v[18]=x; v[19]=1+y; v[20]=zmin;
182  v[21]=x; v[22]=y; v[23]=zmin;
183  v[24]=1+x; v[25]=y; v[26]=zmax;
184  v[27]=x; v[28]=y; v[29]=zmax;
185  v[30]=x; v[31]=y; v[32]=zmin;
186  v[33]=1+x; v[34]=y; v[35]=zmin;
187  v[36]=1+x; v[37]=1+y; v[38]=zmax;
188  v[39]=1+x; v[40]=y; v[41]=zmax;
189  v[42]=1+x; v[43]=y; v[44]=zmin;
190  v[45]=1+x; v[46]=1+y; v[47]=zmin;
191  v[48]=x; v[49]=1+y; v[50]=zmax;
192  v[51]=1+x; v[52]=1+y; v[53]=zmax;
193  v[54]=1+x; v[55]=1+y; v[56]=zmin;
194  v[57]=x; v[58]=1+y; v[59]=zmin;
195 
196  return v;
197 }
198 
199 void SuperRegion::DrawVoxels(unsigned int layer) const
200 {
201  glPushMatrix();
202  GLfloat scale = 1.0/world->Resolution();
203  glScalef( scale, scale, 1.0 ); // XX TODO - this seems slightly
204  glTranslatef( origin.x<<SRBITS, origin.y<<SRBITS,0);
205 
206 
207  glEnable( GL_DEPTH_TEST );
208  glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
209 
210  std::vector<GLfloat> verts(1000);
211  std::vector<GLfloat> colors(1000);
212 
213  const Region* r = &regions[0];
214 
215  for( int y=0; y<SUPERREGIONWIDTH; ++y )
216  for( int x=0; x<SUPERREGIONWIDTH; ++x )
217  {
218  if( r->count ) // not an empty region
219  for( int p=0; p<REGIONWIDTH; ++p )
220  for( int q=0; q<REGIONWIDTH; ++q )
221  {
222  const std::vector<Block*>& blocks =
223  r->cells[p+(q*REGIONWIDTH)].blocks[layer];
224 
225  if( blocks.size() ) // not an empty cell
226  {
227  const GLfloat xx(p+(x<<RBITS));
228  const GLfloat yy(q+(y<<RBITS));
229 
230  FOR_EACH( it, blocks )
231  {
232  Block* block = *it;
233  Color c = block->GetColor();
234 
235  const std::vector<GLfloat> v = DrawBlock( xx, yy, block->global_z.min, block->global_z.max );
236  verts.insert( verts.end(), v.begin(), v.end() );
237 
238  for( unsigned int i=0; i<20; i++ )
239  {
240  colors.push_back( c.r );
241  colors.push_back( c.g );
242  colors.push_back( c.b );
243  }
244  }
245  }
246  }
247  ++r;
248  }
249 
250  if( verts.size() )
251  {
252  assert( verts.size() % 60 == 0 ); // should be full of blocks, each with 20 3D vertices
253 
254  glEnableClientState( GL_COLOR_ARRAY );
255 
256  glVertexPointer( 3, GL_FLOAT, 0, &verts[0] );
257  glColorPointer( 3, GL_FLOAT, 0, &colors[0] );
258 
259  glDrawArrays( GL_QUADS, 0, verts.size()/3 );
260 
261  glDisableClientState( GL_COLOR_ARRAY );
262  }
263 
264  glPopMatrix();
265 }
266 
267 void Stg::Cell::AddBlock( Block* b, unsigned int layer )
268 {
269  blocks[layer].push_back( b );
270  b->rendered_cells[layer].push_back(this);
271  region->AddBlock();
272 }
273 
274 void Stg::Cell::RemoveBlock( Block* b, unsigned int layer )
275 {
276  std::vector<Block*>& blks( blocks[layer] );
277  const size_t len( blks.size() );
278  if( len )
279  {
280 #if 0
281  // Use conventional STL style
282 
283  // this special-case test is faster for worlds with simple models,
284  // which are the ones we want to be really fast. It's a small
285  // extra cost for worlds with several models in each cell. It
286  // gives a 5% overall speed increase in fasr.world.
287 
288  if( (blks.size() == 1) &&
289  (blks[0] == b) ) // special but common case
290  {
291  blks.clear(); // cheap
292  }
293  else // the general but relatively expensive case
294  {
295  EraseAll( b, blks );
296  }
297 #else
298  // attempt faster removal loop
299  // O(n) * low constant array element removal
300  // this C-style pointer work looks to be very slightly faster than the STL way
301  Block **start = &blks[0]; // start of array
302  Block **r = &blks[0]; // read from here
303  Block **w = &blks[0]; // write to here
304 
305  while( r < start + len ) // scan down array, skipping 'this'
306  {
307  if( *r != b )
308  *w++ = *r;
309  ++r;
310  }
311  blks.resize( w-start );
312 #endif
313  }
314 
315  region->RemoveBlock();
316 }
float scale
Definition: make_rsn.c:26
double max
largest value in range, initially zero
Definition: stage.hh:435
World class
Definition: stage.hh:814
The Stage library uses its own namespace.
Definition: canvas.hh:8
const int32_t SRBITS(RBITS+SBITS)
const Color & GetColor()
Definition: block.cc:134
Region regions[SUPERREGIONSIZE]
Definition: region.hh:97
void EraseAll(T thing, C &cont)
Definition: stage.hh:621
double min
smallest value in range, initially zero
Definition: stage.hh:433
std::vector< Cell > cells
Definition: region.hh:63
void AddBlock(Block *b, unsigned int index)
Definition: region.cc:267
SuperRegion * superregion
Definition: region.hh:88
const int32_t RBITS(5)
Bounds global_z
Definition: stage.hh:1283
void RemoveBlock()
Definition: region.cc:62
void RemoveBlock()
Definition: region.cc:29
double r
Definition: stage.hh:200
unsigned long count
Definition: region.hh:95
void DrawVoxels(unsigned int layer) const
Definition: region.cc:199
double Resolution() const
Definition: stage.hh:1171
void RemoveBlock(Block *b, unsigned int index)
Definition: region.cc:274
double b
Definition: stage.hh:200
double g
Definition: stage.hh:200
const int32_t REGIONWIDTH(1<< RBITS)
std::vector< Cell * > rendered_cells[2]
Definition: stage.hh:1291
const int32_t SUPERREGIONSIZE(SUPERREGIONWIDTH *SUPERREGIONWIDTH)
void AddBlock()
Definition: region.cc:22
void DrawOccupancy(void) const
Definition: region.cc:69
std::vector< Block * > blocks[2]
Definition: region.hh:40
World * world
Definition: region.hh:98
point_int_t origin
Definition: region.hh:96
#define FOR_EACH(I, C)
Definition: stage.hh:616
void AddBlock()
Definition: region.cc:56
SuperRegion(World *world, point_int_t origin)
Definition: region.cc:41
static const std::vector< GLfloat > DrawBlock(GLfloat x, GLfloat y, GLfloat zmin, GLfloat zmax)
Definition: region.cc:168
unsigned long count
Definition: region.hh:64
const int32_t SUPERREGIONWIDTH(1<< SBITS)


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 Mon Jun 10 2019 15:06:09