Equalizer 1.0
|
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( co::base::RefPtr< eq::Server > parent ) 00043 : eq::Config( parent ) 00044 , _spinX( 5 ) 00045 , _spinY( 5 ) 00046 , _advance( 0 ) 00047 , _currentCanvas( 0 ) 00048 , _messageTime( 0 ) 00049 , _redraw( true ) 00050 , _freeze( false ) 00051 , _useIdleAA( true ) 00052 , _numFramesAA( 0 ) 00053 { 00054 } 00055 00056 Config::~Config() 00057 { 00058 for( Models::const_iterator i = _models.begin(); 00059 i != _models.end(); ++i ) 00060 { 00061 delete *i; 00062 } 00063 _models.clear(); 00064 00065 for( ModelDists::const_iterator i = _modelDist.begin(); 00066 i != _modelDist.end(); ++i ) 00067 { 00068 EQASSERT( !(*i)->isAttached() ); 00069 delete *i; 00070 } 00071 _modelDist.clear(); 00072 } 00073 00074 bool Config::init() 00075 { 00076 if( !_animation.isValid( )) 00077 _animation.loadAnimation( _initData.getPathFilename( )); 00078 00079 // init distributed objects 00080 if( !_initData.useColor( )) 00081 _frameData.setColorMode( COLOR_WHITE ); 00082 00083 _frameData.setRenderMode( _initData.getRenderMode( )); 00084 registerObject( &_frameData ); 00085 _frameData.setAutoObsolete( getLatency( )); 00086 00087 _initData.setFrameDataID( _frameData.getID( )); 00088 registerObject( &_initData ); 00089 00090 // init config 00091 if( !eq::Config::init( _initData.getID( ))) 00092 { 00093 _deregisterData(); 00094 return false; 00095 } 00096 00097 _loadModels(); 00098 _registerModels(); 00099 00100 // init tracker 00101 if( !_initData.getTrackerPort().empty( )) 00102 { 00103 if( !_tracker.init( _initData.getTrackerPort() )) 00104 EQWARN << "Failed to initialize tracker" << std::endl; 00105 else 00106 { 00107 // Set up position of tracking system wrt world space 00108 // Note: this depends on the physical installation. 00109 eq::Matrix4f m( eq::Matrix4f::IDENTITY ); 00110 m.scale( 1.f, 1.f, -1.f ); 00111 _tracker.setWorldToEmitter( m ); 00112 00113 m = eq::Matrix4f::IDENTITY; 00114 m.rotate_z( -M_PI_2 ); 00115 _tracker.setSensorToObject( m ); 00116 EQINFO << "Tracker initialized" << std::endl; 00117 } 00118 } 00119 00120 const eq::Canvases& canvases = getCanvases(); 00121 if( canvases.empty( )) 00122 _currentCanvas = 0; 00123 else 00124 _currentCanvas = canvases.front(); 00125 00126 _setMessage( "Welcome to eqPly\nPress F1 for help" ); 00127 return true; 00128 } 00129 00130 bool Config::exit() 00131 { 00132 const bool ret = eq::Config::exit(); 00133 _deregisterData(); 00134 _closeAdminServer(); 00135 00136 // retain models and distributors for possible other config runs, destructor 00137 // deletes it 00138 return ret; 00139 } 00140 00141 namespace 00142 { 00143 static bool _isPlyfile( const std::string& filename ) 00144 { 00145 const size_t size = filename.length(); 00146 if( size < 5 ) 00147 return false; 00148 00149 if( filename[size-4] != '.' || filename[size-3] != 'p' || 00150 filename[size-2] != 'l' || filename[size-1] != 'y' ) 00151 { 00152 return false; 00153 } 00154 return true; 00155 } 00156 } 00157 00158 void Config::_loadModels() 00159 { 00160 if( !_models.empty( )) // only load on the first config run 00161 return; 00162 00163 eq::Strings filenames = _initData.getFilenames(); 00164 while( !filenames.empty( )) 00165 { 00166 const std::string filename = filenames.back(); 00167 filenames.pop_back(); 00168 00169 if( _isPlyfile( filename )) 00170 { 00171 Model* model = new Model; 00172 00173 if( _initData.useInvertedFaces() ) 00174 model->useInvertedFaces(); 00175 00176 if( !model->readFromFile( filename.c_str() ) ) 00177 { 00178 EQWARN << "Can't load model: " << filename << std::endl; 00179 delete model; 00180 } 00181 else 00182 _models.push_back( model ); 00183 } 00184 else 00185 { 00186 const std::string basename = co::base::getFilename( filename ); 00187 if( basename == "." || basename == ".." ) 00188 continue; 00189 00190 // recursively search directories 00191 const eq::Strings subFiles = co::base::searchDirectory( filename, 00192 "*" ); 00193 00194 for( eq::Strings::const_iterator i = subFiles.begin(); 00195 i != subFiles.end(); ++i ) 00196 { 00197 filenames.push_back( filename + '/' + *i ); 00198 } 00199 } 00200 } 00201 } 00202 00203 void Config::_registerModels() 00204 { 00205 // Register distribution helpers on each config run 00206 const bool createDist = _modelDist.empty(); //first run, create distributors 00207 const size_t nModels = _models.size(); 00208 EQASSERT( createDist || _modelDist.size() == nModels ); 00209 00210 for( size_t i = 0; i < nModels; ++i ) 00211 { 00212 const Model* model = _models[i]; 00213 ModelDist* modelDist = 0; 00214 if( createDist ) 00215 { 00216 modelDist = new ModelDist( model ); 00217 _modelDist.push_back( modelDist ); 00218 } 00219 else 00220 modelDist = _modelDist[i]; 00221 00222 modelDist->registerTree( getClient( )); 00223 EQASSERT( modelDist->isAttached() ); 00224 00225 _frameData.setModelID( modelDist->getID( )); 00226 } 00227 00228 EQASSERT( _modelDist.size() == nModels ); 00229 00230 if( !_modelDist.empty( )) 00231 { 00232 ModelAssigner assigner( _modelDist ); 00233 accept( assigner ); 00234 } 00235 } 00236 00237 void Config::_deregisterData() 00238 { 00239 for( ModelDists::const_iterator i = _modelDist.begin(); 00240 i != _modelDist.end(); ++i ) 00241 { 00242 ModelDist* modelDist = *i; 00243 if( !modelDist->isAttached() ) // already done 00244 continue; 00245 00246 EQASSERT( modelDist->isMaster( )); 00247 modelDist->deregisterTree(); 00248 } 00249 00250 deregisterObject( &_initData ); 00251 deregisterObject( &_frameData ); 00252 00253 _initData.setFrameDataID( eq::UUID::ZERO ); 00254 _frameData.setModelID( eq::UUID::ZERO ); 00255 } 00256 00257 bool Config::mapData( const eq::uint128_t& initDataID ) 00258 { 00259 if( !_initData.isAttached( )) 00260 { 00261 const uint32_t request = mapObjectNB( &_initData, initDataID, 00262 co::VERSION_OLDEST, 00263 getApplicationNode( )); 00264 if( !mapObjectSync( request )) 00265 return false; 00266 unmapObject( &_initData ); // data was retrieved, unmap immediately 00267 } 00268 else // appNode, _initData is registered already 00269 { 00270 EQASSERT( _initData.getID() == initDataID ); 00271 } 00272 return true; 00273 } 00274 00275 void Config::unmapData() 00276 { 00277 for( ModelDists::const_iterator i = _modelDist.begin(); 00278 i != _modelDist.end(); ++i ) 00279 { 00280 ModelDist* modelDist = *i; 00281 if( !modelDist->isAttached( )) // already done 00282 continue; 00283 00284 if( !modelDist->isMaster( )) // leave registered on appNode 00285 modelDist->unmapTree(); 00286 } 00287 } 00288 00289 const Model* Config::getModel( const eq::uint128_t& modelID ) 00290 { 00291 if( modelID == eq::UUID::ZERO ) 00292 return 0; 00293 00294 // Accessed concurrently from pipe threads 00295 co::base::ScopedMutex<> _mutex( _modelLock ); 00296 00297 const size_t nModels = _models.size(); 00298 EQASSERT( _modelDist.size() == nModels ); 00299 00300 for( size_t i = 0; i < nModels; ++i ) 00301 { 00302 const ModelDist* dist = _modelDist[ i ]; 00303 if( dist->getID() == modelID ) 00304 return _models[ i ]; 00305 } 00306 00307 _modelDist.push_back( new ModelDist ); 00308 Model* model = _modelDist.back()->mapModel( getClient(), modelID ); 00309 EQASSERT( model ); 00310 _models.push_back( model ); 00311 00312 return model; 00313 } 00314 00315 uint32_t Config::startFrame() 00316 { 00317 _updateData(); 00318 const co::base::uint128_t& version = _frameData.commit(); 00319 00320 _redraw = false; 00321 return eq::Config::startFrame( version ); 00322 } 00323 00324 void Config::_updateData() 00325 { 00326 // update head position 00327 if( _tracker.isRunning() ) 00328 { 00329 _tracker.update(); 00330 const eq::Matrix4f& headMatrix = _tracker.getMatrix(); 00331 _setHeadMatrix( headMatrix ); 00332 } 00333 00334 // update database 00335 if( _animation.isValid( )) 00336 { 00337 const eq::Vector3f& modelRotation = _animation.getModelRotation(); 00338 const CameraAnimation::Step& curStep = _animation.getNextStep(); 00339 00340 _frameData.setModelRotation( modelRotation); 00341 _frameData.setRotation( curStep.rotation ); 00342 _frameData.setCameraPosition( curStep.position ); 00343 } 00344 else 00345 { 00346 if( _frameData.usePilotMode()) 00347 _frameData.spinCamera( -0.001f * _spinX, -0.001f * _spinY ); 00348 else 00349 _frameData.spinModel( -0.001f * _spinX, -0.001f * _spinY ); 00350 00351 _frameData.moveCamera( 0.0f, 0.0f, 0.001f*_advance ); 00352 } 00353 00354 // idle mode 00355 if( isIdleAA( )) 00356 { 00357 EQASSERT( _numFramesAA > 0 ); 00358 _frameData.setIdle( true ); 00359 } 00360 else 00361 _frameData.setIdle( false ); 00362 00363 _numFramesAA = 0; 00364 } 00365 00366 bool Config::isIdleAA() 00367 { 00368 return ( !isUserEvent() && _numFramesAA > 0 ); 00369 } 00370 00371 bool Config::needsRedraw() 00372 { 00373 return( isUserEvent() || _numFramesAA > 0 ); 00374 } 00375 00376 bool Config::isUserEvent() 00377 { 00378 if( _messageTime > 0 ) 00379 { 00380 if( getTime() - _messageTime > 2000 ) // reset message after two seconds 00381 { 00382 _messageTime = 0; 00383 _frameData.setMessage( "" ); 00384 } 00385 return true; 00386 } 00387 00388 return ( _spinX != 0 || _spinY != 0 || _advance != 0 || 00389 _tracker.isRunning() || _redraw ); 00390 } 00391 00392 bool Config::handleEvent( const eq::ConfigEvent* event ) 00393 { 00394 switch( event->data.type ) 00395 { 00396 case eq::Event::KEY_PRESS: 00397 if( _handleKeyEvent( event->data.keyPress )) 00398 { 00399 _redraw = true; 00400 return true; 00401 } 00402 break; 00403 00404 case eq::Event::CHANNEL_POINTER_BUTTON_PRESS: 00405 { 00406 const eq::uint128_t& viewID = 00407 event->data.context.view.identifier; 00408 _frameData.setCurrentViewID( viewID ); 00409 if( viewID == eq::UUID::ZERO ) 00410 { 00411 _currentCanvas = 0; 00412 return true; 00413 } 00414 00415 const eq::View* view = find< eq::View > ( viewID ); 00416 const eq::Layout* layout = view->getLayout(); 00417 const eq::Canvases& canvases = getCanvases(); 00418 for( eq::Canvases::const_iterator i = canvases.begin(); 00419 i != canvases.end(); ++i ) 00420 { 00421 eq::Canvas* canvas = *i; 00422 const eq::Layout* canvasLayout = canvas->getActiveLayout(); 00423 00424 if( canvasLayout == layout ) 00425 { 00426 _currentCanvas = canvas; 00427 return true; 00428 } 00429 } 00430 return true; 00431 } 00432 00433 case eq::Event::CHANNEL_POINTER_BUTTON_RELEASE: 00434 { 00435 const eq::PointerEvent& releaseEvent = 00436 event->data.pointerButtonRelease; 00437 if( releaseEvent.buttons == eq::PTR_BUTTON_NONE) 00438 { 00439 if( releaseEvent.button == eq::PTR_BUTTON1 ) 00440 { 00441 _spinX = releaseEvent.dy; 00442 _spinY = releaseEvent.dx; 00443 _redraw = true; 00444 return true; 00445 } 00446 if( releaseEvent.button == eq::PTR_BUTTON2 ) 00447 { 00448 _advance = -releaseEvent.dy; 00449 _redraw = true; 00450 return true; 00451 } 00452 } 00453 break; 00454 } 00455 case eq::Event::CHANNEL_POINTER_MOTION: 00456 if( event->data.pointerMotion.buttons == eq::PTR_BUTTON_NONE ) 00457 return true; 00458 00459 if( event->data.pointerMotion.buttons == eq::PTR_BUTTON1 ) 00460 { 00461 _spinX = 0; 00462 _spinY = 0; 00463 00464 if( _frameData.usePilotMode()) 00465 _frameData.spinCamera(-0.005f*event->data.pointerMotion.dy, 00466 -0.005f*event->data.pointerMotion.dx); 00467 else 00468 _frameData.spinModel( -0.005f*event->data.pointerMotion.dy, 00469 -0.005f*event->data.pointerMotion.dx); 00470 00471 _redraw = true; 00472 } 00473 else if( event->data.pointerMotion.buttons == eq::PTR_BUTTON2 ) 00474 { 00475 _advance = -event->data.pointerMotion.dy; 00476 _frameData.moveCamera( 0.f, 0.f, .005f * _advance ); 00477 _redraw = true; 00478 } 00479 else if( event->data.pointerMotion.buttons == eq::PTR_BUTTON3 ) 00480 { 00481 _frameData.moveCamera( .0005f * event->data.pointerMotion.dx, 00482 -.0005f * event->data.pointerMotion.dy, 00483 0.f ); 00484 _redraw = true; 00485 } 00486 return true; 00487 00488 case eq::Event::WINDOW_POINTER_WHEEL: 00489 _frameData.moveCamera( -0.05f * event->data.pointerWheel.yAxis, 00490 0.f, 00491 0.05f * event->data.pointerWheel.xAxis ); 00492 _redraw = true; 00493 return true; 00494 00495 case eq::Event::MAGELLAN_AXIS: 00496 _spinX = 0; 00497 _spinY = 0; 00498 _advance = 0; 00499 _frameData.spinModel( 0.0001f * event->data.magellan.zRotation, 00500 -0.0001f * event->data.magellan.xRotation, 00501 -0.0001f * event->data.magellan.yRotation ); 00502 _frameData.moveCamera( 0.0001f * event->data.magellan.xAxis, 00503 -0.0001f * event->data.magellan.zAxis, 00504 0.0001f * event->data.magellan.yAxis ); 00505 _redraw = true; 00506 return true; 00507 00508 case eq::Event::MAGELLAN_BUTTON: 00509 if( event->data.magellan.button == eq::PTR_BUTTON1 ) 00510 _frameData.toggleColorMode(); 00511 00512 _redraw = true; 00513 return true; 00514 00515 case eq::Event::WINDOW_EXPOSE: 00516 case eq::Event::WINDOW_RESIZE: 00517 case eq::Event::WINDOW_CLOSE: 00518 case eq::Event::VIEW_RESIZE: 00519 _redraw = true; 00520 break; 00521 00522 case ConfigEvent::IDLE_AA_LEFT: 00523 if( _useIdleAA ) 00524 { 00525 const ConfigEvent* idleEvent = 00526 static_cast< const ConfigEvent* >( event ); 00527 _numFramesAA = EQ_MAX( _numFramesAA, idleEvent->steps ); 00528 } 00529 else 00530 _numFramesAA = 0; 00531 return true; 00532 00533 default: 00534 break; 00535 } 00536 00537 _redraw |= eq::Config::handleEvent( event ); 00538 return _redraw; 00539 } 00540 00541 bool Config::_handleKeyEvent( const eq::KeyEvent& event ) 00542 { 00543 switch( event.key ) 00544 { 00545 case 'n': 00546 case 'N': 00547 _frameData.togglePilotMode(); 00548 return true; 00549 case ' ': 00550 stopFrames(); 00551 _spinX = 0; 00552 _spinY = 0; 00553 _advance = 0; 00554 _frameData.reset(); 00555 _setHeadMatrix( eq::Matrix4f::IDENTITY ); 00556 return true; 00557 00558 case 'i': 00559 _useIdleAA = !_useIdleAA; 00560 return true; 00561 00562 case 'k': 00563 { 00564 co::base::RNG rng; 00565 if( rng.get< bool >( )) 00566 _frameData.toggleOrtho(); 00567 if( rng.get< bool >( )) 00568 _frameData.toggleStatistics(); 00569 if( rng.get< bool >( )) 00570 _switchCanvas(); 00571 if( rng.get< bool >( )) 00572 _switchView(); 00573 if( rng.get< bool >( )) 00574 _switchLayout( 1 ); 00575 if( rng.get< bool >( )) 00576 _switchModel(); 00577 if( rng.get< bool >( )) 00578 eqAdmin::addWindow( _getAdminServer(), rng.get< bool >( )); 00579 if( rng.get< bool >( )) 00580 { 00581 eqAdmin::removeWindow( _getAdminServer( )); 00582 _currentCanvas = 0; 00583 } 00584 if( rng.get< bool >( )) 00585 _switchViewMode(); 00586 return true; 00587 } 00588 00589 case 'o': 00590 case 'O': 00591 _frameData.toggleOrtho(); 00592 return true; 00593 00594 case 's': 00595 case 'S': 00596 _frameData.toggleStatistics(); 00597 return true; 00598 00599 case 'f': 00600 case 'F': 00601 _freeze = !_freeze; 00602 freezeLoadBalancing( _freeze ); 00603 return true; 00604 00605 case eq::KC_F1: 00606 case 'h': 00607 case 'H': 00608 _frameData.toggleHelp(); 00609 return true; 00610 00611 case 'd': 00612 case 'D': 00613 _frameData.toggleColorMode(); 00614 return true; 00615 00616 case 'q': 00617 _frameData.adjustQuality( -.1f ); 00618 return true; 00619 00620 case 'Q': 00621 _frameData.adjustQuality( .1f ); 00622 return true; 00623 00624 case 'c': 00625 case 'C': 00626 _switchCanvas(); 00627 return true; 00628 00629 case 'v': 00630 case 'V': 00631 _switchView(); 00632 return true; 00633 00634 case 'm': 00635 case 'M': 00636 _switchModel(); 00637 return true; 00638 00639 case 'l': 00640 _switchLayout( 1 ); 00641 return true; 00642 case 'L': 00643 _switchLayout( -1 ); 00644 return true; 00645 00646 case 'w': 00647 case 'W': 00648 _frameData.toggleWireframe(); 00649 return true; 00650 00651 case 'r': 00652 case 'R': 00653 _frameData.toggleRenderMode(); 00654 return true; 00655 case 'g': 00656 case 'G': 00657 _switchViewMode(); 00658 return true; 00659 case 'a': 00660 eqAdmin::addWindow( _getAdminServer(), false /* active stereo */ ); 00661 return true; 00662 case 'p': 00663 eqAdmin::addWindow( _getAdminServer(), true /* passive stereo */ ); 00664 return true; 00665 case 'x': 00666 eqAdmin::removeWindow( _getAdminServer( )); 00667 _currentCanvas = 0; 00668 EQASSERT( update() ); 00669 return false; 00670 00671 // Head Tracking Emulation 00672 case eq::KC_UP: 00673 { 00674 eq::Matrix4f headMatrix = _getHeadMatrix(); 00675 headMatrix.y() += 0.1f; 00676 _setHeadMatrix( headMatrix ); 00677 return true; 00678 } 00679 case eq::KC_DOWN: 00680 { 00681 eq::Matrix4f headMatrix = _getHeadMatrix(); 00682 headMatrix.y() -= 0.1f; 00683 _setHeadMatrix( headMatrix ); 00684 return true; 00685 } 00686 case eq::KC_RIGHT: 00687 { 00688 eq::Matrix4f headMatrix = _getHeadMatrix(); 00689 headMatrix.x() += 0.1f; 00690 _setHeadMatrix( headMatrix ); 00691 return true; 00692 } 00693 case eq::KC_LEFT: 00694 { 00695 eq::Matrix4f headMatrix = _getHeadMatrix(); 00696 headMatrix.x() -= 0.1f; 00697 _setHeadMatrix( headMatrix ); 00698 return true; 00699 } 00700 case eq::KC_PAGE_DOWN: 00701 { 00702 eq::Matrix4f headMatrix = _getHeadMatrix(); 00703 headMatrix.z() += 0.1f; 00704 _setHeadMatrix( headMatrix ); 00705 return true; 00706 } 00707 case eq::KC_PAGE_UP: 00708 { 00709 eq::Matrix4f headMatrix = _getHeadMatrix(); 00710 headMatrix.z() -= 0.1f; 00711 _setHeadMatrix( headMatrix ); 00712 return true; 00713 } 00714 case '.': 00715 { 00716 eq::Matrix4f headMatrix = _getHeadMatrix(); 00717 headMatrix.pre_rotate_x( .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_y( .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_z( -.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 00757 default: 00758 return false; 00759 } 00760 } 00761 00762 co::uint128_t Config::sync( const co::uint128_t& version ) 00763 { 00764 if( _admin.isValid() && _admin->isConnected( )) 00765 _admin->syncConfig( getID(), version ); 00766 00767 return eq::Config::sync( version ); 00768 } 00769 00770 void Config::_switchCanvas() 00771 { 00772 const eq::Canvases& canvases = getCanvases(); 00773 if( canvases.empty( )) 00774 return; 00775 00776 _frameData.setCurrentViewID( eq::UUID::ZERO ); 00777 00778 if( !_currentCanvas ) 00779 { 00780 _currentCanvas = canvases.front(); 00781 return; 00782 } 00783 00784 eq::Canvases::const_iterator i = stde::find( canvases, _currentCanvas ); 00785 EQASSERT( i != canvases.end( )); 00786 00787 ++i; 00788 if( i == canvases.end( )) 00789 _currentCanvas = canvases.front(); 00790 else 00791 _currentCanvas = *i; 00792 _switchView(); // activate first view on canvas 00793 } 00794 00795 void Config::_switchView() 00796 { 00797 const eq::Canvases& canvases = getCanvases(); 00798 if( !_currentCanvas && !canvases.empty( )) 00799 _currentCanvas = canvases.front(); 00800 00801 if( !_currentCanvas ) 00802 return; 00803 00804 const eq::Layout* layout = _currentCanvas->getActiveLayout(); 00805 if( !layout ) 00806 return; 00807 00808 const eq::View* current = find< eq::View >( _frameData.getCurrentViewID( )); 00809 const eq::Views& views = layout->getViews(); 00810 EQASSERT( !views.empty( )); 00811 00812 if( !current ) 00813 { 00814 _frameData.setCurrentViewID( views.front()->getID( )); 00815 return; 00816 } 00817 00818 eq::Views::const_iterator i = std::find( views.begin(), views.end(), 00819 current ); 00820 if( i != views.end( )) 00821 ++i; 00822 if( i == views.end( )) 00823 _frameData.setCurrentViewID( eq::UUID::ZERO ); 00824 else 00825 _frameData.setCurrentViewID( (*i)->getID( )); 00826 } 00827 00828 void Config::_switchModel() 00829 { 00830 if( _modelDist.empty( )) // no models 00831 return; 00832 00833 // current model of current view 00834 const eq::uint128_t& viewID = _frameData.getCurrentViewID(); 00835 View* view = static_cast< View* >( find< eq::View >( viewID )); 00836 const eq::uint128_t& currentID = view ? 00837 view->getModelID() : _frameData.getModelID(); 00838 00839 // next model 00840 ModelDists::const_iterator i; 00841 for( i = _modelDist.begin(); i != _modelDist.end(); ++i ) 00842 { 00843 if( (*i)->getID() != currentID ) 00844 continue; 00845 00846 ++i; 00847 break; 00848 } 00849 if( i == _modelDist.end( )) 00850 i = _modelDist.begin(); // wrap around 00851 00852 // set identifier on view or frame data (default model) 00853 const eq::uint128_t& modelID = (*i)->getID(); 00854 if( view ) 00855 view->setModelID( modelID ); 00856 else 00857 _frameData.setModelID( modelID ); 00858 00859 if( view ) 00860 { 00861 const Model* model = getModel( modelID ); 00862 _setMessage( "Using " + co::base::getFilename( model->getName( ))); 00863 } 00864 } 00865 00866 void Config::_switchViewMode() 00867 { 00868 eq::View* current = find< eq::View >( _frameData.getCurrentViewID( )); 00869 if( !current ) 00870 return; 00871 00872 const eq::View::Mode mode = current->getMode( ); 00873 00874 if( mode == eq::View::MODE_MONO ) 00875 { 00876 current->changeMode( eq::View::MODE_STEREO ); 00877 _setMessage( "Switched to stereoscopic rendering" ); 00878 } 00879 else 00880 { 00881 current->changeMode( eq::View::MODE_MONO ); 00882 _setMessage( "Switched to monoscopic rendering" ); 00883 } 00884 } 00885 00886 void Config::_switchLayout( int32_t increment ) 00887 { 00888 if( !_currentCanvas ) 00889 return; 00890 00891 _frameData.setCurrentViewID( eq::UUID::ZERO ); 00892 00893 int64_t index = _currentCanvas->getActiveLayoutIndex() + increment; 00894 const eq::Layouts& layouts = _currentCanvas->getLayouts(); 00895 EQASSERT( !layouts.empty( )); 00896 00897 index = ( index % layouts.size( )); 00898 _currentCanvas->useLayout( uint32_t( index )); 00899 00900 const eq::Layout* layout = _currentCanvas->getLayouts()[index]; 00901 std::ostringstream stream; 00902 stream << "Layout "; 00903 if( layout ) 00904 { 00905 const std::string& name = layout->getName(); 00906 if( name.empty( )) 00907 stream << index; 00908 else 00909 stream << name; 00910 } 00911 else 00912 stream << "NONE"; 00913 00914 stream << " active"; 00915 _setMessage( stream.str( )); 00916 } 00917 00918 // Note: real applications would use one tracking device per observer 00919 void Config::_setHeadMatrix( const eq::Matrix4f& matrix ) 00920 { 00921 const eq::Observers& observers = getObservers(); 00922 for( eq::Observers::const_iterator i = observers.begin(); 00923 i != observers.end(); ++i ) 00924 { 00925 (*i)->setHeadMatrix( matrix ); 00926 } 00927 } 00928 00929 const eq::Matrix4f& Config::_getHeadMatrix() const 00930 { 00931 const eq::Observers& observers = getObservers(); 00932 if( observers.empty( )) 00933 return eq::Matrix4f::IDENTITY; 00934 00935 return observers[0]->getHeadMatrix(); 00936 } 00937 00938 void Config::_setMessage( const std::string& message ) 00939 { 00940 _frameData.setMessage( message ); 00941 _messageTime = getTime(); 00942 } 00943 00944 eq::admin::ServerPtr Config::_getAdminServer() 00945 { 00946 // Debug: _closeAdminServer(); 00947 if( _admin.isValid() && _admin->isConnected( )) 00948 return _admin; 00949 00950 eq::admin::init( 0, 0 ); 00951 eq::admin::ClientPtr client = new eq::admin::Client; 00952 if( !client->initLocal( 0, 0 )) 00953 { 00954 _setMessage( "Can't init admin client" ); 00955 eq::admin::exit(); 00956 } 00957 00958 _admin = new eq::admin::Server; 00959 if( !client->connectServer( _admin )) 00960 { 00961 _setMessage( "Can't open connection to administrate server" ); 00962 client->exitLocal(); 00963 _admin = 0; 00964 eq::admin::exit(); 00965 } 00966 return _admin; 00967 } 00968 00969 void Config::_closeAdminServer() 00970 { 00971 if( !_admin ) 00972 return; 00973 00974 eq::admin::ClientPtr client = _admin->getClient(); 00975 client->disconnectServer( _admin ); 00976 client->exitLocal(); 00977 EQASSERT( client->getRefCount() == 1 ); 00978 EQASSERT( _admin->getRefCount() == 1 ); 00979 00980 _admin = 0; 00981 eq::admin::exit(); 00982 } 00983 00984 }