Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

blocks are now contours of complex polygons, and are no longer limite…

…d to being convex simple polygons. This allows us to parse bitmaps into a few complex polygons instead of a lot of small rectangles. It looks a lot better in the GUI, though there are some glitches to figure out with internal-vs-external contours indicated by winding direction. This is just cosmetic though, so it can go in master
  • Loading branch information...
commit f0e1c49bb63c088f141e44b26f338c65ff013d9d 1 parent 59be1dd
Richard Vaughan rtv authored
59 libstage/block.cc
@@ -12,14 +12,11 @@ static void canonicalize_winding(vector<point_t>& pts);
12 12 after calling this.*/
13 13 Block::Block( BlockGroup* group,
14 14 const std::vector<point_t>& pts,
15   - const Bounds& zrange,
16   - const Color& color,
17   - bool inherit_color ) :
  15 + const Bounds& zrange ) :
18 16 group(group),
19 17 pts(pts),
20 18 local_z( zrange ),
21   - color( color ),
22   - inherit_color( inherit_color ),
  19 + global_z(),
23 20 rendered_cells()
24 21 {
25 22 assert( group );
@@ -33,29 +30,23 @@ Block::Block( BlockGroup* group,
33 30 : group(group),
34 31 pts(),
35 32 local_z(),
36   - color(),
37   - inherit_color(true),
  33 + global_z(),
38 34 rendered_cells()
39 35 {
  36 + assert(group);
40 37 assert(wf);
41 38 assert(entity);
42 39
43 40 Load( wf, entity );
  41 + canonicalize_winding(this->pts);
44 42 }
45 43
46 44 Block::~Block()
47 45 {
48   - if( mapped )
49   - {
50   - UnMap(0);
51   - UnMap(1);
52   - }
  46 + UnMap(0);
  47 + UnMap(1);
53 48 }
54 49
55   -Model* Block::GetModel()
56   -{
57   - return &group->mod;
58   -};
59 50
60 51
61 52 void Block::Translate( double x, double y )
@@ -137,11 +128,6 @@ void Block::SetZ( double min, double max )
137 128 group->BuildDisplayList();
138 129 }
139 130
140   -const Color& Block::GetColor()
141   -{
142   - return( inherit_color ? group->mod.color : color );
143   -}
144   -
145 131 void Block::AppendTouchingModels( std::set<Model*>& touchers )
146 132 {
147 133 unsigned int layer = group->mod.world->updates % 2;
@@ -211,8 +197,6 @@ void Block::Map( unsigned int layer )
211 197 gpose.z += group->mod.geom.pose.z;
212 198 global_z.min = local_z.min + gpose.z;
213 199 global_z.max = local_z.max + gpose.z;
214   -
215   - mapped = true;
216 200 }
217 201
218 202
@@ -222,7 +206,6 @@ void Block::UnMap( unsigned int layer )
222 206 (*it)->RemoveBlock(this, layer );
223 207
224 208 rendered_cells[layer].clear();
225   - mapped = false;
226 209 }
227 210
228 211 void swap( int& a, int& b )
@@ -306,10 +289,13 @@ void Block::Rasterize( uint8_t* data,
306 289 }
307 290 }
308 291
  292 +
  293 +
