Skip to content

Commit

Permalink
fixed evil bug that may have been causing weird behaviour or crashes …
Browse files Browse the repository at this point in the history
…for some people
  • Loading branch information
rtv committed Dec 2, 2010
1 parent 55b9c56 commit 41d193c
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 121 deletions.
2 changes: 1 addition & 1 deletion libstage/block.cc
Expand Up @@ -458,7 +458,7 @@ void Block::MapLine( const point_int_t& start,

while( n )
{
Region* reg( w->GetSuperRegion( GETSREG(globx), GETSREG(globy) )
Region* reg( w->GetSuperRegionCreate( point_int_t(GETSREG(globx), GETSREG(globy)))
->GetRegion( GETREG(globx), GETREG(globy) ));

//printf( "REGION %p\n", reg );
Expand Down
136 changes: 74 additions & 62 deletions libstage/region.cc
Expand Up @@ -58,8 +58,8 @@ SuperRegion::SuperRegion( World* world, point_int_t origin )
world(world),
count(0)
{
for( int32_t r=0; r<SUPERREGIONSIZE;r++)
regions[r].superregion = this;
for( int32_t c=0; c<SUPERREGIONSIZE;++c)
regions[c].superregion = this;
}

SuperRegion::~SuperRegion()
Expand All @@ -82,6 +82,8 @@ void SuperRegion::RemoveBlock()

void SuperRegion::DrawOccupancy() const
{
//printf( "SR origin (%d,%d) this %p\n", origin.x, origin.y, this );

glPushMatrix();
GLfloat scale = 1.0/world->Resolution();
glScalef( scale, scale, 1.0 ); // XX TODO - this seems slightly
Expand All @@ -95,70 +97,80 @@ void SuperRegion::DrawOccupancy() const
glRecti( 0,0, 1<<SRBITS, 1<<SRBITS );

// outline regions
const Region* r = &regions[0];
char buf[32];

glColor3f( 0,1,0 );
for( int y=0; y<SUPERREGIONWIDTH; ++y )
for( int x=0; x<SUPERREGIONWIDTH; ++x )
{
if( r->count ) // region contains some occupied cells
{
// outline the region
glRecti( x<<RBITS, y<<RBITS,
(x+1)<<RBITS, (y+1)<<RBITS );

// show how many cells are occupied
snprintf( buf, 15, "%lu", r->count );
Gl::draw_string( x<<RBITS, y<<RBITS, 0, buf );

// draw a rectangle around each occupied cell
for( int p=0; p<REGIONWIDTH; ++p )
for( int q=0; q<REGIONWIDTH; ++q )
if( r->cells[p+(q*REGIONWIDTH)].blocks.size() )
{
GLfloat xx = p+(x<<RBITS);
GLfloat yy = q+(y<<RBITS);
glRecti( xx, yy, xx+1, yy+1);
}
}
else if( r->cells ) // empty but used previously
{
double left = x << RBITS;
double right = (x+1) << RBITS;
double bottom = y << RBITS;
double top = (y+1) << RBITS;

double d = 3.0;

// draw little corner markers for regions with memory
// allocated but no contents
glBegin( GL_LINES );
glVertex2f( left, bottom );
glVertex2f( left+d, bottom );
glVertex2f( left, bottom );
glVertex2f( left, bottom+d );
glVertex2f( left, top );
glVertex2f( left+d, top );
glVertex2f( left, top );
glVertex2f( left, top-d );
glVertex2f( right, top );
glVertex2f( right-d, top );
glVertex2f( right, top );
glVertex2f( right, top-d );
glVertex2f( right, bottom );
glVertex2f( right-d, bottom );
glVertex2f( right, bottom );
glVertex2f( right, bottom+d );
glEnd();
}
if( regions )
{
const Region* r = &regions[0];
char buf[32];

++r; // next region quickly
glColor3f( 0,1,0 );
for( int y=0; y<SUPERREGIONWIDTH; ++y )
for( int x=0; x<SUPERREGIONWIDTH; ++x )
{
if( r->count ) // region contains some occupied cells
{
// outline the region
glRecti( x<<RBITS, y<<RBITS,
(x+1)<<RBITS, (y+1)<<RBITS );

// show how many cells are occupied
snprintf( buf, 15, "%lu", r->count );
Gl::draw_string( x<<RBITS, y<<RBITS, 0, buf );

// draw a rectangle around each occupied cell
for( int p=0; p<REGIONWIDTH; ++p )
for( int q=0; q<REGIONWIDTH; ++q )
if( r->cells[p+(q*REGIONWIDTH)].blocks.size() )
{
GLfloat xx = p+(x<<RBITS);
GLfloat yy = q+(y<<RBITS);
glRecti( xx, yy, xx+1, yy+1);
}
}
else if( r->cells ) // empty but used previously
{
double left = x << RBITS;
double right = (x+1) << RBITS;
double bottom = y << RBITS;
double top = (y+1) << RBITS;

double d = 3.0;

// draw little corner markers for regions with memory
// allocated but no contents
glBegin( GL_LINES );
glVertex2f( left, bottom );
glVertex2f( left+d, bottom );
glVertex2f( left, bottom );
glVertex2f( left, bottom+d );
glVertex2f( left, top );
glVertex2f( left+d, top );
glVertex2f( left, top );
glVertex2f( left, top-d );
glVertex2f( right, top );
glVertex2f( right-d, top );
glVertex2f( right, top );
glVertex2f( right, top-d );
glVertex2f( right, bottom );
glVertex2f( right-d, bottom );
glVertex2f( right, bottom );
glVertex2f( right, bottom+d );
glEnd();
}

++r; // next region quickly
}
}

else
{ // outline region-collected superregion
glColor3f( 1,1,0 );
glRecti( 0,0, (1<<SRBITS)-1, (1<<SRBITS)-1 );
glColor3f( 0,0,1 );
}

char buf[32];
snprintf( buf, 15, "%lu", count );
Gl::draw_string( 1<<SBITS, 1<<SBITS, 0, buf );
glPopMatrix();
}

Expand Down
21 changes: 3 additions & 18 deletions libstage/region.hh
Expand Up @@ -11,8 +11,6 @@ namespace Stg
{

// a bit of experimenting suggests that these values are fast. YMMV.
//const int32_t RBITS( 5 ); // regions contain (2^RBITS)^2 pixels
//const int32_t SBITS( 5 );// superregions contain (2^SBITS)^2 regions
const int32_t RBITS( 5 ); // regions contain (2^RBITS)^2 pixels
const int32_t SBITS( 5 );// superregions contain (2^SBITS)^2 regions
const int32_t SRBITS( RBITS+SBITS );
Expand All @@ -32,16 +30,12 @@ namespace Stg

// this is slightly faster than the inline method above, but not as safe
//#define GETREG(X) (( (static_cast<int32_t>(X)) & REGIONMASK ) >> RBITS)

// class Region;


class Cell
{
//friend class Region;
friend class SuperRegion;
friend class World;
//friend class Block;


private:
std::vector<Block*> blocks;

Expand All @@ -66,7 +60,6 @@ namespace Stg

private:
Cell* cells;

unsigned long count; // number of blocks rendered into this region

// vector of garbage collected cell arrays to reallocate before
Expand Down Expand Up @@ -105,24 +98,18 @@ namespace Stg

SuperRegion* superregion;

//bool Occupied() const { return( count > 0 ); }
//bool Used() const { return( cells ? true : false ); }

}; // class Region

class SuperRegion
{
// friend class World;
// friend class Model;

private:
Region regions[SUPERREGIONSIZE];

point_int_t origin;
World* world;

unsigned long count; // number of blocks rendered into this superregion

public:
SuperRegion( World* world, point_int_t origin );
~SuperRegion();
Expand All @@ -131,8 +118,6 @@ namespace Stg
{
return( &regions[ x + y * SUPERREGIONWIDTH ]);
}

//inline const Region* GetRegionImmut( int32_t x, int32_t y ) const;

void DrawOccupancy() const;
void DrawVoxels() const;
Expand Down
31 changes: 13 additions & 18 deletions libstage/stage.hh
Expand Up @@ -495,16 +495,16 @@ namespace Stg
point_int_t( int x, int y ) : x(x), y(y){}
point_int_t() : x(0), y(0){}

/** required to put these in sorted containers like std::map */
bool operator<( const point_int_t& other ) const
{
if( x < other.x ) return true;
if( other.x < x ) return false;
return y < other.y;
}
bool operator==( const point_int_t& other ) const
{ return ((x == other.x) && (y == other.y) ); }
/** required to put these in sorted containers like std::map */
bool operator<( const point_int_t& other ) const
{
if( x < other.x ) return true;
if( other.x < x ) return false;
return y < other.y;
}
bool operator==( const point_int_t& other ) const
{ return ((x == other.x) && (y == other.y) ); }
};

typedef std::vector<point_int_t> PointIntVec;
Expand Down Expand Up @@ -956,14 +956,9 @@ namespace Stg
virtual Model* RecentlySelectedModel() const { return NULL; }

SuperRegion* AddSuperRegion( const point_int_t& coord );
SuperRegion* GetSuperRegion( int32_t x, int32_t y );
void ExpireSuperRegion( SuperRegion* sr );

/** 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,
// Block* block );
SuperRegion* GetSuperRegion( const point_int_t& org );
SuperRegion* GetSuperRegionCreate( const point_int_t& org );
//void ExpireSuperRegion( SuperRegion* sr );

/** convert a distance in meters to a distance in world occupancy
grid pixels */
Expand Down
2 changes: 0 additions & 2 deletions libstage/texture_manager.cc
Expand Up @@ -23,8 +23,6 @@ Fl_Shared_Image* TextureManager::loadImage( const char* filename )

GLuint TextureManager::loadTexture( const char *filename )
{
printf( "attemopt to load texture %s\n", filename );

GLuint texName;
Fl_Shared_Image *img = loadImage( filename );
if( img == NULL ) {
Expand Down
53 changes: 35 additions & 18 deletions libstage/world.cc
Expand Up @@ -196,14 +196,14 @@ World::~World( void )
SuperRegion* World::CreateSuperRegion( point_int_t origin )
{
SuperRegion* sr = new SuperRegion( this, origin );
superregions[ origin ] = sr;
superregions[origin] = sr;
dirty = true; // force redraw
return sr;
}

void World::DestroySuperRegion( SuperRegion* sr )
{
superregions.erase( sr->GetOrigin() );
superregions.erase( sr->GetOrigin() );
delete sr;
}

Expand Down Expand Up @@ -788,11 +788,15 @@ RaytraceResult World::Raytrace( const Ray& r )
// inline calls have a noticeable (2-3%) effect on performance.
while( n > 0 ) // while we are still not at the ray end
{
Region* reg( GetSuperRegion( GETSREG(globx), GETSREG(globy) )
->GetRegion( GETREG(globx), GETREG(globy) ));
SuperRegion* sr = GetSuperRegion( point_int_t(GETSREG(globx), GETSREG(globy)) );
//SuperRegion* sr = GetSuperRegion( point_int_t(GETSREG(globx), GETSREG(globy)) );


if( reg->count ) // if the region contains any objects
Region* reg = NULL;

if( sr )
reg = sr->GetRegion( GETREG(globx), GETREG(globy) );

if( reg && reg->count ) // if the region contains any objects
{
//assert( reg->cells.size() );

Expand Down Expand Up @@ -973,9 +977,10 @@ void World::Reload( void )

SuperRegion* World::AddSuperRegion( const point_int_t& sup )
{
//printf( "Creating super region [ %d %d ]\n", sup.x, sup.y );
SuperRegion* sr = CreateSuperRegion( sup );

//printf( "Created super region [%d, %d] %p\n", sup.x, sup.y, sr );

// the bounds of the world have changed
//printf( "lower left (%.2f,%.2f,%.2f)\n", pt.x, pt.y, pt.z );

Expand All @@ -998,31 +1003,43 @@ SuperRegion* World::AddSuperRegion( const point_int_t& sup )
}


inline SuperRegion* World::GetSuperRegion( const int32_t x, const int32_t y )
inline SuperRegion* World::GetSuperRegion( const point_int_t& org )
{
// around 99% of the time the SR is the same as last
// lookup - cache gives a 4% overall speed up :)

point_int_t org(x,y);

if( sr_cached && sr_cached->GetOrigin() == org )
return sr_cached;

// point_int_t pt(x,y);
SuperRegion* sr = NULL;

// I despise some STL syntax sometimes...
std::map<point_int_t,SuperRegion*>::iterator it =
superregions.find(org);

if( it != superregions.end() )
sr = it->second;

SuperRegion* sr = superregions[ org ];
if( sr ) sr_cached = sr;

if( sr == NULL ) // no superregion exists! make a new one
sr = AddSuperRegion( org );
return sr;
}

assert( sr );
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;
}

// cache for next time around
sr_cached = sr;

return sr;
}


void World::Extend( point3_t pt )
{
extent.x.min = std::min( extent.x.min, pt.x );
Expand Down

0 comments on commit 41d193c

Please sign in to comment.