diff --git a/src/osgGA/FlightManipulator.cpp b/src/osgGA/FlightManipulator.cpp index c9df462e4..d2dbaf420 100644 --- a/src/osgGA/FlightManipulator.cpp +++ b/src/osgGA/FlightManipulator.cpp @@ -20,93 +20,94 @@ using namespace osgGA; /// Constructor. FlightManipulator::FlightManipulator( int flags ) - : inherited( flags ), - _yawMode( YAW_AUTOMATICALLY_WHEN_BANKED ) + : inherited( flags ), + _yawMode( YAW_AUTOMATICALLY_WHEN_BANKED ) { } /// Constructor. FlightManipulator::FlightManipulator( const FlightManipulator& fm, const CopyOp& copyOp ) - : inherited( fm, copyOp ), - _yawMode( fm._yawMode ) + : inherited( fm, copyOp ), + _yawMode( fm._yawMode ) { } void FlightManipulator::init( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - inherited::init( ea, us ); + inherited::init( ea, us ); - // center mouse pointer - centerMousePointer( ea, us ); + // center mouse pointer + centerMousePointer( ea, us ); } void FlightManipulator::home( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - inherited::home( ea, us ); + inherited::home( ea, us ); - // center mouse pointer - centerMousePointer( ea, us ); + // center mouse pointer + centerMousePointer( ea, us ); } // doc in parent bool FlightManipulator::handleFrame( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - addMouseEvent( ea ); - if( performMovement() ) - us.requestRedraw(); + addMouseEvent( ea ); + if( performMovement() ) + us.requestRedraw(); - return false; + return false; } // doc in parent bool FlightManipulator::handleMouseMove( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - return flightHandleEvent( ea, us ); + return flightHandleEvent( ea, us ); } // doc in parent bool FlightManipulator::handleMouseDrag( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - return flightHandleEvent( ea, us ); + return flightHandleEvent( ea, us ); } // doc in parent bool FlightManipulator::handleMousePush( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - return flightHandleEvent( ea, us ); + return flightHandleEvent( ea, us ); } // doc in parent bool FlightManipulator::handleMouseRelease( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - return flightHandleEvent( ea, us ); + return flightHandleEvent( ea, us ); } bool FlightManipulator::handleKeyDown( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - if( inherited::handleKeyDown( ea, us ) ) - return true; + if( inherited::handleKeyDown( ea, us ) ) + return true; - if( ea.getKey() == 'q' ) { + if( ea.getKey() == 'q' ) + { - _yawMode = YAW_AUTOMATICALLY_WHEN_BANKED; - return true; + _yawMode = YAW_AUTOMATICALLY_WHEN_BANKED; + return true; - } - else if (ea.getKey()=='a') { - - _yawMode = NO_AUTOMATIC_YAW; - return true; + } + else if (ea.getKey()=='a') + { + _yawMode = NO_AUTOMATIC_YAW; + return true; } return false; @@ -115,27 +116,27 @@ bool FlightManipulator::handleKeyDown( const GUIEventAdapter& ea, GUIActionAdapt bool FlightManipulator::flightHandleEvent( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - addMouseEvent( ea ); - us.requestContinuousUpdate( true ); - if( performMovement() ) - us.requestRedraw(); + addMouseEvent( ea ); + us.requestContinuousUpdate( true ); + if( performMovement() ) + us.requestRedraw(); - return true; + return true; } void FlightManipulator::getUsage( ApplicationUsage& usage ) const { - inherited::getUsage( usage ); - usage.addKeyboardMouseBinding( getManipulatorName() + ": q", "Automatically yaw when banked (default)" ); - usage.addKeyboardMouseBinding( getManipulatorName() + ": a", "No yaw when banked" ); + inherited::getUsage( usage ); + usage.addKeyboardMouseBinding( getManipulatorName() + ": q", "Automatically yaw when banked (default)" ); + usage.addKeyboardMouseBinding( getManipulatorName() + ": a", "No yaw when banked" ); } /** Configure the Yaw control for the flight model. */ void FlightManipulator::setYawControlMode( YawControlMode ycm ) { - _yawMode = ycm; + _yawMode = ycm; } @@ -221,21 +222,21 @@ bool FlightManipulator::performMovement() bool FlightManipulator::performMovementLeftMouseButton( const double dt, const double dx, const double dy ) { - // pan model - _velocity += dt * (_acceleration + _velocity); - return true; + // pan model + _velocity += dt * (_acceleration + _velocity); + return true; } bool FlightManipulator::performMovementMiddleMouseButton( const double dt, const double dx, const double dy ) { - _velocity = 0.0f; - return true; + _velocity = 0.0f; + return true; } bool FlightManipulator::performMovementRightMouseButton( const double dt, const double dx, const double dy ) { - _velocity -= dt * (_acceleration + _velocity); - return true; + _velocity -= dt * (_acceleration + _velocity); + return true; } diff --git a/src/osgGA/OrbitManipulator.cpp b/src/osgGA/OrbitManipulator.cpp index f7fcd8bac..c8e42996a 100644 --- a/src/osgGA/OrbitManipulator.cpp +++ b/src/osgGA/OrbitManipulator.cpp @@ -29,10 +29,10 @@ OrbitManipulator::OrbitManipulator( int flags ) _distance( 1. ), _trackballSize( 0.8 ) { - setMinimumDistance( 0.05, true ); - setWheelZoomFactor( 0.1 ); - if( _flags & SET_CENTER_ON_WHEEL_UP ) - setAnimationTime( 0.2 ); + setMinimumDistance( 0.05, true ); + setWheelZoomFactor( 0.1 ); + if( _flags & SET_CENTER_ON_WHEEL_UP ) + setAnimationTime( 0.2 ); } @@ -52,28 +52,28 @@ OrbitManipulator::OrbitManipulator( const OrbitManipulator& om, const CopyOp& co /** Set the position of the manipulator using a 4x4 matrix.*/ void OrbitManipulator::setByMatrix( const osg::Matrixd& matrix ) { - _center = osg::Vec3d( 0., 0., -_distance ) * matrix; - _rotation = matrix.getRotate(); + _center = osg::Vec3d( 0., 0., -_distance ) * matrix; + _rotation = matrix.getRotate(); - // fix current rotation - if( getVerticalAxisFixed() ) - fixVerticalAxis( _center, _rotation, true ); + // fix current rotation + if( getVerticalAxisFixed() ) + fixVerticalAxis( _center, _rotation, true ); } /** Set the position of the manipulator using a 4x4 matrix.*/ void OrbitManipulator::setByInverseMatrix( const osg::Matrixd& matrix ) { - setByMatrix( osg::Matrixd::inverse( matrix ) ); + setByMatrix( osg::Matrixd::inverse( matrix ) ); } /** Get the position of the manipulator as 4x4 matrix.*/ osg::Matrixd OrbitManipulator::getMatrix() const { - return osg::Matrixd::translate( 0., 0., _distance ) * - osg::Matrixd::rotate( _rotation ) * - osg::Matrixd::translate( _center ); + return osg::Matrixd::translate( 0., 0., _distance ) * + osg::Matrixd::rotate( _rotation ) * + osg::Matrixd::translate( _center ); } @@ -81,109 +81,111 @@ osg::Matrixd OrbitManipulator::getMatrix() const typically used as a model view matrix.*/ osg::Matrixd OrbitManipulator::getInverseMatrix() const { - return osg::Matrixd::translate( -_center ) * - osg::Matrixd::rotate( _rotation.inverse() ) * - osg::Matrixd::translate( 0.0, 0.0, -_distance ); + return osg::Matrixd::translate( -_center ) * + osg::Matrixd::rotate( _rotation.inverse() ) * + osg::Matrixd::translate( 0.0, 0.0, -_distance ); } // doc in parent void OrbitManipulator::setTransformation( const osg::Vec3d& eye, const osg::Quat& rotation ) { - _center = eye + rotation * osg::Vec3d( 0., 0., -_distance ); - _rotation = rotation; + _center = eye + rotation * osg::Vec3d( 0., 0., -_distance ); + _rotation = rotation; - // fix current rotation - if( getVerticalAxisFixed() ) - fixVerticalAxis( _center, _rotation, true ); + // fix current rotation + if( getVerticalAxisFixed() ) + fixVerticalAxis( _center, _rotation, true ); } // doc in parent void OrbitManipulator::getTransformation( osg::Vec3d& eye, osg::Quat& rotation ) const { - eye = _center - _rotation * osg::Vec3d( 0., 0., -_distance ); - rotation = _rotation; + eye = _center - _rotation * osg::Vec3d( 0., 0., -_distance ); + rotation = _rotation; } // doc in parent void OrbitManipulator::setTransformation( const osg::Vec3d& center, const osg::Vec3d& eye, const osg::Vec3d& up ) { - Vec3d lv( center - eye ); + Vec3d lv( center - eye ); - Vec3d f( lv ); - f.normalize(); - Vec3d s( f^up ); - s.normalize(); - Vec3d u( s^f ); - u.normalize(); + Vec3d f( lv ); + f.normalize(); + Vec3d s( f^up ); + s.normalize(); + Vec3d u( s^f ); + u.normalize(); - osg::Matrixd rotation_matrix( s[0], u[0], -f[0], 0.0f, - s[1], u[1], -f[1], 0.0f, - s[2], u[2], -f[2], 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f ); + osg::Matrixd rotation_matrix( s[0], u[0], -f[0], 0.0f, + s[1], u[1], -f[1], 0.0f, + s[2], u[2], -f[2], 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f ); - _center = center; - _distance = lv.length(); - _rotation = rotation_matrix.getRotate().inverse(); + _center = center; + _distance = lv.length(); + _rotation = rotation_matrix.getRotate().inverse(); - // fix current rotation - if( getVerticalAxisFixed() ) - fixVerticalAxis( _center, _rotation, true ); + // fix current rotation + if( getVerticalAxisFixed() ) + fixVerticalAxis( _center, _rotation, true ); } // doc in parent void OrbitManipulator::getTransformation( osg::Vec3d& center, osg::Vec3d& eye, osg::Vec3d& up ) const { - center = _center; - eye = _center + _rotation * osg::Vec3d( 0., 0., _distance ); - up = _rotation * osg::Vec3d( 0., 1., 0. ); + center = _center; + eye = _center + _rotation * osg::Vec3d( 0., 0., _distance ); + up = _rotation * osg::Vec3d( 0., 1., 0. ); } // doc in parent bool OrbitManipulator::handleMouseWheel( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - switch( ea.getScrollingMotion() ) { + switch( ea.getScrollingMotion() ) + { + // mouse scroll up event + case GUIEventAdapter::SCROLL_UP: + { - // mouse scroll up event - case GUIEventAdapter::SCROLL_UP: { + if( _flags & SET_CENTER_ON_WHEEL_UP ) + { - if( _flags & SET_CENTER_ON_WHEEL_UP ) { - - if( getAnimationTime() <= 0. ) - - // center by mouse intersection (no animation) - setCenterByMousePointerIntersection( ea, us ); - - else { - - // start new animation only if there is no animation in progress - if( !isAnimating() ) - startAnimationByMousePointerIntersection( ea, us ); + if( getAnimationTime() <= 0. ) + { + // center by mouse intersection (no animation) + setCenterByMousePointerIntersection( ea, us ); + } + else + { + // start new animation only if there is no animation in progress + if( !isAnimating() ) + startAnimationByMousePointerIntersection( ea, us ); + } } - } - // perform zoom - zoomModel( -_wheelZoomFactor, true ); - us.requestRedraw(); - us.requestContinuousUpdate( isAnimating() || _thrown ); - return true; - } + // perform zoom + zoomModel( -_wheelZoomFactor, true ); + us.requestRedraw(); + us.requestContinuousUpdate( isAnimating() || _thrown ); + return true; + } - // mouse scroll down event - case GUIEventAdapter::SCROLL_DOWN: - zoomModel( _wheelZoomFactor, true ); - us.requestRedraw(); - us.requestContinuousUpdate( false ); - return true; + // mouse scroll down event + case GUIEventAdapter::SCROLL_DOWN: + zoomModel( _wheelZoomFactor, true ); + us.requestRedraw(); + us.requestContinuousUpdate( false ); + return true; - // unhandled mouse scrolling motion - default: - return false; + // unhandled mouse scrolling motion + default: + return false; } } @@ -191,12 +193,12 @@ bool OrbitManipulator::handleMouseWheel( const GUIEventAdapter& ea, GUIActionAda // doc in parent bool OrbitManipulator::performMovementLeftMouseButton( const double dt, const double dx, const double dy ) { - // rotate camera - if( getVerticalAxisFixed() ) - rotateWithFixedVertical( dx, dy ); - else - rotateTrackball( _ga_t0->getXnormalized(), _ga_t0->getYnormalized(), - _ga_t1->getXnormalized(), _ga_t1->getYnormalized() ); + // rotate camera + if( getVerticalAxisFixed() ) + rotateWithFixedVertical( dx, dy ); + else + rotateTrackball( _ga_t0->getXnormalized(), _ga_t0->getYnormalized(), + _ga_t1->getXnormalized(), _ga_t1->getYnormalized() ); return true; } @@ -204,52 +206,52 @@ bool OrbitManipulator::performMovementLeftMouseButton( const double dt, const do // doc in parent bool OrbitManipulator::performMovementMiddleMouseButton( const double dt, const double dx, const double dy ) { - // pan model - float scale = -0.3f * _distance; - panModel( dx*scale, dy*scale ); - return true; + // pan model + float scale = -0.3f * _distance; + panModel( dx*scale, dy*scale ); + return true; } // doc in parent bool OrbitManipulator::performMovementRightMouseButton( const double dt, const double dx, const double dy ) { - // zoom model - zoomModel( dy, true ); - return true; + // zoom model + zoomModel( dy, true ); + return true; } bool OrbitManipulator::performMouseDeltaMovement( const float dx, const float dy ) { - // rotate camera - if( getVerticalAxisFixed() ) - rotateWithFixedVertical( dx, dy ); - else - rotateTrackball( 0.f, 0.f, dx, dy ); + // rotate camera + if( getVerticalAxisFixed() ) + rotateWithFixedVertical( dx, dy ); + else + rotateTrackball( 0.f, 0.f, dx, dy ); - return true; + return true; } void OrbitManipulator::applyAnimationStep( const double currentProgress, const double prevProgress ) { - OrbitAnimationData *ad = dynamic_cast< OrbitAnimationData* >( _animationData.get() ); - assert( ad ); + OrbitAnimationData *ad = dynamic_cast< OrbitAnimationData* >( _animationData.get() ); + assert( ad ); - // compute new center - osg::Vec3d prevCenter, prevEye, prevUp; - getTransformation( prevCenter, prevEye, prevUp ); - osg::Vec3d newCenter = osg::Vec3d(prevCenter) + (ad->_movement * (currentProgress - prevProgress)); + // compute new center + osg::Vec3d prevCenter, prevEye, prevUp; + getTransformation( prevCenter, prevEye, prevUp ); + osg::Vec3d newCenter = osg::Vec3d(prevCenter) + (ad->_movement * (currentProgress - prevProgress)); - // fix vertical axis - if( getVerticalAxisFixed() ) { + // fix vertical axis + if( getVerticalAxisFixed() ) + { - CoordinateFrame coordinateFrame = getCoordinateFrame( newCenter ); - Vec3d localUp = getUpVector( coordinateFrame ); - - fixVerticalAxis( newCenter - prevEye, prevUp, prevUp, localUp, false ); + CoordinateFrame coordinateFrame = getCoordinateFrame( newCenter ); + Vec3d localUp = getUpVector( coordinateFrame ); + fixVerticalAxis( newCenter - prevEye, prevUp, prevUp, localUp, false ); } // apply new transformation @@ -260,30 +262,30 @@ void OrbitManipulator::applyAnimationStep( const double currentProgress, const d bool OrbitManipulator::startAnimationByMousePointerIntersection( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us ) { - // get current transformation - osg::Vec3d prevCenter, prevEye, prevUp; - getTransformation( prevCenter, prevEye, prevUp ); + // get current transformation + osg::Vec3d prevCenter, prevEye, prevUp; + getTransformation( prevCenter, prevEye, prevUp ); - // center by mouse intersection - if( !setCenterByMousePointerIntersection( ea, us ) ) - return false; + // center by mouse intersection + if( !setCenterByMousePointerIntersection( ea, us ) ) + return false; - OrbitAnimationData *ad = dynamic_cast< OrbitAnimationData*>( _animationData.get() ); - assert( ad ); + OrbitAnimationData *ad = dynamic_cast< OrbitAnimationData*>( _animationData.get() ); + assert( ad ); - // setup animation data and restore original transformation - ad->start( osg::Vec3d(_center) - prevCenter, ea.getTime() ); - setTransformation( prevCenter, prevEye, prevUp ); + // setup animation data and restore original transformation + ad->start( osg::Vec3d(_center) - prevCenter, ea.getTime() ); + setTransformation( prevCenter, prevEye, prevUp ); - return true; + return true; } void OrbitManipulator::OrbitAnimationData::start( const osg::Vec3d& movement, const double startTime ) { - AnimationData::start( startTime ); + AnimationData::start( startTime ); - _movement = movement; + _movement = movement; } @@ -291,15 +293,15 @@ void OrbitManipulator::OrbitAnimationData::start( const osg::Vec3d& movement, co by mouse pointer on the screen.*/ void OrbitManipulator::rotateTrackball( const float px0, const float py0, const float px1, const float py1 ) { - osg::Vec3d axis; - float angle; + osg::Vec3d axis; + float angle; - trackball( axis, angle, px1, py1, px0, py0 ); + trackball( axis, angle, px1, py1, px0, py0 ); - Quat new_rotate; - new_rotate.makeRotate( angle, axis ); + Quat new_rotate; + new_rotate.makeRotate( angle, axis ); - _rotation = _rotation * new_rotate; + _rotation = _rotation * new_rotate; } @@ -307,10 +309,10 @@ void OrbitManipulator::rotateTrackball( const float px0, const float py0, const while keeping UP vector.*/ void OrbitManipulator::rotateWithFixedVertical( const float dx, const float dy ) { - CoordinateFrame coordinateFrame = getCoordinateFrame( _center ); - Vec3d localUp = getUpVector( coordinateFrame ); + CoordinateFrame coordinateFrame = getCoordinateFrame( _center ); + Vec3d localUp = getUpVector( coordinateFrame ); - rotateYawPitch( _rotation, dx, dy, localUp ); + rotateYawPitch( _rotation, dx, dy, localUp ); } @@ -318,19 +320,19 @@ void OrbitManipulator::rotateWithFixedVertical( const float dx, const float dy ) while keeping UP vector given by up parameter.*/ void OrbitManipulator::rotateWithFixedVertical( const float dx, const float dy, const Vec3f& up ) { - rotateYawPitch( _rotation, dx, dy, up ); + rotateYawPitch( _rotation, dx, dy, up ); } /** Moves camera in x,y,z directions given in camera local coordinates.*/ void OrbitManipulator::panModel( const float dx, const float dy, const float dz ) { - Matrix rotation_matrix; - rotation_matrix.makeRotate( _rotation ); + Matrix rotation_matrix; + rotation_matrix.makeRotate( _rotation ); - Vec3d dv( dx, dy, dz ); + Vec3d dv( dx, dy, dz ); - _center += dv * rotation_matrix; + _center += dv * rotation_matrix; } @@ -342,42 +344,35 @@ void OrbitManipulator::panModel( const float dx, const float dy, const float dz */ void OrbitManipulator::zoomModel( const float dy, bool pushForwardIfNeeded ) { - // scale - float scale = 1.0f + dy; + // scale + float scale = 1.0f + dy; - // minimum distance - float minDist = _minimumDistance; - if( getRelativeFlag( _minimumDistanceFlagIndex ) ) - minDist *= _modelSize; + // minimum distance + float minDist = _minimumDistance; + if( getRelativeFlag( _minimumDistanceFlagIndex ) ) + minDist *= _modelSize; - if( _distance*scale > minDist ) - { - - // regular zoom - _distance *= scale; - - } - else - { - - if( pushForwardIfNeeded ) - { - - // push the camera forward - float scale = -_distance; - Matrixd rotation_matrix( _rotation ); - Vec3d dv = (Vec3d( 0.0f, 0.0f, -1.0f ) * rotation_matrix) * (dy * scale); - _center += dv; - - } - else - { - - // set distance on its minimum value - _distance = minDist; - - } - } + if( _distance*scale > minDist ) + { + // regular zoom + _distance *= scale; + } + else + { + if( pushForwardIfNeeded ) + { + // push the camera forward + float scale = -_distance; + Matrixd rotation_matrix( _rotation ); + Vec3d dv = (Vec3d( 0.0f, 0.0f, -1.0f ) * rotation_matrix) * (dy * scale); + _center += dv; + } + else + { + // set distance on its minimum value + _distance = minDist; + } + } } @@ -396,9 +391,9 @@ void OrbitManipulator::zoomModel( const float dy, bool pushForwardIfNeeded ) void OrbitManipulator::trackball( osg::Vec3d& axis, float& angle, float p1x, float p1y, float p2x, float p2y ) { /* - * First, figure out z-coordinates for projection of P1 and P2 to - * deformed sphere - */ + * First, figure out z-coordinates for projection of P1 and P2 to + * deformed sphere + */ osg::Matrixd rotation_matrix(_rotation); @@ -410,23 +405,22 @@ void OrbitManipulator::trackball( osg::Vec3d& axis, float& angle, float p1x, flo osg::Vec3d p2 = sv * p2x + uv * p2y - lv * tb_project_to_sphere(_trackballSize, p2x, p2y); /* - * Now, we want the cross product of P1 and P2 - */ + * Now, we want the cross product of P1 and P2 + */ axis = p2^p1; axis.normalize(); /* - * Figure out how much to rotate around that axis. - */ + * Figure out how much to rotate around that axis. + */ float t = (p2 - p1).length() / (2.0 * _trackballSize); /* - * Avoid problems with out-of-control values... - */ + * Avoid problems with out-of-control values... + */ if (t > 1.0) t = 1.0; if (t < -1.0) t = -1.0; angle = inRadians(asin(t)); - } @@ -456,70 +450,70 @@ float OrbitManipulator::tb_project_to_sphere( float r, float x, float y ) /** Get the FusionDistanceMode. Used by SceneView for setting up stereo convergence.*/ osgUtil::SceneView::FusionDistanceMode OrbitManipulator::getFusionDistanceMode() const { - return osgUtil::SceneView::USE_FUSION_DISTANCE_VALUE; + return osgUtil::SceneView::USE_FUSION_DISTANCE_VALUE; } /** Get the FusionDistanceValue. Used by SceneView for setting up stereo convergence.*/ float OrbitManipulator::getFusionDistanceValue() const { - return _distance; + return _distance; } /** Set the center of the manipulator. */ void OrbitManipulator::setCenter( const Vec3d& center ) { - _center = center; + _center = center; } /** Get the center of the manipulator. */ const Vec3d& OrbitManipulator::getCenter() const { - return _center; + return _center; } /** Set the rotation of the manipulator. */ void OrbitManipulator::setRotation( const Quat& rotation ) { - _rotation = rotation; + _rotation = rotation; } /** Get the rotation of the manipulator. */ const Quat& OrbitManipulator::getRotation() const { - return _rotation; + return _rotation; } /** Set the distance of camera to the center. */ void OrbitManipulator::setDistance( double distance ) { - _distance = distance; + _distance = distance; } /** Get the distance of the camera to the center. */ double OrbitManipulator::getDistance() const { - return _distance; + return _distance; } /** Set the size of the trackball. Value is relative to the model size. */ void OrbitManipulator::setTrackballSize( const double& size ) { - /* + /* * This size should really be based on the distance from the center of * rotation to the point on the object underneath the mouse. That * point would then track the mouse as closely as possible. This is a * simple example, though, so that is left as an Exercise for the * Programmer. */ - _trackballSize = size; - clampBetweenRange( _trackballSize, 0.1, 1.0, "TrackballManipulator::setTrackballSize(float)" ); + _trackballSize = size; + clampBetweenRange( _trackballSize, 0.1, 1.0, "TrackballManipulator::setTrackballSize(float)" ); } @@ -529,7 +523,7 @@ void OrbitManipulator::setTrackballSize( const double& size ) For example, value of 0.1 will short distance to center by 10% on each wheel up event.*/ void OrbitManipulator::setWheelZoomFactor( double wheelZoomFactor ) { - _wheelZoomFactor = wheelZoomFactor; + _wheelZoomFactor = wheelZoomFactor; } @@ -537,8 +531,8 @@ void OrbitManipulator::setWheelZoomFactor( double wheelZoomFactor ) before the center is pushed forward.*/ void OrbitManipulator::setMinimumDistance( const double& minimumDistance, bool relativeToModelSize ) { - _minimumDistance = minimumDistance; - setRelativeFlag( _minimumDistanceFlagIndex, relativeToModelSize ); + _minimumDistance = minimumDistance; + setRelativeFlag( _minimumDistanceFlagIndex, relativeToModelSize ); } @@ -546,8 +540,8 @@ void OrbitManipulator::setMinimumDistance( const double& minimumDistance, bool r before the center is pushed forward.*/ double OrbitManipulator::getMinimumDistance( bool *relativeToModelSize ) const { - if( relativeToModelSize ) - *relativeToModelSize = getRelativeFlag( _minimumDistanceFlagIndex ); + if( relativeToModelSize ) + *relativeToModelSize = getRelativeFlag( _minimumDistanceFlagIndex ); - return _minimumDistance; + return _minimumDistance; } diff --git a/src/osgGA/StandardManipulator.cpp b/src/osgGA/StandardManipulator.cpp index 919058ed9..e09465c81 100644 --- a/src/osgGA/StandardManipulator.cpp +++ b/src/osgGA/StandardManipulator.cpp @@ -39,20 +39,20 @@ int StandardManipulator::numRelativeFlagsAllocated = 0; int StandardManipulator::allocateRelativeFlag() { - return numRelativeFlagsAllocated++; + return numRelativeFlagsAllocated++; } /// Constructor. StandardManipulator::StandardManipulator( int flags ) - : inherited(), - _thrown( false ), - _mouseCenterX(0.0f), _mouseCenterY(0.0f), - _delta_frame_time(0.01), _last_frame_time(0.0), - _modelSize( 0. ), - _verticalAxisFixed( true ), - _flags( flags ), - _relativeFlags( 0 ) + : inherited(), + _thrown( false ), + _mouseCenterX(0.0f), _mouseCenterY(0.0f), + _delta_frame_time(0.01), _last_frame_time(0.0), + _modelSize( 0. ), + _verticalAxisFixed( true ), + _flags( flags ), + _relativeFlags( 0 ) { } @@ -79,32 +79,36 @@ StandardManipulator::StandardManipulator( const StandardManipulator& uim, const Is ignored by manipulators which do not require a reference model.*/ void StandardManipulator::setNode( Node* node ) { - _node = node; + _node = node; - // update model size - if( _node.get() ) { - const BoundingSphere& boundingSphere = _node->getBound(); - _modelSize = boundingSphere.radius(); - } else - _modelSize = 0.; + // update model size + if( _node.get() ) + { + const BoundingSphere& boundingSphere = _node->getBound(); + _modelSize = boundingSphere.radius(); + } + else + { + _modelSize = 0.; + } - // compute home position - if( getAutoComputeHomePosition() ) - computeHomePosition( NULL, ( _flags & COMPUTE_HOME_USING_BBOX ) != 0 ); + // compute home position + if( getAutoComputeHomePosition() ) + computeHomePosition( NULL, ( _flags & COMPUTE_HOME_USING_BBOX ) != 0 ); } /** Return node if attached.*/ const Node* StandardManipulator::getNode() const { - return _node.get(); + return _node.get(); } /** Return node if attached.*/ Node* StandardManipulator::getNode() { - return _node.get(); + return _node.get(); } @@ -115,52 +119,53 @@ Node* StandardManipulator::getNode() * To change up vector, use MatrixManipulator::setCoordinateFrameCallback.*/ void StandardManipulator::setVerticalAxisFixed( bool value ) { - _verticalAxisFixed = value; + _verticalAxisFixed = value; } /// Sets manipulator animation time when centering on mouse wheel up is enabled. void StandardManipulator::setAnimationTime( const double t ) { - if( t <= 0. ) { - finishAnimation(); - _animationData = NULL; - return; - } + if( t <= 0. ) + { + finishAnimation(); + _animationData = NULL; + return; + } - if( !_animationData ) - allocAnimationData(); + if( !_animationData ) + allocAnimationData(); - _animationData->_animationTime = t; + _animationData->_animationTime = t; } /// Returns manipulator animation time when centering on mouse wheel up is enabled. double StandardManipulator::getAnimationTime() const { - if( _animationData ) - return _animationData->_animationTime; - else - return 0.; + if( _animationData ) + return _animationData->_animationTime; + else + return 0.; } /// Returns whether manipulator is performing animation at the moment. bool StandardManipulator::isAnimating() const { - if( _animationData ) - return _animationData->_isAnimating; - else - return false; + if( _animationData ) + return _animationData->_isAnimating; + else + return false; } void StandardManipulator::finishAnimation() { - if( !isAnimating() ) - return; + if( !isAnimating() ) + return; - applyAnimationStep( 1., _animationData->_phase ); + applyAnimationStep( 1., _animationData->_phase ); } @@ -175,12 +180,12 @@ void StandardManipulator::finishAnimation() Descendant classes are expected to update camera position.*/ void StandardManipulator::home( double /*currentTime*/ ) { - if( getAutoComputeHomePosition() ) - computeHomePosition( NULL, ( _flags & COMPUTE_HOME_USING_BBOX ) != 0 ); + if( getAutoComputeHomePosition() ) + computeHomePosition( NULL, ( _flags & COMPUTE_HOME_USING_BBOX ) != 0 ); - _thrown = false; - setTransformation( _homeCenter, _homeEye, _homeUp ); - flushMouseEventStack(); + _thrown = false; + setTransformation( _homeCenter, _homeEye, _homeUp ); + flushMouseEventStack(); } @@ -195,78 +200,80 @@ void StandardManipulator::home( double /*currentTime*/ ) it has to reimplement the method to update manipulator transformation.*/ void StandardManipulator::home( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - if( getAutoComputeHomePosition() ) { - const Camera *camera = us.asView() ? us.asView()->getCamera() : NULL; - computeHomePosition( camera, ( _flags & COMPUTE_HOME_USING_BBOX ) != 0 ); - } + if( getAutoComputeHomePosition() ) + { + const Camera *camera = us.asView() ? us.asView()->getCamera() : NULL; + computeHomePosition( camera, ( _flags & COMPUTE_HOME_USING_BBOX ) != 0 ); + } - _thrown = false; - setTransformation( _homeCenter, _homeEye, _homeUp ); + _thrown = false; + setTransformation( _homeCenter, _homeEye, _homeUp ); - us.requestRedraw(); - us.requestContinuousUpdate( false ); - flushMouseEventStack(); + us.requestRedraw(); + us.requestContinuousUpdate( false ); + flushMouseEventStack(); } /** Start/restart the manipulator.*/ void StandardManipulator::init( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - flushMouseEventStack(); + flushMouseEventStack(); - // stop animation - _thrown = false; - us.requestContinuousUpdate(false); + // stop animation + _thrown = false; + us.requestContinuousUpdate(false); } /** Handles events. Returns true if handled, false otherwise.*/ bool StandardManipulator::handle( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - switch( ea.getEventType() ) { + switch( ea.getEventType() ) + { - case GUIEventAdapter::FRAME: - return handleFrame( ea, us ); + case GUIEventAdapter::FRAME: + return handleFrame( ea, us ); - case GUIEventAdapter::RESIZE: - return handleResize( ea, us ); + case GUIEventAdapter::RESIZE: + return handleResize( ea, us ); - default: - break; + default: + break; } - if( ea.getHandled() ) - return false; + if( ea.getHandled() ) + return false; - switch( ea.getEventType() ) { + switch( ea.getEventType() ) + { + case GUIEventAdapter::MOVE: + return handleMouseMove( ea, us ); - case GUIEventAdapter::MOVE: - return handleMouseMove( ea, us ); + case GUIEventAdapter::DRAG: + return handleMouseDrag( ea, us ); - case GUIEventAdapter::DRAG: - return handleMouseDrag( ea, us ); + case GUIEventAdapter::PUSH: + return handleMousePush( ea, us ); - case GUIEventAdapter::PUSH: - return handleMousePush( ea, us ); + case GUIEventAdapter::RELEASE: + return handleMouseRelease( ea, us ); - case GUIEventAdapter::RELEASE: - return handleMouseRelease( ea, us ); + case GUIEventAdapter::KEYDOWN: + return handleKeyDown( ea, us ); - case GUIEventAdapter::KEYDOWN: - return handleKeyDown( ea, us ); + case GUIEventAdapter::KEYUP: + return handleKeyUp( ea, us ); - case GUIEventAdapter::KEYUP: - return handleKeyUp( ea, us ); - - case GUIEventAdapter::SCROLL: - if( _flags & PROCESS_MOUSE_WHEEL ) + case GUIEventAdapter::SCROLL: + if( _flags & PROCESS_MOUSE_WHEEL ) return handleMouseWheel( ea, us ); - else + else return false; - default: - return false; - } + default: + return false; + } } @@ -294,161 +301,163 @@ bool StandardManipulator::handleFrame( const GUIEventAdapter& ea, GUIActionAdapt /// Handles GUIEventAdapter::RESIZE event. bool StandardManipulator::handleResize( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - init( ea, us ); - us.requestRedraw(); + init( ea, us ); + us.requestRedraw(); - return true; + return true; } /// Handles GUIEventAdapter::MOVE event. bool StandardManipulator::handleMouseMove( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - return false; + return false; } /// Handles GUIEventAdapter::DRAG event. bool StandardManipulator::handleMouseDrag( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - addMouseEvent( ea ); + addMouseEvent( ea ); - if( performMovement() ) - us.requestRedraw(); + if( performMovement() ) + us.requestRedraw(); - us.requestContinuousUpdate( false ); - _thrown = false; + us.requestContinuousUpdate( false ); + _thrown = false; - return true; + return true; } /// Handles GUIEventAdapter::PUSH event. bool StandardManipulator::handleMousePush( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - flushMouseEventStack(); - addMouseEvent( ea ); + flushMouseEventStack(); + addMouseEvent( ea ); - if( performMovement() ) - us.requestRedraw(); + if( performMovement() ) + us.requestRedraw(); - us.requestContinuousUpdate( false ); - _thrown = false; + us.requestContinuousUpdate( false ); + _thrown = false; - return true; + return true; } /// Handles GUIEventAdapter::RELEASE event. bool StandardManipulator::handleMouseRelease( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - if( ea.getButtonMask() == 0 ) { + if( ea.getButtonMask() == 0 ) + { - double timeSinceLastRecordEvent = _ga_t0.valid() ? (ea.getTime() - _ga_t0->getTime()) : DBL_MAX; - if( timeSinceLastRecordEvent > 0.02 ) - flushMouseEventStack(); + double timeSinceLastRecordEvent = _ga_t0.valid() ? (ea.getTime() - _ga_t0->getTime()) : DBL_MAX; + if( timeSinceLastRecordEvent > 0.02 ) + flushMouseEventStack(); - if( isMouseMoving() ) { + if( isMouseMoving() ) + { - if( performMovement() ) { + if( performMovement() ) + { + us.requestRedraw(); + us.requestContinuousUpdate( true ); + _thrown = true; + } - us.requestRedraw(); - us.requestContinuousUpdate( true ); - _thrown = true; + return true; + } + } - } + flushMouseEventStack(); + addMouseEvent( ea ); + if( performMovement() ) + us.requestRedraw(); + us.requestContinuousUpdate( false ); + _thrown = false; - return true; - } - } - - flushMouseEventStack(); - addMouseEvent( ea ); - if( performMovement() ) - us.requestRedraw(); - us.requestContinuousUpdate( false ); - _thrown = false; - - return true; + return true; } /// Handles GUIEventAdapter::KEYDOWN event. bool StandardManipulator::handleKeyDown( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - if( ea.getKey() == GUIEventAdapter::KEY_Space ) { + if( ea.getKey() == GUIEventAdapter::KEY_Space ) + { + flushMouseEventStack(); + _thrown = false; + home(ea,us); + return true; + } - flushMouseEventStack(); - _thrown = false; - home(ea,us); - return true; - } - - return false; + return false; } /// Handles GUIEventAdapter::KEYUP event. bool StandardManipulator::handleKeyUp( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - return false; + return false; } /// Handles GUIEventAdapter::SCROLL event. bool StandardManipulator::handleMouseWheel( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - return false; + return false; } /** Get the keyboard and mouse usage of the manipulator.*/ void StandardManipulator::getUsage( ApplicationUsage& usage ) const { - usage.addKeyboardMouseBinding( getManipulatorName() + ": Space", "Reset the viewing position to home" ); + usage.addKeyboardMouseBinding( getManipulatorName() + ": Space", "Reset the viewing position to home" ); } /// Make movement step of manipulator. Returns true if any movement was made. bool StandardManipulator::performMovement() { - // return if less then two events have been added - if( _ga_t0.get() == NULL || _ga_t1.get() == NULL ) - return false; + // return if less then two events have been added + if( _ga_t0.get() == NULL || _ga_t1.get() == NULL ) + return false; - // get delta time - double dt = _ga_t0->getTime() - _ga_t1->getTime(); - if( dt < 0. ) { - notify( INFO ) << "Manipulator warning: dt = " << dt << std::endl; - dt = 0.; - } + // get delta time + double dt = _ga_t0->getTime() - _ga_t1->getTime(); + if( dt < 0. ) + { + notify( INFO ) << "Manipulator warning: dt = " << dt << std::endl; + dt = 0.; + } - // get deltaX and deltaY - float dx = _ga_t0->getXnormalized() - _ga_t1->getXnormalized(); - float dy = _ga_t0->getYnormalized() - _ga_t1->getYnormalized(); + // get deltaX and deltaY + float dx = _ga_t0->getXnormalized() - _ga_t1->getXnormalized(); + float dy = _ga_t0->getYnormalized() - _ga_t1->getYnormalized(); - // return if there is no movement. - if( dx == 0. && dy == 0. ) - return false; + // return if there is no movement. + if( dx == 0. && dy == 0. ) + return false; - // call appropriate methods - unsigned int buttonMask = _ga_t1->getButtonMask(); - if( buttonMask == GUIEventAdapter::LEFT_MOUSE_BUTTON ) - - return performMovementLeftMouseButton( dt, dx, dy ); - - else if( buttonMask == GUIEventAdapter::MIDDLE_MOUSE_BUTTON || + // call appropriate methods + unsigned int buttonMask = _ga_t1->getButtonMask(); + if( buttonMask == GUIEventAdapter::LEFT_MOUSE_BUTTON ) + { + return performMovementLeftMouseButton( dt, dx, dy ); + } + else if( buttonMask == GUIEventAdapter::MIDDLE_MOUSE_BUTTON || buttonMask == (GUIEventAdapter::LEFT_MOUSE_BUTTON | GUIEventAdapter::RIGHT_MOUSE_BUTTON) ) + { + return performMovementMiddleMouseButton( dt, dx, dy ); + } + else if( buttonMask == GUIEventAdapter::RIGHT_MOUSE_BUTTON ) + { + return performMovementRightMouseButton( dt, dx, dy ); + } - return performMovementMiddleMouseButton( dt, dx, dy ); - - else if( buttonMask == GUIEventAdapter::RIGHT_MOUSE_BUTTON ) - - return performMovementRightMouseButton( dt, dx, dy ); - - - return false; + return false; } @@ -456,7 +465,7 @@ bool StandardManipulator::performMovement() This method implements movement for left mouse button.*/ bool StandardManipulator::performMovementLeftMouseButton( const double dt, const double dx, const double dy ) { - return false; + return false; } @@ -465,7 +474,7 @@ bool StandardManipulator::performMovementLeftMouseButton( const double dt, const or combination of left and right mouse button pressed together.*/ bool StandardManipulator::performMovementMiddleMouseButton( const double dt, const double dx, const double dy ) { - return false; + return false; } @@ -473,22 +482,22 @@ bool StandardManipulator::performMovementMiddleMouseButton( const double dt, con This method implements movement for right mouse button.*/ bool StandardManipulator::performMovementRightMouseButton( const double dt, const double dx, const double dy ) { - return false; + return false; } bool StandardManipulator::handleMouseDeltaMovement( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - float dx = ea.getX() - _mouseCenterX; - float dy = ea.getY() - _mouseCenterY; + float dx = ea.getX() - _mouseCenterX; + float dy = ea.getY() - _mouseCenterY; - if( dx == 0.f && dy == 0.f ) - return false; + if( dx == 0.f && dy == 0.f ) + return false; - addMouseEvent( ea ); - centerMousePointer( ea, us ); + addMouseEvent( ea ); + centerMousePointer( ea, us ); - return performMouseDeltaMovement( dx, dy ); + return performMouseDeltaMovement( dx, dy ); } @@ -500,20 +509,21 @@ bool StandardManipulator::performMouseDeltaMovement( const float dx, const float bool StandardManipulator::performAnimationMovement( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - double f = (ea.getTime() - _animationData->_startTime) / _animationData->_animationTime; - if( f >= 1. ) { - f = 1.; - _animationData->_isAnimating = false; - if( !_thrown ) - us.requestContinuousUpdate( false ); - } + double f = (ea.getTime() - _animationData->_startTime) / _animationData->_animationTime; + if( f >= 1. ) + { + f = 1.; + _animationData->_isAnimating = false; + if( !_thrown ) + us.requestContinuousUpdate( false ); + } - applyAnimationStep( f, _animationData->_phase ); + applyAnimationStep( f, _animationData->_phase ); - _animationData->_phase = f; - us.requestRedraw(); + _animationData->_phase = f; + us.requestRedraw(); - return _animationData->_isAnimating; + return _animationData->_isAnimating; } @@ -524,25 +534,25 @@ void StandardManipulator::applyAnimationStep( const double currentProgress, cons void StandardManipulator::centerMousePointer( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - _mouseCenterX = (ea.getXmin() + ea.getXmax()) / 2.0f; - _mouseCenterY = (ea.getYmin() + ea.getYmax()) / 2.0f; - us.requestWarpPointer( _mouseCenterX, _mouseCenterY ); + _mouseCenterX = (ea.getXmin() + ea.getXmax()) / 2.0f; + _mouseCenterY = (ea.getYmin() + ea.getYmax()) / 2.0f; + us.requestWarpPointer( _mouseCenterX, _mouseCenterY ); } /** Add the current mouse GUIEvent to internal stack.*/ void StandardManipulator::addMouseEvent( const GUIEventAdapter& ea ) { - _ga_t1 = _ga_t0; - _ga_t0 = &ea; + _ga_t1 = _ga_t0; + _ga_t0 = &ea; } /** Reset the internal GUIEvent stack.*/ void StandardManipulator::flushMouseEventStack() { - _ga_t1 = NULL; - _ga_t0 = NULL; + _ga_t1 = NULL; + _ga_t0 = NULL; } @@ -550,16 +560,16 @@ void StandardManipulator::flushMouseEventStack() If speed is below a threshold then return false, otherwise return true.*/ bool StandardManipulator::isMouseMoving() const { - if (_ga_t0.get()==NULL || _ga_t1.get()==NULL) return false; + if (_ga_t0.get()==NULL || _ga_t1.get()==NULL) return false; - static const float velocity = 0.1f; + static const float velocity = 0.1f; - float dx = _ga_t0->getXnormalized()-_ga_t1->getXnormalized(); - float dy = _ga_t0->getYnormalized()-_ga_t1->getYnormalized(); - float len = sqrtf(dx*dx+dy*dy); - float dt = _ga_t0->getTime()-_ga_t1->getTime(); + float dx = _ga_t0->getXnormalized()-_ga_t1->getXnormalized(); + float dy = _ga_t0->getYnormalized()-_ga_t1->getYnormalized(); + float len = sqrtf(dx*dx+dy*dy); + float dt = _ga_t0->getTime()-_ga_t1->getTime(); - return (len>dt*velocity); + return (len>dt*velocity); } @@ -571,48 +581,50 @@ bool StandardManipulator::isMouseMoving() const void StandardManipulator::rotateYawPitch( Quat& rotation, const double yaw, const double pitch, const Vec3d& localUp ) { - bool verticalAxisFixed = (localUp != Vec3d( 0.,0.,0. )); + bool verticalAxisFixed = (localUp != Vec3d( 0.,0.,0. )); - // fix current rotation - if( verticalAxisFixed ) - fixVerticalAxis( rotation, localUp, true ); + // fix current rotation + if( verticalAxisFixed ) + fixVerticalAxis( rotation, localUp, true ); - // rotations - Quat rotateYaw( -yaw, verticalAxisFixed ? localUp : rotation * Vec3d( 0.,1.,0. ) ); - Quat rotatePitch; - Quat newRotation; - Vec3d cameraRight( rotation * Vec3d( 1.,0.,0. ) ); + // rotations + Quat rotateYaw( -yaw, verticalAxisFixed ? localUp : rotation * Vec3d( 0.,1.,0. ) ); + Quat rotatePitch; + Quat newRotation; + Vec3d cameraRight( rotation * Vec3d( 1.,0.,0. ) ); - double my_dy = pitch; - int i = 0; + double my_dy = pitch; + int i = 0; - do { + do { - // rotations - rotatePitch.makeRotate( my_dy, cameraRight ); - newRotation = rotation * rotateYaw * rotatePitch; + // rotations + rotatePitch.makeRotate( my_dy, cameraRight ); + newRotation = rotation * rotateYaw * rotatePitch; - // update vertical axis - if( verticalAxisFixed ) - fixVerticalAxis( newRotation, localUp, false ); + // update vertical axis + if( verticalAxisFixed ) + fixVerticalAxis( newRotation, localUp, false ); - // check for viewer's up vector to be more than 90 degrees from "up" axis - Vec3d newCameraUp = newRotation * Vec3d( 0.,1.,0. ); - if( newCameraUp * localUp > 0. ) { + // check for viewer's up vector to be more than 90 degrees from "up" axis + Vec3d newCameraUp = newRotation * Vec3d( 0.,1.,0. ); + if( newCameraUp * localUp > 0. ) + { - // apply new rotation - rotation = newRotation; - return; + // apply new rotation + rotation = newRotation; + return; - } + } - my_dy /= 2.; - if( ++i == 20 ) { - rotation = rotation * rotateYaw; - return; - } + my_dy /= 2.; + if( ++i == 20 ) + { + rotation = rotation * rotateYaw; + return; + } - } while( true ); + } while( true ); } @@ -635,36 +647,37 @@ void StandardManipulator::fixVerticalAxis( Vec3d& eye, Quat& rotation, bool disa * making pitch once again between -90..+90 degrees limits.*/ void StandardManipulator::fixVerticalAxis( Quat& rotation, const Vec3d& localUp, bool disallowFlipOver ) { - // camera direction vectors - Vec3d cameraUp = rotation * Vec3d( 0.,1.,0. ); - Vec3d cameraRight = rotation * Vec3d( 1.,0.,0. ); - Vec3d cameraForward = rotation * Vec3d( 0.,0.,-1. ); + // camera direction vectors + Vec3d cameraUp = rotation * Vec3d( 0.,1.,0. ); + Vec3d cameraRight = rotation * Vec3d( 1.,0.,0. ); + Vec3d cameraForward = rotation * Vec3d( 0.,0.,-1. ); - // computed directions - Vec3d newCameraRight1 = cameraForward ^ localUp; - Vec3d newCameraRight2 = cameraUp ^ localUp; - Vec3d newCameraRight = (newCameraRight1.length2() > newCameraRight2.length2()) ? - newCameraRight1 : newCameraRight2; - if( newCameraRight * cameraRight < 0. ) - newCameraRight = -newCameraRight; + // computed directions + Vec3d newCameraRight1 = cameraForward ^ localUp; + Vec3d newCameraRight2 = cameraUp ^ localUp; + Vec3d newCameraRight = (newCameraRight1.length2() > newCameraRight2.length2()) ? + newCameraRight1 : newCameraRight2; + if( newCameraRight * cameraRight < 0. ) + newCameraRight = -newCameraRight; - assert( newCameraRight.length2() > 0. ); + assert( newCameraRight.length2() > 0. ); - // vertical axis correction - Quat rotationVerticalAxisCorrection; - rotationVerticalAxisCorrection.makeRotate( cameraRight, newCameraRight ); + // vertical axis correction + Quat rotationVerticalAxisCorrection; + rotationVerticalAxisCorrection.makeRotate( cameraRight, newCameraRight ); - // rotate camera - rotation *= rotationVerticalAxisCorrection; + // rotate camera + rotation *= rotationVerticalAxisCorrection; - if( disallowFlipOver ) { + if( disallowFlipOver ) + { - // make viewer's up vector to be always less than 90 degrees from "up" axis - Vec3d newCameraUp = newCameraRight ^ cameraForward; - if( newCameraUp * localUp < 0. ) - rotation = Quat( PI, Vec3d( 0.,0.,1. ) ) * rotation; + // make viewer's up vector to be always less than 90 degrees from "up" axis + Vec3d newCameraUp = newCameraRight ^ cameraForward; + if( newCameraUp * localUp < 0. ) + rotation = Quat( PI, Vec3d( 0.,0.,1. ) ) * rotation; - } + } } @@ -681,88 +694,89 @@ void StandardManipulator::fixVerticalAxis( Quat& rotation, const Vec3d& localUp, void StandardManipulator::fixVerticalAxis( const osg::Vec3d& forward, const osg::Vec3d& up, osg::Vec3d& newUp, const osg::Vec3d& localUp, bool disallowFlipOver ) { - // right direction - osg::Vec3d right1 = forward ^ localUp; - osg::Vec3d right2 = up ^ localUp; - osg::Vec3d right = (right1.length2() > right2.length2()) ? right1 : right2; + // right direction + osg::Vec3d right1 = forward ^ localUp; + osg::Vec3d right2 = up ^ localUp; + osg::Vec3d right = (right1.length2() > right2.length2()) ? right1 : right2; - // newUp - // note: do not use up and other parameters from now as they may point - // to the same variable as newUp parameter - newUp = right ^ forward; - assert( newUp.length2() > 0. ); - newUp.normalize(); + // newUp + // note: do not use up and other parameters from now as they may point + // to the same variable as newUp parameter + newUp = right ^ forward; + assert( newUp.length2() > 0. ); + newUp.normalize(); } bool StandardManipulator::setCenterByMousePointerIntersection( const GUIEventAdapter& ea, GUIActionAdapter& us ) { - osg::View* view = us.asView(); - if( !view ) - return false; + osg::View* view = us.asView(); + if( !view ) + return false; - Camera *camera = view->getCamera(); - if( !camera ) - return false; + Camera *camera = view->getCamera(); + if( !camera ) + return false; - // prepare variables - float x = ( ea.getX() - ea.getXmin() ) / ( ea.getXmax() - ea.getXmin() ); - float y = ( ea.getY() - ea.getYmin() ) / ( ea.getYmax() - ea.getYmin() ); - LineSegmentIntersector::CoordinateFrame cf; - Viewport *vp = camera->getViewport(); - if( vp ) { - cf = Intersector::WINDOW; - x *= vp->width(); - y *= vp->height(); - } else - cf = Intersector::PROJECTION; + // prepare variables + float x = ( ea.getX() - ea.getXmin() ) / ( ea.getXmax() - ea.getXmin() ); + float y = ( ea.getY() - ea.getYmin() ) / ( ea.getYmax() - ea.getYmin() ); + LineSegmentIntersector::CoordinateFrame cf; + Viewport *vp = camera->getViewport(); + if( vp ) { + cf = Intersector::WINDOW; + x *= vp->width(); + y *= vp->height(); + } else + cf = Intersector::PROJECTION; - // perform intersection computation - ref_ptr< LineSegmentIntersector > picker = new LineSegmentIntersector( cf, x, y ); - IntersectionVisitor iv( picker.get() ); - camera->accept( iv ); + // perform intersection computation + ref_ptr< LineSegmentIntersector > picker = new LineSegmentIntersector( cf, x, y ); + IntersectionVisitor iv( picker.get() ); + camera->accept( iv ); - // return on no intersections - if( !picker->containsIntersections() ) - return false; + // return on no intersections + if( !picker->containsIntersections() ) + return false; - // get all intersections - LineSegmentIntersector::Intersections& intersections = picker->getIntersections(); + // get all intersections + LineSegmentIntersector::Intersections& intersections = picker->getIntersections(); - // get current transformation - osg::Vec3d eye, oldCenter, up; - getTransformation( oldCenter, eye, up ); + // get current transformation + osg::Vec3d eye, oldCenter, up; + getTransformation( oldCenter, eye, up ); - // new center - osg::Vec3d newCenter = (*intersections.begin()).getWorldIntersectPoint(); + // new center + osg::Vec3d newCenter = (*intersections.begin()).getWorldIntersectPoint(); - // make vertical axis correction - if( getVerticalAxisFixed() ) { + // make vertical axis correction + if( getVerticalAxisFixed() ) + { - CoordinateFrame coordinateFrame = getCoordinateFrame( newCenter ); - Vec3d localUp = getUpVector( coordinateFrame ); + CoordinateFrame coordinateFrame = getCoordinateFrame( newCenter ); + Vec3d localUp = getUpVector( coordinateFrame ); - fixVerticalAxis( newCenter - eye, up, up, localUp, true ); + fixVerticalAxis( newCenter - eye, up, up, localUp, true ); - } + } - // set the new center - setTransformation( newCenter, eye, up ); + // set the new center + setTransformation( newCenter, eye, up ); - // warp pointer - // note: this works for me on standard camera on GraphicsWindowEmbedded and Qt, - // while it was necessary to implement requestWarpPointer like follows: - // - // void QOSGWidget::requestWarpPointer( float x, float y ) - // { - // osgViewer::Viewer::requestWarpPointer( x, y ); - // QCursor::setPos( this->mapToGlobal( QPoint( int( x+.5f ), int( y+.5f ) ) ) ); - // } - // - // Additions of .5f are just for the purpose of rounding. - centerMousePointer( ea, us ); + // warp pointer + // note: this works for me on standard camera on GraphicsWindowEmbedded and Qt, + // while it was necessary to implement requestWarpPointer like follows: + // + // void QOSGWidget::requestWarpPointer( float x, float y ) + // { + // osgViewer::Viewer::requestWarpPointer( x, y ); + // QCursor::setPos( this->mapToGlobal( QPoint( int( x+.5f ), int( y+.5f ) ) ) ); + // } + // + // Additions of .5f are just for the purpose of rounding. + centerMousePointer( ea, us ); - return true; + return true; } @@ -774,19 +788,19 @@ bool StandardManipulator::setCenterByMousePointerIntersection( const GUIEventAda bool StandardManipulator::startAnimationByMousePointerIntersection( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us ) { - return false; + return false; } StandardManipulator::AnimationData::AnimationData() - :_isAnimating( false ) + :_isAnimating( false ) { } void StandardManipulator::AnimationData::start( const double startTime ) { - _isAnimating = true; - _startTime = startTime; - _phase = 0.; + _isAnimating = true; + _startTime = startTime; + _phase = 0.; } diff --git a/src/osgGA/TerrainManipulator.cpp b/src/osgGA/TerrainManipulator.cpp index c569a5f06..eb730af12 100644 --- a/src/osgGA/TerrainManipulator.cpp +++ b/src/osgGA/TerrainManipulator.cpp @@ -22,42 +22,45 @@ using namespace osgGA; /// Constructor. TerrainManipulator::TerrainManipulator( int flags ) - : inherited( flags ) + : inherited( flags ) { } /// Constructor. TerrainManipulator::TerrainManipulator( const TerrainManipulator& tm, const CopyOp& copyOp ) - : inherited( tm, copyOp ), - _previousUp( tm._previousUp ) + : inherited( tm, copyOp ), + _previousUp( tm._previousUp ) { } void TerrainManipulator::setRotationMode( TerrainManipulator::RotationMode mode ) { - setVerticalAxisFixed( mode == ELEVATION_AZIM ); + setVerticalAxisFixed( mode == ELEVATION_AZIM ); } TerrainManipulator::RotationMode TerrainManipulator::getRotationMode() const { - return getVerticalAxisFixed() ? ELEVATION_AZIM : ELEVATION_AZIM_ROLL; + return getVerticalAxisFixed() ? ELEVATION_AZIM : ELEVATION_AZIM_ROLL; } void TerrainManipulator::setNode( Node* node ) { - inherited::setNode( node ); + inherited::setNode( node ); - // update model size - if( _flags & UPDATE_MODEL_SIZE ) - if( _node.get() ) { - setMinimumDistance( clampBetween( _modelSize * 0.001, 0.00001, 1.0 ) ); - notify( INFO ) << "TerrainManipulator: setting _minimumDistance to " + // update model size + if( _flags & UPDATE_MODEL_SIZE ) + { + if( _node.get() ) + { + setMinimumDistance( clampBetween( _modelSize * 0.001, 0.00001, 1.0 ) ); + notify( INFO ) << "TerrainManipulator: setting _minimumDistance to " << _minimumDistance << std::endl; - } + } + } } @@ -199,107 +202,106 @@ bool TerrainManipulator::intersect( const Vec3d& start, const Vec3d& end, Vec3d& bool TerrainManipulator::performMovementMiddleMouseButton( const double dt, const double dx, const double dy ) { - // pan model. - double scale = -0.3f*_distance; + // pan model. + double scale = -0.3f*_distance; - Matrixd rotation_matrix; - rotation_matrix.makeRotate(_rotation); + Matrixd rotation_matrix; + rotation_matrix.makeRotate(_rotation); - // compute look vector. - Vec3d lookVector = -getUpVector(rotation_matrix); - Vec3d sideVector = getSideVector(rotation_matrix); - Vec3d upVector = getFrontVector(rotation_matrix); + // compute look vector. + Vec3d lookVector = -getUpVector(rotation_matrix); + Vec3d sideVector = getSideVector(rotation_matrix); + Vec3d upVector = getFrontVector(rotation_matrix); - // CoordinateFrame coordinateFrame = getCoordinateFrame(_center); - // Vec3d localUp = getUpVector(coordinateFrame); - Vec3d localUp = _previousUp; + // CoordinateFrame coordinateFrame = getCoordinateFrame(_center); + // Vec3d localUp = getUpVector(coordinateFrame); + Vec3d localUp = _previousUp; - Vec3d forwardVector =localUp^sideVector; - sideVector = forwardVector^localUp; + Vec3d forwardVector =localUp^sideVector; + sideVector = forwardVector^localUp; - forwardVector.normalize(); - sideVector.normalize(); + forwardVector.normalize(); + sideVector.normalize(); - Vec3d dv = forwardVector * (dy*scale) + sideVector * (dx*scale); + Vec3d dv = forwardVector * (dy*scale) + sideVector * (dx*scale); - _center += dv; + _center += dv; - // need to recompute the intersection point along the look vector. + // need to recompute the intersection point along the look vector. - bool hitFound = false; + bool hitFound = false; - if (_node.valid()) - { + if (_node.valid()) + { + // now reorientate the coordinate frame to the frame coords. + CoordinateFrame coordinateFrame = getCoordinateFrame(_center); - // now reorientate the coordinate frame to the frame coords. - CoordinateFrame coordinateFrame = getCoordinateFrame(_center); + // need to reintersect with the terrain + double distance = _node->getBound().radius()*0.25f; - // need to reintersect with the terrain - double distance = _node->getBound().radius()*0.25f; - - Vec3d ip1; - Vec3d ip2; - bool hit_ip1 = intersect(_center, _center + getUpVector(coordinateFrame) * distance, ip1); - bool hit_ip2 = intersect(_center, _center - getUpVector(coordinateFrame) * distance, ip2); - if (hit_ip1) - { - if (hit_ip2) - { - _center = (_center-ip1).length2() < (_center-ip2).length2() ? - ip1 : - ip2; + Vec3d ip1; + Vec3d ip2; + bool hit_ip1 = intersect(_center, _center + getUpVector(coordinateFrame) * distance, ip1); + bool hit_ip2 = intersect(_center, _center - getUpVector(coordinateFrame) * distance, ip2); + if (hit_ip1) + { + if (hit_ip2) + { + _center = (_center-ip1).length2() < (_center-ip2).length2() ? + ip1 : + ip2; + hitFound = true; + } + else + { + _center = ip1; + hitFound = true; + } + } + else if (hit_ip2) + { + _center = ip2; hitFound = true; - } - else - { - _center = ip1; - hitFound = true; - } - } - else if (hit_ip2) - { - _center = ip2; - hitFound = true; - } + } - if (!hitFound) - { - // ?? - notify(INFO)<<"TerrainManipulator unable to intersect with terrain."<