Browse files

cleaning up Block class

  • Loading branch information...
1 parent 7d4d001 commit 17f2908f07665eb163c6a92f92e75cc729ee2525 rtv committed Jun 14, 2009
Showing with 139 additions and 146 deletions.
  1. +31 −48 libstage/block.cc
  2. +4 −0 libstage/region.hh
  3. +47 −64 libstage/stage.hh
  4. +57 −34 libstage/world.cc
View
79 libstage/block.cc
@@ -16,34 +16,37 @@ Block::Block( Model* mod,
bool inherit_color
) :
mod( mod ),
- mpts(NULL),
+ mpts(),
pt_count( pt_count ),
- pts( (stg_point_t*)g_memdup( pts, pt_count * sizeof(stg_point_t)) ),
+ pts(),
+ local_z( zmin, zmax ),
color( color ),
inherit_color( inherit_color ),
rendered_cells( new std::vector<Cell*> ),
- candidate_cells( new std::vector<Cell*> )
+ candidate_cells( new std::vector<Cell*> ),
+ gpts()
{
assert( mod );
assert( pt_count > 0 );
- assert( pts );
- local_z.min = zmin;
- local_z.max = zmax;
+ // copy the argument point data into the member vector
+ this->pts.reserve( pt_count );
+ for( size_t p=0; p<pt_count; p++ )
+ this->pts.push_back( pts[p] );
}
/** A from-file constructor */
Block::Block( Model* mod,
Worldfile* wf,
int entity)
: mod( mod ),
- mpts(NULL),
+ mpts(),
pt_count(0),
- pts(NULL),
+ pts(),
color(0),
inherit_color(true),
- rendered_cells( new std::vector<Cell*> ),
- candidate_cells( new std::vector<Cell*> )
+ rendered_cells( new std::vector<Cell*> ),
+ candidate_cells( new std::vector<Cell*> )
{
assert(mod);
assert(wf);
@@ -56,10 +59,7 @@ Block::~Block()
{
if( mapped ) UnMap();
- if( pts ) delete[] pts;
- InvalidateModelPointCache();
-
- delete rendered_cells;
+ delete rendered_cells;
delete candidate_cells;
}
@@ -256,48 +256,34 @@ inline stg_point_t Block::BlockPointToModelMeters( const stg_point_t& bpt )
(bpt.y - bgoffset.y) * (mod->geom.size.y/bgsize.y));
}
-stg_point_t* Block::GetPointsInModelCoords()
-{
- if( ! mpts )
- {
- // no valid cache of model coord points, so generate them
- mpts = new stg_point_t[pt_count];
-
- for( unsigned int i=0; i<pt_count; i++ )
- mpts[i] = BlockPointToModelMeters( pts[i] );
- }
-
- return mpts;
-}
-
void Block::InvalidateModelPointCache()
{
- // this doesn't happen often, so this simple strategy isn't too wasteful
- if( mpts )
- {
- delete[] mpts;
- mpts = NULL;
- }
+ // this doesn't happen often, so this simple strategy isn't too wasteful
+ mpts.clear();
}
void Block::GenerateCandidateCells()
{
candidate_cells->clear();
-
- stg_point_t* mpts = GetPointsInModelCoords();
-
+
+ if( mpts.size() == 0 )
+ {
+ // no valid cache of model coord points, so generate them
+ mpts.resize( pt_count );
+ for( unsigned int i=0; i<pt_count; i++ )
+ mpts[i] = BlockPointToModelMeters( pts[i] );
+ }
+
// convert the mpts in model coords into global pixel coords
- stg_point_int_t gpts[pt_count]; // should be plenty of room on the
- // stack (crosses fingers). I don't
- // want to pay for a malloc here.
+ gpts.resize(pt_count);
+
for( unsigned int i=0; i<pt_count; i++ )
gpts[i] = mod->world->MetersToPixels( mod->LocalToGlobal( mpts[i] ));
for( unsigned int i=0; i<pt_count; i++ )
- mod->world->ForEachCellInLine( gpts[i],
- gpts[(i+1)%pt_count],
- *candidate_cells );
-
+ mod->world->ForEachCellInLine( gpts[i],
+ gpts[(i+1)%pt_count],
+ *candidate_cells );
// set global Z
Pose gpose = mod->GetGlobalPose();
gpose.z += mod->geom.pose.z;
@@ -464,11 +450,8 @@ void Block::Load( Worldfile* wf, int entity )
{
//printf( "Block::Load entity %d\n", entity );
- if( pts )
- delete[] pts;
-
pt_count = wf->ReadInt( entity, "points", 0);
- pts = new stg_point_t[ pt_count ];
+ pts.resize( pt_count );
//printf( "reading %d points\n",
// pt_count );
View
4 libstage/region.hh
@@ -31,6 +31,10 @@ namespace Stg
inline int32_t GETREG( const int32_t x ) { return( ( x & REGIONMASK ) >> RBITS); }
inline int32_t GETSREG( const int32_t x ) { return( x >> SRBITS); }
+ // this is slightly faster than the inline method above, but not as safe
+ //#define GETREG(X) (( (static_cast<int32_t>(X)) & REGIONMASK ) >> RBITS)
+
+
class Cell
{
friend class Region;
View
111 libstage/stage.hh
@@ -370,12 +370,13 @@ namespace Stg
class Bounds
{
public:
- /// largest value in range, initially zero
- double max;
- /// smallest value in range, initially zero
+ /// smallest value in range, initially zero
double min;
+ /// largest value in range, initially zero
+ double max;
- Bounds() : max(0), min(0) { /* empty*/ }
+ Bounds() : min(0), max(0) { /* empty*/ }
+ Bounds( double min, double max ) : min(min), max(max) { /* empty*/ }
};
/** Define a three-dimensional bounding box, initialized to zero */
@@ -1006,9 +1007,6 @@ namespace Stg
void ExpireSuperRegion( SuperRegion* sr );
inline Cell* GetCell( const stg_point_int_t& glob );
- //inline Cell* GetCellNoCreate( const int32_t x, const int32_t y );
- //inline Cell* GetCellCreate( const int32_t x, const int32_t y );
- //inline Cell* GetCellCreate( const stg_point_int_t& glob );
/** add a Cell pointer to the vector for each cell on the line from
pt1 to pt2 inclusive */
@@ -1164,75 +1162,58 @@ namespace Stg
~Block();
/** render the block into the world's raytrace data structure */
- void Map();
-
+ void Map();
/** remove the block from the world's raytracing data structure */
- void UnMap();
-
+ void UnMap();
void Draw( Model* mod );
void DrawSolid(); // draw the block in OpenGL as a solid single color
- void DrawFootPrint(); // draw the projection of the block onto the z=0 plane
-
- /** Translate all points in the block by the indicated amounts */
- void Translate( double x, double y );
-
- /** Return the center of the block on the X axis */
- double CenterX();
+ void DrawFootPrint(); // draw the projection of the block onto the z=0 plane
+ /** Translate all points in the block by the indicated amounts */
+ void Translate( double x, double y );
+ /** Return the center of the block on the X axis */
+ double CenterX();
/** Return the center of the block on the Y axis */
- double CenterY();
-
- /** Set the center of the block on the X axis */
- void SetCenterX( double y );
- /** Set the center of the block on the Y axis */
- void SetCenterY( double y );
- /** Set the center of the block */
- void SetCenter( double x, double y);
-
- void SetZ( double min, double max );
+ double CenterY();
+ /** Set the center of the block on the X axis */
+ void SetCenterX( double y );
+ /** Set the center of the block on the Y axis */
+ void SetCenterY( double y );
+ /** Set the center of the block */
+ void SetCenter( double x, double y);
+ void SetZ( double min, double max );
void RecordRendering( Cell* cell )
- {
- rendered_cells->push_back( cell );
- }
-
- stg_point_t* Points( unsigned int *count )
- { if( count ) *count = pt_count; return pts; };
-
- //bool IntersectGlobalZ( stg_meters_t z )
- //{ return( z >= global_zmin && z <= global_zmax ); }
-
- void AddToCellArray( std::vector<Cell*>* blocks );
- void RemoveFromCellArray( std::vector<Cell*>* blocks );
-
- void GenerateCandidateCells();
-
- // /** Prepare to render the block in a new position in global coordinates */
- // void SetPoseTentative( const Pose pose );
-
+ { rendered_cells->push_back( cell ); }
- GList* AppendTouchingModels( GList* list );
+ stg_point_t* Points( unsigned int *count )
+ { if( count ) *count = pt_count; return &pts[0]; };
- /** Returns the first model that shares a bitmap cell with this model */
- Model* TestCollision();
-
- void SwitchToTestedCells();
-
- void Load( Worldfile* wf, int entity );
-
- Model* GetModel(){ return mod; };
-
- stg_color_t GetColor();
-
- void Rasterize( uint8_t* data,
- unsigned int width, unsigned int height,
- stg_meters_t cellwidth, stg_meters_t cellheight );
+ std::vector<stg_point_t>& Points()
+ { return pts; };
+ void AddToCellArray( std::vector<Cell*>* blocks );
+ void RemoveFromCellArray( std::vector<Cell*>* blocks );
+ void GenerateCandidateCells();
+ GList* AppendTouchingModels( GList* list );
+
+ /** Returns the first model that shares a bitmap cell with this model */
+ Model* TestCollision();
+ void SwitchToTestedCells();
+ void Load( Worldfile* wf, int entity );
+ Model* GetModel(){ return mod; };
+ stg_color_t GetColor();
+ void Rasterize( uint8_t* data,
+ unsigned int width, unsigned int height,
+ stg_meters_t cellwidth, stg_meters_t cellheight );
+
private:
Model* mod; ///< model to which this block belongs
- stg_point_t* mpts; ///< cache of this->pts in model coordindates
+ std::vector<stg_point_t> mpts; ///< cache of this->pts in model coordindates
size_t pt_count; ///< the number of points
- stg_point_t* pts; ///< points defining a polygon
+
+ std::vector<stg_point_t> pts; ///< points defining a polygonx
+ //stg_point_t* pts; ///< points defining a polygon
Size size;
@@ -1261,12 +1242,14 @@ namespace Stg
switched for next time (avoiding a memory copy).*/
std::vector<Cell*> * candidate_cells;
+ std::vector<stg_point_int_t> gpts;
+
/** find the position of a block's point in model coordinates
(m) */
stg_point_t BlockPointToModelMeters( const stg_point_t& bpt );
/** Update the cache of block points converted to model coordinates */
- stg_point_t* GetPointsInModelCoords();
+ //stg_point_t* GetPointsInModelCoords();
/** invalidate the cache of points in model coordinates */
void InvalidateModelPointCache();
View
91 libstage/world.cc
@@ -757,7 +757,7 @@ stg_raytrace_result_t World::Raytrace( const Ray& r )
c += sy * REGIONWIDTH; // move the cell up or down
cy += sy; // cell coordinate for bounds checking
}
- n--; // decrement the manhattan distance remaining
+ --n; // decrement the manhattan distance remaining
//rt_cells.push_back( stg_point_int_t( globx, globy ));
}
@@ -945,46 +945,69 @@ void World::ForEachCellInLine( const stg_point_int_t& start,
const stg_point_int_t& end,
std::vector<Cell*>& cells )
{
-
- int dx = end.x - start.x;
- int dy = end.y - start.y;
-
- stg_point_int_t cell = start;
-
// line rasterization adapted from Cohen's 3D version in
- // Graphics Gems II. Should be very fast.
-
- const int sx(sgn(dx));
- const int sy(sgn(dy));
- const int ax(abs(dx));
- const int ay(abs(dy));
- const int bx(2*ax);
- const int by(2*ay);
- int exy(ay-ax);
- int n(ax+ay);
+ // 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);
// 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++;
+ // if( (dx > 0) || ( dy > 0 ) )
+ // n++;
- while( n-- )
+ while( n )
{
- // find the cell at this location, then add it to the vector
- cells.push_back( GetCell( cell ) );
-
- // cleverly skip to the next cell
- if( exy < 0 )
- {
- cell.x += sx;
- exy += by;
- }
- else
- {
- cell.y += sy;
- exy -= bx;
+ Region* reg( GetSuperRegionCached( GETSREG(globx), GETSREG(globy) )
+ ->GetRegion( GETREG(globx), GETREG(globy) ));
+
+ // 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( (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 );
+
+ // 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;
}
- }
+
+ }
}
void World::Extend( stg_point3_t pt )

0 comments on commit 17f2908

Please sign in to comment.