309 294 void Block::DrawTop()
310 295 {
311 296 // draw the top of the block - a polygon at the highest vertical
312 297 // extent
  298 +
313 299 glBegin( GL_POLYGON);
314 300 FOR_EACH( it, pts )
315 301 glVertex3f( it->x, it->y, local_z.max );
@@ -342,9 +328,7 @@ void Block::DrawFootPrint()
342 328
343 329 void Block::DrawSolid( bool topview )
344 330 {
345   - if( ! topview )
346   - DrawSides();
347   -
  331 + DrawSides();
348 332 DrawTop();
349 333 }
350 334
@@ -352,7 +336,7 @@ void Block::Load( Worldfile* wf, int entity )
352 336 {
353 337 const size_t pt_count = wf->ReadInt( entity, "points", 0);
354 338
355   - char key[128];
  339 + char key[256];
356 340 for( size_t p=0; p<pt_count; ++p )
357 341 {
358 342 snprintf(key, sizeof(key), "point[%d]", (int)p );
@@ -364,17 +348,7 @@ void Block::Load( Worldfile* wf, int entity )
364 348
365 349 canonicalize_winding(pts);
366 350
367   - wf->ReadTuple( entity, "z", 0, 2, "ll", &local_z.min, &local_z.max );
368   -
369   - const std::string& colorstr = wf->ReadString( entity, "color", "" );
370   -
371   - if( colorstr != "" )
372   - {
373   - color = Color( colorstr );
374   - inherit_color = false;
375   - }
376   - else
377   - inherit_color = true;
  351 + wf->ReadTuple( entity, "z", 0, 2, "ll", &local_z.min, &local_z.max );
378 352 }
379 353
380 354 /////////////////////////////////////////////////////////////////////////////////////////
@@ -444,12 +418,7 @@ static
444 418 /// Util
445 419 bool is_canonical_winding(vector<point_t> const& ps)
446 420 {
447   - // reuse point_t as vector
448   - vector<point_t> vs = find_vectors(ps);
449   - radians_t sum = angles_sum(vs);
450   - bool bCanon = 0 < sum;
451   -
452   - return bCanon;
  421 + return( 0 < angles_sum( find_vectors(ps) ) );
453 422 }
454 423
455 424 static
204 libstage/blockgroup.cc
@@ -138,9 +138,39 @@ void BlockGroup::DrawFootPrint( const Geom & geom )
138 138 it->DrawFootPrint();
139 139 }
140 140
  141 +// tesselation callbacks used in BlockGroup::BuildDisplayListTess()------------
  142 +
  143 +static void errorCallback(GLenum errorCode)
  144 +{
  145 + const GLubyte *estring;
  146 +
  147 + estring = gluErrorString(errorCode);
  148 + fprintf (stderr, "Tessellation Error: %s\n", estring);
  149 + exit (0);
  150 +}
  151 +
  152 +static void combineCallback(GLdouble coords[3],
  153 + GLdouble *vertex_data[4],
  154 + GLfloat weight[4], GLdouble **dataOut )
  155 +{
  156 + GLdouble *vertex;
  157 +
  158 + vertex = (GLdouble *) malloc(3 * sizeof(GLdouble));
  159 + vertex[0] = coords[0];
  160 + vertex[1] = coords[1];
  161 + vertex[2] = coords[2];
  162 +
  163 + // @todo: fix the leak of this vertex buffer. it's not a lot of
  164 + // data, and doesn't happen much, but it would be tidy.
  165 +
  166 + *dataOut = vertex;
  167 +}
  168 +
  169 +// render each block as a polygon extruded into Z
141 170 void BlockGroup::BuildDisplayList()
142 171 {
143   - //puts( "build" );
  172 + static bool init = false;
  173 + static GLUtesselator *tobj = NULL;
144 174
145 175 if( ! mod.world->IsGUI() )
146 176 return;
@@ -148,76 +178,106 @@ void BlockGroup::BuildDisplayList()
148 178 //printf( "display list for model %s\n", mod->token );
149 179 if( displaylist == 0 )
150 180 {
  181 + CalcSize(); // todo: is this redundant? count calls per model to figure this out.
  182 +
151 183 displaylist = glGenLists(1);
152   - CalcSize();
  184 + assert(displaylist !=0 );
  185 +
  186 + // Stage polygons need not be convex, so we have to tesselate them for rendering in OpenGL.
  187 + tobj = gluNewTess();
  188 + assert(tobj != NULL);
  189 +
  190 + // these use the standard GL calls
  191 + gluTessCallback(tobj, GLU_TESS_VERTEX,
  192 + (GLvoid (*) ()) &glVertex3dv);
  193 + gluTessCallback(tobj, GLU_TESS_EDGE_FLAG,
  194 + (GLvoid (*) ()) &glEdgeFlag);
  195 + gluTessCallback(tobj, GLU_TESS_BEGIN,
  196 + (GLvoid (*) ()) &glBegin);
  197 + gluTessCallback(tobj, GLU_TESS_END,
  198 + (GLvoid (*) ()) &glEnd);
  199 +
  200 + // these are custom, defined above.
  201 + gluTessCallback(tobj, GLU_TESS_ERROR,
  202 + (GLvoid (*) ()) &errorCallback);
  203 + gluTessCallback(tobj, GLU_TESS_COMBINE,
  204 + (GLvoid (*) ()) &combineCallback);
153 205 }
154 206
155   -
156   - glNewList( displaylist, GL_COMPILE );
157   -
158   -
159   - // render each block as a polygon extruded into Z
160   -
161 207 Geom geom = mod.GetGeom();
162 208
  209 + std::vector<std::vector<GLdouble> > contours;
  210 +
  211 + FOR_EACH( blk, blocks )
  212 + {
  213 + std::vector<GLdouble> verts;
  214 + FOR_EACH( it, blk->pts )
  215 + {
  216 + verts.push_back( it->x );
  217 + verts.push_back( it->y );
  218 + verts.push_back( blk->local_z.max );
  219 + }
  220 + contours.push_back( verts );
  221 + }
  222 +
  223 + glNewList( displaylist, GL_COMPILE );
163 224 Gl::pose_shift( geom.pose );
164   -
  225 +
  226 + // draw filled polys
165 227 glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
166 228 glEnable(GL_POLYGON_OFFSET_FILL);
167   - glPolygonOffset(1.0, 1.0);
  229 + glPolygonOffset(0.5, 0.5);
168 230
169 231 mod.PushColor( mod.color );
170   -
171   - //const bool topview = dynamic_cast<WorldGui*>(mod->world)->IsTopView();
172   -
173   - FOR_EACH( blk, blocks )
174   - {
175   - if( (!blk->inherit_color) && (blk->color != mod.color) )
176   - {
177   - mod.PushColor( blk->color );
178   - blk->DrawSolid(false);
179   - mod.PopColor();
180   - }
181   - else
182   - blk->DrawSolid(false);
  232 +
  233 + gluTessBeginPolygon(tobj, NULL);
  234 +
  235 + FOR_EACH( contour, contours )
  236 + {
  237 + gluTessBeginContour(tobj);
  238 + for( size_t v=0; v<contour->size(); v+=3 )
  239 + gluTessVertex(tobj, &(*contour)[v], &(*contour)[v]);
  240 + gluTessEndContour(tobj);
183 241 }
184   -
185   - mod.PopColor();
186   -
187   - // outline each poly in a darker version of the same color
  242 +
  243 + gluTessEndPolygon(tobj);
188 244
189   - glDisable(GL_POLYGON_OFFSET_FILL);
  245 + FOR_EACH( blk, blocks )
  246 + blk->DrawSides();
  247 +
  248 + mod.PopColor();
190 249
  250 + // now outline the polys
  251 + glDisable(GL_POLYGON_OFFSET_FILL);
191 252 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
192 253 glDepthMask(GL_FALSE);
193   -
  254 +
194 255 Color c = mod.color;
195 256 c.r /= 2.0;
196 257 c.g /= 2.0;
197 258 c.b /= 2.0;
198 259 mod.PushColor( c );
199 260
200   - FOR_EACH( blk, blocks )
201   - {
202   - if( (!blk->inherit_color) && (blk->color != mod.color) )
203   - {
204   - Color c = blk->color;
205   - c.r /= 2.0;
206   - c.g /= 2.0;
207   - c.b /= 2.0;
208   - mod.PushColor( c );
209   - blk->DrawSolid(false);
210   - mod.PopColor();
211   - }
212   - else
213   - blk->DrawSolid(false);
214   - }
  261 + gluTessBeginPolygon(tobj, NULL);
215 262
  263 + FOR_EACH( contour, contours )
  264 + {
  265 + gluTessBeginContour(tobj);
  266 + for( size_t v=0; v<contour->size(); v+=3 )
  267 + gluTessVertex(tobj, &(*contour)[v], &(*contour)[v]);
  268 + gluTessEndContour(tobj);
  269 + }
  270 +
  271 + gluTessEndPolygon(tobj);
  272 +
  273 + FOR_EACH( blk, blocks )
  274 + blk->DrawSides();
  275 +
216 276 glDepthMask(GL_TRUE);
217 277 glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
218   -
219   - mod.PopColor();
220 278
  279 + mod.PopColor();
  280 +
221 281 glEndList();
222 282 }
223 283
@@ -252,50 +312,34 @@ void BlockGroup::LoadBitmap( const std::string& bitmapfile, Worldfile* wf )
252 312 full = std::string(dirname(workaround_const)) + "/" + bitmapfile;
253 313 free( workaround_const );
254 314 }
  315 +
  316 + char buf[512];
  317 + snprintf( buf, 512, "[Image \"%s\"", bitmapfile.c_str() );
  318 + fputs( buf, stdout );
  319 + fflush( stdout );
255 320
256 321 PRINT_DEBUG1( "attempting to load image %s", full );
257 322
258   - std::vector<rotrect_t> rects;
259   - if( rotrects_from_image_file( full,
260   - rects ) )
  323 + Color col( 1.0, 0.0, 1.0, 1.0 );
  324 +
  325 + std::vector<std::vector<point_t> > polys;
  326 +
  327 + if( polys_from_image_file( full,
  328 + polys ) )
261 329 {
262   - PRINT_ERR1( "failed to load rects from image file \"%s\"",
  330 + PRINT_ERR1( "failed to load polys from image file \"%s\"",
263 331 full.c_str() );
264 332 return;
265 333 }
266 334
267   - //printf( "found %d rects in \"%s\" at %p\n",
268   - // rect_count, full, rects );
269   -
270   - // TODO fix this
271   - Color col( 1.0, 0.0, 1.0, 1.0 );
272   -
273   - FOR_EACH( rect, rects )
274   - {
275   - std::vector<point_t> pts(4);
276   -
277   - const double x = rect->pose.x;
278   - const double y = rect->pose.y;
279   - const double w = rect->size.x;
280   - const double h = rect->size.y;
281   -
282   - pts[0].x = x;
283   - pts[0].y = y;
284   - pts[1].x = x + w;
285   - pts[1].y = y;
286   - pts[2].x = x + w;
287   - pts[2].y = y + h;
288   - pts[3].x = x;
289   - pts[3].y = y + h;
290   -
291   - AppendBlock( Block( this,
292   - pts,
293   - Bounds(0,1) ,
294   - col,
295   - true ) );
296   - }
  335 + FOR_EACH( it, polys )
  336 + AppendBlock( Block( this,
  337 + *it,
  338 + Bounds(0,1) ));
297 339
298 340 CalcSize();
  341 +
  342 + fputs( "]", stdout );
299 343 }
300 344
301 345
7 libstage/model.cc
@@ -458,9 +458,8 @@ void Model::AddBlockRect( meters_t x,
458 458
459 459 blockgroup.AppendBlock( Block( &blockgroup,
460 460 pts,
461   - Bounds(0,dz),
462   - color,
463   - true ));
  461 + Bounds(0,dz) ));
  462 +
