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