00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
00058
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* , const std::vector<std::string>& )
00101 {
00102 return 0;
00103 }
00104
00105 SofaGUI* SimpleGUI::CreateGUI(const char* , const std::vector<std::string>& , sofa::simulation::Node* groot, const char* filename)
00106 {
00107
00108 glutInitDisplayMode ( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
00109
00110
00111
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
00148
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
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
00233
00234
00235 enum { SHADOW_WIDTH = 512 };
00236 enum { SHADOW_HEIGHT = 512 };
00237 enum { SHADOW_MASK_SIZE = 2048 };
00238
00239
00240
00241 #define GL_TEXTURE_COMPARE_MODE_ARB 0x884C
00242
00243
00244
00245 #define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D
00246
00247
00248 #define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E
00249
00250
00251 GLuint g_DepthTexture;
00252
00253
00254 GLSLShader g_Shader;
00255
00256
00257 float g_DepthOffset[2] = { 10.0f, 0.0f };
00258 float g_DepthBias[2] = { 0.0f, 0.0f };
00259
00260
00261 float g_mProjection[16] = {0};
00262 float g_mModelView[16] = {0};
00263
00264
00265 GLuint ShadowTextureMask;
00266
00267
00268 #endif // SOFA_HAVE_GLEW
00269
00270
00271
00272
00273 SimpleGUI::SimpleGUI()
00274 {
00275 instance = this;
00276
00277 groot = NULL;
00278 initTexturesDone = false;
00279
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
00304
00305
00306
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
00329 _newTrackball.ComputeQuaternion(0.0, 0.0, 0.0, 0.0);
00330 _newQuat = _newTrackball.GetQuaternion();
00331
00333
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
00359
00360 SimpleGUI::~SimpleGUI()
00361 {
00362 if (instance == this) instance = NULL;
00363 }
00364
00365
00366
00367
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
00383
00384
00385
00386
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
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
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
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
00440 glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
00441
00442
00443 glMaterialfv(GL_FRONT, GL_SPECULAR, specref);
00444 glMateriali(GL_FRONT, GL_SHININESS, 128);
00445
00446 glShadeModel(GL_SMOOTH);
00447
00448
00449 glClearColor(0.0589f, 0.0589f, 0.0589f, 1.0f);
00450
00451
00452
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
00460
00461 glEnable(GL_LIGHT0);
00462
00463
00464 #ifdef SOFA_HAVE_GLEW
00465
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
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
00481 initialized = true;
00482
00483 _beginTime = CTime::getTime();
00484
00485 printf("\n");
00486 }
00487
00488
00489 SwitchToPresetView();
00490 }
00491
00492
00493
00494
00495
00501
00502 void SimpleGUI::StoreLightMatrices()
00503 {
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513 memset(g_mModelView, 0, sizeof(float)*16);
00514 memset(g_mProjection, 0, sizeof(float)*16);
00515
00516 g_mModelView[0] = 1;
00517 g_mModelView[5] = 1;
00518 g_mModelView[10] = 1;
00519 g_mModelView[15] = 1;
00520
00521
00522
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
00528
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
00559 glGetFloatv(GL_MODELVIEW_MATRIX, g_mProjection);
00560
00561
00562 }glPopMatrix();
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
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
00604 glTexImage2D(GL_TEXTURE_2D, 0, channels, sizeX, sizeY, 0, type, GL_UNSIGNED_INT, NULL);
00605
00606
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
00623 g_Shader.TurnOn();
00624
00625
00626 glActiveTextureARB(GL_TEXTURE1_ARB);
00627 glEnable(GL_TEXTURE_2D);
00628 glBindTexture(GL_TEXTURE_2D, g_DepthTexture);
00629
00630
00631 g_Shader.SetInt(g_Shader.GetVariable("shadowMap"), 1);
00632
00633
00634
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
00644
00645
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);
00654 glMultMatrixf(g_mProjection);
00655 glMultMatrixf(g_mModelView);
00656
00657
00658 glMatrixMode(GL_MODELVIEW);
00659
00660 glActiveTextureARB(GL_TEXTURE0_ARB);
00661
00662
00663
00664 glPushMatrix();
00665 {
00666 glLoadIdentity();
00667 _sceneTransform.Apply();
00668 glGetDoublev(GL_MODELVIEW_MATRIX,lastModelviewMatrix);
00669 DisplayOBJs();
00670 }
00671 glPopMatrix();
00672
00673
00674 glMatrixMode(GL_TEXTURE);
00675 glLoadIdentity();
00676 glMatrixMode(GL_MODELVIEW);
00677
00678
00679
00680 glActiveTextureARB(GL_TEXTURE1_ARB);
00681 glDisable(GL_TEXTURE_2D);
00682 glActiveTextureARB(GL_TEXTURE0_ARB);
00683
00684
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
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
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
00754 glTranslated(-xpos, -ypos, -zpos);
00755 glPopMatrix();
00756
00757
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
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
00776 glTranslated(-xpos, -ypos, -zpos);
00777 glPopMatrix();
00778
00779
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
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
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
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
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
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
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
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
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
00909
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
00938
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
00967
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
01051 glColor4f(1,1,1,1);
01052 glDisable(GL_COLOR_MATERIAL);
01053
01054 if (!initTexturesDone)
01055 {
01056
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
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
01101
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
01122
01123
01124 StoreLightMatrices();
01125
01126
01127 glViewport(0, 0, (int)SHADOW_WIDTH, (int)SHADOW_HEIGHT);
01128
01129
01130 glClearColor(0.0f,0.0f,0.0f,0.0f);
01131 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
01132
01133
01134 glMatrixMode(GL_PROJECTION);
01135
01136
01137 glPushMatrix();{
01138
01139 glLoadMatrixf(g_mProjection);
01140
01141
01142 glMatrixMode(GL_MODELVIEW);
01143 glPushMatrix();{
01144
01145 glLoadMatrixf(g_mModelView);
01146
01147
01148
01149 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
01150
01151
01152
01153 glEnable(GL_POLYGON_OFFSET_FILL);
01154 glDisable(GL_BLEND);
01155
01156
01157
01158 glPolygonOffset(g_DepthOffset[0], g_DepthOffset[1]);
01159
01160 _sceneTransform.Apply();
01161
01162 DisplayOBJs(true);
01163
01164
01165 glDisable(GL_BLEND);
01166
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
01172 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
01173
01174
01175 glDisable(GL_POLYGON_OFFSET_FILL);
01176
01177 }glPopMatrix();
01178
01179 glMatrixMode(GL_PROJECTION);
01180
01181 }glPopMatrix();
01182
01183
01184 glMatrixMode(GL_MODELVIEW);
01185
01186
01187 glViewport(0, 0, GetWidth(), GetHeight());
01188
01189
01190 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
01191
01192
01193
01194
01195
01196
01197
01198 glLightfv( GL_LIGHT0, GL_POSITION, _lightPosition );
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236 glMatrixMode(GL_PROJECTION);
01237 glLoadMatrixd(lastProjectionMatrix);
01238 glMatrixMode(GL_MODELVIEW);
01239 ApplyShadowMap();
01240 {
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
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
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
01322
01323
01324 DisplayOBJs();
01325
01326 DisplayMenu();
01327 }
01328 }
01329 }
01330
01331
01332
01333
01334
01335 void SimpleGUI::resizeGL(int width, int height)
01336 {
01337
01338 _W = width;
01339 _H = height;
01340
01341
01342
01343 calcProjection();
01344 }
01345
01346
01347
01348
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
01361 {
01362 getSimulation()->computeBBox(groot, sceneMinBBox.ptr(), sceneMaxBBox.ptr());
01363 sceneBBoxIsValid = true;
01364 }
01365
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;
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
01411 }
01412 xNear = 0.35*zNear;
01413 yNear = 0.35*zNear;
01414 offset = 0.001*zNear;
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
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
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
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
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
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
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
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
01730
01731
01732 bool SimpleGUI::isControlPressed() const {
01733 return m_isControlPressed;
01734
01735 }
01736
01737 bool SimpleGUI::isShiftPressed() const {
01738 return m_isShiftPressed;
01739
01740 }
01741
01742 bool SimpleGUI::isAltPressed() const {
01743 return m_isAltPressed;
01744
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() )
01757 {
01758
01759 sofa::core::objectmodel::KeypressedEvent keyEvent(k);
01760 groot->propagateEvent(&keyEvent);
01761 }
01762 else
01763 switch(k)
01764 {
01765
01766 case 's':
01767
01768 {
01769 screenshot();
01770 break;
01771 }
01772 case 'v':
01773
01774 {
01775 _video = !_video;
01776 capture.setCounter();
01777 break;
01778 }
01779 case 'w':
01780
01781 {
01782 saveView();
01783 break;
01784 }
01785
01786 case 'o':
01787
01788 {
01789 exportOBJ();
01790 break;
01791 }
01792 case 'p':
01793
01794 {
01795 _animationOBJ = !_animationOBJ;
01796 _animationOBJcounter = 0;
01797 break;
01798 }
01799 case 'r':
01800
01801 {
01802 _axis = !_axis;
01803 redraw();
01804 break;
01805 }
01806 case 'b':
01807
01808 {
01809 _background = (_background+1)%3;
01810 redraw();
01811 break;
01812 }
01813
01814 case 'l':
01815
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
01831 {
01832 playpause();
01833 break;
01834 }
01835
01836 case 'n':
01837
01838 {
01839 step();
01840 redraw();
01841 break;
01842 }
01843
01844 case 'q':
01845 {
01846 exit(0);
01847 break;
01848 }
01849
01850 case 'c':
01851 {
01852
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
01895 if( isControlPressed() )
01896 {
01897 sofa::core::objectmodel::KeyreleasedEvent keyEvent(k);
01898 groot->propagateEvent(&keyEvent);
01899 }
01900 }
01901
01902
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
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
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
01945 if (button == GLUT_LEFT_BUTTON)
01946 {
01947 _translationMode = XY_TRANSLATION;
01948 _mouseInteractorSavedPosX = eventX;
01949 _mouseInteractorSavedPosY = eventY;
01950 _mouseInteractorMoving = true;
01951 }
01952
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
01964 if ((button == GLUT_LEFT_BUTTON) && (_translationMode == XY_TRANSLATION))
01965 {
01966 if (_mouseInteractorMoving)
01967 {
01968
01969 _mouseInteractorMoving = false;
01970 }
01971 }
01972
01973 else if ((button == GLUT_RIGHT_BUTTON) && (_translationMode == Z_TRANSLATION))
01974 {
01975 if (_mouseInteractorMoving)
01976 {
01977
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
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)
02010 {
02011 interactor->newEvent("pick");
02012 }
02013 else if (button == GLUT_RIGHT_BUTTON)
02014 {
02015 interactor->newEvent("pick2");
02016 }
02017 else if (button == GLUT_MIDDLE_BUTTON)
02018 {
02019 interactor->newEvent("pick3");
02020 }
02021 break;
02022 case MouseButtonRelease:
02023
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
02058 interactor->newPosition(p0, q, transform);
02059 }
02060 else if (isAltPressed())
02061 {
02062 _moving = false;
02063 switch (type)
02064 {
02065 case MouseButtonPress:
02066
02067 if (button == GLUT_LEFT_BUTTON)
02068 {
02069 _navigationMode = BTLEFT_MODE;
02070 _mouseInteractorMoving = true;
02071 _mouseInteractorSavedPosX = eventX;
02072 _mouseInteractorSavedPosY = eventY;
02073 }
02074
02075 else if (button == GLUT_RIGHT_BUTTON)
02076 {
02077 _navigationMode = BTRIGHT_MODE;
02078 _mouseInteractorMoving = true;
02079 _mouseInteractorSavedPosX = eventX;
02080 _mouseInteractorSavedPosY = eventY;
02081 }
02082
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
02098 if (button == GLUT_LEFT_BUTTON)
02099 {
02100 if (_mouseInteractorMoving)
02101 {
02102 _mouseInteractorMoving = false;
02103 }
02104 }
02105
02106 else if (button == GLUT_RIGHT_BUTTON)
02107 {
02108 if (_mouseInteractorMoving)
02109 {
02110 _mouseInteractorMoving = false;
02111 }
02112 }
02113
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
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
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
02182 if (button == GLUT_LEFT_BUTTON)
02183 {
02184 _navigationMode = BTLEFT_MODE;
02185 _mouseInteractorMoving = true;
02186 _mouseInteractorSavedPosX = eventX;
02187 _mouseInteractorSavedPosY = eventY;
02188 }
02189
02190 else if (button == GLUT_RIGHT_BUTTON)
02191 {
02192 _navigationMode = BTRIGHT_MODE;
02193 _mouseInteractorMoving = true;
02194 _mouseInteractorSavedPosX = eventX;
02195 _mouseInteractorSavedPosY = eventY;
02196 }
02197
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
02213 if (button == GLUT_LEFT_BUTTON)
02214 {
02215 if (_mouseInteractorMoving)
02216 {
02217 _mouseInteractorMoving = false;
02218 }
02219 }
02220
02221 else if (button == GLUT_RIGHT_BUTTON)
02222 {
02223 if (_mouseInteractorMoving)
02224 {
02225 _mouseInteractorMoving = false;
02226 }
02227 }
02228
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
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
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
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
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
02345 else if (button == GLUT_MIDDLE_BUTTON)
02346 {
02347 if (_moving && _navigationMode == PAN_MODE)
02348 {
02349 _moving = false;
02350 }
02351 }
02352
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
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
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
02418 }
02419
02420
02421 void SimpleGUI::step()
02422 {
02423 {
02424 if (_waitForRender) return;
02425
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
02635
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
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 }
02689
02690 }
02691
02692 }