464 463 Map();
465 464 }
466 465
@@ -1235,6 +1234,8 @@ void Model::SetGeom( const Geom& val )
1235 1234
1236 1235 blockgroup.CalcSize();
1237 1236
  1237 + //printf( "model %s SetGeom size [%.3f %.3f %.3f]\n", Token(), geom.size.x, geom.size.y, geom.size.z );
  1238 +
1238 1239 NeedRedraw();
1239 1240
1240 1241 MapWithChildren(0);
2  libstage/region.cc
@@ -230,7 +230,7 @@ void SuperRegion::DrawVoxels(unsigned int layer) const
230 230 FOR_EACH( it, blocks )
231 231 {
232 232 Block* block = *it;
233   - Color c = block->GetColor();
  233 + Color c = block->group->mod.GetColor();
234 234
235 235 const std::vector<GLfloat> v = DrawBlock( xx, yy, block->global_z.min, block->global_z.max );
236 236 verts.insert( verts.end(), v.begin(), v.end() );
167 libstage/stage.cc
@@ -157,7 +157,7 @@ int Stg::rotrects_from_image_file( const std::string& filename,
157 157 // rather than graphics coordinates. this is much faster than
158 158 // inverting the original image.
159 159
160   - rotrect_t latest;// = &(*rects)[(*rect_count)-1];
  160 + rotrect_t latest;
161 161 latest.pose.x = startx;
162 162 latest.pose.y = height-1 - (starty + rheight);
163 163 latest.pose.a = 0.0;
@@ -182,36 +182,153 @@ int Stg::rotrects_from_image_file( const std::string& filename,
182 182 return 0; // ok
183 183 }
184 184
185   -/*
186   -private static void Floodfill(byte[,] vals, point_int_t q, byte SEED_COLOR, byte COLOR)
  185 +double direction( double a )
187 186 {
188   - int h = vals.GetLength(0);
189   - int w = vals.GetLength(1);
  187 + if( a == 0.0 )
  188 + return 0;
  189 + else
  190 + return sgn(a);
  191 +}
190 192
191   - if (q.Y < 0 || q.Y > h - 1 || q.X < 0 || q.X > w - 1)
192   - return;
  193 +int Stg::polys_from_image_file( const std::string& filename,
  194 + std::vector<std::vector<point_t> >& polys )
  195 +{
  196 + // TODO: make this a parameter
  197 + const int threshold = 127;
  198 +
  199 + Fl_Shared_Image *img = Fl_Shared_Image::get(filename.c_str());
  200 + if( img == NULL )
  201 + {
  202 + std::cerr << "failed to open file: " << filename << std::endl;
193 203
194   - std::stack<Point> stack = new Stack<Point>();
195   - stack.Push(q);
196   - while (stack.Count > 0)
  204 + assert( img ); // easy access to this point in debugger
  205 + exit(-1);
  206 + }
  207 +
  208 + //printf( "loaded image %s w %d h %d d %d count %d ld %d\n",
  209 + // filename, img->w(), img->h(), img->d(), img->count(), img->ld() );
  210 +
  211 + const unsigned int width = img->w();
  212 + const unsigned height = img->h();
  213 + const unsigned int depth = img->d();
  214 + uint8_t* pixels = (uint8_t*)img->data()[0];
  215 +
  216 + // a set of previously seen directed edges, The key is a 4-element vector
  217 + // [x1,y1,x2,y2].
  218 + std::set<std::vector<uint32_t> > edges;
  219 +
  220 + for(unsigned int y = 0; y < height; y++)
  221 + {
  222 + for(unsigned int x = 0; x < width; x++)
  223 + {
  224 + // skip blank (white) pixels
  225 + if( pixel_is_set( pixels, width, depth, x, y, threshold) )
  226 + continue;
  227 +
  228 + // generate the four directed edges for this pixel
  229 + std::vector<uint32_t> edge[4];
  230 +
  231 + for( int i=0; i<4; i++ )
  232 + edge[i].resize(4);
  233 +
  234 + edge[0][0] = x+0;
  235 + edge[0][1] = y+0;
  236 + edge[0][2] = x+1;
  237 + edge[0][3] = y+0;
  238 +
  239 + edge[1][0] = x+1;
  240 + edge[1][1] = y+0;
  241 + edge[1][2] = x+1;
  242 + edge[1][3] = y+1;
  243 +
  244 + edge[2][0] = x+1;
  245 + edge[2][1] = y+1;
  246 + edge[2][2] = x+0;
  247 + edge[2][3] = y+1;
  248 +
  249 + edge[3][0] = x+0;
  250 + edge[3][1] = y+1;
  251 + edge[3][2] = x+0;
  252 + edge[3][3] = y+0;
  253 +
  254 + // put them in the set of the inverse edge does not exist
  255 + for( int i=0; i<4; i++ )
  256 + {
  257 + // the same edge with the opposite direction
  258 + std::vector<uint32_t> inv(4);
  259 + inv[0] = edge[i][2];
  260 + inv[1] = edge[i][3];
  261 + inv[2] = edge[i][0];
  262 + inv[3] = edge[i][1];
  263 +
  264 + std::set<std::vector<uint32_t> >::iterator it =
  265 + edges.find( inv );
  266 +
  267 + if( it == edges.end() ) // inverse not found
  268 + edges.insert( edge[i] ); // add the new edge
  269 + else // inverse found! delete it
  270 + edges.erase( it );
  271 + }
  272 + }
  273 + }
  274 +
  275 + std::multimap<point_t,point_t> mmap;
  276 +
  277 + FOR_EACH( it, edges )
  278 + {
  279 + // fill a multimap with start-point / end-point pairs.
  280 + std::pair<point_t,point_t> p( point_t( (*it)[0], (*it)[1] ),
  281 + point_t( (*it)[2], (*it)[3] ));
  282 + mmap.insert( p );
  283 + }
  284 +
  285 + for( std::multimap<point_t,point_t>::iterator seedit = mmap.begin();
  286 + seedit != mmap.end();
  287 + seedit = mmap.begin() )
197 288 {
198   - Point p = stack.Pop();
199   - int x = p.X;
200   - int y = p.Y;
201   - if (y < 0 || y > h - 1 || x < 0 || x > w - 1)
202   - continue;
203   - byte val = vals[y, x];
204   - if (val == SEED_COLOR)
205   - {
206   - vals[y, x] = COLOR;
207   - stack.Push(new Point(x + 1, y));
208   - stack.Push(new Point(x - 1, y));
209   - stack.Push(new Point(x, y + 1));
210   - stack.Push(new Point(x, y - 1));
211   - }
  289 + std::vector<point_t> poly;
  290 +
  291 + while( seedit != mmap.end() )
  292 + {
  293 + // invert y axis and add the new point to the poly
  294 + point_t pt = seedit->first;
  295 + pt.y = -pt.y;
  296 +
  297 + // can this vector simply extend the previous one?
  298 + size_t psize = poly.size();
  299 + if( psize > 2 ) // need at least two points already
  300 + {
  301 + // find the direction of the vector descrived by the two previous points
  302 + double ldx = direction( poly[psize-1].x - poly[psize-2].x );
  303 + double ldy = direction( poly[psize-1].y - poly[psize-2].y );
  304 +
  305 + // find the direction of the vector described by the new point and the previous point
  306 + double ndx = direction( pt.x - poly[psize-1].x );
  307 + double ndy = direction( pt.y - poly[psize-1].y );
  308 +
  309 + // if the direction is the same, we can replace the
  310 + // previous point with this one, rather than adding a
  311 + // new point
  312 + if( ldx == ndx && ldy == ndy )
  313 + poly[psize-1] = pt;
  314 + else
  315 + poly.push_back( pt );
  316 + }
  317 + else
  318 + poly.push_back( pt );
  319 +
  320 + point_t next = seedit->second;
  321 + mmap.erase( seedit );
  322 +
  323 + seedit = mmap.find( next );
  324 + }
  325 +
  326 + polys.push_back( poly );
212 327 }
  328 +
  329 + if( img ) img->release(); // frees all resources for this image
  330 + return 0; // ok
213 331 }
214   -*/
215 332
216 333 // POINTS -----------------------------------------------------------
217 334
64 libstage/stage.hh
@@ -476,6 +476,17 @@ namespace Stg
476 476
477 477 bool operator+=( const point_t& other )
478 478 { return ((x += other.x) && (y += other.y) ); }
  479 +
  480 + /** required to put these in sorted containers like std::map */
  481 + bool operator<( const point_t& other ) const
  482 + {
  483 + if( x < other.x ) return true;
  484 + if( other.x < x ) return false;
  485 + return y < other.y;
  486 + }
  487 +
  488 + bool operator==( const point_t& other ) const
  489 + { return ((x == other.x) && (y == other.y) ); }
479 490 };
480 491
481 492 /** Define a point in 3d space */
@@ -597,6 +608,10 @@ namespace Stg
597 608 int rotrects_from_image_file( const std::string& filename,
598 609 std::vector<rotrect_t>& rects );
599 610
  611 + int polys_from_image_file( const std::string& filename,
  612 + std::vector<std::vector<point_t> >& polys );
  613 +
  614 +
600 615 /** matching function should return true iff the candidate block is
601 616 stops the ray, false if the block transmits the ray
602 617 */
@@ -882,10 +897,10 @@ namespace Stg
882 897
883 898 double ppm; ///< the resolution of the world model in pixels per meter
884 899 bool quit; ///< quit this world ASAP
885   -
886 900 bool show_clock; ///< iff true, print the sim time on stdout
887 901 unsigned int show_clock_interval; ///< updates between clock outputs
888 902
  903 + //--- thread sync ----
889 904 pthread_mutex_t sync_mutex; ///< protect the worker thread management stuff
890 905 unsigned int threads_working; ///< the number of worker threads not yet finished
891 906 pthread_cond_t threads_start_cond; ///< signalled to unblock worker threads
@@ -956,15 +971,16 @@ namespace Stg
956 971 virtual std::string ClockString( void ) const;
957 972
958 973 Model* CreateModel( Model* parent, const std::string& typestr );
959   - void LoadModel( Worldfile* wf, int entity );
960   - void LoadBlock( Worldfile* wf, int entity );
  974 +
  975 + void LoadModel( Worldfile* wf, int entity );
  976 + void LoadBlock( Worldfile* wf, int entity );
961 977 void LoadBlockGroup( Worldfile* wf, int entity );
962   -
963   - void LoadSensor( Worldfile* wf, int entity );
  978 + void LoadSensor( Worldfile* wf, int entity );
964 979
965 980 virtual Model* RecentlySelectedModel() const { return NULL; }
966   -
967   - /** call Cell::AddBlock(block) for each cell on the polygon */
  981 +
  982 + /** Add the block to every raytrace bitmap cell that intersects
  983 + the edges of the polygon.*/
968 984 void MapPoly( const std::vector<point_int_t>& poly,
969 985 Block* block,
970 986 unsigned int layer );
@@ -972,13 +988,13 @@ namespace Stg
972 988 SuperRegion* AddSuperRegion( const point_int_t& coord );
973 989 SuperRegion* GetSuperRegion( const point_int_t& org );
974 990 SuperRegion* GetSuperRegionCreate( const point_int_t& org );
975   - //void ExpireSuperRegion( SuperRegion* sr );
976 991
977 992 /** convert a distance in meters to a distance in world occupancy
978 993 grid pixels */
979 994 int32_t MetersToPixels( meters_t x ) const
980 995 { return (int32_t)floor(x * ppm); };
981   -
  996 +
  997 + /** Return the bitmap coordinates corresponding to the location in meters. */
982 998 point_int_t MetersToPixels( const point_t& pt ) const
983 999 { return point_int_t( MetersToPixels(pt.x), MetersToPixels(pt.y)); };
984 1000
@@ -1208,9 +1224,7 @@ namespace Stg
1208 1224 after constructing the block.*/
1209 1225 Block( BlockGroup* group,
1210 1226 const std::vector<point_t>& pts,
1211   - const Bounds& zrange,
1212   - const Color& color,
1213   - bool inherit_color );
  1227 + const Bounds& zrange );
