diff --git a/Common/CMakeLists.txt b/Common/CMakeLists.txt index d6277d210116f9314db66f10fbb67b9ce4773108..7a0c54c48607aed199869b22ff086e99100be0f3 100644 --- a/Common/CMakeLists.txt +++ b/Common/CMakeLists.txt @@ -23,6 +23,7 @@ set(SRC TreeUtils.cpp avl.cpp MallocUtils.cpp onelabUtils.cpp + GamePad.cpp ) file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h) diff --git a/Common/Context.cpp b/Common/Context.cpp index 4af6665233c6fe05afb714207367bbd9960516e5..72523b278e9f86d5f85dd2028df09a17da1b021f 100644 --- a/Common/Context.cpp +++ b/Common/Context.cpp @@ -19,7 +19,6 @@ CTX::CTX() short int word = 0x0001; char *byte = (char*)&word; bigEndian = (byte[0] ? 0 : 1); - const char *tmp; if((tmp = GetEnvironmentVar("GMSH_HOME"))) homeDir = tmp; @@ -59,6 +58,9 @@ CTX::CTX() post.draw = 1; post.combineTime = 0; // try to combineTime views at startup lock = 0; // very primitive locking + /// + fileread=false; + /// #if defined(HAVE_FLTK) glFontEnum = FL_HELVETICA; diff --git a/Common/Context.h b/Common/Context.h index 5e9b0f3e1c019765683a288edff4cc05e68a9d50..f5c79550cc1ef3e7b0ae8209d1065284164264af 100644 --- a/Common/Context.h +++ b/Common/Context.h @@ -11,6 +11,9 @@ #include <string> #include "CGNSOptions.h" #include "meshPartitionOptions.h" +/// +#include "GamePad.h" +/// // The interface-independent context. @@ -137,11 +140,12 @@ class CTX { double min[3], max[3]; // "center of mass" of the current geometry, used for graphics only double cg[3]; - // characteristic length for the whole problem (never used in mesh + // characteristic length for the whole problem (never used in mesh // generation ->only for geo/post) double lc; // double buffer/antialias/stereo graphics? - int db, antialiasing, stereo, camera; + int db, antialiasing, stereo, camera ; + bool fileread; ; double eye_sep_ratio,focallength_ratio,camera_aperture; // orthogonal projection? int ortho; @@ -256,6 +260,8 @@ class CTX { unsigned int tangents, normals; } mesh; } color; + // listen to a USB gamepad + GamePad gamepad; // is the machine big-endian? int bigEndian; // how RGBA values are packed and unpacked into/from an unsigned integer to be diff --git a/Common/GamePad.cpp b/Common/GamePad.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5b3467d060b65039106f154e8585c19b950bb805 --- /dev/null +++ b/Common/GamePad.cpp @@ -0,0 +1,199 @@ +// Gmsh - Copyright (C) 1997-2013 C. Geuzaine, J.-F. Remacle +// +// See the LICENSE.txt file for license information. Please report all +// bugs and problems to the public mailing list <gmsh@geuz.org>. +// +// Contributed by Gilles Marckmann <gilles.marckmann@ec-nantes.fr> + + +#if defined(WIN32) + + + #include <cstring> + #include <string> + #include <iostream> + #include <stdio.h> + #include "GamePad.h" + #include "Context.h" + #include <unistd.h> + + GamePad::GamePad() : active(false), frequency(.01), gamepad_fd(0) { + for (int i=0;i<9;i++) button_map[i]=i; + for (int i=0;i<7;i++) axe_map[i]=i; + axe_map[6]=1; + // other recognized map "Thrustmaster Run'N' Drive Wireless PS3" + if ( strcmp(name,"Thrustmaster Run'N' Drive Wireless PS3" ) == 0){ + button_map[0]=1; + button_map[1]=0; + button_map[5]=6; + button_map[6]=5; + } + } + + GamePad::~GamePad() { gamepad_fd = 0;} + + bool GamePad::toggle(const int _nbut) { + bool res; + if( toggle_status[_nbut] ){ res = true; toggle_status[_nbut]=false;} + else { res=false; } + return res; + } + + int GamePad::read_event() { return 1;} + + void GamePad::affiche() {} + + + + +#else // if !win32 => if linux/apple + + #include <cstring> + #include <string> + #include <iostream> + #include <stdio.h> + #include "GamePad.h" + #include "Context.h" + #include <unistd.h> + + GamePad::GamePad() : active(false), frequency(.01), gamepad_fd(0) { + gamepad_fd = open(GAMEPAD_DEV, O_RDONLY | O_NONBLOCK); + if (gamepad_fd > 0) { + ioctl(gamepad_fd, JSIOCGNAME(256), name); + ioctl(gamepad_fd, JSIOCGVERSION, &version); + ioctl(gamepad_fd, JSIOCGAXES, &axes); + ioctl(gamepad_fd, JSIOCGBUTTONS, &buttons); + std::cout << "Joystick/Gamepad detected: " << name ; + std::cout << " (version " << version << " / " ; + std::cout << (int)axes <<" axes /" ; + std::cout << (int)buttons <<" buttons)" << std::endl; + active = true; + } + + // default map is "THRUSTMASTER FireStorm Dual Power"-like + // + // ###### ###### + // # but5 # # but7 # + // .########.. ..#######. + // ............ .......... . + // ...#######... ...########.. + // ..# but4 #... ...# but6 #.. + // ...########....... but9 but10........#########.. + // .................... ..................... + // .......#................... .......................... + // ......axis5..........................................####....... + // ........ #...........................................# b3 #....... + // ..........#...........................................# #....... + // ...###< axis4 >###...............................####..####..####... + // ...........#.....................................# b1 #......# b2 #... + // ............#.....................................# #......# #.... + // ............#......................................####........####..... + // .............#.............................................####........... + // ..........................................................# b0 #.......... + // ...........................................................# #........... + // .......................#######................#######.......####............ + // ......................# axis1 ##............## axis3 ##...................... + // .....................## | ##..........## | ##..................... + // ......................#<--axis0-->#..........#<--axis2--> #..................... + // ......................## | ##. .####. .## | ##...................... + // .......................## | ##.. # b8 #...## | ##....................... + // ..........................#######......####......#######......................... + // .................................................................................. + // ..................... .......... ......... ..................... + // .................... .................... + // .................. .................. + // .................. .................. + // .................. ................. + // ................. ................ + // ................ ............... + // .............. .............. + // ............. ............ + // ............ ............ + // .......... .......... + // ....... ........ + // .... ... + // + + for (int i=0;i<9;i++) button_map[i]=i; + for (int i=0;i<7;i++) axe_map[i]=i; + axe_map[6]=1; + + + // other recognized map "Thrustmaster Run'N' Drive Wireless PS3" + if ( strcmp(name,"Thrustmaster Run'N' Drive Wireless PS3" ) == 0){ + button_map[0]=1; + button_map[1]=0; + button_map[5]=6; + button_map[6]=5; + } + + } + + GamePad::~GamePad() { + if (gamepad_fd > 0) { active = false; close(gamepad_fd); } + gamepad_fd = 0; + } + + bool GamePad::toggle(const int _nbut) { + bool res; + if( toggle_status[_nbut] ){ res = true; toggle_status[_nbut]=false;} + else { res=false; } + return res; + } + + int GamePad::read_event() { + int result = read(gamepad_fd, &event, sizeof(event)) ; + if (result > 0) + { + // time( &rawtime ); + switch (event.type) + { + case JS_EVENT_INIT: + break; + case JS_EVENT_INIT | JS_EVENT_AXIS: + break; + case JS_EVENT_INIT | JS_EVENT_BUTTON: + break; + case JS_EVENT_AXIS: + // std::cout<< "------"<<rawtime<<"---- " <<std::endl; + axe[(int)event.number]=(double)event.value/32767. ; + break; + case JS_EVENT_BUTTON: + // std::cout<< "------"<<rawtime<<"---- " <<std::endl; + if(button[(int)event.number]==0. && (bool)event.value) + { toggle_status[(int)event.number]=true; } + button[(int)event.number]=(bool)event.value ; + + break; + default: + break; + } + } + // std::cout<< "------"<<rawtime<<"---- " <<std::endl; + // else if (event_read){changed=false;} + return 1; + + } + + + void GamePad::affiche() { + // printf ("----------------------------------------------\n"); + for (int i=0;i<axes;i++) printf ("___________"); + printf ("\n"); + for (int i=0;i<axes;i++) printf (" axis %2d |",i); + printf ("\n"); + for (int i=0;i<axes;i++) printf (" %7f |", axe[i] ); + printf ("\n"); + for (int i=0;i<buttons;i++) printf ("_______"); + printf ("\n"); + for (int i=0;i<buttons;i++) printf (" b.%2d |",i); + printf ("\n"); + for (int i=0;i<buttons;i++) printf (" %4d |",button[i]); + printf ("\n"); + for (int i=0;i<buttons;i++) printf ("_______"); + printf ("\n"); + } + + + +#endif // win32 diff --git a/Common/GamePad.h b/Common/GamePad.h new file mode 100644 index 0000000000000000000000000000000000000000..a57d53a3d73499e613c164497eac894e13f67990 --- /dev/null +++ b/Common/GamePad.h @@ -0,0 +1,83 @@ +// Gmsh - Copyright (C) 1997-2013 C. Geuzaine, J.-F. Remacle +// +// See the LICENSE.txt file for license information. Please report all +// bugs and problems to the public mailing list <gmsh@geuz.org>. +// +// Contributed by Gilles Marckmann <gilles.marckmann@ec-nantes.fr> + +#ifndef _GAMEPAD_H_ +#define _GAMEPAD_H_ + +#define GP_RANGE 1.0 +#define GP_DEV 16 +#define GP_BUTTONS 32 +#define GP_AXES 6 + + + +#if defined(WIN32) + + class GamePad { + public: + bool active; + bool toggle_status[GP_BUTTONS]; + bool event_read; + double frequency; + GamePad(); + ~GamePad(); + double axe[GP_AXES]; + bool button[GP_BUTTONS]; + bool toggle(const int _nbut); + int read_event(); + void affiche(); + int button_map[10]; + int axe_map[8]; + private: + int gamepad_fd; + // js_event event; + // __u32 version; + // __u8 axes; + // __u8 buttons; + char name[256]; + }; + + + +#else // !win32 => linux/apple + + + #include <linux/joystick.h> + #include <fcntl.h> + + #define GAMEPAD_DEV "/dev/input/js0" + + class GamePad { + public: + bool active; + bool toggle_status[GP_BUTTONS]; + bool event_read; + double frequency; + GamePad(); + ~GamePad(); + double axe[GP_AXES]; + bool button[GP_BUTTONS]; + bool toggle(const int _nbut); + int read_event(); + void affiche(); + int button_map[10]; + int axe_map[8]; + + + private: + // time_t rawtime; + int gamepad_fd; + js_event event; + __u32 version; + __u8 axes; + __u8 buttons; + char name[256]; + }; + +#endif //win32 + +#endif // _GAMEPAD_H_ diff --git a/Common/OpenFile.cpp b/Common/OpenFile.cpp index 6d32978dc62bb14ab4f2c1ec48dbb95b2fd3089a..63905e6942ded8797d34667ac990a5a2367d88de 100644 --- a/Common/OpenFile.cpp +++ b/Common/OpenFile.cpp @@ -100,6 +100,7 @@ void SetBoundingBox(double xmin, double xmax, SQU(CTX::instance()->max[2] - CTX::instance()->min[2])); for(int i = 0; i < 3; i++) CTX::instance()->cg[i] = 0.5 * (CTX::instance()->min[i] + CTX::instance()->max[i]); + } void SetBoundingBox(bool aroundVisible) @@ -116,7 +117,6 @@ void SetBoundingBox(bool aroundVisible) bb += PView::list[i]->getData()->getBoundingBox(); } #endif - if(bb.empty()){ bb += SPoint3(-1., -1., -1.); bb += SPoint3(1., 1., 1.); @@ -131,8 +131,8 @@ void SetBoundingBox(bool aroundVisible) SQU(CTX::instance()->max[2] - CTX::instance()->min[2])); for(int i = 0; i < 3; i++) CTX::instance()->cg[i] = 0.5 * (CTX::instance()->min[i] + CTX::instance()->max[i]); -} +} // FIXME: this is necessary for now to have an approximate // CTX::instance()->lc *while* parsing input files (it's important // since some of the geometrical operations use a tolerance that @@ -463,7 +463,6 @@ int MergeFile(const std::string &fileName, bool warnIfMissing) ComputeMaxEntityNum(); SetBoundingBox(); - CTX::instance()->geom.draw = 1; CTX::instance()->mesh.changed = ENT_ALL; @@ -481,7 +480,7 @@ int MergeFile(const std::string &fileName, bool warnIfMissing) if(!status) Msg::Error("Error loading '%s'", fileName.c_str()); Msg::StatusBar(true, "Done reading '%s'", fileName.c_str()); - + CTX::instance()->fileread=true; // merge the associated option file if there is one if(!StatFile(fileName + ".opt")) MergeFile(fileName + ".opt"); diff --git a/Common/Options.cpp b/Common/Options.cpp index b5fff7e397a67fc7abda4be1f198b30195abf118..fa1671862f3f6b4fa24d532216882f86db70824b 100644 --- a/Common/Options.cpp +++ b/Common/Options.cpp @@ -3143,8 +3143,7 @@ double opt_general_stereo_mode(OPT_ARGS_NUM) { if(action & GMSH_SET) CTX::instance()->stereo = (int)val; - if (CTX::instance()->stereo) // when stereo mode is active camera mode is obligatory - opt_general_camera_mode(num, action, 1.); + if (CTX::instance()->stereo) opt_general_camera_mode(num, action, 1.); #if defined(HAVE_FLTK) if(FlGui::available() && (action & GMSH_GUI)) FlGui::instance()->options->general.butt[17]->value(CTX::instance()->stereo); @@ -3202,6 +3201,7 @@ double opt_general_camera_mode(OPT_ARGS_NUM) return CTX::instance()->camera ; } + double opt_general_clip0a(OPT_ARGS_NUM) { if(action & GMSH_SET) diff --git a/Fltk/CMakeLists.txt b/Fltk/CMakeLists.txt index 9b223d38bb4c31e088da38deabc2c390618abb89..482a976a69bcc3efe160cc10137de6582e544e1b 100644 --- a/Fltk/CMakeLists.txt +++ b/Fltk/CMakeLists.txt @@ -9,6 +9,7 @@ set(SRC openglWindow.cpp optionWindow.cpp colorbarWindow.cpp + gamepadWindow.cpp fieldWindow.cpp pluginWindow.cpp statisticsWindow.cpp @@ -26,6 +27,7 @@ set(SRC onelabGroup.cpp inputRegion.cpp viewButton.cpp + Navigator.cpp ) file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h) diff --git a/Fltk/FlGui.cpp b/Fltk/FlGui.cpp index 5908e835371b4a3a88ca92c90ced6377e1b32e6d..c970764ff4eacb6deb7bbe5161b5bc13f9c985d5 100644 --- a/Fltk/FlGui.cpp +++ b/Fltk/FlGui.cpp @@ -202,6 +202,15 @@ static void gmsh_search(Fl_Color col) #undef bl #undef el +///// handler : read event from GAMEPAD ///////// +static void gp_handler(void *data) +{ + GamePad* gp_ptr = &(CTX::instance()->gamepad ); + gp_ptr->read_event(); + Fl::add_timeout(gp_ptr->frequency, gp_handler,data); +} +///// + FlGui::FlGui(int argc, char **argv) { // set X display @@ -219,6 +228,14 @@ FlGui::FlGui(int argc, char **argv) Fl::set_boxtype(GMSH_SIMPLE_RIGHT_BOX, simple_right_box_draw, 0, 0, 1, 0); Fl::set_boxtype(GMSH_SIMPLE_TOP_BOX, simple_top_box_draw, 0, 1, 0, 1); + /// + // add external reader for gamepad events + if (CTX::instance()->gamepad.active) { + CTX::instance()->camera = 1; + Fl::add_timeout(CTX::instance()->gamepad.frequency, gp_handler, (void*)0); + } + /// + // add global shortcuts Fl::add_handler(globalShortcut); diff --git a/Fltk/Navigator.cpp b/Fltk/Navigator.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1f08c869d2a3ea45133c3fe8b95ef456b573f809 --- /dev/null +++ b/Fltk/Navigator.cpp @@ -0,0 +1,764 @@ +// Gmsh - Copyright (C) 1997-2013 C. Geuzaine, J.-F. Remacle +// +// See the LICENSE.txt file for license information. Please report all +// bugs and problems to the public mailing list <gmsh@geuz.org>. +// +// Contributed by Gilles Marckmann <gilles.marckmann@ec-nantes.fr> + + + +#include <string> +#include <iostream> +#include <stdio.h> +#include <unistd.h> +#include <Navigator.h> +#include "Trackball.h" +#include "Context.h" +#include "drawContext.h" +#include "gl2ps.h" + +Navigator::Navigator(double _freq, drawContext* _ctx): + ax0(0.),ax1(0.),ax0_cur(0.),ax1_cur(0.),speed(0.),awake(true) + ,ctx(_ctx),frequency(_freq) +{ + ctx->camera.init(); + pad = &(CTX::instance()->gamepad); + along=AXE_Z; + mode = PEDESTRIAN; + reference_angle = 3.14*frequency/5.; + reference_speed = 1.5*frequency*(ctx->camera.Lc)/25.; +} + +Navigator::~Navigator() {} ; + +void Navigator::setDrawContext( drawContext* _ctx) { + ctx = _ctx; + ctx->camera.init(); +} + +void Navigator::setFrequency(double _freq) { + frequency = _freq; + reference_angle = 3.14*frequency/5.; + reference_speed = 1.5*frequency*(ctx->camera.Lc)/100.; +} + +void Navigator::setResponseFrequency(double _freq) { + reference_angle = 3.14*frequency/5.*(_freq/.01); + reference_speed = 1.5*frequency*(ctx->camera.Lc)/100.*(_freq/.01); +} + + +void Navigator::drawIcons() +{ + double l = CTX::instance()->smallAxesSize ; + double dx = CTX::instance()->smallAxesPos[0]+.5*l ; + double dy = 1.25*l; + + ctx->fix2dCoordinates(&dx, &dy); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLineWidth( (float)CTX::instance()->lineWidth); + gl2psLineWidth((float)(CTX::instance()->lineWidth * + CTX::instance()->print.epsLineWidthFactor)); + + glColor4ubv((GLubyte *) & CTX::instance()->color.smallAxes); + + double scale=l/100.; + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable (GL_LINE_SMOOTH); + + + switch(mode){ + case PEDESTRIAN : + glBegin(GL_LINES); + glVertex2d(dx+scale*3.01052761E+01,dy+scale* 4.07178345E+01 ); + glVertex2d(dx+scale*3.69660988E+01,dy+scale* 3.01357174E+01); + glVertex2d(dx+scale*3.69660988E+01,dy+scale* 3.01357174E+01 ); + glVertex2d(dx+scale*4.07505989E+01,dy+scale* 2.80945930E+01); + glVertex2d(dx+scale*4.07505989E+01,dy+scale* 2.80945930E+01 ); + glVertex2d(dx+scale*4.87266998E+01,dy+scale* 2.00446148E+01); + glVertex2d(dx+scale*4.87266998E+01,dy+scale* 2.00446148E+01 ); + glVertex2d(dx+scale*5.38157959E+01,dy+scale* 1.13534155E+01); + glVertex2d(dx+scale*5.38157959E+01,dy+scale* 1.13534155E+01 ); + glVertex2d(dx+scale*5.25646591E+01,dy+scale* 3.44290900E+00); + glVertex2d(dx+scale*5.25646591E+01,dy+scale* 3.44290900E+00 ); + glVertex2d(dx+scale*5.01248283E+01,dy+scale* 2.56559372E+00); + glVertex2d(dx+scale*5.01248283E+01,dy+scale* 2.56559372E+00 ); + glVertex2d(dx+scale*5.01248283E+01,dy+scale* 1.18554187E+00); + glVertex2d(dx+scale*5.01248283E+01,dy+scale* 1.18554187E+00 ); + glVertex2d(dx+scale*5.57356987E+01,dy+scale* 1.18554187E+00); + glVertex2d(dx+scale*5.57356987E+01,dy+scale* 1.18554187E+00 ); + glVertex2d(dx+scale*5.98938141E+01,dy+scale* 7.02665806E+00); + glVertex2d(dx+scale*5.98938141E+01,dy+scale* 7.02665806E+00 ); + glVertex2d(dx+scale*6.34061890E+01,dy+scale* 1.35390358E+01); + glVertex2d(dx+scale*6.34061890E+01,dy+scale* 1.35390358E+01 ); + glVertex2d(dx+scale*6.04280853E+01,dy+scale* 1.56590576E+01); + glVertex2d(dx+scale*6.04280853E+01,dy+scale* 1.56590576E+01 ); + glVertex2d(dx+scale*5.67851448E+01,dy+scale* 1.66882896E+01); + glVertex2d(dx+scale*5.67851448E+01,dy+scale* 1.66882896E+01 ); + glVertex2d(dx+scale*5.56003265E+01,dy+scale* 1.87117329E+01); + glVertex2d(dx+scale*5.56003265E+01,dy+scale* 1.87117329E+01 ); + glVertex2d(dx+scale*5.12019005E+01,dy+scale* 2.62234058E+01); + glVertex2d(dx+scale*5.12019005E+01,dy+scale* 2.62234058E+01 ); + glVertex2d(dx+scale*4.87266998E+01,dy+scale* 3.04505730E+01); + glVertex2d(dx+scale*4.87266998E+01,dy+scale* 3.04505730E+01 ); + glVertex2d(dx+scale*4.26556816E+01,dy+scale* 3.47723503E+01); + glVertex2d(dx+scale*4.26556816E+01,dy+scale* 3.47723503E+01 ); + glVertex2d(dx+scale*4.11023293E+01,dy+scale* 3.66784554E+01); + glVertex2d(dx+scale*4.11023293E+01,dy+scale* 3.66784554E+01 ); + glVertex2d(dx+scale*4.07505989E+01,dy+scale* 3.88915939E+01); + glVertex2d(dx+scale*4.07505989E+01,dy+scale* 3.88915939E+01 ); + glVertex2d(dx+scale*3.96205177E+01,dy+scale* 4.60021973E+01); + glVertex2d(dx+scale*3.96205177E+01,dy+scale* 4.60021973E+01 ); + glVertex2d(dx+scale*3.76618462E+01,dy+scale* 5.14492989E+01); + glVertex2d(dx+scale*3.76618462E+01,dy+scale* 5.14492989E+01 ); + glVertex2d(dx+scale*3.82070084E+01,dy+scale* 5.48961716E+01); + glVertex2d(dx+scale*3.82070084E+01,dy+scale* 5.48961716E+01 ); + glVertex2d(dx+scale*3.82070084E+01,dy+scale* 5.79802170E+01); + glVertex2d(dx+scale*3.82070084E+01,dy+scale* 5.79802170E+01 ); + glVertex2d(dx+scale*3.69349632E+01,dy+scale* 6.15177956E+01); + glVertex2d(dx+scale*3.69349632E+01,dy+scale* 6.15177956E+01 ); + glVertex2d(dx+scale*3.25736656E+01,dy+scale* 6.68695145E+01); + glVertex2d(dx+scale*3.25736656E+01,dy+scale* 6.68695145E+01 ); + glVertex2d(dx+scale*3.18467827E+01,dy+scale* 7.03163834E+01); + glVertex2d(dx+scale*3.18467827E+01,dy+scale* 7.03163834E+01 ); + glVertex2d(dx+scale*3.38457108E+01,dy+scale* 7.73915405E+01); + glVertex2d(dx+scale*3.38457108E+01,dy+scale* 7.73915405E+01 ); + glVertex2d(dx+scale*3.38457108E+01,dy+scale* 8.45574112E+01); + glVertex2d(dx+scale*3.38457108E+01,dy+scale* 8.45574112E+01 ); + glVertex2d(dx+scale*3.38457108E+01,dy+scale* 8.58094559E+01); + glVertex2d(dx+scale*3.45101509E+01,dy+scale* 5.14492989E+01 ); + glVertex2d(dx+scale*3.01052761E+01,dy+scale* 4.07178345E+01); + glVertex2d(dx+scale*1.95475960E+01,dy+scale* 7.45358734E+01 ); + glVertex2d(dx+scale*2.16000557E+01,dy+scale* 6.88279419E+01); + glVertex2d(dx+scale*2.16000557E+01,dy+scale* 6.88279419E+01 ); + glVertex2d(dx+scale*2.16000557E+01,dy+scale* 6.32443161E+01); + glVertex2d(dx+scale*2.16000557E+01,dy+scale* 6.32443161E+01 ); + glVertex2d(dx+scale*2.39542980E+01,dy+scale* 5.92237206E+01); + glVertex2d(dx+scale*2.39542980E+01,dy+scale* 5.92237206E+01 ); + glVertex2d(dx+scale*2.06011562E+01,dy+scale* 5.10545654E+01); + glVertex2d(dx+scale*2.06011562E+01,dy+scale* 5.10545654E+01 ); + glVertex2d(dx+scale*1.91084385E+01,dy+scale* 4.16166077E+01); + glVertex2d(dx+scale*1.91084385E+01,dy+scale* 4.16166077E+01 ); + glVertex2d(dx+scale*1.89741859E+01,dy+scale* 3.61561012E+01); + glVertex2d(dx+scale*1.89741859E+01,dy+scale* 3.61561012E+01 ); + glVertex2d(dx+scale*1.80558548E+01,dy+scale* 3.29056969E+01); + glVertex2d(dx+scale*1.80558548E+01,dy+scale* 3.29056969E+01 ); + glVertex2d(dx+scale*1.80558548E+01,dy+scale* 2.96775036E+01); + glVertex2d(dx+scale*1.80558548E+01,dy+scale* 2.96775036E+01 ); + glVertex2d(dx+scale*1.72696590E+01,dy+scale* 2.55330906E+01); + glVertex2d(dx+scale*1.72696590E+01,dy+scale* 2.55330906E+01 ); + glVertex2d(dx+scale*1.53084030E+01,dy+scale* 1.60425396E+01); + glVertex2d(dx+scale*1.53084030E+01,dy+scale* 1.60425396E+01 ); + glVertex2d(dx+scale*1.19248409E+01,dy+scale* 9.76899910E+00); + glVertex2d(dx+scale*1.19248409E+01,dy+scale* 9.76899910E+00 ); + glVertex2d(dx+scale*1.04403715E+01,dy+scale* 1.05696316E+01); + glVertex2d(dx+scale*1.04403715E+01,dy+scale* 1.05696316E+01 ); + glVertex2d(dx+scale*7.35945797E+00,dy+scale* 8.76561642E+00); + glVertex2d(dx+scale*7.35945797E+00,dy+scale* 8.76561642E+00 ); + glVertex2d(dx+scale*4.11787891E+00,dy+scale* 8.65881157E+00); + glVertex2d(dx+scale*4.11787891E+00,dy+scale* 8.65881157E+00 ); + glVertex2d(dx+scale*1.94821942E+00,dy+scale* 9.27180004E+00); + glVertex2d(dx+scale*1.94821942E+00,dy+scale* 9.27180004E+00 ); + glVertex2d(dx+scale*2.77175337E-01,dy+scale* 8.18839359E+00); + glVertex2d(dx+scale*2.77175337E-01,dy+scale* 8.18839359E+00 ); + glVertex2d(dx+scale*1.94821942E+00,dy+scale* 5.61097956E+00); + glVertex2d(dx+scale*1.94821942E+00,dy+scale* 5.61097956E+00 ); + glVertex2d(dx+scale*6.22622919E+00,dy+scale* 2.56559372E+00); + glVertex2d(dx+scale*6.22622919E+00,dy+scale* 2.56559372E+00 ); + glVertex2d(dx+scale*1.11108894E+01,dy+scale* 1.18554187E+00); + glVertex2d(dx+scale*1.11108894E+01,dy+scale* 1.18554187E+00 ); + glVertex2d(dx+scale*1.72696590E+01,dy+scale* 1.18554187E+00); + glVertex2d(dx+scale*1.72696590E+01,dy+scale* 1.18554187E+00 ); + glVertex2d(dx+scale*1.72696590E+01,dy+scale* 7.02665806E+00); + glVertex2d(dx+scale*1.72696590E+01,dy+scale* 7.02665806E+00 ); + glVertex2d(dx+scale*1.65164566E+01,dy+scale* 8.18839359E+00); + glVertex2d(dx+scale*1.65164566E+01,dy+scale* 8.18839359E+00 ); + glVertex2d(dx+scale*2.46518440E+01,dy+scale* 2.32723999E+01); + glVertex2d(dx+scale*2.46518440E+01,dy+scale* 2.32723999E+01 ); + glVertex2d(dx+scale*2.46518440E+01,dy+scale* 3.04505730E+01); + glVertex2d(dx+scale*2.46518440E+01,dy+scale* 3.04505730E+01 ); + glVertex2d(dx+scale*2.58728657E+01,dy+scale* 3.47723503E+01); + glVertex2d(dx+scale*2.58728657E+01,dy+scale* 3.47723503E+01 ); + glVertex2d(dx+scale*3.01052761E+01,dy+scale* 4.07178345E+01); + glVertex2d(dx+scale*2.75617714E+01,dy+scale* 8.75848465E+01 ); + glVertex2d(dx+scale*3.76618462E+01,dy+scale* 8.47312927E+01); + glVertex2d(dx+scale*3.76618462E+01,dy+scale* 8.47312927E+01 ); + glVertex2d(dx+scale*3.92328835E+01,dy+scale* 8.36129227E+01); + glVertex2d(dx+scale*3.92328835E+01,dy+scale* 8.36129227E+01 ); + glVertex2d(dx+scale*4.11023293E+01,dy+scale* 7.90666428E+01); + glVertex2d(dx+scale*4.11023293E+01,dy+scale* 7.90666428E+01 ); + glVertex2d(dx+scale*4.46455917E+01,dy+scale* 7.30154266E+01); + glVertex2d(dx+scale*4.46455917E+01,dy+scale* 7.30154266E+01 ); + glVertex2d(dx+scale*4.62260017E+01,dy+scale* 7.03163834E+01); + glVertex2d(dx+scale*4.62260017E+01,dy+scale* 7.03163834E+01 ); + glVertex2d(dx+scale*4.56109505E+01,dy+scale* 6.64276276E+01); + glVertex2d(dx+scale*4.56109505E+01,dy+scale* 6.64276276E+01 ); + glVertex2d(dx+scale*4.56109505E+01,dy+scale* 6.53531952E+01); + glVertex2d(dx+scale*4.56109505E+01,dy+scale* 6.53531952E+01 ); + glVertex2d(dx+scale*4.87266998E+01,dy+scale* 6.36727524E+01); + glVertex2d(dx+scale*4.87266998E+01,dy+scale* 6.36727524E+01 ); + glVertex2d(dx+scale*5.15070915E+01,dy+scale* 6.64276276E+01); + glVertex2d(dx+scale*5.15070915E+01,dy+scale* 6.64276276E+01 ); + glVertex2d(dx+scale*5.15070915E+01,dy+scale* 6.88279419E+01); + glVertex2d(dx+scale*5.15070915E+01,dy+scale* 6.88279419E+01 ); + glVertex2d(dx+scale*4.95096855E+01,dy+scale* 7.22391281E+01); + glVertex2d(dx+scale*4.95096855E+01,dy+scale* 7.22391281E+01 ); + glVertex2d(dx+scale*4.58495522E+01,dy+scale* 8.24180374E+01); + glVertex2d(dx+scale*4.58495522E+01,dy+scale* 8.24180374E+01 ); + glVertex2d(dx+scale*4.32594948E+01,dy+scale* 8.68413620E+01); + glVertex2d(dx+scale*4.32594948E+01,dy+scale* 8.68413620E+01 ); + glVertex2d(dx+scale*4.18205223E+01,dy+scale* 8.72479095E+01); + glVertex2d(dx+scale*4.18205223E+01,dy+scale* 8.72479095E+01 ); + glVertex2d(dx+scale*3.02508583E+01,dy+scale* 9.19968338E+01); + glVertex2d(dx+scale*3.02508583E+01,dy+scale* 9.19968338E+01 ); + glVertex2d(dx+scale*2.86896305E+01,dy+scale* 9.26376648E+01); + glVertex2d(dx+scale*2.86896305E+01,dy+scale* 9.26376648E+01 ); + glVertex2d(dx+scale*2.80653210E+01,dy+scale* 9.37038651E+01); + glVertex2d(dx+scale*2.80653210E+01,dy+scale* 9.37038651E+01 ); + glVertex2d(dx+scale*2.71819935E+01,dy+scale* 9.52124176E+01); + glVertex2d(dx+scale*2.71819935E+01,dy+scale* 9.52124176E+01 ); + glVertex2d(dx+scale*2.96779137E+01,dy+scale* 9.61099014E+01); + glVertex2d(dx+scale*2.96779137E+01,dy+scale* 9.61099014E+01 ); + glVertex2d(dx+scale*3.02764988E+01,dy+scale* 9.90064621E+01); + glVertex2d(dx+scale*3.02764988E+01,dy+scale* 9.90064621E+01 ); + glVertex2d(dx+scale*2.92283592E+01,dy+scale* 1.05601486E+02); + glVertex2d(dx+scale*2.92283592E+01,dy+scale* 1.05601486E+02 ); + glVertex2d(dx+scale*2.25053406E+01,dy+scale* 1.08361038E+02); + glVertex2d(dx+scale*2.25053406E+01,dy+scale* 1.08361038E+02 ); + glVertex2d(dx+scale*1.72556629E+01,dy+scale* 1.05287109E+02); + glVertex2d(dx+scale*1.72556629E+01,dy+scale* 1.05287109E+02 ); + glVertex2d(dx+scale*1.52413979E+01,dy+scale* 9.81576691E+01); + glVertex2d(dx+scale*1.52413979E+01,dy+scale* 9.81576691E+01 ); + glVertex2d(dx+scale*1.72696590E+01,dy+scale* 9.25170364E+01); + glVertex2d(dx+scale*1.72696590E+01,dy+scale* 9.25170364E+01 ); + glVertex2d(dx+scale*2.16000557E+01,dy+scale* 9.32052612E+01); + glVertex2d(dx+scale*2.16000557E+01,dy+scale* 9.32052612E+01 ); + glVertex2d(dx+scale*2.31259499E+01,dy+scale* 8.89617233E+01); + glVertex2d(dx+scale*2.31259499E+01,dy+scale* 8.89617233E+01 ); + glVertex2d(dx+scale*2.01361866E+01,dy+scale* 8.34183350E+01); + glVertex2d(dx+scale*2.01361866E+01,dy+scale* 8.34183350E+01 ); + glVertex2d(dx+scale*1.86794548E+01,dy+scale* 8.07173691E+01); + glVertex2d(dx+scale*1.86794548E+01,dy+scale* 8.07173691E+01 ); + glVertex2d(dx+scale*1.86794548E+01,dy+scale* 7.69501953E+01); + glVertex2d(dx+scale*1.86794548E+01,dy+scale* 7.69501953E+01 ); + glVertex2d(dx+scale*1.98941078E+01,dy+scale* 7.35722198E+01); + glVertex2d(dx+scale*1.38444281E+01,dy+scale* 7.19181519E+01 ); + glVertex2d(dx+scale*1.31145697E+01,dy+scale* 7.24377136E+01); + glVertex2d(dx+scale*1.31145697E+01,dy+scale* 7.24377136E+01 ); + glVertex2d(dx+scale*7.04405022E+00,dy+scale* 7.85644531E+01); + glVertex2d(dx+scale*7.04405022E+00,dy+scale* 7.85644531E+01 ); + glVertex2d(dx+scale*6.26990461E+00,dy+scale* 8.07173691E+01); + glVertex2d(dx+scale*6.26990461E+00,dy+scale* 8.07173691E+01 ); + glVertex2d(dx+scale*6.94693804E+00,dy+scale* 8.31137161E+01); + glVertex2d(dx+scale*6.94693804E+00,dy+scale* 8.31137161E+01 ); + glVertex2d(dx+scale*6.52368259E+00,dy+scale* 8.57768860E+01); + glVertex2d(dx+scale*6.52368259E+00,dy+scale* 8.57768860E+01 ); + glVertex2d(dx+scale*5.51406002E+00,dy+scale* 8.63214188E+01); + glVertex2d(dx+scale*5.51406002E+00,dy+scale* 8.63214188E+01 ); + glVertex2d(dx+scale*2.57401466E+00,dy+scale* 8.62266617E+01); + glVertex2d(dx+scale*2.57401466E+00,dy+scale* 8.62266617E+01 ); + glVertex2d(dx+scale*2.63223171E-01,dy+scale* 8.29805756E+01); + glVertex2d(dx+scale*2.63223171E-01,dy+scale* 8.29805756E+01 ); + glVertex2d(dx+scale*5.74481070E-01,dy+scale* 8.10221024E+01); + glVertex2d(dx+scale*5.74481070E-01,dy+scale* 8.10221024E+01 ); + glVertex2d(dx+scale*3.50635505E+00,dy+scale* 7.89349899E+01); + glVertex2d(dx+scale*3.50635505E+00,dy+scale* 7.89349899E+01 ); + glVertex2d(dx+scale*4.06134844E+00,dy+scale* 7.73915405E+01); + glVertex2d(dx+scale*4.06134844E+00,dy+scale* 7.73915405E+01 ); + glVertex2d(dx+scale*1.02916317E+01,dy+scale* 6.82235336E+01); + glVertex2d(dx+scale*1.02916317E+01,dy+scale* 6.82235336E+01 ); + glVertex2d(dx+scale*1.35903749E+01,dy+scale* 6.68695145E+01); + glVertex2d(dx+scale*1.35903749E+01,dy+scale* 6.68695145E+01 ); + glVertex2d(dx+scale*1.50925760E+01,dy+scale* 6.74096756E+01); + glVertex2d(dx+scale*1.50925760E+01,dy+scale* 6.74096756E+01 ); + glVertex2d(dx+scale*2.02666225E+01,dy+scale* 7.25362473E+01); + glVertex2d(dx+scale*1.33335953E+01,dy+scale* 7.23014450E+01 ); + glVertex2d(dx+scale*1.86794548E+01,dy+scale* 7.88337784E+01); + glEnd(); + break; + case DIVER : + glBegin(GL_LINES); + glVertex2d(dx+scale*4.70261803E+01,dy+scale* 3.19546795E+01 ); + glVertex2d(dx+scale*4.34834213E+01,dy+scale* 3.27708626E+01); + glVertex2d(dx+scale*4.34834213E+01,dy+scale* 3.27708626E+01 ); + glVertex2d(dx+scale*4.13941002E+01,dy+scale* 3.19546795E+01); + glVertex2d(dx+scale*4.13941002E+01,dy+scale* 3.19546795E+01 ); + glVertex2d(dx+scale*3.96319656E+01,dy+scale* 3.27708626E+01); + glVertex2d(dx+scale*4.70261803E+01,dy+scale* 3.19546795E+01 ); + glVertex2d(dx+scale*6.37407417E+01,dy+scale* 2.29766846E+01); + glVertex2d(dx+scale*6.37407417E+01,dy+scale* 2.29766846E+01 ); + glVertex2d(dx+scale*6.88277817E+01,dy+scale* 2.83272076E+01); + glVertex2d(dx+scale*6.88277817E+01,dy+scale* 2.83272076E+01 ); + glVertex2d(dx+scale*7.49140625E+01,dy+scale* 3.19546795E+01); + glVertex2d(dx+scale*7.49140625E+01,dy+scale* 3.19546795E+01 ); + glVertex2d(dx+scale*7.75205078E+01,dy+scale* 3.05546646E+01); + glVertex2d(dx+scale*5.73819389E+01,dy+scale* 1.82609520E+01 ); + glVertex2d(dx+scale*6.51033478E+01,dy+scale* 1.64820938E+01); + glVertex2d(dx+scale*6.51033478E+01,dy+scale* 1.64820938E+01 ); + glVertex2d(dx+scale*6.72513809E+01,dy+scale* 1.64820938E+01); + glVertex2d(dx+scale*6.72513809E+01,dy+scale* 1.64820938E+01 ); + glVertex2d(dx+scale*6.88277817E+01,dy+scale* 1.81401482E+01); + glVertex2d(dx+scale*6.88277817E+01,dy+scale* 1.81401482E+01 ); + glVertex2d(dx+scale*7.75205078E+01,dy+scale* 3.05546646E+01); + glVertex2d(dx+scale*7.75205078E+01,dy+scale* 3.05546646E+01 ); + glVertex2d(dx+scale*7.91115646E+01,dy+scale* 3.05546646E+01); + glVertex2d(dx+scale*7.91115646E+01,dy+scale* 3.05546646E+01 ); + glVertex2d(dx+scale*7.96394882E+01,dy+scale* 3.28461914E+01); + glVertex2d(dx+scale*7.96394882E+01,dy+scale* 3.28461914E+01 ); + glVertex2d(dx+scale*8.69550934E+01,dy+scale* 3.72063484E+01); + glVertex2d(dx+scale*8.69550934E+01,dy+scale* 3.72063484E+01 ); + glVertex2d(dx+scale*9.21887970E+01,dy+scale* 3.60006065E+01); + glVertex2d(dx+scale*9.21887970E+01,dy+scale* 3.60006065E+01 ); + glVertex2d(dx+scale*9.73070221E+01,dy+scale* 4.33102036E+01); + glVertex2d(dx+scale*9.73070221E+01,dy+scale* 4.33102036E+01 ); + glVertex2d(dx+scale*9.48979111E+01,dy+scale* 4.38652153E+01); + glVertex2d(dx+scale*9.48979111E+01,dy+scale* 4.38652153E+01 ); + glVertex2d(dx+scale*7.96394882E+01,dy+scale* 3.86619072E+01); + glVertex2d(dx+scale*7.96394882E+01,dy+scale* 3.86619072E+01 ); + glVertex2d(dx+scale*7.41574936E+01,dy+scale* 3.60006065E+01); + glVertex2d(dx+scale*7.41574936E+01,dy+scale* 3.60006065E+01 ); + glVertex2d(dx+scale*7.35288086E+01,dy+scale* 3.32717209E+01); + glVertex2d(dx+scale*7.35288086E+01,dy+scale* 3.32717209E+01 ); + glVertex2d(dx+scale*7.49140625E+01,dy+scale* 3.19546795E+01); + glVertex2d(dx+scale*7.25460358E+01,dy+scale* 2.34503746E+01 ); + glVertex2d(dx+scale*7.35393219E+01,dy+scale* 2.14043198E+01); + glVertex2d(dx+scale*7.35393219E+01,dy+scale* 2.14043198E+01 ); + glVertex2d(dx+scale*7.72988739E+01,dy+scale* 2.26863708E+01); + glVertex2d(dx+scale*7.72988739E+01,dy+scale* 2.26863708E+01 ); + glVertex2d(dx+scale*8.08417358E+01,dy+scale* 1.53884392E+01); + glVertex2d(dx+scale*8.08417358E+01,dy+scale* 1.53884392E+01 ); + glVertex2d(dx+scale*9.27881927E+01,dy+scale* 5.54670620E+00); + glVertex2d(dx+scale*9.27881927E+01,dy+scale* 5.54670620E+00 ); + glVertex2d(dx+scale*1.00075905E+02,dy+scale* 8.03190613E+00); + glVertex2d(dx+scale*1.00075905E+02,dy+scale* 8.03190613E+00 ); + glVertex2d(dx+scale*8.60352936E+01,dy+scale* 1.99065475E+01); + glVertex2d(dx+scale*8.60352936E+01,dy+scale* 1.99065475E+01 ); + glVertex2d(dx+scale*7.86158524E+01,dy+scale* 2.84351845E+01); + glVertex2d(dx+scale*7.86158524E+01,dy+scale* 2.84351845E+01 ); + glVertex2d(dx+scale*7.69795456E+01,dy+scale* 2.67141228E+01); + glVertex2d(dx+scale*7.69795456E+01,dy+scale* 2.67141228E+01 ); + glVertex2d(dx+scale*7.41574936E+01,dy+scale* 2.57517700E+01); + glVertex2d(dx+scale*7.30426788E+01,dy+scale* 2.24273472E+01 ); + glVertex2d(dx+scale*7.14492264E+01,dy+scale* 2.18839607E+01); + glVertex2d(dx+scale*6.16945724E+01,dy+scale* 2.40757561E+01 ); + glVertex2d(dx+scale*6.62687149E+01,dy+scale* 2.56355934E+01); + glVertex2d(dx+scale*3.96319656E+01,dy+scale* 3.27708626E+01 ); + glVertex2d(dx+scale*2.45886974E+01,dy+scale* 3.97385635E+01); + glVertex2d(dx+scale*2.45886974E+01,dy+scale* 3.97385635E+01 ); + glVertex2d(dx+scale*2.06685200E+01,dy+scale* 3.97385635E+01); + glVertex2d(dx+scale*5.73819389E+01,dy+scale* 1.82609520E+01 ); + glVertex2d(dx+scale*5.58739510E+01,dy+scale* 2.29766846E+01); + glVertex2d(dx+scale*5.58739510E+01,dy+scale* 2.29766846E+01 ); + glVertex2d(dx+scale*5.10441551E+01,dy+scale* 2.47799721E+01); + glVertex2d(dx+scale*5.10441551E+01,dy+scale* 2.47799721E+01 ); + glVertex2d(dx+scale*3.96319656E+01,dy+scale* 3.27708626E+01); + glVertex2d(dx+scale*1.71485100E+01,dy+scale* 3.83634911E+01 ); + glVertex2d(dx+scale*2.31309643E+01,dy+scale* 3.34350243E+01); + glVertex2d(dx+scale*2.31309643E+01,dy+scale* 3.34350243E+01 ); + glVertex2d(dx+scale*3.66521492E+01,dy+scale* 3.01534729E+01); + glVertex2d(dx+scale*3.66521492E+01,dy+scale* 3.01534729E+01 ); + glVertex2d(dx+scale*4.84622536E+01,dy+scale* 2.18839607E+01); + glVertex2d(dx+scale*4.84622536E+01,dy+scale* 2.18839607E+01 ); + glVertex2d(dx+scale*5.24489517E+01,dy+scale* 1.73012562E+01); + glVertex2d(dx+scale*5.24489517E+01,dy+scale* 1.73012562E+01 ); + glVertex2d(dx+scale*5.73819389E+01,dy+scale* 1.82609520E+01); + glVertex2d(dx+scale*2.31120663E+01,dy+scale* 2.08601875E+01 ); + glVertex2d(dx+scale*2.65303173E+01,dy+scale* 1.84667053E+01); + glVertex2d(dx+scale*2.65303173E+01,dy+scale* 1.84667053E+01 ); + glVertex2d(dx+scale*2.76829071E+01,dy+scale* 1.88597527E+01); + glVertex2d(dx+scale*2.76829071E+01,dy+scale* 1.88597527E+01 ); + glVertex2d(dx+scale*2.98293095E+01,dy+scale* 2.46085243E+01); + glVertex2d(dx+scale*2.98293095E+01,dy+scale* 2.46085243E+01 ); + glVertex2d(dx+scale*2.20083504E+01,dy+scale* 2.88094444E+01); + glVertex2d(dx+scale*2.20083504E+01,dy+scale* 2.88094444E+01 ); + glVertex2d(dx+scale*1.73340797E+01,dy+scale* 3.05546646E+01); + glVertex2d(dx+scale*1.73340797E+01,dy+scale* 3.05546646E+01 ); + glVertex2d(dx+scale*1.43467293E+01,dy+scale* 3.55669289E+01); + glVertex2d(dx+scale*1.43467293E+01,dy+scale* 3.55669289E+01 ); + glVertex2d(dx+scale*1.43467293E+01,dy+scale* 3.66936073E+01); + glVertex2d(dx+scale*2.31120663E+01,dy+scale* 2.08601875E+01 ); + glVertex2d(dx+scale*1.77385178E+01,dy+scale* 2.08601875E+01); + glVertex2d(dx+scale*1.77385178E+01,dy+scale* 2.08601875E+01 ); + glVertex2d(dx+scale*1.45902586E+01,dy+scale* 2.89193249E+01); + glVertex2d(dx+scale*1.45902586E+01,dy+scale* 2.89193249E+01 ); + glVertex2d(dx+scale*1.09701309E+01,dy+scale* 3.08638268E+01); + glVertex2d(dx+scale*1.09701309E+01,dy+scale* 3.08638268E+01 ); + glVertex2d(dx+scale*1.09701309E+01,dy+scale* 3.19546795E+01); + glVertex2d(dx+scale*1.09701309E+01,dy+scale* 3.19546795E+01 ); + glVertex2d(dx+scale*1.02964087E+01,dy+scale* 2.72419567E+01); + glVertex2d(dx+scale*1.02964087E+01,dy+scale* 2.72419567E+01 ); + glVertex2d(dx+scale*1.43467293E+01,dy+scale* 1.33082447E+01); + glVertex2d(dx+scale*1.43467293E+01,dy+scale* 1.33082447E+01 ); + glVertex2d(dx+scale*1.55345182E+01,dy+scale* 9.59382534E+00); + glVertex2d(dx+scale*1.55345182E+01,dy+scale* 9.59382534E+00 ); + glVertex2d(dx+scale*1.72489243E+01,dy+scale* 9.19886017E+00); + glVertex2d(dx+scale*1.72489243E+01,dy+scale* 9.19886017E+00 ); + glVertex2d(dx+scale*1.69032230E+01,dy+scale* 1.32596684E+01); + glVertex2d(dx+scale*1.69032230E+01,dy+scale* 1.32596684E+01 ); + glVertex2d(dx+scale*1.31571884E+01,dy+scale* 2.49741650E+01); + glVertex2d(dx+scale*1.31571884E+01,dy+scale* 2.49741650E+01 ); + glVertex2d(dx+scale*1.69212170E+01,dy+scale* 2.29523678E+01); + glVertex2d(dx+scale*3.90322609E+01,dy+scale* 1.84667053E+01 ); + glVertex2d(dx+scale*5.05798721E+01,dy+scale* 1.94497623E+01); + glVertex2d(dx+scale*2.31120663E+01,dy+scale* 2.08601875E+01 ); + glVertex2d(dx+scale*3.18689404E+01,dy+scale* 1.13308659E+01); + glVertex2d(dx+scale*3.18689404E+01,dy+scale* 1.13308659E+01 ); + glVertex2d(dx+scale*3.67675819E+01,dy+scale* 1.42504940E+01); + glVertex2d(dx+scale*3.67675819E+01,dy+scale* 1.42504940E+01 ); + glVertex2d(dx+scale*3.90322609E+01,dy+scale* 1.84667053E+01); + glVertex2d(dx+scale*4.70261803E+01,dy+scale* 3.19546795E+01 ); + glVertex2d(dx+scale*4.75925865E+01,dy+scale* 3.30091743E+01); + glVertex2d(dx+scale*4.75925865E+01,dy+scale* 3.30091743E+01 ); + glVertex2d(dx+scale*4.81551323E+01,dy+scale* 3.54509926E+01); + glVertex2d(dx+scale*4.81551323E+01,dy+scale* 3.54509926E+01 ); + glVertex2d(dx+scale*4.75925865E+01,dy+scale* 3.66097794E+01); + glVertex2d(dx+scale*4.75925865E+01,dy+scale* 3.66097794E+01 ); + glVertex2d(dx+scale*4.65963593E+01,dy+scale* 3.86619072E+01); + glVertex2d(dx+scale*4.65963593E+01,dy+scale* 3.86619072E+01 ); + glVertex2d(dx+scale*2.57703133E+01,dy+scale* 4.64376678E+01); + glVertex2d(dx+scale*2.57703133E+01,dy+scale* 4.64376678E+01 ); + glVertex2d(dx+scale*2.36515903E+01,dy+scale* 4.62573013E+01); + glVertex2d(dx+scale*2.36515903E+01,dy+scale* 4.62573013E+01 ); + glVertex2d(dx+scale*2.06685200E+01,dy+scale* 4.50919800E+01); + glVertex2d(dx+scale*2.06685200E+01,dy+scale* 4.50919800E+01 ); + glVertex2d(dx+scale*2.02995567E+01,dy+scale* 4.41037750E+01); + glVertex2d(dx+scale*4.15640564E+01,dy+scale* 2.67141228E+01 ); + glVertex2d(dx+scale*3.90322609E+01,dy+scale* 1.84667053E+01); + glVertex2d(dx+scale*5.23835278E+00,dy+scale* 3.55669289E+01 ); + glVertex2d(dx+scale*3.22941685E+00,dy+scale* 3.47821503E+01); + glVertex2d(dx+scale*1.57866726E+01,dy+scale* 3.79439583E+01 ); + glVertex2d(dx+scale*1.53819942E+01,dy+scale* 4.26975594E+01); + glVertex2d(dx+scale*1.53819942E+01,dy+scale* 4.26975594E+01 ); + glVertex2d(dx+scale*1.34937668E+01,dy+scale* 4.58656845E+01); + glVertex2d(dx+scale*1.34937668E+01,dy+scale* 4.58656845E+01 ); + glVertex2d(dx+scale*9.24889469E+00,dy+scale* 4.68436165E+01); + glVertex2d(dx+scale*9.24889469E+00,dy+scale* 4.68436165E+01 ); + glVertex2d(dx+scale*6.85485315E+00,dy+scale* 4.68436165E+01); + glVertex2d(dx+scale*6.85485315E+00,dy+scale* 4.68436165E+01 ); + glVertex2d(dx+scale*2.90823507E+00,dy+scale* 4.44914017E+01); + glVertex2d(dx+scale*2.90823507E+00,dy+scale* 4.44914017E+01 ); + glVertex2d(dx+scale*2.90823507E+00,dy+scale* 4.07268143E+01); + glVertex2d(dx+scale*5.95178938E+00,dy+scale* 3.35593605E+01 ); + glVertex2d(dx+scale*5.95178938E+00,dy+scale* 3.16901569E+01); + glVertex2d(dx+scale*5.95178938E+00,dy+scale* 3.16901569E+01 ); + glVertex2d(dx+scale*7.64524508E+00,dy+scale* 3.16901569E+01); + glVertex2d(dx+scale*7.64524508E+00,dy+scale* 3.16901569E+01 ); + glVertex2d(dx+scale*1.12084312E+01,dy+scale* 3.38138428E+01); + glVertex2d(dx+scale*1.12084312E+01,dy+scale* 3.38138428E+01 ); + glVertex2d(dx+scale*1.73539886E+01,dy+scale* 3.62145729E+01); + glVertex2d(dx+scale*1.73539886E+01,dy+scale* 3.62145729E+01 ); + glVertex2d(dx+scale*2.15019493E+01,dy+scale* 3.78349495E+01); + glVertex2d(dx+scale*2.15019493E+01,dy+scale* 3.78349495E+01 ); + glVertex2d(dx+scale*2.46490135E+01,dy+scale* 3.97106285E+01); + glVertex2d(dx+scale*2.46490135E+01,dy+scale* 3.97106285E+01 ); + glVertex2d(dx+scale*2.73888340E+01,dy+scale* 4.13435822E+01); + glVertex2d(dx+scale*2.73888340E+01,dy+scale* 4.13435822E+01 ); + glVertex2d(dx+scale*2.86334686E+01,dy+scale* 4.46771202E+01); + glVertex2d(dx+scale*2.86334686E+01,dy+scale* 4.46771202E+01 ); + glVertex2d(dx+scale*2.71944695E+01,dy+scale* 4.76413078E+01); + glVertex2d(dx+scale*2.71944695E+01,dy+scale* 4.76413078E+01 ); + glVertex2d(dx+scale*2.39893608E+01,dy+scale* 4.83796997E+01); + glVertex2d(dx+scale*2.39893608E+01,dy+scale* 4.83796997E+01 ); + glVertex2d(dx+scale*1.62659492E+01,dy+scale* 4.59099236E+01); + glVertex2d(dx+scale*1.62659492E+01,dy+scale* 4.59099236E+01 ); + glVertex2d(dx+scale*1.52036419E+01,dy+scale* 4.47925949E+01); + glVertex2d(dx+scale*1.52036419E+01,dy+scale* 4.47925949E+01 ); + glVertex2d(dx+scale*1.52036419E+01,dy+scale* 4.29968033E+01); + glVertex2d(dx+scale*8.08595753E+00,dy+scale* 3.58040657E+01 ); + glVertex2d(dx+scale*5.95178938E+00,dy+scale* 3.35593605E+01); + glVertex2d(dx+scale*1.56476307E+01,dy+scale* 4.10665283E+01 ); + glVertex2d(dx+scale*1.93166199E+01,dy+scale* 4.10665283E+01); + glVertex2d(dx+scale*1.93166199E+01,dy+scale* 4.10665283E+01 ); + glVertex2d(dx+scale*2.33771973E+01,dy+scale* 4.10665283E+01); + glVertex2d(dx+scale*2.33771973E+01,dy+scale* 4.10665283E+01 ); + glVertex2d(dx+scale*2.33771973E+01,dy+scale* 4.26527710E+01); + glVertex2d(dx+scale*2.33771973E+01,dy+scale* 4.26527710E+01 ); + glVertex2d(dx+scale*2.13850403E+01,dy+scale* 4.40476913E+01); + glVertex2d(dx+scale*2.13850403E+01,dy+scale* 4.40476913E+01 ); + glVertex2d(dx+scale*1.70507278E+01,dy+scale* 4.36787071E+01); + glVertex2d(dx+scale*1.70507278E+01,dy+scale* 4.36787071E+01 ); + glVertex2d(dx+scale*1.55381908E+01,dy+scale* 4.08627815E+01); + glVertex2d(dx+scale*5.44178314E+01,dy+scale* 5.39478874E+00 ); + glVertex2d(dx+scale*5.19188347E+01,dy+scale* 1.05424643E+01); + glVertex2d(dx+scale*5.19188347E+01,dy+scale* 1.05424643E+01 ); + glVertex2d(dx+scale*4.79111748E+01,dy+scale* 1.68014603E+01); + glVertex2d(dx+scale*4.79111748E+01,dy+scale* 1.68014603E+01 ); + glVertex2d(dx+scale*4.09703102E+01,dy+scale* 2.47799721E+01); + glVertex2d(dx+scale*1.97410069E+01,dy+scale* 2.08601875E+01 ); + glVertex2d(dx+scale*3.03358269E+01,dy+scale* 1.29992170E+01); + glVertex2d(dx+scale*3.34980812E+01,dy+scale* 1.23018475E+01 ); + glVertex2d(dx+scale*4.00906754E+01,dy+scale* 6.03390121E+00); + glVertex2d(dx+scale*5.23835278E+00,dy+scale* 3.55669289E+01 ); + glVertex2d(dx+scale*5.95178938E+00,dy+scale* 3.35593605E+01); + glVertex2d(dx+scale*5.23835278E+00,dy+scale* 3.55669289E+01 ); + glVertex2d(dx+scale*5.23835278E+00,dy+scale* 3.72466736E+01); + glVertex2d(dx+scale*5.23835278E+00,dy+scale* 3.72466736E+01 ); + glVertex2d(dx+scale*5.23835278E+00,dy+scale* 3.80246620E+01); + glVertex2d(dx+scale*5.23835278E+00,dy+scale* 3.80246620E+01 ); + glVertex2d(dx+scale*6.44296885E+00,dy+scale* 3.80246620E+01); + glVertex2d(dx+scale*6.44296885E+00,dy+scale* 3.80246620E+01 ); + glVertex2d(dx+scale*7.81519079E+00,dy+scale* 3.80246620E+01); + glVertex2d(dx+scale*7.81519079E+00,dy+scale* 3.80246620E+01 ); + glVertex2d(dx+scale*9.44908714E+00,dy+scale* 4.10665283E+01); + glVertex2d(dx+scale*9.44908714E+00,dy+scale* 4.10665283E+01 ); + glVertex2d(dx+scale*7.57615042E+00,dy+scale* 4.31311188E+01); + glVertex2d(dx+scale*7.57615042E+00,dy+scale* 4.31311188E+01 ); + glVertex2d(dx+scale*3.57823205E+00,dy+scale* 4.07483292E+01); + glVertex2d(dx+scale*3.57823205E+00,dy+scale* 4.07483292E+01 ); + glVertex2d(dx+scale*2.90823507E+00,dy+scale* 3.95009766E+01); + glVertex2d(dx+scale*2.90823507E+00,dy+scale* 3.95009766E+01 ); + glVertex2d(dx+scale*8.70941460E-01,dy+scale* 3.73581619E+01); + glVertex2d(dx+scale*8.70941460E-01,dy+scale* 3.73581619E+01 ); + glVertex2d(dx+scale*3.22941685E+00,dy+scale* 3.47821503E+01); + glVertex2d(dx+scale*3.22941685E+00,dy+scale* 3.47821503E+01 ); + glVertex2d(dx+scale*5.23835278E+00,dy+scale* 3.55669289E+01); + glVertex2d(dx+scale*5.53392906E+01,dy+scale* 5.84212208E+00 ); + glVertex2d(dx+scale*5.34963722E+01,dy+scale* 4.94745588E+00); + glVertex2d(dx+scale*5.34963722E+01,dy+scale* 4.94745588E+00 ); + glVertex2d(dx+scale*5.33497162E+01,dy+scale* 2.90410757E+00); + glVertex2d(dx+scale*5.33497162E+01,dy+scale* 2.90410757E+00 ); + glVertex2d(dx+scale*5.50459785E+01,dy+scale* 1.75542593E+00); + glVertex2d(dx+scale*5.50459785E+01,dy+scale* 1.75542593E+00 ); + glVertex2d(dx+scale*5.68888969E+01,dy+scale* 2.65009236E+00); + glVertex2d(dx+scale*5.68888969E+01,dy+scale* 2.65009236E+00 ); + glVertex2d(dx+scale*5.70355530E+01,dy+scale* 4.69344044E+00); + glVertex2d(dx+scale*5.70355530E+01,dy+scale* 4.69344044E+00 ); + glVertex2d(dx+scale*5.53392906E+01,dy+scale* 5.84212208E+00); + glVertex2d(dx+scale*4.06703568E+01,dy+scale* 6.64360666E+00 ); + glVertex2d(dx+scale*3.95109940E+01,dy+scale* 5.42419529E+00); + glVertex2d(dx+scale*3.95109940E+01,dy+scale* 5.42419529E+00 ); + glVertex2d(dx+scale*3.99873543E+01,dy+scale* 3.81045246E+00); + glVertex2d(dx+scale*3.99873543E+01,dy+scale* 3.81045246E+00 ); + glVertex2d(dx+scale*4.16230736E+01,dy+scale* 3.41612053E+00); + glVertex2d(dx+scale*4.16230736E+01,dy+scale* 3.41612053E+00 ); + glVertex2d(dx+scale*4.20994339E+01,dy+scale* 1.80237734E+00); + glVertex2d(dx+scale*4.20994339E+01,dy+scale* 1.80237734E+00 ); + glVertex2d(dx+scale*4.37351570E+01,dy+scale* 1.40804553E+00); + glVertex2d(dx+scale*4.37351570E+01,dy+scale* 1.40804553E+00 ); + glVertex2d(dx+scale*4.48945198E+01,dy+scale* 2.62745667E+00); + glVertex2d(dx+scale*4.48945198E+01,dy+scale* 2.62745667E+00 ); + glVertex2d(dx+scale*4.44181595E+01,dy+scale* 4.24119997E+00); + glVertex2d(dx+scale*4.44181595E+01,dy+scale* 4.24119997E+00 ); + glVertex2d(dx+scale*4.27824364E+01,dy+scale* 4.63553190E+00); + glVertex2d(dx+scale*4.27824364E+01,dy+scale* 4.63553190E+00 ); + glVertex2d(dx+scale*4.23060799E+01,dy+scale* 6.24927473E+00); + glVertex2d(dx+scale*4.23060799E+01,dy+scale* 6.24927473E+00 ); + glVertex2d(dx+scale*4.06703568E+01,dy+scale* 6.64360666E+00); + glVertex2d(dx+scale*2.04135437E+01,dy+scale* 5.37603645E+01 ); + glVertex2d(dx+scale*2.09234962E+01,dy+scale* 5.39400024E+01); + glVertex2d(dx+scale*2.09234962E+01,dy+scale* 5.39400024E+01 ); + glVertex2d(dx+scale*2.10229034E+01,dy+scale* 5.44714508E+01); + glVertex2d(dx+scale*2.10229034E+01,dy+scale* 5.44714508E+01 ); + glVertex2d(dx+scale*2.06123581E+01,dy+scale* 5.48232651E+01); + glVertex2d(dx+scale*2.06123581E+01,dy+scale* 5.48232651E+01 ); + glVertex2d(dx+scale*2.01024036E+01,dy+scale* 5.46436272E+01); + glVertex2d(dx+scale*2.01024036E+01,dy+scale* 5.46436272E+01 ); + glVertex2d(dx+scale*2.00029964E+01,dy+scale* 5.41121788E+01); + glVertex2d(dx+scale*2.00029964E+01,dy+scale* 5.41121788E+01 ); + glVertex2d(dx+scale*2.04135437E+01,dy+scale* 5.37603645E+01); + glVertex2d(dx+scale*2.92241192E+01,dy+scale* 5.89225616E+01 ); + glVertex2d(dx+scale*2.92241192E+01,dy+scale* 6.01559525E+01); + glVertex2d(dx+scale*2.92241192E+01,dy+scale* 6.01559525E+01 ); + glVertex2d(dx+scale*2.81559734E+01,dy+scale* 6.07726440E+01); + glVertex2d(dx+scale*2.81559734E+01,dy+scale* 6.07726440E+01 ); + glVertex2d(dx+scale*2.70878277E+01,dy+scale* 6.01559525E+01); + glVertex2d(dx+scale*2.70878277E+01,dy+scale* 6.01559525E+01 ); + glVertex2d(dx+scale*2.70878277E+01,dy+scale* 5.89225616E+01); + glVertex2d(dx+scale*2.70878277E+01,dy+scale* 5.89225616E+01 ); + glVertex2d(dx+scale*2.81559734E+01,dy+scale* 5.83058662E+01); + glVertex2d(dx+scale*2.81559734E+01,dy+scale* 5.83058662E+01 ); + glVertex2d(dx+scale*2.92241192E+01,dy+scale* 5.89225616E+01); + glVertex2d(dx+scale*4.00748558E+01,dy+scale* 6.66682663E+01 ); + glVertex2d(dx+scale*4.00748558E+01,dy+scale* 6.86397629E+01); + glVertex2d(dx+scale*4.00748558E+01,dy+scale* 6.86397629E+01 ); + glVertex2d(dx+scale*3.83674927E+01,dy+scale* 6.96255112E+01); + glVertex2d(dx+scale*3.83674927E+01,dy+scale* 6.96255112E+01 ); + glVertex2d(dx+scale*3.66601257E+01,dy+scale* 6.86397629E+01); + glVertex2d(dx+scale*3.66601257E+01,dy+scale* 6.86397629E+01 ); + glVertex2d(dx+scale*3.66601257E+01,dy+scale* 6.66682663E+01); + glVertex2d(dx+scale*3.66601257E+01,dy+scale* 6.66682663E+01 ); + glVertex2d(dx+scale*3.83674927E+01,dy+scale* 6.56825180E+01); + glVertex2d(dx+scale*3.83674927E+01,dy+scale* 6.56825180E+01 ); + glVertex2d(dx+scale*4.00748558E+01,dy+scale* 6.66682663E+01); + glVertex2d(dx+scale*3.55498581E+01,dy+scale* 5.91182632E+01 ); + glVertex2d(dx+scale*3.62619553E+01,dy+scale* 5.99602509E+01); + glVertex2d(dx+scale*3.62619553E+01,dy+scale* 5.99602509E+01 ); + glVertex2d(dx+scale*3.58888245E+01,dy+scale* 6.09979362E+01); + glVertex2d(dx+scale*3.58888245E+01,dy+scale* 6.09979362E+01 ); + glVertex2d(dx+scale*3.48035927E+01,dy+scale* 6.11936378E+01); + glVertex2d(dx+scale*3.48035927E+01,dy+scale* 6.11936378E+01 ); + glVertex2d(dx+scale*3.40914955E+01,dy+scale* 6.03516541E+01); + glVertex2d(dx+scale*3.40914955E+01,dy+scale* 6.03516541E+01 ); + glVertex2d(dx+scale*3.44646263E+01,dy+scale* 5.93139648E+01); + glVertex2d(dx+scale*3.44646263E+01,dy+scale* 5.93139648E+01 ); + glVertex2d(dx+scale*3.55498581E+01,dy+scale* 5.91182632E+01); + glEnd(); + break; + default: break; + } + + + glDisable (GL_BLEND); + glPopMatrix(); + +} + + + + + + +void Navigator::move(){ + if(pad->toggle( pad->button_map[3]) ) + { + switch (mode) + { + case PEDESTRIAN : mode = DIVER ; break; + case DIVER : mode = PEDESTRIAN ; break; + default: break; + } + } + // reset 1:1 + if(pad->toggle( pad->button_map[8]) ) + { + ctx->camera.lookAtCg(); + reference_speed= 1.5*frequency*(ctx->camera.Lc)/100.; + } + // change the plane + if(pad->toggle( pad->button_map[0]) ) ctx->camera.lookAtCg(); + if(pad->toggle( pad->button_map[1]) ) + { + switch(along){ + case AXE_X : along=AXE_Y; ctx->camera.alongY(); break; + case AXE_Y : along=AXE_Z; ctx->camera.alongZ(); break; + case AXE_Z : along=AXE_X; ctx->camera.alongX(); break; + default: break; + } + } + // reset vertical axe or invers it + if(pad->toggle( pad->button_map[2] ) ) { + switch(along){ + case AXE_X : ctx->camera.upZ(); break; + case AXE_Y : ctx->camera.upX(); break; + case AXE_Z : ctx->camera.upY(); break; + default: break; + } + } + // head movement is damped to avoid nausea + if(pad->button[ pad->button_map[4] ] ) { + ax0 = int(pad->axe[ pad->axe_map[0] ]*10)/10.; ax1 =int( pad->axe[ pad->axe_map[1] ]*10)/10.; + if(ax1 >0.) ax0=-ax0; + } + else { + ax0 =0.; ax1 =0. ; + } + if( (ax0-ax0_cur)>0. ) { ax0_cur=ax0_cur + std::min((ax0-ax0_cur),0.005); } + else{ ax0_cur=ax0_cur + std::max((ax0-ax0_cur), -0.005); } + + if( (ax1-ax1_cur) >0.) { ax1_cur=ax1_cur + std::min((ax1-ax1_cur),0.005); } + else{ ax1_cur=ax1_cur + std::max((ax1-ax1_cur), -0.005); } + + azimut = -(ax0_cur) *(2.*ctx->camera.aperture*0.01745329 ) ; + elevation = (ax1_cur) *(2.*ctx->camera.aperture*0.01745329 ); + + //======================================================== + + switch(mode){ + case PEDESTRIAN : + //------------------------------------------ + // accelaration + if(!pad->button[ pad->button_map[4] ] ) + { + if(pad->axe[ pad->axe_map[1] ]!=0.) + { + acc=-pad->axe[ pad->axe_map[1] ] * ctx->camera.Lc / 500. * frequency ; + if (acc>0.) + { + speed = reference_speed +acc; + } + else + { + speed = reference_speed + 2.*acc; + } + speed = std::max(speed,(frequency * ctx->camera.Lc / 1000.)); + reference_speed = std::min(speed,(frequency*(ctx->camera.Lc))); + /* + std::cout<<"acc: "<< acc << std::endl; + std::cout<<"lc: "<< ctx->camera.Lc << std::endl; + std::cout<<"vitesse: "<< reference_speed << std::endl; + */ + } + } + lift = -.25 *pad->axe[ pad->axe_map[5] ] *reference_speed ; + lateral= 0.25* pad->axe[ pad->axe_map[4] ] *reference_speed ; + angular_lat= -1.0 * (pad->axe[ pad->axe_map[2] ]) *reference_angle; + // walk else run + if(pad->button[ pad->button_map[6]] ) + { + speed = -1.0 * pad->axe[ pad->axe_map[3] ] *reference_speed ; + } + else + { + speed= -4.0 * (pad->axe[ pad->axe_map[3] ]) *reference_speed ; + } + ctx->camera.move_and_look(speed,lateral,lift,0.,0.,angular_lat,azimut,elevation); + //------------------------------------- + + break; // end of mode PESDESTRIAN + + + + + case DIVER : + //------------------------------------- + // accelaration + // pad->affiche(); + if(!pad->button[ pad->button_map[4] ]) { + angular_fr = 1.0 * (pad->axe[ pad->axe_map[0] ]) *reference_angle; + if(pad->axe[ pad->axe_map[1] ]!=0. ) + { + acc=-pad->axe[ pad->axe_map[1] ] * ctx->camera.Lc / 1000. * frequency ; + if (acc>0.) { + speed = reference_speed +acc; + } + else { + speed = reference_speed + 2.*acc; + } + speed = std::max(speed,(frequency * ctx->camera.Lc / 1000.)); + reference_speed = std::min(speed,(frequency*(ctx->camera.Lc))); + } + + if(pad->button[ pad->button_map[6] ] ) { + speed = reference_speed ; + } + else { + speed = 0.; + } + } + + lift = -.25 *pad->axe[ pad->axe_map[5] ] *reference_speed ; + lateral= 0.25* pad->axe[ pad->axe_map[4] ] *reference_speed ; + angular_lat= -1.0 * (pad->axe[ pad->axe_map[2] ]) *reference_angle; + angular_up = 1.0 * (pad->axe[ pad->axe_map[3] ]) *reference_angle; + + ctx->camera.move_and_look(speed,lateral,lift,angular_fr,angular_up,angular_lat,azimut,elevation); + //------------------------------------- + + + break; // end of mode DIVER + + case PLANE : + break; // end of mode PLANE + + case CAR : + break; // end of mode CAR + + + default: break; + + } // end of switch(mode) + +} + diff --git a/Fltk/Navigator.h b/Fltk/Navigator.h new file mode 100644 index 0000000000000000000000000000000000000000..756ececa8dd9d5507310bbe2cfe02fb05e280276 --- /dev/null +++ b/Fltk/Navigator.h @@ -0,0 +1,59 @@ +// Gmsh - Copyright (C) 1997-2013 C. Geuzaine, J.-F. Remacle +// +// See the LICENSE.txt file for license information. Please report all +// bugs and problems to the public mailing list <gmsh@geuz.org>. +// +// Contributed by Gilles Marckmann <gilles.marckmann@ec-nantes.fr> +// + +#ifndef _NAVIGATOR_H_ +#define _NAVIGATOR_H_ + +#include "drawContext.h" +#include "Camera.h" +#include "GamePad.h" + + + +typedef enum { AXE_X, AXE_Y, AXE_Z } AXE ; +typedef enum { PLANE, PEDESTRIAN, DIVER, CAR } NAV_MODE ; + +class Navigator { + public: + double ax0 ,ax1,ax0_cur,ax1_cur; + double speed,acc; + double lateral; + double angular_lat; + double angular_up; + double angular_fr; + AXE along; + NAV_MODE mode; + double axe[3]; + double quatern[4]; + bool awake; + double reference_angle; + double reference_speed; + double angle_up; + double angle_rl; + double angle_fr; + drawContext* ctx; + double frequency; + GamePad* pad; + double azimut; + double elevation; + double lift; + int ncount; + public: + Navigator( double _freq, drawContext* _ctx); + Navigator(); + ~Navigator(); + void setFrequency(double _freq) ; + void setResponseFrequency(double _freq) ; + void setDrawContext( drawContext* _ctx) ; + void move(); + void drawIcons(); +}; + + + +#endif // _NAVIGATOR_H_ diff --git a/Fltk/gamepadWindow.cpp b/Fltk/gamepadWindow.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cc0f3212beadbc1899bf54f97f6d185ac0ed853c --- /dev/null +++ b/Fltk/gamepadWindow.cpp @@ -0,0 +1,160 @@ +// Gmsh - Copyright (C) 1997-2013 C. Geuzaine, J.-F. Remacle +// +// See the LICENSE.txt file for license information. Please report all +// bugs and problems to the public mailing list <gmsh@geuz.org>. + +#include "GmshConfig.h" +#if !defined(HAVE_NO_STDINT_H) +#include <stdint.h> +#elif defined(HAVE_NO_INTPTR_T) +typedef unsigned long intptr_t; +#endif +#include <string.h> +#include <FL/Fl.H> +#include <FL/Fl_Tabs.H> +#include <FL/Fl_Scroll.H> +#include <FL/Fl_Color_Chooser.H> +#include <FL/fl_ask.H> +#include "GmshDefines.h" +#include "GmshMessage.h" +#include "FlGui.h" +#include "optionWindow.h" +#include "GamePad.h" +#include "gamepadWindow.h" +#include "graphicWindow.h" +#include "openglWindow.h" +#include "paletteWindow.h" +#include "extraDialogs.h" +#include "drawContext.h" +#include "Options.h" +#include "GModel.h" +#include "MElement.h" +#include "PView.h" +#include "PViewData.h" +#include "PViewOptions.h" +#include "OS.h" +#include "Context.h" +#include "StringUtils.h" + +///// handler (listen to gamepad or other names pipes) ///////// +static void gamepadWindow_handler(void *data) +{ + if (CTX::instance()->gamepad.active) { + gamepadWindow* gmpd_win = (gamepadWindow*)data; + GamePad* pad = &(CTX::instance()->gamepad); + for (int i=0; i<std::min(13,GP_BUTTONS);i++) gmpd_win->gamepad.butt[i]->value(pad->button[i]); + for (int i=0; i<std::min(9,GP_AXES);i++) gmpd_win->gamepad.axe[i]->value(pad->axe[i]); + Fl::add_timeout(gmpd_win->frequency, gamepadWindow_handler,data); + gmpd_win->gamepad.mapping[16]->value(pad->axe_map[1]); + } +} +/// + +static void gamepad_update_cb(Fl_Widget *w) +{ + gamepadWindow* gmpd_win = FlGui::instance()->options->gmpdoption; + GamePad* pad = &(CTX::instance()->gamepad); + for (int i=0; i<std::min(8,GP_BUTTONS) ;i++) pad->button_map[i] = gmpd_win->gamepad.mapping[i]->value(); + for (int i=0; i<std::min(7,GP_AXES);i++) pad->axe_map[i] = gmpd_win->gamepad.mapping[10+i]->value(); +} + +gamepadWindow::gamepadWindow() : +frequency(CTX::instance()->gamepad.frequency) +{ + // FL_NORMAL_SIZE -= deltaFontSize; + + int width = 34 * FL_NORMAL_SIZE + WB; + int height = 15 * BH + 4 * WB; + int L = FL_NORMAL_SIZE; + // int BW = width - 4 * WB; + + + win = new paletteWindow + (width, height, CTX::instance()->nonModalWindows ? true : false); + win->box(GMSH_WINDOW_BOX); + win->label("Gamepad Configuration Tool (in work)"); + + Fl_Box *bt = new Fl_Box(FL_NO_BOX, L , L-.3*BH , IW, BH, "Gamepad buttons:"); + bt->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT); + + gamepad.butt[0] = new Fl_Check_Button(L , L+BH , BH, WB, "0" ); + gamepad.butt[1] = new Fl_Check_Button(L +1*BB*.35 , L+BH , BH, WB, "1" ); + gamepad.butt[2] = new Fl_Check_Button(L +2*BB*.35 , L+BH , BH, WB, "2" ); + gamepad.butt[3] = new Fl_Check_Button(L +3*BB*.35 , L+BH , BH, WB, "3" ); + gamepad.butt[4] = new Fl_Check_Button(L +4*BB*.35 , L+BH , BH, WB, "4" ); + gamepad.butt[5] = new Fl_Check_Button(L +5*BB*.35 , L+BH , BH, WB, "5" ); + gamepad.butt[6] = new Fl_Check_Button(L +6*BB*.35 , L+BH , BH, WB, "6" ); + gamepad.butt[7] = new Fl_Check_Button(L +7*BB*.35 , L+BH , BH, WB, "7" ); + gamepad.butt[8] = new Fl_Check_Button(L +8*BB*.35 , L+BH , BH, WB, "8" ); + gamepad.butt[9] = new Fl_Check_Button(L +9*BB*.35 , L+BH , BH, WB, "9" ); + gamepad.butt[10] = new Fl_Check_Button(L +10*BB*.35 , L+BH , BH, WB, "10" ); + gamepad.butt[11] = new Fl_Check_Button(L +11*BB*.35 , L+BH , BH, WB, "11" ); + gamepad.butt[12] = new Fl_Check_Button(L +12*BB*.35 , L+BH , BH, WB, "12" ); + for (int i=0; i<13;i++) gamepad.butt[i]->deactivate(); + + Fl_Box *bta = new Fl_Box(FL_NO_BOX, L , L+1.7*BH , IW, BH, "Gamepad axes:"); + bta->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT); + + gamepad.axe[0] = new Fl_Check_Button(L , L+3.*BH , BH, WB, "0" ); + gamepad.axe[1] = new Fl_Check_Button(L +1*BB*.4 , L+3.*BH , BH, WB, "1" ); + gamepad.axe[2] = new Fl_Check_Button(L +2*BB*.4 , L+3.*BH , BH, WB, "2" ); + gamepad.axe[3] = new Fl_Check_Button(L +3*BB*.4 , L+3.*BH , BH, WB, "3" ); + gamepad.axe[4] = new Fl_Check_Button(L +4*BB*.4 , L+3.*BH , BH, WB, "4" ); + gamepad.axe[5] = new Fl_Check_Button(L +5*BB*.4 , L+3.*BH , BH, WB, "5" ); + gamepad.axe[6] = new Fl_Check_Button(L +6*BB*.4 , L+3.*BH , BH, WB, "6" ); + gamepad.axe[7] = new Fl_Check_Button(L +7*BB*.4 , L+3.*BH , BH, WB, "7" ); + gamepad.axe[8] = new Fl_Check_Button(L +8*BB*.4 , L+3.*BH , BH, WB, "8" ); + for (int i=0; i<9;i++) gamepad.axe[i]->deactivate(); + + Fl_Box *btt1 = new Fl_Box(FL_NO_BOX, L , L+4.*BH , IW, BH, "Preferences:"); + btt1->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT); + Fl_Box *btt2 = new Fl_Box(FL_NO_BOX, L , L+5.*BH , IW, BH, "Action Axes:"); + btt2->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT); + Fl_Box *btt3 = new Fl_Box(FL_NO_BOX, L +width/2, L+5.*BH , IW, BH, "Action buttons:"); + btt3->align(FL_ALIGN_INSIDE|FL_ALIGN_LEFT); + + GamePad* pad = &(CTX::instance()->gamepad); + + gamepad.mapping[0] = new Fl_Value_Input( L+width/2, L+6.*BH , IW/5,BH, "1:1"); + gamepad.mapping[1] = new Fl_Value_Input( L+width/2, L+7.*BH , IW/5,BH, "permute axes"); + gamepad.mapping[2] = new Fl_Value_Input( L+width/2, L+8.*BH , IW/5,BH, "reset/invers up axis"); + gamepad.mapping[3] = new Fl_Value_Input( L+width/2, L+9.*BH , IW/5,BH, "change nav-mode"); + gamepad.mapping[4] = new Fl_Value_Input( L+width/2, L+10.*BH, IW/5,BH, "move head (with axes)"); + gamepad.mapping[5] = new Fl_Value_Input( L+width/2, L+11.*BH, IW/5,BH, " "); + gamepad.mapping[6] = new Fl_Value_Input( L+width/2, L+12.*BH, IW/5,BH, "walk / swimm"); + gamepad.mapping[7] = new Fl_Value_Input( L+width/2, L+13.*BH, IW/5,BH, " "); + gamepad.mapping[8] = new Fl_Value_Input( L+width/2, L+14.*BH, IW/5,BH, "1:1 ; reset speed"); + + for (int i=0; i<9;i++) { + // gamepad.mapping[i]->deactivate(); + gamepad.mapping[i]->align(FL_ALIGN_RIGHT); + gamepad.mapping[i]->callback(gamepad_update_cb); + gamepad.mapping[i]->value( pad->button_map[i] ); + } + + gamepad.mapping[10] = new Fl_Value_Input( L, L+6.*BH , IW/5, BH, "head right/left (with button)"); + gamepad.mapping[11] = new Fl_Value_Input( L, L+7.*BH , IW/5, BH, "head up/down (with button)"); + gamepad.mapping[12] = new Fl_Value_Input( L, L+8.*BH , IW/5, BH, "turn left/right"); + gamepad.mapping[13] = new Fl_Value_Input( L, L+9.*BH, IW/5, BH, "for/backward or up/down "); + gamepad.mapping[14] = new Fl_Value_Input( L, L+10.*BH, IW/5, BH, "move aside left/right"); + gamepad.mapping[15] = new Fl_Value_Input( L, L+11.*BH, IW/5, BH, "move up/down"); + gamepad.mapping[16] = new Fl_Value_Input( L, L+12.*BH , IW/5, BH, "speed up/slow down"); + + for (int i=0; i<7;i++) { + gamepad.mapping[10+i]->align(FL_ALIGN_RIGHT); + gamepad.mapping[10+i]->callback(gamepad_update_cb); + gamepad.mapping[10+i]->value( pad->axe_map[i] ); + } + + //// add external reader for gamepad events + if (CTX::instance()->gamepad.active) { + Fl::add_timeout(frequency, gamepadWindow_handler, (void*)this); + } + //// + + win->position(CTX::instance()->optPosition[0], CTX::instance()->optPosition[1]); + win->end(); + +} + + diff --git a/Fltk/gamepadWindow.h b/Fltk/gamepadWindow.h new file mode 100644 index 0000000000000000000000000000000000000000..39f015a8a9f0e984ece17c4b58347df38b822fbc --- /dev/null +++ b/Fltk/gamepadWindow.h @@ -0,0 +1,90 @@ +// Gmsh - Copyright (C) 1997-2013 C. Geuzaine, J.-F. Remacle +// +// See the LICENSE.txt file for license information. Please report all +// bugs and problems to the public mailing list <gmsh@geuz.org>. + +#ifndef _GAMEPAD_WINDOW_H_ +#define _GAMEPAD_WINDOW_H_ + +#include <FL/Fl_Window.H> +#include <FL/Fl_Value_Slider.H> +#include <FL/Fl_Hold_Browser.H> +#include <FL/Fl_Button.H> +#include <FL/Fl_Return_Button.H> +#include <FL/Fl_Check_Button.H> +#include <FL/Fl_Menu_Button.H> +#include <FL/Fl_Group.H> +#include <FL/Fl_Choice.H> +#include <FL/Fl_Input.H> +#include <FL/Fl_Value_Input.H> +#include <FL/Fl_Box.H> + + +extern Fl_Menu_Item menu_font_names[]; + + +// A small 2D widget to visualize the coordinates of a point on the unit +// circle. +class AxesPositionWidget : public Fl_Widget { + private: + double _x, _y; + void draw() + { + draw_box(box(), color()); + int x1 = x() + 3; + int y1 = y() + 3; + int w1 = w() - 6; + int h1 = h() - 6; + fl_color(FL_FOREGROUND_COLOR); + fl_arc(x1, y1, w1, h1, 0, 360); + int px = int(x1 + 0.5 * w1 * (1 + _x)); + int py = int(y1 + 0.5 * h1 * (1 - _y)); + draw_box(FL_UP_BOX, px - 3, py - 3, 6, 6, FL_FOREGROUND_COLOR); + } + public: + AxesPositionWidget(int x, int y, int w, const char *l=0) + : Fl_Widget(x, y, w, w, l), _x(0.), _y(0.) + { + box(FL_FLAT_BOX); + align(FL_ALIGN_BOTTOM); + } + void setValue(double x, double y) + { + double norm = sqrt(x * x + y * y ); + if(norm){ + _x = x / norm; _y = y / norm; + } + else{ + _x = _y = 0.; + } + redraw(); + } +}; + + + + + +class gamepadWindow{ + public: Fl_Window *win; + + struct{ + + Fl_Check_Button *butt[21]; + Fl_Check_Button *axe[21]; + Fl_Check_Button *cont[21]; + Fl_Value_Input *mapping[21]; + AxesPositionWidget *padL; + AxesPositionWidget *padR; + AxesPositionWidget *Dpad; + } gamepad; + + public: + gamepadWindow(); + double frequency; +}; + + + +#endif + diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp index 20361bd24a51ae235971b6b0066f79abcc7fd248..0a0792a470be26581528959d14109a1e7993b3bb 100644 --- a/Fltk/graphicWindow.cpp +++ b/Fltk/graphicWindow.cpp @@ -23,6 +23,7 @@ typedef unsigned long intptr_t; #include "paletteWindow.h" #include "graphicWindow.h" #include "optionWindow.h" +#include "gamepadWindow.h" #include "statisticsWindow.h" #include "contextWindow.h" #include "visibilityWindow.h" @@ -2886,24 +2887,18 @@ bool graphicWindow::split(openglWindow *g, char how) return true; } -void graphicWindow::setStereo() +void graphicWindow::setStereo(bool st) { openglWindow::setLastHandled(0); for(unsigned int i = 0; i < gl.size(); i++){ - _tile->remove(gl[i]); - delete gl[i]; - } - gl.clear(); - openglWindow *g2 = new openglWindow - (_tile->x() + (_onelab && !_menuwin ? _onelab->w() : 0), - _tile->y(), - _tile->w() - (_onelab && !_menuwin ? _onelab->w() : 0), - _tile->h() - (_browser ? _browser->h() : 0)); - g2->mode(FL_RGB | FL_DEPTH | FL_DOUBLE | FL_STEREO); - g2->end(); - gl.push_back(g2); - _tile->add(g2); - g2->show(); + if (st) { + gl[i]->mode(FL_RGB | FL_DEPTH | FL_DOUBLE | FL_STEREO); + } + else{ + gl[i]->mode(FL_RGB | FL_DEPTH | FL_DOUBLE ); + } + gl[i]->show(); + } Msg::Info("new gl window for stereo vision!"); } diff --git a/Fltk/graphicWindow.h b/Fltk/graphicWindow.h index b8488c30f002ff2eee929eb50424fc5dbcd4f852..4ca254bc44035bfcb80dba610d02bfb08e561f33 100644 --- a/Fltk/graphicWindow.h +++ b/Fltk/graphicWindow.h @@ -52,7 +52,7 @@ class graphicWindow{ void setAutoScroll(bool val){ _autoScrollMessages = val; } bool getAutoScroll(){ return _autoScrollMessages; } void setTitle(std::string str); - void setStereo(); + void setStereo(bool st); int getGlWidth(); void setGlWidth(int w); int getGlHeight(); diff --git a/Fltk/openglWindow.cpp b/Fltk/openglWindow.cpp index 6e48e01b739d1aa2ed1f9e0b8001a2b6096a4005..1948276140a300640b96d9e8c986ba3d32c1033f 100644 --- a/Fltk/openglWindow.cpp +++ b/Fltk/openglWindow.cpp @@ -20,6 +20,18 @@ #include "Context.h" #include <FL/Fl_Tooltip.H> +#include "Trackball.h" +#include "GamePad.h" + +///// Navigator handler (listen to gamepad or other names pipes) ///////// +static void navigator_handler(void *data) +{ + openglWindow* gl_win = (openglWindow*)data; + if (CTX::instance()->gamepad.active) gl_win->move_with_gamepad(); + Fl::add_timeout(gl_win->frequency, navigator_handler,data); +} +/// + static void lassoZoom(drawContext *ctx, mousePosition &click1, mousePosition &click2) { if(click1.win[0] == click2.win[0] || click1.win[1] == click2.win[1]) return; @@ -40,8 +52,13 @@ static void lassoZoom(drawContext *ctx, mousePosition &click1, mousePosition &cl } openglWindow::openglWindow(int x, int y, int w, int h) - : Fl_Gl_Window(x, y, w, h, "gl"), _lock(false), - _selection(ENT_NONE), _trySelection(0) + : Fl_Gl_Window(x, y, w, h, "gl"), _lock(false) + , _drawn(false) + , _selection(ENT_NONE) , _trySelection(0) + , ntime(0) + , frequency(CTX::instance()->gamepad.frequency) + + { _ctx = new drawContext(); for(int i = 0; i < 3; i++) _point[i] = 0.; @@ -50,11 +67,21 @@ openglWindow::openglWindow(int x, int y, int w, int h) addPointMode = lassoMode = selectionMode = false; endSelection = undoSelection = invertSelection = quitSelection = 0; + + + //// add external reader for gamepad events + if (CTX::instance()->gamepad.active) { + Nautilus = new Navigator(frequency,_ctx); + Fl::add_timeout(frequency, navigator_handler, (void*)this); + } + //// + } openglWindow::~openglWindow() { delete _ctx; + delete Nautilus; } void openglWindow::_drawScreenMessage() @@ -119,9 +146,11 @@ void openglWindow::draw() // that we don't fire draw() while we are already drawing, e.g. due to an // impromptu Fl::check(). The same lock is also used in _select to guarantee // that we don't mix GL_RENDER and GL_SELECT rendering passes. + _drawn=true; if(_lock) return; _lock = true; + Msg::Debug("openglWindow::draw()"); if(!context_valid()) _ctx->invalidateQuadricsAndDisplayLists(); @@ -217,8 +246,10 @@ void openglWindow::draw() cam->giveViewportDimension(_ctx->viewport[2],_ctx->viewport[3]); glMatrixMode(GL_PROJECTION); glLoadIdentity(); + glFrustum(cam->glFleft, cam->glFright, cam->glFbottom, - cam->glFtop, cam->glFnear, cam->glFfar); + cam->glFtop, cam->glFnear , cam->glFfar*cam->Lc ); + glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glDrawBuffer(GL_BACK); @@ -229,12 +260,15 @@ void openglWindow::draw() cam->up.x,cam->up.y,cam->up.z); _ctx->draw3d(); _ctx->draw2d(); + /// + if (CTX::instance()->gamepad.active){ Nautilus->drawIcons();} + /// _drawScreenMessage(); _drawBorder(); } else if(CTX::instance()->stereo){ Camera *cam = &(_ctx->camera); - if(!cam->on) cam->init(); + if(!cam->on ) cam->init(); cam->giveViewportDimension(_ctx->viewport[2], _ctx->viewport[3]); XYZ eye = cam->eyesep / 2.0 * cam->right; // right eye @@ -244,7 +278,7 @@ void openglWindow::draw() double right = cam->screenratio * cam->wd2 - 0.5 * cam->eyesep * cam->ndfl; double top = cam->wd2; double bottom = - cam->wd2; - glFrustum(left, right, bottom, top, cam->glFnear, cam->glFfar); + glFrustum(left, right, bottom, top, cam->glFnear, cam->glFfar*cam->Lc); glMatrixMode(GL_MODELVIEW); glDrawBuffer(GL_BACK_RIGHT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -263,7 +297,7 @@ void openglWindow::draw() right = cam->screenratio * cam->wd2 + 0.5 * cam->eyesep * cam->ndfl; top = cam->wd2; bottom = - cam->wd2; - glFrustum(left, right, bottom, top, cam->glFnear, cam->glFfar); + glFrustum(left, right, bottom, top, cam->glFnear, cam->glFfar*cam->Lc); glMatrixMode(GL_MODELVIEW); glDrawBuffer(GL_BACK_LEFT); @@ -710,3 +744,22 @@ void openglWindow::drawTooltip(const std::string &text) Fl_Tooltip::hoverdelay(d2); if(!enabled) Fl_Tooltip::disable(); } + + + + +//// +void openglWindow::move_with_gamepad() { + if (CTX::instance()->gamepad.active) { + + if( !(_ctx->camera.on)) _ctx->camera.init(); + + if (_drawn && (_lastHandled == this || _lastHandled == 0 ) ) { + Nautilus->move(); + this->flush(); + } + } + +} + +///// diff --git a/Fltk/openglWindow.h b/Fltk/openglWindow.h index 5c831990962f61b26140c2b4c1aa8ee43f5d0f24..5cd39efc55d9f4c19e27cd19b17acbdd10497a8f 100644 --- a/Fltk/openglWindow.h +++ b/Fltk/openglWindow.h @@ -11,6 +11,7 @@ #include <FL/Fl_Gl_Window.H> #include <FL/Fl_Box.H> #include "drawContext.h" +#include "Navigator.h" class GVertex; class GEdge; @@ -23,6 +24,7 @@ class openglWindow : public Fl_Gl_Window { static openglWindow *_lastHandled; static void _setLastHandled(openglWindow*); bool _lock; + bool _drawn; mousePosition _click, _curr, _prev; drawContext *_ctx; double _point[3]; @@ -38,6 +40,9 @@ class openglWindow : public Fl_Gl_Window { void draw(); int handle(int); public: + time_t rawtime, prev_rawtime; + int ntime; + double response_frequency; bool addPointMode, lassoMode, selectionMode; int endSelection, undoSelection, invertSelection, quitSelection; std::string screenMessage[2]; @@ -51,6 +56,12 @@ class openglWindow : public Fl_Gl_Window { static openglWindow *getLastHandled(){ return _lastHandled; } static void setLastHandled(openglWindow *w){ _lastHandled = w; } void drawTooltip(const std::string &text); + /// + double frequency; + void move_with_gamepad() ; + Navigator* Nautilus; + /// }; #endif + diff --git a/Fltk/optionWindow.cpp b/Fltk/optionWindow.cpp index d7a853b372e014a9273a2e632f575569a08cf1ff..acf0109ef4fa233e6dd0df5f7a2486689868698a 100644 --- a/Fltk/optionWindow.cpp +++ b/Fltk/optionWindow.cpp @@ -10,6 +10,7 @@ typedef unsigned long intptr_t; #endif #include <string.h> +#include <FL/Fl.H> #include <FL/Fl_Tabs.H> #include <FL/Fl_Scroll.H> #include <FL/Fl_Color_Chooser.H> @@ -18,6 +19,7 @@ typedef unsigned long intptr_t; #include "GmshMessage.h" #include "FlGui.h" #include "optionWindow.h" +#include "gamepadWindow.h" #include "graphicWindow.h" #include "openglWindow.h" #include "paletteWindow.h" @@ -159,6 +161,16 @@ static void view_color_cb(Fl_Widget *w, void *data) drawContext::global()->draw(); } + +void general_gmpdcf_cb(Fl_Widget *w, void *data) +{ + FlGui::instance()->options->gmpdoption = new gamepadWindow; + FlGui::instance()->options->gmpdoption->win->show(); +} + + + + void options_cb(Fl_Widget *w, void *data) { FlGui::instance()->options->win->show(); @@ -350,10 +362,9 @@ static void general_options_ok_cb(Fl_Widget *w, void *data) opt_general_camera_mode(0, GMSH_SET, o->general.butt[18]->value()); if(opt_general_stereo_mode(0, GMSH_GET, 0) != o->general.butt[17]->value()) { opt_general_stereo_mode(0, GMSH_SET, o->general.butt[17]->value()); - if (CTX::instance()->stereo){ - for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++) - FlGui::instance()->graph[i]->setStereo(); - } + // if (CTX::instance()->stereo){ + for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++) FlGui::instance()->graph[i]->setStereo((bool)CTX::instance()->stereo); + // } } if(CTX::instance()->fastRedraw) @@ -1809,6 +1820,10 @@ optionWindow::optionWindow(int deltaFontSize) general.value[31]->align(FL_ALIGN_RIGHT); general.value[31]->callback(general_options_ok_cb); + Fl_Button *gmpdcf = new Fl_Button + (L + 2 * WB, 2 * WB + 6 * BH, 1.5*IW, BH, "Configure Gamepad"); + gmpdcf->callback(general_gmpdcf_cb); + o->end(); } diff --git a/Fltk/optionWindow.h b/Fltk/optionWindow.h index 54d3da023cd85811a1017dc940ec95626dc167c3..453e49f4a539c9847aa833711cf60810dd315c44 100644 --- a/Fltk/optionWindow.h +++ b/Fltk/optionWindow.h @@ -20,6 +20,7 @@ #include <FL/Fl_Box.H> #include "spherePositionWidget.h" #include "colorbarWindow.h" +#include "gamepadWindow.h" #define NUM_FONTS 14 extern Fl_Menu_Item menu_font_names[]; @@ -86,6 +87,7 @@ class optionWindow{ public: optionWindow(int deltaFontSize=0); + gamepadWindow* gmpdoption ; void showGroup(int num, bool showWindow=true); void resetBrowser(); void resetExternalViewList(); @@ -100,5 +102,6 @@ void mesh_options_cb(Fl_Widget *w, void *data); void solver_options_cb(Fl_Widget *w, void *data); void post_options_cb(Fl_Widget *w, void *data); void view_options_cb(Fl_Widget *w, void *data); +void general_gmpdcf_cb(Fl_Widget *w, void *data); #endif diff --git a/Graphics/Camera.cpp b/Graphics/Camera.cpp index a7e32310db7f0692ad6ede7f6cf7495883b734df..3e57e130a50120137f9a7d5b2fceb4945e1c05c6 100644 --- a/Graphics/Camera.cpp +++ b/Graphics/Camera.cpp @@ -17,11 +17,13 @@ #include "Context.h" #include "drawContext.h" +Camera::Camera() : on(false), stereoEnable(false), Lc(1.), glFnear(0.1), glFfar(10000) {} + +Camera::~Camera() {} + void Camera::init() { - on = true; - glFnear = 0.1 ; - glFfar = 10000; + if(CTX::instance()->fileread ) { on = true; } eye_sep_ratio = CTX::instance()->eye_sep_ratio; aperture = CTX::instance()->camera_aperture; focallength = CTX::instance()->focallength_ratio * 100.; @@ -29,45 +31,94 @@ void Camera::init() this->lookAtCg(); eyesep = distance * eye_sep_ratio / 100.; ref_distance=distance; + glFnear=.0001*distance; + glFfar=10000*distance; this->update(); + } void Camera::alongX() { - view.set(-1., 0., 0.); + front.set(-1., 0., 0.); up.set(0., 0., 1); - position = target-distance * view; + position = target-distance * front; this->update(); } void Camera::alongY() { - view.set(0., -1., 0.); + front.set(0., -1., 0.); up.set(1., 0., 0); - position = target-distance * view; + position = target-distance * front; this->update(); } void Camera::alongZ() { - view.set(0., 0., -1.); + front.set(0., 0., -1.); up.set(0., 1., 0); - position = target-distance * view; + position = target-distance * front; this->update(); } -void Camera::tiltHeadLeft() +void Camera::upX() { - up = -1. * right; - update(); + if( up.x > 0.){ + if (up.x !=1.) { up.set(1.,0.,0.); } + else { up.set(-1.,0.,0.); right=-right; } + } + else { + if (up.x !=-1.) {up.set(-1.,0.,0.); } + else { up.set(1.,0.,0.); right=-right; } + } + front.x = up.y * right.z - up.z * right.y; + front.y = up.z * right.x - up.x * right.z; + front.z = up.x * right.y - up.y * right.x; + target = position + distance * front; + this->update(); } -void Camera::tiltHeadRight() +void Camera::upY() { - up = right; - update(); + if( up.y > 0.){ + if (up.y !=1.) { up.set(0.,1.,0.); } + else { up.set(0.,-1.,0.); right=-right; } + } + else { + if (up.y !=-1.) {up.set(0.,-1.,0.); } + else { up.set(0.,1.,0.); right=-right; } + } + front.x = up.y * right.z - up.z * right.y; + front.y = up.z * right.x - up.x * right.z; + front.z = up.x * right.y - up.y * right.x; + target = position + distance * front; + this->update(); +} + + +void Camera::upZ() +{ + if( up.z > 0.){ + if (up.z !=1.) { up.set(0.,0.,1.); } + else { up.set(0.,0.,-1.); right=-right; } + } + else { + if (up.z !=-1.) {up.set(0.,0.,-1.); } + else { up.set(0.,0.,1.); right=-right; } + } + front.x = up.y * right.z - up.z * right.y; + front.y = up.z * right.x - up.x * right.z; + front.z = up.x * right.y - up.y * right.x; + target = position + distance * front; + this->update(); } + + +void Camera::tiltHeadLeft() { up = -1. * right; update(); } + +void Camera::tiltHeadRight() { up = right; update(); } + void Camera::lookAtCg() { target.x = CTX::instance()->cg[0]; @@ -78,7 +129,7 @@ void Camera::lookAtCg() double P = CTX::instance()->max[2] - CTX::instance()->min[2]; Lc = sqrt(1. * W * W + 1. * H * H + 1. * P * P); distance = .8 * fabs(.5 * Lc * 4. / 3. / tan(aperture * .01745329 / 2.)); - position = target - distance * view; + position = target - distance * front; this->update(); focallength = focallength_ratio * distance; ref_distance = distance; @@ -98,13 +149,18 @@ void Camera::giveViewportDimension(const int& W,const int& H) void Camera::update() { - right.x = view.y * up.z - view.z * up.y; - right.y = view.z * up.x - view.x * up.z; - right.z = view.x * up.y - view.y * up.x; + right.x = front.y * up.z - front.z * up.y; + right.y = front.z * up.x - front.x * up.z; + right.z = front.x * up.y - front.y * up.x; + + up.x = right.y * front.z - right.z * front.y; + up.y = right.z * front.x - right.x * front.z; + up.z = right.x * front.y - right.y * front.x; + ref_distance = distance; normalize(up); normalize(right); - normalize(view); + normalize(front); aperture = CTX::instance()->camera_aperture; focallength_ratio = CTX::instance()->focallength_ratio; focallength = focallength_ratio * distance; @@ -123,7 +179,7 @@ void Camera::affiche() std::cout<<" CTX focallength ratio "<< CTX::instance()->focallength_ratio <<std::endl ; std::cout<<" ------------ CAMERA PARAMETERS ------------" <<std::endl ; std::cout<<" position "<< position.x<<","<<position.y<<","<<position.z <<std::endl ; - std::cout<<" view "<< view.x<<","<<view.y<<","<<view.z <<std::endl; + std::cout<<" front "<< front.x<<","<<front.y<<","<<front.z <<std::endl; std::cout<<" up "<< up.x<<","<<up.y<<","<<up.z <<std::endl; std::cout<<" right "<< right.x<<","<<right.y<<","<<right.z <<std::endl; std::cout<<" target "<< target.x<<","<<target.y<<","<<target.z <<std::endl; @@ -153,7 +209,7 @@ void Camera::moveRight(double& theta) { this->update(); position = position-distance * tan(theta) * right; - target = position + distance * view; + target = position + distance * front; this->update(); } @@ -161,14 +217,14 @@ void Camera::moveUp(double& theta) { this->update(); position = position+distance * tan(theta) * up; - target = position+distance * view; + target = position+distance * front; this->update(); } void Camera::zoom(double& factor) { distance = fabs(1. / factor * ref_distance); - position = target - distance * view; + position = target - distance * front; } void Camera::rotate(double* q) @@ -176,41 +232,85 @@ void Camera::rotate(double* q) this->update(); // rotation projection in global coordinates Quaternion omega; - omega.x = q[0] * right.x + q[1] * up.x - q[2] * view.x; - omega.y = q[0] * right.y + q[1] * up.y - q[2] * view.y; - omega.z = q[0] * right.z + q[1] * up.z - q[2] * view.z; + omega.x = q[0] * right.x + q[1] * up.x - q[2] * front.x; + omega.y = q[0] * right.y + q[1] * up.y - q[2] * front.y; + omega.z = q[0] * right.z + q[1] * up.z - q[2] * front.z; omega.w = q[3]; - // normalize the axe of rotation in the Quaternion omega if not null - double sina = sin(acos(omega.w)); - double length; - if (sina != 0.){ - length = (omega.x * omega.x + omega.y * omega.y + omega.z * omega.z) / (sina * sina); - } - else{ - length = 0.; - } - length = sqrt(length); - if (length!=0.){ - omega.x /= length; - omega.y /= length; - omega.z /= length; - Quaternion conj = conjugate(omega); - view = omega * view * conj; - up = omega * up * conj; - right = omega * right * conj; - normalize(view); - normalize(up); - normalize(right); - //actualize camera position - position = target - distance * view; - } + normalize(omega); + Quaternion conj = conjugate(omega); + front = omega * front * conj; + up = omega * up * conj; + right = omega * right * conj; + normalize(front); + normalize(up); + normalize(right); + //actualize camera position + position = target - distance * front; + this->update(); +} + +void Camera::move_and_look(double _movfront,double _movright,double _movup, + double _thetafront,double _thetaright,double _thetaup, + double _azimut,double _elevation) +{ + position= position + _movfront*front + _movright*right + _movup*up; + Quaternion omega_up; + omega_up.x = sin( _thetaup ) * up.x ; + omega_up.y = sin( _thetaup ) * up.y ; + omega_up.z = sin( _thetaup ) * up.z ; + omega_up.w = cos( _thetaup ); + normalize(omega_up); + Quaternion omega_right; + omega_right.x = sin( _thetaright ) * right.x ; + omega_right.y = sin( _thetaright ) * right.y ; + omega_right.z = sin( _thetaright ) * right.z ; + omega_right.w = cos( _thetaright ); + normalize(omega_right); + Quaternion omega_front; + omega_front.x = sin( _thetafront ) * front.x ; + omega_front.y = sin( _thetafront ) * front.y ; + omega_front.z = sin( _thetafront ) * front.z ; + omega_front.w = cos( _thetafront ); + normalize(omega_front); + Quaternion omega; + omega = omega_up * omega_right * omega_front; + normalize(omega); + Quaternion conj = conjugate(omega); + front = omega * front * conj; + up = omega * up * conj; + right = omega * right * conj; + normalize(front); + normalize(up); + normalize(right); this->update(); + // in azimuthal coordinates + XYZ look,newlook; + _elevation = std::min(_elevation,1.57); + _elevation = std::max(_elevation,-1.57); + look=cos(_azimut)*front-sin(_azimut)*right; + newlook=cos(_elevation)*look+sin(_elevation)*up; + target = position + distance * newlook; } -// Quaternion and XYZ functions + + + + + + + + + + + + +//////////////////////////////////////////////////////////////// +// QUATERNION and XYZ functions +//////////////////////////////////////////////////////////////// + double length(Quaternion &q) { - return sqrt(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w); + return sqrt(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w); } double length(XYZ &p) @@ -218,10 +318,26 @@ double length(XYZ &p) return sqrt(p.x * p.x + p.y * p.y + p.z * p.z); } -void normalize(Quaternion &quat) +void normalize_axe(Quaternion &q) +{ + double sina = sin(acos(q.w)); + double l; + if (sina != 0.){ + l = ( q.x*q.x + q.y*q.y + q.z*q.z ) / (sina*sina); + l =sqrt(l) ; + } + else{ + l = 0.; + } + if(l != 0. ){ + q.x /= l; q.y /= l; q.z /= l; + } +} +void normalize(Quaternion &q) { - double L = length(quat); - quat.x /= L; quat.y /= L; quat.z /= L; quat.w /= L; + double L = length(q); + q.x /= L; q.y /= L; q.z /= L; q.w /= L; + } void normalize(XYZ &p) @@ -234,6 +350,7 @@ XYZ::XYZ (const Quaternion &R) : x(R.x), y(R.y), z(R.z){} XYZ::XYZ(double _x,double _y,double _z) : x(_x),y(_y),z(_z){} + void XYZ::set(const double& _x, const double& _y, const double& _z){ x = _x; y =_y; z = _z; } void rotate(Quaternion omega,XYZ axe) @@ -270,9 +387,27 @@ XYZ operator- (const XYZ &L, const XYZ &R) res.z -= R.z; return res; } +XYZ operator- (const XYZ &R) +{ + XYZ res; + res.x = -R.x; + res.y = -R.y; + res.z = -R.z; + return res; +} Quaternion::Quaternion(const XYZ &R) : x(R.x), y(R.y), z(R.z), w(0.) {} +Quaternion::Quaternion(const XYZ &R, const double &A) { + x=R.x*sin(A); + y=R.y*sin(A); + z=R.z*sin(A); + w=cos(A); +} +Quaternion::Quaternion(): x(0.), y(0.),z(0.),w(1.) {} + +Quaternion::~Quaternion() {} + Quaternion mult(const Quaternion& A, const Quaternion& B) { Quaternion C; diff --git a/Graphics/Camera.h b/Graphics/Camera.h index a1b4c5714b8b71b42e24da51b5e67904283ef7de..bcad5599dd55bc2adf526fa12d6406c73e7ea122 100644 --- a/Graphics/Camera.h +++ b/Graphics/Camera.h @@ -26,13 +26,15 @@ void rotate(Quaternion omega,XYZ axe) ; XYZ operator* (const double &a,const XYZ &T); XYZ operator+ (const XYZ &L,const XYZ &R); XYZ operator- (const XYZ &L,const XYZ &R); +XYZ operator- (const XYZ &R); class Quaternion{ public: double x,y,z,w; - Quaternion(){}; - ~Quaternion(){}; + Quaternion(); Quaternion(const XYZ &R); + Quaternion(const XYZ &R, const double &A); + ~Quaternion(); }; double length(Quaternion &quat); @@ -43,9 +45,11 @@ Quaternion operator *(const Quaternion &A, const Quaternion &B); class Camera { public: + Camera(); + ~Camera(); bool on; XYZ position; /* camera position */ - XYZ view; /* View direction vector */ + XYZ front; /* View direction vector */ XYZ up; /* View up direction */ XYZ right; /* View right direction */ XYZ target; /* center of rotation and screen */ @@ -59,12 +63,15 @@ class Camera { bool stereoEnable; double Lc, eye_sep_ratio, closeness, ndfl, glFnear, glFfar, radians, wd2; double glFleft,glFright,glFtop,glFbottom; - Camera() : on(false), stereoEnable(false) {} - ~Camera(){} void giveViewportDimension(const int& W,const int& H); void lookAtCg(); void init(); void rotate(double* q); + // + void move_and_look(double _movfront,double _movright,double _movup, + double _rotfront,double _rotright,double _rotup, + double _azimut,double _elevation); + // void moveRight(double& theta); void moveUp(double& theta); void zoom(double& factor); @@ -73,6 +80,9 @@ class Camera { void alongX(); void alongY(); void alongZ(); + void upX(); + void upY(); + void upZ(); void tiltHeadLeft(); void tiltHeadRight(); }; diff --git a/Graphics/drawAxes.cpp b/Graphics/drawAxes.cpp index 49ff583f1c043804d4320e8915970b7fe63335cc..b6cc93d61a90e2e7eac0e588e1db1740b60c209f 100644 --- a/Graphics/drawAxes.cpp +++ b/Graphics/drawAxes.cpp @@ -380,6 +380,9 @@ void drawContext::drawSmallAxes() yy = l * fvViewMatrix[5]; zx = l * fvViewMatrix[8]; zy = l * fvViewMatrix[9]; + /// + + /// } else{ xx = l * rot[0]; diff --git a/Graphics/drawContext.cpp b/Graphics/drawContext.cpp index 41500f4df6ac3698154c3946555981031ba0cad2..b0f3a0a5b80631e375a084fe9038a43a631bb7a3 100644 --- a/Graphics/drawContext.cpp +++ b/Graphics/drawContext.cpp @@ -288,6 +288,7 @@ void drawContext::draw3d() drawPost(); } + void drawContext::draw2d() { glDisable(GL_DEPTH_TEST); @@ -306,15 +307,15 @@ void drawContext::draw2d() glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - drawGraph2d(); drawText2d(); - if(CTX::instance()->post.draw && !CTX::instance()->stereo) drawScales(); if(CTX::instance()->smallAxes) drawSmallAxes(); + + } void drawContext::drawBackgroundGradient() diff --git a/tutorial/t13.geo b/tutorial/t13.geo index 16f2acb6eca27b884b0e9750b5cc4bd7d453e90e..5f9bb7097ab3ad8c077cd77258ec8d1dfc70844c 100644 --- a/tutorial/t13.geo +++ b/tutorial/t13.geo @@ -1,51 +1,19 @@ -/********************************************************************* - * - * Gmsh tutorial 13 - * - * Remeshing STL with compounds - * - *********************************************************************/ - -// Since compound geometrical compute a new parametrization, one can -// also use them to remesh STL files, even if in this case there's -// usually only a single elementary geometrical entity per compound. - -// Let's merge the mesh that we would like to remesh. This mesh was -// reclassified ("colored") from an initial STL triangulation using -// the "Reclassify 2D" tool in Gmsh, so that we could split it along -// sharp geometrical features. -Merge "t13_data.msh"; - -// Since the original mesh is a bit coarse, we refine it once -RefineMesh; - -// Create the topology of the discrete model -CreateTopology; - -// We can now define a compound line (resp. surface) for each discrete -// line (resp. surface) in the model -ll[] = Line "*"; -For j In {0 : #ll[]-1} - Compound Line(newl) = ll[j]; -EndFor -ss[] = Surface "*"; -s = news; -For i In {0 : #ss[]-1} - Compound Surface(s+i) = ss[i]; -EndFor - -// And we can create the volume based on the new compound entities -Surface Loop(1) = {s : s + #ss[]-1}; -Volume(1) = {1}; - -Physical Surface(1) = {s : s + #ss[]-1}; -Physical Volume(1) = 1; - -// Apply a funny mesh size field, just because we can :-) -Field[1] = MathEval; -Field[1].F = "2*Sin((x+y)/5) + 3"; +cl1 = 0.01; +Point(1) = {0, 0, 0, 0.01}; +Point(2) = {0.1, 0, 0, 0.01}; +Point(3) = {0.1, 0.3, 0, 0.01}; +Point(4) = {0, 0.3, 0, 0.01}; +Line(1) = {1, 2}; +Line(2) = {3, 2}; +Line(3) = {3, 4}; +Line(4) = {4, 1}; +Line Loop(6) = {4, 1, -2, 3}; +Plane Surface(6) = {6}; +Physical Point(1) = {1, 2}; +MyLine = 99; +Physical Line(MyLine) = {1, 2, 4}; +Physical Surface("My fancy surface label") = {6}; +Field[1] = PostView; +Field[1].CropNegativeValues = 1; +Field[1].IView = 0; Background Field = 1; - -Mesh.RemeshAlgorithm = 1; // (0) no split (1) automatic (2) automatic only with metis -Mesh.RemeshParametrization = 7; // (0) harmonic (1) conformal spectral (7) conformal finite element -Geometry.HideCompounds = 0; // don't hide the compound entities