Permalink
Browse files

small optimizations

  • Loading branch information...
1 parent d464722 commit edbf4371a5414f172e81031c15b255197856aca4 @rtv committed Dec 3, 2010
Showing with 162 additions and 93 deletions.
  1. +73 −74 libstage/block.cc
  2. +5 −5 libstage/stage.hh
  3. +84 −14 libstage/world.cc
View
@@ -194,29 +194,28 @@ void Block::Map()
RemoveFromCellArray( rendered_cells );
// now calculate the local coords of the block vertices
- const unsigned int pt_count = pts.size();
+ const size_t pt_count(pts.size());
if( mpts.size() == 0 )
{
// no valid cache of model coord points, so generate them
mpts.resize( pts.size() );
- for( unsigned int i=0; i<pt_count; ++i )
+ for( size_t i=0; i<pt_count; ++i )
mpts[i] = BlockPointToModelMeters( pts[i] );
}
// now calculate the global pixel coords of the block vertices
gpts.clear();
mod->LocalToPixels( mpts, gpts );
-
- for( unsigned int i=0; i<pt_count; ++i )
- MapLine( gpts[i],
- gpts[(i+1)%pt_count] );
+
+ // and render this block's polygon into the world
+ mod->GetWorld()->MapPoly( gpts, this );
// update the block's absolute z bounds at this rendering
- Pose gpose = mod->GetGlobalPose();
+ Pose gpose( mod->GetGlobalPose() );
gpose.z += mod->geom.pose.z;
- double scalez = mod->geom.size.z / mod->blockgroup.GetSize().z;
+ double scalez( mod->geom.size.z / mod->blockgroup.GetSize().z );
meters_t z = gpose.z - mod->blockgroup.GetOffset().z;
global_z.min = (scalez * local_z.min) + z;
global_z.max = (scalez * local_z.max) + z;
@@ -281,8 +280,8 @@ void Block::Rasterize( uint8_t* data,
//printf( "rasterize block %p : w: %u h: %u scale %.2f %.2f offset %.2f %.2f\n",
// this, width, height, scalex, scaley, offsetx, offsety );
- const unsigned int pt_count = pts.size();
- for( unsigned int i=0; i<pt_count; ++i )
+ const size_t pt_count = pts.size();
+ for( size_t i=0; i<pt_count; ++i )
{
// convert points from local to model coords
point_t mpt1 = BlockPointToModelMeters( pts[i] );
@@ -406,10 +405,10 @@ void Block::DrawSolid()
void Block::Load( Worldfile* wf, int entity )
{
- const unsigned int pt_count = wf->ReadInt( entity, "points", 0);
+ const size_t pt_count = wf->ReadInt( entity, "points", 0);
char key[128];
- for( unsigned int p=0; p<pt_count; ++p )
+ for( size_t p=0; p<pt_count; ++p )
{
snprintf(key, sizeof(key), "point[%d]", p );
@@ -434,72 +433,72 @@ void Block::Load( Worldfile* wf, int entity )
}
-void Block::MapLine( const point_int_t& start,
- const point_int_t& end )
-{
- // 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);
-
-
- World* w = mod->GetWorld();
-
- while( n )
- {
- Region* reg( w->GetSuperRegionCreate( point_int_t(GETSREG(globx), GETSREG(globy)))
- ->GetRegion( GETREG(globx), GETREG(globy) ));
+// void Block::MapLine( const point_int_t& start,
+// const point_int_t& end )
+// {
+// // 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( mod->GetWorld()
+// ->GetSuperRegionCreate( point_int_t(GETSREG(globx),
+// GETSREG(globy)))
+// ->GetRegion( GETREG(globx),
+// GETREG(globy)));
- //printf( "REGION %p\n", 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) );
+// // 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(this);
+// // 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(this);
- // 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;
- }
- }
-}
+// // 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;
+// }
+// }
+// }
/////////////////////////////////////////////////////////////////////////////////////////
// utility functions to ensure block winding is consistent and matches OpenGL's default
View
@@ -609,7 +609,7 @@ namespace Stg
// this could be an issue one day.
#define VAR(V,init) __typeof(init) V=(init)
- //#define FOR_EACH(I,C) for(VAR(I,(C).begin());I!=(C).end();++I)
+//#define FOR_EACH(I,C) for(VAR(I,(C).begin());I!=(C).end();++I)
// NOTE:
// this version assumes the container is not modified in the loop,
@@ -955,6 +955,10 @@ namespace Stg
virtual Model* RecentlySelectedModel() const { return NULL; }
+ /** call Cell::AddBlock(block) for each cell on the polygon */
+ void MapPoly( const PointIntVec& poly,
+ Block* block );
+
SuperRegion* AddSuperRegion( const point_int_t& coord );
SuperRegion* GetSuperRegion( const point_int_t& org );
SuperRegion* GetSuperRegionCreate( const point_int_t& org );
@@ -1274,10 +1278,6 @@ namespace Stg
/** invalidate the cache of points in model coordinates */
void InvalidateModelPointCache();
- /** add a Cell pointer to the vector for each cell on the line from
- pt1 to pt2 inclusive */
- void MapLine( const point_int_t& pt1,
- const point_int_t& pt2 );
};
View
@@ -782,25 +782,20 @@ RaytraceResult World::Raytrace( const Ray& r )
double ycrossx(0), ycrossy(0);
double distX(0), distY(0);
bool calculatecrossings( true );
-
+
// Stage spends up to 95% of its time in this loop! It would be
// neater with more function calls encapsulating things, but even
// inline calls have a noticeable (2-3%) effect on performance.
while( n > 0 ) // while we are still not at the ray end
{
- SuperRegion* sr = GetSuperRegion( point_int_t(GETSREG(globx), GETSREG(globy)) );
- //SuperRegion* sr = GetSuperRegion( point_int_t(GETSREG(globx), GETSREG(globy)) );
-
- Region* reg = NULL;
-
- if( sr )
- reg = sr->GetRegion( GETREG(globx), GETREG(globy) );
+ SuperRegion* sr( GetSuperRegion(point_int_t(GETSREG(globx),GETSREG(globy))));
+ Region* reg( sr ? sr->GetRegion(GETREG(globx),GETREG(globy)) : NULL );
if( reg && reg->count ) // if the region contains any objects
- {
- //assert( reg->cells.size() );
-
- // invalidate the region crossing points used to jump over
+ {
+ //assert( reg->cells.size() );
+
+ // invalidate the region crossing points used to jump over
// empty regions
calculatecrossings = true;
@@ -975,6 +970,81 @@ void World::Reload( void )
ForEachDescendant( _reload_cb, NULL );
}
+
+void World::MapPoly( const PointIntVec& pts, Block* block )
+{
+ 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);
+
+ while( n )
+ {
+ Region* reg( GetSuperRegionCreate( point_int_t(GETSREG(globx),
+ GETSREG(globy)))
+ ->GetRegion( GETREG(globx),
+ GETREG(globy)));
+
+ //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);
+
+ // 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;
+ }
+ }
+ }
+}
+
+
SuperRegion* World::AddSuperRegion( const point_int_t& sup )
{
SuperRegion* sr = CreateSuperRegion( sup );
@@ -1025,15 +1095,15 @@ inline SuperRegion* World::GetSuperRegion( const point_int_t& org )
return sr;
}
-SuperRegion* World::GetSuperRegionCreate( const point_int_t& org )
+inline SuperRegion* World::GetSuperRegionCreate( const point_int_t& org )
{
SuperRegion* sr = GetSuperRegion(org);
if( sr == NULL ) // no superregion exists! make a new one
{
sr = AddSuperRegion( org );
assert( sr );
- //sr_cached = sr;
+ sr_cached = sr;
}
return sr;

0 comments on commit edbf437

Please sign in to comment.