Fixed 3 space indenting

This commit is contained in:
Robert Osfield
2010-05-25 17:02:22 +00:00
parent db003c12c0
commit ee78e70d78
5 changed files with 661 additions and 651 deletions

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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.;
}

View File

@@ -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."<<std::endl;
}
if (!hitFound)
{
// ??
notify(INFO)<<"TerrainManipulator unable to intersect with terrain."<<std::endl;
}
coordinateFrame = getCoordinateFrame(_center);
Vec3d new_localUp = getUpVector(coordinateFrame);
coordinateFrame = getCoordinateFrame(_center);
Vec3d new_localUp = getUpVector(coordinateFrame);
Quat pan_rotation;
pan_rotation.makeRotate(localUp,new_localUp);
Quat pan_rotation;
pan_rotation.makeRotate(localUp,new_localUp);
if (!pan_rotation.zeroRotation())
{
_rotation = _rotation * pan_rotation;
_previousUp = new_localUp;
//notify(NOTICE)<<"Rotating from "<<localUp<<" to "<<new_localUp<<" angle = "<<acos(localUp*new_localUp/(localUp.length()*new_localUp.length()))<<std::endl;
if (!pan_rotation.zeroRotation())
{
_rotation = _rotation * pan_rotation;
_previousUp = new_localUp;
//notify(NOTICE)<<"Rotating from "<<localUp<<" to "<<new_localUp<<" angle = "<<acos(localUp*new_localUp/(localUp.length()*new_localUp.length()))<<std::endl;
//clampOrientation();
}
else
{
notify(INFO)<<"New up orientation nearly inline - no need to rotate"<<std::endl;
}
}
//clampOrientation();
}
else
{
notify(INFO)<<"New up orientation nearly inline - no need to rotate"<<std::endl;
}
}
return true;
return true;
}
bool TerrainManipulator::performMovementRightMouseButton( const double dt, const double dx, const double dy )
{
// zoom model
zoomModel( dy, false );
return true;
// zoom model
zoomModel( dy, false );
return true;
}
@@ -325,7 +327,6 @@ void TerrainManipulator::clampOrientation()
sideVector = upVector^localUp;
sideVector.normalize();
}
Vec3d newUpVector = sideVector^lookVector;

View File

@@ -9,12 +9,12 @@ using namespace osgGA;
TrackballManipulator::TrackballManipulator( int flags )
: inherited( flags )
{
setVerticalAxisFixed( false );
setVerticalAxisFixed( false );
}
/// Constructor.
TrackballManipulator::TrackballManipulator( const TrackballManipulator& tm, const CopyOp& copyOp )
: inherited( tm, copyOp )
: inherited( tm, copyOp )
{
}