Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

major changes for 3.1

  • Loading branch information...
commit 89dcdaf144804cfd234047889caf636e4cb8d50e 1 parent 98b9033
rtv authored
View
2  libstage/CMakeLists.txt
@@ -2,6 +2,7 @@ MESSAGE( STATUS "Configuring libstage" )
set( stageSrcs ancestor.cc
block.cc
+ blockgroup.cc
camera.cc
canvas.cc
file_manager.cc
@@ -23,6 +24,7 @@ set( stageSrcs ancestor.cc
option.hh
options_dlg.cc
options_dlg.hh
+ region.cc
resource.cc
stage.cc
stage.hh
View
503 libstage/block.cc
@@ -1,281 +1,328 @@
-//#define DEBUG 1
-#include "stage_internal.hh"
-typedef struct
-{
- GSList** head;
- GSList* link;
- unsigned int* counter1;
- unsigned int* counter2;
-} stg_list_entry_t;
+#include "stage_internal.hh"
+//GPtrArray* StgBlock::global_verts = g_ptr_array_sized_new( 1024 );
/** 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.*/
-StgBlock::StgBlock( StgModel* mod,
- stg_point_t* pts,
- size_t pt_count,
- stg_meters_t zmin,
- stg_meters_t zmax,
- stg_color_t color,
- bool inherit_color )
-{
- this->mod = mod;
- this->pt_count = pt_count;
- this->pts = (stg_point_t*)g_memdup( pts, pt_count * sizeof(stg_point_t));
- // allocate space for the integer version of the block vertices
- this->pts_global_pixels = new stg_point_int_t[pt_count];
-
- this->zmin = zmin;
- this->zmax = zmax;
- this->color = color;
- this->inherit_color = inherit_color;
- this->rendered_points =
- g_array_new( FALSE, FALSE, sizeof(stg_list_entry_t));
-
- // flag these as unset until StgBlock::Map() is called.
- this->global_zmin = -1;
- this->global_zmax = -1;
+ blocks. The point data is copied, so pts can safely be freed
+ after calling this.*/
+StgBlock::StgBlock( StgModel* mod,
+ stg_point_t* pts,
+ size_t pt_count,
+ stg_meters_t zmin,
+ stg_meters_t zmax,
+ stg_color_t color,
+ bool inherit_color
+ ) :
+ mod( mod ),
+ pt_count( pt_count ),
+ pts( (stg_point_t*)g_memdup( pts, pt_count * sizeof(stg_point_t)) ),
+ color( color ),
+ inherit_color( inherit_color ),
+ rendered_cells( g_ptr_array_sized_new(32) ),
+ candidate_cells( g_ptr_array_sized_new(32) )
+ // _gpts( NULL )
+{
+ assert( mod );
+ assert( pt_count > 0 );
+ assert( pts );
+
+ local_z.min = zmin;
+ local_z.max = zmax;
+
+ // add this block's global coords array to a global list
+ //g_ptr_array_add( global_verts, this );
}
+/** A from-file constructor */
+StgBlock::StgBlock( StgModel* mod,
+ Worldfile* wf,
+ int entity)
+ : mod( mod ),
+ pts(NULL),
+ pt_count(0),
+ color(0),
+ inherit_color(true),
+ rendered_cells( g_ptr_array_sized_new(32) ),
+ candidate_cells( g_ptr_array_sized_new(32) )
+ // _gpts( NULL )
+{
+ assert(mod);
+ assert(wf);
+ assert(entity);
+
+ Load( wf, entity );
+
+ // add this block's global coords array to a global list
+ //g_ptr_array_add( global_verts, this );
+}
+
+
StgBlock::~StgBlock()
{
- this->UnMap();
- g_free( pts );
- g_array_free( rendered_points, TRUE );
-
- //delete[] edge_indices;
+ if( mapped ) UnMap();
+
+ stg_points_destroy( pts );
+
+ g_ptr_array_free( rendered_cells, TRUE );
+ g_ptr_array_free( candidate_cells, TRUE );
+
+ //free( _gpts );
+ //g_ptr_array_remove( global_verts, this );
}
-void Stg::stg_block_list_destroy( GList* list )
+stg_color_t StgBlock::GetColor()
{
- GList* it;
- for( it=list; it; it=it->next )
- delete (StgBlock*)it->data;
- g_list_free( list );
+ return( inherit_color ? mod->color : color );
}
-void StgBlock::DrawTop()
-{
- // draw a top that fits over the side strip
- glPushMatrix();
- glTranslatef( 0,0,zmax);
- glVertexPointer( 2, GL_DOUBLE, 0, pts );
- glDrawArrays( GL_POLYGON, 0, pt_count );
- glPopMatrix();
-}
-//TODO FIXME - this is really SLOW
-void StgBlock::DrawSides()
+StgModel* StgBlock::TestCollision()
{
- // construct a strip that wraps around the polygon
- glBegin(GL_QUAD_STRIP);
- for( unsigned int p=0; p<pt_count; p++)
- {
- glVertex3f( pts[p].x, pts[p].y, zmax );
- glVertex3f( pts[p].x, pts[p].y, zmin );
- }
- // close the strip
- glVertex3f( pts[0].x, pts[0].y, zmax );
- glVertex3f( pts[0].x, pts[0].y, zmin );
- glEnd();
+ //printf( "model %s block %p test collision...\n", mod->Token(), this );
+
+ // find the set of cells we would render into given the current global pose
+ GenerateCandidateCells();
+
+ // for every cell we may be rendered into
+ for( int i=0; i<candidate_cells->len; i++ )
+ {
+ Cell* cell = (Cell*)g_ptr_array_index(candidate_cells, i);
+
+ // for every rendered into that cell
+ for( GSList* it = cell->list; it; it=it->next )
+ {
+ StgBlock* testblock = (StgBlock*)it->data;
+ StgModel* testmod = testblock->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) &&
+ testmod->obstacle_return &&
+ !mod->IsRelated( testmod ))
+ {
+ //puts( "HIT");
+ return testmod; // bail immediately with the bad news
+ }
+ }
+ }
+
+ //printf( "model %s block %p collision done. no hits.\n", mod->Token(), this );
+ return NULL; // no hit
}
-void StgBlock::DrawFootPrint()
-{
- glBegin(GL_POLYGON);
- for( unsigned int p=0; p<pt_count; p++ )
- glVertex2f( pts[p].x, pts[p].y );
+void StgBlock::RemoveFromCellArray( GPtrArray* ptrarray )
+{
+ for( unsigned int i=0; i<ptrarray->len; i++ )
+ ((Cell*)g_ptr_array_index(ptrarray, i))->RemoveBlock( this );
+}
- glEnd();
+void StgBlock::AddToCellArray( GPtrArray* ptrarray )
+{
+ for( unsigned int i=0; i<ptrarray->len; i++ )
+ ((Cell*)g_ptr_array_index(ptrarray, i))->AddBlock( this );
}
-void StgBlock::Draw()
+// used as a callback to gather an array of cells in a polygon
+void AppendCellToPtrArray( Cell* c, GPtrArray* a )
{
- // draw filled color polygons
- stg_color_t color = Color();
-
- PushColor( color );
- glEnable(GL_POLYGON_OFFSET_FILL);
- glPolygonOffset(1.0, 1.0);
- DrawSides();
- DrawTop();
- glDisable(GL_POLYGON_OFFSET_FILL);
-
- // // draw the block outline in a darker version of the same color
- double r,g,b,a;
- stg_color_unpack( color, &r, &g, &b, &a );
- PushColor( stg_color_pack( r/2.0, g/2.0, b/2.0, a ));
-
- glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
- glDepthMask(GL_FALSE);
- DrawTop();
- DrawSides();
- glDepthMask(GL_TRUE);
- glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
-
- PopColor();
- PopColor();
+ g_ptr_array_add( a, c );
}
-void StgBlock::DrawSolid( void )
+// used as a callback to gather an array of cells in a polygon
+void AddBlockToCell( Cell* c, StgBlock* block )
{
- DrawSides();
- DrawTop();
+ c->AddBlock( block );
}
void StgBlock::Map()
{
- PRINT_DEBUG2( "%s mapping block with %d points",
- mod->Token(),
- (int)pt_count );
-
- // update the global coordinate list
- stg_point3_t global;
- stg_point3_t local;
-
- for( unsigned int p=0; p<pt_count; p++ )
- {
- local.x = pts[p].x;
- local.y = pts[p].y;
- local.z = zmin;
-
- global = mod->LocalToGlobal( local );
- //global = local;
-
- pts_global_pixels[p].x = mod->GetWorld()->MetersToPixels( global.x );
- pts_global_pixels[p].y = mod->GetWorld()->MetersToPixels( global.y );
-
- PRINT_DEBUG2("loc [%.2f %.2f]",
- pts[p].x,
- pts[p].y );
-
- PRINT_DEBUG2("glb [%d %d]",
- pts_global_pixels[p].x,
- pts_global_pixels[p].y );
- }
-
- // store the block's global vertical bounds for inspection by the
- // raytracer
- global_zmin = global.z;
- global_zmax = global.z + (zmax-zmin);
-
- stg_render_info_t render_info;
- render_info.world = mod->GetWorld();
- render_info.block = this;
-
- stg_polygon_3d( pts_global_pixels, pt_count,
- (stg_line3d_func_t)StgWorld::AddBlockPixel,
- (void*)&render_info );
+ // TODO - if called often, we may not need to generate each time
+ GenerateCandidateCells();
+ SwitchToTestedCells();
+ return;
+ mapped = true;
}
void StgBlock::UnMap()
{
- PRINT_DEBUG2( "UnMapping block of model %s with %d points",
- mod->Token(),
- (int)pt_count);
-
- for( unsigned int p=0; p<rendered_points->len; p++ )
- {
- stg_list_entry_t* pt =
- &g_array_index( rendered_points, stg_list_entry_t, p);
-
- *pt->head = g_slist_delete_link( *pt->head, pt->link );
-
- // decrement the region and superregion render counts
- (*pt->counter1)--;
- (*pt->counter2)--;
- }
-
- // forget the points we have unrendered (but keep their storage)
- g_array_set_size( rendered_points,0 );
-}
-
-void StgBlock::RecordRenderPoint( GSList** head,
- GSList* link,
- unsigned int* c1,
- unsigned int* c2 )
-{
- // store this index in the block for later fast deletion
- stg_list_entry_t el;
- el.head = head;
- el.link = link;
- el.counter1 = c1;
- el.counter2 = c2;
- g_array_append_val( rendered_points, el );
+ RemoveFromCellArray( rendered_cells );
+
+ g_ptr_array_set_size( rendered_cells, 0 );
+ mapped = false;
}
-
-void StgBlock::ScaleList( GList* blocks,
- stg_size_t* size )
+void StgBlock::SwitchToTestedCells()
{
- if( g_list_length( blocks ) < 1 )
- return;
-
- // assuming the blocks currently fit in a square +/- one billion units
- double minx, miny, maxx, maxy;
- minx = miny = billion;
- maxx = maxy = -billion;
-
- double maxz = 0;
-
- GList* it;
- for( it=blocks; it; it=it->next ) // examine all the blocks
- {
- // examine all the points in the polygon
- StgBlock* block = (StgBlock*)it->data;
+ RemoveFromCellArray( rendered_cells );
+ AddToCellArray( candidate_cells );
+
+ // switch current and candidate cell pointers
+ GPtrArray* tmp = rendered_cells;
+ rendered_cells = candidate_cells;
+ candidate_cells = tmp;
+
+ mapped = true;
+}
- block->UnMap(); // just in case
+void StgBlock::GenerateCandidateCells()
- for( unsigned int p=0; p < block->pt_count; p++ )
- {
- stg_point_t* pt = &block->pts[p];
- if( pt->x < minx ) minx = pt->x;
- if( pt->y < miny ) miny = pt->y;
- if( pt->x > maxx ) maxx = pt->x;
- if( pt->y > maxy ) maxy = pt->y;
+{
+ stg_pose_t gpose = mod->GetGlobalPose();
+
+ stg_point3_t scale;
+ scale.x = mod->geom.size.x / mod->blockgroup.size.x;
+ scale.y = mod->geom.size.y / mod->blockgroup.size.y;
+ scale.z = mod->geom.size.z / mod->blockgroup.size.z;
+
+ g_ptr_array_set_size( candidate_cells, 0 );
+
+ // compute the global location of the first point
+ stg_pose_t local( pts[0].x * scale.x,
+ pts[0].y * scale.y,
+ 0, 0 );
+ stg_pose_t first_gpose, last_gpose;
+ first_gpose = last_gpose = pose_sum( gpose, local );
+
+ // store the block's absolute z bounds at this rendering
+ global_z.min = (scale.z * local_z.min) + last_gpose.z;
+ global_z.max = (scale.z * local_z.max) + last_gpose.z;
+
+ // now loop from the the second to the last
+ for( int p=1; p<pt_count; p++ )
+ {
+ stg_pose_t local( pts[p].x * scale.x,
+ pts[p].y * scale.y,
+ 0, 0 );
+
+ stg_pose_t gpose2 = pose_sum( gpose, local );
+
+ // and render the shape of the block into the global cells
+ mod->world->ForEachCellInLine( last_gpose.x, last_gpose.y,
+ gpose2.x, gpose2.y,
+ (stg_cell_callback_t)AppendCellToPtrArray,
+ candidate_cells );
+ last_gpose = gpose2;
+ }
+
+ // close the polygon
+ mod->world->ForEachCellInLine( last_gpose.x, last_gpose.y,
+ first_gpose.x, first_gpose.y,
+ (stg_cell_callback_t)AppendCellToPtrArray,
+ candidate_cells );
+
+ mapped = true;
+}
- assert( ! isnan( pt->x ) );
- assert( ! isnan( pt->y ) );
- }
+void StgBlock::DrawTop()
+{
+ // draw the top of the block - a polygon at the highest vertical
+ // extent
+ glBegin( GL_POLYGON);
+ for( int i=0; i<pt_count; i++ )
+ glVertex3f( pts[i].x, pts[i].y, local_z.max );
+ glEnd();
+}
- if( block->zmax > maxz )
- maxz = block->zmax;
- }
+void StgBlock::DrawSides()
+{
+ // construct a strip that wraps around the polygon
+ glBegin(GL_QUAD_STRIP);
+ for( unsigned int p=0; p<pt_count; p++)
+ {
+ glVertex3f( pts[p].x, pts[p].y, local_z.max );
+ glVertex3f( pts[p].x, pts[p].y, local_z.min );
+ }
+ // close the strip
+ glVertex3f( pts[0].x, pts[0].y, local_z.max );
+ glVertex3f( pts[0].x, pts[0].y, local_z.min );
+ glEnd();
+}
- // now normalize all lengths so that the lines all fit inside
- // the specified rectangle
- double scalex = (maxx - minx);
- double scaley = (maxy - miny);
+void StgBlock::DrawFootPrint()
+{
+ glBegin(GL_POLYGON);
+ for( unsigned int p=0; p<pt_count; p++ )
+ glVertex2f( pts[p].x, pts[p].y );
+ glEnd();
+}
- double scalez = size->z / maxz;
+void StgBlock::Draw( StgModel* mod )
+{
+ // draw filled color polygons
+ stg_color_t col = inherit_color ? mod->color : color;
+
+ mod->PushColor( col );
+ glEnable(GL_POLYGON_OFFSET_FILL);
+ glPolygonOffset(1.0, 1.0);
+ DrawSides();
+ DrawTop();
+ glDisable(GL_POLYGON_OFFSET_FILL);
+
+ // // draw the block outline in a darker version of the same color
+ double r,g,b,a;
+ stg_color_unpack( col, &r, &g, &b, &a );
+ mod->PushColor( stg_color_pack( r/2.0, g/2.0, b/2.0, a ));
+
+ glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
+ glDepthMask(GL_FALSE);
+ DrawTop();
+ DrawSides();
+ glDepthMask(GL_TRUE);
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+
+ mod->PopColor();
+ mod->PopColor();
+}
- for( it=blocks; it; it=it->next ) // examine all the blocks again
- {
- StgBlock* block = (StgBlock*)it->data;
+void StgBlock::DrawSolid()
+{
+ DrawSides();
+ DrawTop();
+}
- // scale all the points in the block
- // TODO - scaling data in the block instead?
- for( unsigned int p=0; p < block->pt_count; p++ )
- {
- stg_point_t* pt = &block->pts[p];
- pt->x = ((pt->x - minx) / scalex * size->x) - size->x/2.0;
- pt->y = ((pt->y - miny) / scaley * size->y) - size->y/2.0;
+//#define DEBUG 1
- assert( ! isnan( pt->x ) );
- assert( ! isnan( pt->y ) );
- }
- // todo - scale min properly
- block->zmax *= scalez;
- block->zmin *= scalez;
- }
+void StgBlock::Load( Worldfile* wf, int entity )
+{
+ //printf( "StgBlock::Load entity %d\n", entity );
+
+ if( pts )
+ stg_points_destroy( pts );
+
+ pt_count = wf->ReadInt( entity, "points", 0);
+ pts = stg_points_create( pt_count );
+
+ //printf( "reading %d points\n",
+ // pt_count );
+
+ char key[128];
+ int p;
+ for( p=0; p<pt_count; p++ ) {
+ snprintf(key, sizeof(key), "point[%d]", p );
+
+ pts[p].x = wf->ReadTupleLength(entity, key, 0, 0);
+ pts[p].y = wf->ReadTupleLength(entity, key, 1, 0);
+ }
+
+ local_z.min = wf->ReadTupleLength( entity, "z", 0, 0.0 );
+ local_z.max = wf->ReadTupleLength( entity, "z", 1, 1.0 );
+
+ const char* colorstr = wf->ReadString( entity, "color", NULL );
+ if( colorstr )
+ {
+ color = stg_lookup_color( colorstr );
+ inherit_color = false;
+ }
}
+
+
View
277 libstage/blockgroup.cc
@@ -0,0 +1,277 @@
+
+#include "stage_internal.hh"
+#include <libgen.h> // for dirname(3)
+
+#undef DEBUG
+
+using namespace Stg;
+
+BlockGroup::BlockGroup()
+ : blocks(NULL),
+ count(0),
+ displaylist(0)
+{ /* empty */ }
+
+BlockGroup::~BlockGroup()
+{
+ Clear();
+}
+
+void BlockGroup::AppendBlock( StgBlock* block )
+{
+ blocks = g_list_append( blocks, block );
+ ++count;
+
+ block->mod->map_caches_are_invalid = true;
+}
+
+void BlockGroup::Clear()
+{
+ while( blocks )
+ {
+ delete (StgBlock*)blocks->data;
+ blocks = blocks->next;
+ }
+
+ g_list_free( blocks );
+ blocks = NULL;
+}
+
+
+void BlockGroup::SwitchToTestedCells()
+{
+ // confirm the tentative pose for all blocks
+ LISTMETHOD( blocks, StgBlock*, SwitchToTestedCells );
+}
+
+StgModel* BlockGroup::TestCollision()
+{
+ //printf( "blockgroup %p test collision...\n", this );
+
+ StgModel* hitmod = NULL;
+
+ for( GList* it=blocks; it; it = it->next )
+ if( hitmod = ((StgBlock*)it->data)->TestCollision())
+ break; // bail on the earliest collision
+
+ //printf( "blockgroup %p test collision done.\n", this );
+
+ return hitmod;
+}
+
+
+// establish the min and max of all the blocks, so we can scale this
+// group later
+void BlockGroup::CalcSize()
+{
+ // assuming the blocks currently fit in a square +/- one billion units
+ double minx, miny, maxx, maxy, minz, maxz;
+ minx = miny = billion;
+ maxx = maxy = -billion;
+
+ size.z = 0.0; // grow to largest z we see
+
+ if( blocks )
+ ((StgBlock*)blocks->data)->mod->map_caches_are_invalid = true;
+
+ for( GList* it=blocks; it; it=it->next ) // examine all the blocks
+ {
+ // examine all the points in the polygon
+ StgBlock* block = (StgBlock*)it->data;
+
+ for( unsigned int p=0; p < block->pt_count; p++ )
+ {
+ stg_point_t* pt = &block->pts[p];
+ if( pt->x < minx ) minx = pt->x;
+ if( pt->y < miny ) miny = pt->y;
+ if( pt->x > maxx ) maxx = pt->x;
+ if( pt->y > maxy ) maxy = pt->y;
+ }
+
+ size.z = MAX( block->local_z.max, size.z );
+ }
+
+ // store these bounds for scaling purposes
+ size.x = maxx-minx;
+ size.y = maxy-miny;
+}
+
+
+void BlockGroup::Map()
+{
+ LISTMETHOD( blocks, StgBlock*, Map );
+}
+
+void BlockGroup::UnMap()
+{
+ LISTMETHOD( blocks, StgBlock*, UnMap );
+}
+
+void BlockGroup::DrawSolid()
+{
+ LISTMETHOD( blocks, StgBlock*, DrawSolid );
+}
+
+void BlockGroup::DrawFootPrint()
+{
+ LISTMETHOD( blocks, StgBlock*, DrawFootPrint);
+}
+
+void BlockGroup::BuildDisplayList( StgModel* mod )
+{
+ //printf( "display list for model %s\n", mod->token );
+
+ if( displaylist == 0 )
+ displaylist = glGenLists(1);
+
+ glNewList( displaylist, GL_COMPILE );
+
+ stg_geom_t geom = mod->GetGeom();
+ glScalef( geom.size.x / size.x,
+ geom.size.y / size.y,
+ geom.size.z / size.z );
+
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+ glEnable(GL_POLYGON_OFFSET_FILL);
+ glPolygonOffset(1.0, 1.0);
+
+ mod->PushColor( mod->color );
+
+ for( GList* it=blocks; it; it=it->next )
+ {
+ StgBlock* blk = (StgBlock*)it->data;
+
+ if( (!blk->inherit_color) && (blk->color != mod->color) )
+ {
+ mod->PushColor( blk->color );
+ blk->DrawSolid();
+ mod->PopColor();
+ }
+ else
+ blk->DrawSolid();
+ }
+
+ mod->PopColor();
+
+ glDisable(GL_POLYGON_OFFSET_FILL);
+
+ glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
+ glDepthMask(GL_FALSE);
+
+ double r,g,b,a;
+ stg_color_unpack( mod->color, &r, &g, &b, &a );
+ mod->PushColor( stg_color_pack( r/2.0, g/2.0, b/2.0, a ));
+
+ for( GList* it=blocks; it; it=it->next )
+ {
+ StgBlock* blk = (StgBlock*)it->data;
+
+ if( (!blk->inherit_color) && (blk->color != mod->color) )
+ {
+ stg_color_unpack( blk->color, &r, &g, &b, &a );
+ mod->PushColor( stg_color_pack( r/2.0, g/2.0, b/2.0, a ));
+ blk->DrawSolid();
+ mod->PopColor();
+ }
+ else
+ blk->DrawSolid();
+ }
+
+ // LISTMETHOD( blocks, StgBlock*, DrawSolid );
+
+ glDepthMask(GL_TRUE);
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+
+ mod->PopColor();
+
+ glEndList();
+}
+
+void BlockGroup::CallDisplayList( StgModel* mod )
+{
+ if( displaylist == 0 )
+ BuildDisplayList( mod );
+
+ //gl_pose_shift( &geom.pose );
+
+ glCallList( displaylist );
+}
+
+void BlockGroup::LoadBlock( StgModel* mod, Worldfile* wf, int entity )
+{
+ AppendBlock( new StgBlock( mod, wf, entity ));
+}
+
+void BlockGroup::LoadBitmap( StgModel* mod, const char* bitmapfile, Worldfile* wf )
+{
+ PRINT_DEBUG1( "attempting to load bitmap \"%s\n", bitmapfile );
+
+ char full[_POSIX_PATH_MAX];
+
+ if( bitmapfile[0] == '/' )
+ strcpy( full, bitmapfile );
+ else
+ {
+ char *tmp = strdup(wf->filename);
+ snprintf( full, _POSIX_PATH_MAX,
+ "%s/%s", dirname(tmp), bitmapfile );
+ free(tmp);
+ }
+
+ PRINT_DEBUG1( "attempting to load image %s", full );
+
+ stg_rotrect_t* rects = NULL;
+ unsigned int rect_count = 0;
+ unsigned int width, height;
+ if( stg_rotrects_from_image_file( full,
+ &rects,
+ &rect_count,
+ &width, &height ) )
+ {
+ PRINT_ERR1( "failed to load rects from image file \"%s\"",
+ full );
+ return;
+ }
+
+ //printf( "found %d rects in \"%s\" at %p\n",
+ // rect_count, full, rects );
+
+ if( rects && (rect_count > 0) )
+ {
+ // shift the origin from bottom-left to center of the image
+ double dx = width/2.0;
+ double dy = height/2.0;
+
+ //puts( "loading rects" );
+ for( unsigned int r=0; r<rect_count; r++ )
+ {
+ stg_point_t pts[4];
+
+ double x = rects[r].pose.x;
+ double y = rects[r].pose.y;
+ double w = rects[r].size.x;
+ double h = rects[r].size.y;
+
+ pts[0].x = x - dx;
+ pts[0].y = y - dy;
+ pts[1].x = x + w - dx;
+ pts[1].y = y -dy;
+ pts[2].x = x + w -dx;
+ pts[2].y = y + h -dy;
+ pts[3].x = x - dx;
+ pts[3].y = y + h -dy;
+
+ // TODO fix this
+ stg_color_t col = stg_color_pack( 1.0, 0,0,1.0 );
+
+ AppendBlock( new StgBlock( mod,
+ pts,4,
+ 0,1,
+ col,
+ true ) );
+ }
+ free( rects );
+ }
+
+ CalcSize();
+}
View
35 libstage/camera.cc
@@ -12,8 +12,8 @@
#include <iostream>
// Perspective Camera
-StgPerspectiveCamera::StgPerspectiveCamera( void ) :
- StgCamera(),
+PerspectiveCamera::PerspectiveCamera( void ) :
+ Camera(),
_z_near( 0.2 ), _z_far( 40.0 ),
_vert_fov( 70 ), _horiz_fov( 70 ),
_aspect( 1.0 )
@@ -21,7 +21,7 @@ StgPerspectiveCamera::StgPerspectiveCamera( void ) :
setPitch( 70.0 );
}
-void StgPerspectiveCamera::move( float x, float y, float z )
+void PerspectiveCamera::move( float x, float y, float z )
{
//scale relative to zoom level
x *= _z / 100.0;
@@ -35,7 +35,7 @@ void StgPerspectiveCamera::move( float x, float y, float z )
_y += cos( dtor( _yaw ) ) * y;
}
-void StgPerspectiveCamera::Draw( void ) const
+void PerspectiveCamera::Draw( void ) const
{
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
@@ -45,10 +45,9 @@ void StgPerspectiveCamera::Draw( void ) const
glTranslatef( - _x, - _y, - _z );
//zooming needs to happen in the Projection code (don't use glScale for zoom)
-
}
-void StgPerspectiveCamera::SetProjection( void ) const
+void PerspectiveCamera::SetProjection( void ) const
{
// SetProjection( pixels_width/pixels_height );
@@ -69,24 +68,24 @@ void StgPerspectiveCamera::SetProjection( void ) const
}
-void StgPerspectiveCamera::update( void )
+void PerspectiveCamera::update( void )
{
}
-void StgPerspectiveCamera::strafe( float amount )
+void PerspectiveCamera::strafe( float amount )
{
_x += cos( dtor( _yaw ) ) * amount;
_y += sin( dtor( _yaw ) ) * amount;
}
-void StgPerspectiveCamera::forward( float amount )
+void PerspectiveCamera::forward( float amount )
{
_x += -sin( dtor( _yaw ) ) * amount;
_y += cos( dtor( _yaw ) ) * amount;
}
-void StgPerspectiveCamera::Load( Worldfile* wf, int sec ) {
+void PerspectiveCamera::Load( Worldfile* wf, int sec ) {
float x_pos = wf->ReadTupleLength(sec, "pcam_loc", 0, x() );
float y_pos = wf->ReadTupleLength(sec, "pcam_loc", 1, y() );
float z_pos = wf->ReadTupleLength(sec, "pcam_loc", 2, z() );
@@ -95,7 +94,7 @@ void StgPerspectiveCamera::Load( Worldfile* wf, int sec ) {
setYaw( wf->ReadTupleFloat( sec, "pcam_angle", 1, yaw() ) );
}
-void StgPerspectiveCamera::Save( Worldfile* wf, int sec ) {
+void PerspectiveCamera::Save( Worldfile* wf, int sec ) {
wf->WriteTupleFloat( sec, "pcam_loc", 0, x() );
wf->WriteTupleFloat( sec, "pcam_loc", 1, y() );
wf->WriteTupleFloat( sec, "pcam_loc", 2, z() );
@@ -109,7 +108,7 @@ void StgPerspectiveCamera::Save( Worldfile* wf, int sec ) {
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Ortho camera
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
-void StgOrthoCamera::Draw( void ) const
+void OrthoCamera::Draw( void ) const
{
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
@@ -122,7 +121,7 @@ void StgOrthoCamera::Draw( void ) const
}
-void StgOrthoCamera::SetProjection( void ) const
+void OrthoCamera::SetProjection( void ) const
{
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
@@ -134,7 +133,7 @@ void StgOrthoCamera::SetProjection( void ) const
glMatrixMode (GL_MODELVIEW);
}
-void StgOrthoCamera::SetProjection( float pixels_width, float pixels_height, float y_min, float y_max )
+void OrthoCamera::SetProjection( float pixels_width, float pixels_height, float y_min, float y_max )
{
_pixels_width = pixels_width;
_pixels_height = pixels_height;
@@ -143,7 +142,7 @@ void StgOrthoCamera::SetProjection( float pixels_width, float pixels_height, flo
SetProjection();
}
-void StgOrthoCamera::move( float x, float y ) {
+void OrthoCamera::move( float x, float y ) {
//convert screen points into world points
x = x / ( _scale );
y = y / ( _scale );
@@ -167,7 +166,7 @@ void StgOrthoCamera::move( float x, float y ) {
}
//TODO re-evaluate the way the camera is shifted when the mouse zooms - it might be possible to simplify
-void StgOrthoCamera::scale( float scale, float shift_x, float w, float shift_y, float h )
+void OrthoCamera::scale( float scale, float shift_x, float w, float shift_y, float h )
{
float to_scale = -scale;
const float old_scale = _scale;
@@ -205,7 +204,7 @@ void StgOrthoCamera::scale( float scale, float shift_x, float w, float shift_y,
}
}
-void StgOrthoCamera::Load( Worldfile* wf, int sec ) {
+void OrthoCamera::Load( Worldfile* wf, int sec ) {
float x_pos = wf->ReadTupleLength(sec, "center", 0, x() );
float y_pos = wf->ReadTupleLength(sec, "center", 1, y() );
setPose( x_pos, y_pos );
@@ -214,7 +213,7 @@ void StgOrthoCamera::Load( Worldfile* wf, int sec ) {
setScale( wf->ReadFloat(sec, "scale", scale() ) );
}
-void StgOrthoCamera::Save( Worldfile* wf, int sec ) {
+void OrthoCamera::Save( Worldfile* wf, int sec ) {
wf->WriteTupleFloat( sec, "center", 0, x() );
wf->WriteTupleFloat( sec, "center", 1, y() );
wf->WriteTupleFloat( sec, "rotate", 0, pitch() );
View
817 libstage/canvas.cc
@@ -1,8 +1,8 @@
/** canvas.cc
Implement the main world viewing area in FLTK and OpenGL.
Authors: Richard Vaughan (vaughan@sfu.ca)
- Alex Couture-Beil (asc17@sfu.ca)
- Jeremy Asher (jra11@sfu.ca)
+ Alex Couture-Beil (asc17@sfu.ca)
+ Jeremy Asher (jra11@sfu.ca)
$Id$
*/
@@ -14,6 +14,7 @@
#include <map>
#include <sstream>
#include <png.h>
+#include <GLUT/glut.h>
#include "file_manager.hh"
#include "options_dlg.hh"
@@ -30,11 +31,14 @@ void StgCanvas::TimerCallback( StgCanvas* c )
c->redraw();
Fl::repeat_timeout(((double)c->interval/1000),
- (Fl_Timeout_Handler)StgCanvas::TimerCallback,
- c);
+ (Fl_Timeout_Handler)StgCanvas::TimerCallback,
+ c);
}
+
+
+
StgCanvas::StgCanvas( StgWorldGui* world, int x, int y, int w, int h) :
Fl_Gl_Window(x,y,w,h),
// initialize Option objects
@@ -74,11 +78,17 @@ StgCanvas::StgCanvas( StgWorldGui* world, int x, int y, int w, int h) :
interval = 50; //msec between redraws
graphics = true;
-
+
// // start the timer that causes regular redraws
Fl::add_timeout( ((double)interval/1000),
- (Fl_Timeout_Handler)StgCanvas::TimerCallback,
- this);
+ (Fl_Timeout_Handler)StgCanvas::TimerCallback,
+ this);
+
+
+ GLenum status;
+
+
+
}
StgCanvas::~StgCanvas()
@@ -89,7 +99,7 @@ StgModel* StgCanvas::getModel( int x, int y )
{
// render all models in a unique color
make_current(); // make sure the GL context is current
- glClearColor ( 1,1,1,1 ); // white
+ glClearColor( 1,1,1,1 ); // white
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glLoadIdentity();
current_camera->SetProjection();
@@ -106,19 +116,19 @@ StgModel* StgCanvas::getModel( int x, int y )
StgModel* mod = (StgModel*)it->data;
if( mod->GuiMask() & (STG_MOVE_TRANS | STG_MOVE_ROT ))
- {
- uint8_t rByte, gByte, bByte, aByte;
- uint32_t modelId = mod->id;
- rByte = modelId;
- gByte = modelId >> 8;
- bByte = modelId >> 16;
- aByte = modelId >> 24;
-
- //printf("mod->Id(): 0x%X, rByte: 0x%X, gByte: 0x%X, bByte: 0x%X, aByte: 0x%X\n", modelId, rByte, gByte, bByte, aByte);
+ {
+ uint8_t rByte, gByte, bByte, aByte;
+ uint32_t modelId = mod->id;
+ rByte = modelId;
+ gByte = modelId >> 8;
+ bByte = modelId >> 16;
+ aByte = modelId >> 24;
+
+ //printf("mod->Id(): 0x%X, rByte: 0x%X, gByte: 0x%X, bByte: 0x%X, aByte: 0x%X\n", modelId, rByte, gByte, bByte, aByte);
- glColor4ub( rByte, gByte, bByte, aByte );
- mod->DrawPicker();
- }
+ glColor4ub( rByte, gByte, bByte, aByte );
+ mod->DrawPicker();
+ }
}
// read the color of the pixel in the back buffer under the mouse
@@ -130,13 +140,13 @@ StgModel* StgCanvas::getModel( int x, int y )
uint32_t modelId;
glReadPixels( x,viewport[3]-y,1,1,
- GL_RED,GL_UNSIGNED_BYTE,(void*)&rByte );
+ GL_RED,GL_UNSIGNED_BYTE,(void*)&rByte );
glReadPixels( x,viewport[3]-y,1,1,
- GL_GREEN,GL_UNSIGNED_BYTE,(void*)&gByte );
+ GL_GREEN,GL_UNSIGNED_BYTE,(void*)&gByte );
glReadPixels( x,viewport[3]-y,1,1,
- GL_BLUE,GL_UNSIGNED_BYTE,(void*)&bByte );
+ GL_BLUE,GL_UNSIGNED_BYTE,(void*)&bByte );
glReadPixels( x,viewport[3]-y,1,1,
- GL_ALPHA,GL_UNSIGNED_BYTE,(void*)&aByte );
+ GL_ALPHA,GL_UNSIGNED_BYTE,(void*)&aByte );
modelId = rByte;
modelId |= gByte << 8;
@@ -162,65 +172,65 @@ StgModel* StgCanvas::getModel( int x, int y )
}
bool StgCanvas::selected( StgModel* mod ) {
- if( g_list_find( selected_models, mod ) )
- return true;
- else
- return false;
+ if( g_list_find( selected_models, mod ) )
+ return true;
+ else
+ return false;
}
void StgCanvas::select( StgModel* mod ) {
- if( mod )
+ if( mod )
{
last_selection = mod;
selected_models = g_list_prepend( selected_models, mod );
-// mod->Disable();
+ // mod->Disable();
}
}
void StgCanvas::unSelect( StgModel* mod ) {
- if( mod )
- {
+ if( mod )
+ {
if ( GList* link = g_list_find( selected_models, mod ) )
- {
- // remove it from the selected list
- selected_models =
- g_list_remove_link( selected_models, link );
-// mod->Enable();
- }
- }
+ {
+ // remove it from the selected list
+ selected_models =
+ g_list_remove_link( selected_models, link );
+ // mod->Enable();
+ }
+ }
}
void StgCanvas::unSelectAll() {
-// for( GList* it=selected_models; it; it=it->next )
-// ((StgModel*)it->data)->Enable();
+ // for( GList* it=selected_models; it; it=it->next )
+ // ((StgModel*)it->data)->Enable();
- g_list_free( selected_models );
- selected_models = NULL;
+ g_list_free( selected_models );
+ selected_models = NULL;
}
// convert from 2d window pixel to 3d world coordinates
void StgCanvas::CanvasToWorld( int px, int py,
- double *wx, double *wy, double* wz )
+ double *wx, double *wy, double* wz )
{
- if( px <= 0 )
- px = 1;
- else if( px >= w() )
- px = w() - 1;
- if( py <= 0 )
- py = 1;
- else if( py >= h() )
- py = h() - 1;
+ if( px <= 0 )
+ px = 1;
+ else if( px >= w() )
+ px = w() - 1;
+ if( py <= 0 )
+ py = 1;
+ else if( py >= h() )
+ py = h() - 1;
- //redraw the screen only if the camera model isn't active.
- //TODO new selection technique will simply use drawfloor to result in z = 0 always and prevent strange behaviours near walls
- //TODO refactor, so glReadPixels reads (then caches) the whole screen only when the camera changes.
- if( true || dirtyBuffer() ) {
- glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
- current_camera->SetProjection();
- current_camera->Draw();
- DrawFloor(); //call this rather than renderFrame for speed - this won't give correct z values
- dirty_buffer = false;
- }
+ //redraw the screen only if the camera model isn't active.
+ //TODO new selection technique will simply use drawfloor to result in z = 0 always and prevent strange behaviours near walls
+ //TODO refactor, so glReadPixels reads (then caches) the whole screen only when the camera changes.
+ if( true || dirtyBuffer() ) {
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+ current_camera->SetProjection();
+ current_camera->Draw();
+ DrawFloor(); //call this rather than renderFrame for speed - this won't give correct z values
+ dirty_buffer = false;
+ }
int viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
@@ -239,214 +249,214 @@ void StgCanvas::CanvasToWorld( int px, int py,
int StgCanvas::handle(int event)
{
- switch(event)
- {
- case FL_MOUSEWHEEL:
+ switch(event)
+ {
+ case FL_MOUSEWHEEL:
if( pCamOn == true ) {
- perspective_camera.scroll( Fl::event_dy() / 10.0 );
+ perspective_camera.scroll( Fl::event_dy() / 10.0 );
}
else {
- camera.scale( Fl::event_dy(), Fl::event_x(), w(), Fl::event_y(), h() );
+ camera.scale( Fl::event_dy(), Fl::event_x(), w(), Fl::event_y(), h() );
}
invalidate();
redraw();
return 1;
- case FL_MOVE: // moused moved while no button was pressed
+ case FL_MOVE: // moused moved while no button was pressed
if ( startx >=0 ) {
- // mouse pointing to valid value
+ // mouse pointing to valid value
- if( Fl::event_state( FL_CTRL ) )
- {
+ if( Fl::event_state( FL_CTRL ) )
+ {
int dx = Fl::event_x() - startx;
int dy = Fl::event_y() - starty;
if( pCamOn == true ) {
- perspective_camera.addYaw( -dx );
- perspective_camera.addPitch( -dy );
+ perspective_camera.addYaw( -dx );
+ perspective_camera.addPitch( -dy );
}
else {
- camera.addPitch( - 0.5 * static_cast<double>( dy ) );
- camera.addYaw( - 0.5 * static_cast<double>( dx ) );
+ camera.addPitch( - 0.5 * static_cast<double>( dy ) );
+ camera.addYaw( - 0.5 * static_cast<double>( dx ) );
}
invalidate();
redraw();
- }
- else if( Fl::event_state( FL_ALT ) )
- {
+ }
+ else if( Fl::event_state( FL_ALT ) )
+ {
int dx = Fl::event_x() - startx;
int dy = Fl::event_y() - starty;
if( pCamOn == true ) {
- perspective_camera.move( -dx, dy, 0.0 );
+ perspective_camera.move( -dx, dy, 0.0 );
}
else {
- camera.move( -dx, dy );
+ camera.move( -dx, dy );
}
invalidate();
- }
+ }
}
startx = Fl::event_x();
starty = Fl::event_y();
return 1;
- case FL_PUSH: // button pressed
- {
- StgModel* mod = getModel( startx, starty );
- startx = Fl::event_x();
- starty = Fl::event_y();
- selectedModel = false;
- switch( Fl::event_button() )
- {
- case 1:
- clicked_empty_space = ( mod == NULL );
- empty_space_startx = startx;
- empty_space_starty = starty;
- if( mod ) {
- // clicked a model
- if ( Fl::event_state( FL_SHIFT ) ) {
- // holding shift, toggle selection
- if ( selected( mod ) )
- unSelect( mod );
- else {
- select( mod );
- selectedModel = true; // selected a model
- }
- }
- else {
- if ( !selected( mod ) ) {
- // clicked on an unselected model while
- // not holding shift, this is the new
- // selection
- unSelectAll();
- select( mod );
- }
- selectedModel = true; // selected a model
- }
- }
-
- return 1;
- case 3:
+ case FL_PUSH: // button pressed
{
- // leave selections alone
- // rotating handled within FL_DRAG
- return 1;
+ StgModel* mod = getModel( startx, starty );
+ startx = Fl::event_x();
+ starty = Fl::event_y();
+ selectedModel = false;
+ switch( Fl::event_button() )
+ {
+ case 1:
+ clicked_empty_space = ( mod == NULL );
+ empty_space_startx = startx;
+ empty_space_starty = starty;
+ if( mod ) {
+ // clicked a model
+ if ( Fl::event_state( FL_SHIFT ) ) {
+ // holding shift, toggle selection
+ if ( selected( mod ) )
+ unSelect( mod );
+ else {
+ select( mod );
+ selectedModel = true; // selected a model
+ }
+ }
+ else {
+ if ( !selected( mod ) ) {
+ // clicked on an unselected model while
+ // not holding shift, this is the new
+ // selection
+ unSelectAll();
+ select( mod );
+ }
+ selectedModel = true; // selected a model
+ }
+ }
+
+ return 1;
+ case 3:
+ {
+ // leave selections alone
+ // rotating handled within FL_DRAG
+ return 1;
+ }
+ default:
+ return 0;
+ }
}
- default:
- return 0;
- }
- }
- case FL_DRAG: // mouse moved while button was pressed
- {
- int dx = Fl::event_x() - startx;
- int dy = Fl::event_y() - starty;
-
- if ( Fl::event_state( FL_BUTTON1 ) && Fl::event_state( FL_CTRL ) == false ) {
- // Left mouse button drag
- if ( selectedModel ) {
+ case FL_DRAG: // mouse moved while button was pressed
+ {
+ int dx = Fl::event_x() - startx;
+ int dy = Fl::event_y() - starty;
+
+ if ( Fl::event_state( FL_BUTTON1 ) && Fl::event_state( FL_CTRL ) == false ) {
+ // Left mouse button drag
+ if ( selectedModel ) {
// started dragging on a selected model
double sx,sy,sz;
CanvasToWorld( startx, starty,
- &sx, &sy, &sz );
+ &sx, &sy, &sz );
double x,y,z;
CanvasToWorld( Fl::event_x(), Fl::event_y(),
- &x, &y, &z );
+ &x, &y, &z );
// move all selected models to the mouse pointer
for( GList* it = selected_models; it; it=it->next )
- {
- StgModel* mod = (StgModel*)it->data;
- mod->AddToPose( x-sx, y-sy, 0, 0 );
- }
- }
- else {
+ {
+ StgModel* mod = (StgModel*)it->data;
+ mod->AddToPose( x-sx, y-sy, 0, 0 );
+ }
+ }
+ else {
// started dragging on empty space or an
// unselected model, move the canvas
if( pCamOn == true ) {
- perspective_camera.move( -dx, dy, 0.0 );
+ perspective_camera.move( -dx, dy, 0.0 );
}
else {
- camera.move( -dx, dy );
+ camera.move( -dx, dy );
}
invalidate(); // so the projection gets updated
- }
- }
- else if ( Fl::event_state( FL_BUTTON3 ) || ( Fl::event_state( FL_BUTTON1 ) && Fl::event_state( FL_CTRL ) ) ) {
- // rotate all selected models
- for( GList* it = selected_models; it; it=it->next )
+ }
+ }
+ else if ( Fl::event_state( FL_BUTTON3 ) || ( Fl::event_state( FL_BUTTON1 ) && Fl::event_state( FL_CTRL ) ) ) {
+ // rotate all selected models
+ for( GList* it = selected_models; it; it=it->next )
{
- StgModel* mod = (StgModel*)it->data;
- mod->AddToPose( 0,0,0, 0.05*(dx+dy) );
+ StgModel* mod = (StgModel*)it->data;
+ mod->AddToPose( 0,0,0, 0.05*(dx+dy) );
}
- }
+ }
- startx = Fl::event_x();
- starty = Fl::event_y();
+ startx = Fl::event_x();
+ starty = Fl::event_y();
- redraw();
- return 1;
- } // end case FL_DRAG
+ redraw();
+ return 1;
+ } // end case FL_DRAG
- case FL_RELEASE: // mouse button released
- if( empty_space_startx == Fl::event_x() && empty_space_starty == Fl::event_y() && clicked_empty_space == true ) {
- // clicked on empty space, unselect all
- unSelectAll();
- }
+ case FL_RELEASE: // mouse button released
+ if( empty_space_startx == Fl::event_x() && empty_space_starty == Fl::event_y() && clicked_empty_space == true ) {
+ // clicked on empty space, unselect all
+ unSelectAll();
+ }
return 1;
- case FL_FOCUS:
- case FL_UNFOCUS:
+ case FL_FOCUS:
+ case FL_UNFOCUS:
//.... Return 1 if you want keyboard events, 0 otherwise
return 1;
- case FL_KEYBOARD:
+ case FL_KEYBOARD:
switch( Fl::event_key() )
- {
- case 'p': // pause
- world->TogglePause();
- break;
- case ' ': // space bar
+ {
+ case 'p': // pause
+ world->TogglePause();
+ break;
+ case ' ': // space bar
- // if the worldfile doesn't have the fields you need, you get
- // a weird view. need to think this through a bit before
- // eliminating the old behaviour - rtv
-
- //if ( wf )
- //current_camera->Load( wf, wf->LookupEntity( "window" ) );
- //else
- current_camera->reset();
+ // if the worldfile doesn't have the fields you need, you get
+ // a weird view. need to think this through a bit before
+ // eliminating the old behaviour - rtv
+
+ //if ( wf )
+ //current_camera->Load( wf, wf->LookupEntity( "window" ) );
+ //else
+ current_camera->reset();
- //invalidate();
- if( Fl::event_state( FL_CTRL ) ) {
+ //invalidate();
+ if( Fl::event_state( FL_CTRL ) ) {
resetCamera();
- }
- redraw();
- break;
- case FL_Left:
- if( pCamOn == false ) { camera.move( -10, 0 ); }
- else { perspective_camera.strafe( -0.5 ); } break;
- case FL_Right:
- if( pCamOn == false ) {camera.move( 10, 0 ); }
- else { perspective_camera.strafe( 0.5 ); } break;
- case FL_Down:
- if( pCamOn == false ) {camera.move( 0, -10 ); }
- else { perspective_camera.forward( -0.5 ); } break;
- case FL_Up:
- if( pCamOn == false ) {camera.move( 0, 10 ); }
- else { perspective_camera.forward( 0.5 ); } break;
- default:
- return 0; // keypress unhandled
- }
+ }
+ redraw();
+ break;
+ case FL_Left:
+ if( pCamOn == false ) { camera.move( -10, 0 ); }
+ else { perspective_camera.strafe( -0.5 ); } break;
+ case FL_Right:
+ if( pCamOn == false ) {camera.move( 10, 0 ); }
+ else { perspective_camera.strafe( 0.5 ); } break;
+ case FL_Down:
+ if( pCamOn == false ) {camera.move( 0, -10 ); }
+ else { perspective_camera.forward( -0.5 ); } break;
+ case FL_Up:
+ if( pCamOn == false ) {camera.move( 0, 10 ); }
+ else { perspective_camera.forward( 0.5 ); } break;
+ default:
+ return 0; // keypress unhandled
+ }
invalidate(); // update projection
return 1;
-// case FL_SHORTCUT:
-// //... shortcut, key is in Fl::event_key(), ascii in Fl::event_text()
-// //... Return 1 if you understand/use the shortcut event, 0 otherwise...
-// return 1;
- default:
+ // case FL_SHORTCUT:
+ // //... shortcut, key is in Fl::event_key(), ascii in Fl::event_text()
+ // //... Return 1 if you understand/use the shortcut event, 0 otherwise...
+ // return 1;
+ default:
// pass other events to the base class...
//printf( "EVENT %d\n", event );
return Fl_Gl_Window::handle(event);
@@ -482,6 +492,8 @@ void StgCanvas::DrawGlobalGrid()
}
PopColor();
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(2.0, 2.0);
glDisable(GL_BLEND);
@@ -493,20 +505,19 @@ void StgCanvas::DrawGlobalGrid()
glBegin(GL_QUADS);
glTexCoord2f( bounds.x.min/2.0, bounds.y.min/2.0 );
- glVertex3f( bounds.x.min, bounds.y.min, 0 );
+ glVertex2f( bounds.x.min, bounds.y.min );
glTexCoord2f( bounds.x.max/2.0, bounds.y.min/2.0);
- glVertex3f( bounds.x.max, bounds.y.min, 0 );
+ glVertex2f( bounds.x.max, bounds.y.min );
glTexCoord2f( bounds.x.max/2.0, bounds.y.max/2.0 );
- glVertex3f( bounds.x.max, bounds.y.max, 0 );
+ glVertex2f( bounds.x.max, bounds.y.max );
glTexCoord2f( bounds.x.min/2.0, bounds.y.max/2.0 );
- glVertex3f( bounds.x.min, bounds.y.max, 0 );
+ glVertex2f( bounds.x.min, bounds.y.max );
glEnd();
glDisable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
-
glDisable(GL_POLYGON_OFFSET_FILL );
}
@@ -514,17 +525,17 @@ void StgCanvas::DrawGlobalGrid()
void StgCanvas::DrawFloor()
{
stg_bounds3d_t bounds = world->GetExtent();
- float z = 0;
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(2.0, 2.0);
glColor4f( 1.0, 1.0, 1.0, 1.0 );
+
glBegin(GL_QUADS);
- glVertex3f( bounds.x.min, bounds.y.min, z );
- glVertex3f( bounds.x.max, bounds.y.min, z );
- glVertex3f( bounds.x.max, bounds.y.max, z );
- glVertex3f( bounds.x.min, bounds.y.max, z );
+ glVertex2f( bounds.x.min, bounds.y.min );
+ glVertex2f( bounds.x.max, bounds.y.min );
+ glVertex2f( bounds.x.max, bounds.y.max );
+ glVertex2f( bounds.x.min, bounds.y.max );
glEnd();
glEnd();
@@ -537,109 +548,108 @@ void StgCanvas::DrawBlocks()
void StgCanvas::resetCamera()
{
- float max_x = 0, max_y = 0, min_x = 0, min_y = 0;
+ float max_x = 0, max_y = 0, min_x = 0, min_y = 0;
- //TODO take orrientation ( `a' ) and geom.pose offset into consideration
- for( GList* it=world->StgWorld::children; it; it=it->next ) {
- StgModel* ptr = (StgModel*) it->data;
- stg_pose_t pose = ptr->GetPose();
- stg_geom_t geom = ptr->GetGeom();
+ //TODO take orrientation ( `a' ) and geom.pose offset into consideration
+ for( GList* it=world->StgWorld::children; it; it=it->next ) {
+ StgModel* ptr = (StgModel*) it->data;
+ stg_pose_t pose = ptr->GetPose();
+ stg_geom_t geom = ptr->GetGeom();
- float tmp_min_x = pose.x - geom.size.x / 2.0;
- float tmp_max_x = pose.x + geom.size.x / 2.0;
- float tmp_min_y = pose.y - geom.size.y / 2.0;
- float tmp_max_y = pose.y + geom.size.y / 2.0;
+ float tmp_min_x = pose.x - geom.size.x / 2.0;
+ float tmp_max_x = pose.x + geom.size.x / 2.0;
+ float tmp_min_y = pose.y - geom.size.y / 2.0;
+ float tmp_max_y = pose.y + geom.size.y / 2.0;
- if( tmp_min_x < min_x ) min_x = tmp_min_x;
- if( tmp_max_x > max_x ) max_x = tmp_max_x;
- if( tmp_min_y < min_y ) min_y = tmp_min_y;
- if( tmp_max_y > max_y ) max_y = tmp_max_y;
- }
+ if( tmp_min_x < min_x ) min_x = tmp_min_x;
+ if( tmp_max_x > max_x ) max_x = tmp_max_x;
+ if( tmp_min_y < min_y ) min_y = tmp_min_y;
+ if( tmp_max_y > max_y ) max_y = tmp_max_y;
+ }
- //do a complete reset
- float x = ( min_x + max_x ) / 2.0;
- float y = ( min_y + max_y ) / 2.0;
- camera.setPose( x, y );
- float scale_x = w() / (max_x - min_x) * 0.9;
- float scale_y = h() / (max_y - min_y) * 0.9;
- camera.setScale( scale_x < scale_y ? scale_x : scale_y );
+ //do a complete reset
+ float x = ( min_x + max_x ) / 2.0;
+ float y = ( min_y + max_y ) / 2.0;
+ camera.setPose( x, y );
+ float scale_x = w() / (max_x - min_x) * 0.9;
+ float scale_y = h() / (max_y - min_y) * 0.9;
+ camera.setScale( scale_x < scale_y ? scale_x : scale_y );
- //TODO reset perspective cam
+ //TODO reset perspective cam
}
void StgCanvas::renderFrame()
{
- //before drawing, order all models based on distance from camera
- float x = current_camera->x();
- float y = current_camera->y();
- float sphi = -dtor( current_camera->yaw() );
+ //before drawing, order all models based on distance from camera
+ float x = current_camera->x();
+ float y = current_camera->y();
+ float sphi = -dtor( current_camera->yaw() );
- //estimate point of camera location - hard to do with orthogonal mode
- x += -sin( sphi ) * 100;
- y += -cos( sphi ) * 100;
+ //estimate point of camera location - hard to do with orthogonal mode
+ x += -sin( sphi ) * 100;
+ y += -cos( sphi ) * 100;
- // TODO - keep this map around in between frames, because the order
- // changes slowly, and sorting an already-sorted list is
- // usually very fast (rtv)
-
- //store all models in a sorted multimap
- std::multimap< float, StgModel* > ordered;
- for( GList* it=world->StgWorld::children; it; it=it->next ) {
- StgModel* ptr = (StgModel*) it->data;
- stg_pose_t pose = ptr->GetPose();
+ // TODO - keep this map around in between frames, because the order
+ // changes slowly, and sorting an already-sorted list is
+ // usually very fast (rtv)
+
+ //store all models in a sorted multimap
+ std::multimap< float, StgModel* > ordered;
+ for( GList* it=world->StgWorld::children; it; it=it->next ) {
+ StgModel* ptr = (StgModel*) it->data;
+ stg_pose_t pose = ptr->GetPose();
- float dist = sqrt( ( x - pose.x ) * ( x - pose.x ) + ( y - pose.y ) * ( y - pose.y ) );
- ordered.insert( std::pair< float, StgModel* >( dist, (StgModel*)it->data ) );
- }
+ float dist = sqrt( ( x - pose.x ) * ( x - pose.x ) + ( y - pose.y ) * ( y - pose.y ) );
+ ordered.insert( std::pair< float, StgModel* >( dist, (StgModel*)it->data ) );
+ }
- //now the models can be iterated over with:
- // for( std::multimap< float, StgModel* >::reverse_iterator i = ordered.rbegin(); i != ordered.rend(); i++ )
+ //now the models can be iterated over with:
+ // for( std::multimap< float, StgModel* >::reverse_iterator i = ordered.rbegin(); i != ordered.rend(); i++ )
+ glEnable( GL_DEPTH_TEST );
+
if( ! showTrails )
- glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
-
- if( showGrid )
- DrawGlobalGrid();
- else
- DrawFloor();
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
if( showTree || showOccupancy )
{
glPushMatrix();
- glScalef( 1.0/world->Resolution(), 1.0/world->Resolution(), 0 );
-
- glLineWidth( 1 );
- glPolygonMode( GL_FRONT, GL_LINE );
- colorstack.Push(1,0,0);
+
+ GLfloat scale = 1.0/world->Resolution();
+ glScalef( scale, scale, 1.0 ); // XX TODO - this seems slightly
+ // out for Z. look into it.
if( showOccupancy )
- ((StgWorldGui*)world)->DrawTree( false );
+ ((StgWorldGui*)world)->DrawTree( false );
if( showTree )
- ((StgWorldGui*)world)->DrawTree( true );
+ ((StgWorldGui*)world)->DrawTree( true );
- colorstack.Pop();
- glPolygonMode( GL_FRONT, GL_FILL );
glPopMatrix();
}
-
- for( GList* it=selected_models; it; it=it->next )
- ((StgModel*)it->data)->DrawSelected();
+
+ if( showGrid )
+ DrawGlobalGrid();
+ else
+ DrawFloor();
if( showFootprints )
{
glDisable( GL_DEPTH_TEST );
for( std::multimap< float, StgModel* >::reverse_iterator i = ordered.rbegin(); i != ordered.rend(); i++ ) {
- i->second->DrawTrailFootprint();
+ i->second->DrawTrailFootprint();
}
glEnable( GL_DEPTH_TEST );
}
+
+ if( showBlocks )
+ DrawBlocks();
if( showTrailRise )
{
for( std::multimap< float, StgModel* >::reverse_iterator i = ordered.rbegin(); i != ordered.rend(); i++ ) {
- i->second->DrawTrailBlocks();
+ i->second->DrawTrailBlocks();
}
}
@@ -647,74 +657,76 @@ void StgCanvas::renderFrame()
{
glEnable( GL_DEPTH_TEST );
for( std::multimap< float, StgModel* >::reverse_iterator i = ordered.rbegin(); i != ordered.rend(); i++ ) {
- i->second->DrawTrailArrows();
+ i->second->DrawTrailArrows();
}
}
- if( showBlocks )
- DrawBlocks();
+
+ for( GList* it=selected_models; it; it=it->next )
+ ((StgModel*)it->data)->DrawSelected();
+
// useful debug - puts a point at the origin of each model
//for( GList* it = world->StgWorld::children; it; it=it->next )
// ((StgModel*)it->data)->DrawOriginTree();
// draw the model-specific visualizations
- if( showData ) {
- if ( visualizeAll ) {
- for( GList* it = world->StgWorld::children; it; it=it->next )
- ((StgModel*)it->data)->DataVisualizeTree( current_camera );
- }
- else if ( selected_models ) {
- for( GList* it = selected_models; it; it=it->next )
- ((StgModel*)it->data)->DataVisualizeTree( current_camera );
- }
- else if ( last_selection ) {
- last_selection->DataVisualizeTree( current_camera );
- }
- }
+ if( showData ) {
+ if ( visualizeAll ) {
+ for( GList* it = world->StgWorld::children; it; it=it->next )
+ ((StgModel*)it->data)->DataVisualizeTree( current_camera );
+ }
+ else if ( selected_models ) {
+ for( GList* it = selected_models; it; it=it->next )
+ ((StgModel*)it->data)->DataVisualizeTree( current_camera );
+ }
+ else if ( last_selection ) {
+ last_selection->DataVisualizeTree( current_camera );
+ }
+ }
if( showGrid )
- for( std::multimap< float, StgModel* >::reverse_iterator i = ordered.rbegin(); i != ordered.rend(); i++ ) {
- i->second->DrawGrid();
- }
+ for( std::multimap< float, StgModel* >::reverse_iterator i = ordered.rbegin(); i != ordered.rend(); i++ ) {
+ i->second->DrawGrid();
+ }
if( showFlags )
- for( std::multimap< float, StgModel* >::reverse_iterator i = ordered.rbegin(); i != ordered.rend(); i++ ) {
- i->second->DrawFlagList();
- }
+ for( std::multimap< float, StgModel* >::reverse_iterator i = ordered.rbegin(); i != ordered.rend(); i++ ) {
+ i->second->DrawFlagList();
+ }
if( showBlinken )
- for( std::multimap< float, StgModel* >::reverse_iterator i = ordered.rbegin(); i != ordered.rend(); i++ ) {
+ for( std::multimap< float, StgModel* >::reverse_iterator i = ordered.rbegin(); i != ordered.rend(); i++ ) {
i->second->DrawBlinkenlights();
- }
+ }
- if ( showStatus ) {
- glPushMatrix();
- for( std::multimap< float, StgModel* >::reverse_iterator i = ordered.rbegin(); i != ordered.rend(); i++ ) {
- //ensure two icons can't be in the exact same plane
- if( camera.pitch() == 0 && !pCamOn )
- glTranslatef( 0, 0, 0.1 );
- i->second->DrawStatusTree( current_camera );
- }
- glPopMatrix();
- }
+ if ( showStatus ) {
+ glPushMatrix();
+ for( std::multimap< float, StgModel* >::reverse_iterator i = ordered.rbegin(); i != ordered.rend(); i++ ) {
+ //ensure two icons can't be in the exact same plane
+ if( camera.pitch() == 0 && !pCamOn )
+ glTranslatef( 0, 0, 0.1 );
+ i->second->DrawStatusTree( current_camera );
+ }
+ glPopMatrix();
+ }
if( world->GetRayList() )
{
glDisable( GL_DEPTH_TEST );
PushColor( 0,0,0,0.5 );
for( GList* it = world->GetRayList(); it; it=it->next )
- {
- float* pts = (float*)it->data;
- glBegin( GL_LINES );
- glVertex2f( pts[0], pts[1] );
- glVertex2f( pts[2], pts[3] );
- glEnd();
- }
+ {
+ float* pts = (float*)it->data;
+ glBegin( GL_LINES );
+ glVertex2f( pts[0], pts[1] );
+ glVertex2f( pts[2], pts[3] );
+ glEnd();
+ }
PopColor();
glEnable( GL_DEPTH_TEST );
@@ -738,7 +750,7 @@ void StgCanvas::renderFrame()
std::string clockstr = world->ClockString();
if( showFollow == true && last_selection )
- clockstr.append( " [ FOLLOW MODE ]" );
+ clockstr.append( " [ FOLLOW MODE ]" );
fl_font( FL_HELVETICA, 12 );
float txtWidth = gl_width( clockstr.c_str() );
@@ -819,11 +831,11 @@ void StgCanvas::Screenshot()
//png_set_compression_level(pp, Z_DEFAULT_COMPRESSION);
png_set_IHDR( pp, info,
- width, height, 8,
- PNG_COLOR_TYPE_RGBA,
- PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_DEFAULT,
- PNG_FILTER_TYPE_DEFAULT);
+ width, height, 8,
+ PNG_COLOR_TYPE_RGBA,
+ PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_DEFAULT,
+ PNG_FILTER_TYPE_DEFAULT);
png_write_png( pp, info, PNG_TRANSFORM_IDENTITY, NULL );
@@ -837,23 +849,23 @@ void StgCanvas::Screenshot()
void StgCanvas::perspectiveCb( Fl_Widget* w, void* p )
{
- StgCanvas* canvas = static_cast<StgCanvas*>( w );
- Option* opt = static_cast<Option*>( p ); // pCamOn
- if ( opt ) {
- // Perspective mode is on, change camera
- canvas->current_camera = &canvas->perspective_camera;
- }
- else {
- canvas->current_camera = &canvas->camera;
- }
+ StgCanvas* canvas = static_cast<StgCanvas*>( w );
+ Option* opt = static_cast<Option*>( p ); // pCamOn
+ if ( opt ) {
+ // Perspective mode is on, change camera
+ canvas->current_camera = &canvas->perspective_camera;
+ }
+ else {
+ canvas->current_camera = &canvas->camera;
+ }
- canvas->invalidate();
+ canvas->invalidate();
}
void StgCanvas::createMenuItems( Fl_Menu_Bar* menu, std::string path )
{
showData.createMenuItem( menu, path );
-// visualizeAll.createMenuItem( menu, path );
+ // visualizeAll.createMenuItem( menu, path );
showBlocks.createMenuItem( menu, path );
showFlags.createMenuItem( menu, path );
showClock.createMenuItem( menu, path );
@@ -935,10 +947,9 @@ void StgCanvas::draw()
{
valid(1);
FixViewport(w(), h());
-
+
// set gl state that won't change every redraw
glClearColor ( 0.7, 0.7, 0.8, 1.0);
- //glClearColor ( 1,1,1,1 );
glDisable( GL_LIGHTING );
glEnable( GL_DEPTH_TEST );
glDepthFunc( GL_LESS );
@@ -950,84 +961,88 @@ void StgCanvas::draw()
glHint( GL_LINE_SMOOTH_HINT, GL_FASTEST );
glDepthMask( GL_TRUE );
glEnable( GL_TEXTURE_2D );
- glEnableClientState( GL_VERTEX_ARRAY );
- glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+ glEnableClientState( GL_VERTEX_ARRAY );
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
//TODO find a better home for loading textures
- if( loaded_texture == false ) {
- std::string fullpath = FileManager::findFile( "assets/stall.png" );
- if ( fullpath == "" ) {
- PRINT_DEBUG( "Unable to load texture.\n" );
- }
-
- GLuint stall_id = TextureManager::getInstance().loadTexture( fullpath.c_str() );
- TextureManager::getInstance()._stall_texture_id = stall_id;
-
- //create floor texture
- {
- //TODO merge this code into the textureManager
- int i, j;
- for (i = 0; i < checkImageHeight; i++)
- for (j = 0; j < checkImageWidth; j++)
- {
- int even = (i+j)%2;
- checkImage[i][j][0] = (GLubyte) 255 - 10*even;
- checkImage[i][j][1] = (GLubyte) 255 - 10*even;
- checkImage[i][j][2] = (GLubyte) 255;// - 5*even;
- checkImage[i][j][3] = 255;
- }
+ if( loaded_texture == false )
+ {
+ std::string fullpath = FileManager::findFile( "assets/stall.png" );
+ if ( fullpath == "" ) {
+ PRINT_DEBUG( "Unable to load texture.\n" );
+ }
+
+ GLuint stall_id = TextureManager::getInstance().loadTexture( fullpath.c_str() );
+ TextureManager::getInstance()._stall_texture_id = stall_id;
+
+ //create floor texture
+ {
+ //TODO merge this code into the textureManager
+ int i, j;
+ for (i = 0; i < checkImageHeight; i++)
+ for (j = 0; j < checkImageWidth; j++)
+ {
+ int even = (i+j)%2;
+ checkImage[i][j][0] = (GLubyte) 255 - 10*even;
+ checkImage[i][j][1] = (GLubyte) 255 - 10*even;
+ checkImage[i][j][2] = (GLubyte) 255;// - 5*even;
+ checkImage[i][j][3] = 255;
+ }
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glGenTextures(1, &texName);
- glBindTexture(GL_TEXTURE_2D, texName);
- glEnable(GL_TEXTURE_2D);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glGenTextures(1, &texName);
+ glBindTexture(GL_TEXTURE_2D, texName);
+ glEnable(GL_TEXTURE_2D);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth, checkImageHeight,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth, checkImageHeight,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage);
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- }
-
- loaded_texture = true;
- }
-
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ }
+
+ loaded_texture = true;
+ }
+
// install a font
gl_font( FL_HELVETICA, 12 );
-
- if( pCamOn == true ) {
- perspective_camera.setAspect( static_cast< float >( w() ) / static_cast< float >( h() ) );
- perspective_camera.SetProjection();
- current_camera = &perspective_camera;
- } else {
- stg_bounds3d_t extent = world->GetExtent();
- camera.SetProjection( w(), h(), extent.y.min, extent.y.max );
- current_camera = &camera;
- }
-
- // enable vertex arrays
- glEnableClientState( GL_VERTEX_ARRAY );
- //glEnableClientState( GL_COLOR_ARRAY );
-
+
+ if( pCamOn == true )
+ {
+ perspective_camera.setAspect( static_cast< float >( w() ) / static_cast< float >( h() ) );
+ perspective_camera.SetProjection();
+ current_camera = &perspective_camera;
+ }
+ else
+ {
+ stg_bounds3d_t extent = world->GetExtent();
+ camera.SetProjection( w(), h(), extent.y.min, extent.y.max );
+ current_camera = &camera;
+ }
+
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
}
//Follow the selected robot
- if( showFollow && last_selection ) {
- stg_pose_t gpose = last_selection->GetGlobalPose();
- if( pCamOn == true ) {
- perspective_camera.setPose( gpose.x, gpose.y, 0.2 );
- perspective_camera.setYaw( rtod( gpose.a ) - 90.0 );
- } else {
- camera.setPose( gpose.x, gpose.y );
- }
- }
-
+ if( showFollow && last_selection )
+ {
+ stg_pose_t gpose = last_selection->GetGlobalPose();
+ if( pCamOn == true )
+ {
+ perspective_camera.setPose( gpose.x, gpose.y, 0.2 );
+ perspective_camera.setYaw( rtod( gpose.a ) - 90.0 );
+ }
+ else
+ {
+ camera.setPose( gpose.x, gpose.y );
+ }
+ }
+
current_camera->Draw();
renderFrame();
}
View
113 libstage/main.cc
@@ -18,68 +18,71 @@ static struct option longopts[] = {
int main( int argc, char* argv[] )
{
- printf( "%s %s ", PROJECT, VERSION );
+ // initialize libstage - call this first
+ Stg::Init( &argc, &argv );
- int ch=0, optindex=0;
- bool usegui = true;
-
- while ((ch = getopt_long(argc, argv, "gf", longopts, &optindex)) != -1)
- {
+ printf( "%s %s ", PROJECT, VERSION );
+
+ int ch=0, optindex=0;
+ bool usegui = true;
+
+ while ((ch = getopt_long(argc, argv, "gf", longopts, &optindex)) != -1)
+ {
switch( ch )
- {
- case 0: // long option given
- printf( "option %s given", longopts[optindex].name );
- break;
- case 'g':
- usegui = false;
- printf( "[GUI disabled]" );
- break;
- case '?':
- break;
- default:
- printf("unhandled option %c\n", ch );
- }
- }
-
- puts("");// end the first start-up line
-
- // initialize libstage
- Stg::Init( &argc, &argv );
-
- // arguments at index optindex and later are not options, so they
- // must be world file names
-
-
- bool loaded_world_file = false;
- optindex = optind; //points to first non-option
- while( optindex < argc )
- {
+ {
+ case 0: // long option given
+ printf( "option %s given", longopts[optindex].name );
+ break;
+ case 'g':
+ usegui = false;
+ printf( "[GUI disabled]" );
+ break;
+ case '?':
+ break;
+ default:
+ printf("unhandled option %c\n", ch );
+ }
+ }
+
+ puts("");// end the first start-up line
+
+
+ // arguments at index [optindex] and later are not options, so they
+ // must be world file names
+
+ bool loaded_world_file = false;
+ optindex = optind; //points to first non-option
+ while( optindex < argc )
+ {
if( optindex > 0 )
- {
- const char* worldfilename = argv[optindex];
- StgWorld* world = ( usegui ?
- new StgWorldGui( 400, 300, worldfilename ) :
- new StgWorld( worldfilename ) );
- world->Load( worldfilename );
- loaded_world_file = true;
- }
+ {
+ const char* worldfilename = argv[optindex];
+ StgWorld* world = ( usegui ?
+ new StgWorldGui( 400, 300, worldfilename ) :
+ new StgWorld( worldfilename ) );
+ world->Load( worldfilename );
+ loaded_world_file = true;
+ }
optindex++;
- }
-
- if( loaded_world_file == false ) {
- // TODO: special window/loading dialog for this case
- new StgWorldGui( 400, 300 );
- }
-
- if( usegui == true ) {
+ }
+
+ if( loaded_world_file == false )
+ {
+ // TODO: special window/loading dialog for this case
+ new StgWorldGui( 400, 300 );
+ }
+
+ if( usegui == true )
+ {
//don't close the window once time has finished
while( true )
- StgWorld::UpdateAll();
- } else {
+ StgWorld::UpdateAll();
+ }
+ else
+ {
//close program once time has completed
bool quit = false;
while( quit == false )
- quit = StgWorld::UpdateAll();
- }
+ quit = StgWorld::UpdateAll();
+ }
}
-
View
974 libstage/model.cc
@@ -128,9 +128,6 @@ static const bool DEFAULT_ENERGY_CHARGEENABLE = true;
static const stg_watts_t DEFAULT_ENERGY_GIVERATE = 0.0;
static const stg_meters_t DEFAULT_ENERGY_PROBERANGE = 0.0;
static const stg_watts_t DEFAULT_ENERGY_TRICKLERATE = 0.1;
-static const stg_meters_t DEFAULT_GEOM_SIZEX = 0.10;
-static const stg_meters_t DEFAULT_GEOM_SIZEY = 0.10;
-static const stg_meters_t DEFAULT_GEOM_SIZEZ = 0.10;
static const bool DEFAULT_GRID = false;
static const bool DEFAULT_GRIPPERRETURN = false;
static const stg_laser_return_t DEFAULT_LASERRETURN = LaserVisible;
@@ -157,7 +154,48 @@ GHashTable* StgModel::modelsbyid = g_hash_table_new( NULL, NULL );
StgModel::StgModel( StgWorld* world,
StgModel* parent,
const stg_model_type_t type )
- : StgAncestor()
+ : StgAncestor(),
+ world(world),
+ parent(parent),
+ type(type),
+ id( StgModel::count++ ),
+ gpose_dirty(true),
+ trail( g_array_new( false, false, sizeof(stg_trail_item_t) )),
+ blocks_dl(0),
+ data_fresh(false),
+ disabled(false),
+ rebuild_displaylist(true),
+ say_string(NULL),
+ subs(0),
+ used(false),
+ stall(false),
+ obstacle_return(DEFAULT_OBSTACLERETURN),
+ ranger_return(DEFAULT_RANGERRETURN),
+ blob_return(DEFAULT_BLOBRETURN),
+ laser_return(DEFAULT_LASERRETURN),
+ gripper_return(DEFAULT_GRIPPERRETURN),
+ fiducial_return(0),
+ fiducial_key(0),
+ boundary(DEFAULT_BOUNDARY),
+ color(DEFAULT_COLOR),
+ map_resolution(DEFAULT_MAP_RESOLUTION),
+ gui_nose(DEFAULT_NOSE),
+ gui_grid(DEFAULT_GRID),
+ gui_outline(DEFAULT_OUTLINE),
+ gui_mask( parent ? 0 : DEFAULT_MASK),
+ callbacks( g_hash_table_new( g_int_hash, g_int_equal ) ),
+ flag_list(NULL),
+ blinkenlights( g_ptr_array_new() ),
+ last_update(0),
+ interval((stg_usec_t)1e4), // 10msec
+ initfunc(NULL),
+ wf(NULL),
+ on_velocity_list( false ),
+ on_update_list( false ),
+ wf_entity(0),
+ has_default_block( true ),
+ map_caches_are_invalid( true ),
+ thread_safe( false )
{
assert( modelsbyid );
assert( world );
@@ -167,84 +205,22 @@ StgModel::StgModel( StgWorld* world,
parent ? parent->Token() : "(null)",
type );
- this->parent = parent;
- this->world = world;
- this->type = type;
- this->id = StgModel::count++; // assign a unique ID and increment
- // the global model counter
+ g_hash_table_insert( modelsbyid, (void*)id, this );
- g_hash_table_insert( modelsbyid, (void*)this->id, this );
-
// Adding this model to its ancestor also gives this model a
// sensible default name
if ( parent )
parent->AddChild( this );
else
world->AddChild( this );
-
- world->AddModel( this );
- bzero( &pose, sizeof(pose));
-
- bzero( &global_pose, sizeof(global_pose));
- this->gpose_dirty = true;
+ world->AddModel( this );
- this->trail = g_array_new( false, false, sizeof(stg_trail_item_t) );
-
- this->data_fresh = false;
- this->disabled = false;
- this->blocks = NULL;
- this->rebuild_displaylist = true;
- this->say_string = NULL;
- this->subs = 0;
- this->used = false;
- this->stall = false;
-
- if( world->IsGUI() )
- this->blocks_dl = glGenLists( 1 );
-
- this->geom.size.x = DEFAULT_GEOM_SIZEX;
- this->geom.size.y = DEFAULT_GEOM_SIZEY;
- this->geom.size.z = DEFAULT_GEOM_SIZEZ;
- memset( &this->geom.pose, 0, sizeof(this->geom.pose));
-
- this->obstacle_return = DEFAULT_OBSTACLERETURN;
- this->ranger_return = DEFAULT_RANGERRETURN;
- this->blob_return = DEFAULT_BLOBRETURN;
- this->laser_return = DEFAULT_LASERRETURN;
- this->gripper_return = DEFAULT_GRIPPERRETURN;