Skip to content

Commit edbf437

Browse files
committed
small optimizations
1 parent d464722 commit edbf437

File tree

3 files changed

+162
-93
lines changed

3 files changed

+162
-93
lines changed

libstage/block.cc

Lines changed: 73 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -194,29 +194,28 @@ void Block::Map()
194194
RemoveFromCellArray( rendered_cells );
195195

196196
// now calculate the local coords of the block vertices
197-
const unsigned int pt_count = pts.size();
197+
const size_t pt_count(pts.size());
198198

199199
if( mpts.size() == 0 )
200200
{
201201
// no valid cache of model coord points, so generate them
202202
mpts.resize( pts.size() );
203203

204-
for( unsigned int i=0; i<pt_count; ++i )
204+
for( size_t i=0; i<pt_count; ++i )
205205
mpts[i] = BlockPointToModelMeters( pts[i] );
206206
}
207207

208208
// now calculate the global pixel coords of the block vertices
209209
gpts.clear();
210210
mod->LocalToPixels( mpts, gpts );
211-
212-
for( unsigned int i=0; i<pt_count; ++i )
213-
MapLine( gpts[i],
214-
gpts[(i+1)%pt_count] );
211+
212+
// and render this block's polygon into the world
213+
mod->GetWorld()->MapPoly( gpts, this );
215214

