SimpleGUI.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This program is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU General Public License as published by the Free  *
00007 * Software Foundation; either version 2 of the License, or (at your option)   *
00008 * any later version.                                                          *
00009 *                                                                             *
00010 * This program is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    *
00013 * more details.                                                               *
00014 *                                                                             *
00015 * You should have received a copy of the GNU General Public License along     *
00016 * with this program; if not, write to the Free Software Foundation, Inc., 51  *
00017 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.                   *
00018 *******************************************************************************
00019 *                            SOFA :: Applications                             *
00020 *                                                                             *
00021 * Authors: M. Adam, J. Allard, B. Andre, P-J. Bensoussan, S. Cotin, C. Duriez,*
00022 * H. Delingette, F. Falipou, F. Faure, S. Fonteneau, L. Heigeas, C. Mendoza,  *
00023 * M. Nesme, P. Neumann, J-P. de la Plata Alcade, F. Poyer and F. Roy          *
00024 *                                                                             *
00025 * Contact information: contact@sofa-framework.org                             *
00026 ******************************************************************************/
00027 #include "SimpleGUI.h"
00028 #include <sofa/helper/system/config.h>
00029 #include <sofa/helper/system/FileRepository.h>
00030 #include <sofa/simulation/tree/Simulation.h>
00031 #include <sofa/simulation/common/MechanicalVisitor.h>
00032 #include <sofa/simulation/common/UpdateMappingVisitor.h>
00033 #include <sofa/core/objectmodel/KeypressedEvent.h>
00034 #include <sofa/core/objectmodel/KeyreleasedEvent.h>
00035 #include <sofa/helper/system/SetDirectory.h>
00036 #include <math.h>
00037 #include <iostream>
00038 #include <fstream>
00039 #include <string.h>
00040 #include <math.h>
00041 
00042 #include <sofa/helper/gl/glfont.h>
00043 #include <sofa/helper/gl/RAII.h>
00044 #include <sofa/helper/gl/GLSLShader.h>
00045 #include <sofa/helper/io/ImageBMP.h>
00046 
00047 #include <sofa/helper/system/thread/CTime.h>
00048 
00049 #include <sofa/defaulttype/RigidTypes.h>
00050 #include <sofa/defaulttype/LaparoscopicRigidTypes.h>
00051 
00052 #ifdef SOFA_HAVE_CHAI3D
00053 #include <sofa/simulation/common/PropagateEventVisitor.h>
00054 #include <sofa/core/objectmodel/GLInitializedEvent.h>
00055 #endif // SOFA_HAVE_CHAI3D
00056 
00057 // define this if you want video and OBJ capture to be only done once per N iteration
00058 //#define CAPTURE_PERIOD 5
00059 
00060 
00061 namespace sofa
00062 {
00063 
00064 namespace gui
00065 {
00066 
00067 namespace glut
00068 {
00069 
00070 using std::cout;
00071 using std::endl;
00072 using namespace sofa::defaulttype;
00073 using namespace sofa::helper::gl;
00074 using sofa::simulation::tree::getSimulation;
00075 
00076 
00077 SimpleGUI* SimpleGUI::instance = NULL;
00078 
00079 int SimpleGUI::mainLoop()
00080 {
00081     glutMainLoop();
00082     return 0;
00083 }
00084 
00085 void SimpleGUI::redraw()
00086 {
00087     glutPostRedisplay();
00088 }
00089 
00090 int SimpleGUI::closeGUI()
00091 {
00092     delete this;
00093     return 0;
00094 }
00095 
00096 
00097 SOFA_DECL_CLASS(SimpleGUI)
00098 
00099 int SimpleGUIClass = SofaGUI::RegisterGUI("glut", &SimpleGUI::CreateGUI, &SimpleGUI::InitGUI, 0);
00100 int SimpleGUI::InitGUI(const char* /*name*/, const std::vector<std::string>& /*options*/)
00101 {
00102     return 0;
00103 }
00104 
00105 SofaGUI* SimpleGUI::CreateGUI(const char* /*name*/, const std::vector<std::string>& /*options*/, sofa::simulation::Node* groot, const char* filename)
00106 {
00107 
00108     glutInitDisplayMode ( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
00109 
00110     //glutInitWindowPosition ( x0, y0 );
00111     //glutInitWindowSize ( nx, ny );
00112     glutCreateWindow ( ":: SOFA ::" );
00113 
00114 
00115 
00116     std::cout << "Window created:"
00117               << " red="<<glutGet(GLUT_WINDOW_RED_SIZE)
00118               << " green="<<glutGet(GLUT_WINDOW_GREEN_SIZE)
00119               << " blue="<<glutGet(GLUT_WINDOW_BLUE_SIZE)
00120               << " alpha="<<glutGet(GLUT_WINDOW_ALPHA_SIZE)
00121               << " depth="<<glutGet(GLUT_WINDOW_DEPTH_SIZE)
00122               << " stencil="<<glutGet(GLUT_WINDOW_STENCIL_SIZE)
00123               << std::endl;
00124 
00125     glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
00126     glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00127     glutSwapBuffers ();
00128     glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00129     glutSwapBuffers ();
00130 
00131     
00132     glutReshapeFunc ( glut_reshape );
00133     glutIdleFunc ( glut_idle );
00134     glutDisplayFunc ( glut_display );
00135     glutKeyboardFunc ( glut_keyboard );
00136     glutSpecialFunc ( glut_special );
00137     glutMouseFunc ( glut_mouse );
00138     glutMotionFunc ( glut_motion );
00139     glutPassiveMotionFunc ( glut_motion );
00140 
00141     SimpleGUI* gui = new SimpleGUI();
00142     gui->setScene(groot, filename);
00143 
00144     gui->initializeGL();
00145 
00146     #ifdef SOFA_HAVE_CHAI3D
00147     // Tell nodes that openGl is initialized
00148     // especialy the GL_MODELVIEW_MATRIX
00149     sofa::core::objectmodel::GLInitializedEvent ev;
00150     sofa::simulation::PropagateEventVisitor act(&ev);
00151     groot->execute(act);
00152     #endif // SOFA_HAVE_CHAI3D
00153 
00154     return gui;
00155 }
00156 
00157 
00158 
00159 void SimpleGUI::glut_display()
00160 {
00161     glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00162     if (instance)
00163     {
00164     instance->paintGL();
00165     }
00166     glutSwapBuffers ();
00167 }
00168 
00169 void SimpleGUI::glut_reshape(int w, int h)
00170 {
00171     if (instance)
00172     {
00173     instance->resizeGL(w,h);
00174     }
00175 }
00176 
00177 void SimpleGUI::glut_keyboard(unsigned char k, int, int)
00178 {
00179     if (instance)
00180     {
00181     instance->updateModifiers();
00182     instance->keyPressEvent(k);
00183     }
00184 }
00185 
00186 void SimpleGUI::glut_mouse(int button, int state, int x, int y)
00187 {
00188     if (instance)
00189     {
00190     instance->updateModifiers();
00191     instance->mouseEvent( (state==GLUT_DOWN?MouseButtonPress : MouseButtonRelease), x, y, button );
00192     }
00193 }
00194 
00195 void SimpleGUI::glut_motion(int x, int y)
00196 {
00197     if (instance)
00198     {
00199     //instance->updateModifiers();
00200     instance->mouseEvent( MouseMove, x, y, 0 );
00201     }
00202 }
00203 
00204 void SimpleGUI::glut_special(int k, int, int)
00205 {
00206     if (instance)
00207     {
00208     instance->updateModifiers();
00209     instance->keyPressEvent(k);
00210     }
00211 }
00212 
00213 void SimpleGUI::glut_idle()
00214 {
00215     if (instance)
00216     {
00217     if (instance->getScene() && instance->getScene()->getContext()->getAnimate())
00218         instance->step();
00219     else
00220         CTime::sleep(0.01);
00221     instance->animate();
00222     }
00223 }
00224 
00225 
00226 
00227 
00228 
00229 
00230 #ifdef SOFA_HAVE_GLEW
00231 
00232 // Shadow Mapping parameters
00233 
00234 // These store our width and height for the shadow texture
00235 enum { SHADOW_WIDTH = 512 };
00236 enum { SHADOW_HEIGHT = 512 };
00237 enum { SHADOW_MASK_SIZE = 2048 };
00238 
00239 // This is used to set the mode with glTexParameteri() for comparing depth values.
00240 // We use GL_COMPARE_R_TO_TEXTURE_ARB as our mode.  R is used to represent the depth value.
00241 #define GL_TEXTURE_COMPARE_MODE_ARB       0x884C
00242 
00243 // This is used to set the function with glTexParameteri() to tell OpenGL how we
00244 // will compare the depth values (we use GL_LEQUAL (less than or equal)).
00245 #define GL_TEXTURE_COMPARE_FUNC_ARB       0x884D
00246 
00247 // This mode is what will compare our depth values for shadow mapping
00248 #define GL_COMPARE_R_TO_TEXTURE_ARB       0x884E
00249 
00250 // The texture array where we store our image data
00251 GLuint g_DepthTexture;
00252 
00253 // This is our global shader object that will load the shader files
00254 GLSLShader g_Shader;
00255 
00256 //float g_DepthOffset[2] = { 3.0f, 0.0f };
00257 float g_DepthOffset[2] = { 10.0f, 0.0f };
00258 float g_DepthBias[2] = { 0.0f, 0.0f };
00259 
00260 // These are the light's matrices that need to be stored
00261 float g_mProjection[16] = {0};
00262 float g_mModelView[16] = {0};
00263 //float g_mCameraInverse[16] = {0};
00264 
00265 GLuint ShadowTextureMask;
00266 
00267 // End of Shadow Mapping Parameters
00268 #endif // SOFA_HAVE_GLEW
00269 
00270 // ---------------------------------------------------------
00271 // --- Constructor
00272 // ---------------------------------------------------------
00273 SimpleGUI::SimpleGUI()
00274 {
00275     instance = this;
00276 
00277     groot = NULL;                
00278     initTexturesDone = false;
00279     // setup OpenGL mode for the window
00280 
00281     _previousEyePos = Vector3(0.0, 0.0, 0.0);
00282     _zoom = 1.0;
00283     _zoomSpeed = 250.0;
00284     _panSpeed = 25.0;
00285     _navigationMode = TRACKBALL_MODE;
00286     _spinning = false;
00287     _moving = false;
00288     _video = false;
00289     _animationOBJ = false;
00290     _axis = false;
00291     _background = 0;
00292     _shadow = false;
00293     _numOBJmodels = 0;
00294     _materialMode = 0;
00295     _facetNormal = GL_FALSE;
00296     _renderingMode = GL_RENDER;
00297     _waitForRender = false;
00298     _mouseTrans = false;
00299     _mouseRotate = false;
00300     sceneBBoxIsValid = false;
00301     texLogo = NULL;
00302 
00303     /*_surfaceModel = NULL;
00304     _springMassView = NULL;
00305     _mapView = NULL;
00306     sphViewer = NULL;
00307     */
00308     _arrow = gluNewQuadric();
00309     gluQuadricDrawStyle(_arrow, GLU_FILL);
00310     gluQuadricOrientation(_arrow, GLU_OUTSIDE);
00311     gluQuadricNormals(_arrow, GLU_SMOOTH);
00312 
00313     _tube = gluNewQuadric();
00314     gluQuadricDrawStyle(_tube, GLU_FILL);
00315     gluQuadricOrientation(_tube, GLU_OUTSIDE);
00316     gluQuadricNormals(_tube, GLU_SMOOTH);
00317 
00318     _sphere = gluNewQuadric();
00319     gluQuadricDrawStyle(_sphere, GLU_FILL);
00320     gluQuadricOrientation(_sphere, GLU_OUTSIDE);
00321     gluQuadricNormals(_sphere, GLU_SMOOTH);
00322 
00323     _disk = gluNewQuadric();
00324     gluQuadricDrawStyle(_disk, GLU_FILL);
00325     gluQuadricOrientation(_disk, GLU_OUTSIDE);
00326     gluQuadricNormals(_disk, GLU_SMOOTH);
00327 
00328     // init trackball rotation matrix / quaternion
00329     _newTrackball.ComputeQuaternion(0.0, 0.0, 0.0, 0.0);
00330     _newQuat = _newTrackball.GetQuaternion();
00331 
00333     // Interactor //
00335     _mouseInteractorMoving = false;
00336     _mouseInteractorTranslationMode = false;
00337     _mouseInteractorRotationMode = false;
00338     _mouseInteractorSavedPosX = 0;
00339     _mouseInteractorSavedPosY = 0;
00340     _mouseInteractorTrackball.ComputeQuaternion(0.0, 0.0, 0.0, 0.0);
00341     _mouseInteractorNewQuat = _mouseInteractorTrackball.GetQuaternion();
00342 
00343     interactor = NULL;
00344         
00346     m_isControlPressed = false;
00347     m_isShiftPressed = false;
00348     m_isAltPressed = false;
00349     m_dumpState = false;
00350     m_dumpStateStream = 0;
00351     m_displayComputationTime = false;
00352     m_exportGnuplot = false;
00353 
00354 }
00355 
00356 
00357 // ---------------------------------------------------------
00358 // --- Destructor
00359 // ---------------------------------------------------------
00360 SimpleGUI::~SimpleGUI()
00361 {
00362     if (instance == this) instance = NULL;
00363 }
00364 
00365 // -----------------------------------------------------------------
00366 // --- OpenGL initialization method - includes light definitions, 
00367 // --- color tracking, etc.
00368 // -----------------------------------------------------------------
00369 void SimpleGUI::initializeGL(void)
00370 {
00371     static GLfloat    specref[4];
00372     static GLfloat    ambientLight[4];
00373     static GLfloat    diffuseLight[4];
00374     static GLfloat    specular[4];
00375     static GLfloat    lmodel_ambient[]    ={0.0f, 0.0f, 0.0f, 0.0f};
00376     static GLfloat    lmodel_twoside[]    ={GL_FALSE};
00377     static GLfloat    lmodel_local[]        ={GL_FALSE};
00378     static bool        initialized            = false;
00379 
00380     if (!initialized)
00381     {
00382         // Define light parameters
00383         //_lightPosition[0] = 0.0f;
00384         //_lightPosition[1] = 10.0f;
00385         //_lightPosition[2] = 0.0f;
00386         //_lightPosition[3] = 1.0f;
00387 
00388         _lightPosition[0] = -0.7f;
00389         _lightPosition[1] = 0.3f;
00390         _lightPosition[2] = 0.0f;
00391         _lightPosition[3] = 1.0f;
00392 
00393         ambientLight[0] = 0.5f;
00394         ambientLight[1] = 0.5f;
00395         ambientLight[2] = 0.5f;
00396         ambientLight[3] = 1.0f;
00397 
00398         diffuseLight[0] = 0.9f;
00399         diffuseLight[1] = 0.9f;
00400         diffuseLight[2] = 0.9f;
00401         diffuseLight[3] = 1.0f;
00402 
00403         specular[0] = 1.0f;
00404         specular[1] = 1.0f;
00405         specular[2] = 1.0f;
00406         specular[3] = 1.0f;
00407 
00408         specref[0] = 1.0f;
00409         specref[1] = 1.0f;
00410         specref[2] = 1.0f;
00411         specref[3] = 1.0f;
00412         // Here we initialize our multi-texturing functions
00413 #ifdef SOFA_HAVE_GLEW
00414         glewInit();
00415         if (!GLEW_ARB_multitexture)
00416             std::cerr << "Error: GL_ARB_multitexture not supported\n";
00417 #endif
00418 
00419         _clearBuffer = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
00420         _lightModelTwoSides = false;
00421 
00422         glDepthFunc(GL_LEQUAL);
00423         glClearDepth(1.0);
00424         glEnable(GL_NORMALIZE);
00425 
00426         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
00427 
00428         // Set light model
00429         glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, lmodel_local);
00430         glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
00431         glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
00432 
00433         // Setup 'light 0'
00434         glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
00435         glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
00436         glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
00437         glLightfv(GL_LIGHT0, GL_POSITION, _lightPosition);
00438 
00439         // Enable color tracking
00440         glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
00441 
00442         // All materials hereafter have full specular reflectivity with a high shine
00443         glMaterialfv(GL_FRONT, GL_SPECULAR, specref);
00444         glMateriali(GL_FRONT, GL_SHININESS, 128);
00445 
00446         glShadeModel(GL_SMOOTH);
00447 
00448         // Define background color
00449         glClearColor(0.0589f, 0.0589f, 0.0589f, 1.0f);
00450 
00451         //glBlendFunc(GL_SRC_ALPHA, GL_ONE);
00452         //Load texture for logo
00453     texLogo = new helper::gl::Texture(new helper::io::ImageBMP( sofa::helper::system::DataRepository.getFile("textures/SOFA_logo.bmp")));
00454          texLogo->init();
00455 
00456         glEnableClientState(GL_VERTEX_ARRAY);
00457         glEnableClientState(GL_NORMAL_ARRAY);
00458 
00459         // Turn on our light and enable color along with the light
00460         //glEnable(GL_LIGHTING);
00461         glEnable(GL_LIGHT0);
00462         //glEnable(GL_COLOR_MATERIAL);
00463 
00464 #ifdef SOFA_HAVE_GLEW
00465         // Here we allocate memory for our depth texture that will store our light's view
00466         CreateRenderTexture(g_DepthTexture, SHADOW_WIDTH, SHADOW_HEIGHT, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT);
00467         CreateRenderTexture(ShadowTextureMask, SHADOW_MASK_SIZE, SHADOW_MASK_SIZE, GL_LUMINANCE, GL_LUMINANCE);
00468         
00469         if (_glshadow == GLSLShader::InitGLSL())
00470         {
00471             // Here we pass in our new vertex and fragment shader files to our shader object.
00472         g_Shader.InitShaders(sofa::helper::system::DataRepository.getFile("shaders/ShadowMappingPCF.vert"), sofa::helper::system::DataRepository.getFile("shaders/ShadowMappingPCF.frag"));
00473         }else
00474 #endif
00475         {
00476             printf("WARNING SimpleGUI : shadows are not supported !\n");
00477             _shadow = false;
00478         }
00479 
00480         // change status so we only do this stuff once
00481         initialized = true;
00482 
00483         _beginTime = CTime::getTime();
00484 
00485         printf("\n");
00486     }
00487 
00488     // switch to preset view
00489     SwitchToPresetView();
00490 }
00491 
00492 // ---------------------------------------------------------
00493 // ---
00494 // ---------------------------------------------------------
00495 
00501 
00502 void SimpleGUI::StoreLightMatrices()
00503 {    
00504     //    _lightPosition[0] =  _sceneTransform.translation[0] + 10;//*cosf(TT);
00505     //    _lightPosition[1] =  _sceneTransform.translation[1] + 10;//*sinf(2*TT);
00506     //    _lightPosition[2] =  _sceneTransform.translation[2] + 35;//
00507 
00508     //_lightPosition[0] =  1;
00509     //_lightPosition[1] =  -10;
00510     //_lightPosition[2] =  0;
00511 
00512     // Reset our current light matrices
00513     memset(g_mModelView, 0, sizeof(float)*16);
00514     memset(g_mProjection, 0, sizeof(float)*16);
00515 
00516     g_mModelView[0] = 1; // identity
00517     g_mModelView[5] = 1;
00518     g_mModelView[10] = 1;
00519     g_mModelView[15] = 1;
00520 
00521     // Using perpective shadow map for the "miner lamp" case ( i.e. light.z == 0 )
00522     // which is just a "rotation" in sceen space
00523 
00524     float lx = -_lightPosition[0] * lastProjectionMatrix[0] - _lightPosition[1] * lastProjectionMatrix[4] + lastProjectionMatrix[12];
00525     float ly = -_lightPosition[0] * lastProjectionMatrix[1] - _lightPosition[1] * lastProjectionMatrix[5] + lastProjectionMatrix[13];
00526     float lz = -_lightPosition[0] * lastProjectionMatrix[2] - _lightPosition[1] * lastProjectionMatrix[6] + lastProjectionMatrix[14];
00527     //float lw = -_lightPosition[0] * lastProjectionMatrix[3] - _lightPosition[1] * lastProjectionMatrix[7] + lastProjectionMatrix[15];
00528     //std::cout << "lx = "<<lx<<" ly = "<<ly<<" lz = "<<lz<<" lw = "<<lw<<std::endl;
00529 
00530     Vector3 l(-lx,-ly,-lz);
00531     Vector3 y;
00532     y = l.cross(Vector3(1,0,0));
00533     Vector3 x;
00534     x = y.cross(l);
00535     l.normalize();
00536     y.normalize();
00537     x.normalize();
00538 
00539     g_mProjection[ 0] = x[0]; g_mProjection[ 4] = x[1]; g_mProjection[ 8] = x[2]; g_mProjection[12] =    0;
00540     g_mProjection[ 1] = y[0]; g_mProjection[ 5] = y[1]; g_mProjection[ 9] = y[2]; g_mProjection[13] =    0;
00541     g_mProjection[ 2] = l[0]; g_mProjection[ 6] = l[1]; g_mProjection[10] = l[2]; g_mProjection[14] =    0;
00542     g_mProjection[ 3] =    0; g_mProjection[ 7] =    0; g_mProjection[11] =    0; g_mProjection[15] =    1;
00543 
00544     g_mProjection[ 0] = x[0]; g_mProjection[ 4] = y[0]; g_mProjection[ 8] = l[0]; g_mProjection[12] =    0;
00545     g_mProjection[ 1] = x[1]; g_mProjection[ 5] = y[1]; g_mProjection[ 9] = l[1]; g_mProjection[13] =    0;
00546     g_mProjection[ 2] = x[2]; g_mProjection[ 6] = y[2]; g_mProjection[10] = l[2]; g_mProjection[14] =    0;
00547     g_mProjection[ 3] =    0; g_mProjection[ 7] =    0; g_mProjection[11] =    0; g_mProjection[15] =    1;
00548 
00549     glPushMatrix();{
00550 
00551         glLoadIdentity();
00552         glScaled(1.0/(fabs(g_mProjection[0])+fabs(g_mProjection[4])+fabs(g_mProjection[8])),
00553             1.0/(fabs(g_mProjection[1])+fabs(g_mProjection[5])+fabs(g_mProjection[9])),
00554             1.0/(fabs(g_mProjection[2])+fabs(g_mProjection[6])+fabs(g_mProjection[10])));
00555         glMultMatrixf(g_mProjection);
00556         glMultMatrixd(lastProjectionMatrix);
00557         
00558         // Grab the current matrix that will be used for the light's projection matrix
00559         glGetFloatv(GL_MODELVIEW_MATRIX, g_mProjection);
00560 
00561         // Go back to the original matrix
00562     }glPopMatrix();
00563 
00564     /*
00565     // Let's push on a new matrix so we don't change the rest of the world
00566     glPushMatrix();{
00567 
00568         // Reset the current modelview matrix
00569         glLoadIdentity();
00570         
00571         // This is where we set the light's position and view.
00572         gluLookAt(_lightPosition[0],  _lightPosition[1],  _lightPosition[2], 
00573         _sceneTransform.translation[0],       _sceneTransform.translation[1],        _sceneTransform.translation[2],        0, 1, 0);
00574 
00575         // Now that we have the light's view, let's save the current modelview matrix.
00576         glGetFloatv(GL_MODELVIEW_MATRIX, g_mModelView);
00577 
00578         // Reset the current matrix
00579         glLoadIdentity();
00580 
00581         // Set our FOV, aspect ratio, then near and far planes for the light's view
00582         gluPerspective(90.0f, 1.0f, 4.0f, 250.0f);
00583 
00584         // Grab the current matrix that will be used for the light's projection matrix
00585         glGetFloatv(GL_MODELVIEW_MATRIX, g_mProjection);
00586 
00587         // Go back to the original matrix
00588     }glPopMatrix();
00589     */
00590 }
00591 
00597 
00598 void SimpleGUI::CreateRenderTexture(GLuint& textureID, int sizeX, int sizeY, int channels, int type)
00599 {
00600     glGenTextures(1, &textureID);                                
00601     glBindTexture(GL_TEXTURE_2D, textureID);
00602 
00603     // Create the texture and store it on the video card
00604     glTexImage2D(GL_TEXTURE_2D, 0, channels, sizeX, sizeY, 0, type, GL_UNSIGNED_INT, NULL);
00605 
00606     // Set the texture quality
00607     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
00608     glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
00609     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
00610     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
00611 }
00612 
00618 
00619 void SimpleGUI::ApplyShadowMap()
00620 {                
00621 #ifdef SOFA_HAVE_GLEW
00622     // Let's turn our shaders on for doing shadow mapping on our world
00623     g_Shader.TurnOn();
00624 
00625     // Turn on our texture unit for shadow mapping and bind our depth texture
00626     glActiveTextureARB(GL_TEXTURE1_ARB);
00627     glEnable(GL_TEXTURE_2D); 
00628     glBindTexture(GL_TEXTURE_2D, g_DepthTexture);
00629 
00630     // Give GLSL our texture unit that holds the shadow map
00631     g_Shader.SetInt(g_Shader.GetVariable("shadowMap"), 1);
00632     //g_Shader.SetInt(g_Shader.GetVariable("tex"), 0);
00633 
00634     // Here is where we set the mode and function for shadow mapping with shadow2DProj().
00635 
00636     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00637     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00638     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,     GL_CLAMP_TO_EDGE);
00639     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,     GL_CLAMP_TO_EDGE);
00640     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
00641         GL_COMPARE_R_TO_TEXTURE_ARB);
00642 
00643     //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
00644 
00645     // Create our bias matrix to have a 0 to 1 ratio after clip space
00646     const float mBias[] = {0.5, 0.0, 0.0, 0.0, 
00647         0.0, 0.5, 0.0, 0.0,
00648         0.0, 0.0, 0.5+g_DepthBias[0], 0.0,
00649         0.5, 0.5, 0.5+g_DepthBias[1], 1.0};
00650 
00651     glMatrixMode(GL_TEXTURE);
00652 
00653     glLoadMatrixf(mBias);            // The bias matrix to convert to a 0 to 1 ratio
00654     glMultMatrixf(g_mProjection);    // The light's projection matrix
00655     glMultMatrixf(g_mModelView);    // The light's modelview matrix
00656     //glMultMatrixf(g_mCameraInverse);// The inverse modelview matrix
00657 
00658     glMatrixMode(GL_MODELVIEW);            // Switch back to normal modelview mode
00659 
00660     glActiveTextureARB(GL_TEXTURE0_ARB);
00661 
00662     // Render the world that needs to be shadowed
00663 
00664     glPushMatrix();
00665     {
00666         glLoadIdentity();
00667         _sceneTransform.Apply();
00668         glGetDoublev(GL_MODELVIEW_MATRIX,lastModelviewMatrix);
00669         DisplayOBJs();
00670     }
00671     glPopMatrix();
00672 
00673     // Reset the texture matrix
00674     glMatrixMode(GL_TEXTURE);
00675     glLoadIdentity();
00676     glMatrixMode(GL_MODELVIEW);
00677 
00678     // Turn the first multi-texture pass off
00679     
00680     glActiveTextureARB(GL_TEXTURE1_ARB);
00681     glDisable(GL_TEXTURE_2D);
00682     glActiveTextureARB(GL_TEXTURE0_ARB);
00683 
00684     // Light expected, we need to turn our shader off since we are done
00685     g_Shader.TurnOff();
00686 #endif
00687 }
00688 
00689 // ---------------------------------------------------------
00690 // ---
00691 // ---------------------------------------------------------
00692 void SimpleGUI::PrintString(void* font, char* string)
00693 {
00694     int    len, i;
00695 
00696     len = (int) strlen(string);
00697     for (i = 0; i < len; i++)
00698     {
00699         glutBitmapCharacter(font, string[i]);
00700     }
00701 }
00702 
00703 // ---------------------------------------------------------
00704 // ---
00705 // ---------------------------------------------------------
00706 void SimpleGUI::Display3DText(float x, float y, float z, char* string)
00707 {
00708     char*    c;
00709 
00710     glPushMatrix();
00711     glTranslatef(x, y, z);
00712     for (c = string; *c != '\0'; c++)
00713     {
00714         glutStrokeCharacter(GLUT_STROKE_ROMAN, *c);
00715     }
00716     glPopMatrix();
00717 }
00718 
00719 // ---------------------------------------------------
00720 // --- 
00721 // --- 
00722 // ---------------------------------------------------
00723 void SimpleGUI::DrawAxis(double xpos, double ypos, double zpos,
00724     double arrowSize)
00725 {
00726     float    fontScale    = (float) (arrowSize / 600.0);
00727 
00728     Enable<GL_DEPTH_TEST> depth;
00729     Enable<GL_LIGHTING> lighting;
00730     Enable<GL_COLOR_MATERIAL> colorMat;
00731 
00732     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00733     glShadeModel(GL_SMOOTH);
00734 
00735     // --- Draw the "X" axis in red
00736     glPushMatrix();
00737     glColor3f(1.0, 0.0, 0.0);
00738     glTranslated(xpos, ypos, zpos);
00739     glRotatef(90.0f, 0.0, 1.0, 0.0);
00740     gluCylinder(_tube, arrowSize / 50.0, arrowSize / 50.0, arrowSize, 10, 10);
00741     glTranslated(0.0, 0.0, arrowSize);
00742     gluCylinder(_arrow, arrowSize / 15.0, 0.0, arrowSize / 5.0, 10, 10);
00743     // ---- Display a "X" near the tip of the arrow
00744     glTranslated(-0.5 * fontScale * (double)
00745         glutStrokeWidth(GLUT_STROKE_ROMAN, 88),
00746         arrowSize / 15.0, arrowSize /
00747         5.0);
00748     glLineWidth(3.0);
00749     glScalef(fontScale, fontScale, fontScale);
00750     glutStrokeCharacter(GLUT_STROKE_ROMAN, 88);
00751     glScalef(1.0f / fontScale, 1.0f / fontScale, 1.0f / fontScale);
00752     glLineWidth(1.0f);
00753     // --- Undo transforms
00754     glTranslated(-xpos, -ypos, -zpos);
00755     glPopMatrix();
00756 
00757     // --- Draw the "Y" axis in green
00758     glPushMatrix();
00759     glColor3f(0.0, 1.0, 0.0);
00760     glTranslated(xpos, ypos, zpos);
00761     glRotatef(-90.0f, 1.0, 0.0, 0.0);
00762     gluCylinder(_tube, arrowSize / 50.0, arrowSize / 50.0, arrowSize, 10, 10);
00763     glTranslated(0.0, 0.0, arrowSize);
00764     gluCylinder(_arrow, arrowSize / 15.0, 0.0, arrowSize / 5.0, 10, 10);
00765     // ---- Display a "Y" near the tip of the arrow
00766     glTranslated(-0.5 * fontScale * (double)
00767         glutStrokeWidth(GLUT_STROKE_ROMAN, 89),
00768         arrowSize / 15.0, arrowSize /
00769         5.0);
00770     glLineWidth(3.0);
00771     glScalef(fontScale, fontScale, fontScale);
00772     glutStrokeCharacter(GLUT_STROKE_ROMAN, 89);
00773     glScalef(1.0f / fontScale, 1.0f / fontScale, 1.0f / fontScale);
00774     glLineWidth(1.0);
00775     // --- Undo transforms
00776     glTranslated(-xpos, -ypos, -zpos);
00777     glPopMatrix();
00778 
00779     // --- Draw the "Z" axis in blue
00780     glPushMatrix();
00781     glColor3f(0.0, 0.0, 1.0);
00782     glTranslated(xpos, ypos, zpos);
00783     glRotatef(0.0f, 1.0, 0.0, 0.0);
00784     gluCylinder(_tube, arrowSize / 50.0, arrowSize / 50.0, arrowSize, 10, 10);
00785     glTranslated(0.0, 0.0, arrowSize);
00786     gluCylinder(_arrow, arrowSize / 15.0, 0.0, arrowSize / 5.0, 10, 10);
00787     // ---- Display a "Z" near the tip of the arrow
00788     glTranslated(-0.5 * fontScale * (double)
00789         glutStrokeWidth(GLUT_STROKE_ROMAN, 90),
00790         arrowSize / 15.0, arrowSize /
00791         5.0);
00792     glLineWidth(3.0);
00793     glScalef(fontScale, fontScale, fontScale);
00794     glutStrokeCharacter(GLUT_STROKE_ROMAN, 90);
00795     glScalef(1.0f / fontScale, 1.0f / fontScale, 1.0f / fontScale);
00796     glLineWidth(1.0);
00797     // --- Undo transforms
00798     glTranslated(-xpos, -ypos, -zpos);
00799     glPopMatrix();
00800 }
00801 
00802 // ---------------------------------------------------
00803 // --- 
00804 // --- 
00805 // ---------------------------------------------------
00806 void SimpleGUI::DrawBox(double* minBBox, double* maxBBox, double r)
00807 {
00808     //std::cout << "box = < " << minBBox[0] << ' ' << minBBox[1] << ' ' << minBBox[2] << " >-< " << maxBBox[0] << ' ' << maxBBox[1] << ' ' << maxBBox[2] << " >"<< std::endl;
00809     if (r==0.0)
00810         r = (Vector3(maxBBox) - Vector3(minBBox)).norm() / 500;
00811 #if 0
00812     {
00813         Enable<GL_DEPTH_TEST> depth;
00814         Disable<GL_LIGHTING> lighting;
00815         glColor3f(0.0, 1.0, 1.0);
00816         glBegin(GL_LINES);
00817             for (int corner=0; corner<4; ++corner)
00818             {
00819                 glVertex3d(           minBBox[0]           ,
00820                            (corner&1)?minBBox[1]:maxBBox[1],
00821                            (corner&2)?minBBox[2]:maxBBox[2]);
00822                 glVertex3d(           maxBBox[0]           ,
00823                            (corner&1)?minBBox[1]:maxBBox[1],
00824                            (corner&2)?minBBox[2]:maxBBox[2]);
00825             }
00826             for (int corner=0; corner<4; ++corner)
00827             {
00828                 glVertex3d((corner&1)?minBBox[0]:maxBBox[0],
00829                                       minBBox[1]           ,
00830                            (corner&2)?minBBox[2]:maxBBox[2]);
00831                 glVertex3d((corner&1)?minBBox[0]:maxBBox[0],
00832                                       maxBBox[1]           ,
00833                            (corner&2)?minBBox[2]:maxBBox[2]);
00834             }
00835         
00836             // --- Draw the Z edges
00837             for (int corner=0; corner<4; ++corner)
00838             {
00839                 glVertex3d((corner&1)?minBBox[0]:maxBBox[0],
00840                            (corner&2)?minBBox[1]:maxBBox[1],
00841                                       minBBox[2]           );
00842                 glVertex3d((corner&1)?minBBox[0]:maxBBox[0],
00843                            (corner&2)?minBBox[1]:maxBBox[1],
00844                                       maxBBox[2]           );
00845             }
00846         glEnd();
00847         return;
00848     }
00849 #endif
00850     Enable<GL_DEPTH_TEST> depth;
00851     Enable<GL_LIGHTING> lighting;
00852     Enable<GL_COLOR_MATERIAL> colorMat;
00853 
00854     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00855     glShadeModel(GL_SMOOTH);
00856 
00857     // --- Draw the corners
00858     glColor3f(0.0, 1.0, 1.0);
00859     for (int corner=0; corner<8; ++corner)
00860     {
00861         glPushMatrix();
00862         glTranslated((corner&1)?minBBox[0]:maxBBox[0],
00863                      (corner&2)?minBBox[1]:maxBBox[1],
00864                      (corner&4)?minBBox[2]:maxBBox[2]);
00865         gluSphere(_sphere,2*r,20,10);
00866         glPopMatrix();
00867     }
00868 
00869     glColor3f(1.0, 1.0, 0.0);
00870     // --- Draw the X edges
00871     for (int corner=0; corner<4; ++corner)
00872     {
00873         glPushMatrix();
00874         glTranslated(           minBBox[0]           ,
00875                      (corner&1)?minBBox[1]:maxBBox[1],
00876                      (corner&2)?minBBox[2]:maxBBox[2]);
00877         glRotatef(90,0,1,0);
00878         gluCylinder(_tube, r, r, maxBBox[0] - minBBox[0], 10, 10);
00879         glPopMatrix();
00880     }
00881 
00882     // --- Draw the Y edges
00883     for (int corner=0; corner<4; ++corner)
00884     {
00885         glPushMatrix();
00886         glTranslated((corner&1)?minBBox[0]:maxBBox[0],
00887                                 minBBox[1]           ,
00888                      (corner&2)?minBBox[2]:maxBBox[2]);
00889         glRotatef(-90,1,0,0);
00890         gluCylinder(_tube, r, r, maxBBox[1] - minBBox[1], 10, 10);
00891         glPopMatrix();
00892     }
00893 
00894     // --- Draw the Z edges
00895     for (int corner=0; corner<4; ++corner)
00896     {
00897         glPushMatrix();
00898         glTranslated((corner&1)?minBBox[0]:maxBBox[0],
00899                      (corner&2)?minBBox[1]:maxBBox[1],
00900                                 minBBox[2]           );
00901         gluCylinder(_tube, r, r, maxBBox[2] - minBBox[2], 10, 10);
00902         glPopMatrix();
00903     }
00904 }
00905 
00906 
00907 // ----------------------------------------------------------------------------------
00908 // --- Draw a "plane" in wireframe. The "plane" is parallel to the XY axis
00909 // --- of the main coordinate system 
00910 // ----------------------------------------------------------------------------------
00911 void SimpleGUI::DrawXYPlane(double zo, double xmin, double xmax, double ymin,
00912     double ymax, double step)
00913 {
00914     register double x, y;
00915 
00916     Enable<GL_DEPTH_TEST> depth;
00917 
00918     glBegin(GL_LINES);
00919     for (x = xmin; x <= xmax; x += step)
00920     {
00921         glVertex3d(x, ymin, zo);
00922         glVertex3d(x, ymax, zo);
00923     }
00924     glEnd();
00925 
00926     glBegin(GL_LINES);
00927     for (y = ymin; y <= ymax; y += step)
00928     {
00929         glVertex3d(xmin, y, zo);
00930         glVertex3d(xmax, y, zo);
00931     }
00932     glEnd();
00933 }
00934 
00935 
00936 // ----------------------------------------------------------------------------------
00937 // --- Draw a "plane" in wireframe. The "plane" is parallel to the XY axis
00938 // --- of the main coordinate system 
00939 // ----------------------------------------------------------------------------------
00940 void SimpleGUI::DrawYZPlane(double xo, double ymin, double ymax, double zmin,
00941     double zmax, double step)
00942 {
00943     register double y, z;
00944     Enable<GL_DEPTH_TEST> depth;
00945 
00946     glBegin(GL_LINES);
00947     for (y = ymin; y <= ymax; y += step)
00948     {
00949         glVertex3d(xo, y, zmin);
00950         glVertex3d(xo, y, zmax);
00951     }
00952     glEnd();
00953 
00954     glBegin(GL_LINES);
00955     for (z = zmin; z <= zmax; z += step)
00956     {
00957         glVertex3d(xo, ymin, z);
00958         glVertex3d(xo, ymax, z);
00959     }
00960     glEnd();
00961 
00962 }
00963 
00964 
00965 // ----------------------------------------------------------------------------------
00966 // --- Draw a "plane" in wireframe. The "plane" is parallel to the XY axis
00967 // --- of the main coordinate system 
00968 // ----------------------------------------------------------------------------------
00969 void SimpleGUI::DrawXZPlane(double yo, double xmin, double xmax, double zmin,
00970     double zmax, double step)
00971 {
00972     register double x, z;
00973     Enable<GL_DEPTH_TEST> depth;
00974 
00975     glBegin(GL_LINES);
00976     for (x = xmin; x <= xmax; x += step)
00977     {
00978         glVertex3d(x, yo, zmin);
00979         glVertex3d(x, yo, zmax);
00980     }
00981     glEnd();
00982 
00983     glBegin(GL_LINES);
00984     for (z = zmin; z <= zmax; z += step)
00985     {
00986         glVertex3d(xmin, yo, z);
00987         glVertex3d(xmax, yo, z);
00988     }
00989     glEnd();
00990 }
00991 
00992 // -------------------------------------------------------------------
00993 // ---
00994 // -------------------------------------------------------------------
00995 void SimpleGUI::DrawLogo()
00996 {
00997     int w = 0;
00998     int h = 0; 
00999 
01000     if (texLogo && texLogo->getImage()) {
01001         h = texLogo->getImage()->getHeight();
01002         w = texLogo->getImage()->getWidth();
01003     }
01004     else return;
01005 
01006     Enable <GL_TEXTURE_2D> tex;
01007     glDisable(GL_DEPTH_TEST);
01008     glMatrixMode(GL_PROJECTION);
01009     glPushMatrix();
01010     glLoadIdentity();
01011     glOrtho(-0.5, _W, -0.5, _H, -1.0, 1.0);
01012     glMatrixMode(GL_MODELVIEW);
01013     glLoadIdentity();
01014 
01015     if (texLogo)
01016         texLogo->bind();
01017 
01018     glColor3f(1.0f, 1.0f, 1.0f);
01019     glBegin(GL_QUADS);
01020     glTexCoord2d(0.0, 0.0);
01021     glVertex3d((_W-w)/2, (_H-h)/2, 0.0);
01022 
01023     glTexCoord2d(1.0, 0.0);
01024     glVertex3d( _W-(_W-w)/2, (_H-h)/2, 0.0);
01025 
01026     glTexCoord2d(1.0, 1.0);
01027     glVertex3d( _W-(_W-w)/2, _H-(_H-h)/2, 0.0);
01028 
01029     glTexCoord2d(0.0, 1.0);
01030     glVertex3d((_W-w)/2, _H-(_H-h)/2, 0.0);
01031     glEnd();
01032 
01033     glBindTexture(GL_TEXTURE_2D, 0);    
01034 
01035     glMatrixMode(GL_PROJECTION);
01036     glPopMatrix();
01037     glMatrixMode(GL_MODELVIEW);
01038 }
01039 
01040 // -------------------------------------------------------------------
01041 // ---
01042 // -------------------------------------------------------------------
01043 void SimpleGUI::DisplayOBJs(bool shadowPass)
01044 {
01045     
01046     Enable<GL_LIGHTING> light;
01047     Enable<GL_DEPTH_TEST> depth;
01048     
01049     glShadeModel(GL_SMOOTH);
01050     //glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
01051     glColor4f(1,1,1,1);
01052     glDisable(GL_COLOR_MATERIAL);
01053     
01054     if (!initTexturesDone)
01055     {
01056 //         std::cout << "-----------------------------------> initTexturesDone\n";
01057         //---------------------------------------------------
01058         simulation::tree::getSimulation()->initTextures(groot);
01059         //---------------------------------------------------
01060         initTexturesDone = true;
01061     }
01062     
01063     {
01064         if (shadowPass)
01065             getSimulation()->drawShadows(groot);
01066         else
01067             getSimulation()->draw(groot);
01068         if (_axis)
01069         {
01070             DrawAxis(0.0, 0.0, 0.0, 10.0);
01071             if (sceneMinBBox[0] < sceneMaxBBox[0])
01072           {
01073         Vec3d minTemp=sceneMinBBox;
01074         Vec3d maxTemp=sceneMaxBBox;
01075         DrawBox(minTemp.ptr(), maxTemp.ptr());
01076           }
01077         }
01078     }
01079 
01080     // glDisable(GL_COLOR_MATERIAL);
01081 }
01082 
01083 // -------------------------------------------------------
01084 // ---
01085 // -------------------------------------------------------
01086 void SimpleGUI::DisplayMenu(void)
01087 {
01088     Disable<GL_LIGHTING> light;
01089 
01090     glMatrixMode(GL_PROJECTION);
01091     glPushMatrix();
01092     glLoadIdentity();
01093     glOrtho(-0.5, _W, -0.5, _H, -1.0, 1.0);
01094     glMatrixMode(GL_MODELVIEW);
01095     glPushMatrix();
01096     glLoadIdentity();
01097 
01098     glColor3f(0.3f, 0.7f, 0.95f);
01099     glRasterPos2i(_W / 2 - 5, _H - 15);
01100     //sprintf(buffer,"FPS: %.1f\n", _frameRate.GetFPS());
01101     //PrintString(GLUT_BITMAP_HELVETICA_12, buffer);
01102 
01103     glMatrixMode(GL_PROJECTION);
01104     glPopMatrix();
01105     glMatrixMode(GL_MODELVIEW);
01106     glPopMatrix();
01107 }
01108 
01109 // ---------------------------------------------------------
01110 // ---
01111 // ---------------------------------------------------------
01112 void SimpleGUI::DrawScene(void)
01113 {    
01114 
01115     _newQuat.buildRotationMatrix(_sceneTransform.rotation);
01116     calcProjection();
01117 
01118 #ifdef SOFA_HAVE_GLEW
01119     if (_shadow)
01120     {
01121         //glGetDoublev(GL_MODELVIEW_MATRIX,lastModelviewMatrix);
01122 
01123         // Update the light matrices for it's current position
01124         StoreLightMatrices();
01125 
01126         // Set the current viewport to our texture size
01127         glViewport(0, 0, (int)SHADOW_WIDTH, (int)SHADOW_HEIGHT);
01128 
01129         // Clear the screen and depth buffer so we can render from the light's view
01130         glClearColor(0.0f,0.0f,0.0f,0.0f);
01131         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
01132 
01133         // Now we just need to set the matrices for the light before we render
01134         glMatrixMode(GL_PROJECTION);
01135 
01136         // Push on a matrix to make sure we can restore to the old matrix easily
01137         glPushMatrix();{
01138             // Set the current projection matrix to our light's projection matrix
01139             glLoadMatrixf(g_mProjection);
01140 
01141             // Load modelview mode to set our light's modelview matrix
01142             glMatrixMode(GL_MODELVIEW);
01143             glPushMatrix();{
01144                 // Load the light's modelview matrix before we render to a texture
01145                 glLoadMatrixf(g_mModelView);
01146 
01147                 // Since we don't care about color when rendering the depth values to
01148                 // the shadow-map texture, we disable color writing to increase speed.
01149                 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 
01150 
01151                 // This turns of the polygon offset functionality to fix artifacts.
01152                 // Comment this out and run the program to see what artifacts I mean.
01153                 glEnable(GL_POLYGON_OFFSET_FILL);
01154                 glDisable(GL_BLEND);
01155 
01156                 // Eliminate artifacts caused by shadow mapping
01157                 //    glPolygonOffset(1.0f, 0.10f);
01158                 glPolygonOffset(g_DepthOffset[0], g_DepthOffset[1]);
01159 
01160                 _sceneTransform.Apply();
01161                 // Render the world according to the light's view
01162                 DisplayOBJs(true);
01163 
01164                 // Now that the world is rendered, save the depth values to a texture
01165                 glDisable(GL_BLEND);
01166                 //glEnable(GL_TEXTURE_2D);
01167                 glBindTexture(GL_TEXTURE_2D, g_DepthTexture);
01168 
01169                 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, (int)SHADOW_WIDTH, (int)SHADOW_HEIGHT);
01170 
01171                 // We can turn color writing back on since we already stored the depth values
01172                 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 
01173 
01174                 // Turn off polygon offsetting
01175                 glDisable(GL_POLYGON_OFFSET_FILL);
01176 
01177             }glPopMatrix();
01178             // Go back to the projection mode and restore the original matrix
01179             glMatrixMode(GL_PROJECTION);
01180             // Restore the original projection matrix
01181         }glPopMatrix();
01182 
01183         // Go back to modelview model to start drawing like normal
01184         glMatrixMode(GL_MODELVIEW);
01185 
01186         // Restore our normal viewport size to our screen width and height
01187         glViewport(0, 0, GetWidth(), GetHeight());
01188 
01189         // Clear the color and depth bits and start over from the camera's view
01190         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
01191 
01192         //glPushMatrix();{
01193         //    glLoadIdentity();
01194         //    _sceneTransform.ApplyInverse();
01195         //    glGetFloatv(GL_MODELVIEW_MATRIX, g_mCameraInverse);
01196         //}glPopMatrix();
01197 
01198         glLightfv( GL_LIGHT0, GL_POSITION, _lightPosition );
01199         /*
01200         {
01201             glEnable(GL_TEXTURE_2D);
01202             glActiveTextureARB(GL_TEXTURE0_ARB);
01203             glBindTexture(GL_TEXTURE_2D, g_Texture[SHADOW_ID]);
01204             glTexEnvi(GL_TEXTURE_2D,GL_TEXTURE_ENV_MODE,  GL_REPLACE);
01205             Disable<GL_DEPTH_TEST> dtoff;
01206             Disable<GL_LIGHTING> dlight;
01207             glColor3f(1,1,1);
01208             glViewport(0, 0, 128, 128);
01209             glMatrixMode(GL_PROJECTION);
01210             glPushMatrix();
01211             glLoadIdentity();
01212             glOrtho(0,1,0,1,-1,1); 
01213             glMatrixMode(GL_MODELVIEW);
01214             glPushMatrix();{
01215                 glLoadIdentity();
01216                 glBegin(GL_QUADS);{
01217                     glTexCoord2f(0,0);
01218                     glVertex2f(0,0);
01219                     glTexCoord2f(0,1);
01220                     glVertex2f(0,1);
01221                     glTexCoord2f(1,1);
01222                     glVertex2f(1,1);
01223                     glTexCoord2f(1,0);
01224                     glVertex2f(1,0);
01225                 }glEnd();
01226             }glPopMatrix();
01227             glMatrixMode(GL_PROJECTION);
01228             glPopMatrix();
01229             glMatrixMode(GL_MODELVIEW);
01230             glViewport(0, 0, GetWidth(), GetHeight());
01231         }
01232         */
01233 
01234 
01235         // Render the world and apply the shadow map texture to it
01236         glMatrixMode(GL_PROJECTION);
01237         glLoadMatrixd(lastProjectionMatrix);
01238         glMatrixMode(GL_MODELVIEW);
01239         ApplyShadowMap();
01240         { // NICO
01241             Enable<GL_TEXTURE_2D> texture_on;
01242                 glDisable(GL_BLEND);
01243             glBindTexture(GL_TEXTURE_2D, ShadowTextureMask);
01244             glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GetWidth(), GetHeight());
01245         }
01246         if (_background==0)
01247             glClearColor(0.0589f, 0.0589f, 0.0589f, 1.0f);
01248         else if (_background==1)
01249             glClearColor(0.0f,0.0f,0.0f,0.0f);
01250         else if (_background==2)
01251             glClearColor(1.0f,1.0f,1.0f,1.0f);
01252         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
01253         if (_background==0)
01254             DrawLogo();
01255         glPushMatrix();
01256         _sceneTransform.Apply();
01257         DisplayOBJs();
01258         glPopMatrix();
01259 
01260         {
01261             float ofu = GetWidth()/(float)SHADOW_MASK_SIZE;
01262             float ofv = GetHeight()/(float)SHADOW_MASK_SIZE;
01263             glActiveTextureARB(GL_TEXTURE0_ARB);
01264             glEnable(GL_TEXTURE_2D);
01265             glBindTexture(GL_TEXTURE_2D,ShadowTextureMask);
01266             //glTexEnvi(GL_TEXTURE_2D,GL_TEXTURE_ENV_MODE,  GL_REPLACE);
01267             Disable<GL_DEPTH_TEST> dtoff;
01268             Disable<GL_LIGHTING> dlight;
01269             Enable<GL_BLEND> blend_on;
01270             glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
01271             glColor3f(1,1,1);
01272             glViewport(0, 0, GetWidth(), GetHeight());
01273             glMatrixMode(GL_PROJECTION);
01274             glPushMatrix();
01275             glLoadIdentity();
01276             glOrtho(0,1,0,1,-1,1); 
01277             glMatrixMode(GL_MODELVIEW);
01278             glPushMatrix();{
01279                 glLoadIdentity();
01280                 glBegin(GL_QUADS);{
01281                     glTexCoord2f(0,0);
01282                     glVertex2f(0,0);
01283                     glTexCoord2f(0,ofv);
01284                     glVertex2f(0,1);
01285                     glTexCoord2f(ofu,ofv);
01286                     glVertex2f(1,1);
01287                     glTexCoord2f(ofu,0);
01288                     glVertex2f(1,0);
01289                 }glEnd();
01290             }glPopMatrix();
01291             glMatrixMode(GL_PROJECTION);
01292             glPopMatrix();
01293             glMatrixMode(GL_MODELVIEW);
01294             glViewport(0, 0, GetWidth(), GetHeight());
01295             glDisable(GL_TEXTURE_2D);
01296             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
01297         }
01298     
01299     }
01300     else
01301 #endif
01302     {
01303         if (_background==0)
01304             DrawLogo();
01305 
01306         glLoadIdentity();
01307         _sceneTransform.Apply();
01308 
01309         glGetDoublev(GL_MODELVIEW_MATRIX,lastModelviewMatrix);
01310 
01311         if (_renderingMode == GL_RENDER)
01312         {
01313         // Initialize lighting
01314         glPushMatrix();
01315         glLoadIdentity();
01316         glLightfv(GL_LIGHT0, GL_POSITION, _lightPosition);
01317         glPopMatrix();
01318         Enable<GL_LIGHT0> light0;
01319 
01320         glColor3f(0.5f, 0.5f, 0.6f);
01321         //    DrawXZPlane(-4.0, -20.0, 20.0, -20.0, 20.0, 1.0);
01322         //    DrawAxis(0.0, 0.0, 0.0, 10.0);
01323 
01324         DisplayOBJs();
01325 
01326         DisplayMenu();        // always needs to be the last object being drawn
01327         }
01328     }
01329 }
01330 
01331 
01332 // ---------------------------------------------------------
01333 // --- Reshape of the window, reset the projection
01334 // ---------------------------------------------------------
01335 void SimpleGUI::resizeGL(int width, int height)
01336 {
01337 
01338     _W = width;
01339     _H = height;
01340 
01341 //     std::cout << "GL window: " <<width<<"x"<<height <<std::endl;
01342 
01343     calcProjection();
01344 }
01345 
01346 
01347 // ---------------------------------------------------------
01348 // --- Reshape of the window, reset the projection
01349 // ---------------------------------------------------------
01350 void SimpleGUI::calcProjection()
01351 {
01352     int width = _W;
01353     int height = _H;
01354     double xNear, yNear, zNear, zFar, xOrtho, yOrtho;
01355     double xFactor = 1.0, yFactor = 1.0;
01356     double offset;
01357     double xForeground, yForeground, zForeground, xBackground, yBackground,
01358            zBackground;
01359 
01360     //if (!sceneBBoxIsValid)
01361     {
01362         getSimulation()->computeBBox(groot, sceneMinBBox.ptr(), sceneMaxBBox.ptr());
01363         sceneBBoxIsValid = true;
01364     }
01365     //std::cout << "Scene BBox = "<<sceneMinBBox<<" - "<<sceneMaxBBox<<"\n";
01366     if (sceneMinBBox[0] > sceneMaxBBox[0])
01367     {
01368         zNear = 1.0;
01369         zFar = 1000.0;
01370     }
01371     else
01372     {
01373         zNear = 1e10;
01374         zFar = -1e10;
01375         double minBBox[3] = {sceneMinBBox[0], sceneMinBBox[1], sceneMinBBox[2] };
01376         double maxBBox[3] = {sceneMaxBBox[0], sceneMaxBBox[1], sceneMaxBBox[2] };
01377         if (_axis)
01378         {
01379             for (int i=0;i<3;i++)
01380             {
01381                 if (minBBox[i]>-2) minBBox[i] = -2;
01382                 if (maxBBox[i]<14) maxBBox[i] = 14;
01383             }
01384         }
01385 
01386         for (int corner=0;corner<8;++corner)
01387         {
01388             Vector3 p((corner&1)?minBBox[0]:maxBBox[0],
01389                       (corner&2)?minBBox[1]:maxBBox[1],
01390                       (corner&4)?minBBox[2]:maxBBox[2]);
01391             p = _sceneTransform * p;
01392             double z = -p[2];
01393             if (z < zNear) zNear = z;
01394             if (z > zFar) zFar = z;
01395         }
01396         if (zFar <= 0 || zFar >= 1000)
01397         {
01398             zNear = 1;
01399             zFar = 1000.0;
01400         }
01401         else
01402         {
01403             zNear *= 0.9; // add some margin
01404             zFar *= 1.1;
01405             if (zNear < zFar*0.01)
01406                     zNear = zFar*0.01;
01407             if (zNear < 1.0) zNear = 1.0;
01408             if (zFar < 2.0) zFar = 2.0;
01409         }
01410         //std::cout << "Z = ["<<zNear<<" - "<<zFar<<"]\n";
01411     }
01412     xNear = 0.35*zNear;
01413     yNear = 0.35*zNear;
01414     offset = 0.001*zNear;        // for foreground and background planes
01415 
01416     xOrtho = fabs(_sceneTransform.translation[2]) * xNear / zNear;
01417     yOrtho = fabs(_sceneTransform.translation[2]) * yNear / zNear;
01418 
01419     if ((height != 0) && (width != 0))
01420     {
01421         if (height > width)
01422         {
01423             xFactor = 1.0;
01424             yFactor = (double) height / (double) width;
01425         }
01426         else
01427         {
01428             xFactor = (double) width / (double) height;
01429             yFactor = 1.0;
01430         }
01431     }
01432 
01433     lastViewport[0] = 0;
01434     lastViewport[1] = 0;
01435     lastViewport[2] = width;
01436     lastViewport[3] = height;
01437     glViewport(0, 0, width, height);
01438     glMatrixMode(GL_PROJECTION);
01439     glLoadIdentity();
01440 
01441     zForeground = -zNear - offset;
01442     zBackground = -zFar + offset;
01443 
01444     glFrustum(-xNear * xFactor, xNear * xFactor, -yNear * yFactor,
01445                yNear * yFactor, zNear, zFar);
01446     xForeground = -zForeground * xNear / zNear;
01447     yForeground = -zForeground * yNear / zNear;
01448     xBackground = -zBackground * xNear / zNear;
01449     yBackground = -zBackground * yNear / zNear;
01450 
01451     xForeground *= xFactor;
01452     yForeground *= yFactor;
01453     xBackground *= xFactor;
01454     yBackground *= yFactor;
01455 
01456     glGetDoublev(GL_PROJECTION_MATRIX,lastProjectionMatrix);
01457 
01458     glMatrixMode(GL_MODELVIEW);
01459 }
01460 
01461 // ---------------------------------------------------------
01462 // ---
01463 // ---------------------------------------------------------
01464 void SimpleGUI::paintGL()
01465 {
01466     //    ctime_t beginDisplay;
01467     //ctime_t endOfDisplay;
01468 
01469     //    beginDisplay = MesureTemps();
01470 
01471     // valid() is turned off when FLTK creates a new context for this window 
01472     // or when the window resizes, and is turned on after draw() is called.  
01473     // Use this to avoid unneccessarily initializing the OpenGL context.
01474     //static double lastOrthoTransZ = 0.0;
01475     /*
01476     if (!valid())
01477     {
01478     InitGFX();        // this has to be called here since we don't know when the context is created
01479     _W = w();
01480     _H = h();
01481     reshape(_W, _H);
01482     }
01483     */
01484     // clear buffers (color and depth)
01485     if (_background==0)
01486         glClearColor(0.0589f, 0.0589f, 0.0589f, 1.0f);
01487     else if (_background==1)
01488         glClearColor(0.0f,0.0f,0.0f,0.0f);
01489     else if (_background==2)
01490         glClearColor(1.0f,1.0f,1.0f,1.0f);
01491     glClearDepth(1.0);
01492     glClear(_clearBuffer);
01493 
01494     // draw the scene
01495     DrawScene();
01496 
01497     if (_video)
01498     {
01499 #ifdef CAPTURE_PERIOD
01500         static int counter = 0;
01501         if ((counter++ % CAPTURE_PERIOD)==0)
01502 #endif
01503             screenshot(2);
01504     }
01505 
01506     if (_waitForRender)
01507         _waitForRender = false;
01508 }
01509 
01510 void SimpleGUI::eventNewStep()
01511 {
01512     static ctime_t beginTime[10];
01513     static const ctime_t timeTicks = CTime::getRefTicksPerSec();
01514     static int frameCounter = 0;
01515     if (frameCounter==0)
01516     {
01517         ctime_t t = CTime::getRefTime();
01518         for (int i=0;i<10;i++)
01519             beginTime[i] = t;
01520     }
01521     ++frameCounter;
01522     if ((frameCounter%10) == 0)
01523     {
01524         ctime_t curtime = CTime::getRefTime();
01525         int i = ((frameCounter/10)%10);
01526         double fps = ((double)timeTicks / (curtime - beginTime[i]))*(frameCounter<100?frameCounter:100);
01527         char buf[100];
01528         sprintf(buf, "%.1f FPS", fps);
01529     std::string title = "SOFA";
01530     if (!sceneFileName.empty())
01531     {
01532         title += " :: ";
01533         title += sceneFileName;
01534     }
01535     title += " :: ";
01536     title += buf;
01537     glutSetWindowTitle(title.c_str());
01538 
01539         beginTime[i] = curtime;
01540         //frameCounter = 0;
01541     }
01542     if (m_displayComputationTime && (frameCounter%100) == 0 && groot!=NULL)
01543     {
01544         std::cout << "========== ITERATION " << frameCounter << " ==========\n";
01545         const simulation::tree::GNode::NodeTimer& total = groot->getTotalTime();
01546         const std::map<std::string, simulation::tree::GNode::NodeTimer>& times = groot->getVisitorTime();
01547         const std::map<std::string, std::map<sofa::core::objectmodel::BaseObject*, simulation::tree::GNode::ObjectTimer> >& objtimes = groot->getObjectTime();
01548         const double fact = 1000000.0 / (100*groot->getTimeFreq());
01549         for (std::map<std::string, simulation::tree::GNode::NodeTimer>::const_iterator it = times.begin(); it != times.end(); ++it)
01550         {
01551             std::cout << "TIME "<<it->first<<": " << ((int)(fact*it->second.tTree+0.5))*0.001 << " ms (" << (1000*it->second.tTree/total.tTree)*0.1 << " %).\n";
01552             std::map<std::string, std::map<sofa::core::objectmodel::BaseObject*, simulation::tree::GNode::ObjectTimer> >::const_iterator it1 = objtimes.find(it->first);
01553             if (it1 != objtimes.end())
01554             {
01555                 for (std::map<sofa::core::objectmodel::BaseObject*, simulation::tree::GNode::ObjectTimer>::const_iterator it2 = it1->second.begin(); it2 != it1->second.end(); ++it2)
01556                 {
01557                     std::cout << "  "<< sofa::helper::gettypename(typeid(*(it2->first)))<<" "<< it2->first->getName() <<": "
01558                         << ((int)(fact*it2->second.tObject+0.5))*0.001 << " ms (" << (1000*it2->second.tObject/it->second.tTree)*0.1 << " %).\n";
01559                 }
01560             }
01561         }
01562         for (std::map<std::string, std::map<sofa::core::objectmodel::BaseObject*, simulation::tree::GNode::ObjectTimer> >::const_iterator it = objtimes.begin(); it != objtimes.end(); ++it)
01563         {
01564             if (times.count(it->first)>0) continue;
01565             ctime_t ttotal = 0;
01566             for (std::map<sofa::core::objectmodel::BaseObject*, simulation::tree::GNode::ObjectTimer>::const_iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2)
01567                 ttotal += it2->second.tObject;
01568             std::cout << "TIME "<<it->first<<": " << ((int)(fact*ttotal+0.5))*0.001 << " ms (" << (1000*ttotal/total.tTree)*0.1 << " %).\n";
01569             if (ttotal > 0)
01570                 for (std::map<sofa::core::objectmodel::BaseObject*, simulation::tree::GNode::ObjectTimer>::const_iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2)
01571                 {
01572                     std::cout << "  "<< sofa::helper::gettypename(typeid(*(it2->first)))<<" "<< it2->first->getName() <<": "
01573                         << ((int)(fact*it2->second.tObject+0.5))*0.001 << " ms (" << (1000*it2->second.tObject/ttotal)*0.1 << " %).\n";
01574                 }
01575         }
01576         std::cout << "TOTAL TIME: " << ((int)(fact*total.tTree+0.5))*0.001 << " ms (" << ((int)(100/(fact*total.tTree*0.000001)+0.5))*0.01 << " FPS).\n";
01577         groot->resetTime();
01578     }
01579 }
01580 
01581 // ---------------------------------------------------------
01582 // ---
01583 // ---------------------------------------------------------
01584 void SimpleGUI::animate(void)
01585 {
01586     if (_spinning)
01587     {
01588         _newQuat = _currentQuat + _newQuat;
01589     }
01590 
01591     // update the entire scene
01592     redraw();
01593 }
01594 
01595 
01596 // ---------------------------------------------------------
01597 // ---
01598 // ---------------------------------------------------------
01599 void SimpleGUI::ApplySceneTransformation(int x, int y)
01600 {
01601     float    x1, x2, y1, y2;
01602     float    xshift, yshift, zshift;
01603 
01604     if (_moving)
01605     {
01606         if (_navigationMode == TRACKBALL_MODE)
01607         {
01608             x1 = (2.0f * _W / 2.0f - _W) / _W;
01609             y1 = (_H - 2.0f * _H / 2.0f) / _H;
01610             x2 = (2.0f * (x + (-_mouseX + _W / 2.0f)) - _W) / _W;
01611             y2 = (_H - 2.0f * (y + (-_mouseY + _H / 2.0f))) / _H;
01612             _currentTrackball.ComputeQuaternion(x1, y1, x2, y2);
01613             _currentQuat = _currentTrackball.GetQuaternion();
01614             _savedMouseX = _mouseX;
01615             _savedMouseY = _mouseY;
01616             _mouseX = x;
01617             _mouseY = y;
01618             _newQuat = _currentQuat + _newQuat;
01619             redraw();
01620         }
01621         else if (_navigationMode == ZOOM_MODE)
01622         {
01623             zshift = (2.0f * y - _W) / _W - (2.0f * _mouseY - _W) / _W;
01624             _sceneTransform.translation[2] = _previousEyePos[2] -
01625                 _zoomSpeed * zshift;
01626             redraw();
01627         }
01628         else if (_navigationMode == PAN_MODE)
01629         {
01630             xshift = (2.0f * x - _W) / _W - (2.0f * _mouseX - _W) / _W;
01631             yshift = (2.0f * y - _W) / _W - (2.0f * _mouseY - _W) / _W;
01632             _sceneTransform.translation[0] = _previousEyePos[0] +
01633                 _panSpeed * xshift;
01634             _sceneTransform.translation[1] = _previousEyePos[1] -
01635                 _panSpeed * yshift;
01636             redraw();
01637         }
01638     }
01639 }
01640 
01641 
01642 // ---------------------------------------------------------
01643 // ---
01644 // ---------------------------------------------------------
01645 void SimpleGUI::ApplyMouseInteractorTransformation(int x, int y)
01646 {
01647     // Mouse Interaction
01648     double coeffDeplacement = 0.025;
01649     Quaternion conjQuat, resQuat, _newQuatBckUp;
01650 
01651     float x1, x2, y1, y2;
01652 
01653     if (_mouseInteractorMoving)
01654     {
01655         if (_mouseInteractorRotationMode)
01656         {
01657             if ((_mouseInteractorSavedPosX != x) || (_mouseInteractorSavedPosY != y))
01658             {
01659                 x1 = 0;
01660                 y1 = 0;
01661                 x2 = (2.0f * (x + (-_mouseInteractorSavedPosX + _W / 2.0f)) - _W) / _W;
01662                 y2 = (_H - 2.0f * (y + (-_mouseInteractorSavedPosY + _H / 2.0f))) / _H;
01663 
01664                 _mouseInteractorTrackball.ComputeQuaternion(x1, y1, x2, y2);
01665                 _mouseInteractorCurrentQuat = _mouseInteractorTrackball.GetQuaternion();
01666                 _mouseInteractorSavedPosX = x;
01667                 _mouseInteractorSavedPosY = y;
01668 
01669                 _mouseInteractorNewQuat = _mouseInteractorCurrentQuat + _mouseInteractorNewQuat;
01670                 _mouseRotate = true;
01671             }
01672             else
01673             {
01674                 _mouseRotate = false;
01675             }
01676 
01677             redraw();
01678         }
01679         else if (_mouseInteractorTranslationMode)
01680         {
01681             _mouseInteractorAbsolutePosition =  Vector3(0,0,0);
01682             _mouseInteractorRelativePosition =  Vector3(0,0,0);
01683 
01684             if (_translationMode == XY_TRANSLATION)
01685             {
01686                 _mouseInteractorAbsolutePosition[0] = coeffDeplacement * (x - _mouseInteractorSavedPosX);
01687                 _mouseInteractorAbsolutePosition[1] = -coeffDeplacement * (y - _mouseInteractorSavedPosY);
01688 
01689                 _mouseInteractorSavedPosX = x;
01690                 _mouseInteractorSavedPosY = y;
01691             }
01692             else if (_translationMode == Z_TRANSLATION)
01693             {
01694                 _mouseInteractorAbsolutePosition[2] = coeffDeplacement * (y - _mouseInteractorSavedPosY);
01695 
01696                 _mouseInteractorSavedPosX = x;
01697                 _mouseInteractorSavedPosY = y;
01698             }
01699 
01700             _newQuatBckUp[0] = _newQuat[0];
01701             _newQuatBckUp[1] = _newQuat[1];
01702             _newQuatBckUp[2] = _newQuat[2];
01703             _newQuatBckUp[3] = _newQuat[3];
01704 
01705             _newQuatBckUp.normalize();
01706 
01707             // Conjugate calculation of the scene orientation quaternion
01708             conjQuat[0] = -_newQuatBckUp[0];
01709             conjQuat[1] = -_newQuatBckUp[1];
01710             conjQuat[2] = -_newQuatBckUp[2];
01711             conjQuat[3] = _newQuatBckUp[3];
01712 
01713             conjQuat.normalize();
01714 
01715             resQuat = _newQuatBckUp.quatVectMult(_mouseInteractorAbsolutePosition) * conjQuat;
01716 
01717             _mouseInteractorRelativePosition[0] = resQuat[0];
01718             _mouseInteractorRelativePosition[1] = resQuat[1];
01719             _mouseInteractorRelativePosition[2] = resQuat[2];
01720 
01721             _mouseTrans = true;
01722             redraw();
01723         }
01724     }
01725 }
01726 
01727 
01728 // ----------------------------------------
01729 // --- Handle events (mouse, keyboard, ...)
01730 // ----------------------------------------
01731 
01732 bool SimpleGUI::isControlPressed() const {
01733     return m_isControlPressed;
01734     //return glutGetModifiers()&GLUT_ACTIVE_CTRL;
01735 }
01736 
01737 bool SimpleGUI::isShiftPressed() const {
01738     return m_isShiftPressed;
01739     //return glutGetModifiers()&GLUT_ACTIVE_SHIFT;
01740 }
01741 
01742 bool SimpleGUI::isAltPressed() const {
01743     return m_isAltPressed;
01744     //return glutGetModifiers()&GLUT_ACTIVE_ALT;
01745 }
01746 
01747 void SimpleGUI::updateModifiers()
01748 {
01749     m_isControlPressed =  (glutGetModifiers()&GLUT_ACTIVE_CTRL )!=0;
01750     m_isShiftPressed   =  (glutGetModifiers()&GLUT_ACTIVE_SHIFT)!=0;
01751     m_isAltPressed     =  (glutGetModifiers()&GLUT_ACTIVE_ALT  )!=0;
01752 }
01753 
01754 void SimpleGUI::keyPressEvent ( int k )
01755 {
01756     if( isControlPressed() ) // pass event to the scene data structure
01757     {
01758         //cerr<<"SimpleGUI::keyPressEvent, key = "<<k<<" with Control pressed "<<endl;
01759         sofa::core::objectmodel::KeypressedEvent keyEvent(k);
01760         groot->propagateEvent(&keyEvent);
01761     }
01762     else  // control the GUI
01763         switch(k)
01764     {
01765 
01766     case 's':
01767         // --- save screenshot
01768         {
01769             screenshot();
01770             break;
01771         }
01772     case 'v':
01773         // --- save video
01774         {
01775             _video = !_video;
01776             capture.setCounter();
01777             break;
01778         }
01779     case 'w':
01780         // --- save current view
01781         {
01782             saveView();
01783             break;
01784         }
01785 
01786     case 'o':
01787         // --- export to OBJ
01788         {
01789             exportOBJ();
01790             break;
01791         }
01792     case 'p':
01793         // --- export to a succession of OBJ to make a video
01794         {
01795             _animationOBJ = !_animationOBJ;
01796             _animationOBJcounter = 0;
01797             break;
01798         }
01799     case  'r':
01800         // --- draw axis
01801         {
01802             _axis = !_axis;
01803             redraw();
01804             break;
01805         }
01806     case 'b':
01807         // --- change background
01808         {
01809             _background = (_background+1)%3;
01810             redraw();
01811             break;
01812         }
01813 
01814     case 'l':
01815         // --- draw shadows
01816         {
01817             if (_glshadow)
01818             {
01819                 _shadow = !_shadow;
01820                 redraw();
01821             }else
01822             {
01823                 printf("WARNING SimpleGUI : shadows are not supported !\n");
01824                 _shadow=false;
01825             }
01826             break;
01827         }
01828 
01829     case ' ':
01830     // --- start/stop
01831         {
01832         playpause();
01833         break;
01834     }
01835 
01836     case 'n':
01837     // --- step
01838         {
01839         step();
01840         redraw();
01841         break;
01842     }
01843 
01844     case 'q': //GLUT_KEY_Escape:
01845         {
01846             exit(0);
01847             break;
01848         }
01849 
01850     case 'c':
01851         {
01852             // --- switch interaction mode
01853             if (!_mouseInteractorTranslationMode)
01854             {
01855                 std::cout << "Interaction Mode ON\n";
01856                 _mouseInteractorTranslationMode = true;
01857                 _mouseInteractorRotationMode = false;
01858             }
01859             else
01860             {
01861                 std::cout << "Interaction Mode OFF\n";
01862                 _mouseInteractorTranslationMode = false;
01863                 _mouseInteractorRotationMode = false;
01864             }    
01865             break;
01866         }
01867     case GLUT_KEY_F5:
01868         {
01869             if (!sceneFileName.empty())
01870             {
01871                 std::cout << "Reloading "<<sceneFileName<<std::endl;
01872                 std::string filename = sceneFileName;
01873                 Quaternion q = _newQuat;
01874                 Transformation t = _sceneTransform;
01875                 simulation::Node* newroot = getSimulation()->load(filename.c_str());
01876                 if (newroot == NULL)
01877                 {
01878                     std::cerr << "Failed to load "<<filename<<std::endl;
01879                     break;
01880                 }
01881                 setScene(newroot, filename.c_str());
01882                 _newQuat = q;
01883                 _sceneTransform = t;
01884             }
01885 
01886             break;
01887         }
01888     }
01889 }
01890 
01891 
01892 void SimpleGUI::keyReleaseEvent ( int k )
01893 {
01894     //cerr<<"SimpleGUI::keyReleaseEvent, key = "<<k<<endl;
01895     if( isControlPressed() ) // pass event to the scene data structure
01896     {
01897     sofa::core::objectmodel::KeyreleasedEvent keyEvent(k);
01898         groot->propagateEvent(&keyEvent);
01899     }
01900 }
01901 
01902 // ---------------------- Here are the mouse controls for the scene  ----------------------
01903 void SimpleGUI::mouseEvent ( int type, int eventX, int eventY, int button )
01904 {
01905     if (_mouseInteractorRotationMode)
01906     {
01907         switch (type)
01908         {
01909         case MouseButtonPress:
01910             // Mouse left button is pushed
01911             if (button == GLUT_LEFT_BUTTON)
01912             {
01913                 _mouseInteractorMoving = true;
01914                 _mouseInteractorSavedPosX = eventX;
01915                 _mouseInteractorSavedPosY = eventY;
01916             }
01917             break;
01918 
01919         case MouseMove:
01920             // 
01921             break;
01922 
01923         case MouseButtonRelease:
01924             // Mouse left button is released 
01925             if (button == GLUT_LEFT_BUTTON)
01926             {
01927                 if (_mouseInteractorMoving)
01928                 {
01929                     _mouseInteractorMoving = false;
01930                 }
01931             }
01932             break;
01933 
01934         default:
01935             break;
01936         }
01937         ApplyMouseInteractorTransformation(eventX, eventY);
01938     }
01939     else if (_mouseInteractorTranslationMode)
01940     {
01941         switch (type)
01942         {
01943         case MouseButtonPress:
01944             // Mouse left button is pushed
01945             if (button == GLUT_LEFT_BUTTON)
01946             {
01947                 _translationMode = XY_TRANSLATION;
01948                 _mouseInteractorSavedPosX = eventX;
01949                 _mouseInteractorSavedPosY = eventY;
01950                 _mouseInteractorMoving = true;
01951             }
01952             // Mouse right button is pushed 
01953             else if (button == GLUT_RIGHT_BUTTON)
01954             {
01955                 _translationMode = Z_TRANSLATION;
01956                 _mouseInteractorSavedPosY = eventY;
01957                 _mouseInteractorMoving = true;
01958             }
01959 
01960             break;
01961 
01962         case MouseButtonRelease:
01963             // Mouse left button is released 
01964             if ((button == GLUT_LEFT_BUTTON) && (_translationMode == XY_TRANSLATION))
01965             {
01966                 if (_mouseInteractorMoving)
01967                 {
01968                     //_mouseInteractorRelativePosition = Vector3::ZERO;
01969                     _mouseInteractorMoving = false;
01970                 }
01971             }
01972             // Mouse right button is released 
01973             else if ((button == GLUT_RIGHT_BUTTON) && (_translationMode == Z_TRANSLATION))
01974             {
01975                 if (_mouseInteractorMoving)
01976                 {
01977                     //_mouseInteractorRelativePosition = Vector3::ZERO;
01978                     _mouseInteractorMoving = false;
01979                 }
01980             }
01981             break;
01982 
01983         default:
01984             break;
01985         }
01986 
01987         ApplyMouseInteractorTransformation(eventX, eventY);
01988     }
01989     else if (isShiftPressed())
01990     {
01991         _moving = false;
01992         //_sceneTransform.ApplyInverse();
01993         if (interactor==NULL)
01994         {
01995             interactor = new RayPickInteractor();
01996             interactor->setName("mouse");
01997             if (groot)
01998             {
01999                 simulation::tree::GNode* child = new simulation::tree::GNode("mouse");
02000                 groot->addChild(child);
02001                 child->addObject(interactor);
02002             }
02003         interactor->init();
02004         }
02005         interactor->newEvent("show");
02006         switch (type)
02007         {
02008         case MouseButtonPress:
02009             if (button == GLUT_LEFT_BUTTON) // Shift+Leftclick to deform the mesh
02010             {
02011                 interactor->newEvent("pick");
02012             }
02013             else if (button == GLUT_RIGHT_BUTTON) // Shift+Rightclick to remove triangles
02014             {
02015                 interactor->newEvent("pick2");
02016             }
02017             else if (button == GLUT_MIDDLE_BUTTON) // Shift+Midclick (by 2 steps defining 2 input points) to cut from one point to another
02018             {
02019                 interactor->newEvent("pick3");
02020             }
02021             break;
02022         case MouseButtonRelease:
02023             //if (button == GLUT_LEFT_BUTTON)
02024             {
02025                 interactor->newEvent("release");
02026             }
02027             break;
02028         default: break;
02029         }
02030         Vec3d p0, px, py, pz;
02031         gluUnProject(eventX, lastViewport[3]-1-(eventY), 0, lastModelviewMatrix, lastProjectionMatrix, lastViewport, &(p0[0]), &(p0[1]), &(p0[2]));
02032         gluUnProject(eventX+1, lastViewport[3]-1-(eventY), 0, lastModelviewMatrix, lastProjectionMatrix, lastViewport, &(px[0]), &(px[1]), &(px[2]));
02033         gluUnProject(eventX, lastViewport[3]-1-(eventY+1), 0, lastModelviewMatrix, lastProjectionMatrix, lastViewport, &(py[0]), &(py[1]), &(py[2]));
02034         gluUnProject(eventX, lastViewport[3]-1-(eventY), 1, lastModelviewMatrix, lastProjectionMatrix, lastViewport, &(pz[0]), &(pz[1]), &(pz[2]));
02035         px -= p0;
02036         py -= p0;
02037         pz -= p0;
02038         px.normalize();
02039         py.normalize();
02040         pz.normalize();
02041         Mat4x4d transform;
02042         transform.identity();
02043         transform[0][0] = px[0];
02044         transform[1][0] = px[1];
02045         transform[2][0] = px[2];
02046         transform[0][1] = py[0];
02047         transform[1][1] = py[1];
02048         transform[2][1] = py[2];
02049         transform[0][2] = pz[0];
02050         transform[1][2] = pz[1];
02051         transform[2][2] = pz[2];
02052         transform[0][3] = p0[0];
02053         transform[1][3] = p0[1];
02054         transform[2][3] = p0[2];
02055         Mat3x3d mat; mat = transform;
02056         Quat q; q.fromMatrix(mat);
02057         //std::cout << p0[0]<<' '<<p0[1]<<' '<<p0[2] << " -> " << pz[0]<<' '<<pz[1]<<' '<<pz[2] << std::endl;
02058         interactor->newPosition(p0, q, transform);
02059     }
02060     else if (isAltPressed())
02061     {
02062         _moving = false;
02063         switch (type)
02064         {
02065         case MouseButtonPress:
02066             // Mouse left button is pushed
02067             if (button == GLUT_LEFT_BUTTON)
02068             {
02069                 _navigationMode = BTLEFT_MODE;
02070                 _mouseInteractorMoving = true;
02071                 _mouseInteractorSavedPosX = eventX;
02072                 _mouseInteractorSavedPosY = eventY;
02073             }
02074             // Mouse right button is pushed 
02075             else if (button == GLUT_RIGHT_BUTTON)
02076             {
02077                 _navigationMode = BTRIGHT_MODE;
02078                 _mouseInteractorMoving = true;
02079                 _mouseInteractorSavedPosX = eventX;
02080                 _mouseInteractorSavedPosY = eventY;
02081             }
02082             // Mouse middle button is pushed 
02083             else if (button == GLUT_MIDDLE_BUTTON)
02084             {
02085                 _navigationMode = BTMIDDLE_MODE;
02086                 _mouseInteractorMoving = true;
02087                 _mouseInteractorSavedPosX = eventX;
02088                 _mouseInteractorSavedPosY = eventY;
02089             }
02090             break;
02091 
02092         case MouseMove:
02093             // 
02094             break;
02095 
02096         case MouseButtonRelease:
02097             // Mouse left button is released 
02098             if (button == GLUT_LEFT_BUTTON)
02099             {
02100                 if (_mouseInteractorMoving)
02101                 {
02102                     _mouseInteractorMoving = false;
02103                 }
02104             }
02105             // Mouse right button is released
02106             else if (button == GLUT_RIGHT_BUTTON)
02107             {
02108                 if (_mouseInteractorMoving)
02109                 {
02110                     _mouseInteractorMoving = false;
02111                 }
02112             }
02113             // Mouse middle button is released
02114             else if (button == GLUT_MIDDLE_BUTTON)
02115             {
02116                 if (_mouseInteractorMoving)
02117                 {
02118                     _mouseInteractorMoving = false;
02119                 }
02120             }
02121             break;
02122 
02123         default:
02124             break;
02125         }
02126         if (_mouseInteractorMoving && _navigationMode == BTLEFT_MODE)
02127         {
02128             int dx = eventX - _mouseInteractorSavedPosX;
02129             int dy = eventY - _mouseInteractorSavedPosY;
02130             if (dx || dy)
02131             {
02132             _lightPosition[0] -= dx*0.1;
02133             _lightPosition[1] += dy*0.1;
02134             std::cout << "Light = "<< _lightPosition[0] << " "<< _lightPosition[1] << " "<< _lightPosition[2] << std::endl;
02135             redraw();
02136             _mouseInteractorSavedPosX = eventX;
02137             _mouseInteractorSavedPosY = eventY;
02138             }
02139         }
02140         else if (_mouseInteractorMoving && _navigationMode == BTMIDDLE_MODE)
02141         {
02142             int dx = eventX - _mouseInteractorSavedPosX;
02143             int dy = eventY - _mouseInteractorSavedPosY;
02144             if (dx || dy)
02145             {
02146             //g_DepthBias[0] += dx*0.01;
02147             g_DepthBias[1] += dy*0.01;
02148             std::cout << "Depth bias = "<< g_DepthBias[0] << " " << g_DepthBias[1] << std::endl;
02149             redraw();
02150             _mouseInteractorSavedPosX = eventX;
02151             _mouseInteractorSavedPosY = eventY;
02152             }
02153         }
02154         else if (_mouseInteractorMoving && _navigationMode == BTRIGHT_MODE)
02155         {
02156             int dx = eventX - _mouseInteractorSavedPosX;
02157             int dy = eventY - _mouseInteractorSavedPosY;
02158             if (dx || dy)
02159             {
02160             g_DepthOffset[0] += dx*0.01;
02161             g_DepthOffset[1] += dy*0.01;
02162             std::cout << "Depth offset = "<< g_DepthOffset[0] << " " << g_DepthOffset[1] << std::endl;
02163             redraw();
02164             _mouseInteractorSavedPosX = eventX;
02165             _mouseInteractorSavedPosY = eventY;
02166             }
02167         }
02168     }
02169     else if (isControlPressed())
02170     {
02171         std::vector< sofa::core::componentmodel::behavior::MechanicalState<sofa::defaulttype::LaparoscopicRigidTypes>* > instruments;
02172         groot->getTreeObjects<sofa::core::componentmodel::behavior::MechanicalState<sofa::defaulttype::LaparoscopicRigidTypes>, std::vector< sofa::core::componentmodel::behavior::MechanicalState<sofa::defaulttype::LaparoscopicRigidTypes>* > >(&instruments);
02173         //std::cout << instruments.size() << " instruments\n";
02174         if (!instruments.empty())
02175         {
02176         _moving = false;
02177         sofa::core::componentmodel::behavior::MechanicalState<sofa::defaulttype::LaparoscopicRigidTypes>* instrument = instruments[0];
02178         switch (type)
02179         {
02180         case MouseButtonPress:
02181             // Mouse left button is pushed
02182             if (button == GLUT_LEFT_BUTTON)
02183             {
02184                 _navigationMode = BTLEFT_MODE;
02185                 _mouseInteractorMoving = true;
02186                 _mouseInteractorSavedPosX = eventX;
02187                 _mouseInteractorSavedPosY = eventY;
02188             }
02189             // Mouse right button is pushed 
02190             else if (button == GLUT_RIGHT_BUTTON)
02191             {
02192                 _navigationMode = BTRIGHT_MODE;
02193                 _mouseInteractorMoving = true;
02194                 _mouseInteractorSavedPosX = eventX;
02195                 _mouseInteractorSavedPosY = eventY;
02196             }
02197             // Mouse middle button is pushed 
02198             else if (button == GLUT_MIDDLE_BUTTON)
02199             {
02200                 _navigationMode = BTMIDDLE_MODE;
02201                 _mouseInteractorMoving = true;
02202                 _mouseInteractorSavedPosX = eventX;
02203                 _mouseInteractorSavedPosY = eventY;
02204             }
02205             break;
02206 
02207         case MouseMove:
02208             // 
02209             break;
02210 
02211         case MouseButtonRelease:
02212             // Mouse left button is released 
02213             if (button == GLUT_LEFT_BUTTON)
02214             {
02215                 if (_mouseInteractorMoving)
02216                 {
02217                     _mouseInteractorMoving = false;
02218                 }
02219             }
02220             // Mouse right button is released
02221             else if (button == GLUT_RIGHT_BUTTON)
02222             {
02223                 if (_mouseInteractorMoving)
02224                 {
02225                     _mouseInteractorMoving = false;
02226                 }
02227             }
02228             // Mouse middle button is released
02229             else if (button == GLUT_MIDDLE_BUTTON)
02230             {
02231                 if (_mouseInteractorMoving)
02232                 {
02233                     _mouseInteractorMoving = false;
02234                 }
02235             }
02236             break;
02237 
02238         default:
02239             break;
02240         }
02241         if (_mouseInteractorMoving && _navigationMode == BTLEFT_MODE)
02242         {
02243             int dx = eventX - _mouseInteractorSavedPosX;
02244             int dy = eventY - _mouseInteractorSavedPosY;
02245             if (dx || dy)
02246             {
02247             (*instrument->getX())[0].getOrientation() = (*instrument->getX())[0].getOrientation() * Quat(Vector3(0,1,0),dx*0.001) * Quat(Vector3(0,0,1),dy*0.001);
02248             redraw();
02249             _mouseInteractorSavedPosX = eventX;
02250             _mouseInteractorSavedPosY = eventY;
02251             }
02252         }
02253         else if (_mouseInteractorMoving && _navigationMode == BTMIDDLE_MODE)
02254         {
02255             int dx = eventX - _mouseInteractorSavedPosX;
02256             int dy = eventY - _mouseInteractorSavedPosY;
02257             if (dx || dy)
02258             {
02259                 if (!groot || !groot->getContext()->getAnimate())
02260                     redraw();
02261                 _mouseInteractorSavedPosX = eventX;
02262                 _mouseInteractorSavedPosY = eventY;
02263             }
02264         }
02265         else if (_mouseInteractorMoving && _navigationMode == BTRIGHT_MODE)
02266         {
02267             int dx = eventX - _mouseInteractorSavedPosX;
02268             int dy = eventY - _mouseInteractorSavedPosY;
02269             if (dx || dy)
02270             {
02271             (*instrument->getX())[0].getTranslation() += (dy)*0.01;
02272             (*instrument->getX())[0].getOrientation() = (*instrument->getX())[0].getOrientation() * Quat(Vector3(1,0,0),dx*0.001);
02273                 if (!groot || !groot->getContext()->getAnimate())
02274                     redraw();
02275             _mouseInteractorSavedPosX = eventX;
02276             _mouseInteractorSavedPosY = eventY;
02277             }
02278         }
02279         static_cast<sofa::simulation::tree::GNode*>(instrument->getContext())->execute<sofa::simulation::MechanicalPropagatePositionAndVelocityVisitor>();
02280         static_cast<sofa::simulation::tree::GNode*>(instrument->getContext())->execute<sofa::simulation::UpdateMappingVisitor>();
02281         }
02282     }
02283     else
02284     {
02285         if (interactor!=NULL)
02286             interactor->newEvent("hide");
02287         switch (type)
02288         {
02289         case MouseButtonPress:
02290             // rotate with left button
02291             if (button == GLUT_LEFT_BUTTON)
02292             {
02293                 _navigationMode = TRACKBALL_MODE;
02294                 _newTrackball.ComputeQuaternion(0.0, 0.0, 0.0, 0.0);
02295                 _currentQuat = _newTrackball.GetQuaternion();
02296                 _moving = true;
02297                 _spinning = false;
02298                 _mouseX = eventX;
02299                 _mouseY = eventY;
02300             }
02301             // translate with middle button (if it exists)
02302             else if (button == GLUT_MIDDLE_BUTTON)
02303             {
02304                 _navigationMode = PAN_MODE;
02305                 _moving = true;
02306                 _spinning = false;
02307                 _mouseX = eventX;
02308                 _mouseY = eventY;
02309                 _previousEyePos[0] = _sceneTransform.translation[0];
02310                 _previousEyePos[1] = _sceneTransform.translation[1];
02311             }
02312             // zoom with right button
02313             else if (button == GLUT_RIGHT_BUTTON)
02314             {
02315                 _navigationMode = ZOOM_MODE;
02316                 _moving = true;
02317                 _spinning = false;
02318                 _mouseX = eventX;
02319                 _mouseY = eventY;
02320                 _previousEyePos[2] = _sceneTransform.translation[2];
02321             }
02322             break;
02323 
02324         case MouseMove:
02325             // 
02326             break;
02327 
02328         case MouseButtonRelease:
02329             // Mouse left button is released 
02330             if (button == GLUT_LEFT_BUTTON)
02331             {
02332                 if (_moving && _navigationMode == TRACKBALL_MODE)
02333                 {
02334                     _moving = false;
02335                     int dx = eventX - _savedMouseX;
02336                     int dy = eventY - _savedMouseY;
02337                     if ((dx >= MINMOVE) || (dx <= -MINMOVE) ||
02338                         (dy >= MINMOVE) || (dy <= -MINMOVE))
02339                     {
02340                         _spinning = true;
02341                     }
02342                 }
02343             }
02344             // Mouse middle button is released
02345             else if (button == GLUT_MIDDLE_BUTTON)
02346             {
02347                 if (_moving && _navigationMode == PAN_MODE)
02348                 {
02349                     _moving = false;
02350                 }
02351             }
02352             // Mouse right button is released
02353             else if (button == GLUT_RIGHT_BUTTON)
02354             {
02355                 if (_moving && _navigationMode == ZOOM_MODE)
02356                 {
02357                     _moving = false;
02358                 }
02359             }
02360 
02361             break;
02362             /*
02363             case FL_MOUSEWHEEL:
02364             // it is also possible to zoom with mouse wheel (if it exists)
02365             if (Fl::event_button() == FL_MOUSEWHEEL)
02366             {
02367             _navigationMode = ZOOM_MODE;
02368             _moving = true;
02369             _mouseX = 0;
02370             _mouseY = 0;
02371             eventX = 0;
02372             eventY = 10 * Fl::event_dy();
02373             _previousEyePos[2] = _sceneTransform.translation[2];
02374             }
02375             break;
02376             */
02377         default:
02378             break;
02379         }
02380 
02381         ApplySceneTransformation(eventX, eventY);
02382     }
02383 }
02384 
02385 // -------------------------------------------------------------------
02386 // ---
02387 // -------------------------------------------------------------------
02388 void SimpleGUI::SwitchToPresetView()
02389 {
02390     if (!sceneFileName.empty())
02391     {
02392         std::string viewFileName = sceneFileName+".view";
02393         std::ifstream in(viewFileName.c_str());
02394         if (!in.fail())
02395         {
02396             in >> _sceneTransform.translation[0];
02397             in >> _sceneTransform.translation[1];
02398             in >> _sceneTransform.translation[2];
02399             in >> _newQuat[0];
02400             in >> _newQuat[1];
02401             in >> _newQuat[2];
02402             in >> _newQuat[3];
02403             _newQuat.normalize();
02404             in.close();
02405             return;
02406         }
02407         std::cout << "PRESET FAILED " << viewFileName << std::endl;
02408     }
02409     std::cout << "PRESET" << std::endl;
02410     _sceneTransform.translation[0] = 0.0;
02411     _sceneTransform.translation[1] = 0.0;
02412     _sceneTransform.translation[2] = -50.0;
02413     _newQuat[0] = 0.17;
02414     _newQuat[1] = -0.83;
02415     _newQuat[2] = -0.26;
02416     _newQuat[3] = -0.44;
02417     //ResetScene();
02418 }
02419 
02420 
02421 void SimpleGUI::step()
02422 {
02423     {
02424         if (_waitForRender) return;
02425         //groot->setLogTime(true);
02426 
02427         getSimulation()->animate(groot);
02428         
02429         if( m_dumpState )
02430           getSimulation()->dumpState( groot, *m_dumpStateStream );
02431         if( m_exportGnuplot )
02432           getSimulation()->exportGnuplot( groot, groot->getTime() );
02433         
02434 
02435         _waitForRender = true;
02436         eventNewStep();
02437 
02438         redraw();
02439     }
02440     
02441     if (_animationOBJ)
02442     {
02443 #ifdef CAPTURE_PERIOD
02444         static int counter = 0;
02445         if ((counter++ % CAPTURE_PERIOD)==0)
02446 #endif
02447         {
02448             exportOBJ(false);
02449             ++_animationOBJcounter;
02450         }
02451     }
02452 }
02453 
02454 void SimpleGUI::playpause()
02455 {
02456     if (groot)
02457     {
02458         groot->getContext()->setAnimate(!groot->getContext()->getAnimate());
02459     }
02460 }
02461 
02462 void SimpleGUI::dumpState(bool value)
02463 {
02464     m_dumpState = value;
02465     if( m_dumpState )
02466     {
02467         m_dumpStateStream = new std::ofstream("dumpState.data");
02468     }
02469     else if( m_dumpStateStream!=NULL )
02470     {
02471         delete m_dumpStateStream;
02472         m_dumpStateStream = 0;
02473     }
02474 }
02475 
02476 void SimpleGUI::displayComputationTime(bool value)
02477 {
02478     m_displayComputationTime = value;
02479     if (groot)
02480     {
02481         groot->setLogTime(m_displayComputationTime);
02482     }
02483 }
02484 
02485 void SimpleGUI::resetScene()
02486 {
02487     if (groot)
02488     {
02489         getSimulation()->reset(groot);
02490         redraw();
02491     }
02492 }
02493 
02494 void SimpleGUI::resetView()
02495 {
02496     SwitchToPresetView();
02497     redraw();
02498 }
02499 
02500 void SimpleGUI::saveView()
02501 {
02502     if (!sceneFileName.empty())
02503     {
02504         std::string viewFileName = sceneFileName+".view";
02505         std::ofstream out(viewFileName.c_str());
02506         if (!out.fail())
02507         {
02508             out << _sceneTransform.translation[0] << " " << _sceneTransform.translation[1] << " " << _sceneTransform.translation[2] << "\n";
02509             out << _newQuat[0] << " " << _newQuat[1] << " " << _newQuat[2] << " " << _newQuat[3] << "\n";
02510             out.close();
02511         }
02512         std::cout << "View parameters saved in "<<viewFileName<<std::endl;
02513     }
02514 }
02515 
02516 void SimpleGUI::showVisual(bool value)
02517 {
02518     if (groot)
02519     {
02520         groot->getContext()->setShowVisualModels(value);
02521     getSimulation()->updateVisualContext(groot);
02522     }
02523     redraw();
02524 }
02525 
02526 void SimpleGUI::showBehavior(bool value)
02527 {
02528     if (groot)
02529     {
02530         groot->getContext()->setShowBehaviorModels(value);
02531     getSimulation()->updateVisualContext(groot);
02532     }
02533     redraw();
02534 }
02535 
02536 void SimpleGUI::showCollision(bool value)
02537 {
02538     if (groot)
02539     {
02540         groot->getContext()->setShowCollisionModels(value);
02541     getSimulation()->updateVisualContext(groot);
02542     }
02543     redraw();
02544 }
02545 
02546 void SimpleGUI::showBoundingCollision(bool value)
02547 {
02548     if (groot)
02549     {
02550         groot->getContext()->setShowBoundingCollisionModels(value);
02551     getSimulation()->updateVisualContext(groot);
02552     }
02553     redraw();
02554 }
02555 
02556 void SimpleGUI::showMapping(bool value)
02557 {
02558     if (groot)
02559     {
02560         groot->getContext()->setShowMappings(value);
02561     getSimulation()->updateVisualContext(groot);
02562     }
02563     redraw();
02564 }
02565 
02566 void SimpleGUI::showMechanicalMapping(bool value)
02567 {
02568     if (groot)
02569     {
02570         groot->getContext()->setShowMechanicalMappings(value);
02571     getSimulation()->updateVisualContext(groot);
02572     }
02573     redraw();
02574 }
02575 
02576 void SimpleGUI::showForceField(bool value)
02577 {
02578     if (groot)
02579     {
02580         groot->getContext()->setShowForceFields(value);
02581     getSimulation()->updateVisualContext(groot);
02582     }
02583     redraw();
02584 }
02585 
02586 void SimpleGUI::showInteractionForceField(bool value)
02587 {
02588     if (groot)
02589     {
02590         groot->getContext()->setShowInteractionForceFields(value);
02591     getSimulation()->updateVisualContext(groot);
02592     }
02593     redraw();
02594 }
02595 
02596 void SimpleGUI::showWireFrame(bool value)
02597 {
02598     if (groot)
02599     {
02600         groot->getContext()->setShowWireFrame(value);
02601     getSimulation()->updateVisualContext(groot);
02602     }
02603     redraw();
02604 }
02605 
02606 void SimpleGUI::showNormals(bool value)
02607 {
02608     if (groot)
02609     {
02610         groot->getContext()->setShowNormals(value);
02611         getSimulation()->updateVisualContext(groot);
02612     }
02613     redraw();
02614 }
02615 
02616 void SimpleGUI::screenshot(int compression_level)
02617 {
02618     capture.saveScreen(compression_level);
02619 }
02620 
02621 void SimpleGUI::exportOBJ(bool exportMTL)
02622 {
02623     if (!groot) return;
02624     std::ostringstream ofilename;
02625     if (!sceneFileName.empty())
02626     {
02627         const char* begin = sceneFileName.c_str();
02628         const char* end = strrchr(begin,'.');
02629         if (!end) end = begin + sceneFileName.length();
02630         ofilename << std::string(begin, end);
02631     }
02632     else
02633         ofilename << "scene";
02634 //     double time = groot->getTime();
02635 //     ofilename << '-' << (int)(time*1000);
02636     
02637     std::stringstream oss;
02638     oss.width(5);
02639     oss.fill('0');
02640     oss << _animationOBJcounter;
02641     
02642     ofilename << '_' << (oss.str().c_str());
02643     ofilename << ".obj";
02644     std::string filename = ofilename.str();
02645     std::cout << "Exporting OBJ Scene "<<filename<<std::endl;
02646     getSimulation()->exportOBJ(groot, filename.c_str(),exportMTL);
02647 }
02648 
02649 void SimpleGUI::setScene(sofa::simulation::Node* scene, const char* filename)
02650 {
02651     std::ostringstream ofilename;
02652 
02653     sceneFileName = (filename==NULL)?"":filename;
02654     if (!sceneFileName.empty())
02655     {
02656         const char* begin = sceneFileName.c_str();
02657         const char* end = strrchr(begin,'.');
02658         if (!end) end = begin + sceneFileName.length();
02659         ofilename << std::string(begin, end);
02660         ofilename << "_";
02661     }
02662     else
02663         ofilename << "scene_";
02664 
02665     capture.setPrefix(ofilename.str());
02666     if (scene != groot)
02667     {
02668         //SwitchToPresetView();
02669         if (interactor != NULL)
02670             interactor = NULL;
02671     }
02672     groot = static_cast< sofa::simulation::tree::GNode *>(scene);
02673     groot->getContext()->get( interactor);
02674     initTexturesDone = false;
02675     sceneBBoxIsValid = false;
02676     redraw();
02677 }
02678 
02679 void SimpleGUI::setExportGnuplot( bool exp )
02680 {
02681   m_exportGnuplot = exp;
02682   if( m_exportGnuplot ){
02683     getSimulation()->initGnuplot( groot );
02684     getSimulation()->exportGnuplot( groot, groot->getTime() );
02685   }
02686 }
02687 
02688 } // namespace glut
02689 
02690 } // namespace gui
02691 
02692 } // namespace sofa

Generated on Sun Nov 23 02:28:35 2008 for Sofa by  doxygen 1.5.7.1