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