Equalizer  1.2.1
osgScaleViewer/config.cpp
00001 
00002 /*
00003  * Copyright (c)
00004  *   2008-2009, Thomas McGuire <thomas.mcguire@student.uni-siegen.de>
00005  *   2010, Stefan Eilemann <eile@equalizergraphics.com>
00006  *   2010, Sarah Amsellem <sarah.amsellem@gmail.com>
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *
00011  * - Redistributions of source code must retain the above copyright notice, this
00012  *   list of conditions and the following disclaimer.
00013  * - Redistributions in binary form must reproduce the above copyright notice,
00014  *   this list of conditions and the following disclaimer in the documentation
00015  *   and/or other materials provided with the distribution.
00016  * - Neither the name of Eyescale Software GmbH nor the names of its
00017  *   contributors may be used to endorse or promote products derived from this
00018  *   software without specific prior written permission.
00019  *
00020  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00021  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00022  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00023  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00024  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00025  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00026  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00027  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00028  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00029  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00030  * POSSIBILITY OF SUCH DAMAGE.
00031  */
00032 
00033 #include "config.h"
00034 
00035 #include "util.h"
00036 #include "sceneReader.h"
00037 
00038 #include <osg/Math>
00039 
00040 namespace osgScaleViewer
00041 {
00042 static const float maxVerticalAngle = osg::PI;
00043 static const float minVerticalAngle = 0.2f;
00044 static const float mouseViewSpeed = 0.005f;
00045 static const float defaultCameraHorizontalAngle( 0.0f );
00046 static const float defaultCameraVerticalAngle( osg::PI / 2.0f );
00047 static const eq::Vector3f defaultCameraViewingDirection( 0., 0., -1. );
00048 
00049 Config::Config( eq::ServerPtr parent )
00050     : eq::Config( parent )
00051     , _moveDirection( 0.0f, 0.0f, 0.0f )
00052     , _cameraWalkingVector( 0., 0., -1. )
00053     , _pointerXDiff( 0.0f )
00054     , _pointerYDiff( 0.0f )
00055     , _cameraAngleHor( defaultCameraHorizontalAngle )
00056     , _cameraAngleVer( defaultCameraVerticalAngle )
00057 {
00058 }
00059 
00060 bool Config::init()
00061 {
00062     // init tracker
00063     std::string trackerPort = _initData.getTrackerPort();
00064     if( !trackerPort.empty( ))
00065     {
00066         if( !_tracker.init( trackerPort ))
00067             EQWARN << "Failed to initialize tracker" << std::endl;
00068         else
00069         {
00070             // Set up position of tracking system wrt world space
00071             // Note: this depends on the physical installation.
00072             eq::Matrix4f matrix( eq::Matrix4f::IDENTITY );
00073             matrix.scale( 1.f, 1.f, -1.f );
00074             _tracker.setWorldToEmitter( matrix );
00075 
00076             matrix = eq::Matrix4f::IDENTITY;
00077             matrix.rotate_z( -M_PI_2 );
00078             _tracker.setSensorToObject( matrix );
00079             EQINFO << "Tracker initialized" << std::endl;
00080         }
00081     }
00082 
00083     registerObject( &_frameData );
00084     _initData.setFrameDataID( _frameData.getID( ));
00085     registerObject( &_initData );
00086 
00087     return eq::Config::init( _initData.getID( ));
00088 }
00089 
00090 bool Config::exit()
00091 {
00092     bool ret = eq::Config::exit();
00093     
00094     _initData.setFrameDataID( eq::UUID::ZERO );
00095     deregisterObject( &_initData );
00096     deregisterObject( &_frameData );
00097     return ret;
00098 }
00099 
00100 void Config::updateFrameData( float elapsed )
00101 {
00102     // Update the viewing direction based on the mouse movement
00103     _cameraAngleHor += mouseViewSpeed * _pointerXDiff;
00104     if( _cameraAngleHor > 2 * osg::PI || _cameraAngleHor < -2 * osg::PI )
00105         _cameraAngleHor = 0.0f;
00106     _cameraAngleVer += mouseViewSpeed * _pointerYDiff;
00107     if( _cameraAngleVer > maxVerticalAngle )
00108         _cameraAngleVer = maxVerticalAngle;
00109     if( _cameraAngleVer < minVerticalAngle )
00110         _cameraAngleVer = minVerticalAngle;
00111     _pointerXDiff = _pointerYDiff = 0.0f;
00112 
00113     eq::Vector3f cameraViewingDirection;
00114     cameraViewingDirection.x() = sin( _cameraAngleHor ) * sin( _cameraAngleVer );
00115     cameraViewingDirection.z() = -cos( _cameraAngleHor ) * sin( _cameraAngleVer );
00116     cameraViewingDirection.y() = cos( _cameraAngleVer );
00117     _cameraWalkingVector = cameraViewingDirection;
00118     _cameraWalkingVector.y() = 0.0f;
00119 
00120     // save camera data to frame data and update the camera position
00121     _frameData.setCameraPosition( _frameData.getCameraPosition() +
00122                                   _moveDirection * elapsed );
00123     _frameData.setCameraLookAtPoint( _frameData.getCameraPosition() +
00124                      cameraViewingDirection );
00125     _frameData.setCameraUpVector( eq::Vector3f( 0., 1., 0. ));
00126 }
00127 
00128 uint32_t Config::startFrame()
00129 {
00130     // update head position
00131     if( _tracker.isRunning( ))
00132     {
00133         _tracker.update();
00134         const eq::Matrix4f& headMatrix = _tracker.getMatrix();
00135         _setHeadMatrix( headMatrix );
00136     }
00137 
00138     float elapsed = _clock.getTimef();
00139     _clock.reset();
00140     updateFrameData( elapsed );
00141 
00142     const eq::uint128_t version = _frameData.commit();
00143     return eq::Config::startFrame( version );   
00144 }
00145 
00146 void Config::setInitData( const InitData& data )
00147 {
00148     _initData = data;
00149 }
00150 
00151 const InitData& Config::getInitData() const
00152 {
00153     return _initData;
00154 }
00155 
00156 bool Config::mapData( const eq::uint128_t& initDataID )
00157 {
00158     if( !_initData.isAttached( ))
00159     {
00160         EQCHECK( mapObject( &_initData, initDataID ) );
00161         unmapObject( &_initData );
00162     }
00163     else
00164     {
00165         EQASSERT( _initData.getID() == initDataID );
00166     }
00167     return true;
00168 }
00169 
00170 bool Config::handleEvent( const eq::ConfigEvent* event )
00171 {
00172     const float moveSpeed = .1f;
00173 
00174     switch( event->data.type )
00175     {
00176         // set mMoveDirection to a null vector after a key is released
00177         // so that the updating of the camera position stops
00178         case eq::Event::KEY_RELEASE:
00179             if ( event->data.keyPress.key >= 261 &&
00180                  event->data.keyPress.key <= 266 )
00181                 _moveDirection = eq::Vector3f( 0, 0, 0 );
00182         break;
00183 
00184         // change mMoveDirection when the appropriate key is pressed
00185         case eq::Event::KEY_PRESS:
00186             switch ( event->data.keyPress.key )
00187             {
00188                 case eq::KC_LEFT:
00189                     _moveDirection = vmml::normalize( orthographicVector(
00190                                      _cameraWalkingVector )) * moveSpeed;
00191                     return true;
00192 
00193                 case eq::KC_UP:
00194                     _moveDirection.y() = moveSpeed;
00195                     return true;
00196 
00197                 case eq::KC_RIGHT:
00198                     _moveDirection = -vmml::normalize( orthographicVector(
00199                                      _cameraWalkingVector )) * moveSpeed;
00200                     return true;
00201 
00202                 case eq::KC_DOWN:
00203                     _moveDirection.y() = -moveSpeed;
00204                     return true;
00205 
00206                 case eq::KC_PAGE_UP:
00207                     _moveDirection = vmml::normalize( _cameraWalkingVector )
00208                                      * moveSpeed;
00209                     return true;
00210 
00211                 case eq::KC_PAGE_DOWN:
00212                     _moveDirection = -vmml::normalize( _cameraWalkingVector ) *
00213                                       moveSpeed;
00214                     return true;
00215 
00216                 case 's':
00217                     _frameData.toggleStatistics();
00218             }
00219             break;
00220 
00221         // turn left and right, up and down with mouse pointer
00222         case eq::Event::CHANNEL_POINTER_MOTION:
00223             if ( event->data.pointerMotion.buttons == eq::PTR_BUTTON1 &&
00224                  event->data.pointerMotion.x <= event->data.context.pvp.w &&
00225                  event->data.pointerMotion.x >= 0 &&
00226                  event->data.pointerMotion.y <= event->data.context.pvp.h &&
00227                  event->data.pointerMotion.y >= 0 )
00228             {
00229                 _pointerXDiff += event->data.pointerMotion.dx;
00230                 _pointerYDiff += event->data.pointerMotion.dy;
00231                 return true;
00232             }
00233             break;
00234     }
00235 
00236     // let Equalizer handle any events we don't handle ourselves here, like the
00237     // escape key for closing the application.
00238     return eq::Config::handleEvent( event );
00239 }
00240 
00241 // Note: real applications would use one tracking device per observer
00242 void Config::_setHeadMatrix( const eq::Matrix4f& matrix )
00243 {
00244     const eq::Observers& observers = getObservers();
00245     for( eq::Observers::const_iterator i = observers.begin();
00246          i != observers.end(); ++i )
00247     {
00248         (*i)->setHeadMatrix( matrix );
00249     }
00250 }
00251 
00252 const eq::Matrix4f& Config::_getHeadMatrix() const
00253 {
00254     const eq::Observers& observers = getObservers();
00255     if( observers.empty( ))
00256         return eq::Matrix4f::IDENTITY;
00257 
00258     return observers[0]->getHeadMatrix();
00259 }
00260 }
Generated on Fri Jun 8 2012 15:44:29 for Equalizer 1.2.1 by  doxygen 1.8.0