From Jan Peciva, additional comments, and standarisation of throw and handling of mouse wheel.
This commit is contained in:
@@ -37,7 +37,7 @@ FirstPersonManipulator::FirstPersonManipulator( int flags )
|
||||
setAcceleration( 0.25, true );
|
||||
setMaxVelocity( 0.25, true );
|
||||
setWheelMovement( 0.05, true );
|
||||
if( _flags & SET_CENTER_ON_WHEEL_UP )
|
||||
if( _flags & SET_CENTER_ON_WHEEL_FORWARD_MOVEMENT )
|
||||
setAnimationTime( 0.2 );
|
||||
}
|
||||
|
||||
@@ -233,50 +233,62 @@ void FirstPersonManipulator::init( const GUIEventAdapter& ea, GUIActionAdapter&
|
||||
// doc in parent
|
||||
bool FirstPersonManipulator::handleMouseWheel( const GUIEventAdapter& ea, GUIActionAdapter& us )
|
||||
{
|
||||
switch( ea.getScrollingMotion() ) {
|
||||
osgGA::GUIEventAdapter::ScrollingMotion sm = ea.getScrollingMotion();
|
||||
|
||||
// mouse scroll up event
|
||||
case GUIEventAdapter::SCROLL_UP: {
|
||||
// handle centering
|
||||
if( _flags & SET_CENTER_ON_WHEEL_FORWARD_MOVEMENT )
|
||||
{
|
||||
|
||||
if( _flags & SET_CENTER_ON_WHEEL_UP ) {
|
||||
if( sm == GUIEventAdapter::SCROLL_DOWN && _wheelMovement > 0. ||
|
||||
sm == GUIEventAdapter::SCROLL_UP && _wheelMovement < 0. )
|
||||
{
|
||||
|
||||
// stop thrown animation
|
||||
_thrown = false;
|
||||
|
||||
if( getAnimationTime() <= 0. )
|
||||
|
||||
// center by mouse intersection (no animation)
|
||||
setCenterByMousePointerIntersection( ea, us );
|
||||
// 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 );
|
||||
// start new animation only if there is no animation in progress
|
||||
if( !isAnimating() )
|
||||
startAnimationByMousePointerIntersection( ea, us );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// move forward
|
||||
moveForward( isAnimating() ? dynamic_cast< FirstPersonAnimationData* >( _animationData.get() )->_targetRot : _rotation,
|
||||
_wheelMovement * (getRelativeFlag( _wheelMovementFlagIndex ) ? _modelSize : 1. ));
|
||||
us.requestRedraw();
|
||||
us.requestContinuousUpdate( isAnimating() || _thrown );
|
||||
return true;
|
||||
}
|
||||
switch( sm ) {
|
||||
|
||||
// mouse scroll down event
|
||||
case GUIEventAdapter::SCROLL_DOWN:
|
||||
moveForward( -_wheelMovement * (getRelativeFlag( _wheelMovementFlagIndex ) ? _modelSize : 1. ));
|
||||
_thrown = false;
|
||||
us.requestRedraw();
|
||||
us.requestContinuousUpdate( isAnimating() || _thrown );
|
||||
return true;
|
||||
// mouse scroll up event
|
||||
case GUIEventAdapter::SCROLL_UP:
|
||||
{
|
||||
// move forward
|
||||
moveForward( isAnimating() ? dynamic_cast< FirstPersonAnimationData* >( _animationData.get() )->_targetRot : _rotation,
|
||||
-_wheelMovement * (getRelativeFlag( _wheelMovementFlagIndex ) ? _modelSize : 1. ));
|
||||
us.requestRedraw();
|
||||
us.requestContinuousUpdate( isAnimating() || _thrown );
|
||||
return true;
|
||||
}
|
||||
|
||||
// unhandled mouse scrolling motion
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
// mouse scroll down event
|
||||
case GUIEventAdapter::SCROLL_DOWN:
|
||||
{
|
||||
// move backward
|
||||
moveForward( _wheelMovement * (getRelativeFlag( _wheelMovementFlagIndex ) ? _modelSize : 1. ));
|
||||
_thrown = false;
|
||||
us.requestRedraw();
|
||||
us.requestContinuousUpdate( isAnimating() || _thrown );
|
||||
return true;
|
||||
}
|
||||
|
||||
// unhandled mouse scrolling motion
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -114,6 +114,7 @@ bool FlightManipulator::handleKeyDown( const GUIEventAdapter& ea, GUIActionAdapt
|
||||
}
|
||||
|
||||
|
||||
/// General flight-style event handler
|
||||
bool FlightManipulator::flightHandleEvent( const GUIEventAdapter& ea, GUIActionAdapter& us )
|
||||
{
|
||||
addMouseEvent( ea );
|
||||
|
||||
@@ -36,7 +36,7 @@ OrbitManipulator::OrbitManipulator( int flags )
|
||||
{
|
||||
setMinimumDistance( 0.05, true );
|
||||
setWheelZoomFactor( 0.1 );
|
||||
if( _flags & SET_CENTER_ON_WHEEL_UP )
|
||||
if( _flags & SET_CENTER_ON_WHEEL_FORWARD_MOVEMENT )
|
||||
setAnimationTime( 0.2 );
|
||||
}
|
||||
|
||||
@@ -148,34 +148,108 @@ void OrbitManipulator::getTransformation( osg::Vec3d& center, osg::Vec3d& eye, o
|
||||
}
|
||||
|
||||
|
||||
/** Sets the transformation by heading. Heading is given as an angle in radians giving a azimuth in xy plane.
|
||||
Its meaning is similar to longitude used in cartography and navigation.
|
||||
Positive number is going to the east direction.*/
|
||||
void OrbitManipulator::setHeading( double azimuth )
|
||||
{
|
||||
CoordinateFrame coordinateFrame = getCoordinateFrame( _center );
|
||||
Vec3d localUp = getUpVector( coordinateFrame );
|
||||
Vec3d localRight = getSideVector( coordinateFrame );
|
||||
|
||||
Vec3d dir = Quat( getElevation(), localRight ) * Quat( azimuth, localUp ) * Vec3d( 0., -_distance, 0. );
|
||||
|
||||
setTransformation( _center, _center + dir, localUp );
|
||||
}
|
||||
|
||||
|
||||
/// Returns the heading in radians. \sa setHeading
|
||||
double OrbitManipulator::getHeading() const
|
||||
{
|
||||
CoordinateFrame coordinateFrame = getCoordinateFrame( _center );
|
||||
Vec3d localFront = getFrontVector( coordinateFrame );
|
||||
Vec3d localRight = getSideVector( coordinateFrame );
|
||||
|
||||
Vec3d center, eye, tmp;
|
||||
getTransformation( center, eye, tmp );
|
||||
|
||||
Plane frontPlane( localFront, center );
|
||||
double frontDist = frontPlane.distance( eye );
|
||||
Plane rightPlane( localRight, center );
|
||||
double rightDist = rightPlane.distance( eye );
|
||||
|
||||
return atan2( rightDist, -frontDist );
|
||||
}
|
||||
|
||||
|
||||
/** Sets the transformation by elevation. Elevation is given as an angle in radians from xy plane.
|
||||
Its meaning is similar to latitude used in cartography and navigation.
|
||||
Positive number is going to the north direction, negative to the south.*/
|
||||
void OrbitManipulator::setElevation( double elevation )
|
||||
{
|
||||
CoordinateFrame coordinateFrame = getCoordinateFrame( _center );
|
||||
Vec3d localUp = getUpVector( coordinateFrame );
|
||||
Vec3d localRight = getSideVector( coordinateFrame );
|
||||
|
||||
Vec3d dir = Quat( -elevation, localRight ) * Quat( getHeading(), localUp ) * Vec3d( 0., -_distance, 0. );
|
||||
|
||||
setTransformation( _center, _center + dir, localUp );
|
||||
}
|
||||
|
||||
|
||||
/// Returns the elevation in radians. \sa setElevation
|
||||
double OrbitManipulator::getElevation() const
|
||||
{
|
||||
CoordinateFrame coordinateFrame = getCoordinateFrame( _center );
|
||||
Vec3d localUp = getUpVector( coordinateFrame );
|
||||
localUp.normalize();
|
||||
|
||||
Vec3d center, eye, tmp;
|
||||
getTransformation( center, eye, tmp );
|
||||
|
||||
Plane plane( localUp, center );
|
||||
double dist = plane.distance( eye );
|
||||
|
||||
return asin( -dist / (eye-center).length() );
|
||||
}
|
||||
|
||||
|
||||
// doc in parent
|
||||
bool OrbitManipulator::handleMouseWheel( const GUIEventAdapter& ea, GUIActionAdapter& us )
|
||||
{
|
||||
switch( ea.getScrollingMotion() )
|
||||
osgGA::GUIEventAdapter::ScrollingMotion sm = ea.getScrollingMotion();
|
||||
|
||||
// handle centering
|
||||
if( _flags & SET_CENTER_ON_WHEEL_FORWARD_MOVEMENT )
|
||||
{
|
||||
|
||||
if( sm == GUIEventAdapter::SCROLL_DOWN && _wheelZoomFactor > 0. ||
|
||||
sm == GUIEventAdapter::SCROLL_UP && _wheelZoomFactor < 0. )
|
||||
{
|
||||
|
||||
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 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
switch( sm )
|
||||
{
|
||||
// mouse scroll up event
|
||||
case GUIEventAdapter::SCROLL_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 );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// perform zoom
|
||||
zoomModel( -_wheelZoomFactor, true );
|
||||
zoomModel( _wheelZoomFactor, true );
|
||||
us.requestRedraw();
|
||||
us.requestContinuousUpdate( isAnimating() || _thrown );
|
||||
return true;
|
||||
@@ -183,10 +257,13 @@ bool OrbitManipulator::handleMouseWheel( const GUIEventAdapter& ea, GUIActionAda
|
||||
|
||||
// mouse scroll down event
|
||||
case GUIEventAdapter::SCROLL_DOWN:
|
||||
zoomModel( _wheelZoomFactor, true );
|
||||
{
|
||||
// perform zoom
|
||||
zoomModel( -_wheelZoomFactor, true );
|
||||
us.requestRedraw();
|
||||
us.requestContinuousUpdate( false );
|
||||
return true;
|
||||
}
|
||||
|
||||
// unhandled mouse scrolling motion
|
||||
default:
|
||||
@@ -530,7 +607,8 @@ void OrbitManipulator::setTrackballSize( const double& size )
|
||||
/** Set the mouse wheel zoom factor.
|
||||
The amount of camera movement on each mouse wheel event
|
||||
is computed as the current distance to the center multiplied by this factor.
|
||||
For example, value of 0.1 will short distance to center by 10% on each wheel up event.*/
|
||||
For example, value of 0.1 will short distance to center by 10% on each wheel up event.
|
||||
Use negative value for reverse mouse wheel direction.*/
|
||||
void OrbitManipulator::setWheelZoomFactor( double wheelZoomFactor )
|
||||
{
|
||||
_wheelZoomFactor = wheelZoomFactor;
|
||||
|
||||
@@ -25,16 +25,16 @@ using namespace osgUtil;
|
||||
|
||||
|
||||
|
||||
/** \fn void StandardManipulator::setTransformation( const osg::Vec3d& eye, const osg::Quat& rotation );
|
||||
/** \fn void StandardManipulator::setTransformation( const osg::Vec3d& eye, const osg::Quat& rotation )
|
||||
Sets manipulator by eye position and eye orientation.*/
|
||||
|
||||
/** \fn void StandardManipulator::setTransformation( const osg::Vec3d& center, const osg::Vec3d& eye, const osg::Vec3d& up );
|
||||
/** \fn void StandardManipulator::setTransformation( const osg::Vec3d& center, const osg::Vec3d& eye, const osg::Vec3d& up )
|
||||
Sets manipulator by focal center, eye position, and up vector.*/
|
||||
|
||||
/** \fn void StandardManipulator::getTransformation( osg::Vec3d& eye, osg::Quat& rotation );
|
||||
/** \fn void StandardManipulator::getTransformation( osg::Vec3d& eye, osg::Quat& rotation )
|
||||
Gets manipulator's eye position and eye orientation.*/
|
||||
|
||||
/** \fn void StandardManipulator::getTransformation( osg::Vec3d& center, osg::Vec3d& eye, osg::Vec3d& up );
|
||||
/** \fn void StandardManipulator::getTransformation( osg::Vec3d& center, osg::Vec3d& eye, osg::Vec3d& up )
|
||||
Gets manipulator's focal center, eye position, and up vector.*/
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ int StandardManipulator::allocateRelativeFlag()
|
||||
StandardManipulator::StandardManipulator( int flags )
|
||||
: inherited(),
|
||||
_thrown( false ),
|
||||
_allowThrow( true ),
|
||||
_mouseCenterX(0.0f), _mouseCenterY(0.0f),
|
||||
_delta_frame_time(0.01), _last_frame_time(0.0),
|
||||
_modelSize( 0. ),
|
||||
@@ -65,6 +66,7 @@ StandardManipulator::StandardManipulator( int flags )
|
||||
StandardManipulator::StandardManipulator( const StandardManipulator& uim, const CopyOp& copyOp )
|
||||
: inherited( uim, copyOp ),
|
||||
_thrown( uim._thrown ),
|
||||
_allowThrow( uim._allowThrow ),
|
||||
_mouseCenterX(0.0f), _mouseCenterY(0.0f),
|
||||
_ga_t1( dynamic_cast< GUIEventAdapter* >( copyOp( uim._ga_t1.get() ) ) ),
|
||||
_ga_t0( dynamic_cast< GUIEventAdapter* >( copyOp( uim._ga_t0.get() ) ) ),
|
||||
@@ -364,7 +366,7 @@ bool StandardManipulator::handleMouseRelease( const GUIEventAdapter& ea, GUIActi
|
||||
if( isMouseMoving() )
|
||||
{
|
||||
|
||||
if( performMovement() )
|
||||
if( performMovement() && _allowThrow )
|
||||
{
|
||||
us.requestRedraw();
|
||||
us.requestContinuousUpdate( true );
|
||||
@@ -583,6 +585,15 @@ bool StandardManipulator::isMouseMoving() const
|
||||
}
|
||||
|
||||
|
||||
/** Set the 'allow throw' flag. If it is set to true (default), releasing the mouse button
|
||||
while moving the mouse results in a throw. If manipulator was thrown, it continues spinning
|
||||
although no mouse button is down at the moment.*/
|
||||
void StandardManipulator::setAllowThrow( bool allowThrow )
|
||||
{
|
||||
_allowThrow = allowThrow;
|
||||
}
|
||||
|
||||
|
||||
/** Returns the scale that should be applied on animation of "thrown" manipulator state
|
||||
to avoid its dependency on varying frame rate.
|
||||
|
||||
|
||||
@@ -35,12 +35,16 @@ TerrainManipulator::TerrainManipulator( const TerrainManipulator& tm, const Copy
|
||||
}
|
||||
|
||||
|
||||
/** Sets the manipulator rotation mode. RotationMode is now deprecated by
|
||||
osgGA::StandardManipulator::setVerticalAxisFixed() functionality,
|
||||
that is used across StandardManipulator derived classes.*/
|
||||
void TerrainManipulator::setRotationMode( TerrainManipulator::RotationMode mode )
|
||||
{
|
||||
setVerticalAxisFixed( mode == ELEVATION_AZIM );
|
||||
}
|
||||
|
||||
|
||||
/** Returns the manipulator rotation mode.*/
|
||||
TerrainManipulator::RotationMode TerrainManipulator::getRotationMode() const
|
||||
{
|
||||
return getVerticalAxisFixed() ? ELEVATION_AZIM : ELEVATION_AZIM_ROLL;
|
||||
|
||||
Reference in New Issue
Block a user