Revision: 8195
http://playerstage.svn.sourceforge.net/playerstage/?rev=8195&view=rev
Author: rtv
Date: 2009-08-11 21:04:09 +0000 (Tue, 11 Aug 2009)
Log Message:
-----------
fixed stepping and quit_time. Added property docs
Modified Paths:
--------------
code/stage/trunk/libstage/main.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/libstage/main.cc
===================================================================
--- code/stage/trunk/libstage/main.cc 2009-08-11 16:14:06 UTC (rev 8194)
+++ code/stage/trunk/libstage/main.cc 2009-08-11 21:04:09 UTC (rev 8195)
@@ -99,5 +99,6 @@
else
while( ! World::UpdateAll() );
+ puts( "\n[Stage: done]" );
exit(0);
}
Modified: code/stage/trunk/libstage/stage.hh
===================================================================
--- code/stage/trunk/libstage/stage.hh 2009-08-11 16:14:06 UTC (rev 8194)
+++ code/stage/trunk/libstage/stage.hh 2009-08-11 21:04:09 UTC (rev 8195)
@@ -834,15 +834,13 @@
double ppm; ///< the resolution of the world model in pixels per meter
bool quit; ///< quit this world ASAP
- /** World::quit is set true when this simulation time is reached */
- stg_usec_t quit_time;
stg_usec_t real_time_now; ///< The current real time in microseconds
stg_usec_t real_time_start; ///< the real time at which this world was
created
bool show_clock; ///< iff true, print the sim time on stdout
- unsigned int show_clock_interval; ///< updates between clock xoutputs
+ unsigned int show_clock_interval; ///< updates between clock outputs
pthread_mutex_t thread_mutex; ///< protect the worker thread management
stuff
- unsigned int threads_working; ///< the number of worker threads
not yet finished
+ unsigned int threads_working; ///< the number of worker threads not
yet finished
pthread_cond_t threads_start_cond; ///< signalled to unblock worker threads
pthread_cond_t threads_done_cond; ///< signalled by last worker thread to
unblock main thread
int total_subs; ///< the total number of subscriptions to all models
@@ -853,9 +851,11 @@
std::list<std::pair<stg_world_callback_t,void*> > cb_list; ///< List
of callback functions and arguments
stg_bounds3d_t extent; ///< Describes the 3D volume of the world
bool graphics;///< true iff we have a GUI
- stg_usec_t interval_track;
+
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
+ /** World::quit is set true when this simulation time is reached */
+ stg_usec_t quit_time;
std::list<float*> ray_list;///< List of rays traced for debug
visualization
stg_usec_t sim_time; ///< the current sim time in this world in
microseconds
std::map<stg_point_int_t,SuperRegion*> superregions;
@@ -871,9 +871,7 @@
public:
- bool paused; ///< the world only updates when this is false or steps > 0
- unsigned int steps; ///< When paused, stage updates while steps >
- ///0, decrementing steps with
each update.
+ bool paused; ///< if true, the simulation is stopped
virtual void Start(){ paused = false; };
virtual void Stop(){ paused = true; };
@@ -1006,9 +1004,9 @@
void Enqueue( unsigned int queue_num, Event::type_t type, stg_usec_t
delay, Model* mod );
/** The sim time of the next event in the queue. */
- //stg_usec_t time_of_next_event;
- uint32_t event_pending_count;
-
+ uint32_t event_pending_count;
+
+ /** The amount of simulated time to run for each call to Update() */
stg_usec_t sim_interval;
/** consume events from the queue up to and including the current
sim_time */
Modified: code/stage/trunk/libstage/world.cc
===================================================================
--- code/stage/trunk/libstage/world.cc 2009-08-11 16:14:06 UTC (rev 8194)
+++ code/stage/trunk/libstage/world.cc 2009-08-11 21:04:09 UTC (rev 8195)
@@ -11,25 +11,59 @@
@verbatim
- resolution 0.02
- threads 0
+ name <worldfile name>
+ interval_sim 100
+ quit_time 0
+ resolution 0.02
+ show_clock 0
+ show_clock_interval 100
+ threads 0
@endverbatim
@par Details
+ - name <string>\n
+ An identifying name for the world, used e.g. in the title bar of
+ the GUI.
+
+ - interval_sim <float>\n
+ The amount of simulation time run for each call of
+ World::Update(). Each model has its own configurable update
+ interval, which can be greater or less than this, but intervals
+ shorter than this are not visible in the GUI or in World update
+ callbacks. You are not likely to need to change the default of 100
+ msec: this is used internally by clients such as Player and WebSim.
+
+ - quit_time <float>\n
+ Stop the simulation after this many simulated seconds have
+ elapsed. In libstage, World::Update() returns true. In Stage with
+ a GUI, the simulation is paused. In Stage without a GUI, Stage
+ quits.
+
- resolution <float>\n
The resolution (in meters) of the underlying bitmap model. Larger
values speed up raytracing at the expense of fidelity in collision
- detection and sensing.
+ detection and sensing. The default is often a reasonable choice.
- - threads <int>\n
- The number of worker threads to spawn. Some models can be updated
- in parallel (e.g. laser, ranger), and running 2 or more threads
- here may make the simulation run faster, depending on the number
- of CPU cores available and the worldfile. As a guideline, use one
- thread per core if you have high-resolution models, e.g. a laser
- with hundreds of samples
+ - show_clock <int>\n
+ If non-zero, print the simulation time on stdout every
+ $show_clock_interval updates. Useful to watch the progress of
+ non-GUI simulations.
+
+ - show_clock_interval <int>\n
+ Sets the number of updates between printing the time on stdoutm,
+ if $show_clock is enabled. The default is once every 10 simulated
+ seconds. Smaller values slow the simulation down a little.
+
+ - threads <int>\n
+ The number of worker threads to spawn. Some
+ models can be updated in parallel (e.g. laser, ranger), and
+ running 2 or more threads here may make the simulation run faster,
+ depending on the number of CPU cores available and the
+ worldfile. As a guideline, use one thread per core if you have
+ parallel-enabled high-resolution models, e.g. a laser with
+ hundreds or thousands of samples, or lots of models.
@par More examples
The Stage source distribution contains several example world files in
@@ -63,7 +97,7 @@
std::set<World*> World::world_set;
World::World( const char* token,
- double ppm )
+ double ppm )
:
// private
destroy( false ),
@@ -72,7 +106,6 @@
models_with_fiducials(),
ppm( ppm ), // raytrace resolution
quit( false ),
- quit_time( 0 ),
real_time_now( RealTimeNow() ),
real_time_start( real_time_now ),
show_clock( false ),
@@ -88,9 +121,9 @@
cb_list(NULL),
extent(),
graphics( false ),
- interval_track( 1e5 ),
option_table(),
powerpack_list(),
+ quit_time( 0 ),
ray_list(),
sim_time( 0 ),
superregions(),
@@ -98,9 +131,8 @@
updates( 0 ),
wf( NULL ),
paused( false ),
- steps(0),
- event_queues(1),
- sim_interval( 1e5 ) // 100 msec
+ event_queues(1), // use 1 thread by default
+ sim_interval( 1e5 ) // 100 msec has proved a good default
{
if( ! Stg::InitDone() )
{
@@ -143,7 +175,7 @@
FOR_EACH( world_it, World::world_set )
{
if( (*world_it)->Update() == false )
- quit = false;
+ quit = false;
}
return quit;
@@ -175,10 +207,10 @@
pthread_mutex_lock( &world->thread_mutex );
if( --world->threads_working == 0 )
- {
- //puts( "last worker signalling main thread" );
- pthread_cond_signal( &world->threads_done_cond );
- }
+ {
+ //puts( "last worker signalling main thread" );
+ pthread_cond_signal( &world->threads_done_cond );
+ }
// keep lock going round the loop
}
@@ -232,7 +264,7 @@
else
{
PRINT_ERR1( "Unknown model type %s in world file.",
- typestr );
+ typestr );
exit( 1 );
}
@@ -246,7 +278,7 @@
int parent_entity = wf->GetEntityParent( entity );
PRINT_DEBUG2( "wf entity %d parent entity %d\n",
- entity, parent_entity );
+ entity, parent_entity );
Model* parent = models_by_wfentity[ parent_entity ];
@@ -285,12 +317,21 @@
wf->ReadString( entity, "name", token );
this->quit_time = (stg_usec_t)( million *
- wf->ReadFloat( entity, "quit_time", 0 ) );
+
wf->ReadFloat( entity, "quit_time", 0 ) );
this->ppm =
1.0 / wf->ReadFloat( entity, "resolution", 1.0 / this->ppm );
+ this->show_clock =
+ wf->ReadInt( entity, "show_clock", this->show_clock );
+ this->show_clock_interval =
+ wf->ReadInt( entity, "show_clock_interval", this->show_clock_interval
);
+
+ // read msec instead of usec: easier for user
+ this->sim_interval =
+ 1e3 * wf->ReadFloat( entity, "interval_sim", this->sim_interval / 1e3
);
+
this->worker_threads = wf->ReadInt( entity, "threads", this->worker_threads
);
if( worker_threads > 0 )
{
@@ -300,18 +341,18 @@
// kick off the threads
for( unsigned int t=0; t<worker_threads; t++ )
- {
- std::pair<World*,int> *p = new std::pair<World*,int>( this, t+1 );
+ {
+ std::pair<World*,int> *p = new std::pair<World*,int>(
this, t+1 );
- //normal posix pthread C function pointer
- typedef void* (*func_ptr) (void*);
+ //normal posix pthread C function pointer
+ typedef void* (*func_ptr) (void*);
- pthread_t pt;
- pthread_create( &pt,
- NULL,
- (func_ptr)World::update_thread_entry,
- p );
- }
+ pthread_t pt;
+ pthread_create( &pt,
+ NULL,
+
(func_ptr)World::update_thread_entry,
+ p );
+ }
printf( "[threads %u]", worker_threads );
}
@@ -323,13 +364,13 @@
// 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 );
+ LoadBlock( wf, entity );
else
- LoadModel( wf, entity );
+ LoadModel( wf, entity );
}
// warn about unused WF lines
@@ -342,7 +383,7 @@
if( debug )
printf( "[Load time %.3fsec]\n",
- (load_end_time - load_start_time) / 1e6 );
+ (load_end_time - load_start_time) / 1e6 );
else
putchar( '\n' );
}
@@ -417,7 +458,7 @@
}
void World::AddUpdateCallback( stg_world_callback_t cb,
- void* user )
+
void* user )
{
// add the callback & argument to the list
std::pair<stg_world_callback_t,void*> p(cb, user);
@@ -425,21 +466,17 @@
}
int World::RemoveUpdateCallback( stg_world_callback_t cb,
- void* user )
+
void* user )
{
std::pair<stg_world_callback_t,void*> p( cb, user );
- // std::list<std::pair<stg_world_callback_t,void*> >::iterator it;
- // for( it = cb_list.begin();
- // it != cb_list.end();
- // it++ )
FOR_EACH( it, cb_list )
{
if( (*it) == p )
- {
- cb_list.erase( it );
- break;
- }
+ {
+ cb_list.erase( it );
+ break;
+ }
}
// return the number of callbacks now in the list. Useful for
@@ -449,20 +486,10 @@
void World::CallUpdateCallbacks()
{
-
- // for each callback in the list
- // for( std::list<std::pair<stg_world_callback_t,void*> >::iterator it =
cb_list.begin();
- // it != cb_list.end();
- // it++ )
FOR_EACH( it, cb_list )
{
- //printf( "cbs %p data %p cvs->next %p\n", cbs, cbs->data, cbs->next );
-
if( ((*it).first )( this, (*it).second ) )
- {
- //printf( "callback returned TRUE - schedule removal from list\n" );
- it = cb_list.erase( it );
- }
+ it = cb_list.erase( it );
}
}
@@ -487,25 +514,25 @@
// only update events are allowed in queues other than zero
if( queue_num > 0 && ev.type != Event::UPDATE )
- PRINT_WARN1( "event type %d in async queue", queue_num );
+ PRINT_WARN1( "event type %d in async queue", queue_num );
switch( ev.type )
- {
- case Event::UPDATE:
- ev.mod->Update();
- break;
+ {
+ case Event::UPDATE:
+ ev.mod->Update();
+ break;
- case Event::POSE:
- ev.mod->UpdatePose();
- break;
+ case Event::POSE:
+ ev.mod->UpdatePose();
+ break;
- case Event::ENERGY:
- ev.mod->UpdateCharge();
- break;
+ case Event::ENERGY:
+ ev.mod->UpdateCharge();
+ break;
- default:
- PRINT_WARN1( "unknown event type %d", ev.type );
- }
+ default:
+ PRINT_WARN1( "unknown event type %d", ev.type );
+ }
ev = queue.top();
}
@@ -514,32 +541,18 @@
bool World::Update()
{
- PRINT_DEBUG( "World::Update()" );
+ //puts( "World::Update()" );
// if we've run long enough, exit
- // if( PastQuitTime() )
- // {
- // if( IsGUI() == false )
- // return true;
- // }
+ if( PastQuitTime() )
+ return true;
if( event_pending_count < 1 )
{
PRINT_WARN( "event queue(s) empty." );
return false;
}
-
- // if( paused )
- // {
- // if( steps < 1 )
- // return true;
- // else
- // {
- // --steps;
- // //printf( "world::update (steps remaining %d)\n", steps );
- // }
- // }
-
+
sim_time += sim_interval;
// handle the zeroth queue synchronously in the main thread
@@ -559,10 +572,10 @@
// wait for all the last update job to complete - it will
// signal the worker_threads_done condition var
while( threads_working > 0 )
- {
- //puts( "main thread waiting for workers to finish" );
- pthread_cond_wait( &threads_done_cond, &thread_mutex );
- }
+ {
+ //puts( "main thread waiting for workers to finish" );
+ pthread_cond_wait( &threads_done_cond, &thread_mutex );
+ }
pthread_mutex_unlock( &thread_mutex );
//puts( "main thread awakes" );
@@ -570,11 +583,7 @@
// threads
}
- //stg_usec_t step = time_of_next_event - sim_time;
- // smoothed interval tracking
- //interval_track = 0.1 * step + 0.9 * interval_track;
dirty = true; // need redraw
- // printf( "@ %llu done. (next event at %llu)\n\n", sim_time, next_time );
// world callbacks
CallUpdateCallbacks();
@@ -641,14 +650,14 @@
void World::Raytrace( const Pose &gpose, // global pose
- const stg_meters_t range,
- const stg_radians_t fov,
- const stg_ray_test_func_t func,
- const Model* model,
- const void* arg,
- stg_raytrace_result_t* samples, // preallocated storage
for samples
- const uint32_t sample_count, // number of samples
- const bool ztest )
+ const stg_meters_t
range,
+ const stg_radians_t
fov,
+ const
stg_ray_test_func_t func,
+ const Model* model,
+ const void* arg,
+ stg_raytrace_result_t*
samples, // preallocated storage for samples
+ const uint32_t
sample_count, // number of samples
+ const bool ztest )
{
// find the direction of the first ray
Pose raypose = gpose;
@@ -663,11 +672,11 @@
// Stage spends 50-99% of its time in this method.
stg_raytrace_result_t World::Raytrace( const Pose &gpose,
- const stg_meters_t range,
- const stg_ray_test_func_t func,
- const Model* mod,
- const void* arg,
- const bool ztest )
+
const stg_meters_t range,
+
const stg_ray_test_func_t func,
+
const Model* mod,
+
const void* arg,
+
const bool ztest )
{
Ray r( mod, gpose, range, func, arg, ztest );
return Raytrace( r );
@@ -734,154 +743,154 @@
while( n > 0 ) // while we are still not at the ray end
{
Region* reg( GetSuperRegionCached( GETSREG(globx), GETSREG(globy) )
- ->GetRegion( GETREG(globx), GETREG(globy) ));
+ ->GetRegion( GETREG(globx),
GETREG(globy) ));
if( reg->count ) // if the region contains any objects
- {
- // invalidate the region crossing points used to jump over
- // empty regions
- calculatecrossings = true;
+ {
+ // invalidate the region crossing points used to jump
over
+ // empty regions
+ calculatecrossings = true;
- // convert from global cell to local cell coords
- int32_t cx( GETCELL(globx) );
- int32_t cy( GETCELL(globy) );
+ // convert from global cell to local cell coords
+ int32_t cx( GETCELL(globx) );
+ int32_t cy( GETCELL(globy) );
- Cell* c( ®->cells[ cx + cy * REGIONWIDTH ] );
- assert(c); // should be good: we know the region contains objects
+ Cell* c( ®->cells[ cx + cy * REGIONWIDTH ] );
+ assert(c); // should be good: we know the region
contains objects
- // while within the bounds of this region and while some ray remains
- // we'll tweak the cell pointer directly to move around quickly
- while( (cx>=0) && (cx<REGIONWIDTH) &&
- (cy>=0) && (cy<REGIONWIDTH) &&
- n > 0 )
- {
- for( BlockPtrVec::iterator it( c->blocks.begin() );
- it != c->blocks.end();
- ++it )
- {
- Block* block( *it );
- assert( block );
+ // while within the bounds of this region and while
some ray remains
+ // we'll tweak the cell pointer directly to move
around quickly
+ while( (cx>=0) && (cx<REGIONWIDTH) &&
+ (cy>=0) && (cy<REGIONWIDTH) &&
+ n > 0 )
+ {
+ for( BlockPtrVec::iterator it(
c->blocks.begin() );
+ it != c->blocks.end();
+ ++it )
+ {
+ Block* block( *it );
+ assert( block );
- // skip if not in the right z range
- if( r.ztest &&
- ( r.origin.z < block->global_z.min ||
- r.origin.z > block->global_z.max ) )
- continue;
+ // skip if not in the right z
range
+ if( r.ztest &&
+ ( r.origin.z <
block->global_z.min ||
+ r.origin.z >
block->global_z.max ) )
+ continue;
- // test the predicate we were passed
- if( (*r.func)( block->mod, (Model*)r.mod, r.arg ))
- {
- // a hit!
- sample.color = block->GetColor();
- sample.mod = block->mod;
+ // test the predicate we were
passed
+ if( (*r.func)( block->mod,
(Model*)r.mod, r.arg ))
+ {
+ // a hit!
+ sample.color =
block->GetColor();
+ sample.mod =
block->mod;
- if( ax > ay ) // faster than the equivalent hypot() call
- sample.range = fabs((globx-startx) / cosa) / ppm;
- else
- sample.range = fabs((globy-starty) / sina) / ppm;
+ if( ax > ay ) //
faster than the equivalent hypot() call
+ sample.range =
fabs((globx-startx) / cosa) / ppm;
+ else
+ sample.range =
fabs((globy-starty) / sina) / ppm;
- return sample;
- }
- }
+ return sample;
+ }
+ }
- // increment our cell in the correct direction
- if( exy < 0 ) // we're iterating along X
- {
- globx += sx; // global coordinate
- exy += by;
- c += sx; // move the cell left or right
- cx += sx; // cell coordinate for bounds checking
- }
- else // we're iterating along Y
- {
- globy += sy; // global coordinate
- exy -= bx;
- c += sy * REGIONWIDTH; // move the cell up or down
- cy += sy; // cell coordinate for bounds checking
- }
- --n; // decrement the manhattan distance remaining
+ // increment our cell in the correct direction
+ if( exy < 0 ) // we're iterating along X
+ {
+ globx += sx; // global
coordinate
+ exy += by;
+ c += sx; // move the cell left
or right
+ cx += sx; // cell coordinate
for bounds checking
+ }
+ else // we're iterating along Y
+ {
+ globy += sy; // global
coordinate
+ exy -= bx;
+ c += sy * REGIONWIDTH; // move
the cell up or down
+ cy += sy; // cell coordinate
for bounds checking
+ }
+ --n; // decrement the manhattan distance
remaining
- //rt_cells.push_back( stg_point_int_t( globx, globy ));
- }
- //printf( "leaving populated region\n" );
- }
+ //rt_cells.push_back( stg_point_int_t( globx,
globy ));
+ }
+ //printf( "leaving populated region\n" );
+ }
else // jump over the empty region
- {
- // on the first run, and when we've been iterating over
- // cells, we need to calculate the next crossing of a region
- // boundary along each axis
- if( calculatecrossings )
- {
- calculatecrossings = false;
+ {
+ // on the first run, and when we've been iterating over
+ // cells, we need to calculate the next crossing of a
region
+ // boundary along each axis
+ if( calculatecrossings )
+ {
+ calculatecrossings = false;
- // find the coordinate in cells of the bottom left corner of
- // the current region
- int32_t ix( globx );
- int32_t iy( globy );
- double regionx( ix/REGIONWIDTH*REGIONWIDTH );
- double regiony( iy/REGIONWIDTH*REGIONWIDTH );
- if( (globx < 0) && (ix % REGIONWIDTH) ) regionx -= REGIONWIDTH;
- if( (globy < 0) && (iy % REGIONWIDTH) ) regiony -= REGIONWIDTH;
+ // find the coordinate in cells of the bottom
left corner of
+ // the current region
+ int32_t ix( globx );
+ int32_t iy( globy );
+ double regionx( ix/REGIONWIDTH*REGIONWIDTH );
+ double regiony( iy/REGIONWIDTH*REGIONWIDTH );
+ if( (globx < 0) && (ix % REGIONWIDTH) )
regionx -= REGIONWIDTH;
+ if( (globy < 0) && (iy % REGIONWIDTH) )
regiony -= REGIONWIDTH;
- // calculate the distance to the edge of the current region
- double xdx( sx < 0 ?
- regionx - globx - 1.0 : // going left
- regionx + REGIONWIDTH - globx ); // going right
- double xdy( xdx*tana );
+ // calculate the distance to the edge of the
current region
+ double xdx( sx < 0 ?
+ regionx -
globx - 1.0 : // going left
+ regionx +
REGIONWIDTH - globx ); // going right
+ double xdy( xdx*tana );
- double ydy( sy < 0 ?
- regiony - globy - 1.0 : // going down
- regiony + REGIONWIDTH - globy ); // going up
- double ydx( ydy/tana );
+ double ydy( sy < 0 ?
+ regiony -
globy - 1.0 : // going down
+ regiony +
REGIONWIDTH - globy ); // going up
+ double ydx( ydy/tana );
- // these stored hit points are updated as we go along
- xcrossx = globx+xdx;
- xcrossy = globy+xdy;
+ // these stored hit points are updated as we
go along
+ xcrossx = globx+xdx;
+ xcrossy = globy+xdy;
- ycrossx = globx+ydx;
- ycrossy = globy+ydy;
+ ycrossx = globx+ydx;
+ ycrossy = globy+ydy;
- // find the distances to the region crossing points
- // manhattan distance is faster than using hypot()
- distX = fabs(xdx)+fabs(xdy);
- distY = fabs(ydx)+fabs(ydy);
- }
+ // find the distances to the region crossing
points
+ // manhattan distance is faster than using
hypot()
+ distX = fabs(xdx)+fabs(xdy);
+ distY = fabs(ydx)+fabs(ydy);
+ }
- if( distX < distY ) // crossing a region boundary left or right
- {
- // move to the X crossing
- globx = xcrossx;
- globy = xcrossy;
+ if( distX < distY ) // crossing a region boundary left
or right
+ {
+ // move to the X crossing
+ globx = xcrossx;
+ globy = xcrossy;
- n -= distX; // decrement remaining manhattan distance
+ n -= distX; // decrement remaining manhattan
distance
- // calculate the next region crossing
- xcrossx += xjumpx;
- xcrossy += xjumpy;
+ // calculate the next region crossing
+ xcrossx += xjumpx;
+ xcrossy += xjumpy;
- distY -= distX;
- distX = xjumpdist;
+ distY -= distX;
+ distX = xjumpdist;
- //rt_candidate_cells.push_back( stg_point_int_t( xcrossx, xcrossy
));
- }
- else // crossing a region boundary up or down
- {
- // move to the X crossing
- globx = ycrossx;
- globy = ycrossy;
+ //rt_candidate_cells.push_back(
stg_point_int_t( xcrossx, xcrossy ));
+ }
+ else // crossing a region boundary up or down
+ {
+ // move to the X crossing
+ globx = ycrossx;
+ globy = ycrossy;
- n -= distY; // decrement remaining manhattan distance
+ n -= distY; // decrement remaining manhattan
distance
- // calculate the next region crossing
- ycrossx += yjumpx;
- ycrossy += yjumpy;
+ // calculate the next region crossing
+ ycrossx += yjumpx;
+ ycrossy += yjumpy;
- distX -= distY;
- distY = yjumpdist;
+ distX -= distY;
+ distY = yjumpdist;
- //rt_candidate_cells.push_back( stg_point_int_t( ycrossx, ycrossy
));
- }
- }
+ //rt_candidate_cells.push_back(
stg_point_int_t( ycrossx, ycrossy ));
+ }
+ }
//rt_cells.push_back( stg_point_int_t( globx, globy ));
}
// hit nothing
@@ -978,14 +987,14 @@
Cell* World::GetCell( const stg_point_int_t& glob )
{
return( ((Region*)GetSuperRegionCached( GETSREG(glob.x), GETSREG(glob.y) )
- ->GetRegion( GETREG(glob.x), GETREG(glob.y) ))
- ->GetCell( GETCELL(glob.x), GETCELL(glob.y) )) ;
+ ->GetRegion( GETREG(glob.x), GETREG(glob.y) ))
+ ->GetCell( GETCELL(glob.x), GETCELL(glob.y) )) ;
}
void World::ForEachCellInLine( const stg_point_int_t& start,
- const stg_point_int_t& end,
- std::vector<Cell*>& cells )
+
const stg_point_int_t& end,
+
std::vector<Cell*>& cells )
{
// line rasterization adapted from Cohen's 3D version in
// Graphics Gems II. Should be very fast.
@@ -1003,15 +1012,10 @@
int32_t globx(start.x);
int32_t globy(start.y);
- // fix a little issue where the edges are not drawn long enough
- // when drawing to the right or up
- // if( (dx > 0) || ( dy > 0 ) )
- // n++;
-
while( n )
{
Region* reg( GetSuperRegionCached( GETSREG(globx), GETSREG(globy) )
- ->GetRegion( GETREG(globx), GETREG(globy) ));
+ ->GetRegion( GETREG(globx),
GETREG(globy) ));
// add all the required cells in this region before looking up
// another region
@@ -1023,32 +1027,32 @@
// for a call of this method
Cell* c = reg->GetCell( cx, cy );
+ // while inside the region, manipulate the Cell pointer directly
while( (cx>=0) && (cx<REGIONWIDTH) &&
- (cy>=0) && (cy<REGIONWIDTH) &&
- n > 0 )
- {
- // find the cell at this location, then add it to the vector
- cells.push_back( c );
+ (cy>=0) && (cy<REGIONWIDTH) &&
+ n > 0 )
+ {
+ // find the cell at this location, then add it to the
vector
+ cells.push_back( c );
- // cleverly skip to the next cell (now it's safe to
- // manipulate the cell pointer direcly)
- if( exy < 0 )
- {
- globx += sx;
- exy += by;
- c += sx;
- cx += sx;
- }
- else
- {
- globy += sy;
- exy -= bx;
- c += sy * REGIONWIDTH;
- cy += sy;
- }
- --n;
- }
-
+ // cleverly skip to the next cell (now it's safe to
+ // manipulate the cell pointer)
+ if( exy < 0 )
+ {
+ globx += sx;
+ exy += by;
+ c += sx;
+ cx += sx;
+ }
+ else
+ {
+ globy += sy;
+ exy -= bx;
+ c += sy * REGIONWIDTH;
+ cy += sy;
+ }
+ --n;
+ }
}
}
@@ -1108,13 +1112,13 @@
if( time == other.time )
{
if( type > other.type )
- return true;
+ return true;
if( type == other.type )
- {
- if( mod < other.mod ) // tends to do children first
- return true;
- }
+ {
+ if( mod < other.mod ) // tends to do children first
+ return true;
+ }
}
return false;
Modified: code/stage/trunk/libstage/worldgui.cc
===================================================================
--- code/stage/trunk/libstage/worldgui.cc 2009-08-11 16:14:06 UTC (rev
8194)
+++ code/stage/trunk/libstage/worldgui.cc 2009-08-11 21:04:09 UTC (rev
8195)
@@ -351,7 +351,15 @@
real_time_of_last_update = timenow;
// inherit
- return World::Update();
+ bool done = World::Update();
+
+ if( done )
+ {
+ quit_time = 0; // allows us to continue by un-pausing
+ Stop();
+ }
+
+ return done;
}
std::string WorldGui::ClockString()
@@ -364,9 +372,7 @@
average_real_interval += interval_log[i];
average_real_interval /= interval_log.size();
- // TODO
- //double localratio = (double)interval_sim / (double)average_real_interval;
- double localratio = (double)interval_track / (double)average_real_interval;
+ double localratio = (double)sim_interval / (double)average_real_interval;
char buf[32];
snprintf( buf, 32, " [%.1f]", localratio );
@@ -567,7 +573,9 @@
void WorldGui::onceCb( Fl_Widget* w, WorldGui* wg )
{
wg->paused = true;
- wg->steps = 1; // number of steps to run
+
+ // run exactly once
+ wg->World::Update();
}
void WorldGui::viewOptionsCb( OptionsDlg* oDlg, WorldGui* wg )
Modified: code/stage/trunk/worlds/fasr.world
===================================================================
--- code/stage/trunk/worlds/fasr.world 2009-08-11 16:14:06 UTC (rev 8194)
+++ code/stage/trunk/worlds/fasr.world 2009-08-11 21:04:09 UTC (rev 8195)
@@ -10,8 +10,10 @@
paused 1
# time to pause (in GUI mode) or quit (in headless mode) the simulation
-quit_time 3600 # 1 hour of simulated time
+# quit_time 3600 # 1 hour of simulated time
+quit_time 360 # 6 minutes of simulated time
+
resolution 0.02
threads 0
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now. http://p.sf.net/sfu/bobj-july
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit