Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

threaded double-buffer with raytracing and moving happening in differ…

…ent buffers. Runs without crashing on dual core i7. Background not yet implemented.
  • Loading branch information...
commit 047355a9f2d1619bc73df1109cc8e3b3823874b6 1 parent 6dd2b05
@rtv authored
View
20 libstage/block.cc
@@ -55,7 +55,7 @@ Block::Block( Model* mod,
Block::~Block()
{
- if( mapped ) UnMap();
+ if( mapped ) UnMapAllLayers();
}
void Block::Translate( double x, double y )
@@ -192,11 +192,11 @@ Model* Block::TestCollision()
return NULL; // no hit
}
-void Block::Map()
+void Block::Map( unsigned int layer )
{
// calculate the local coords of the block vertices
const size_t pt_count(pts.size());
-
+
if( mpts.size() == 0 )
{
// no valid cache of model coord points, so generate them
@@ -211,7 +211,7 @@ void Block::Map()
mod->LocalToPixels( mpts, gpts );
// and render this block's polygon into the world
- mod->GetWorld()->MapPoly( gpts, this );
+ mod->world->MapPoly( gpts, this, layer );
// update the block's absolute z bounds at this rendering
Pose gpose( mod->GetGlobalPose() );
@@ -227,16 +227,14 @@ void Block::Map()
#include <algorithm>
#include <functional>
-void Block::UnMap()
+void Block::UnMap( unsigned int layer )
{
-// std::for_each( rendered_cells.begin(),
-// rendered_cells.end(),
-// std::bind2nd( std::mem_fun(&Cell::RemoveBlock), this));
+ // std::for_each( rendered_cells.begin(),
+ // rendered_cells.end(),
+ // std::bind2nd( std::mem_fun(&Cell::RemoveBlock), this));
- unsigned int layer = mod->world->updates % 2;
-
FOR_EACH( it, rendered_cells[layer] )
- (*it)->RemoveBlock(this, layer );
+ (*it)->RemoveBlock(this, layer );
rendered_cells[layer].clear();
mapped = false;
View
8 libstage/blockgroup.cc
@@ -94,19 +94,19 @@ void BlockGroup::CalcSize()
}
-void BlockGroup::Map()
+void BlockGroup::Map( unsigned int layer )
{
FOR_EACH( it, blocks )
- (*it)->Map();
+ (*it)->Map(layer);
}
// defined in world.cc
//void SwitchSuperRegionLock( SuperRegion* current, SuperRegion* next );
-void BlockGroup::UnMap()
+void BlockGroup::UnMap( unsigned int layer )
{
FOR_EACH( it, blocks )
- (*it)->UnMap();
+ (*it)->UnMap(layer);
}
void BlockGroup::DrawSolid( const Geom & geom )
View
58 libstage/model.cc
@@ -430,7 +430,8 @@ Model::~Model( void )
if( world ) // if I'm not a worldless dummy model
{
- UnMap(); // remove from the raytrace bitmap
+ UnMap(0); // remove from the raytrace bitmap
+ UnMap(1); // remove from the raytrace bitmap
EraseAll( this, parent ? parent->children : world->children );
modelsbyid.erase(id);
@@ -485,9 +486,10 @@ Model::Flag* Model::PopFlag()
return flag;
}
-void Model::ClearBlocks( void )
+void Model::ClearBlocks()
{
- UnMap();
+ blockgroup.UnMapAllLayers();
+
blockgroup.Clear();
//no need to Map() - we have no blocks
NeedRedraw();
@@ -511,8 +513,8 @@ Block* Model::AddBlockRect( meters_t x,
meters_t dy,
meters_t dz )
{
- UnMap();
-
+ blockgroup.UnMapAllLayers();
+
std::vector<point_t> pts(4);
pts[0].x = x;
pts[0].y = y;
@@ -532,7 +534,7 @@ Block* Model::AddBlockRect( meters_t x,
blockgroup.AppendBlock( newblock );
- Map();
+ Map( world->updates%2 );
return newblock;
}
@@ -668,33 +670,33 @@ void Model::LocalToPixels( const std::vector<point_t>& local,
}
}
-void Model::MapWithChildren()
+void Model::MapWithChildren( unsigned int layer )
{
- UnMap();
- Map();
+ UnMap(layer);
+ Map(layer);
// recursive call for all the model's children
FOR_EACH( it, children )
- (*it)->MapWithChildren();
+ (*it)->MapWithChildren(layer);
}
-void Model::MapFromRoot()
+void Model::MapFromRoot( unsigned int layer )
{
- Root()->MapWithChildren();
+ Root()->MapWithChildren(layer);
}
-void Model::UnMapWithChildren()
+void Model::UnMapWithChildren(unsigned int layer)
{
- UnMap();
+ UnMap(layer);
// recursive call for all the model's children
FOR_EACH( it, children )
- (*it)->UnMapWithChildren();
+ (*it)->UnMapWithChildren(layer);
}
-void Model::UnMapFromRoot()
+void Model::UnMapFromRoot(unsigned int layer)
{
- Root()->UnMapWithChildren();
+ Root()->UnMapWithChildren(layer);
}
void Model::Subscribe( void )
@@ -958,16 +960,18 @@ void Model::Move( void )
pose = newpose; // do the move provisionally - we might undo it below
+ const unsigned int layer( world->updates%2 );
+
//UnMapWithChildren(); // remove from all blocks
- MapWithChildren(); // render into new blocks
+ MapWithChildren(layer); // render into new blocks
if( TestCollision() ) // crunch!
{
// put things back the way they were
// this is expensive, but it happens _very_ rarely for most people
pose = startpose;
- UnMapWithChildren();
- MapWithChildren();
+ UnMapWithChildren(layer);
+ MapWithChildren(layer);
SetStall(true);
}
else
@@ -1066,23 +1070,23 @@ kg_t Model::GetMassOfChildren() const
return( GetTotalMass() - mass);
}
-void Model::Map()
+void Model::Map( unsigned int layer )
{
if( ! mapped )
{
// render all blocks in the group at my global pose and size
- blockgroup.Map();
+ blockgroup.Map( layer );
mapped = true;
}
}
-void Model::UnMap()
+void Model::UnMap( unsigned int layer )
{
if( mapped )
- {
- blockgroup.UnMap();
- mapped = false;
- }
+ {
+ blockgroup.UnMap(layer);
+ mapped = false;
+ }
}
void Model::BecomeParentOf( Model* child )
View
8 libstage/model_getset.cc
@@ -4,7 +4,9 @@ using namespace Stg;
void Model::SetGeom( const Geom& val )
{
- UnMapWithChildren();
+ unsigned int layer = world->updates%2;
+
+ UnMapWithChildren(layer);
geom = val;
@@ -12,7 +14,7 @@ void Model::SetGeom( const Geom& val )
NeedRedraw();
- MapWithChildren();
+ MapWithChildren(layer);
CallCallbacks( CB_GEOM );
}
@@ -216,7 +218,7 @@ void Model::SetPose( const Pose& newpose )
// token, pose.x, pose.y, pose.z, pose.a );
NeedRedraw();
- MapWithChildren();
+ MapWithChildren(world->updates%2);
world->dirty = true;
}
View
6 libstage/model_gripper.cc
@@ -184,7 +184,9 @@ void ModelGripper::FixBlocks()
// Update the blocks that are the gripper's body
void ModelGripper::PositionPaddles()
{
- UnMap();
+ unsigned int layer = world->GetUpdateCount()%2;
+ UnMap(layer);
+
double paddle_center_pos = cfg.paddle_position * (0.5 - cfg.paddle_size.y );
paddle_left->SetCenterY( paddle_center_pos + cfg.paddle_size.y/2.0 );
paddle_right->SetCenterY( 1.0 - paddle_center_pos - cfg.paddle_size.y/2.0);
@@ -195,7 +197,7 @@ void ModelGripper::PositionPaddles()
paddle_left->SetZ( paddle_bottom, paddle_top );
paddle_right->SetZ( paddle_bottom, paddle_top );
- Map();
+ Map(layer);
}
View
4 libstage/model_load.cc
@@ -248,8 +248,8 @@ void Model::Load()
// we may well have changed blocks or geometry
blockgroup.CalcSize();
- UnMapWithChildren();
- MapWithChildren();
+ UnMapWithChildren(world->updates%2);
+ MapWithChildren(world->updates%2);
if( this->debug )
printf( "Model \"%s\" is in debug mode\n", token.c_str() );
View
2  libstage/region.cc
@@ -118,7 +118,7 @@ void SuperRegion::DrawOccupancy( unsigned int layer ) const
for( int y=0; y<SUPERREGIONWIDTH; ++y )
for( int x=0; x<SUPERREGIONWIDTH; ++x )
{
- if( r->count ) // region contains some occupied cells
+ if( r->count ) // region contains some occupied cells
{
// outline the region
glRecti( x<<RBITS, y<<RBITS,
View
64 libstage/stage.hh
@@ -146,6 +146,8 @@ namespace Stg
"\n" \
"The text of the license may also be available online at\n" \
"http://www.gnu.org/licenses/old-licenses/gpl-2.0.html\n";
+
+ const unsigned int LAYER_COUNT = 2;
/** Convenient constant */
const double thousand = 1e3;
@@ -974,7 +976,8 @@ namespace Stg
/** call Cell::AddBlock(block) for each cell on the polygon */
void MapPoly( const PointIntVec& poly,
- Block* block );
+ Block* block,
+ unsigned int layer );
SuperRegion* AddSuperRegion( const point_int_t& coord );
SuperRegion* GetSuperRegion( const point_int_t& org );
@@ -1200,31 +1203,38 @@ namespace Stg
friend class SuperRegion;
friend class World;
friend class Canvas;
- friend class Cell;
+ friend class Cell;
public:
-
+
/** Block Constructor. A model's body is a list of these
- blocks. The point data is copied, so pts can safely be freed
- after constructing the block.*/
+ blocks. The point data is copied, so pts can safely be freed
+ after constructing the block.*/
Block( Model* mod,
- const std::vector<point_t>& pts,
- meters_t zmin,
- meters_t zmax,
- Color color,
- bool inherit_color,
- bool wheel );
-
+ const std::vector<point_t>& pts,
+ meters_t zmin,
+ meters_t zmax,
+ Color color,
+ bool inherit_color,
+ bool wheel );
+
/** A from-file constructor */
Block( Model* mod, Worldfile* wf, int entity);
-
+
~Block();
/** render the block into the world's raytrace data structure */
- void Map();
+ void Map( unsigned int layer );
/** remove the block from the world's raytracing data structure */
- void UnMap();
+ void UnMap( unsigned int layer );
+ void UnMapAllLayers()
+ {
+ for( unsigned int i(0); i<LAYER_COUNT; ++i )
+ UnMap(i);
+ }
+
+
/** draw the block in OpenGL as a solid single color */
void DrawSolid();
@@ -1340,9 +1350,15 @@ namespace Stg
with a block in this group, or NULL, if none are detected. */
Model* TestCollision();
- void Map();
- void UnMap();
-
+ void Map( unsigned int layer );
+ void UnMap( unsigned int layer );
+
+ void UnMapAllLayers()
+ {
+ for( unsigned int i(0); i<LAYER_COUNT; ++i )
+ UnMap(i);
+ }
+
/** Draw the block in OpenGL as a solid single color. */
void DrawSolid( const Geom &geom);
@@ -2078,15 +2094,15 @@ namespace Stg
void CommitTestedPose();
- void Map();
- void UnMap();
+ void Map( unsigned int layer );
+ void UnMap( unsigned int layer );
- void MapWithChildren();
- void UnMapWithChildren();
+ void MapWithChildren( unsigned int layer );
+ void UnMapWithChildren( unsigned int layer );
// Find the root model, and map/unmap the whole tree.
- void MapFromRoot();
- void UnMapFromRoot();
+ void MapFromRoot( unsigned int layer );
+ void UnMapFromRoot( unsigned int layer );
/** raytraces a single ray from the point and heading identified by
pose, in local coords */
View
164 libstage/world.cc
@@ -168,7 +168,6 @@ World::World( const std::string& name,
active_energy(),
active_velocity(),
active_velocity_threaded(),
- //thread_task(0),
sim_interval( 1e5 ), // 100 msec has proved a good default
update_cb_count(0)
{
@@ -472,8 +471,8 @@ void World::Load( const std::string& worldfile_path )
{
// all this is a hack and shouldn't be necessary
(*it)->blockgroup.CalcSize();
- (*it)->UnMap();
- (*it)->Map();
+ (*it)->UnMap(updates%2);
+ (*it)->Map(updates%2);
// to here
(*it)->InitControllers();
@@ -825,7 +824,7 @@ RaytraceResult World::Raytrace( const Ray& r )
double distX(0), distY(0);
bool calculatecrossings( true );
- unsigned int layer = updates % 2;
+ unsigned int layer = (updates+1) % 2;
// Stage spends up to 95% of its time in this loop! It would be
// neater with more function calls encapsulating things, but even
@@ -1014,99 +1013,78 @@ void World::Reload( void )
ForEachDescendant( _reload_cb, NULL );
}
-// SuperRegion* SwitchSuperRegionLock( SuperRegion* current, SuperRegion* next )
-// {
-// assert(next);
-
-// if( current == next )
-// return current; // do nothing
-
-// if(current)
-// current->Unlock();
-
-// next->Lock();
-
-// return next;
-// }
-
-void World::MapPoly( const PointIntVec& pts, Block* block )
+void World::MapPoly( const PointIntVec& pts, Block* block, unsigned int layer )
{
const size_t pt_count = pts.size();
for( size_t i(0); i<pt_count; ++i )
- {
- const point_int_t& start(pts[i] );
- const point_int_t& end(pts[(i+1)%pt_count]);
-
- // line rasterization adapted from Cohen's 3D version in
- // Graphics Gems II. Should be very fast.
- const int32_t dx( end.x - start.x );
- const int32_t dy( end.y - start.y );
- const int32_t sx(sgn(dx));
- const int32_t sy(sgn(dy));
- const int32_t ax(abs(dx));
- const int32_t ay(abs(dy));
- const int32_t bx(2*ax);
- const int32_t by(2*ay);
- int32_t exy(ay-ax);
- int32_t n(ax+ay);
-
- int32_t globx(start.x);
- int32_t globy(start.y);
-
- unsigned int layer( updates % 2 );
-
- while( n )
- {
- SuperRegion* sr( GetSuperRegionCreate( point_int_t(GETSREG(globx),
- GETSREG(globy))));
- assert(sr);
-
- Region* reg(sr->GetRegion( GETREG(globx),
- GETREG(globy)));
-
- assert(reg);
-
- //printf( "REGION %p\n", reg );
-
- // add all the required cells in this region before looking up
- // another region
- int32_t cx( GETCELL(globx) );
- int32_t cy( GETCELL(globy) );
-
- // need to call Region::GetCell() before using a Cell pointer
- // directly, because the region allocates cells lazily, waiting
- // 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 )
- {
- c->AddBlock(block, layer ); // odd or even
- // timesteps render into different layers
-
- // 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;
- }
- }
- }
+ {
+ const point_int_t& start(pts[i] );
+ const point_int_t& end(pts[(i+1)%pt_count]);
+
+ // line rasterization adapted from Cohen's 3D version in
+ // Graphics Gems II. Should be very fast.
+ const int32_t dx( end.x - start.x );
+ const int32_t dy( end.y - start.y );
+ const int32_t sx(sgn(dx));
+ const int32_t sy(sgn(dy));
+ const int32_t ax(abs(dx));
+ const int32_t ay(abs(dy));
+ const int32_t bx(2*ax);
+ const int32_t by(2*ay);
+ int32_t exy(ay-ax);
+ int32_t n(ax+ay);
+
+ int32_t globx(start.x);
+ int32_t globy(start.y);
+
+ while( n )
+ {
+ Region* reg( GetSuperRegionCreate( point_int_t(GETSREG(globx),
+ GETSREG(globy)))
+ ->GetRegion( GETREG(globx),
+ GETREG(globy)));
+ assert(reg);
+
+ //printf( "REGION %p\n", reg );
+
+ // add all the required cells in this region before looking up
+ // another region
+ int32_t cx( GETCELL(globx) );
+ int32_t cy( GETCELL(globy) );
+
+ // need to call Region::GetCell() before using a Cell pointer
+ // directly, because the region allocates cells lazily, waiting
+ // 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 )
+ {
+ c->AddBlock(block, layer );
+
+ // 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;
+ }
+ }
+ }
}
View
2  worlds/fasr2.world
@@ -16,7 +16,7 @@ quit_time 2000
resolution 0.02
-threads 4
+threads 3
# configure the GUI window
window

0 comments on commit 047355a

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