1214 1228
1215 1229 /** A from-file constructor */
1216 1230 Block( BlockGroup* group, Worldfile* wf, int entity);
@@ -1257,29 +1271,15 @@ namespace Stg
1257 1271
1258 1272 void Load( Worldfile* wf, int entity );
1259 1273
1260   - /** return a pointer to the Model that owns the BlockGroup that owns this Block.*/
1261   - Model* GetModel();
1262   -
1263   - const Color& GetColor();
1264   -
1265 1274 void Rasterize( uint8_t* data,
1266 1275 unsigned int width, unsigned int height,
1267 1276 meters_t cellwidth, meters_t cellheight );
1268   -
  1277 +
1269 1278 private:
1270   - //Model* mod; ///< model to which this block belongs.
1271   -
1272   - BlockGroup* group;
1273   -
  1279 + BlockGroup* group; ///< The BlockGroup to which this Block belongs.
1274 1280 std::vector<point_t> pts; ///< points defining a polygon.
1275   - Size size; ///< Size of the polygon in meters.
1276 1281 Bounds local_z; ///< z extent in local coords.
1277   - Color color; ///< Color of the polygon as seen in sensors and the GUI.
1278   - bool inherit_color; ///< Use parent's color instead of this->color.
1279   -
1280 1282 Bounds global_z; ///< z extent in global coordinates.
1281   -
1282   - bool mapped; ///< iff true, the block has been mapped in the bitmap (TODO: which layer?)
1283 1283
1284 1284 /** record the cells into which this block has been rendered so we
1285 1285 can remove them very quickly. One vector for each of the two
@@ -1296,6 +1296,7 @@ namespace Stg
1296 1296 friend class Model;
1297 1297 friend class Block;
1298 1298 friend class World;
  1299 + friend class SuperRegion;
1299 1300
1300 1301 private:
1301 1302 std::vector<Block> blocks; ///< Contains the blocks in this group.
@@ -1749,7 +1750,7 @@ namespace Stg
1749 1750 friend class ModelFiducial;
1750 1751
1751 1752 private:
1752   - /** the number of models instatiated - used to assign unique IDs */
  1753 + /** the number of models instatiated - used to assign unique sequential IDs */
