From Jan Pecvia, improvements to manipulators and added new manipulator to osgviewer

This commit is contained in:
Robert Osfield 2010-05-27 13:59:34 +00:00
parent 72663ec3df
commit 2cf3224dd3
15 changed files with 176 additions and 98 deletions

View File

@ -1,9 +1,9 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
*
* This application is open source and may be redistributed and/or modified
* This application is open source and may be redistributed and/or modified
* freely and without restriction, both in commericial and non commericial applications,
* as long as this copyright notice is maintained.
*
*
* This application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
@ -85,14 +85,16 @@ int main(int argc, char** argv)
keyswitchManipulator->addMatrixManipulator( '2', "Flight", new osgGA::FlightManipulator() );
keyswitchManipulator->addMatrixManipulator( '3', "Drive", new osgGA::DriveManipulator() );
keyswitchManipulator->addMatrixManipulator( '4', "Terrain", new osgGA::TerrainManipulator() );
keyswitchManipulator->addMatrixManipulator( '5', "Spherical", new osgGA::SphericalManipulator() );
keyswitchManipulator->addMatrixManipulator( '5', "Orbit", new osgGA::OrbitManipulator() );
keyswitchManipulator->addMatrixManipulator( '6', "FirstPerson", new osgGA::FirstPersonManipulator() );
keyswitchManipulator->addMatrixManipulator( '7', "Spherical", new osgGA::SphericalManipulator() );
std::string pathfile;
char keyForAnimationPath = '6';
char keyForAnimationPath = '8';
while (arguments.read("-p",pathfile))
{
osgGA::AnimationPathManipulator* apm = new osgGA::AnimationPathManipulator(pathfile);
if (apm || !apm->valid())
if (apm || !apm->valid())
{
unsigned int num = keyswitchManipulator->getNumMatrixManipulators();
keyswitchManipulator->addMatrixManipulator( keyForAnimationPath, "Path", apm );
@ -130,7 +132,7 @@ int main(int argc, char** argv)
// load the data
osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFiles(arguments);
if (!loadedModel)
if (!loadedModel)
{
std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl;
return 1;

View File

@ -1,4 +1,4 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
@ -11,7 +11,7 @@
* OpenSceneGraph Public License for more details.
*
* FirstPersonManipulator code Copyright (C) 2010 PCJohn (Jan Peciva)
* while some pieces of code were reused from OSG.
* while some pieces of code were taken from OSG.
* Thanks to company Cadwork (www.cadwork.ch) and
* Brno University of Technology (www.fit.vutbr.cz) for open-sourcing this work.
*/
@ -68,7 +68,7 @@ class OSGGA_EXPORT FirstPersonManipulator : public StandardManipulator
virtual bool handleMouseWheel( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );
virtual bool performMovementLeftMouseButton( const double dt, const double dx, const double dy );
virtual bool performMovementLeftMouseButton( const double eventTimeDelta, const double dx, const double dy );
virtual bool performMouseDeltaMovement( const float dx, const float dy );
virtual void applyAnimationStep( const double currentProgress, const double prevProgress );
virtual bool startAnimationByMousePointerIntersection( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );

View File

@ -61,9 +61,9 @@ class OSGGA_EXPORT FlightManipulator : public FirstPersonManipulator
virtual bool flightHandleEvent( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );
virtual bool performMovement();
virtual bool performMovementLeftMouseButton( const double dt, const double dx, const double dy );
virtual bool performMovementMiddleMouseButton( const double dt, const double dx, const double dy );
virtual bool performMovementRightMouseButton( const double dt, const double dx, const double dy );
virtual bool performMovementLeftMouseButton( const double eventTimeDelta, const double dx, const double dy );
virtual bool performMovementMiddleMouseButton( const double eventTimeDelta, const double dx, const double dy );
virtual bool performMovementRightMouseButton( const double eventTimeDelta, const double dx, const double dy );
YawControlMode _yawMode;

View File

@ -86,9 +86,9 @@ class OSGGA_EXPORT NodeTrackerManipulator : public OrbitManipulator
protected:
virtual bool performMovementLeftMouseButton(const double dt, const double dx, const double dy);
virtual bool performMovementMiddleMouseButton(const double dt, const double dx, const double dy);
virtual bool performMovementRightMouseButton(const double dt, const double dx, const double dy);
virtual bool performMovementLeftMouseButton(const double eventTimeDelta, const double dx, const double dy);
virtual bool performMovementMiddleMouseButton(const double eventTimeDelta, const double dx, const double dy);
virtual bool performMovementRightMouseButton(const double eventTimeDelta, const double dx, const double dy);
osg::NodePath getNodePath() const;

View File

@ -1,4 +1,4 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
@ -9,6 +9,11 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*
* OrbitManipulator code Copyright (C) 2010 PCJohn (Jan Peciva)
* while some pieces of code were taken from OSG.
* Thanks to company Cadwork (www.cadwork.ch) and
* Brno University of Technology (www.fit.vutbr.cz) for open-sourcing this work.
*/
#ifndef OSGGA_ORBIT_MANIPULATOR
@ -31,7 +36,7 @@ class OSGGA_EXPORT OrbitManipulator : public StandardManipulator
OrbitManipulator( int flags = DEFAULT_SETTINGS );
OrbitManipulator( const OrbitManipulator& om,
const osg::CopyOp& copyOp = osg::CopyOp::SHALLOW_COPY );
const osg::CopyOp& copyOp = osg::CopyOp::SHALLOW_COPY );
META_Object( osgGA, OrbitManipulator );
@ -67,13 +72,14 @@ class OSGGA_EXPORT OrbitManipulator : public StandardManipulator
virtual bool handleMouseWheel( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );
virtual bool performMovementLeftMouseButton( const double dt, const double dx, const double dy );
virtual bool performMovementMiddleMouseButton( const double dt, const double dx, const double dy );
virtual bool performMovementRightMouseButton( const double dt, const double dx, const double dy );
virtual bool performMovementLeftMouseButton( const double eventTimeDelta, const double dx, const double dy );
virtual bool performMovementMiddleMouseButton( const double eventTimeDelta, const double dx, const double dy );
virtual bool performMovementRightMouseButton( const double eventTimeDelta, const double dx, const double dy );
virtual bool performMouseDeltaMovement( const float dx, const float dy );
virtual void applyAnimationStep( const double currentProgress, const double prevProgress );
virtual void rotateTrackball( const float px0, const float py0, const float px1, const float py1 );
virtual void rotateTrackball( const float px0, const float py0,
const float px1, const float py1, const float scale );
virtual void rotateWithFixedVertical( const float dx, const float dy );
virtual void rotateWithFixedVertical( const float dx, const float dy, const osg::Vec3f& up );
virtual void panModel( const float dx, const float dy, const float dz = 0.f );

View File

@ -1,4 +1,4 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
@ -11,7 +11,7 @@
* OpenSceneGraph Public License for more details.
*
* StandardManipulator code Copyright (C) 2010 PCJohn (Jan Peciva)
* while some pieces of code were reused from OSG.
* while some pieces of code were taken from OSG.
* Thanks to company Cadwork (www.cadwork.ch) and
* Brno University of Technology (www.fit.vutbr.cz) for open-sourcing this work.
*/
@ -89,9 +89,9 @@ class OSGGA_EXPORT StandardManipulator : public MatrixManipulator
virtual bool handleMouseDeltaMovement( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );
virtual bool performMovement();
virtual bool performMovementLeftMouseButton( const double dt, const double dx, const double dy );
virtual bool performMovementMiddleMouseButton( const double dt, const double dx, const double dy );
virtual bool performMovementRightMouseButton( const double dt, const double dx, const double dy );
virtual bool performMovementLeftMouseButton( const double eventTimeDelta, const double dx, const double dy );
virtual bool performMovementMiddleMouseButton( const double eventTimeDelta, const double dx, const double dy );
virtual bool performMovementRightMouseButton( const double eventTimeDelta, const double dx, const double dy );
virtual bool performMouseDeltaMovement( const float dx, const float dy );
virtual bool performAnimationMovement( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );
virtual void applyAnimationStep( const double currentProgress, const double prevProgress );
@ -99,6 +99,7 @@ class OSGGA_EXPORT StandardManipulator : public MatrixManipulator
void addMouseEvent( const osgGA::GUIEventAdapter& ea );
void flushMouseEventStack();
virtual bool isMouseMoving() const;
float getThrowScale( const double eventTimeDelta ) const;
virtual void centerMousePointer( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );
static void rotateYawPitch( osg::Quat& rotation, const double yaw, const double pitch,
@ -106,7 +107,7 @@ class OSGGA_EXPORT StandardManipulator : public MatrixManipulator
static void fixVerticalAxis( osg::Quat& rotation, const osg::Vec3d& localUp, bool disallowFlipOver );
void fixVerticalAxis( osg::Vec3d& eye, osg::Quat& rotation, bool disallowFlipOver );
static void fixVerticalAxis( const osg::Vec3d& forward, const osg::Vec3d& up, osg::Vec3d& newUp,
const osg::Vec3d& localUp, bool disallowFlipOver );
const osg::Vec3d& localUp, bool disallowFlipOver );
virtual bool setCenterByMousePointerIntersection( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );
virtual bool startAnimationByMousePointerIntersection( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us );

View File

@ -1,4 +1,4 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
@ -49,8 +49,8 @@ public:
protected:
virtual bool performMovementMiddleMouseButton( const double dt, const double dx, const double dy );
virtual bool performMovementRightMouseButton( const double dt, const double dx, const double dy );
virtual bool performMovementMiddleMouseButton( const double eventTimeDelta, const double dx, const double dy );
virtual bool performMovementRightMouseButton( const double eventTimeDelta, const double dx, const double dy );
bool intersect( const osg::Vec3d& start, const osg::Vec3d& end, osg::Vec3d& intersection ) const;
void clampOrientation();

View File

@ -1,4 +1,4 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
@ -28,7 +28,7 @@ class OSGGA_EXPORT TrackballManipulator : public OrbitManipulator
TrackballManipulator( int flags = DEFAULT_SETTINGS );
TrackballManipulator( const TrackballManipulator& tm,
const osg::CopyOp& copyOp = osg::CopyOp::SHALLOW_COPY );
const osg::CopyOp& copyOp = osg::CopyOp::SHALLOW_COPY );
META_Object( osgGA, TrackballManipulator );

View File

@ -1,4 +1,4 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
@ -11,7 +11,7 @@
* OpenSceneGraph Public License for more details.
*
* FirstPersonManipulator code Copyright (C) 2010 PCJohn (Jan Peciva)
* while some pieces of code were reused from OSG.
* while some pieces of code were taken from OSG.
* Thanks to company Cadwork (www.cadwork.ch) and
* Brno University of Technology (www.fit.vutbr.cz) for open-sourcing this work.
*/
@ -281,7 +281,7 @@ bool FirstPersonManipulator::handleMouseWheel( const GUIEventAdapter& ea, GUIAct
// doc in parent
bool FirstPersonManipulator::performMovementLeftMouseButton( const double dt, const double dx, const double dy )
bool FirstPersonManipulator::performMovementLeftMouseButton( const double eventTimeDelta, const double dx, const double dy )
{
// world up vector
CoordinateFrame coordinateFrame = getCoordinateFrame( _eye );

View File

@ -146,27 +146,27 @@ bool FlightManipulator::performMovement()
if (_ga_t0.get()==NULL || _ga_t1.get()==NULL) return false;
double dt = _ga_t0->getTime()-_ga_t1->getTime();
double eventTimeDelta = _ga_t0->getTime()-_ga_t1->getTime();
if (dt<0.0f)
if (eventTimeDelta<0.0f)
{
notify(WARN) << "Manipulator warning dt = " << dt << std::endl;
dt = 0.0f;
notify(WARN) << "Manipulator warning: eventTimeDelta = " << eventTimeDelta << std::endl;
eventTimeDelta = 0.0f;
}
unsigned int buttonMask = _ga_t1->getButtonMask();
if (buttonMask==GUIEventAdapter::LEFT_MOUSE_BUTTON)
{
return performMovementLeftMouseButton(dt, 0., 0.);
performMovementLeftMouseButton(eventTimeDelta, 0., 0.);
}
else if (buttonMask==GUIEventAdapter::MIDDLE_MOUSE_BUTTON ||
buttonMask==(GUIEventAdapter::LEFT_MOUSE_BUTTON|GUIEventAdapter::RIGHT_MOUSE_BUTTON))
{
return performMovementMiddleMouseButton(dt, 0., 0.);
performMovementMiddleMouseButton(eventTimeDelta, 0., 0.);
}
else if (buttonMask==GUIEventAdapter::RIGHT_MOUSE_BUTTON)
{
return performMovementRightMouseButton(dt, 0., 0.);
performMovementRightMouseButton(eventTimeDelta, 0., 0.);
}
float dx = _ga_t0->getXnormalized();
@ -183,8 +183,8 @@ bool FlightManipulator::performMovement()
Vec3d sv = lv^up;
sv.normalize();
double pitch = -inDegrees(dy*50.0f*dt);
double roll = inDegrees(dx*50.0f*dt);
double pitch = -inDegrees(dy*50.0f*eventTimeDelta);
double roll = inDegrees(dx*50.0f*eventTimeDelta);
Quat delta_rotate;
@ -200,7 +200,7 @@ bool FlightManipulator::performMovement()
{
//float bank = asinf(sv.z());
double bank = asinf(sv *getUpVector(cf));
double yaw = inRadians(bank)*dt;
double yaw = inRadians(bank)*eventTimeDelta;
Quat yaw_rotate;
//yaw_rotate.makeRotate(yaw,0.0f,0.0f,1.0f);
@ -211,7 +211,7 @@ bool FlightManipulator::performMovement()
delta_rotate = delta_rotate*yaw_rotate;
}
lv *= (_velocity*dt);
lv *= (_velocity*eventTimeDelta);
_eye += lv;
_rotation = _rotation*delta_rotate;
@ -220,23 +220,23 @@ bool FlightManipulator::performMovement()
}
bool FlightManipulator::performMovementLeftMouseButton( const double dt, const double dx, const double dy )
bool FlightManipulator::performMovementLeftMouseButton( const double eventTimeDelta, const double dx, const double dy )
{
// pan model
_velocity += dt * (_acceleration + _velocity);
_velocity += eventTimeDelta * (_acceleration + _velocity);
return true;
}
bool FlightManipulator::performMovementMiddleMouseButton( const double dt, const double dx, const double dy )
bool FlightManipulator::performMovementMiddleMouseButton( const double eventTimeDelta, const double dx, const double dy )
{
_velocity = 0.0f;
return true;
}
bool FlightManipulator::performMovementRightMouseButton( const double dt, const double dx, const double dy )
bool FlightManipulator::performMovementRightMouseButton( const double eventTimeDelta, const double dx, const double dy )
{
_velocity -= dt * (_acceleration + _velocity);
_velocity -= eventTimeDelta * (_acceleration + _velocity);
return true;
}

View File

@ -1,4 +1,4 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
@ -263,7 +263,7 @@ void NodeTrackerManipulator::computePosition(const osg::Vec3d& eye,const osg::Ve
// doc in parent
bool NodeTrackerManipulator::performMovementLeftMouseButton( const double dt, const double dx, const double dy )
bool NodeTrackerManipulator::performMovementLeftMouseButton( const double eventTimeDelta, const double dx, const double dy )
{
osg::Vec3d nodeCenter;
osg::Quat nodeRotation;
@ -297,14 +297,15 @@ bool NodeTrackerManipulator::performMovementLeftMouseButton( const double dt, co
} else
rotateTrackball( _ga_t0->getXnormalized(), _ga_t0->getYnormalized(),
_ga_t1->getXnormalized(), _ga_t1->getYnormalized() );
_ga_t1->getXnormalized(), _ga_t1->getYnormalized(),
_thrown ? float( _delta_frame_time / eventTimeDelta ) : 1.f );
return true;
}
// doc in parent
bool NodeTrackerManipulator::performMovementMiddleMouseButton( const double dt, const double dx, const double dy )
bool NodeTrackerManipulator::performMovementMiddleMouseButton( const double eventTimeDelta, const double dx, const double dy )
{
osg::Vec3d nodeCenter;
osg::Quat nodeRotation;
@ -315,11 +316,11 @@ bool NodeTrackerManipulator::performMovementMiddleMouseButton( const double dt,
// doc in parent
bool NodeTrackerManipulator::performMovementRightMouseButton( const double dt, const double dx, const double dy )
bool NodeTrackerManipulator::performMovementRightMouseButton( const double eventTimeDelta, const double dx, const double dy )
{
osg::Vec3d nodeCenter;
osg::Quat nodeRotation;
computeNodeCenterAndRotation(nodeCenter, nodeRotation);
return inherited::performMovementRightMouseButton(dt, dx, dy);
return inherited::performMovementRightMouseButton(eventTimeDelta, dx, dy);
}

View File

@ -1,4 +1,4 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
@ -9,6 +9,11 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*
* OrbitManipulator code Copyright (C) 2010 PCJohn (Jan Peciva)
* while some pieces of code were taken from OSG.
* Thanks to company Cadwork (www.cadwork.ch) and
* Brno University of Technology (www.fit.vutbr.cz) for open-sourcing this work.
*/
#include <osgGA/OrbitManipulator>
@ -191,33 +196,34 @@ bool OrbitManipulator::handleMouseWheel( const GUIEventAdapter& ea, GUIActionAda
// doc in parent
bool OrbitManipulator::performMovementLeftMouseButton( const double dt, const double dx, const double dy )
bool OrbitManipulator::performMovementLeftMouseButton( const double eventTimeDelta, 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() );
return true;
_ga_t1->getXnormalized(), _ga_t1->getYnormalized(),
getThrowScale( eventTimeDelta ) );
return true;
}
// doc in parent
bool OrbitManipulator::performMovementMiddleMouseButton( const double dt, const double dx, const double dy )
bool OrbitManipulator::performMovementMiddleMouseButton( const double eventTimeDelta, const double dx, const double dy )
{
// pan model
float scale = -0.3f * _distance;
float scale = -0.3f * _distance * getThrowScale( eventTimeDelta );
panModel( dx*scale, dy*scale );
return true;
}
// doc in parent
bool OrbitManipulator::performMovementRightMouseButton( const double dt, const double dx, const double dy )
bool OrbitManipulator::performMovementRightMouseButton( const double eventTimeDelta, const double dx, const double dy )
{
// zoom model
zoomModel( dy, true );
zoomModel( dy * getThrowScale( eventTimeDelta ), true );
return true;
}
@ -228,7 +234,7 @@ bool OrbitManipulator::performMouseDeltaMovement( const float dx, const float dy
if( getVerticalAxisFixed() )
rotateWithFixedVertical( dx, dy );
else
rotateTrackball( 0.f, 0.f, dx, dy );
rotateTrackball( 0.f, 0.f, dx, dy, 1.f );
return true;
}
@ -290,8 +296,12 @@ void OrbitManipulator::OrbitAnimationData::start( const osg::Vec3d& movement, co
/** Performs trackball rotation based on two points given, for example,
by mouse pointer on the screen.*/
void OrbitManipulator::rotateTrackball( const float px0, const float py0, const float px1, const float py1 )
by mouse pointer on the screen.
Scale parameter is useful, for example, when manipulator is thrown.
It scales the amount of rotation based, for example, on the current frame time.*/
void OrbitManipulator::rotateTrackball( const float px0, const float py0,
const float px1, const float py1, const float scale )
{
osg::Vec3d axis;
float angle;

View File

@ -1,4 +1,4 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
@ -9,11 +9,15 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*
* StandardManipulator code Copyright (C) 2010 PCJohn (Jan Peciva)
* while some pieces of code were taken from OSG.
* Thanks to company Cadwork (www.cadwork.ch) and
* Brno University of Technology (www.fit.vutbr.cz) for open-sourcing this work.
*/
#include <osgGA/StandardManipulator>
#include <osgViewer/View>
#include <cassert>
using namespace osg;
using namespace osgGA;
@ -160,6 +164,7 @@ bool StandardManipulator::isAnimating() const
}
/// Finishes the animation by performing a step that moves it to its final position.
void StandardManipulator::finishAnimation()
{
if( !isAnimating() )
@ -425,11 +430,11 @@ bool StandardManipulator::performMovement()
return false;
// get delta time
double dt = _ga_t0->getTime() - _ga_t1->getTime();
if( dt < 0. )
double eventTimeDelta = _ga_t0->getTime() - _ga_t1->getTime();
if( eventTimeDelta < 0. )
{
notify( INFO ) << "Manipulator warning: dt = " << dt << std::endl;
dt = 0.;
notify( WARN ) << "Manipulator warning: eventTimeDelta = " << eventTimeDelta << std::endl;
eventTimeDelta = 0.;
}
// get deltaX and deltaY
@ -445,16 +450,16 @@ bool StandardManipulator::performMovement()
unsigned int buttonMask = _ga_t1->getButtonMask();
if( buttonMask == GUIEventAdapter::LEFT_MOUSE_BUTTON )
{
return performMovementLeftMouseButton( dt, dx, dy );
return performMovementLeftMouseButton( eventTimeDelta, dx, dy );
}
else if( buttonMask == GUIEventAdapter::MIDDLE_MOUSE_BUTTON ||
buttonMask == (GUIEventAdapter::LEFT_MOUSE_BUTTON | GUIEventAdapter::RIGHT_MOUSE_BUTTON) )
{
return performMovementMiddleMouseButton( dt, dx, dy );
return performMovementMiddleMouseButton( eventTimeDelta, dx, dy );
}
else if( buttonMask == GUIEventAdapter::RIGHT_MOUSE_BUTTON )
{
return performMovementRightMouseButton( dt, dx, dy );
return performMovementRightMouseButton( eventTimeDelta, dx, dy );
}
return false;
@ -463,7 +468,7 @@ bool StandardManipulator::performMovement()
/** Make movement step of manipulator.
This method implements movement for left mouse button.*/
bool StandardManipulator::performMovementLeftMouseButton( const double dt, const double dx, const double dy )
bool StandardManipulator::performMovementLeftMouseButton( const double eventTimeDelta, const double dx, const double dy )
{
return false;
}
@ -472,7 +477,7 @@ bool StandardManipulator::performMovementLeftMouseButton( const double dt, const
/** Make movement step of manipulator.
This method implements movement for middle mouse button
or combination of left and right mouse button pressed together.*/
bool StandardManipulator::performMovementMiddleMouseButton( const double dt, const double dx, const double dy )
bool StandardManipulator::performMovementMiddleMouseButton( const double eventTimeDelta, const double dx, const double dy )
{
return false;
}
@ -480,12 +485,13 @@ bool StandardManipulator::performMovementMiddleMouseButton( const double dt, con
/** Make movement step of manipulator.
This method implements movement for right mouse button.*/
bool StandardManipulator::performMovementRightMouseButton( const double dt, const double dx, const double dy )
bool StandardManipulator::performMovementRightMouseButton( const double eventTimeDelta, const double dx, const double dy )
{
return false;
}
/// The method processes events for manipulation based on relative mouse movement (mouse delta).
bool StandardManipulator::handleMouseDeltaMovement( const GUIEventAdapter& ea, GUIActionAdapter& us )
{
float dx = ea.getX() - _mouseCenterX;
@ -501,12 +507,14 @@ bool StandardManipulator::handleMouseDeltaMovement( const GUIEventAdapter& ea, G
}
/// The method performs manipulator update based on relative mouse movement (mouse delta).
bool StandardManipulator::performMouseDeltaMovement( const float dx, const float dy )
{
return false;
}
/// Makes the manipulator progress in its current animation.
bool StandardManipulator::performAnimationMovement( const GUIEventAdapter& ea, GUIActionAdapter& us )
{
double f = (ea.getTime() - _animationData->_startTime) / _animationData->_animationTime;
@ -527,11 +535,13 @@ bool StandardManipulator::performAnimationMovement( const GUIEventAdapter& ea, G
}
/// Updates manipulator by a single animation step
void StandardManipulator::applyAnimationStep( const double currentProgress, const double prevProgress )
{
}
/// Centers mouse pointer
void StandardManipulator::centerMousePointer( const GUIEventAdapter& ea, GUIActionAdapter& us )
{
_mouseCenterX = (ea.getXmin() + ea.getXmax()) / 2.0f;
@ -573,6 +583,18 @@ bool StandardManipulator::isMouseMoving() const
}
/** Returns the scale that should be applied on animation of "thrown" manipulator state
to avoid its dependency on varying frame rate.
eventTimeDelta parameter gives the time difference between last two
events that started the animation.*/
float StandardManipulator::getThrowScale( const double eventTimeDelta ) const
{
if( _thrown ) return float( _delta_frame_time / eventTimeDelta );
else return 1.f;
}
/** Update rotation by yaw and pitch.
*
* localUp parameter defines either camera's "UP" vector
@ -628,6 +650,17 @@ void StandardManipulator::rotateYawPitch( Quat& rotation, const double yaw, cons
}
/** The method corrects the rotation to make impression of fixed up direction.
* Technically said, it makes the roll component of the rotation equal to zero.
*
* Up vector is given by CoordinateFrame and it is +z by default.
* It can be changed by osgGA::MatrixManipulator::setCoordinateFrameCallback().
*
* Eye parameter is user position, rotation is the rotation to be fixed, and
* disallowFlipOver, when set on true, avoids pitch rotation component to grow
* over +/- 90 degrees. If this happens and disallowFlipOver is true,
* manipulator is rotated by 180 degrees. More precisely, roll rotation component is changed by 180 degrees,
* making pitch once again between -90..+90 degrees limits.*/
void StandardManipulator::fixVerticalAxis( Vec3d& eye, Quat& rotation, bool disallowFlipOver )
{
CoordinateFrame coordinateFrame = getCoordinateFrame( eye );
@ -640,10 +673,11 @@ void StandardManipulator::fixVerticalAxis( Vec3d& eye, Quat& rotation, bool disa
/** The method corrects the rotation to make impression of fixed up direction.
* Technically said, it makes the roll component of the rotation equal to zero.
*
* Rotation parameter is the rotation to be fixed, localUp is UP vector, and
* disallowFlipOver when set on true avoids pitch rotation component to grow
* rotation parameter is the rotation to be fixed.
* localUp is UP vector and must not be zero length.
* disallowFlipOver, when set on true, avoids pitch rotation component to grow
* over +/- 90 degrees. If this happens and disallowFlipOver is true,
* right and up camera vectors are negated (changing roll by 180 degrees),
* manipulator is rotated by 180 degrees. More precisely, roll rotation component is changed by 180 degrees,
* making pitch once again between -90..+90 degrees limits.*/
void StandardManipulator::fixVerticalAxis( Quat& rotation, const Vec3d& localUp, bool disallowFlipOver )
{
@ -660,8 +694,6 @@ void StandardManipulator::fixVerticalAxis( Quat& rotation, const Vec3d& localUp,
if( newCameraRight * cameraRight < 0. )
newCameraRight = -newCameraRight;
assert( newCameraRight.length2() > 0. );
// vertical axis correction
Quat rotationVerticalAxisCorrection;
rotationVerticalAxisCorrection.makeRotate( cameraRight, newCameraRight );
@ -684,8 +716,8 @@ void StandardManipulator::fixVerticalAxis( Quat& rotation, const Vec3d& localUp,
/** The method corrects the rotation to make impression of fixed up direction.
* Technically said, it makes the roll component of the rotation equal to zero.
*
* forward and up parameter is the forward and up vector of the camera.
* newUp will receive corrected UP camera vector. localUp is UP vector
* forward and up parameters are the forward and up vectors of the manipulator.
* newUp will receive corrected UP manipulator vector. localUp is UP vector
* that is used for vertical correction.
* disallowFlipOver when set on true avoids pitch rotation component to grow
* over +/- 90 degrees. If this happens and disallowFlipOver is true,
@ -699,14 +731,27 @@ void StandardManipulator::fixVerticalAxis( const osg::Vec3d& forward, const osg:
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();
// updatedUp
osg::Vec3d updatedUp = right ^ forward;
if( updatedUp.normalize() >= 0. )
// return updatedUp
newUp = updatedUp;
else {
// return original up
notify( WARN ) << "StandardManipulator::fixVerticalAxis warning: Can not update vertical axis." << std::endl;
newUp = up;
}
}
/** The method sends a ray into the scene and the point of the closest intersection
is used to set a new center for the manipulator. For Orbit-style manipulators,
the orbiting center is set. For FirstPerson-style manipulators, view is pointed
towards the center.*/
bool StandardManipulator::setCenterByMousePointerIntersection( const GUIEventAdapter& ea, GUIActionAdapter& us )
{
osg::View* view = us.asView();

View File

@ -200,10 +200,10 @@ bool TerrainManipulator::intersect( const Vec3d& start, const Vec3d& end, Vec3d&
}
bool TerrainManipulator::performMovementMiddleMouseButton( const double dt, const double dx, const double dy )
bool TerrainManipulator::performMovementMiddleMouseButton( const double eventTimeDelta, const double dx, const double dy )
{
// pan model.
double scale = -0.3f*_distance;
double scale = -0.3f * _distance * getThrowScale( eventTimeDelta );
Matrixd rotation_matrix;
rotation_matrix.makeRotate(_rotation);
@ -297,10 +297,10 @@ bool TerrainManipulator::performMovementMiddleMouseButton( const double dt, cons
}
bool TerrainManipulator::performMovementRightMouseButton( const double dt, const double dx, const double dy )
bool TerrainManipulator::performMovementRightMouseButton( const double eventTimeDelta, const double dx, const double dy )
{
// zoom model
zoomModel( dy, false );
zoomModel( dy * getThrowScale( eventTimeDelta ), false );
return true;
}

View File

@ -1,3 +1,16 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2010 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#include <osgGA/TrackballManipulator>
using namespace osg;