Equalizer
1.2.1
|
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 }