1753 1754 static uint32_t count;
1754 1755 static std::map<id_t,Model*> modelsbyid;
1755 1756
@@ -1894,8 +1895,6 @@ namespace Stg
1894 1895 uint32_t id;
1895 1896 usec_t interval; ///< time between updates in usec
1896 1897 usec_t interval_energy; ///< time between updates of powerpack in usec
1897   - // usec_t interval_pose; ///< time between updates of pose due to velocity in usec
1898   -
1899 1898 usec_t last_update; ///< time of last update in us
1900 1899 bool log_state; ///< iff true, model state is logged
1901 1900 meters_t map_resolution;
@@ -2748,8 +2747,7 @@ namespace Stg
2748 2747 {
2749 2748 public:
2750 2749 public:
2751   - ModelRanger( World* world, Model* parent,
2752   - const std::string& type );
  2750 + ModelRanger( World* world, Model* parent, const std::string& type );
2753 2751 virtual ~ModelRanger();
2754 2752
2755 2753 virtual void Load();
8 libstage/world.cc
@@ -878,9 +878,9 @@ RaytraceResult World::Raytrace( const Ray& r )
878 878 if( (*r.func)( &block->group->mod, (Model*)r.mod, r.arg ))
879 879 {
880 880 // a hit!
881   - sample.color = block->GetColor();
882   - sample.mod = &block->group->mod;
883   -
  881 + sample.mod = &block->group->mod;
  882 + sample.color = sample.mod->GetColor();
  883 +
884 884 if( ax > ay ) // faster than the equivalent hypot() call
885 885 sample.range = fabs((globx-startx) / cosa) / ppm;
886 886 else
@@ -1051,7 +1051,7 @@ void World::MapPoly( const std::vector<point_int_t>& pts, Block* block, unsigned
1051 1051 GETSREG(globy)))
1052 1052 ->GetRegion( GETREG(globx),
1053 1053 GETREG(globy)));
1054   - // assert(reg);
  1054 + assert(reg);
