48 c->
world->dirty =
false;
51 Fl::repeat_timeout( c->
interval/1000.0,
58 int width,
int height) :
59 Fl_Gl_Window( x, y, width, height ),
74 showBBoxes(
"Debug/Bounding boxes",
"show_boundingboxes",
"^b", false, world ),
75 showBlocks(
"Blocks",
"show_blocks",
"b", true, world ),
76 showBlur(
"Trails/Blur",
"show_trailblur",
"^d", false, world ),
77 showClock(
"Clock",
"show_clock",
"c", true, world ),
78 showData(
"Data",
"show_data",
"d", false, world ),
79 showFlags(
"Flags",
"show_flags",
"l", true, world ),
80 showFollow(
"Follow",
"show_follow",
"f", false, world ),
81 showFootprints(
"Footprints",
"show_footprints",
"o", false, world ),
82 showGrid(
"Grid",
"show_grid",
"g", true, world ),
83 showOccupancy(
"Debug/Occupancy",
"show_occupancy",
"^o", false, world ),
85 showStatus(
"Status",
"show_status",
"s", true, world ),
86 showTrailArrows(
"Trails/Rising Arrows",
"show_trailarrows",
"^a", false, world ),
87 showTrailRise(
"Trails/Rising blocks",
"show_trailrise",
"^r", false, world ),
88 showTrails(
"Trails/Fast",
"show_trailfast",
"^f", false, world ),
89 showVoxels(
"Debug/Voxels",
"show_voxels",
"^v", false, world ),
90 pCamOn(
"Perspective camera",
"pcam_on",
"r", false, world ),
91 visualizeAll(
"Selected only",
"vis_all",
"v", false, world ),
117 glClearColor ( 0.7, 0.7, 0.8, 1.0);
118 glDisable( GL_LIGHTING );
119 glEnable( GL_DEPTH_TEST );
120 glDepthFunc( GL_LESS );
124 glEnable( GL_BLEND );
125 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
126 glEnable( GL_LINE_SMOOTH );
127 glHint( GL_LINE_SMOOTH_HINT, GL_FASTEST );
128 glDepthMask( GL_TRUE );
129 glEnable( GL_TEXTURE_2D );
130 glEnableClientState( GL_VERTEX_ARRAY );
131 glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
134 gl_font( FL_HELVETICA, 12 );
138 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
148 if ( fullpath ==
"" )
159 if ( fullpath ==
"" )
197 checkImage[i][j][0] = (GLubyte) 255 - 10*even;
198 checkImage[i][j][1] = (GLubyte) 255 - 10*even;
204 glBindTexture(GL_TEXTURE_2D,
checkTex);
206 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
207 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
208 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
209 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
211 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth, checkImageHeight,
227 glClearColor( 1,1,1,1 );
228 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
233 glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
234 glDisable(GL_DITHER);
246 uint8_t rByte, gByte, bByte, aByte;
247 uint32_t modelId = mod->
id;
249 gByte = modelId >> 8;
250 bByte = modelId >> 16;
251 aByte = modelId >> 24;
255 glColor4ub( rByte, gByte, bByte, aByte );
265 glGetIntegerv(GL_VIEWPORT,viewport);
270 glReadPixels( x,viewport[3]-y,1,1,
271 GL_RGBA,GL_UNSIGNED_BYTE,&rgbaByte[0] );
273 modelId = rgbaByte[0];
274 modelId |= rgbaByte[1] << 8;
275 modelId |= rgbaByte[2] << 16;
288 glClearColor ( 0.7, 0.7, 0.8, 1.0);
328 double *wx,
double *wy,
double* wz )
343 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
351 glGetIntegerv(GL_VIEWPORT, viewport);
353 GLdouble modelview[16];
354 glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
356 GLdouble projection[16];
357 glGetDoublev(GL_PROJECTION_MATRIX, projection);
360 glReadPixels( px, h()-py, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &pz );
361 gluUnProject( px, w()-py, pz, modelview, projection, viewport, wx,wy,wz );
375 camera.
scale( Fl::event_dy(), Fl::event_x(), w(), Fl::event_y(), h() );
382 if( Fl::event_state( FL_META ) )
384 puts(
"TODO: HANDLE HISTORY" );
393 if( Fl::event_state( FL_CTRL ) )
395 int dx = Fl::event_x() -
startx;
396 int dy = Fl::event_y() -
starty;
409 else if( Fl::event_state( FL_ALT ) )
411 int dx = Fl::event_x() -
startx;
412 int dy = Fl::event_y() -
starty;
434 switch( Fl::event_button() )
442 if ( Fl::event_state( FL_SHIFT ) ) {
479 int dx = Fl::event_x() -
startx;
480 int dy = Fl::event_y() -
starty;
482 if ( Fl::event_state( FL_BUTTON1 ) && Fl::event_state( FL_CTRL ) ==
false ) {
512 else if ( Fl::event_state( FL_BUTTON3 ) || ( Fl::event_state( FL_BUTTON1 ) && Fl::event_state( FL_CTRL ) ) ) {
527 int dx = Fl::event_x() -
startx;
528 int dy = Fl::event_y() -
starty;
564 switch( Fl::event_key() )
593 return Fl_Gl_Window::handle(event);
614 printf(
"removing model %s from canvas list\n", mod->
Token() );
622 glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
624 glEnable(GL_POLYGON_OFFSET_FILL);
625 glPolygonOffset(2.0, 2.0);
628 glEnable(GL_TEXTURE_2D);
629 glBindTexture(GL_TEXTURE_2D,
checkTex );
630 glColor3f( 1.0, 1.0, 1.0 );
633 glTexCoord2f( bounds.
x.
min/2.0, bounds.
y.
min/2.0 );
634 glVertex2f( bounds.
x.
min, bounds.
y.
min );
635 glTexCoord2f( bounds.
x.
max/2.0, bounds.
y.
min/2.0);
636 glVertex2f( bounds.
x.
max, bounds.
y.
min );
637 glTexCoord2f( bounds.
x.
max/2.0, bounds.
y.
max/2.0 );
638 glVertex2f( bounds.
x.
max, bounds.
y.
max );
639 glTexCoord2f( bounds.
x.
min/2.0, bounds.
y.
max/2.0 );
640 glVertex2f( bounds.
x.
min, bounds.
y.
max );
643 glDisable(GL_TEXTURE_2D);
646 glDisable(GL_POLYGON_OFFSET_FILL );
658 if( skip < 1 ) skip = 1;
659 if( skip > 2 && skip % 2 ) skip += 1;
666 for(
double i=0; i < bounds.
x.
max; i+=skip)
668 snprintf( str, 16,
"%d", (
int)i );
672 for(
double i=0; i >= bounds.
x.
min; i-=skip)
674 snprintf( str, 16,
"%d", (
int)i );
679 for(
double i=0; i < bounds.
y.
max; i+=skip)
681 snprintf( str, 16,
"%d", (
int)i );
685 for(
double i=0; i >= bounds.
y.
min; i-=skip)
687 snprintf( str, 16,
"%d", (
int)i );
701 glEnable(GL_POLYGON_OFFSET_FILL);
702 glPolygonOffset(2.0, 2.0);
704 glColor4f( 1.0, 1.0, 1.0, 1.0 );
707 glVertex2f( bounds.
x.
min, bounds.
y.
min );
708 glVertex2f( bounds.
x.
max, bounds.
y.
min );
709 glVertex2f( bounds.
x.
max, bounds.
y.
max );
710 glVertex2f( bounds.
x.
min, bounds.
y.
max );
717 (*it)->DrawBlocksTree();
722 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
725 glDisable (GL_CULL_FACE);
729 glEnable (GL_CULL_FACE);
731 glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
736 float max_x = 0, max_y = 0, min_x = 0, min_y = 0;
745 float tmp_min_x = pose.
x - geom.
size.
x / 2.0;
746 float tmp_max_x = pose.
x + geom.
size.
x / 2.0;
747 float tmp_min_y = pose.
y - geom.
size.
y / 2.0;
748 float tmp_max_y = pose.
y + geom.
size.
y / 2.0;
750 if( tmp_min_x < min_x ) min_x = tmp_min_x;
751 if( tmp_max_x > max_x ) max_x = tmp_max_x;
752 if( tmp_min_y < min_y ) min_y = tmp_min_y;
753 if( tmp_max_y > max_y ) max_y = tmp_max_y;
757 float x = ( min_x + max_x ) / 2.0;
758 float y = ( min_y + max_y ) / 2.0;
760 float scale_x = w() / (max_x - min_x) * 0.9;
761 float scale_y = h() / (max_y - min_y) * 0.9;
779 const meters_t a_dist = hypot( y - a_pose.
y, x - a_pose.
x );
780 const meters_t b_dist = hypot( y - b_pose.
y, x - b_pose.
x );
782 return ( a_dist < b_dist );
811 glEnable( GL_DEPTH_TEST );
814 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
823 if( ! world->rt_cells.empty() )
826 GLfloat
scale = 1.0/world->Resolution();
827 glScalef( scale, scale, 1.0 );
829 world->PushColor(
Color( 0,0,1,0.5) );
831 glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
834 glBegin( GL_POINTS );
836 for(
unsigned int i=0;
837 i < world->rt_cells.size();
841 snprintf( str, 128,
"(%d,%d)",
842 world->rt_cells[i].x,
843 world->rt_cells[i].y );
846 world->rt_cells[i].y+1, 0.1, str );
852 glVertex2f( world->rt_cells[i].x, world->rt_cells[i].y );
859 world->PushColor(
Color( 0,1,0,0.2) );
860 glBegin( GL_LINE_STRIP );
861 for(
unsigned int i=0;
862 i < world->rt_cells.size();
865 glVertex2f( world->rt_cells[i].x+0.5, world->rt_cells[i].y+0.5 );
875 if( ! world->rt_candidate_cells.empty() )
878 GLfloat
scale = 1.0/world->Resolution();
879 glScalef( scale, scale, 1.0 );
881 world->PushColor(
Color( 1,0,0,0.5) );
883 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
885 for(
unsigned int i=0;
886 i < world->rt_candidate_cells.size();
898 glRectf( world->rt_candidate_cells[i].x, world->rt_candidate_cells[i].y,
899 world->rt_candidate_cells[i].x+1, world->rt_candidate_cells[i].y+1 );
902 world->PushColor(
Color( 0,1,0,0.2) );
903 glBegin( GL_LINE_STRIP );
904 for(
unsigned int i=0;
905 i < world->rt_candidate_cells.size();
908 glVertex2f( world->rt_candidate_cells[i].x+0.5, world->rt_candidate_cells[i].y+0.5 );
926 glDisable( GL_DEPTH_TEST );
929 (*it)->DrawTrailFootprint();
931 glEnable( GL_DEPTH_TEST );
936 glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
937 glBegin( GL_TRIANGLES );
940 (*it)->DrawFlagList();
947 (*it)->DrawTrailArrows();
951 (*it)->DrawTrailBlocks();
963 (*it)->DrawSelected();
970 if( world->sim_time > 0 )
974 FOR_EACH( it, world->World::children )
996 glTranslatef( 0, 0, 0.1 );
999 (*it)->DrawStatusTree( &
camera );
1004 if( world->ray_list.size() > 0 )
1006 glDisable( GL_DEPTH_TEST );
1011 glBegin( GL_LINES );
1012 glVertex2f( pts[0], pts[1] );
1013 glVertex2f( pts[2], pts[3] );
1017 glEnable( GL_DEPTH_TEST );
1024 glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
1027 glMatrixMode (GL_PROJECTION);
1030 glOrtho( 0, w(), 0, h(), -100, 100 );
1031 glMatrixMode (GL_MODELVIEW);
1035 glDisable( GL_DEPTH_TEST );
1037 std::string clockstr = world->ClockString();
1039 clockstr.append(
" [FOLLOW MODE]" );
1041 float txtWidth = gl_width( clockstr.c_str());
1042 if( txtWidth < 200 ) txtWidth = 200;
1043 int txtHeight = gl_height();
1045 const int margin = 5;
1047 width = txtWidth + 2 * margin;
1048 height = txtHeight + 2 * margin;
1052 glRectf( 0, 0, width, height );
1062 glRectf( 0, height, width, 90 );
1065 world->EnergyString().c_str(),
1066 (Fl_Align)( FL_ALIGN_LEFT | FL_ALIGN_BOTTOM) );
1071 glEnable( GL_DEPTH_TEST );
1075 glMatrixMode (GL_PROJECTION);
1077 glMatrixMode (GL_MODELVIEW);
1090 glMatrixMode (GL_PROJECTION);
1093 glOrtho( 0, w(), 0, h(), -100, 100 );
1094 glMatrixMode (GL_MODELVIEW);
1098 glDisable( GL_DEPTH_TEST );
1103 glEnable( GL_DEPTH_TEST );
1105 glMatrixMode (GL_PROJECTION);
1107 glMatrixMode (GL_MODELVIEW);
1123 static std::vector<uint8_t> pixels;
1124 pixels.resize( width * height * depth );
1128 glReadPixels( 0,0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0] );
1130 static uint32_t count = 0;
1132 snprintf( filename, 63,
"stage-%06d.png", count++ );
1134 FILE *fp = fopen( filename,
"wb" );
1141 png_structp pp = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
1143 png_infop info = png_create_info_struct(pp);
1147 png_init_io(pp, fp);
1150 png_bytep rowpointers[height];
1151 for(
int i=0; i<height; i++ )
1152 rowpointers[i] = &pixels[ (height-1-i) * width * depth ];
1154 png_set_rows( pp, info, rowpointers );
1156 png_set_IHDR( pp, info,
1158 PNG_COLOR_TYPE_RGBA,
1160 PNG_COMPRESSION_TYPE_DEFAULT,
1161 PNG_FILTER_TYPE_DEFAULT);
1163 png_write_png( pp, info, PNG_TRANSFORM_IDENTITY, NULL );
1166 png_destroy_write_struct(&pp, &info);
1170 printf(
"Saved %s\n", filename );
1185 canvas->invalidate();
1243 Fl::add_timeout( ((
double)
interval/1000),
1302 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
1326 Fl_Gl_Window::resize(X,Y,W,H);
Bounds y
volume extent along y axis, initially zero
GLuint loadTexture(const char *filename)
load a texture on the GPU, returned value is the texture ID, or 0 for failure
void Save(Worldfile *wf, int sec)
virtual void Draw(void) const =0
double max
largest value in range, initially zero
The Stage library uses its own namespace.
static const int checkImageWidth
void setPose(double x, double y)
std::list< Model * > models_sorted
static bool texture_load_done
void setDirtyBuffer(void)
static joules_t global_capacity
virtual void DrawPicker()
void AddToPose(const Pose &pose)
void Load(Worldfile *wf, int sec)
void forward(double amount)
static TextureManager & getInstance(void)
void EraseAll(T thing, C &cont)
double min
smallest value in range, initially zero
virtual int handle(int event)
void createMenuItems(Fl_Menu_Bar *menu, std::string path)
void draw_string_multiline(float x, float y, float w, float h, const char *string, Fl_Align align)
void setPose(double x, double y, double z)
Canvas(WorldGui *world, int x, int y, int width, int height)
PerspectiveCamera perspective_camera
void DataVisualizeTree(Camera *cam)
void PushColor(Color col)
void Save(Worldfile *wf, int sec)
void Save(Worldfile *wf, int section)
void WriteInt(int entity, const char *name, int value)
void scale(double scale, double shift_x=0, double h=0, double shift_y=0, double w=0)
static GLubyte checkImage[checkImageHeight][checkImageWidth][4]
void FixViewport(int W, int H)
int screenshot_frame_skip
void CanvasToWorld(int px, int py, double *wx, double *wy, double *wz)
Pose GetGlobalPose() const
bool operator()(const Model *a, const Model *b) const
void addPitch(double pitch)
virtual void SetProjection(double pixels_width, double pixels_height, double y_min, double y_max)
const bounds3d_t & GetExtent() const
void createMenuItem(Fl_Menu_Bar *menu, std::string path)
void RemoveModel(Model *mod)
void addPitch(double pitch)
bool dirtyBuffer(void) const
DistFuncObj(meters_t x, meters_t y)
virtual void SetProjection(void) const =0
void draw_string(float x, float y, float z, const char *string)
static Model * LookupId(uint32_t id)
Bounds x
volume extent along x axis, intially zero
static std::string findFile(const std::string &filename)
void menuCallback(Fl_Callback *cb, Fl_Widget *w)
bool paused
if true, the simulation is stopped
virtual void SetProjection(void) const
void Push(double r, double g, double b, double a=1.0)
Model * getModel(int x, int y)
void strafe(double amount)
void AddModel(Model *mod)
void setScale(double scale)
static void perspectiveCb(Fl_Widget *w, void *p)
void Save(Worldfile *wf, int section)
static const int checkImageHeight
void Load(Worldfile *wf, int section)
std::list< Model * > selected_models
void Load(Worldfile *wf, int sec)
void DrawBoundingBoxTree()
void Load(Worldfile *wf, int section)
int ReadInt(int entity, const char *name, int value)
class Stg::Model::GuiState gui
radians_t a
rotation about the z axis.
unsigned long frames_rendered_count
void setAspect(double aspect)
update vertical fov based on window aspect and current horizontal fov
void move(double x, double y, double z)
msec_t interval
(even if it is now unselected).
class Stg::Canvas::GlColorStack colorstack
void move(double x, double y)
bool selected(Model *mod)
void resize(int X, int Y, int W, int H)
virtual void renderFrame()
const char * Token() const
static void TimerCallback(Canvas *canvas)
void unSelect(Model *mod)