diff --git a/applications/osgviewer/osgviewer.cpp b/applications/osgviewer/osgviewer.cpp index d66f92470..a860e8bb9 100644 --- a/applications/osgviewer/osgviewer.cpp +++ b/applications/osgviewer/osgviewer.cpp @@ -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 loadedModel = osgDB::readNodeFiles(arguments); - if (!loadedModel) + if (!loadedModel) { std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl; return 1; diff --git a/include/osgGA/FirstPersonManipulator b/include/osgGA/FirstPersonManipulator index 802028b8a..dafb815a0 100644 --- a/include/osgGA/FirstPersonManipulator +++ b/include/osgGA/FirstPersonManipulator @@ -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 ); diff --git a/include/osgGA/FlightManipulator b/include/osgGA/FlightManipulator index 2e2458bd9..b5ea50d56 100644 --- a/include/osgGA/FlightManipulator +++ b/include/osgGA/FlightManipulator @@ -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; diff --git a/include/osgGA/NodeTrackerManipulator b/include/osgGA/NodeTrackerManipulator index 6a2beebce..cc94f4a2b 100644 --- a/include/osgGA/NodeTrackerManipulator +++ b/include/osgGA/NodeTrackerManipulator @@ -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; diff --git a/include/osgGA/OrbitManipulator b/include/osgGA/OrbitManipulator index 051477edd..5584f50bb 100644 --- a/include/osgGA/OrbitManipulator +++ b/include/osgGA/OrbitManipulator @@ -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 ); diff --git a/include/osgGA/StandardManipulator b/include/osgGA/StandardManipulator index cb2d0b463..ba73bf588 100644 --- a/include/osgGA/StandardManipulator +++ b/include/osgGA/StandardManipulator @@ -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 ); diff --git a/include/osgGA/TerrainManipulator b/include/osgGA/TerrainManipulator index 907bcd1cf..9ed2fedc0 100644 --- a/include/osgGA/TerrainManipulator +++ b/include/osgGA/TerrainManipulator @@ -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(); diff --git a/include/osgGA/TrackballManipulator b/include/osgGA/TrackballManipulator index 16321de69..92aba5526 100644 --- a/include/osgGA/TrackballManipulator +++ b/include/osgGA/TrackballManipulator @@ -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 ); diff --git a/src/osgGA/FirstPersonManipulator.cpp b/src/osgGA/FirstPersonManipulator.cpp index 40342467b..8602ac34d 100644 --- a/src/osgGA/FirstPersonManipulator.cpp +++ b/src/osgGA/FirstPersonManipulator.cpp @@ -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 ); diff --git a/src/osgGA/FlightManipulator.cpp b/src/osgGA/FlightManipulator.cpp index d2dbaf420..204ded5a7 100644 --- a/src/osgGA/FlightManipulator.cpp +++ b/src/osgGA/FlightManipulator.cpp @@ -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; } diff --git a/src/osgGA/NodeTrackerManipulator.cpp b/src/osgGA/NodeTrackerManipulator.cpp index 71b648d9b..c44e0a6e4 100644 --- a/src/osgGA/NodeTrackerManipulator.cpp +++ b/src/osgGA/NodeTrackerManipulator.cpp @@ -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); } diff --git a/src/osgGA/OrbitManipulator.cpp b/src/osgGA/OrbitManipulator.cpp index c8e42996a..0624f1b90 100644 --- a/src/osgGA/OrbitManipulator.cpp +++ b/src/osgGA/OrbitManipulator.cpp @@ -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 @@ -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; diff --git a/src/osgGA/StandardManipulator.cpp b/src/osgGA/StandardManipulator.cpp index e09465c81..df076a679 100644 --- a/src/osgGA/StandardManipulator.cpp +++ b/src/osgGA/StandardManipulator.cpp @@ -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 #include -#include 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(); diff --git a/src/osgGA/TerrainManipulator.cpp b/src/osgGA/TerrainManipulator.cpp index ee0d9a097..196872bdb 100644 --- a/src/osgGA/TerrainManipulator.cpp +++ b/src/osgGA/TerrainManipulator.cpp @@ -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; } diff --git a/src/osgGA/TrackballManipulator.cpp b/src/osgGA/TrackballManipulator.cpp index 155487411..2992633a1 100644 --- a/src/osgGA/TrackballManipulator.cpp +++ b/src/osgGA/TrackballManipulator.cpp @@ -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 using namespace osg;