QtOgreViewer.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 <OgreConfigFile.h>
00028 #include <sofa/gui/qt/viewer/qtogre/QtOgreViewer.h>
00029 #include <sofa/gui/qt/viewer/qtogre/DotSceneLoader.h>
00030 #include <sofa/gui/qt/viewer/qtogre/OgreVisualModel.h>
00031 #include <sofa/helper/system/gl.h>
00032 #include <sofa/helper/system/glu.h>
00033 
00034 
00035 #include <sofa/core/objectmodel/KeypressedEvent.h>
00036 #include <sofa/core/objectmodel/KeyreleasedEvent.h>
00037 #include <sofa/core/ObjectFactory.h>
00038 
00039 #include <qapplication.h>
00040 
00041 #ifdef __linux__
00042 #include <X11/Xlib.h>
00043 #endif
00044 
00045 //#define SHOW_CONFIGDIALOG 
00046 #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
00047 #include <CoreFoundation/CoreFoundation.h>
00048 // This function will locate the path to our application on OS X,
00049 // unlike windows you can not rely on the curent working directory
00050 // for locating your configuration files and resources.
00051 std::string macBundlePath()
00052 {
00053     char path[1024];
00054     CFBundleRef mainBundle = CFBundleGetMainBundle();
00055     assert(mainBundle);
00056     
00057     CFURLRef mainBundleURL = CFBundleCopyBundleURL(mainBundle);
00058     assert(mainBundleURL);
00059     
00060     CFStringRef cfStringRef = CFURLCopyFileSystemPath( mainBundleURL, kCFURLPOSIXPathStyle);
00061     assert(cfStringRef);
00062     
00063     CFStringGetCString(cfStringRef, path, 1024, kCFStringEncodingASCII);
00064     
00065     CFRelease(mainBundleURL);
00066     CFRelease(cfStringRef);
00067     
00068     return std::string(path);
00069 }
00070 #endif 
00071 
00072 namespace sofa  
00073 {
00074 
00075   namespace gui
00076   {
00077 
00078     namespace qt
00079     {
00080 
00081       namespace viewer
00082       {
00083 
00084         
00085     namespace qtogre
00086     {
00087 
00088       SOFA_LINK_CLASS(OgreVisualModel) 
00089 
00090       using sofa::simulation::tree::Simulation;
00091       using sofa::component::visualmodel::OgreVisualModel;
00092 
00093       static bool enabled = false;
00094       sofa::core::ObjectFactory::ClassEntry* classOglModel;
00095       sofa::core::ObjectFactory::ClassEntry* classVisualModel;
00096 
00100       int QtOgreViewer::EnableViewer()
00101       {
00102         if (!enabled)
00103           {
00104         enabled = true;
00105         // Replace OpenGL visual models with OgreVisualModel
00106         sofa::core::ObjectFactory::AddAlias("OglModel", "OgreVisualModel", true, &classOglModel); 
00107         sofa::core::ObjectFactory::AddAlias("VisualModel", "OgreVisualModel", true, &classVisualModel); 
00108           }
00109         return 0;
00110       }
00111 
00115       int QtOgreViewer::DisableViewer()
00116       {
00117         if (enabled)
00118           {
00119         enabled = false;
00120         // Replace OpenGL visual models with OgreVisualModel
00121         sofa::core::ObjectFactory::ResetAlias("OglModel", classOglModel); 
00122         sofa::core::ObjectFactory::ResetAlias("VisualModel", classVisualModel); 
00123           }
00124         return 0;
00125       }
00126 
00127       //Application principale
00128       QtOgreViewer::QtOgreViewer( QWidget *parent, const char *name )
00129         : QWidget( parent, name )
00130       { 
00131               
00132 #ifdef SOFA_QT4
00133         setUpdatesEnabled(false);
00134         setWindowFlags(Qt::WindowStaysOnTopHint);
00135 #else
00136         setWFlags(Qt::WNoAutoErase);
00137         setWFlags(Qt::WStyle_StaysOnTop);
00138 #endif      
00139     
00140     
00141 
00142  
00143         // Make sure this class is enabled
00144         EnableViewer();
00145 
00146         //*************************************************************************
00147         // Ogre Init
00148         //*************************************************************************//
00149         mRenderWindow = NULL;
00150         mSceneMgr = NULL;
00151         mVp = NULL;
00152 
00153         shadow = Ogre::SHADOWTYPE_NONE;
00154 //      shadow = Ogre::SHADOWTYPE_STENCIL_ADDITIVE;
00155 
00156         //*************************************************************************
00157         // Interface Init
00158         //*************************************************************************//
00159         _waitForRender = false;
00160 
00161         capture.setCounter();
00162         m_isControlPressed = false;
00163         m_mouseLeftPressed = false;
00164         m_mouseRightPressed = false;
00165         m_mouseMiddlePressed = false;
00166         m_mousePos = QPoint(0, 0);
00167         m_mousePressPos = QPoint(0, 0);
00168         m_mTranslateVector = Ogre::Vector3::ZERO;
00169         m_mRotX = m_mRotY = 0.0f;
00170         m_mMoveSpeed = 10;
00171         m_mRotateSpeed = 36;
00172         m_background = true;
00173         interactor = NULL;
00174         _mouseInteractorMoving = false;
00175         _mouseInteractorSavedPosX = 0;
00176         _mouseInteractorSavedPosY = 0;
00177         number_visualModels=0;              
00178         _video = false;
00179         pickDone=false;
00180 
00181 #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
00182         mResourcePath = macBundlePath() + "/Contents/Resources/";
00183 #else
00184         mResourcePath = "";
00185 #endif
00186 
00187         //Default files
00188         sofa::helper::system::FileRepository repository;
00189         sceneName = sofa::helper::system::DataRepository.getFile("config/default.scene");
00190 
00191 #if defined(SOFA_GPU_CUDA)
00192         mycudaInit(0);
00193 #endif
00194       }
00195 
00196 
00197       void QtOgreViewer::setup()
00198       {
00199 
00200         setupResources();
00201 
00202         setupConfiguration();
00203         //if(!configure()) {std::cout << "No configuration \a\n";exit(0);}
00204 
00205         setupView();
00206 
00207         Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);
00208 
00209         loadResources();
00210 
00211         //createScene();
00212       }
00213 
00214 
00215       //*****************************************************************************************
00216       //Setup Ogre
00217       void QtOgreViewer::setupResources()
00218       {
00219 
00220         Ogre::String pluginsPath;
00221         Ogre::String configPath;
00222         Ogre::String ogrePath;
00223         Ogre::String ogreLog;
00224         // only use plugins.cfg if not static
00225 #ifndef OGRE_STATIC_LIB
00226 
00227 
00228         ogrePath = sofa::helper::system::DataRepository.getFile("config/ogre.cfg");
00229         ogreLog = sofa::helper::system::DataRepository.getFile("config/Ogre.log");
00230 
00231 #ifdef WIN32
00232         pluginsPath = sofa::helper::system::DataRepository.getFile("config/plugins.cfg");
00233 #else
00234         pluginsPath = sofa::helper::system::DataRepository.getFile("config/plugins_unix.cfg");
00235 #endif
00236 
00237 #endif
00238         mRoot = new Ogre::Root(pluginsPath, ogrePath, ogreLog);
00239         Ogre::LogManager::getSingleton().setLogDetail(Ogre::LL_LOW);
00240         Ogre::ResourceGroupManager::getSingleton().addResourceLocation("/","FileSystem","General");
00241         Ogre::ResourceGroupManager::getSingleton().addResourceLocation(sofa::helper::system::DataRepository.getFirstPath() +"/textures","FileSystem","General");
00242         Ogre::ResourceGroupManager::getSingleton().addResourceLocation(sofa::helper::system::DataRepository.getFirstPath() +"/materials","FileSystem","General");
00243         Ogre::ResourceGroupManager::getSingleton().addResourceLocation(sofa::helper::system::DataRepository.getFirstPath() +"/shaders","FileSystem","General");
00244       }
00245 
00246 
00247 
00248       void QtOgreViewer::setupConfiguration(void)
00249       {
00250 #ifdef SHOW_CONFIGDIALOG
00251         mRoot->showConfigDialog();
00252 #else
00253         //Rendering Device - will pick first available render device
00254         Ogre::RenderSystemList::iterator pRend = mRoot->getAvailableRenderers()->begin();       
00255         Ogre::RenderSystem* mRenderSystem = *pRend;
00256 
00257         //RenderSystem
00258         mRoot->setRenderSystem(mRenderSystem);
00259         //Anti aliasing
00260         mRenderSystem->setConfigOption("Anti aliasing", "None");
00261         //Floating-point mode
00262         mRenderSystem->setConfigOption("Floating-point mode", "Fastest");
00263         //Full Screen
00264         mRenderSystem->setConfigOption("Full Screen", "No");
00265         //Vsync
00266         mRenderSystem->setConfigOption("VSync", "No");      
00267 
00268         mRenderSystem->validateConfigOptions(); 
00269 #endif
00270         mRoot->initialise(false, "SOFA - OGRE");
00271       }
00272 
00273       //*****************************************************************************************
00274       //called to redraw the window
00275       void QtOgreViewer::update()
00276       {
00277         if(mRenderWindow == NULL)     
00278           setupView();
00279 
00280         if(mRenderWindow != NULL){
00281           mRoot->_fireFrameStarted();
00282 
00283           if (_video)
00284         {
00285 #ifdef CAPTURE_PERIOD
00286           static int counter = 0;
00287           if ((counter++ % CAPTURE_PERIOD)==0)
00288 #endif
00289             screenshot(capture.findFilename(), 2);
00290         }
00291 
00292           moveCamera();
00293 
00294           mRenderWindow->update();
00295 //        OgreVisualModel::lightSwitched = false;
00296 
00297           mRoot->_fireFrameEnded();
00298           if (_waitForRender) _waitForRender = false;
00299 #ifdef SOFA_QT4
00300           setUpdatesEnabled(false);
00301 #endif
00302         }
00303       }
00304       //******************************Qt paint***********************************
00305 
00306       void QtOgreViewer::paintEvent(QPaintEvent *)
00307       {             
00308         update();
00309         emit( redrawn() );
00310       }
00311 
00312       //*****************************************************************************************
00313       //Initialize the rendering window: create a sofa simulation, Ogre window...
00314       void QtOgreViewer::setupView()
00315       {
00316 
00317         Ogre::NameValuePairList params;
00318 
00319 #if defined(__linux__)
00320 
00321         //  params["parentWindowHandle"] =
00322         //    Ogre::StringConverter::toString ((unsigned long)XOpenDisplay(NULL)) +
00323         //    ":" + Ogre::StringConverter::toString ((unsigned long)parentWidget()->winId());   
00324 
00325 
00326 
00327         Display* display = XOpenDisplay(NULL);
00328         int screen = DefaultScreen(display);
00329 
00330 //      params["parentWindowHandle"] = 
00331 //        Ogre::StringConverter::toString ((unsigned long)display) +
00332 //        //          ":" + Ogre::StringConverter::toString ((unsigned long)screen) +
00333 //        ":" + Ogre::StringConverter::toString ((unsigned long)parentWidget()->winId());
00334 
00335                 params["parentWindowHandle"] = 
00336                   Ogre::StringConverter::toString ((unsigned long)display) +
00337                   ":" + Ogre::StringConverter::toString ((unsigned long)screen) +
00338                   ":" + Ogre::StringConverter::toString ((unsigned long)parentWidget()->winId());
00339 
00340 
00341 
00342 #elif defined (WIN32) 
00343         params["externalWindowHandle"] = Ogre::StringConverter::toString((size_t)(HWND)winId());
00344 #elif defined (__APPLE__)
00345 
00346         // TODO
00347 #endif
00348 
00349         //  try{
00350         //(name, width, height, fullscreen, parametre)
00351         mRenderWindow = mRoot->createRenderWindow("View", width(), height(), false, &params);
00352 
00353         _beginTime = CTime::getTime();
00354 
00355 #if defined(__linux__)
00356         WId window_id;
00357         mRenderWindow->getCustomAttribute("WINDOW", &window_id);
00358 
00359         // Take over the ogre created window.
00360         QWidget::create(window_id);
00361 
00362         mRenderWindow->reposition(x(),y());
00363 #elif defined (__APPLE__)
00364                 
00365         // TODO
00366 #endif
00367 
00368 #ifdef SOFA_QT4
00369         startTimer(500);
00370 #endif
00371       }
00372 
00373 
00374 
00375 
00376       //*****************************************************************************************
00377       //Initialize Sofa with the scene, and load the components to Ogre
00378 
00379       void QtOgreViewer::createScene()
00380       {     
00381 
00382         using namespace Ogre;
00383 
00384 
00385         if (groot==NULL){
00386           groot = new GNode;
00387         }
00388 
00389         DotSceneLoader loader;
00390         std::string::size_type pos_point = this->sceneFileName.rfind(".");
00391         if (pos_point != std::string::npos)
00392         {
00393           std::string file_temp = this->sceneFileName;
00394           file_temp.resize(pos_point); file_temp += ".scene";
00395           if ( sofa::helper::system::DataRepository.findFile(file_temp))
00396         sceneName = sofa::helper::system::DataRepository.getFile(file_temp);
00397         }
00398 
00399         loader.parseDotScene(sceneName, "General", NULL); //mSceneMgr);
00400         mSceneMgr = loader.getSceneManager();   
00401 
00402 
00403         mSceneMgr->setShadowTechnique(SHADOWTYPE_NONE);
00404 //      mSceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);
00405         if (groot)
00406           {
00407         // This could be done as an action, but it is shorter to do it this way
00408         std::vector<OgreVisualModel*> visualModels;
00409         groot->getTreeObjects<OgreVisualModel>(&visualModels);
00410 
00411         for (unsigned int i=0; i<visualModels.size(); i++)
00412           {       
00413             visualModels[i]->attach(mSceneMgr);
00414           }
00415         number_visualModels = visualModels.size();
00416 
00417           }
00418 
00419         if (mSceneMgr->hasCamera("sofa_camera"))    
00420           mCamera = mSceneMgr->getCamera("sofa_camera");    
00421         else
00422           {       
00423         // Create the camera
00424         mCamera = mSceneMgr->createCamera("sofa_camera");
00425         // Position it at 50 in Z direction 
00426         mCamera->setPosition(Ogre::Vector3(0,0,0));
00427         // Look back along -Z       
00428         mCamera->lookAt(Ogre::Vector3(0,0,1));
00429         mCamera->setNearClipDistance(loader.environment.nearClipDistance);
00430         mCamera->setFarClipDistance(loader.environment.farClipDistance);
00431           }
00432         //Always yaw around the camera Y axis.
00433 //      mCamera->setFixedYawAxis(true);
00434         camNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
00435         camNode->attachObject(mCamera);
00436 
00437         zeroNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
00438         mCamera->setAutoTracking(true, zeroNode);
00439         // Create one viewport, entire window
00440         if (mVp)
00441           {
00442         mRenderWindow->removeViewport(0);
00443           }
00444         mVp = mRenderWindow->addViewport(mCamera);
00445         mVp->setBackgroundColour(loader.environment.backgroundColour);
00446 
00447 
00448         showEntireScene();
00449 
00450     
00451         //************************************************************************************************
00452         //insert background sofa
00453         if ( !mSceneMgr->hasSceneNode("Background"))
00454           {
00455         //Warning: if scene reloaded, the resource still exists but may have lost its information.
00456         if (Ogre::MaterialManager::getSingleton().resourceExists("Background"))
00457           Ogre::MaterialManager::getSingleton().remove("Background");
00458 
00459         Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create("Background", "General");
00460 
00461         material->getTechnique(0)->getPass(0)->createTextureUnitState("SOFA_logo.bmp");
00462         material->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false);
00463         material->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
00464         material->getTechnique(0)->getPass(0)->setLightingEnabled(false);
00465         material->getTechnique(0)->getPass(0)->setSceneBlending (Ogre::SBT_ADD);
00466 
00467         // Create background rectangle covering the whole screen
00468         Ogre::Rectangle2D* rect = new Ogre::Rectangle2D(true);
00469         rect->setCorners(-1.0, 0.5, 1.0, -0.5);
00470         rect->setMaterial("Background");
00471     
00472         // Render the background before everything else
00473         rect->setRenderQueueGroup(Ogre::RENDER_QUEUE_BACKGROUND);
00474     
00475         Ogre::AxisAlignedBox aabInf;
00476 //      aabInf.setInfinite();
00477         rect->setBoundingBox(aabInf);
00478 
00479         // Attach background to the scene
00480         Ogre::SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode("Background");
00481         node->attachObject(rect);
00482           }
00483 
00484         //************************************************************************************************
00485         // Alter the camera aspect ratio to match the viewport
00486         mCamera->setAspectRatio(Real(mVp->getActualWidth()) / Real(mVp->getActualHeight()));
00487 
00488       }
00489 
00490       void QtOgreViewer::showEntireScene()
00491       {
00492         if (mSceneMgr == NULL) return;
00493         
00494         mSceneMgr->_updateSceneGraph (mCamera);
00495         //Verify if there is no new visual model.
00496         if (groot)
00497           {
00498         std::vector<OgreVisualModel*> visualModels;
00499         groot->getTreeObjects<OgreVisualModel>(&visualModels);
00500         if (visualModels.size() != number_visualModels)
00501           {
00502             if (visualModels.size() > number_visualModels)
00503               {
00504             //Add only the new visual models
00505             for ( int i=number_visualModels; i<(int)visualModels.size(); i++)            
00506               visualModels[i]->attach(mSceneMgr);
00507               
00508               }
00509             else
00510               {
00511             //Remove elements  
00512             mSceneMgr->destroyAllEntities();
00513             //Add the visual models
00514             for (unsigned int i=0; i<visualModels.size(); i++)            
00515               visualModels[i]->attach(mSceneMgr);             
00516 
00517               }
00518 
00519             number_visualModels = visualModels.size();
00520           }
00521           }
00522         //************************************************************************************************
00523         //Calculate the World Bounding Box
00524         
00525         sofa::defaulttype::Vector3 sceneMinBBox;
00526         sofa::defaulttype::Vector3 sceneMaxBBox;
00527         getSimulation()->computeBBox(groot, sceneMinBBox.ptr(), sceneMaxBBox.ptr());
00528         Ogre::Vector3 size_world(sceneMaxBBox[0] - sceneMinBBox[0],sceneMaxBBox[1] - sceneMinBBox[1],sceneMaxBBox[2] - sceneMinBBox[2]);
00529         float max = ((size_world.x > size_world.y)?size_world.x:size_world.y);
00530         max = ((max > size_world.z)?max:size_world.z);
00531         float min = ((size_world.x < size_world.y)?size_world.x:size_world.y);
00532         min = ((min < size_world.z)?min:size_world.z);
00533 
00534 
00535         //frustrum
00536         if (min <= 1) min = 1.0;
00537 //      if (max <= min) max = 1000.0*min;
00538 
00539         mCamera->setFarClipDistance(Ogre::Real( 100.0*max));
00540         //mCamera->setNearClipDistance(Ogre::Real( 0.1*min)); //cause a crash of wrong BBox
00541 
00542         //position
00543         Ogre::Vector3 camera_position((sceneMaxBBox[0]+sceneMinBBox[0])/2.0f,(sceneMaxBBox[1]+sceneMinBBox[1])/2.0f,(sceneMaxBBox[2]+sceneMinBBox[2])/2.0f);
00544 
00545         zeroNode->setPosition(camera_position);
00546         mCamera->setPosition(camera_position);
00547         mCamera->moveRelative(Ogre::Vector3(0.0,0.0,2*std::max(size_world[0], // std::max(
00548                                                size_world[1]// , size_world[2])
00549                         )));
00550         
00551 //          mCamera->setAutoTracking(true);
00552 //      mCamera->setFixedYawAxis(true);
00553         return;
00554       }
00555 
00556 
00557 
00558       //*********************************Qt Control*******************************
00559       void QtOgreViewer::resizeEvent(QResizeEvent *evt)
00560       {
00561         Q_UNUSED(evt);
00562         resize();
00563       }
00564 
00565 
00566       //*****************************************************************************************
00567       //Keyboard Events
00568 
00569       void QtOgreViewer::keyPressEvent ( QKeyEvent * e )
00570       {
00571         if( isControlPressed() ) // pass event to the scene data structure
00572           {
00573         //cerr<<"QtViewer::keyPressEvent, key = "<<e->key()<<" with Control pressed "<<endl;
00574         sofa::core::objectmodel::KeypressedEvent keyEvent(e->key());
00575         groot->propagateEvent(&keyEvent);
00576           }
00577         else  // control the GUI
00578           {
00579         switch(e->key())
00580           {
00581           case Qt::Key_B:
00582             {
00583               m_background = !m_background;
00584               Ogre::SceneNode* node = mSceneMgr->getSceneNode("Background");
00585               node->setVisible(m_background);
00586         
00587               break;
00588             }
00589           case Qt::Key_C:
00590             {
00591               showEntireScene();
00592               break;
00593             }
00594           case Qt::Key_L:
00595             // --- Modify the shadow type
00596             {
00597               switch(shadow)
00598             {           
00599             case Ogre::SHADOWTYPE_NONE:
00600               pickDone=true;
00601               shadow = Ogre::SHADOWTYPE_STENCIL_ADDITIVE;
00602               OgreVisualModel::lightSwitched = true;
00603               break;
00604             case Ogre::SHADOWTYPE_STENCIL_ADDITIVE:
00605             default:
00606               OgreVisualModel::lightSwitched = false;
00607               shadow = Ogre::SHADOWTYPE_NONE;
00608               break;
00609             }
00610               mCamera->getSceneManager()->setShadowTechnique(shadow);
00611               break;
00612             }
00613           case Qt::Key_R:
00614             // --- Modify the way the polygons are rendered
00615             {
00616               switch(mCamera->getPolygonMode())
00617             {
00618             case Ogre::PM_POINTS:
00619               mCamera->setPolygonMode(Ogre::PM_WIREFRAME);
00620               break;
00621 
00622             case Ogre::PM_WIREFRAME:
00623               mCamera->setPolygonMode(Ogre::PM_SOLID);
00624               break;
00625 
00626             case Ogre::PM_SOLID:
00627               mCamera->setPolygonMode(Ogre::PM_POINTS);
00628               break;
00629             }
00630               break;
00631             }
00632           default:
00633             {
00634               SofaViewer::keyPressEvent(e);           
00635               e->ignore();
00636             }
00637           }
00638           }
00639         update();
00640       }
00641 
00642 
00643       //*****************************************************************************************
00644       //Mouse Events
00645 
00646       void QtOgreViewer::mousePressEvent(QMouseEvent* evt)
00647       {
00648         if (!updateInteractor(evt))
00649           {
00650         m_mousePos = evt->globalPos(); 
00651 
00652         if(evt->button() == Qt::LeftButton)
00653           m_mouseLeftPressed = true;
00654         if(evt->button() == Qt::RightButton)
00655           m_mouseRightPressed = true;       
00656         if(evt->button() == Qt::MidButton)
00657           m_mouseMiddlePressed = true;
00658           }
00659 
00660       }
00661 
00662 
00663       void QtOgreViewer::mouseReleaseEvent(QMouseEvent* evt)
00664       {
00665         if (!updateInteractor(evt))
00666           {
00667         m_mousePos = evt->globalPos(); 
00668         Q_UNUSED(evt);
00669         m_mouseLeftPressed = false;
00670         m_mouseRightPressed = false;
00671         m_mouseMiddlePressed = false;
00672         m_mRotX = m_mRotY = Ogre::Degree(0);
00673         m_mTranslateVector = Ogre::Vector3::ZERO;
00674           }
00675 
00676         if (interactor!=NULL)
00677           interactor->newEvent("hide");
00678         
00679       }
00680 
00681       void QtOgreViewer::mouseMoveEvent(QMouseEvent* evt)
00682       {
00683 
00684         if (!updateInteractor(evt))
00685           {
00686         Ogre::Vector3 pos_cam= mCamera->getPosition();
00687         const float dist = (zeroNode->getPosition()-pos_cam).length();   
00688         const float factor = 0.001f;  
00689         if( m_mouseRightPressed )
00690           {                     
00691             Ogre::Vector3 d(-(evt->globalX() - m_mousePos.x()) * dist*factor,(evt->globalY() - m_mousePos.y())* dist*factor,0);
00692             mCamera->moveRelative(d);
00693             pos_cam = mCamera->getPosition()-pos_cam;
00694             zeroNode->translate(pos_cam);
00695           }
00696         if( m_mouseMiddlePressed )
00697           {
00698             m_mTranslateVector.z -= (evt->globalY() - m_mousePos.y()) * 0.065;
00699             mCamera->moveRelative(m_mTranslateVector);
00700           }
00701         if( m_mouseLeftPressed )
00702           {  
00703             m_mTranslateVector.x -=  (evt->globalX() - m_mousePos.x()) * dist*factor*5.0;
00704             m_mTranslateVector.y -= -(evt->globalY() - m_mousePos.y()) * dist*factor*5.0;
00705             mCamera->moveRelative(m_mTranslateVector);
00706             float new_dist = (zeroNode->getPosition()-mCamera->getPosition()).length();
00707             mCamera->moveRelative(Ogre::Vector3(0,0,dist-new_dist));
00708           }
00709 
00710         m_mousePos = evt->globalPos(); 
00711         if (m_mouseLeftPressed || m_mouseMiddlePressed ||  m_mouseRightPressed ) update();        
00712           }
00713       }
00714 
00715 
00716       void QtOgreViewer::wheelEvent(QWheelEvent* evt)
00717       {
00718         m_mTranslateVector.z +=  evt->delta()* 0.04;
00719         mCamera->moveRelative(m_mTranslateVector);
00720         update();
00721       }
00722 
00723 
00724 
00725       void QtOgreViewer::setScene(sofa::simulation::tree::GNode* scene, const char* filename, bool keepParams)
00726       {
00727             
00728             SofaViewer::setScene(scene, filename, keepParams);
00729         createScene();
00730             update();
00731       }
00732 
00733 
00734       bool QtOgreViewer::updateInteractor(QMouseEvent * e)
00735       {
00736         if(e->state()&Qt::ShiftButton)
00737           {        
00738         SofaViewer::mouseEvent(e);
00739         return true;
00740           }
00741         return false;
00742       }
00743 
00744       void QtOgreViewer::moveRayPickInteractor(int eventX, int eventY)
00745       {
00746         sofa::defaulttype::Vec3d  p0, px, py, pz;
00747         GLint viewPort[4] = {0,0,width(), height()};
00748         Ogre::Matrix4 modelViewMatrix = mCamera->getViewMatrix().transpose();
00749         Ogre::Matrix4 projectionMatrix = mCamera->getProjectionMatrix(); 
00750 
00751         double modelViewMatrixGL[16] =
00752           {
00753         modelViewMatrix[0][0], modelViewMatrix[0][1], modelViewMatrix[0][2], modelViewMatrix[0][3],
00754         modelViewMatrix[1][0], modelViewMatrix[1][1], modelViewMatrix[1][2], modelViewMatrix[1][3],
00755         modelViewMatrix[2][0], modelViewMatrix[2][1], modelViewMatrix[2][2], modelViewMatrix[2][3],
00756         modelViewMatrix[3][0], modelViewMatrix[3][1], modelViewMatrix[3][2], modelViewMatrix[3][3],
00757           };
00758 
00759 
00760         double projectionMatrixGL[16] =
00761           {
00762         projectionMatrix[0][0], projectionMatrix[0][1], projectionMatrix[0][2], projectionMatrix[0][3],
00763         projectionMatrix[1][0], projectionMatrix[1][1], projectionMatrix[1][2], projectionMatrix[1][3],
00764         projectionMatrix[2][0], projectionMatrix[2][1], projectionMatrix[2][2], -1,
00765         projectionMatrix[3][0], projectionMatrix[3][1], projectionMatrix[3][2], projectionMatrix[3][3],
00766           };
00767 
00768         gluUnProject(eventX, viewPort[3]-1-(eventY),  0, modelViewMatrixGL, projectionMatrixGL, viewPort, &(p0[0]), &(p0[1]), &(p0[2]));
00769         gluUnProject(eventX+1, viewPort[3]-1-(eventY),0, modelViewMatrixGL, projectionMatrixGL, viewPort, &(px[0]), &(px[1]), &(px[2]));
00770         gluUnProject(eventX, viewPort[3]-1-(eventY+1),0, modelViewMatrixGL, projectionMatrixGL, viewPort, &(py[0]), &(py[1]), &(py[2]));
00771         gluUnProject(eventX, viewPort[3]-1-(eventY),  1, modelViewMatrixGL, projectionMatrixGL, viewPort, &(pz[0]), &(pz[1]), &(pz[2]));
00772 
00773 
00774         if ( pickDone)
00775           pz*=-1;
00776 
00777         px -= p0;
00778         py -= p0;
00779         pz -= p0;
00780 
00781         px.normalize();
00782         py.normalize();
00783         pz.normalize();
00784         sofa::defaulttype::Mat4x4d transform;
00785         transform.identity();
00786         transform[0][0] = px[0];
00787         transform[1][0] = px[1];
00788         transform[2][0] = px[2];
00789         transform[0][1] = py[0];
00790         transform[1][1] = py[1];
00791         transform[2][1] = py[2];
00792         transform[0][2] = pz[0];
00793         transform[1][2] = pz[1];
00794         transform[2][2] = pz[2];
00795         transform[0][3] = p0[0];
00796         transform[1][3] = p0[1];
00797         transform[2][3] = p0[2];
00798 
00799 
00800         sofa::defaulttype::Mat3x3d mat; mat = transform;
00801         sofa::defaulttype::Quat q; q.fromMatrix(mat);
00802         //std::cout << p0[0]<<' '<<p0[1]<<' '<<p0[2] << " -> " << pz[0]<<' '<<pz[1]<<' '<<pz[2] << std::endl;
00803         interactor->newPosition(p0, q, transform);
00804       }
00805 
00806       QString QtOgreViewer::helpString() 
00807       {
00808 
00809         QString text("<H1>QtOgreViewer</H1><br>\
00810 <ul>\
00811 <li><b>Mouse</b>: TO NAVIGATE<br></li>\
00812 <li><b>Shift & Left Button</b>: TO PICK OBJECTS<br></li>\
00813 <li><b>C</b>: TO CENTER THE VIEW<br></li>\
00814 <li><b>B</b>: TO CHANGE THE BACKGROUND<br></li>\
00815 <li><b>T</b>: TO CHANGE BETWEEN A PERSPECTIVE OR AN ORTHOGRAPHIC CAMERA<br></li>\
00816 <li><b>L</b>: TO DRAW SHADOWS<br></li>\
00817 <li><b>P</b>: TO SAVE A SEQUENCE OF OBJ<br>\
00818 Each time the frame is updated an obj is exported<br></li>\
00819 <li><b>R</b>: TO CHANGE THE RENDER MODE<br></li>\
00820 <li><b>I</b>: TO SAVE A SCREENSHOT<br>\
00821 The captured images are saved in the running project directory under the name format capturexxxx.bmp<br></li>\
00822 <li><b>V</b>: TO SAVE A VIDEO<br>\
00823 Each time the frame is updated a screenshot is saved<br></li>\
00824 <li><b>Esc</b>: TO QUIT ::sofa:: <br></li></ul>");
00825 
00826         return text;
00827       }
00828 
00829     } //qtogre
00830 
00831       } //viewer
00832 
00833     } //qt
00834 
00835   } //gui
00836 
00837 } //sofa

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