Revision: 8064
http://playerstage.svn.sourceforge.net/playerstage/?rev=8064&view=rev
Author: rtv
Date: 2009-07-21 07:46:10 +0000 (Tue, 21 Jul 2009)
Log Message:
-----------
more STLing, and viz fixes
Modified Paths:
--------------
code/stage/trunk/examples/ctrl/fasr.cc
code/stage/trunk/libstage/canvas.cc
code/stage/trunk/libstage/model.cc
code/stage/trunk/libstage/model_callbacks.cc
code/stage/trunk/libstage/model_draw.cc
code/stage/trunk/libstage/model_load.cc
code/stage/trunk/libstage/stage.hh
code/stage/trunk/libstage/world.cc
code/stage/trunk/libstage/worldgui.cc
code/stage/trunk/worlds/fasr.world
Modified: code/stage/trunk/examples/ctrl/fasr.cc
===================================================================
--- code/stage/trunk/examples/ctrl/fasr.cc 2009-07-21 05:03:39 UTC (rev
8063)
+++ code/stage/trunk/examples/ctrl/fasr.cc 2009-07-21 07:46:10 UTC (rev
8064)
@@ -494,7 +494,6 @@
}
};
-
// Stage calls this when the model starts up
extern "C" int Init( Model* mod )
{
@@ -515,7 +514,6 @@
putchar( '\n' );
}
delete data;
-
}
new Robot( (ModelPosition*)mod,
Modified: code/stage/trunk/libstage/canvas.cc
===================================================================
--- code/stage/trunk/libstage/canvas.cc 2009-07-21 05:03:39 UTC (rev 8063)
+++ code/stage/trunk/libstage/canvas.cc 2009-07-21 07:46:10 UTC (rev 8064)
@@ -770,164 +770,166 @@
if( showTree || showOccupancy )
{
glPushMatrix();
-
- GLfloat scale = 1.0/world->Resolution();
+
+ GLfloat scale = 1.0/world->Resolution();
glScalef( scale, scale, 1.0 ); // XX TODO - this seems slightly
-
// out for Z. look into it.
-
+ // out for Z. look into it.
+
if( showOccupancy )
- ((WorldGui*)world)->DrawTree( false );
-
+ ((WorldGui*)world)->DrawTree( false );
+
if( showTree )
- ((WorldGui*)world)->DrawTree( true );
-
+ ((WorldGui*)world)->DrawTree( true );
+
glPopMatrix();
}
if( ! world->rt_cells.empty() )
- {
- glPushMatrix();
- GLfloat scale = 1.0/world->Resolution();
+ {
+ glPushMatrix();
+ GLfloat scale = 1.0/world->Resolution();
glScalef( scale, scale, 1.0 ); // XX TODO - this seems slightly
-
- world->PushColor( Color( 0,0,1,0.5) );
-
- glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
-
-
- glPointSize( 2 );
- glBegin( GL_POINTS );
-
- for( unsigned int i=0;
- i < world->rt_cells.size();
- i++ )
- {
- char str[128];
- snprintf( str, 128, "(%d,%d)",
- world->rt_cells[i].x,
- world->rt_cells[i].y );
-
- Gl::draw_string( world->rt_cells[i].x+1,
-
world->rt_cells[i].y+1, 0.1, str );
-
- //printf( "x: %d y: %d\n", world->rt_regions[i].x,
world->rt_regions[i].y );
- //glRectf( world->rt_cells[i].x+0.3,
world->rt_cells[i].y+0.3,
- // world->rt_cells[i].x+0.7,
world->rt_cells[i].y+0.7 );
-
- glVertex2f( world->rt_cells[i].x,
world->rt_cells[i].y );
-
- }
-
- glEnd();
-
+
+ world->PushColor( Color( 0,0,1,0.5) );
+
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+
+ glPointSize( 2 );
+ glBegin( GL_POINTS );
+
+ for( unsigned int i=0;
+ i < world->rt_cells.size();
+ i++ )
+ {
+ char str[128];
+ snprintf( str, 128, "(%d,%d)",
+
world->rt_cells[i].x,
+
world->rt_cells[i].y );
+
+ Gl::draw_string(
world->rt_cells[i].x+1,
+
world->rt_cells[i].y+1, 0.1, str );
+
+ //printf( "x: %d y: %d\n",
world->rt_regions[i].x, world->rt_regions[i].y );
+ //glRectf( world->rt_cells[i].x+0.3,
world->rt_cells[i].y+0.3,
+ // world->rt_cells[i].x+0.7,
world->rt_cells[i].y+0.7 );
+
+ glVertex2f( world->rt_cells[i].x,
world->rt_cells[i].y );
+
+ }
+
+ glEnd();
+
#if 1
world->PushColor( Color( 0,1,0,0.2) );
glBegin( GL_LINE_STRIP );
for( unsigned int i=0;
- i < world->rt_cells.size();
- i++ )
+ i < world->rt_cells.size();
+ i++ )
{
- glVertex2f( world->rt_cells[i].x+0.5,
world->rt_cells[i].y+0.5 );
+ glVertex2f( world->rt_cells[i].x+0.5,
world->rt_cells[i].y+0.5 );
}
glEnd();
world->PopColor();
#endif
-
+
glPopMatrix();
- world->PopColor();
+ world->PopColor();
}
-
+
if( ! world->rt_candidate_cells.empty() )
- {
- glPushMatrix();
- GLfloat scale = 1.0/world->Resolution();
+ {
+ glPushMatrix();
+ GLfloat scale = 1.0/world->Resolution();
glScalef( scale, scale, 1.0 ); // XX TODO - this seems slightly
-
- world->PushColor( Color( 1,0,0,0.5) );
-
- glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
-
- for( unsigned int i=0;
- i < world->rt_candidate_cells.size();
- i++ )
- {
-// char str[128];
-// snprintf( str, 128, "(%d,%d)",
-//
world->rt_candidate_cells[i].x,
-//
world->rt_candidate_cells[i].y );
-
-// Gl::draw_string( world->rt_candidate_cells[i].x+1,
-//
world->rt_candidate_cells[i].y+1, 0.1, str );
-
- //printf( "x: %d y: %d\n", world->rt_regions[i].x,
world->rt_regions[i].y );
- glRectf( world->rt_candidate_cells[i].x,
world->rt_candidate_cells[i].y,
-
world->rt_candidate_cells[i].x+1, world->rt_candidate_cells[i].y+1 );
- }
-
- world->PushColor( Color( 0,1,0,0.2) );
- glBegin( GL_LINE_STRIP );
- for( unsigned int i=0;
- i < world->rt_candidate_cells.size();
- i++ )
- {
- glVertex2f( world->rt_candidate_cells[i].x+0.5,
world->rt_candidate_cells[i].y+0.5 );
- }
- glEnd();
- world->PopColor();
-
+
+ world->PushColor( Color( 1,0,0,0.5) );
+
+ glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
+
+ for( unsigned int i=0;
+ i < world->rt_candidate_cells.size();
+ i++ )
+ {
+ // char str[128];
+ // snprintf( str,
128, "(%d,%d)",
+ //
world->rt_candidate_cells[i].x,
+ //
world->rt_candidate_cells[i].y );
+
+ //
Gl::draw_string( world->rt_candidate_cells[i].x+1,
+ //
world->rt_candidate_cells[i].y+1, 0.1, str );
+
+ //printf( "x: %d y: %d\n",
world->rt_regions[i].x, world->rt_regions[i].y );
+ glRectf(
world->rt_candidate_cells[i].x, world->rt_candidate_cells[i].y,
+
world->rt_candidate_cells[i].x+1, world->rt_candidate_cells[i].y+1 );
+ }
+
+ world->PushColor( Color( 0,1,0,0.2) );
+ glBegin( GL_LINE_STRIP );
+ for( unsigned int i=0;
+ i < world->rt_candidate_cells.size();
+ i++ )
+ {
+ glVertex2f(
world->rt_candidate_cells[i].x+0.5, world->rt_candidate_cells[i].y+0.5 );
+ }
+ glEnd();
+ world->PopColor();
+
glPopMatrix();
- world->PopColor();
-
- //world->rt_cells.clear();
+ world->PopColor();
+
+ //world->rt_cells.clear();
}
-
-
- if( showFootprints )
- {
- glDisable( GL_DEPTH_TEST );
-
- FOR_EACH( it, models_sorted )
- (*it)->DrawTrailFootprint();
-
- glEnable( GL_DEPTH_TEST );
- }
+
+
if( showGrid )
- DrawGlobalGrid();
+ DrawGlobalGrid();
else
- DrawFloor();
+ DrawFloor();
+ if( showFootprints )
+ {
+ glDisable( GL_DEPTH_TEST );
+
+ FOR_EACH( it, models_sorted )
+ (*it)->DrawTrailFootprint();
+
+ glEnable( GL_DEPTH_TEST );
+ }
+
if( showBlocks )
- DrawBlocks();
-
+ DrawBlocks();
+
if( showBBoxes )
- DrawBoundingBoxes();
-
+ DrawBoundingBoxes();
+
// TODO - finish this properly
//LISTMETHOD( models_sorted, Model*, DrawWaypoints );
+
+
-// MOTION BLUR
+ // MOTION BLUR
if( 0 )//showBlur )
- {
- DrawBlocks();
-
- //static float count = 0;
-
- if( ! blur )
- {
- blur = true;
- glClear( GL_ACCUM_BUFFER_BIT | GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT );
- glAccum( GL_LOAD, 1.0 );
- }
- else
- {
- glAccum( GL_MULT, 0.9 );
- glAccum( GL_ACCUM, 0.1 );
-
- glAccum( GL_RETURN, 1.1 );
-
- DrawBlocks(); // outline at current location
- }
+ {
+ DrawBlocks();
+
+ //static float count = 0;
+
+ if( ! blur )
+ {
+ blur = true;
+ glClear( GL_ACCUM_BUFFER_BIT |
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+ glAccum( GL_LOAD, 1.0 );
+ }
+ else
+ {
+ glAccum( GL_MULT, 0.9 );
+ glAccum( GL_ACCUM, 0.1 );
+
+ glAccum( GL_RETURN, 1.1 );
+
+ DrawBlocks(); // outline at current
location
+ }
}
// GRAY TRAILS
@@ -1137,7 +1139,7 @@
void Canvas::EnterScreenCS()
{
- //use orthogonal projeciton without any zoom
+ //use orthogonal projection without any zoom
glMatrixMode (GL_PROJECTION);
glPushMatrix(); //save old projection
glLoadIdentity ();
@@ -1170,13 +1172,13 @@
// pixels avoid a nasty word-alignment problem when indexing into
// the pixel array.
- // might save a bit of time as the image size rarely changes
- static uint8_t* pixels = NULL;
- pixels = g_renew( uint8_t, pixels, width * height * depth );
+ // might save a bit of time with a static var as the image size rarely
changes
+ static std::vector<uint8_t> pixels;
+ pixels.resize( width * height * depth );
glFlush(); // make sure the drawing is done
// read the pixels from the screen
- glReadPixels( 0,0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels );
+ glReadPixels( 0,0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0] );
static uint32_t count = 0;
char filename[64];
@@ -1185,7 +1187,7 @@
FILE *fp = fopen( filename, "wb" );
if( fp == NULL )
{
- PRINT_ERR1( "Unable to open %s", filename );
+ PRINT_ERR1( "Unable to open %s", filename );
}
// create PNG data
@@ -1253,9 +1255,9 @@
showOccupancy.createMenuItem( menu, path );
//showTrailArrows.createMenuItem( menu, path ); // broken
showTrails.createMenuItem( menu, path );
- // showTrailRise.createMenuItem( menu, path ); // broken
+ //showTrailRise.createMenuItem( menu, path ); // broken
showBBoxes.createMenuItem( menu, path );
- showBlur.createMenuItem( menu, path );
+ //showBlur.createMenuItem( menu, path );
showTree.createMenuItem( menu, path );
showScreenshots.createMenuItem( menu, path );
}
Modified: code/stage/trunk/libstage/model.cc
===================================================================
--- code/stage/trunk/libstage/model.cc 2009-07-21 05:03:39 UTC (rev 8063)
+++ code/stage/trunk/libstage/model.cc 2009-07-21 07:46:10 UTC (rev 8064)
@@ -196,11 +196,11 @@
blockgroup(),
blocks_dl(0),
boundary(false),
- callbacks( g_hash_table_new( g_direct_hash, g_direct_equal ) ),
+ callbacks(),// g_hash_table_new( g_direct_hash, g_direct_equal ) ),
color( 1,0,0 ), // red
data_fresh(false),
disabled(false),
- cv_list(),
+ cv_list(),
flag_list(),
geom(),
has_default_block( true ),
@@ -208,33 +208,35 @@
initfunc(NULL),
interval((stg_usec_t)1e4), // 10msec
last_update(0),
- log_state(false),
+ log_state(false),
map_resolution(0.1),
mass(0),
on_velocity_list( false ),
parent(parent),
pose(),
- power_pack( NULL ),
- pps_charging(),
+ power_pack( NULL ),
+ pps_charging(),
props(NULL),
- rastervis(),
+ rastervis(),
rebuild_displaylist(true),
say_string(NULL),
stall(false),
subs(0),
thread_safe( false ),
- trail( g_array_new( false, false, sizeof(stg_trail_item_t) )),
+ trail(),
+ trail_length(25),
+ trail_interval(5),
type(type),
- update_list_num( -1 ),
+ update_list_num( -1 ),
used(false),
velocity(),
watts(0.0),
- watts_give(0.0),
- watts_take(0.0),
+ watts_give(0.0),
+ watts_take(0.0),
wf(NULL),
wf_entity(0),
world(world),
- world_gui( dynamic_cast<WorldGui*>( world ) )
+ world_gui( dynamic_cast<WorldGui*>( world ) )
{
//assert( modelsbyid );
assert( world );
@@ -281,7 +283,7 @@
ModelPtrVec& vec = parent ? parent->children : world->children;
vec.erase( std::remove( vec.begin(), vec.end(), this ));
- if( callbacks ) g_hash_table_destroy( callbacks );
+ //if( callbacks ) g_hash_table_destroy( callbacks );
g_datalist_clear( &props );
@@ -864,21 +866,14 @@
if( disabled )
return;
- // TODO - control this properly, and maybe do it faster
- //if( 0 )
- //if( (world->updates % 10 == 0) )
- // {
- // stg_trail_item_t checkpoint;
- // memcpy( &checkpoint.pose, &pose, sizeof(pose));
- // checkpoint.color = color;
- // checkpoint.time = world->sim_time;
-
- // if( trail->len > 100 )
- // g_array_remove_index( trail, 0 );
-
- // g_array_append_val( this->trail, checkpoint );
- // }
-
+ if( world->updates % trail_interval == 0 )
+ {
+ trail.push_back( TrailItem( world->sim_time,
GetGlobalPose(), color ) );
+
+ if( trail.size() > trail_length )
+ trail.pop_front();
+ }
+
// convert usec to sec
double interval( (double)world->interval_sim / 1e6 );
Modified: code/stage/trunk/libstage/model_callbacks.cc
===================================================================
--- code/stage/trunk/libstage/model_callbacks.cc 2009-07-21 05:03:39 UTC
(rev 8063)
+++ code/stage/trunk/libstage/model_callbacks.cc 2009-07-21 07:46:10 UTC
(rev 8064)
@@ -1,141 +1,50 @@
#include "stage.hh"
using namespace Stg;
+using namespace std;
-
void Model::AddCallback( void* address,
stg_model_callback_t cb,
void* user )
{
-// // treat update callbacks specially as they are so frequently called
-// if( address == &hooks.update )
-// {
-// // a dedicated vector avoids a hash table lookup
-// update_callbacks.push_back( std::pair<stg_model_callback_t,void*>(
cb, user ) );
-// }
-// else
- {
- GList* cb_list = (GList*)g_hash_table_lookup( callbacks, address );
-
- //printf( "installing callback in model %s with key %p\n",
- // token, address );
-
- // add the callback & argument to the list
- cb_list = g_list_prepend( cb_list, new stg_cb_t( cb, user ) );
-
- // and replace the list in the hash table
- g_hash_table_insert( callbacks, address, cb_list );
- }
+ callbacks[address].insert( stg_cb_t( cb, user ));
}
-int Model::RemoveCallback( void* member,
- stg_model_callback_t callback )
+int Model::RemoveCallback( void* address,
+
stg_model_callback_t callback )
{
-
- // XX TODO
- // if( address == &hooks.update )
- // {
- // std::erase( std::remove( update_callbacks.begin();
update_callbacks.end(),
-
- GList* cb_list = (GList*)g_hash_table_lookup( callbacks, member );
-
- // find our callback in the list of stg_cbarg_t
- GList* el = NULL;
-
- // scan the list for the first matching callback
- for( el = g_list_first( cb_list );
- el;
- el = el->next )
- {
- if( ((stg_cb_t*)el->data)->callback == callback )
- break;
- }
-
- if( el ) // if we found the matching callback, remove it
- {
- //puts( "removed callback" );
-
- cb_list = g_list_remove( cb_list, el->data);
-
- // store the new, shorter, list of callbacks
- g_hash_table_insert( callbacks, member, cb_list );
-
- // we're done with the stored data
- delete (stg_cb_t*)(el->data);
- }
- else
- {
- //puts( "callback was not installed" );
- }
+ set<stg_cb_t>& callset = callbacks[address];
- // return the number of callbacks now in the list. Useful for
- // detecting when the list is empty.
- return g_list_length( cb_list );
+ callset.erase( stg_cb_t( callback, NULL) );
+
+ // return the number of callbacks remaining for this address. Useful
+ // for detecting when there are none.
+ return callset.size();
}
-void Model::CallCallbacks( void* address )
+int Model::CallCallbacks( void* address )
{
-
assert( address );
-// // avoid a hash table lookup for
-// if( address == &hooks.update )
-// {
-// FOR_EACH( it, update_callbacks )
-// (it->first)( this, it->second );
-
-// return;
-// }
-
-
- //int key = key_gen( this, address );
+ // maintain a list of callbacks that should be cancelled
+ vector<stg_cb_t> doomed;
- //printf( "CallCallbacks for model %s %p key %p\n", this->Token(),
this, address );
-
- //printf( "Model %s has %d callbacks. Checking key %d\n",
- // this->token, g_hash_table_size( this->callbacks ),
key );
+ set<stg_cb_t>& callset = callbacks[address];
- GList* cbs = (GList*)g_hash_table_lookup( callbacks, address );
+ FOR_EACH( it, callset )
+ {
+ const stg_cb_t& cba = *it;
+ if( (cba.callback)( this, cba.arg ) )
+ doomed.push_back( cba );
+ }
- //printf( "key %p has %d callbacks registered\n",
- // address, g_list_length( cbs ) );
-
- // maintain a list of callbacks that should be cancelled
- GList* doomed = NULL;
+ FOR_EACH( it, doomed )
+ callset.erase( *it );
- // for each callback in the list
- while( cbs )
- {
- //printf( "cbs %p data %p cvs->next %p\n", cbs, cbs->data, cbs->next
);
-
- stg_cb_t* cba = (stg_cb_t*)cbs->data;
- assert( cba );
-
- if( (cba->callback)( this, cba->arg ) )
- {
- //printf( "callback returned TRUE - schedule removal from
list\n" );
- doomed = g_list_prepend( doomed, (void*)cba->callback );
- }
- else
- {
- //printf( "callback returned FALSE - keep in list\n" );
- }
-
- cbs = cbs->next;
- }
-
- if( doomed ) // delete all the callbacks that returned TRUE
- {
- //printf( "removing %d doomed callbacks\n", g_list_length(
doomed ) );
-
- for( ; doomed ; doomed = doomed->next )
- this->RemoveCallback( address,
(stg_model_callback_t)doomed->data );
-
- g_list_free( doomed );
- }
-
- //puts( "Callbacks done" );
+ // return the number of callbacks remaining for this address. Useful
+ // for detecting when there are none.
+ return callset.size();
}
Modified: code/stage/trunk/libstage/model_draw.cc
===================================================================
--- code/stage/trunk/libstage/model_draw.cc 2009-07-21 05:03:39 UTC (rev
8063)
+++ code/stage/trunk/libstage/model_draw.cc 2009-07-21 07:46:10 UTC (rev
8064)
@@ -50,26 +50,33 @@
void Model::DrawTrailFootprint()
{
- for( int i=trail->len-1; i>=0; i-- )
+ double darkness = 0;
+ double fade = 0.5 / (double)(trail_length+1);
+
+ FOR_EACH( it, trail )
{
- stg_trail_item_t* checkpoint = & g_array_index( trail, stg_trail_item_t,
i );
-
+ TrailItem& checkpoint = *it;
+
glPushMatrix();
- Gl::pose_shift( checkpoint->pose );
- Gl::pose_shift( geom.pose );
+ Pose pz = checkpoint.pose;
+ pz.z += 0.02;
+ Gl::pose_shift( pz );
+ Gl::pose_shift( geom.pose );
+
+ darkness += fade;
- //stg_color_unpack( checkpoint->color, &r, &g, &b, &a );
- Color c = checkpoint->color;
- c.a = 0.1;
- PushColor( c );
+ Color c = checkpoint.color;
+ c.a = darkness;
+ PushColor( c );
+
blockgroup.DrawFootPrint( geom );
-
+
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
- PushColor( c.r/2, c.g/2, c.b/2, 0.1 );
-
+ PushColor( c.r/2, c.g/2, c.b/2, darkness );
+
blockgroup.DrawFootPrint( geom );
-
+
PopColor();
PopColor();
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
@@ -81,17 +88,14 @@
{
double timescale = 0.0000001;
- for( int i=trail->len-1; i>=0; i-- )
+ FOR_EACH( it, trail )
{
- stg_trail_item_t* checkpoint = & g_array_index( trail, stg_trail_item_t,
i );
+ TrailItem& checkpoint = *it;
- Pose pose;
- memcpy( &pose, &checkpoint->pose, sizeof(pose));
- pose.z = (world->sim_time - checkpoint->time) * timescale;
+ Pose pose = checkpoint.pose;
+ pose.z = (world->sim_time - checkpoint.time) * timescale;
PushLocalCoords();
- //blockgroup.Draw( this );
-
DrawBlocksTree();
PopCoords();
}
@@ -103,19 +107,18 @@
double dy = 0.07;
double timescale = 0.0000001;
- for( unsigned int i=0; i<trail->len; i++ )
+ FOR_EACH( it, trail )
{
- stg_trail_item_t* checkpoint = & g_array_index( trail, stg_trail_item_t,
i );
+ TrailItem& checkpoint = *it;
- Pose pose;
- memcpy( &pose, &checkpoint->pose, sizeof(pose));
- pose.z = (world->sim_time - checkpoint->time) * timescale;
+ Pose pose = checkpoint.pose;
+ pose.z = (world->sim_time - checkpoint.time) * timescale;
PushLocalCoords();
// set the height proportional to age
- PushColor( checkpoint->color );
+ PushColor( checkpoint.color );
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(1.0, 1.0);
@@ -128,13 +131,13 @@
glDisable(GL_POLYGON_OFFSET_FILL);
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
+
+ Color c = checkpoint.color;
+ c.r /= 2.0;
+ c.g /= 2.0;
+ c.b /= 2.0;
+ PushColor( c ); // darker color
- Color c = checkpoint->color;
- c.r /= 2.0;
- c.g /= 2.0;
- c.b /= 2.0;
- PushColor( c ); // darker color
-
glDepthMask(GL_FALSE);
glBegin( GL_TRIANGLES );
glVertex3f( 0, -dy, 0);
Modified: code/stage/trunk/libstage/model_load.cc
===================================================================
--- code/stage/trunk/libstage/model_load.cc 2009-07-21 05:03:39 UTC (rev
8063)
+++ code/stage/trunk/libstage/model_load.cc 2009-07-21 07:46:10 UTC (rev
8064)
@@ -226,6 +226,8 @@
if( wf->PropertyExists( wf_entity, "say" ))
this->Say( wf->ReadString(wf_entity, "say", NULL ));
+ trail_length = wf->ReadInt( wf_entity, "trail_length", trail_length );
+ trail_interval = wf->ReadInt( wf_entity, "trail_interval",
trail_interval );
// call any type-specific load callbacks
this->CallCallbacks( &hooks.load );
Modified: code/stage/trunk/libstage/stage.hh
===================================================================
--- code/stage/trunk/libstage/stage.hh 2009-07-21 05:03:39 UTC (rev 8063)
+++ code/stage/trunk/libstage/stage.hh 2009-07-21 07:46:10 UTC (rev 8064)
@@ -49,6 +49,7 @@
#include <ext/hash_map>
//#include <unordered_map>
#include <set>
+#include <queue>
#include <algorithm>
// we use GLib's data structures extensively. Gradually we're moving
@@ -118,14 +119,13 @@
MODEL_TYPE_BLOBFINDER,
MODEL_TYPE_BLINKENLIGHT,
MODEL_TYPE_CAMERA,
- MODEL_TYPE_GRIPPER,
- MODEL_TYPE_ACTUATOR,
- MODEL_TYPE_LOADCELL,
- MODEL_TYPE_LIGHTINDICATOR,
- MODEL_TYPE_COUNT // must be the last entry, to count the number of
- // types
+ MODEL_TYPE_GRIPPER,
+ MODEL_TYPE_ACTUATOR,
+ MODEL_TYPE_LOADCELL,
+ MODEL_TYPE_LIGHTINDICATOR,
+ MODEL_TYPE_COUNT // must be the last entry, to count the number of types
} stg_model_type_t;
-
+
/// Copyright string
const char COPYRIGHT[] =
"Copyright Richard Vaughan and contributors 2000-2009";
@@ -144,7 +144,7 @@
/// Project distribution license string
const char LICENSE[] =
"Stage robot simulation library\n" \
- "Copyright (C) 2000-2008 Richard Vaughan and contributors\n" \
+ "Copyright (C) 2000-2009 Richard Vaughan and contributors\n" \
"Part of the Player Project [http://playerstage.org]\n" \
"\n" \
"This program is free software; you can redistribute it and/or\n" \
@@ -195,12 +195,6 @@
/** take binary sign of a, either -1, or 1 if >= 0. */
inline double sgn( double a){ return( a<0 ? -1.0 : 1.0); }
-
- /** Describe the image format used for saving screenshots. */
- typedef enum {
- STG_IMAGE_FORMAT_PNG,
- STG_IMAGE_FORMAT_JPG
- } stg_image_format_t;
/** any integer value other than this is a valid fiducial ID */
enum { FiducialNone = 0 };
@@ -300,9 +294,9 @@
stg_meters_t ymin, stg_meters_t
ymax )
{
return Pose( xmin + drand48() * (xmax-xmin),
- ymin + drand48() * (ymax-ymin),
- 0,
- normalize( drand48() * (2.0 * M_PI) ));
+ ymin +
drand48() * (ymax-ymin),
+ 0,
+
normalize( drand48() * (2.0 * M_PI) ));
}
/** Print pose in human-readable format on stdout
@@ -605,30 +599,17 @@
double duty_cycle; ///< mark/space ratio
} stg_blinkenlight_t;
- typedef struct {
+ class TrailItem
+ {
+ public:
+ stg_usec_t time;
Pose pose;
Color color;
- stg_usec_t time;
- } stg_trail_item_t;
-
- /** container for a callback function and a single argument, so
- they can be stored together in a list with a single pointer. */
- class stg_cb_t
- {
- public:
- stg_model_callback_t callback;
- void* arg;
-
- stg_cb_t( stg_model_callback_t cb, void* arg )
- : callback(cb), arg(arg) {}
- stg_cb_t( stg_world_callback_t cb, void* arg )
- : callback(NULL), arg(arg) {}
-
- stg_cb_t() : callback(NULL), arg(NULL) {}
+ TrailItem( stg_usec_t time, Pose pose, Color color )
+ : time(time), pose(pose), color(color){}
};
-
/** Defines a rectangle of [size] located at [pose] */
typedef struct
{
@@ -853,10 +834,10 @@
{ return( strcmp( a, b ) == 0 ); }
};
- __gnu_cxx::hash_map<const char*, Model*, __gnu_cxx::hash<const char*>,
eqstr > models_by_name; ///< the models that make up the world, indexed by name.
- //tr1::unordered_map<const char*, Model*, __gnu_cxx::hash<const
char*>, eqstr > models_by_name; ///< the models that make up the world, indexed
by name.
+ __gnu_cxx::hash_map<const char*, Model*, __gnu_cxx::hash<const
char*>, eqstr > models_by_name; ///< the models that make up the world, indexed
by name.
+
+ std::map<int,Model*> models_by_wfentity;
-
/** Keep a list of all models with detectable fiducials. This
avoids searching the whole world for fiducials. */
ModelPtrSet models_with_fiducials;
@@ -884,7 +865,6 @@
stg_bounds3d_t extent; ///< Describes the 3D volume of the world
bool graphics;///< true iff we have a GUI
stg_usec_t interval_sim; ///< temporal resolution: microseconds that
elapse between simulated time steps
- //GHashTable* option_table; ///< GUI options (toggles) registered by
models
std::set<Option*> option_table; ///< GUI options (toggles) registered
by models
std::list<PowerPack*> powerpack_list; ///< List of all the powerpacks
attached to models in the world
std::list<float*> ray_list;///< List of rays traced for debug
visualization
@@ -930,110 +910,109 @@
/** hint that the world needs to be redrawn if a GUI is attached */
void NeedRedraw(){ dirty = true; };
-
- /** Special model for the floor of the world */
- Model* ground;
-
+
+ /** Special model for the floor of the world */
+ Model* ground;
+
/** Get human readable string that describes the current simulation
- time. */
+ time. */
virtual std::string ClockString( void );
+
+ Model* CreateModel( Model* parent, const char* typestr );
+ void LoadModel( Worldfile* wf, int entity );
+ void LoadBlock( Worldfile* wf, int entity );
+ void LoadBlockGroup( Worldfile* wf, int entity );
- Model* CreateModel( Model* parent, const char* typestr );
- void LoadModel( Worldfile* wf, int entity, GHashTable* entitytable );
- void LoadBlock( Worldfile* wf, int entity, GHashTable* entitytable );
- void LoadBlockGroup( Worldfile* wf, int entity, GHashTable* entitytable );
- // void LoadPuck( Worldfile* wf, int entity, GHashTable* entitytable
);
-
- virtual Model* RecentlySelectedModel(){ return NULL; }
-
+ virtual Model* RecentlySelectedModel(){ return NULL; }
+
SuperRegion* AddSuperRegion( const stg_point_int_t& coord );
SuperRegion* GetSuperRegion( const stg_point_int_t& coord );
SuperRegion* GetSuperRegionCached( const stg_point_int_t& coord);
SuperRegion* GetSuperRegionCached( int32_t x, int32_t y );
void ExpireSuperRegion( SuperRegion* sr );
-
+
inline Cell* GetCell( const stg_point_int_t& glob );
-
- /** add a Cell pointer to the vector for each cell on the line from
- pt1 to pt2 inclusive */
+
+ /** add a Cell pointer to the vector for each cell on the line
from
+ pt1 to pt2 inclusive */
void ForEachCellInLine( const stg_point_int_t& pt1,
- const
stg_point_int_t& pt2,
-
CellPtrVec& cells );
-
+
const stg_point_int_t& pt2,
+
CellPtrVec& cells );
+
/** convert a distance in meters to a distance in world occupancy
- grid pixels */
+ grid pixels */
int32_t MetersToPixels( stg_meters_t x )
{ return (int32_t)floor(x * ppm); };
-
+
stg_point_int_t MetersToPixels( const stg_point_t& pt )
{ return stg_point_int_t( MetersToPixels(pt.x), MetersToPixels(pt.y)); };
-
+
// dummy implementations to be overloaded by GUI subclasses
virtual void PushColor( Color col ) { /* do nothing */ };
virtual void PushColor( double r, double g, double b, double a ) { /* do
nothing */ };
virtual void PopColor(){ /* do nothing */ };
-
+
SuperRegion* CreateSuperRegion( stg_point_int_t origin );
void DestroySuperRegion( SuperRegion* sr );
-
- /** trace a ray. */
- stg_raytrace_result_t Raytrace( const Ray& ray );
+
+ /** trace a ray. */
+ stg_raytrace_result_t Raytrace( const Ray& ray );
stg_raytrace_result_t Raytrace( const Pose& pose,
-
const stg_meters_t range,
-
const stg_ray_test_func_t func,
-
const Model* finder,
-
const void* arg,
-
const bool ztest );
-
+
const
stg_meters_t range,
+
const
stg_ray_test_func_t func,
+
const Model*
finder,
+
const void* arg,
+
const bool
ztest );
+
void Raytrace( const Pose &pose,
- const stg_meters_t range,
- const stg_radians_t fov,
- const stg_ray_test_func_t func,
- const Model* finder,
- const void* arg,
- stg_raytrace_result_t* samples,
- const uint32_t sample_count,
- const bool ztest );
-
-
+ const
stg_meters_t range,
+ const
stg_radians_t fov,
+ const
stg_ray_test_func_t func,
+ const
Model* finder,
+ const
void* arg,
+
stg_raytrace_result_t* samples,
+ const
uint32_t sample_count,
+ const
bool ztest );
+
+
/** Enlarge the bounding volume to include this point */
void Extend( stg_point3_t pt );
virtual void AddModel( Model* mod );
virtual void RemoveModel( Model* mod );
-
+
void AddPowerPack( PowerPack* pp );
void RemovePowerPack( PowerPack* pp );
-
+
void ClearRays();
/** store rays traced for debugging purposes */
void RecordRay( double x1, double y1, double x2, double y2 );
-
+
/** Returns true iff the current time is greater than the time we
- should quit */
+ should quit */
bool PastQuitTime();
-
+
int UpdateListAdd( Model* mod );
- void UpdateListRemove( Model* mod );
+ void UpdateListRemove( Model* mod );
- void VelocityListAdd( Model* mod );
- void VelocityListRemove( Model* mod );
-
- void ChargeListAdd( Model* mod );
- void ChargeListRemove( Model* mod );
-
+ void VelocityListAdd( Model* mod );
+ void VelocityListRemove( Model* mod );
+
+ void ChargeListAdd( Model* mod );
+ void ChargeListRemove( Model* mod );
+
static gpointer update_thread_entry( std::pair<World*,int>* info );
public:
/** returns true when time to quit, false otherwise */
static bool UpdateAll();
-
+
World( const char* token = "MyWorld",
- stg_msec_t interval_sim = DEFAULT_INTERVAL_SIM,
- double ppm = DEFAULT_PPM );
-
+ stg_msec_t interval_sim =
DEFAULT_INTERVAL_SIM,
+ double ppm = DEFAULT_PPM );
+
virtual ~World();
stg_usec_t SimTimeNow(void);
@@ -1718,18 +1697,43 @@
forming a solid boundary around the bounding box of the
model. */
int boundary;
-
- /** callback functions can be attached to any field in this
- structure. When the internal function
model_change(<mod>,<field>)
- is called, the callback is triggered */
- GHashTable* callbacks;
- /** Dedicated storage for update callbacks - avoids looking them up in
a hash table */
- //std::vector<std::pair<stg_model_callback_t,void*> > update_callbacks;
-
- /** Default color of the model's blocks.*/
- Color color;
- double friction;
-
+
+ /** container for a callback function and a single argument, so
+ they can be stored together in a list with a
single pointer. */
+ public:
+ class stg_cb_t
+ {
+ public:
+ stg_model_callback_t callback;
+ void* arg;
+
+ stg_cb_t( stg_model_callback_t cb, void* arg )
+ : callback(cb), arg(arg) {}
+
+ stg_cb_t( stg_world_callback_t cb, void* arg )
+ : callback(NULL), arg(arg) {}
+
+ stg_cb_t() : callback(NULL), arg(NULL) {}
+
+ /** for placing in a sorted container */
+ bool operator<( const stg_cb_t& other ) const
+ { return ((void*)(callback)) <
((void*)(other.callback)); }
+
+ /** for searching in a sorted container */
+ bool operator==( const stg_cb_t& other ) const
+ { return( callback == other.callback); }
+ };
+
+ protected:
+ /** A list of callback functions can be attached to any
+ address. When Model::CallCallbacks( void*) is
called, the
+ callbacks are called.*/
+ std::map<void*, std::set<stg_cb_t> > callbacks;
+
+ /** Default color of the model's blocks.*/
+ Color color;
+ double friction;
+
/** This can be set to indicate that the model has new data that
may be of interest to users. This allows polling the model
instead of adding a data callback. */
@@ -1786,7 +1790,6 @@
uint8_t* data;
unsigned int width, height;
stg_meters_t cellwidth, cellheight;
- //GList* pts;
std::vector<stg_point_t> pts;
public:
@@ -1807,19 +1810,30 @@
void ClearPts();
} rastervis;
-
- bool rebuild_displaylist; ///< iff true, regenerate block display list
before redraw
- char* say_string; ///< if non-null, this string is displayed in the
GUI
-
- stg_bool_t stall;
- /** Thread safety flag. Iff true, Update() may be called in
- parallel with other models. Defaults to false for safety */
- int subs; ///< the number of subscriptions to this model
- bool thread_safe;
- GArray* trail;
- stg_model_type_t type;
- /** The index into the world's vector of update lists. Initially
- -1, to indicate that it is not on a list yet. */
+
+ bool rebuild_displaylist; ///< iff true, regenerate block
display list before redraw
+ char* say_string; ///< if non-null, this string is displayed
in the GUI
+
+ stg_bool_t stall;
+ /** Thread safety flag. Iff true, Update() may be called in
+ parallel with other models. Defaults to false
for safety */
+ int subs; ///< the number of subscriptions to this model
+ bool thread_safe;
+
+ /** Cache of recent poses, used to draw the trail. */
+ std::list<TrailItem> trail;
+
+ /** The maxiumum length of the trail drawn. Default is 20, but
can
+ be set in the world file using the tail_length
model
+ property. */
+ unsigned int trail_length;
+
+ /** Number of world updates between trail records. */
+ long unsigned int trail_interval;
+
+ stg_model_type_t type;
+ /** The index into the world's vector of update lists. Initially
+ -1, to indicate that it is not on a list yet. */
int update_list_num;
bool used; ///< TRUE iff this model has been returned by
GetUnusedModelOfType()
Velocity velocity;
@@ -2213,23 +2227,23 @@
void SetGuiGrid( int val );
void SetGuiOutline( int val );
void SetWatts( stg_watts_t watts );
- void SetMapResolution( stg_meters_t res );
- void SetFriction( double friction );
+ void SetMapResolution( stg_meters_t res );
+ void SetFriction( double friction );
bool DataIsFresh() const { return this->data_fresh; }
/* attach callback functions to data members. The function gets
called when the member is changed using SetX() accessor method
*/
-
- void AddCallback( void* address,
- stg_model_callback_t
cb,
- void* user );
-
- int RemoveCallback( void* member,
-
stg_model_callback_t callback );
-
- void CallCallbacks( void* address );
-
+
+ void AddCallback( void* address,
+
stg_model_callback_t cb,
+
void* user );
+
+ int RemoveCallback( void* member,
+
stg_model_callback_t callback );
+
+ int CallCallbacks( void* address );
+
/* wrappers for the generic callback add & remove functions that hide
some implementation detail */
Modified: code/stage/trunk/libstage/world.cc
===================================================================
--- code/stage/trunk/libstage/world.cc 2009-07-21 05:03:39 UTC (rev 8063)
+++ code/stage/trunk/libstage/world.cc 2009-07-21 07:46:10 UTC (rev 8064)
@@ -222,11 +222,10 @@
mod->Init();
}
-void World::LoadBlock( Worldfile* wf, int entity, GHashTable* entitytable )
+void World::LoadBlock( Worldfile* wf, int entity )
{
// lookup the group in which this was defined
- Model* mod = (Model*)g_hash_table_lookup( entitytable,
-
(gpointer)wf->GetEntityParent( entity ) );
+ Model* mod = models_by_wfentity[ wf->GetEntityParent( entity )];
if( ! mod )
PRINT_ERR( "block has no model for a parent" );
@@ -276,15 +275,14 @@
}
-void World::LoadModel( Worldfile* wf, int entity, GHashTable* entitytable )
+void World::LoadModel( Worldfile* wf, int entity )
{
int parent_entity = wf->GetEntityParent( entity );
PRINT_DEBUG2( "wf entity %d parent entity %d\n",
entity, parent_entity );
- Model* parent = (Model*)g_hash_table_lookup( entitytable,
-
(gpointer)parent_entity );
+ Model* parent = models_by_wfentity[ parent_entity ];
char *typestr = (char*)wf->GetEntityType(entity);
assert(typestr);
@@ -295,7 +293,7 @@
mod->Load(wf, entity );
// record the model we created for this worlfile entry
- g_hash_table_insert( entitytable, (gpointer)entity, mod );
+ models_by_wfentity[entity] = mod;
}
void World::Load( const char* worldfile_path )
@@ -303,8 +301,6 @@
// note: must call Unload() before calling Load() if a world already
// exists TODO: unload doesn't clean up enough right now
- GHashTable* entitytable = g_hash_table_new( g_direct_hash, g_direct_equal );
-
printf( " [Loading %s]", worldfile_path );
fflush(stdout);
@@ -366,30 +362,26 @@
// don't load window entries here
if( strcmp( typestr, "window" ) == 0 )
- {
- /* do nothing here */
- }
+ {
+ /* do nothing here */
+ }
else if( strcmp( typestr, "block" ) == 0 )
- LoadBlock( wf, entity, entitytable );
- else
- LoadModel( wf, entity, entitytable );
+ LoadBlock( wf, entity );
+ else
+ LoadModel( wf, entity );
}
-
-
+
// warn about unused WF lines
wf->WarnUnused();
- // now we're done with the worldfile entry lookup
- g_hash_table_destroy( entitytable );
-
FOR_EACH( it, children )
- (*it)->InitRecursive();
+ (*it)->InitRecursive();
stg_usec_t load_end_time = RealTimeNow();
-
+
if( debug )
printf( "[Load time %.3fsec]\n",
- (load_end_time - load_start_time) / 1000000.0 );
+ (load_end_time -
load_start_time) / 1e6 );
else
putchar( '\n' );
}
@@ -404,7 +396,7 @@
//g_hash_table_remove_all( models_by_name );
models_by_name.clear();
-
+ models_by_wfentity.clear();
update_lists.resize(1);
ray_list.clear();
Modified: code/stage/trunk/libstage/worldgui.cc
===================================================================
--- code/stage/trunk/libstage/worldgui.cc 2009-07-21 05:03:39 UTC (rev
8063)
+++ code/stage/trunk/libstage/worldgui.cc 2009-07-21 07:46:10 UTC (rev
8064)
@@ -224,8 +224,8 @@
mbar->add( "Run/Pause", 'p', (Fl_Callback*) WorldGui::pauseCb, this );
mbar->add( "Run/One step", '.', (Fl_Callback*) WorldGui::onceCb, this,
FL_MENU_DIVIDER );
mbar->add( "Run/Faster", ']', (Fl_Callback*) WorldGui::fasterCb, this );
- mbar->add( "Run/Slower", '[', (Fl_Callback*) WorldGui::slowerCb, this );
- mbar->add( "Run/Realtime", '{', (Fl_Callback*) WorldGui::realtimeCb, this,
FL_MENU_DIVIDER );
+ mbar->add( "Run/Slower", '[', (Fl_Callback*) WorldGui::slowerCb, this,
FL_MENU_DIVIDER );
+ mbar->add( "Run/Realtime", '{', (Fl_Callback*) WorldGui::realtimeCb, this );
mbar->add( "Run/Fast", '}', (Fl_Callback*) WorldGui::fasttimeCb, this );
mbar->add( "&Help", 0, 0, 0, FL_SUBMENU );
Modified: code/stage/trunk/worlds/fasr.world
===================================================================
--- code/stage/trunk/worlds/fasr.world 2009-07-21 05:03:39 UTC (rev 8063)
+++ code/stage/trunk/worlds/fasr.world 2009-07-21 07:46:10 UTC (rev 8064)
@@ -87,10 +87,6 @@
)
-# rtv - test ones
-charge_station( pose [ -7.940 2.000 0 0 ] )
-charge_station( pose [ -7.940 3.000 0 0 ] )
-charge_station( pose [ -7.940 4.000 0 0 ] )
charge_station( pose [ 7.940 -2.000 0 0 ] )
charge_station( pose [ 7.940 -3.000 0 0 ] )
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge
This is your chance to win up to $100,000 in prizes! For a limited time,
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit