Equalizer  1.4.1
eqPly/config.cpp
00001 
00002 /* Copyright (c) 2006-2012, Stefan Eilemann <eile@equalizergraphics.com>
00003  *               2010, Cedric Stalder <cedric.stalder@gmail.com>
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  * - Redistributions of source code must retain the above copyright notice, this
00009  *   list of conditions and the following disclaimer.
00010  * - Redistributions in binary form must reproduce the above copyright notice,
00011  *   this list of conditions and the following disclaimer in the documentation
00012  *   and/or other materials provided with the distribution.
00013  * - Neither the name of Eyescale Software GmbH nor the names of its
00014  *   contributors may be used to endorse or promote products derived from this
00015  *   software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 #include "config.h"
00031 #include "configEvent.h"
00032 
00033 #include "view.h"
00034 #include "modelAssigner.h"
00035 
00036 #include <admin/addWindow.h>
00037 #include <admin/removeWindow.h>
00038 
00039 namespace eqPly
00040 {
00041 
00042 Config::Config( eq::ServerPtr parent )
00043         : eq::Config( parent )
00044         , _spinX( 5 )
00045         , _spinY( 5 )
00046         , _advance( 0 )
00047         , _currentCanvas( 0 )
00048         , _messageTime( 0 )
00049         , _redraw( true )
00050         , _useIdleAA( true )
00051         , _numFramesAA( 0 )
00052 {
00053 }
00054 
00055 Config::~Config()
00056 {
00057     for( ModelsCIter i = _models.begin(); i != _models.end(); ++i )
00058         delete *i;
00059     _models.clear();
00060 
00061     for( ModelDistsCIter i = _modelDist.begin(); i != _modelDist.end(); ++i )
00062     {
00063         LBASSERT( !(*i)->isAttached() );
00064         delete *i;
00065     }
00066     _modelDist.clear();
00067 }
00068 
00069 bool Config::init()
00070 {
00071     if( !_animation.isValid( ))
00072         _animation.loadAnimation( _initData.getPathFilename( ));
00073 
00074     // init distributed objects
00075     if( !_initData.useColor( ))
00076         _frameData.setColorMode( COLOR_WHITE );
00077 
00078     _frameData.setRenderMode( _initData.getRenderMode( ));
00079     registerObject( &_frameData );
00080     _frameData.setAutoObsolete( getLatency( ));
00081 
00082     _initData.setFrameDataID( _frameData.getID( ));
00083     registerObject( &_initData );
00084 
00085     // init config
00086     if( !eq::Config::init( _initData.getID( )))
00087     {
00088         _deregisterData();
00089         return false;
00090     }
00091 
00092     _loadModels();
00093     _registerModels();
00094 
00095     // init tracker
00096     if( !_initData.getTrackerPort().empty( ))
00097     {
00098         if( !_tracker.init( _initData.getTrackerPort() ))
00099             LBWARN << "Failed to initialize tracker" << std::endl;
00100         else
00101         {
00102             // Set up position of tracking system wrt world space
00103             // Note: this depends on the physical installation.
00104             eq::Matrix4f m( eq::Matrix4f::IDENTITY );
00105             m.scale( 1.f, 1.f, -1.f );
00106             _tracker.setWorldToEmitter( m );
00107 
00108             m = eq::Matrix4f::IDENTITY;
00109             m.rotate_z( -M_PI_2 );
00110             _tracker.setSensorToObject( m );
00111             LBINFO << "Tracker initialized" << std::endl;
00112         }
00113     }
00114 
00115     const eq::Canvases& canvases = getCanvases();
00116     if( canvases.empty( ))
00117         _currentCanvas = 0;
00118     else
00119         _currentCanvas = canvases.front();
00120 
00121     _setMessage( "Welcome to eqPly\nPress F1 for help" );
00122     return true;
00123 }
00124 
00125 bool Config::exit()
00126 {
00127     const bool ret = eq::Config::exit();
00128     _deregisterData();
00129     _closeAdminServer();
00130 
00131     // retain model & distributors for possible other config runs, dtor deletes
00132     return ret;
00133 }
00134 
00135 namespace
00136 {
00137 static bool _isPlyfile( const std::string& filename )
00138 {
00139     const size_t size = filename.length();
00140     if( size < 5 )
00141         return false;
00142 
00143     if( filename[size-4] != '.' || filename[size-3] != 'p' ||
00144         filename[size-2] != 'l' || filename[size-1] != 'y' )
00145     {
00146         return false;
00147     }
00148     return true;
00149 }
00150 }
00151 
00152 void Config::_loadModels()
00153 {
00154     if( !_models.empty( )) // only load on the first config run
00155         return;
00156 
00157     eq::Strings filenames = _initData.getFilenames();
00158     while( !filenames.empty( ))
00159     {
00160         const std::string filename = filenames.back();
00161         filenames.pop_back();
00162      
00163         if( _isPlyfile( filename ))
00164         {
00165             Model* model = new Model;
00166 
00167             if( _initData.useInvertedFaces() )
00168                 model->useInvertedFaces();
00169         
00170             if( !model->readFromFile( filename.c_str( )))
00171             {
00172                 LBWARN << "Can't load model: " << filename << std::endl;
00173                 delete model;
00174             }
00175             else
00176                 _models.push_back( model );
00177         }
00178         else
00179         {
00180             const std::string basename = lunchbox::getFilename( filename );
00181             if( basename == "." || basename == ".." )
00182                 continue;
00183 
00184             // recursively search directories
00185             const eq::Strings subFiles = lunchbox::searchDirectory( filename,
00186                                                                     "*" );
00187 
00188             for(eq::StringsCIter i = subFiles.begin(); i != subFiles.end(); ++i)
00189                 filenames.push_back( filename + '/' + *i );
00190         }
00191     }
00192 }
00193 
00194 void Config::_registerModels()
00195 {
00196     // Register distribution helpers on each config run
00197     const bool createDist = _modelDist.empty(); //first run, create distributors
00198     const size_t  nModels = _models.size();
00199     LBASSERT( createDist || _modelDist.size() == nModels );
00200 
00201     for( size_t i = 0; i < nModels; ++i )
00202     {
00203         const Model* model = _models[i];
00204         ModelDist* modelDist = 0;
00205         if( createDist )
00206         {
00207             modelDist = new ModelDist( model );
00208             _modelDist.push_back( modelDist );
00209         }
00210         else
00211             modelDist = _modelDist[i];
00212 
00213         modelDist->registerTree( getClient( ));
00214         LBASSERT( modelDist->isAttached() );
00215 
00216         _frameData.setModelID( modelDist->getID( ));
00217     }
00218 
00219     LBASSERT( _modelDist.size() == nModels );
00220 
00221     if( !_modelDist.empty( ))
00222     {
00223         ModelAssigner assigner( _modelDist );
00224         accept( assigner );
00225     }
00226 }
00227 
00228 void Config::_deregisterData()
00229 {
00230     for( ModelDistsCIter i = _modelDist.begin(); i != _modelDist.end(); ++i )
00231     {
00232         ModelDist* modelDist = *i;
00233         if( !modelDist->isAttached() ) // already done
00234             continue;
00235 
00236         LBASSERT( modelDist->isMaster( ));
00237         modelDist->deregisterTree();
00238     }
00239 
00240     deregisterObject( &_initData );
00241     deregisterObject( &_frameData );
00242 
00243     _initData.setFrameDataID( eq::UUID::ZERO );
00244     _frameData.setModelID( eq::UUID::ZERO );
00245 }
00246 
00247 bool Config::loadData( const eq::uint128_t& initDataID )
00248 {
00249     if( !_initData.isAttached( ))
00250     {
00251         const uint32_t request = mapObjectNB( &_initData, initDataID,
00252                                               co::VERSION_OLDEST,
00253                                               getApplicationNode( ));
00254         if( !mapObjectSync( request ))
00255             return false;
00256         unmapObject( &_initData ); // data was retrieved, unmap immediately
00257     }
00258     else // appNode, _initData is registered already
00259     {
00260         LBASSERT( _initData.getID() == initDataID );
00261     }
00262     return true;
00263 }
00264 
00265 const Model* Config::getModel( const eq::uint128_t& modelID )
00266 {
00267     if( modelID == eq::UUID::ZERO )
00268         return 0;
00269 
00270     // Protect if accessed concurrently from multiple pipe threads
00271     const eq::Node* node = getNodes().front();
00272     const bool needModelLock = (node->getPipes().size() > 1);
00273     lunchbox::ScopedWrite _mutex( needModelLock ? &_modelLock : 0 );
00274 
00275     const size_t nModels = _models.size();
00276     LBASSERT( _modelDist.size() == nModels );
00277 
00278     for( size_t i = 0; i < nModels; ++i )
00279     {
00280         const ModelDist* dist = _modelDist[ i ];
00281         if( dist->getID() == modelID )
00282             return _models[ i ];
00283     }
00284     
00285     _modelDist.push_back( new ModelDist );
00286     Model* model = _modelDist.back()->loadModel( getApplicationNode(),
00287                                                  getClient(), modelID );
00288     LBASSERT( model );
00289     _models.push_back( model );
00290 
00291     return model;
00292 }
00293 
00294 uint32_t Config::startFrame()
00295 {
00296     _updateData();
00297     const eq::uint128_t& version = _frameData.commit();
00298 
00299     _redraw = false;
00300     return eq::Config::startFrame( version );
00301 }
00302 
00303 void Config::_updateData()
00304 {
00305     // update head position
00306     if( _tracker.isRunning() )
00307     {
00308         _tracker.update();
00309         const eq::Matrix4f& headMatrix = _tracker.getMatrix();
00310         _setHeadMatrix( headMatrix );
00311     }
00312 
00313     // update camera
00314     if( _animation.isValid( ))
00315     {
00316         const eq::Vector3f&  modelRotation = _animation.getModelRotation();
00317         const CameraAnimation::Step& curStep = _animation.getNextStep();
00318 
00319         _frameData.setModelRotation( modelRotation);
00320         _frameData.setRotation( curStep.rotation );
00321         _frameData.setCameraPosition( curStep.position );
00322     }
00323     else
00324     {
00325         if( _frameData.usePilotMode())
00326             _frameData.spinCamera( -0.001f * _spinX, -0.001f * _spinY );
00327         else
00328             _frameData.spinModel( -0.001f * _spinX, -0.001f * _spinY, 0.f );
00329 
00330         _frameData.moveCamera( 0.0f, 0.0f, 0.001f * _advance );
00331     }
00332 
00333     // idle mode
00334     if( isIdleAA( ))
00335     {
00336         LBASSERT( _numFramesAA > 0 );
00337         _frameData.setIdle( true );
00338     }
00339     else
00340         _frameData.setIdle( false );
00341 
00342     _numFramesAA = 0;
00343 }
00344 
00345 bool Config::isIdleAA()
00346 {
00347     return ( !_needNewFrame() && _numFramesAA > 0 );
00348 }
00349 
00350 bool Config::needRedraw()
00351 {
00352     return( _needNewFrame() || _numFramesAA > 0 );
00353 }
00354 
00355 uint32_t Config::getAnimationFrame()
00356 {
00357     return _animation.getCurrentFrame();
00358 }
00359 
00360 bool Config::_needNewFrame()
00361 {
00362     if( _messageTime > 0 )
00363     {
00364         if( getTime() - _messageTime > 2000 ) // reset message after two seconds
00365         {
00366             _messageTime = 0;
00367             _frameData.setMessage( "" );
00368         }
00369         return true;
00370     }
00371 
00372     return ( _spinX != 0 || _spinY != 0 || _advance != 0 ||
00373              _tracker.isRunning() || _redraw );
00374 }
00375 
00376 bool Config::handleEvent( const eq::ConfigEvent* event )
00377 {
00378     switch( event->data.type )
00379     {
00380         case eq::Event::KEY_PRESS:
00381             if( _handleKeyEvent( event->data.keyPress ))
00382             {
00383                 _redraw = true;
00384                 return true;
00385             }
00386             break;
00387 
00388         case eq::Event::CHANNEL_POINTER_BUTTON_PRESS:
00389         {
00390             const eq::uint128_t& viewID = event->data.context.view.identifier;
00391             _frameData.setCurrentViewID( viewID );
00392             if( viewID == eq::UUID::ZERO )
00393             {
00394                 _currentCanvas = 0;
00395                 return false;
00396             }
00397             
00398             const View* view = _getCurrentView();
00399             const eq::Layout* layout = view->getLayout();
00400             const eq::Canvases& canvases = getCanvases();
00401             for( eq::CanvasesCIter i = canvases.begin();
00402                  i != canvases.end(); ++i )
00403             {
00404                 eq::Canvas* canvas = *i;
00405                 const eq::Layout* canvasLayout = canvas->getActiveLayout();
00406 
00407                 if( canvasLayout == layout )
00408                 {
00409                     _currentCanvas = canvas;
00410                     return true;
00411                 }
00412             }
00413             return true;
00414         }
00415 
00416         case eq::Event::CHANNEL_POINTER_BUTTON_RELEASE:
00417         {
00418             const eq::PointerEvent& releaseEvent = 
00419                 event->data.pointerButtonRelease;
00420             if( releaseEvent.buttons == eq::PTR_BUTTON_NONE)
00421             {
00422                 if( releaseEvent.button == eq::PTR_BUTTON1 )
00423                 {
00424                     _spinX = releaseEvent.dy;
00425                     _spinY = releaseEvent.dx;
00426                     _redraw = true;
00427                     return true;
00428                 }
00429                 if( releaseEvent.button == eq::PTR_BUTTON2 )
00430                 {
00431                     _advance = -releaseEvent.dy;
00432                     _redraw = true;
00433                     return true;
00434                 }
00435             }
00436             break;
00437         }
00438         case eq::Event::CHANNEL_POINTER_MOTION:
00439             switch( event->data.pointerMotion.buttons )
00440             {
00441               case eq::PTR_BUTTON1:
00442                   _spinX = 0;
00443                   _spinY = 0;
00444 
00445                   if( _frameData.usePilotMode())
00446                       _frameData.spinCamera(
00447                           -0.005f * event->data.pointerMotion.dy,
00448                           -0.005f * event->data.pointerMotion.dx );
00449                   else
00450                       _frameData.spinModel(
00451                           -0.005f * event->data.pointerMotion.dy,
00452                           -0.005f * event->data.pointerMotion.dx, 0.f );
00453                   _redraw = true;
00454                   return true;
00455 
00456               case eq::PTR_BUTTON2:
00457                   _advance = -event->data.pointerMotion.dy;
00458                   _frameData.moveCamera( 0.f, 0.f, .005f * _advance );
00459                   _redraw = true;
00460                   return true;
00461 
00462               case eq::PTR_BUTTON3:
00463                   _frameData.moveCamera(  .0005f * event->data.pointerMotion.dx,
00464                                          -.0005f * event->data.pointerMotion.dy,
00465                                           0.f );
00466                   _redraw = true;
00467                   return true;
00468             }
00469             break;
00470 
00471         case eq::Event::WINDOW_POINTER_WHEEL:
00472             _frameData.moveCamera( -0.05f * event->data.pointerWheel.yAxis,
00473                                    0.f,
00474                                    0.05f * event->data.pointerWheel.xAxis );
00475             _redraw = true;
00476             return true;
00477 
00478         case eq::Event::MAGELLAN_AXIS:
00479             _spinX = 0;
00480             _spinY = 0;
00481             _advance = 0;
00482             _frameData.spinModel(  0.0001f * event->data.magellan.zRotation,
00483                                   -0.0001f * event->data.magellan.xRotation,
00484                                   -0.0001f * event->data.magellan.yRotation );
00485             _frameData.moveCamera(  0.0001f * event->data.magellan.xAxis,
00486                                    -0.0001f * event->data.magellan.zAxis,
00487                                     0.0001f * event->data.magellan.yAxis );
00488             _redraw = true;
00489             return true;
00490 
00491         case eq::Event::MAGELLAN_BUTTON:
00492             if( event->data.magellan.button == eq::PTR_BUTTON1 )
00493                 _frameData.toggleColorMode();
00494 
00495             _redraw = true;
00496             return true;
00497 
00498         case eq::Event::WINDOW_EXPOSE:
00499         case eq::Event::WINDOW_RESIZE:
00500         case eq::Event::WINDOW_CLOSE:
00501         case eq::Event::VIEW_RESIZE:
00502             _redraw = true;
00503             break;
00504 
00505         case ConfigEvent::IDLE_AA_LEFT:
00506             if( _useIdleAA )
00507             {
00508                 const ConfigEvent* idleEvent = 
00509                     static_cast< const ConfigEvent* >( event );
00510                 _numFramesAA = LB_MAX( _numFramesAA, idleEvent->steps );
00511             }
00512             else
00513                 _numFramesAA = 0;
00514             return false;
00515 
00516         default:
00517             break;
00518     }
00519 
00520     _redraw |= eq::Config::handleEvent( event );
00521     return _redraw;
00522 }
00523 
00524 bool Config::_handleKeyEvent( const eq::KeyEvent& event )
00525 {
00526     switch( event.key )
00527     {
00528         case 'z':
00529             _adjustEyeBase( -0.1f );
00530             return true;
00531         case 'Z':
00532             _adjustEyeBase( 0.1f );
00533             return true;
00534         case 'y':
00535             _adjustModelScale( 0.1f );
00536             return true;
00537         case 'Y':
00538             _adjustModelScale( 10.0f );
00539             return true;
00540         case 't':
00541             _adjustTileSize( -1 );
00542             return true;
00543         case 'T':
00544             _adjustTileSize( 1 );
00545              return true;
00546         case 'u':
00547             _frameData.toggleCompression();
00548             return true;
00549 
00550         case 'n':
00551         case 'N':
00552             _frameData.togglePilotMode();
00553             return true;
00554         case ' ':
00555             stopFrames();
00556             _spinX   = 0;
00557             _spinY   = 0;
00558             _advance = 0;
00559             _frameData.reset();
00560             _setHeadMatrix( eq::Matrix4f::IDENTITY );
00561             return true;
00562 
00563         case 'i':
00564             _useIdleAA = !_useIdleAA;
00565             return true;
00566 
00567         case 'k':
00568         {
00569             lunchbox::RNG rng;
00570             if( rng.get< bool >( ))
00571                 _frameData.toggleOrtho();
00572             if( rng.get< bool >( ))
00573                 _frameData.toggleStatistics();
00574             if( rng.get< bool >( ))
00575                 _switchCanvas();
00576             if( rng.get< bool >( ))
00577                 _switchView();
00578             if( rng.get< bool >( ))
00579                 _switchLayout( 1 );
00580             if( rng.get< bool >( ))
00581                 _switchModel();
00582             if( rng.get< bool >( ))
00583                 eqAdmin::addWindow( _getAdminServer(), rng.get< bool >( ));
00584             if( rng.get< bool >( ))
00585             {
00586                 eqAdmin::removeWindow( _getAdminServer( ));
00587                 _currentCanvas = 0;
00588             }
00589             if( rng.get< bool >( ))
00590                 _switchViewMode();
00591             return true;
00592         }
00593 
00594         case 'o':
00595         case 'O':
00596             _frameData.toggleOrtho();
00597             return true;
00598 
00599         case 's':
00600         case 'S':
00601             _frameData.toggleStatistics();
00602             return true;
00603             
00604         case 'f':
00605             _freezeLoadBalancing( true );
00606             return true;
00607 
00608         case 'F':
00609             _freezeLoadBalancing( false );
00610             return true;
00611 
00612         case eq::KC_F1:
00613         case 'h':
00614         case 'H':
00615             _frameData.toggleHelp();
00616             return true;
00617 
00618         case 'd':
00619         case 'D':
00620             _frameData.toggleColorMode();
00621             return true;
00622 
00623         case 'q':
00624             _frameData.adjustQuality( -.1f );
00625             return true;
00626 
00627         case 'Q':
00628             _frameData.adjustQuality( .1f );
00629             return true;
00630 
00631         case 'c':
00632         case 'C':
00633             _switchCanvas();
00634             return true;
00635 
00636         case 'v':
00637         case 'V':
00638             _switchView();
00639             return true;
00640 
00641         case 'm':
00642         case 'M':
00643             _switchModel();
00644             return true;
00645 
00646         case 'l':
00647             _switchLayout( 1 );
00648             return true;
00649         case 'L':
00650             _switchLayout( -1 );
00651             return true;
00652 
00653         case 'w':
00654         case 'W':
00655             _frameData.toggleWireframe();
00656             return true;
00657 
00658         case 'r':
00659         case 'R':
00660             _frameData.toggleRenderMode();
00661             return true;
00662         case 'g':
00663         case 'G':
00664             _switchViewMode();
00665             return true;
00666         case 'a':
00667             eqAdmin::addWindow( _getAdminServer(), false /* active stereo */ );
00668             return true;
00669         case 'p':
00670             eqAdmin::addWindow( _getAdminServer(), true /* passive stereo */ );
00671             return true;
00672         case 'x':
00673             eqAdmin::removeWindow( _getAdminServer( ));
00674             _currentCanvas = 0;
00675             LBASSERT( update() );
00676             return false;
00677 
00678         // Head Tracking Emulation
00679         case eq::KC_UP:
00680         {
00681             eq::Matrix4f headMatrix = _getHeadMatrix();
00682             headMatrix.y() += 0.1f;
00683             _setHeadMatrix( headMatrix );
00684             return true;
00685         }
00686         case eq::KC_DOWN:
00687         {
00688             eq::Matrix4f headMatrix = _getHeadMatrix();
00689             headMatrix.y() -= 0.1f;
00690             _setHeadMatrix( headMatrix );
00691             return true;
00692         }
00693         case eq::KC_RIGHT:
00694         {
00695             eq::Matrix4f headMatrix = _getHeadMatrix();
00696             headMatrix.x() += 0.1f;
00697             _setHeadMatrix( headMatrix );
00698             return true;
00699         }
00700         case eq::KC_LEFT:
00701         {
00702             eq::Matrix4f headMatrix = _getHeadMatrix();
00703             headMatrix.x() -= 0.1f;
00704             _setHeadMatrix( headMatrix );
00705             return true;
00706         }
00707         case eq::KC_PAGE_DOWN:
00708         {
00709             eq::Matrix4f headMatrix = _getHeadMatrix();
00710             headMatrix.z() += 0.1f;
00711             _setHeadMatrix( headMatrix );
00712             return true;
00713         }
00714         case eq::KC_PAGE_UP:
00715         {
00716             eq::Matrix4f headMatrix = _getHeadMatrix();
00717             headMatrix.z() -= 0.1f;
00718             _setHeadMatrix( headMatrix );
00719             return true;
00720         }
00721         case '.':
00722         {
00723             eq::Matrix4f headMatrix = _getHeadMatrix();
00724             headMatrix.pre_rotate_x( .1f );
00725             _setHeadMatrix( headMatrix );
00726             return true;
00727         }
00728         case ',':
00729         {
00730             eq::Matrix4f headMatrix = _getHeadMatrix();
00731             headMatrix.pre_rotate_x( -.1f );
00732             _setHeadMatrix( headMatrix );
00733             return true;
00734         }
00735         case ';':
00736         {
00737             eq::Matrix4f headMatrix = _getHeadMatrix();
00738             headMatrix.pre_rotate_y( .1f );
00739             _setHeadMatrix( headMatrix );
00740             return true;
00741         }
00742         case '\'':
00743         {
00744             eq::Matrix4f headMatrix = _getHeadMatrix();
00745             headMatrix.pre_rotate_y( -.1f );
00746             _setHeadMatrix( headMatrix );
00747             return true;
00748         }
00749         case '[':
00750         {
00751             eq::Matrix4f headMatrix = _getHeadMatrix();
00752             headMatrix.pre_rotate_z( -.1f );
00753             _setHeadMatrix( headMatrix );
00754             return true;
00755         }
00756         case ']':
00757         {
00758             eq::Matrix4f headMatrix = _getHeadMatrix();
00759             headMatrix.pre_rotate_z( .1f );
00760             _setHeadMatrix( headMatrix );
00761             return true;
00762         }
00763 
00764         case '+':
00765             _changeFocusDistance( .1f );
00766             return true;
00767 
00768         case '-':
00769             _changeFocusDistance( -.1f );
00770             return true;
00771 
00772         case '1':
00773             _setFocusMode( eq::FOCUSMODE_FIXED );
00774             return true;
00775 
00776         case '2':
00777             _setFocusMode( eq::FOCUSMODE_RELATIVE_TO_ORIGIN );
00778             return true;
00779 
00780         case '3':
00781             _setFocusMode( eq::FOCUSMODE_RELATIVE_TO_OBSERVER );
00782             return true;
00783 
00784         case 'j':
00785             stopFrames();
00786             return true;
00787 
00788         case 'e':
00789             _toggleEqualizer();
00790             return true;
00791 
00792         default:
00793             return false;
00794     }
00795 }
00796 
00797 co::uint128_t Config::sync( const co::uint128_t& version )
00798 {
00799     if( _admin.isValid() && _admin->isConnected( ))
00800         _admin->syncConfig( getID(), version );
00801 
00802     return eq::Config::sync( version );
00803 }
00804 
00805 void Config::_switchCanvas()
00806 {
00807     const eq::Canvases& canvases = getCanvases();
00808     if( canvases.empty( ))
00809         return;
00810 
00811     _frameData.setCurrentViewID( eq::UUID::ZERO );
00812 
00813     if( !_currentCanvas )
00814     {
00815         _currentCanvas = canvases.front();
00816         return;
00817     }
00818 
00819     eq::CanvasesCIter i = stde::find( canvases, _currentCanvas );
00820     LBASSERT( i != canvases.end( ));
00821 
00822     ++i;
00823     if( i == canvases.end( ))
00824         _currentCanvas = canvases.front();
00825     else
00826         _currentCanvas = *i;
00827     _switchView(); // activate first view on canvas
00828 }
00829 
00830 void Config::_switchView()
00831 {
00832     const eq::Canvases& canvases = getCanvases();
00833     if( !_currentCanvas && !canvases.empty( ))
00834         _currentCanvas = canvases.front();
00835 
00836     if( !_currentCanvas )
00837         return;
00838 
00839     const eq::Layout* layout = _currentCanvas->getActiveLayout();
00840     if( !layout )
00841         return;
00842 
00843     const View* view = _getCurrentView();
00844     const eq::Views& views = layout->getViews();
00845     LBASSERT( !views.empty( ));
00846 
00847     if( !view )
00848     {
00849         _frameData.setCurrentViewID( views.front()->getID( ));
00850         return;
00851     }
00852 
00853     eq::ViewsCIter i = std::find( views.begin(), views.end(), view );
00854     if( i != views.end( ))
00855         ++i;
00856     if( i == views.end( ))
00857         _frameData.setCurrentViewID( eq::UUID::ZERO );
00858     else
00859         _frameData.setCurrentViewID( (*i)->getID( ));
00860 }
00861 
00862 void Config::_switchModel()
00863 {
00864     if( _modelDist.empty( )) // no models
00865         return;
00866 
00867     // current model of current view
00868     View* view = _getCurrentView();
00869     const eq::uint128_t& currentID = view ? view->getModelID() :
00870                                             _frameData.getModelID();
00871     // next model
00872     ModelDistsCIter i;
00873     for( i = _modelDist.begin(); i != _modelDist.end(); ++i )
00874     {
00875         if( (*i)->getID() != currentID )
00876             continue;
00877                 
00878         ++i;
00879         break;
00880     }
00881     if( i == _modelDist.end( ))
00882         i = _modelDist.begin(); // wrap around
00883 
00884     // set identifier on view or frame data (default model)
00885     const eq::uint128_t& modelID = (*i)->getID();
00886     if( view )
00887         view->setModelID( modelID );
00888     else
00889         _frameData.setModelID( modelID );
00890 
00891     if( view )
00892     {
00893         const Model* model = getModel( modelID );
00894         _setMessage( "Using " + lunchbox::getFilename( model->getName( )));
00895     }
00896 }
00897 
00898 void Config::_switchViewMode()
00899 {
00900     View* view = _getCurrentView();
00901     if( !view )
00902         return;
00903 
00904     const eq::View::Mode mode = view->getMode();
00905     if( mode == eq::View::MODE_MONO )
00906     {
00907         view->changeMode( eq::View::MODE_STEREO );
00908         _setMessage( "Switched to stereoscopic rendering" );
00909     }
00910     else
00911     {
00912         view->changeMode( eq::View::MODE_MONO );
00913         _setMessage( "Switched to monoscopic rendering" );
00914     }
00915 }
00916 
00917 void Config::_freezeLoadBalancing( const bool onOff )
00918 {
00919     View* view = _getCurrentView();
00920     if ( view )
00921         view->freezeLoadBalancing( onOff );
00922 }
00923 
00924 void Config::_adjustEyeBase( const float delta )
00925 {
00926     const eq::Observers& observers = getObservers();
00927     for( eq::ObserversCIter i = observers.begin(); i != observers.end(); ++i )
00928     {
00929         eq::Observer* observer = *i;
00930         observer->setEyeBase( observer->getEyeBase() + delta );
00931         std::ostringstream stream;
00932         stream << "Set eye base to " << observer->getEyeBase();
00933         _setMessage( stream.str( ));
00934     }
00935 }
00936 
00937 void Config::_adjustTileSize( const int delta )
00938 {
00939     View* view = _getCurrentView();
00940     if( !view )
00941         return;
00942 
00943     eq::Vector2i tileSize = view->getTileSize();
00944     if( tileSize == eq::Vector2i( -1, -1 ) )
00945         tileSize = eq::Vector2i( 64, 64 );
00946     tileSize += delta;
00947     view->setTileSize( tileSize );
00948 }
00949 
00950 void Config::_adjustModelScale( const float factor )
00951 {
00952     View* view = _getCurrentView();
00953     if( !view )
00954         return;
00955 
00956     const float current = view->getModelUnit() * factor;
00957     if( current > std::numeric_limits<float>::epsilon( ))
00958         view->setModelUnit( current );
00959 
00960     std::ostringstream stream;
00961     stream << "Set model unit to " << view->getModelUnit();
00962     _setMessage( stream.str( ));
00963 }
00964 
00965 void Config::_switchLayout( int32_t increment )
00966 {
00967     if( !_currentCanvas )
00968         return;
00969 
00970     _frameData.setCurrentViewID( eq::UUID::ZERO );
00971 
00972     int64_t index = _currentCanvas->getActiveLayoutIndex() + increment;
00973     const eq::Layouts& layouts = _currentCanvas->getLayouts();
00974     LBASSERT( !layouts.empty( ));
00975 
00976     index = ( index % layouts.size( ));
00977     _currentCanvas->useLayout( uint32_t( index ));
00978 
00979     const eq::Layout* layout = layouts[index];
00980     std::ostringstream stream;
00981     stream << "Layout ";
00982     if( layout )
00983     {
00984         const std::string& name = layout->getName();
00985         if( name.empty( ))
00986             stream << index;
00987         else
00988             stream << name;
00989     }
00990     else
00991         stream << "NONE";
00992 
00993     stream << " active";
00994     _setMessage( stream.str( ));
00995 }
00996 
00997 void Config::_toggleEqualizer()
00998 {
00999     View* view = _getCurrentView();
01000     if ( view )
01001         view->toggleEqualizer();
01002 }
01003 
01004 // Note: real applications would use one tracking device per observer
01005 void Config::_setHeadMatrix( const eq::Matrix4f& matrix )
01006 {
01007     const eq::Observers& observers = getObservers();
01008     for( eq::ObserversCIter i = observers.begin(); i != observers.end(); ++i )
01009     {
01010         (*i)->setHeadMatrix( matrix );
01011     }
01012 
01013     eq::Vector3f trans;
01014     matrix.get_translation( trans );
01015     std::ostringstream stream;
01016     stream << "Observer at " << trans;
01017     _setMessage( stream.str( ));
01018 }
01019 
01020 const eq::Matrix4f& Config::_getHeadMatrix() const
01021 {
01022     const eq::Observers& observers = getObservers();
01023     if( observers.empty( ))
01024         return eq::Matrix4f::IDENTITY;
01025 
01026     return observers[0]->getHeadMatrix();
01027 }
01028 
01029 void Config::_changeFocusDistance( const float delta )
01030 {
01031     const eq::Observers& observers = getObservers();
01032     for( eq::ObserversCIter i = observers.begin(); i != observers.end(); ++i )
01033     {
01034         eq::Observer* observer = *i;
01035         observer->setFocusDistance( observer->getFocusDistance() + delta );
01036         std::ostringstream stream;
01037         stream << "Set focus distance to " << observer->getFocusDistance();
01038         _setMessage( stream.str( ));
01039     }
01040 }
01041 
01042 void Config::_setFocusMode( const eq::FocusMode mode )
01043 {
01044     const eq::Observers& observers = getObservers();
01045     for( eq::ObserversCIter i = observers.begin(); i != observers.end(); ++i )
01046         (*i)->setFocusMode( mode );
01047 
01048     std::ostringstream stream;
01049     stream << "Set focus mode to " << mode;
01050     _setMessage( stream.str( ));
01051 }
01052 
01053 void Config::_setMessage( const std::string& message )
01054 {
01055     _frameData.setMessage( message );
01056     _messageTime = getTime();
01057 }
01058 
01059 eq::admin::ServerPtr Config::_getAdminServer()
01060 {
01061     // Debug: _closeAdminServer();
01062     if( _admin.isValid() && _admin->isConnected( ))
01063         return _admin;
01064 
01065     eq::admin::init( 0, 0 );
01066     eq::admin::ClientPtr client = new eq::admin::Client;
01067     if( !client->initLocal( 0, 0 ))
01068     {
01069         _setMessage( "Can't init admin client" );
01070         eq::admin::exit();
01071     }
01072 
01073     _admin = new eq::admin::Server;
01074     if( !client->connectServer( _admin ))
01075     {
01076         _setMessage( "Can't open connection to administrate server" );
01077         client->exitLocal();
01078         _admin = 0;
01079         eq::admin::exit();
01080     }
01081     return _admin;
01082 }
01083 
01084 void Config::_closeAdminServer()
01085 {
01086     if( !_admin )
01087         return;
01088 
01089     eq::admin::ClientPtr client = _admin->getClient();
01090     client->disconnectServer( _admin );
01091     client->exitLocal();
01092     LBASSERT( client->getRefCount() == 1 );
01093     LBASSERT( _admin->getRefCount() == 1 );
01094     
01095     _admin = 0;
01096     eq::admin::exit();
01097 }
01098 
01099 View* Config::_getCurrentView()
01100 {
01101     const eq::uint128_t& viewID = _frameData.getCurrentViewID();
01102     eq::View* view = find< eq::View >( viewID );
01103     return static_cast< View* >( view );
01104 }
01105 
01106 const View* Config::_getCurrentView() const
01107 {
01108     const eq::uint128_t& viewID = _frameData.getCurrentViewID();
01109     const eq::View* view = find< eq::View >( viewID );
01110     return static_cast< const View* >( view );
01111 }
01112 
01113 }
Generated on Mon Nov 26 2012 14:41:48 for Equalizer 1.4.1 by  doxygen 1.7.6.1