216215
// update the block's absolute z bounds at this rendering
217-
Pose gpose = mod->GetGlobalPose();
216+
Pose gpose( mod->GetGlobalPose() );
218217
gpose.z += mod->geom.pose.z;
219-
double scalez = mod->geom.size.z / mod->blockgroup.GetSize().z;
218+
double scalez( mod->geom.size.z / mod->blockgroup.GetSize().z );
220219
meters_t z = gpose.z - mod->blockgroup.GetOffset().z;
221220
global_z.min = (scalez * local_z.min) + z;
222221
global_z.max = (scalez * local_z.max) + z;
@@ -281,8 +280,8 @@ void Block::Rasterize( uint8_t* data,
281280
//printf( "rasterize block %p : w: %u h: %u scale %.2f %.2f offset %.2f %.2f\n",
282281
// this, width, height, scalex, scaley, offsetx, offsety );
283282

284-
const unsigned int pt_count = pts.size();
285-
for( unsigned int i=0; i<pt_count; ++i )
283+
const size_t pt_count = pts.size();
284+
for( size_t i=0; i<pt_count; ++i )
286285
{
287286
// convert points from local to model coords
288287
point_t mpt1 = BlockPointToModelMeters( pts[i] );
@@ -406,10 +405,10 @@ void Block::DrawSolid()
406405

407406
void Block::Load( Worldfile* wf, int entity )
408407
{
409-
const unsigned int pt_count = wf->ReadInt( entity, "points", 0);
408+
const size_t pt_count = wf->ReadInt( entity, "points", 0);
410409

411410
char key[128];
412-
for( unsigned int p=0; p<pt_count; ++p )
411+
for( size_t p=0; p<pt_count; ++p )
413412
{
414413
snprintf(key, sizeof(key), "point[%d]", p );
415414

@@ -434,72 +433,72 @@ void Block::Load( Worldfile* wf, int entity )
434433
}
435434

436435

437-
void Block::MapLine( const point_int_t& start,
438-
const point_int_t& end )
439-
{
440-
// line rasterization adapted from Cohen's 3D version in
441-
// Graphics Gems II. Should be very fast.
442-
const int32_t dx( end.x - start.x );
443-
const int32_t dy( end.y - start.y );
444-
const int32_t sx(sgn(dx));
445-
const int32_t sy(sgn(dy));
446-
const int32_t ax(abs(dx));
447-
const int32_t ay(abs(dy));
448-
const int32_t bx(2*ax);
449-
const int32_t by(2*ay);
450-
int32_t exy(ay-ax);
451-
int32_t n(ax+ay);
452-
453-
int32_t globx(start.x);
454-
int32_t globy(start.y);
455-
456-
457-
World* w = mod->GetWorld();
458-
459-
while( n )
460-
{
461-
Region* reg( w->GetSuperRegionCreate( point_int_t(GETSREG(globx), GETSREG(globy)))
462-
->GetRegion( GETREG(globx), GETREG(globy) ));
436+
// void Block::MapLine( const point_int_t& start,
437+
// const point_int_t& end )
438+
// {
439+
// // line rasterization adapted from Cohen's 3D version in
440+
// // Graphics Gems II. Should be very fast.
441+
// const int32_t dx( end.x - start.x );
442+
// const int32_t dy( end.y - start.y );
443+
// const int32_t sx(sgn(dx));
444+
// const int32_t sy(sgn(dy));
445+
// const int32_t ax(abs(dx));
446+
// const int32_t ay(abs(dy));
447+
// const int32_t bx(2*ax);
448+
// const int32_t by(2*ay);
449+
// int32_t exy(ay-ax);
450+
// int32_t n(ax+ay);
451+
452+
// int32_t globx(start.x);
453+
// int32_t globy(start.y);
454+
455+
// while( n )
456+
// {
457+
// Region* reg( mod->GetWorld()
458+
// ->GetSuperRegionCreate( point_int_t(GETSREG(globx),
459+
// GETSREG(globy)))
460+
// ->GetRegion( GETREG(globx),
461+
// GETREG(globy)));
463462

464-
//printf( "REGION %p\n", reg );
463+
// //printf( "REGION %p\n", reg );
465464

466-
// add all the required cells in this region before looking up
467-
// another region
468-
int32_t cx( GETCELL(globx) );
469-
int32_t cy( GETCELL(globy) );
465+
// // add all the required cells in this region before looking up
466+
// // another region
467+
// int32_t cx( GETCELL(globx) );
468+
// int32_t cy( GETCELL(globy) );
470469

471-
// need to call Region::GetCell() before using a Cell pointer
472-
// directly, because the region allocates cells lazily, waiting
473-
// for a call of this method
474-
Cell* c( reg->GetCell( cx, cy ) );
475-
476-
// while inside the region, manipulate the Cell pointer directly
477-
while( (cx>=0) && (cx<REGIONWIDTH) &&
478-
(cy>=0) && (cy<REGIONWIDTH) &&
479-
n > 0 )
480-
{
481-
c->AddBlock(this);
470+
// // need to call Region::GetCell() before using a Cell pointer
471+
// // directly, because the region allocates cells lazily, waiting
472+
// // for a call of this method
473+
// Cell* c( reg->GetCell( cx, cy ) );
474+
475+
// // while inside the region, manipulate the Cell pointer directly
476+
// while( (cx>=0) && (cx<REGIONWIDTH) &&
477+
// (cy>=0) && (cy<REGIONWIDTH) &&
478+
// n > 0 )
479+
// {
480+
// c->AddBlock(this);
482481

483-
// cleverly skip to the next cell (now it's safe to
484-
// manipulate the cell pointer)
485-
if( exy < 0 )
486-
{
487-
globx += sx;
488-
exy += by;
489-
c += sx;
490-
cx += sx;
491-
}
492-
else
493-
{
494-
globy += sy;
495-
exy -= bx;
496-
c += sy * REGIONWIDTH;
497-
cy += sy;
498-
}
499-
--n;
500-
}
501-
}
502-
}
482+
// // cleverly skip to the next cell (now it's safe to
483+
// // manipulate the cell pointer)
484+
// if( exy < 0 )
485+
// {
486+
// globx += sx;
487+
// exy += by;
488+
// c += sx;
489+
// cx += sx;
490+
// }
491+
// else
492+
// {
493+
// globy += sy;
494+
// exy -= bx;
495+
// c += sy * REGIONWIDTH;
496+
// cy += sy;
497+
// }
498+
// --n;
499+
// }
500+
// }
501+
// }
503502

504503
/////////////////////////////////////////////////////////////////////////////////////////
505504
// utility functions to ensure block winding is consistent and matches OpenGL's default

libstage/stage.hh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ namespace Stg
609609
// this could be an issue one day.
610610
#define VAR(V,init) __typeof(init) V=(init)
611611

612-
//#define FOR_EACH(I,C) for(VAR(I,(C).begin());I!=(C).end();++I)
612+
//#define FOR_EACH(I,C) for(VAR(I,(C).begin());I!=(C).end();++I)
613613

614614
// NOTE:
615615
// this version assumes the container is not modified in the loop,
@@ -955,6 +955,10 @@ namespace Stg
955955

956956
virtual Model* RecentlySelectedModel() const { return NULL; }
957957

958+
/** call Cell::AddBlock(block) for each cell on the polygon */
959+
void MapPoly( const PointIntVec& poly,
960+
Block* block );
961+
958962
SuperRegion* AddSuperRegion( const point_int_t& coord );
959963
SuperRegion* GetSuperRegion( const point_int_t& org );
960964
SuperRegion* GetSuperRegionCreate( const point_int_t& org );
@@ -1274,10 +1278,6 @@ namespace Stg
12741278
/** invalidate the cache of points in model coordinates */
12751279
void InvalidateModelPointCache();
12761280

1277-
/** add a Cell pointer to the vector for each cell on the line from
1278-
pt1 to pt2 inclusive */
1279-
void MapLine( const point_int_t& pt1,
1280-
const point_int_t& pt2 );
12811281
};
12821282

12831283

libstage/world.cc

Lines changed: 84 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -782,25 +782,20 @@ RaytraceResult World::Raytrace( const Ray& r )
782782
double ycrossx(0), ycrossy(0);
783783
double distX(0), distY(0);
784784
bool calculatecrossings( true );
785-
785+
786786
// Stage spends up to 95% of its time in this loop! It would be
787787
// neater with more function calls encapsulating things, but even
788788
// inline calls have a noticeable (2-3%) effect on performance.
789789
while( n > 0 ) // while we are still not at the ray end
790790
{
791-
SuperRegion* sr = GetSuperRegion( point_int_t(GETSREG(globx), GETSREG(globy)) );
792-
//SuperRegion* sr = GetSuperRegion( point_int_t(GETSREG(globx), GETSREG(globy)) );
793-
794-
Region* reg = NULL;
795-
796-
if( sr )
797-
reg = sr->GetRegion( GETREG(globx), GETREG(globy) );
791+
SuperRegion* sr( GetSuperRegion(point_int_t(GETSREG(globx),GETSREG(globy))));
792+
Region* reg( sr ? sr->GetRegion(GETREG(globx),GETREG(globy)) : NULL );
798793

799794
if( reg && reg->count ) // if the region contains any objects
800-
{
801-
//assert( reg->cells.size() );
802-
803-
// invalidate the region crossing points used to jump over
795+
{
796+
//assert( reg->cells.size() );
797+
798+
// invalidate the region crossing points used to jump over
804799
// empty regions
805800
calculatecrossings = true;
806801

@@ -975,6 +970,81 @@ void World::Reload( void )
975970
ForEachDescendant( _reload_cb, NULL );
976971
}
977972

973+
974+
void World::MapPoly( const PointIntVec& pts, Block* block )
975+
{
976+
const size_t pt_count = pts.size();
977+
978+
for( size_t i(0); i<pt_count; ++i )
979+
{
980+
const point_int_t& start = pts[i];
981+
const point_int_t& end = pts[(i+1)%pt_count];
982+
983+
// line rasterization adapted from Cohen's 3D version in
984+
// Graphics Gems II. Should be very fast.
985+
const int32_t dx( end.x - start.x );
986+
const int32_t dy( end.y - start.y );
987+
const int32_t sx(sgn(dx));
988+
const int32_t sy(sgn(dy));
989+
const int32_t ax(abs(dx));
990+
const int32_t ay(abs(dy));
991+
const int32_t bx(2*ax);
992+
const int32_t by(2*ay);
993+
int32_t exy(ay-ax);
994+
int32_t n(ax+ay);
995+
996+
int32_t globx(start.x);
997+
int32_t globy(start.y);
998+
999+
while( n )
1000+
{
1001+
Region* reg( GetSuperRegionCreate( point_int_t(GETSREG(globx),
1002+
GETSREG(globy)))
1003+
->GetRegion( GETREG(globx),
1004+
GETREG(globy)));
1005+
1006+
//printf( "REGION %p\n", reg );
1007+
1008+
// add all the required cells in this region before looking up
1009+
// another region
1010+
int32_t cx( GETCELL(globx) );
1011+
int32_t cy( GETCELL(globy) );
1012+
1013+
// need to call Region::GetCell() before using a Cell pointer
1014+
// directly, because the region allocates cells lazily, waiting
1015+
// for a call of this method
1016+
Cell* c( reg->GetCell( cx, cy ) );
1017+
1018+
// while inside the region, manipulate the Cell pointer directly
1019+
while( (cx>=0) && (cx<REGIONWIDTH) &&
1020+
(cy>=0) && (cy<REGIONWIDTH) &&
1021+
n > 0 )
1022+
{
1023+
c->AddBlock(block);
1024+
1025+
// cleverly skip to the next cell (now it's safe to
1026+
// manipulate the cell pointer)
1027+
if( exy < 0 )
1028+
{
1029+
globx += sx;
1030+
exy += by;
1031+
c += sx;
1032+
cx += sx;
1033+
}
1034+
else
1035+
{
1036+
globy += sy;
1037+
exy -= bx;
1038+
c += sy * REGIONWIDTH;
1039+
cy += sy;
1040+
}
1041+
--n;
1042+
}
1043+
}
1044+
}
1045+
}
1046+
1047+
9781048
SuperRegion* World::AddSuperRegion( const point_int_t& sup )
9791049
{
9801050
SuperRegion* sr = CreateSuperRegion( sup );
@@ -1025,15 +1095,15 @@ inline SuperRegion* World::GetSuperRegion( const point_int_t& org )
10251095
return sr;
10261096
}
10271097

1028-
SuperRegion* World::GetSuperRegionCreate( const point_int_t& org )
1098+
inline SuperRegion* World::GetSuperRegionCreate( const point_int_t& org )
10291099
{
10301100
SuperRegion* sr = GetSuperRegion(org);
10311101

10321102
if( sr == NULL ) // no superregion exists! make a new one
10331103
{
10341104
sr = AddSuperRegion( org );
10351105
assert( sr );
1036-
//sr_cached = sr;
1106+
sr_cached = sr;
10371107
}
10381108

10391109
return sr;

0 commit comments

Comments
 (0)