1055 1055
1056 1056 // add all the required cells in this region before looking up
1057 1057 // another region
2  worlds/benchmark/cave.world
@@ -29,7 +29,7 @@ floorplan
29 29 name "cave"
30 30 size [16.000 16.000 0.600]
31 31 pose [0 0 0 0]
32   - bitmap "../bitmaps/cave.png"
  32 + bitmap "../bitmaps/cave_filled.png"
33 33 )
34 34
35 35 #define rob pioneer2dx
6 worlds/fasr.world
@@ -39,12 +39,12 @@ floorplan
39 39 name "cave"
40 40 pose [0 0 0 0]
41 41 size [16.000 16.000 0.600]
42   - bitmap "bitmaps/cave.png"
  42 + bitmap "bitmaps/cave_filled.png"
43 43 )
44 44
45 45 zone
46 46 (
47   - size [ 2.000 2.000 0 ]
  47 + size [ 2.000 2.000 0.01 ]
48 48 color "green"
49 49 pose [ -7.000 -7.000 0 0 ]
50 50 name "source"
@@ -53,7 +53,7 @@ zone
53 53
54 54 zone
55 55 (
56   - size [ 2.000 2.000 0 ]
  56 + size [ 2.000 2.000 0.01 ]
57 57 color "red"
58 58 pose [ 7.000 7.000 0 0 ]
59 59 name "sink"
2  worlds/map.inc
@@ -24,7 +24,7 @@ define floorplan model
24 24 define zone model
25 25 (
26 26 color "orange"
27   - size [ 4 4 0.02 ]
  27 + size [ 4 4 0.01 ]
28 28
29 29 gui_nose 0
30 30 gui_grid 0
3  worlds/walle.inc
@@ -30,7 +30,6 @@ define walle position
30 30 point[2] [ 0.9 0.75 ]
31 31 point[3] [ 0.1 0.75 ]
32 32 z [ 0.2 0.6 ]
33   - color "yellow"
34 33 )
35 34
36 35 # body top
@@ -53,7 +52,6 @@ define walle position
53 52 point[2] [ 0.0 0.25 ]
54 53 point[3] [ 0 0.0 ]
55 54 z [ 0.0 0.4 ]
56   - color "gray40"
57 55 )
58 56
59 57 # right wheel
@@ -76,7 +74,6 @@ define walle position
76 74 point[2] [0.6 0.49]
77 75 point[3] [0.6 0.30]
78 76 z [0.8 0.95]
79   - color "gray40"
80 77 )
81 78
82 79 # left eye front

0 comments on commit f0e1c49

Please sign in to comment.
Something went wrong with that request. Please try again.