Equalizer  1.2.1
eqPly/config.cpp
00001 
00002 /* Copyright (c) 2006-2011, 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     {
00059         delete *i;
00060     }
00061     _models.clear();
00062 
00063     for( ModelDistsCIter i = _modelDist.begin(); i != _modelDist.end(); ++i )
00064     {
00065         EQASSERT( !(*i)->isAttached() );
00066         delete *i;
00067     }
00068     _modelDist.clear();
00069 }
00070 
00071 bool Config::init()
00072 {
00073     if( !_animation.isValid( ))
00074         _animation.loadAnimation( _initData.getPathFilename( ));
00075 
00076     // init distributed objects
00077     if( !_initData.useColor( ))
00078         _frameData.setColorMode( COLOR_WHITE );
00079 
00080     _frameData.setRenderMode( _initData.getRenderMode( ));
00081     registerObject( &_frameData );
00082     _frameData.setAutoObsolete( getLatency( ));
00083 
00084     _initData.setFrameDataID( _frameData.getID( ));
00085     registerObject( &_initData );
00086 
00087     // init config
00088     if( !eq::Config::init( _initData.getID( )))
00089     {
00090         _deregisterData();
00091         return false;
00092     }
00093 
00094     _loadModels();
00095     _registerModels();
00096 
00097     // init tracker
00098     if( !_initData.getTrackerPort().empty( ))
00099     {
00100         if( !_tracker.init( _initData.getTrackerPort() ))
00101             EQWARN << "Failed to initialize tracker" << std::endl;
00102         else
00103         {
00104             // Set up position of tracking system wrt world space
00105             // Note: this depends on the physical installation.
00106             eq::Matrix4f m( eq::Matrix4f::IDENTITY );
00107             m.scale( 1.f, 1.f, -1.f );
00108             _tracker.setWorldToEmitter( m );
00109 
00110             m = eq::Matrix4f::IDENTITY;
00111             m.rotate_z( -M_PI_2 );
00112             _tracker.setSensorToObject( m );
00113             EQINFO << "Tracker initialized" << std::endl;
00114         }
00115     }
00116 
00117     const eq::Canvases& canvases = getCanvases();
00118     if( canvases.empty( ))
00119         _currentCanvas = 0;
00120     else
00121         _currentCanvas = canvases.front();
00122 
00123     _setMessage( "Welcome to eqPly\nPress F1 for help" );
00124     return true;
00125 }
00126 
00127 bool Config::exit()
00128 {
00129     const bool ret = eq::Config::exit();
00130     _deregisterData();
00131     _closeAdminServer();
00132 
00133     // retain model & distributors for possible other config runs, dtor deletes
00134     return ret;
00135 }
00136 
00137 namespace
00138 {
00139 static bool _isPlyfile( const std::string& filename )
00140 {
00141     const size_t size = filename.length();
00142     if( size < 5 )
00143         return false;
00144 
00145     if( filename[size-4] != '.' || filename[size-3] != 'p' ||
00146         filename[size-2] != 'l' || filename[size-1] != 'y' )
00147     {
00148         return false;
00149     }
00150     return true;
00151 }
00152 }
00153 
00154 void Config::_loadModels()
00155 {
00156     if( !_models.empty( )) // only load on the first config run
00157         return;
00158 
00159     eq::Strings filenames = _initData.getFilenames();
00160     while( !filenames.empty( ))
00161     {
00162         const std::string filename = filenames.back();
00163         filenames.pop_back();
00164      
00165         if( _isPlyfile( filename ))
00166         {
00167             Model* model = new Model;
00168 
00169             if( _initData.useInvertedFaces() )
00170                 model->useInvertedFaces();
00171         
00172             if( !model->readFromFile( filename.c_str() ) )
00173             {
00174                 EQWARN << "Can't load model: " << filename << std::endl;
00175                 delete model;
00176             }
00177             else
00178                 _models.push_back( model );
00179         }
00180         else
00181         {
00182             const std::string basename = co::base::getFilename( filename );
00183             if( basename == "." || basename == ".." )
00184                 continue;
00185 
00186             // recursively search directories
00187             const eq::Strings subFiles = co::base::searchDirectory( filename,
00188                                                                     "*" );
00189 
00190             for(eq::StringsCIter i = subFiles.begin(); i != subFiles.end(); ++i)
00191                 filenames.push_back( filename + '/' + *i );
00192         }
00193     }
00194 }
00195 
00196 void Config::_registerModels()
00197 {
00198     // Register distribution helpers on each config run
00199     const bool createDist = _modelDist.empty(); //first run, create distributors
00200     const size_t  nModels = _models.size();
00201     EQASSERT( createDist || _modelDist.size() == nModels );
00202 
00203     for( size_t i = 0; i < nModels; ++i )
00204     {
00205         const Model* model = _models[i];
00206         ModelDist* modelDist = 0;
00207         if( createDist )
00208         {
00209             modelDist = new ModelDist( model );
00210             _modelDist.push_back( modelDist );
00211         }
00212         else
00213             modelDist = _modelDist[i];
00214 
00215         modelDist->registerTree( getClient( ));
00216         EQASSERT( modelDist->isAttached() );
00217 
00218         _frameData.setModelID( modelDist->getID( ));
00219     }
00220 
00221     EQASSERT( _modelDist.size() == nModels );
00222 
00223     if( !_modelDist.empty( ))
00224     {
00225         ModelAssigner assigner( _modelDist );
00226         accept( assigner );
00227     }
00228 }
00229 
00230 void Config::_deregisterData()
00231 {
00232     for( ModelDistsCIter i = _modelDist.begin(); i != _modelDist.end(); ++i )
00233     {
00234         ModelDist* modelDist = *i;
00235         if( !modelDist->isAttached() ) // already done
00236             continue;
00237 
00238         EQASSERT( modelDist->isMaster( ));
00239         modelDist->deregisterTree();
00240     }
00241 
00242     deregisterObject( &_initData );
00243     deregisterObject( &_frameData );
00244 
00245     _initData.setFrameDataID( eq::UUID::ZERO );
00246     _frameData.setModelID( eq::UUID::ZERO );
00247 }
00248 
00249 bool Config::mapData( const eq::uint128_t& initDataID )
00250 {
00251     if( !_initData.isAttached( ))
00252     {
00253         const uint32_t request = mapObjectNB( &_initData, initDataID,
00254                                               co::VERSION_OLDEST,
00255                                               getApplicationNode( ));
00256         if( !mapObjectSync( request ))
00257             return false;
00258         unmapObject( &_initData ); // data was retrieved, unmap immediately
00259     }
00260     else // appNode, _initData is registered already
00261     {
00262         EQASSERT( _initData.getID() == initDataID );
00263     }
00264     return true;
00265 }
00266 
00267 void Config::unmapData()
00268 {
00269     for( ModelDistsCIter i = _modelDist.begin(); i != _modelDist.end(); ++i )
00270     {
00271         ModelDist* modelDist = *i;
00272         if( !modelDist->isAttached( )) // already done
00273             continue;
00274 
00275         if( !modelDist->isMaster( )) // leave registered on appNode
00276             modelDist->unmapTree();
00277     }
00278 }
00279 
00280 const Model* Config::getModel( const eq::uint128_t& modelID )
00281 {
00282     if( modelID == eq::UUID::ZERO )
00283         return 0;
00284 
00285     // Accessed concurrently from pipe threads
00286     co::base::ScopedMutex<> _mutex( _modelLock );
00287 
00288     const size_t nModels = _models.size();
00289     EQASSERT( _modelDist.size() == nModels );
00290 
00291     for( size_t i = 0; i < nModels; ++i )
00292     {
00293         const ModelDist* dist = _modelDist[ i ];
00294         if( dist->getID() == modelID )
00295             return _models[ i ];
00296     }
00297     
00298     _modelDist.push_back( new ModelDist );
00299     Model* model = _modelDist.back()->mapModel( getClient(), modelID );
00300     EQASSERT( model );
00301     _models.push_back( model );
00302 
00303     return model;
00304 }
00305 
00306 uint32_t Config::startFrame()
00307 {
00308     _updateData();
00309     const eq::uint128_t& version = _frameData.commit();
00310 
00311     _redraw = false;
00312     return eq::Config::startFrame( version );
00313 }
00314 
00315 void Config::_updateData()
00316 {
00317     // update head position
00318     if( _tracker.isRunning() )
00319     {
00320         _tracker.update();
00321         const eq::Matrix4f& headMatrix = _tracker.getMatrix();
00322         _setHeadMatrix( headMatrix );
00323     }
00324 
00325     // update database
00326     if( _animation.isValid( ))
00327     {
00328         const eq::Vector3f&  modelRotation = _animation.getModelRotation();
00329         const CameraAnimation::Step& curStep = _animation.getNextStep();
00330 
00331         _frameData.setModelRotation( modelRotation);
00332         _frameData.setRotation( curStep.rotation );
00333         _frameData.setCameraPosition( curStep.position );
00334     }
00335     else
00336     {
00337         if( _frameData.usePilotMode())
00338             _frameData.spinCamera( -0.001f * _spinX, -0.001f * _spinY );
00339         else
00340             _frameData.spinModel( -0.001f * _spinX, -0.001f * _spinY, 0.f );
00341 
00342         _frameData.moveCamera( 0.0f, 0.0f, 0.001f * _advance );
00343     }
00344 
00345     // idle mode
00346     if( isIdleAA( ))
00347     {
00348         EQASSERT( _numFramesAA > 0 );
00349         _frameData.setIdle( true );
00350     }
00351     else
00352         _frameData.setIdle( false );
00353 
00354     _numFramesAA = 0;
00355 }
00356 
00357 bool Config::isIdleAA()
00358 {
00359     return ( !_needNewFrame() && _numFramesAA > 0 );
00360 }
00361 
00362 bool Config::needRedraw()
00363 {
00364     return( _needNewFrame() || _numFramesAA > 0 );
00365 }
00366 
00367 uint32_t Config::getAnimationFrame()
00368 {
00369     return _animation.getCurrentFrame();
00370 }
00371 
00372 bool Config::_needNewFrame()
00373 {
00374     if( _messageTime > 0 )
00375     {
00376         if( getTime() - _messageTime > 2000 ) // reset message after two seconds
00377         {
00378             _messageTime = 0;
00379             _frameData.setMessage( "" );
00380         }
00381         return true;
00382     }
00383 
00384     return ( _spinX != 0 || _spinY != 0 || _advance != 0 ||
00385              _tracker.isRunning() || _redraw );
00386 }
00387 
00388 bool Config::handleEvent( const eq::ConfigEvent* event )
00389 {
00390     switch( event->data.type )
00391     {
00392         case eq::Event::KEY_PRESS:
00393             if( _handleKeyEvent( event->data.keyPress ))
00394             {
00395                 _redraw = true;
00396                 return true;
00397             }
00398             break;
00399 
00400         case eq::Event::CHANNEL_POINTER_BUTTON_PRESS:
00401         {
00402             const eq::uint128_t& viewID = event->data.context.view.identifier;
00403             _frameData.setCurrentViewID( viewID );
00404             if( viewID == eq::UUID::ZERO )
00405             {
00406                 _currentCanvas = 0;
00407                 return false;
00408             }
00409             
00410             const View* view = _getCurrentView();
00411             const eq::Layout* layout = view->getLayout();
00412             const eq::Canvases& canvases = getCanvases();
00413             for( eq::CanvasesCIter i = canvases.begin();
00414                  i != canvases.end(); ++i )
00415             {
00416                 eq::Canvas* canvas = *i;
00417                 const eq::Layout* canvasLayout = canvas->getActiveLayout();
00418 
00419                 if( canvasLayout == layout )
00420                 {
00421                     _currentCanvas = canvas;
00422                     return true;
00423                 }
00424             }
00425             return true;
00426         }
00427 
00428         case eq::Event::CHANNEL_POINTER_BUTTON_RELEASE:
00429         {
00430             const eq::PointerEvent& releaseEvent = 
00431                 event->data.pointerButtonRelease;
00432             if( releaseEvent.buttons == eq::PTR_BUTTON_NONE)
00433             {
00434                 if( releaseEvent.button == eq::PTR_BUTTON1 )
00435                 {
00436                     _spinX = releaseEvent.dy;
00437                     _spinY = releaseEvent.dx;
00438                     _redraw = true;
00439                     return true;
00440                 }
00441                 if( releaseEvent.button == eq::PTR_BUTTON2 )
00442                 {
00443                     _advance = -releaseEvent.dy;
00444                     _redraw = true;
00445                     return true;
00446                 }
00447             }
00448             break;
00449         }
00450         case eq::Event::CHANNEL_POINTER_MOTION:
00451             switch( event->data.pointerMotion.buttons )
00452             {
00453               case eq::PTR_BUTTON1:
00454                   _spinX = 0;
00455                   _spinY = 0;
00456 
00457                   if( _frameData.usePilotMode())
00458                       _frameData.spinCamera(
00459                           -0.005f * event->data.pointerMotion.dy,
00460                           -0.005f * event->data.pointerMotion.dx );
00461                   else
00462                       _frameData.spinModel(
00463                           -0.005f * event->data.pointerMotion.dy,
00464                           -0.005f * event->data.pointerMotion.dx, 0.f );
00465                   _redraw = true;
00466                   return true;
00467 
00468               case eq::PTR_BUTTON2:
00469                   _advance = -event->data.pointerMotion.dy;
00470                   _frameData.moveCamera( 0.f, 0.f, .005f * _advance );
00471                   _redraw = true;
00472                   return true;
00473 
00474               case eq::PTR_BUTTON3:
00475                   _frameData.moveCamera(  .0005f * event->data.pointerMotion.dx,
00476                                          -.0005f * event->data.pointerMotion.dy,
00477                                           0.f );
00478                   _redraw = true;
00479                   return true;
00480             }
00481             break;
00482 
00483         case eq::Event::WINDOW_POINTER_WHEEL:
00484             _frameData.moveCamera( -0.05f * event->data.pointerWheel.yAxis,
00485                                    0.f,
00486                                    0.05f * event->data.pointerWheel.xAxis );
00487             _redraw = true;
00488             return true;
00489 
00490         case eq::Event::MAGELLAN_AXIS:
00491             _spinX = 0;
00492             _spinY = 0;
00493             _advance = 0;
00494             _frameData.spinModel(  0.0001f * event->data.magellan.zRotation,
00495                                   -0.0001f * event->data.magellan.xRotation,
00496                                   -0.0001f * event->data.magellan.yRotation );
00497             _frameData.moveCamera(  0.0001f * event->data.magellan.xAxis,
00498                                    -0.0001f * event->data.magellan.zAxis,
00499                                     0.0001f * event->data.magellan.yAxis );
00500             _redraw = true;
00501             return true;
00502 
00503         case eq::Event::MAGELLAN_BUTTON:
00504             if( event->data.magellan.button == eq::PTR_BUTTON1 )
00505                 _frameData.toggleColorMode();
00506 
00507             _redraw = true;
00508             return true;
00509 
00510         case eq::Event::WINDOW_EXPOSE:
00511         case eq::Event::WINDOW_RESIZE:
00512         case eq::Event::WINDOW_CLOSE:
00513         case eq::Event::VIEW_RESIZE:
00514             _redraw = true;
00515             break;
00516 
00517         case ConfigEvent::IDLE_AA_LEFT:
00518             if( _useIdleAA )
00519             {
00520                 const ConfigEvent* idleEvent = 
00521                     static_cast< const ConfigEvent* >( event );
00522                 _numFramesAA = EQ_MAX( _numFramesAA, idleEvent->steps );
00523             }
00524             else
00525                 _numFramesAA = 0;
00526             return false;
00527 
00528         default:
00529             break;
00530     }
00531 
00532     _redraw |= eq::Config::handleEvent( event );
00533     return _redraw;
00534 }
00535 
00536 bool Config::_handleKeyEvent( const eq::KeyEvent& event )
00537 {
00538     switch( event.key )
00539     {
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             co::base::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             EQASSERT( 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     EQASSERT( 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     EQASSERT( !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 " + co::base::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::_adjustTileSize( const int delta )
00925 {
00926     View* view = _getCurrentView();
00927     if( !view )
00928         return;
00929 
00930     eq::Vector2i tileSize = view->getTileSize();
00931     if( tileSize == eq::Vector2i( -1, -1 ) )
00932         tileSize = eq::Vector2i( 64, 64 );
00933     tileSize += delta;
00934     view->setTileSize( tileSize );
00935 }
00936 
00937 void Config::_switchLayout( int32_t increment )
00938 {
00939     if( !_currentCanvas )
00940         return;
00941 
00942     _frameData.setCurrentViewID( eq::UUID::ZERO );
00943 
00944     int64_t index = _currentCanvas->getActiveLayoutIndex() + increment;
00945     const eq::Layouts& layouts = _currentCanvas->getLayouts();
00946     EQASSERT( !layouts.empty( ));
00947 
00948     index = ( index % layouts.size( ));
00949     _currentCanvas->useLayout( uint32_t( index ));
00950 
00951     const eq::Layout* layout = layouts[index];
00952     std::ostringstream stream;
00953     stream << "Layout ";
00954     if( layout )
00955     {
00956         const std::string& name = layout->getName();
00957         if( name.empty( ))
00958             stream << index;
00959         else
00960             stream << name;
00961     }
00962     else
00963         stream << "NONE";
00964 
00965     stream << " active";
00966     _setMessage( stream.str( ));
00967 }
00968 
00969 void Config::_toggleEqualizer()
00970 {
00971     View* view = _getCurrentView();
00972     if ( view )
00973         view->toggleEqualizer();
00974 }
00975 
00976 // Note: real applications would use one tracking device per observer
00977 void Config::_setHeadMatrix( const eq::Matrix4f& matrix )
00978 {
00979     const eq::Observers& observers = getObservers();
00980     for( eq::ObserversCIter i = observers.begin(); i != observers.end(); ++i )
00981     {
00982         (*i)->setHeadMatrix( matrix );
00983     }
00984 
00985     eq::Vector3f trans;
00986     matrix.get_translation( trans );
00987     std::ostringstream stream;
00988     stream << "Observer at " << trans;
00989     _setMessage( stream.str( ));
00990 }
00991 
00992 const eq::Matrix4f& Config::_getHeadMatrix() const
00993 {
00994     const eq::Observers& observers = getObservers();
00995     if( observers.empty( ))
00996         return eq::Matrix4f::IDENTITY;
00997 
00998     return observers[0]->getHeadMatrix();
00999 }
01000 
01001 void Config::_changeFocusDistance( const float delta )
01002 {
01003     const eq::Observers& observers = getObservers();
01004     for( eq::ObserversCIter i = observers.begin(); i != observers.end(); ++i )
01005     {
01006         eq::Observer* observer = *i;
01007         observer->setFocusDistance( observer->getFocusDistance() + delta );
01008         std::ostringstream stream;
01009         stream << "Set focus distance to " << observer->getFocusDistance();
01010         _setMessage( stream.str( ));
01011     }
01012 }
01013 
01014 void Config::_setFocusMode( const eq::FocusMode mode )
01015 {
01016     const eq::Observers& observers = getObservers();
01017     for( eq::ObserversCIter i = observers.begin(); i != observers.end(); ++i )
01018         (*i)->setFocusMode( mode );
01019 
01020     std::ostringstream stream;
01021     stream << "Set focus mode to " << mode;
01022     _setMessage( stream.str( ));
01023 }
01024 
01025 void Config::_setMessage( const std::string& message )
01026 {
01027     _frameData.setMessage( message );
01028     _messageTime = getTime();
01029 }
01030 
01031 eq::admin::ServerPtr Config::_getAdminServer()
01032 {
01033     // Debug: _closeAdminServer();
01034     if( _admin.isValid() && _admin->isConnected( ))
01035         return _admin;
01036 
01037     eq::admin::init( 0, 0 );
01038     eq::admin::ClientPtr client = new eq::admin::Client;
01039     if( !client->initLocal( 0, 0 ))
01040     {
01041         _setMessage( "Can't init admin client" );
01042         eq::admin::exit();
01043     }
01044 
01045     _admin = new eq::admin::Server;
01046     if( !client->connectServer( _admin ))
01047     {
01048         _setMessage( "Can't open connection to administrate server" );
01049         client->exitLocal();
01050         _admin = 0;
01051         eq::admin::exit();
01052     }
01053     return _admin;
01054 }
01055 
01056 void Config::_closeAdminServer()
01057 {
01058     if( !_admin )
01059         return;
01060 
01061     eq::admin::ClientPtr client = _admin->getClient();
01062     client->disconnectServer( _admin );
01063     client->exitLocal();
01064     EQASSERT( client->getRefCount() == 1 );
01065     EQASSERT( _admin->getRefCount() == 1 );
01066     
01067     _admin = 0;
01068     eq::admin::exit();
01069 }
01070 
01071 View* Config::_getCurrentView()
01072 {
01073     const eq::uint128_t& viewID = _frameData.getCurrentViewID();
01074     eq::View* view = find< eq::View >( viewID );
01075     return static_cast< View* >( view );
01076 }
01077 
01078 const View* Config::_getCurrentView() const
01079 {
01080     const eq::uint128_t& viewID = _frameData.getCurrentViewID();
01081     const eq::View* view = find< eq::View >( viewID );
01082     return static_cast< const View* >( view );
01083 }
01084 
01085 }
Generated on Fri Jun 8 2012 15:44:29 for Equalizer 1.2.1 by  doxygen 1.8.0