Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

refactored blocks and blockgroups to simplify code and API

  • Loading branch information...
commit 9e1e848842290c17b3cd9ce14f21f566e6e89016 1 parent e55a877
@rtv authored
View
78 libstage/block.cc
@@ -10,40 +10,37 @@ static void canonicalize_winding(vector<point_t>& pts);
/** Create a new block. A model's body is a list of these
blocks. The point data is copied, so pts can safely be freed
after calling this.*/
-Block::Block( Model* mod,
- const std::vector<point_t>& pts,
- meters_t zmin,
- meters_t zmax,
- Color color,
- bool inherit_color ) :
- mod( mod ),
+Block::Block( BlockGroup* group,
+ const std::vector<point_t>& pts,
+ const Bounds& zrange,
+ const Color& color,
+ bool inherit_color ) :
+ group(group),
pts(pts),
- local_z( zmin, zmax ),
+ local_z( zrange ),
color( color ),
inherit_color( inherit_color ),
rendered_cells()
{
- assert( mod );
+ assert( group );
canonicalize_winding(this->pts);
}
/** A from-file constructor */
-Block::Block( Model* mod,
- Worldfile* wf,
- int entity)
- : mod( mod ),
+Block::Block( BlockGroup* group,
+ Worldfile* wf,
+ int entity)
+ : group(group),
pts(),
local_z(),
color(),
inherit_color(true),
rendered_cells()
{
- assert(mod);
assert(wf);
assert(entity);
Load( wf, entity );
- canonicalize_winding(this->pts);
}
Block::~Block()
@@ -55,6 +52,12 @@ Block::~Block()
}
}
+Model* Block::GetModel()
+{
+ return &group->mod;
+};
+
+
void Block::Translate( double x, double y )
{
FOR_EACH( it, pts )
@@ -63,7 +66,7 @@ void Block::Translate( double x, double y )
it->y += y;
}
- mod->blockgroup.BuildDisplayList( mod );
+ group->BuildDisplayList();
}
/** Return the value half way between the min and max Y position of
@@ -131,25 +134,25 @@ void Block::SetZ( double min, double max )
local_z.max = max;
// force redraw
- mod->blockgroup.BuildDisplayList( mod );
+ group->BuildDisplayList();
}
const Color& Block::GetColor()
{
- return( inherit_color ? mod->color : color );
+ return( inherit_color ? group->mod.color : color );
}
void Block::AppendTouchingModels( std::set<Model*>& touchers )
{
- unsigned int layer = mod->world->updates % 2;
+ unsigned int layer = group->mod.world->updates % 2;
// for every cell we are rendered into
FOR_EACH( cell_it, rendered_cells[layer] )
// for every block rendered into that cell
FOR_EACH( block_it, (*cell_it)->GetBlocks(layer) )
{
- if( !mod->IsRelated( (*block_it)->mod ))
- touchers.insert( (*block_it)->mod );
+ if( !group->mod.IsRelated( &(*block_it)->group->mod ))
+ touchers.insert( &(*block_it)->group->mod );
}
}
@@ -160,12 +163,12 @@ Model* Block::TestCollision()
// find the set of cells we would render into given the current global pose
//GenerateCandidateCells();
- if( mod->vis.obstacle_return )
+ if( group->mod.vis.obstacle_return )
{
if ( global_z.min < 0 )
- return mod->world->GetGround();
+ return group->mod.world->GetGround();
- unsigned int layer = mod->world->updates % 2;
+ unsigned int layer = group->mod.world->updates % 2;
// for every cell we may be rendered into
FOR_EACH( cell_it, rendered_cells[layer] )
@@ -174,14 +177,14 @@ Model* Block::TestCollision()
FOR_EACH( block_it, (*cell_it)->GetBlocks(layer) )
{
Block* testblock = *block_it;
- Model* testmod = testblock->mod;
+ Model* testmod = &testblock->group->mod;
//printf( " testing block %p of model %s\n", testblock, testmod->Token() );
// if the tested model is an obstacle and it's not attached to this model
- if( (testmod != this->mod) &&
+ if( (testmod != &group->mod) &&
testmod->vis.obstacle_return &&
- (!mod->IsRelated( testmod )) &&
+ (!group->mod.IsRelated( testmod )) &&
// also must intersect in the Z range
testblock->global_z.min <= global_z.max &&
testblock->global_z.max >= global_z.min )
@@ -198,22 +201,20 @@ Model* Block::TestCollision()
}
void Block::Map( unsigned int layer )
-{
+{
// calculate the global pixel coords of the block vertices
// and render this block's polygon into the world
- mod->world->MapPoly( mod->LocalToPixels( pts ), this, layer );
+ group->mod.world->MapPoly( group->mod.LocalToPixels( pts ), this, layer );
// update the block's absolute z bounds at this rendering
- Pose gpose( mod->GetGlobalPose() );
- gpose.z += mod->geom.pose.z;
+ Pose gpose( group->mod.GetGlobalPose() );
+ gpose.z += group->mod.geom.pose.z;
global_z.min = local_z.min + gpose.z;
global_z.max = local_z.max + gpose.z;
mapped = true;
}
-#include <algorithm>
-#include <functional>
void Block::UnMap( unsigned int layer )
{
@@ -248,13 +249,13 @@ void Block::Rasterize( uint8_t* data,
point_t mpt2 = pts[(i+1)%pt_count]; // BlockPointToModelMeters( pts[(i+1)%pt_count] );
// record for debug visualization
- mod->rastervis.AddPoint( mpt1.x, mpt1.y );
+ group->mod.rastervis.AddPoint( mpt1.x, mpt1.y );
// shift to the bottom left of the model
- mpt1.x += mod->geom.size.x/2.0;
- mpt1.y += mod->geom.size.y/2.0;
- mpt2.x += mod->geom.size.x/2.0;
- mpt2.y += mod->geom.size.y/2.0;
+ mpt1.x += group->mod.geom.size.x/2.0;
+ mpt1.y += group->mod.geom.size.y/2.0;
+ mpt2.x += group->mod.geom.size.x/2.0;
+ mpt2.y += group->mod.geom.size.y/2.0;
// convert from meters to cells
point_int_t a( floor( mpt1.x / cellwidth ),
@@ -361,6 +362,7 @@ void Block::Load( Worldfile* wf, int entity )
pts.push_back( pt );
}
+ canonicalize_winding(pts);
wf->ReadTuple( entity, "z", 0, 2, "ll", &local_z.min, &local_z.max );
View
59 libstage/blockgroup.cc
@@ -10,9 +10,10 @@
using namespace Stg;
using namespace std;
-BlockGroup::BlockGroup()
- : displaylist(0),
- blocks()
+BlockGroup::BlockGroup( Model& mod )
+ : blocks(),
+ displaylist(0),
+ mod(mod)
{ /* empty */ }
BlockGroup::~BlockGroup()
@@ -52,7 +53,7 @@ Model* BlockGroup::TestCollision()
/** find the 3d bounding box of all the blocks in the group */
-bounds3d_t BlockGroup::BoundingBox()
+bounds3d_t BlockGroup::BoundingBox() const
{
// assuming the blocks currently fit in a square +/- one billion units
double minx, miny, maxx, maxy, minz, maxz;
@@ -90,7 +91,7 @@ void BlockGroup::CalcSize()
// now scale the blocks to fit in the model's 3d bounding box, so
// that the original points are now in model coordinates
- const Size modsize = blocks[0].mod->geom.size;
+ const Size modsize = mod.geom.size;
FOR_EACH( it, blocks )
{
@@ -137,11 +138,11 @@ void BlockGroup::DrawFootPrint( const Geom & geom )
it->DrawFootPrint();
}
-void BlockGroup::BuildDisplayList( Model* mod )
+void BlockGroup::BuildDisplayList()
{
//puts( "build" );
- if( ! mod->world->IsGUI() )
+ if( ! mod.world->IsGUI() )
return;
//printf( "display list for model %s\n", mod->token );
@@ -157,7 +158,7 @@ void BlockGroup::BuildDisplayList( Model* mod )
// render each block as a polygon extruded into Z
- Geom geom = mod->GetGeom();
+ Geom geom = mod.GetGeom();
Gl::pose_shift( geom.pose );
@@ -165,23 +166,23 @@ void BlockGroup::BuildDisplayList( Model* mod )
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(1.0, 1.0);
- mod->PushColor( mod->color );
+ mod.PushColor( mod.color );
//const bool topview = dynamic_cast<WorldGui*>(mod->world)->IsTopView();
FOR_EACH( blk, blocks )
{
- if( (!blk->inherit_color) && (blk->color != mod->color) )
+ if( (!blk->inherit_color) && (blk->color != mod.color) )
{
- mod->PushColor( blk->color );
+ mod.PushColor( blk->color );
blk->DrawSolid(false);
- mod->PopColor();
+ mod.PopColor();
}
else
blk->DrawSolid(false);
}
- mod->PopColor();
+ mod.PopColor();
// outline each poly in a darker version of the same color
@@ -190,23 +191,23 @@ void BlockGroup::BuildDisplayList( Model* mod )
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glDepthMask(GL_FALSE);
- Color c = mod->color;
+ Color c = mod.color;
c.r /= 2.0;
c.g /= 2.0;
c.b /= 2.0;
- mod->PushColor( c );
+ mod.PushColor( c );
FOR_EACH( blk, blocks )
{
- if( (!blk->inherit_color) && (blk->color != mod->color) )
+ if( (!blk->inherit_color) && (blk->color != mod.color) )
{
Color c = blk->color;
c.r /= 2.0;
c.g /= 2.0;
c.b /= 2.0;
- mod->PushColor( c );
+ mod.PushColor( c );
blk->DrawSolid(false);
- mod->PopColor();
+ mod.PopColor();
}
else
blk->DrawSolid(false);
@@ -215,29 +216,29 @@ void BlockGroup::BuildDisplayList( Model* mod )
glDepthMask(GL_TRUE);
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
- mod->PopColor();
+ mod.PopColor();
glEndList();
}
-void BlockGroup::CallDisplayList( Model* mod )
+void BlockGroup::CallDisplayList()
{
- if( displaylist == 0 || mod->rebuild_displaylist )
+ if( displaylist == 0 || mod.rebuild_displaylist )
{
- BuildDisplayList( mod );
- mod->rebuild_displaylist = 0;
+ BuildDisplayList();
+ mod.rebuild_displaylist = 0;
}
glCallList( displaylist );
}
-void BlockGroup::LoadBlock( Model* mod, Worldfile* wf, int entity )
+void BlockGroup::LoadBlock( Worldfile* wf, int entity )
{
- AppendBlock( Block( mod, wf, entity ));
- // CalcSize();
+ AppendBlock( Block( this, wf, entity ));
+
}
-void BlockGroup::LoadBitmap( Model* mod, const std::string& bitmapfile, Worldfile* wf )
+void BlockGroup::LoadBitmap( const std::string& bitmapfile, Worldfile* wf )
{
PRINT_DEBUG1( "attempting to load bitmap \"%s\n", bitmapfile );
@@ -287,9 +288,9 @@ void BlockGroup::LoadBitmap( Model* mod, const std::string& bitmapfile, Worldfil
pts[3].x = x;
pts[3].y = y + h;
- AppendBlock( Block( mod,
+ AppendBlock( Block( this,
pts,
- 0,1,
+ Bounds(0,1) ,
col,
true ) );
}
View
24 libstage/model.cc
@@ -248,8 +248,7 @@ Model::Model( World* world,
mapped(false),
drawOptions(),
alwayson(false),
- blockgroup(),
- blocks_dl(0),
+ blockgroup(*this),
boundary(false),
callbacks(__CB_TYPE_COUNT), // one slot in the vector for each type
color( 1,0,0 ), // red
@@ -435,7 +434,7 @@ void Model::LoadBlock( Worldfile* wf, int entity )
has_default_block = false;
}
- blockgroup.LoadBlock( this, wf, entity );
+ blockgroup.LoadBlock( wf, entity );
}
@@ -457,9 +456,9 @@ void Model::AddBlockRect( meters_t x,
pts[3].x = x;
pts[3].y = y + dy;
- blockgroup.AppendBlock( Block( this,
+ blockgroup.AppendBlock( Block( &blockgroup,
pts,
- 0, dz,
+ Bounds(0,dz),
color,
true ));
Map();
@@ -593,16 +592,19 @@ point_t Model::LocalToGlobal( const point_t& pt) const
std::vector<point_int_t> Model::LocalToPixels( const std::vector<point_t>& local ) const
{
- std::vector<point_int_t> global;
+ const size_t sz = local.size();
+
+ std::vector<point_int_t> global( sz );
const Pose gpose( GetGlobalPose() + geom.pose );
Pose ptpose;
- FOR_EACH( it, local )
+ for( size_t i=0; i<sz; i++ )
{
- ptpose = gpose + Pose( it->x, it->y, 0, 0 );
- global.push_back( point_int_t( (int32_t)floor( ptpose.x * world->ppm) ,
- (int32_t)floor( ptpose.y * world->ppm) ));
+ ptpose = gpose + Pose( local[i].x, local[i].y, 0, 0 );
+
+ global[i].x = (int32_t)floor( ptpose.x * world->ppm);
+ global[i].y = (int32_t)floor( ptpose.y * world->ppm);
}
return global;
@@ -1524,7 +1526,7 @@ void Model::Load()
has_default_block = false;
}
- blockgroup.LoadBitmap( this, bitmapfile, wf );
+ blockgroup.LoadBitmap( bitmapfile, wf );
}
if( wf->PropertyExists( wf_entity, "boundary" ))
View
2  libstage/model_draw.cc
@@ -250,7 +250,7 @@ void Model::DrawPose( Pose pose )
void Model::DrawBlocks( )
{
- blockgroup.CallDisplayList( this );
+ blockgroup.CallDisplayList();
}
void Model::DrawBoundingBoxTree()
View
8 libstage/model_gripper.cc
@@ -194,10 +194,10 @@ void ModelGripper::FixBlocks()
AddBlockRect( 1.0-cfg.paddle_size.x, 1.0-cfg.paddle_size.y, cfg.paddle_size.x, cfg.paddle_size.y, cfg.paddle_size.z );
// left (top) paddle
- paddle_left = &blockgroup.GetBlock(1);
+ paddle_left = &blockgroup.GetBlockMutable(1);
// right (bottom) paddle
- paddle_right = &blockgroup.GetBlock(2);
+ paddle_right = &blockgroup.GetBlockMutable(2);
PositionPaddles();
}
@@ -205,9 +205,9 @@ void ModelGripper::FixBlocks()
// Update the blocks that are the gripper's body
void ModelGripper::PositionPaddles()
{
- unsigned int layer = world->GetUpdateCount()%2;
+ 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);
View
113 libstage/stage.hh
@@ -1192,6 +1192,7 @@ namespace Stg
};
+
class Block
{
friend class BlockGroup;
@@ -1205,15 +1206,14 @@ namespace Stg
/** 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.*/
- Block( Model* mod,
+ Block( BlockGroup* group,
const std::vector<point_t>& pts,
- meters_t zmin,
- meters_t zmax,
- Color color,
+ const Bounds& zrange,
+ const Color& color,
bool inherit_color );
/** A from-file constructor */
- Block( Model* mod, Worldfile* wf, int entity);
+ Block( BlockGroup* group, Worldfile* wf, int entity);
~Block();
@@ -1256,8 +1256,9 @@ namespace Stg
Model* TestCollision();
void Load( Worldfile* wf, int entity );
-
- Model* GetModel(){ return mod; };
+
+ /** return a pointer to the Model that owns the BlockGroup that owns this Block.*/
+ Model* GetModel();
const Color& GetColor();
@@ -1266,7 +1267,10 @@ namespace Stg
meters_t cellwidth, meters_t cellheight );
private:
- Model* mod; ///< model to which this block belongs.
+ //Model* mod; ///< model to which this block belongs.
+
+ BlockGroup* group;
+
std::vector<point_t> pts; ///< points defining a polygon.
Size size; ///< Size of the polygon in meters.
Bounds local_z; ///< z extent in local coords.
@@ -1291,25 +1295,16 @@ namespace Stg
{
friend class Model;
friend class Block;
-
+ friend class World;
+
private:
- int displaylist;
-
- void BuildDisplayList( Model* mod );
-
- std::vector<Block> blocks;
-
- public:
- BlockGroup();
- ~BlockGroup();
-
- uint32_t GetCount() const { return blocks.size(); };
- Block& GetBlock( unsigned int index ) { return blocks[index]; };
- bounds3d_t BoundingBox();
+ std::vector<Block> blocks; ///< Contains the blocks in this group.
+ int displaylist; ///< OpenGL displaylist that renders this blockgroup.
+ Model& mod;
- void CalcSize();
void AppendBlock( const Block& block );
- void CallDisplayList( Model* mod );
+
+ void CalcSize();
void Clear() ; /** deletes all blocks from the group */
void AppendTouchingModels( std::set<Model*>& touchers );
@@ -1318,21 +1313,47 @@ namespace Stg
with a block in this group, or NULL, if none are detected. */
Model* TestCollision();
+ /** Renders all blocks into the bitmap at the indicated layer.*/
void Map( unsigned int layer );
+ /** Removes all blocks from the bitmap at the indicated layer.*/
void UnMap( unsigned int layer );
- /** Draw the block in OpenGL as a solid single color. */
- void DrawSolid( const Geom &geom);
-
- /** Draw the projection of the block onto the z=0 plane. */
- void DrawFootPrint( const Geom &geom);
+ /** Interpret the bitmap file as a set of rectangles and add them
+ as blocks to this group.*/
+ void LoadBitmap( const std::string& bitmapfile, Worldfile *wf );
- void LoadBitmap( Model* mod, const std::string& bitmapfile, Worldfile *wf );
- void LoadBlock( Model* mod, Worldfile* wf, int entity );
-
+ /** Add a new block decribed by a worldfile entry. */
+ void LoadBlock( Worldfile* wf, int entity );
+
+ /** Render the blockgroup as a bitmap image. */
void Rasterize( uint8_t* data,
unsigned int width, unsigned int height,
meters_t cellwidth, meters_t cellheight );
+
+ /** Draw the block in OpenGL as a solid single color. */
+ void DrawSolid( const Geom &geom);
+
+ /** Re-create the display list for drawing this blockgroup. This
+ is required whenever a member block or the owning model
+ changes its appearance.*/
+ void BuildDisplayList();
+
+ /** Draw the blockgroup from the cached displaylist. */
+ void CallDisplayList();
+
+ public:
+ BlockGroup( Model& mod );
+ ~BlockGroup();
+
+ uint32_t GetCount() const { return blocks.size(); };
+ const Block& GetBlock( unsigned int index ) const { return blocks[index]; };
+ Block& GetBlockMutable( unsigned int index ) { return blocks[index]; };
+
+ /** Return the extremal points of all member blocks in all three axes. */
+ bounds3d_t BoundingBox() const;
+
+ /** Draw the projection of the block group onto the z=0 plane. */
+ void DrawFootPrint( const Geom &geom);
};
class Camera
@@ -1745,8 +1766,6 @@ namespace Stg
bool alwayson;
BlockGroup blockgroup;
- /** OpenGL display list identifier for the blockgroup */
- int blocks_dl;
/** Iff true, 4 thin blocks are automatically added to the model,
forming a solid boundary around the bounding box of the
@@ -2117,10 +2136,7 @@ namespace Stg
RaytraceResult* samples,
const uint32_t sample_count,
const bool ztest = true );
-
- virtual void Startup();
- virtual void Shutdown();
- virtual void Update();
+
virtual void UpdateCharge();
static int UpdateWrapper( Model* mod, void* arg ){ mod->Update(); return 0; }
@@ -2191,7 +2207,7 @@ namespace Stg
/** Alternate constructor that creates dummy models with only a pose */
Model()
- : mapped(false), alwayson(false), blocks_dl(0),
+ : mapped(false), alwayson(false), blockgroup(*this),
boundary(false), data_fresh(false), disabled(true), friction(0), has_default_block(false), log_state(false), map_resolution(0), mass(0), parent(NULL), rebuild_displaylist(false), stack_children(true), stall(false), subs(0), thread_safe(false),trail_index(0), event_queue_num(0), used(false), watts(0), watts_give(0),watts_take(0),wf(NULL), wf_entity(0), world(NULL)
{}
@@ -2446,7 +2462,10 @@ namespace Stg
// Neighbors() : left(NULL), right(NULL), up(NULL), down(NULL) {}
// } nbors; // instance
-
+ protected:
+ virtual void Startup();
+ virtual void Shutdown();
+ virtual void Update();
};
@@ -2908,6 +2927,7 @@ namespace Stg
class ModelPosition : public Model
{
friend class Canvas;
+ friend class World;
public:
/** Define a position control method */
@@ -2946,7 +2966,6 @@ namespace Stg
/** Set the min and max velocity in all 4 DOF */
Bounds velocity_bounds[4];
- public:
// constructor
ModelPosition( World* world,
Model* parent,
@@ -2954,11 +2973,6 @@ namespace Stg
// destructor
~ModelPosition();
- virtual void Move();
- virtual void Startup();
- virtual void Shutdown();
- virtual void Update();
- virtual void Load();
/** Get (a copy of) the model's velocity in its local reference
frame. */
@@ -3025,6 +3039,13 @@ namespace Stg
Pose est_pose; ///< position estimate in local coordinates
Pose est_pose_error; ///< estimated error in position estimate
Pose est_origin; ///< global origin of the local coordinate system
+
+ protected:
+ virtual void Move();
+ virtual void Startup();
+ virtual void Shutdown();
+ virtual void Update();
+ virtual void Load();
};
View
4 libstage/world.cc
@@ -875,11 +875,11 @@ RaytraceResult World::Raytrace( const Ray& r )
continue;
// test the predicate we were passed
- if( (*r.func)( block->mod, (Model*)r.mod, r.arg ))
+ if( (*r.func)( &block->group->mod, (Model*)r.mod, r.arg ))
{
// a hit!
sample.color = block->GetColor();
- sample.mod = block->mod;
+ sample.mod = &block->group->mod;
if( ax > ay ) // faster than the equivalent hypot() call
sample.range = fabs((globx-startx) / cosa) / ppm;
Please sign in to comment.
Something went wrong with that request. Please try again.